From a0d8aeb57bed044eeed611c7795e4ab3392b7e99 Mon Sep 17 00:00:00 2001 From: Paul Zhang Date: Wed, 27 Sep 2023 18:53:22 +0800 Subject: [PATCH] qcacld-3.0: Receive all expected response frame Currently, it uses timer count to check whether the expected TDLS discovery response frames received or not. But sometimes, the discovery response frame comes back before the timer count increased. The frame pattern like this: Send tdls discovery request on link0 Receive tdls discovery request on link0 Send tlds discovery request on link1 Receive tdls discovery request on link1 In this scenario, driver forwards two different discovery responses frame to supplicant and causes supplicant confusion. To resolve this issue, check whether the expected discovery response frames received or not. If not, let the timer to monitor the situation instead of stop the timer and forward current discovery response frame to supplicant. CRs-Fixed: 3624866 Change-Id: I47ee729ed4c426eda232c704fc99f681b9db2fa4 --- components/tdls/core/src/wlan_tdls_ct.c | 2 + components/tdls/core/src/wlan_tdls_mgmt.c | 56 +++++++++++++++++++++-- components/tdls/core/src/wlan_tdls_peer.c | 6 +-- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/components/tdls/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c index 8a00830615..84d820b0b6 100644 --- a/components/tdls/core/src/wlan_tdls_ct.c +++ b/components/tdls/core/src/wlan_tdls_ct.c @@ -132,6 +132,8 @@ void tdls_discovery_timeout_peer_cb(void *user_data) tdls_notice("[TDLS] TDLS Discovery Response," "QDF_MAC_ADDR_FMT RSSI[%d]<---OTA", rx_mgmt->rx_rssi); + tdls_debug("discovery resp on vdev %d", + wlan_vdev_get_id(tdls_vdev->vdev)); tdls_recv_discovery_resp(tdls_vdev, mac); tdls_set_rssi(tdls_vdev->vdev, mac, rx_mgmt->rx_rssi); diff --git a/components/tdls/core/src/wlan_tdls_mgmt.c b/components/tdls/core/src/wlan_tdls_mgmt.c index 902d5c13c0..b5961e62ee 100644 --- a/components/tdls/core/src/wlan_tdls_mgmt.c +++ b/components/tdls/core/src/wlan_tdls_mgmt.c @@ -134,6 +134,47 @@ tdls_process_mlo_cal_tdls_link_score(struct wlan_objmgr_vdev *vdev) return status; } +/** + * tdls_check_wait_more() - wait until the timer timeout if necessary + * @vdev: vdev object + * + * Return: true if need to wait else false + */ +static bool tdls_check_wait_more(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_mlo_dev_context *mlo_dev_ctx; + struct wlan_objmgr_vdev *mlo_vdev; + struct tdls_vdev_priv_obj *tdls_vdev; + /* expect response number */ + int expect_num; + /* received response number */ + int receive_num; + int i; + + expect_num = 0; + receive_num = 0; + mlo_dev_ctx = vdev->mlo_dev_ctx; + for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { + mlo_vdev = mlo_dev_ctx->wlan_vdev_list[i]; + if (!mlo_vdev) + continue; + + expect_num++; + + tdls_vdev = + wlan_objmgr_vdev_get_comp_private_obj(mlo_vdev, + WLAN_UMAC_COMP_TDLS); + if (tdls_vdev->rx_mgmt) + receive_num++; + } + + /* +1 means the one received last has not been recorded */ + if (expect_num > receive_num + 1) + return true; + else + return false; +} + struct wlan_objmgr_vdev * tdls_process_mlo_choice_tdls_vdev(struct wlan_objmgr_vdev *vdev) { @@ -260,6 +301,7 @@ tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj *tdls_soc, struct wlan_objmgr_vdev *mlo_vdev; struct wlan_mlo_dev_context *mlo_dev_ctx; bool peer_mlo; + bool waitmore = false; uint8_t i; vdev = tdls_vdev->vdev; @@ -303,9 +345,17 @@ tdls_process_mlo_rx_mgmt_sync(struct tdls_soc_priv_obj *tdls_soc, goto exit; } - tdls_vdev->discovery_sent_cnt = 0; - qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); - qdf_atomic_dec(&tdls_soc->timer_cnt); + if (qdf_atomic_read(&tdls_soc->timer_cnt) == 1) + waitmore = tdls_check_wait_more(vdev); + + if (waitmore) { + /* do not stop the timer */ + tdls_debug("wait more tdls response"); + } else { + tdls_vdev->discovery_sent_cnt = 0; + qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); + qdf_atomic_dec(&tdls_soc->timer_cnt); + } tdls_vdev->rx_mgmt = qdf_mem_malloc_atomic(sizeof(*rx_mgmt) + rx_mgmt->frame_len); diff --git a/components/tdls/core/src/wlan_tdls_peer.c b/components/tdls/core/src/wlan_tdls_peer.c index 11e6a6ba54..90acd3502c 100644 --- a/components/tdls/core/src/wlan_tdls_peer.c +++ b/components/tdls/core/src/wlan_tdls_peer.c @@ -886,11 +886,11 @@ void tdls_set_peer_link_status(struct tdls_peer *peer, struct tdls_vdev_priv_obj *vdev_obj; enum tdls_link_state old_status; - tdls_debug("state %d reason %d peer:" QDF_MAC_ADDR_FMT, - link_status, link_reason, + vdev_obj = peer->vdev_priv; + tdls_debug("vdev %d state %d reason %d peer:" QDF_MAC_ADDR_FMT, + wlan_vdev_get_id(vdev_obj->vdev), link_status, link_reason, QDF_MAC_ADDR_REF(peer->peer_mac.bytes)); - vdev_obj = peer->vdev_priv; old_status = peer->link_status; peer->link_status = link_status; tdls_update_pmo_status(vdev_obj, old_status, link_status);