diff options
author | Abhinav Kumar <abhikuma@codeaurora.org> | 2020-03-05 15:02:30 +0530 |
---|---|---|
committer | Isaac Chiou <isaacchiou@google.com> | 2020-07-15 06:24:51 +0000 |
commit | c2a7e0a86ae97290f1eb9a42ddc2ed0c62c63c7a (patch) | |
tree | 70aac813d70f2b05c35fca9f891a621d0369dbcb /core | |
parent | e6b769be80938e5a974a2ac96d2cb70ae5ed3ef9 (diff) | |
download | qcacld-c2a7e0a86ae97290f1eb9a42ddc2ed0c62c63c7a.tar.gz |
qcacld-3.0: Fix race between wpa_supplicant and scheduler_thread
Driver receives roam invoke command from supplicant, Host start
processing it in wpa_supplicant thread and sends ROAM_INVOKE
command to firmware. FW indicates roam invoke failure, so host
clean up the AP (Disconnect). But wpa_supplicant did not get
scheduled till disconnection completion. After disconnection,
wpa_supplicant thread gets resume and sets the roaming in progress
true. This results in roaming in progress remain set in a
disconnection state.
sme_fast_reassoc should be protected with sme lock to avoid
the race between SB disconnect and sme_fast_reassoc.
Fix is to protect sme_fast_reassoc with sme lock and
set roaming in progress flag before sending sme_fast_reassoc
command to FW and reset it again if sme_fast_reassoc fail to
initiate the roam invoke.
Bug: 157172156
Change-Id: I05d92f8d5916decbd2c6f99eb67da0a29525ead5
CRs-Fixed: 2608398
Diffstat (limited to 'core')
-rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 7 | ||||
-rw-r--r-- | core/sme/inc/csr_neighbor_roam.h | 27 | ||||
-rw-r--r-- | core/sme/src/common/sme_api.c | 67 | ||||
-rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 89 |
4 files changed, 132 insertions, 58 deletions
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6ca2c12c49..5ccd7d5892 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -18388,9 +18388,14 @@ static bool wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter, qdf_mem_copy(wext_state->req_bssId.bytes, bssid, QDF_MAC_ADDR_SIZE); + hdd_set_roaming_in_progress(true); *status = hdd_reassoc(adapter, bssid, channel, CONNECT_CMD_USERSPACE); hdd_debug("hdd_reassoc: status: %d", *status); + if (status) + hdd_set_roaming_in_progress(false); + + hdd_debug("hdd_reassoc: status: %d", status); } return reassoc; } diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index 001b81a4e1..441289aa60 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -393,6 +393,22 @@ QDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp, QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason); + +/** + * csr_fast_reassoc() - invokes FAST REASSOC command + * @hal: handle returned by mac_open + * @profile: current connected profile + * @bssid: bssid to look for in scan cache + * @ch_freq: channel on which reassoc should be send + * @vdev_id: vdev id + * @connected_bssid: bssid of currently connected profile + * + * Return: QDF_STATUS + */ +QDF_STATUS csr_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile, + const tSirMacAddr bssid, int channel, + uint8_t vdev_id, const tSirMacAddr connected_bssid); + #else static inline QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, @@ -400,6 +416,15 @@ static inline QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac, { return QDF_STATUS_E_NOSUPPORT; } + +static inline +QDF_STATUS csr_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile, + const tSirMacAddr bssid, int channel, + uint8_t vdev_id, const tSirMacAddr connected_bssid) +{ + return QDF_STATUS_SUCCESS; +} + #endif void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx, uint8_t newstate, uint8_t session); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index f016409908..8603d322fb 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -19257,65 +19257,22 @@ QDF_STATUS sme_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile, const tSirMacAddr bssid, int channel, uint8_t vdev_id, const tSirMacAddr connected_bssid) { - QDF_STATUS status; - struct wma_roam_invoke_cmd *fastreassoc; - cds_msg_t msg = {0}; + QDF_STATUS status = QDF_STATUS_E_FAILURE; tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); - fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc)); - if (NULL == fastreassoc) { - sme_err("qdf_mem_malloc failed for fastreassoc"); - return QDF_STATUS_E_NOMEM; - } - /* if both are same then set the flag */ - if (!qdf_mem_cmp(connected_bssid, bssid, ETH_ALEN)) { - fastreassoc->is_same_bssid = true; - sme_debug("bssid same, bssid[%pM]", bssid); - } - fastreassoc->vdev_id = vdev_id; - fastreassoc->bssid[0] = bssid[0]; - fastreassoc->bssid[1] = bssid[1]; - fastreassoc->bssid[2] = bssid[2]; - fastreassoc->bssid[3] = bssid[3]; - fastreassoc->bssid[4] = bssid[4]; - fastreassoc->bssid[5] = bssid[5]; - - status = sme_get_beacon_frm(hal, profile, bssid, - &fastreassoc->frame_buf, - &fastreassoc->frame_len, - &channel); - - if (!channel) { - sme_err("channel retrieval from BSS desc fails!"); - qdf_mem_free(fastreassoc); - return QDF_STATUS_E_FAULT; - } + if (!mac_ctx) + return QDF_STATUS_E_FAILURE; - fastreassoc->channel = channel; - if (QDF_STATUS_SUCCESS != status) { - sme_warn("sme_get_beacon_frm failed"); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; - } - - if (csr_is_auth_type_ese(mac_ctx->roam.roamSession[vdev_id]. - connectedProfile.AuthType)) { - sme_debug("Beacon is not required for ESE"); - if (fastreassoc->frame_len) { - qdf_mem_free(fastreassoc->frame_buf); - fastreassoc->frame_buf = NULL; - fastreassoc->frame_len = 0; - } + if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { + sme_err("Invalid vdev_id: %d", vdev_id); + return QDF_STATUS_E_INVAL; } - msg.type = SIR_HAL_ROAM_INVOKE; - msg.reserved = 0; - msg.bodyptr = fastreassoc; - status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); - if (QDF_STATUS_SUCCESS != status) { - sme_err("Not able to post ROAM_INVOKE_CMD message to WMA"); - qdf_mem_free(fastreassoc); - } + if (QDF_IS_STATUS_ERROR(sme_acquire_global_lock(&mac_ctx->sme))) + return QDF_STATUS_E_FAILURE; + status = csr_fast_reassoc(hal, profile, bssid, channel, vdev_id, + connected_bssid); + sme_release_global_lock(&mac_ctx->sme); return status; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 1c924e08fc..2719d629d9 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -19603,6 +19603,93 @@ csr_create_per_roam_request(tpAniSirGlobal mac_ctx, uint8_t session_id) return req_buf; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +QDF_STATUS csr_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile, + const tSirMacAddr bssid, int channel, + uint8_t vdev_id, const tSirMacAddr connected_bssid) +{ + QDF_STATUS status; + struct wma_roam_invoke_cmd *fastreassoc; + cds_msg_t msg = {0}; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + tCsrRoamSession *session; + + session = CSR_GET_SESSION(mac_ctx, vdev_id); + if (!session || !session->pCurRoamProfile) { + sme_err("session %d not found", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + if (!csr_is_conn_state_connected(mac_ctx, vdev_id)) { + sme_debug("Not in connected state, Roam Invoke not sent"); + return QDF_STATUS_E_FAILURE; + } + + if (session->pCurRoamProfile->driver_disabled_roaming) { + sme_debug("roaming status in driver %d", + session->pCurRoamProfile->driver_disabled_roaming); + return QDF_STATUS_E_FAILURE; + } + + fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc)); + if (NULL == fastreassoc) { + sme_err("qdf_mem_malloc failed for fastreassoc"); + return QDF_STATUS_E_NOMEM; + } + /* if both are same then set the flag */ + if (!qdf_mem_cmp(connected_bssid, bssid, ETH_ALEN)) { + fastreassoc->is_same_bssid = true; + sme_debug("bssid same, bssid[%pM]", bssid); + } + fastreassoc->vdev_id = vdev_id; + fastreassoc->bssid[0] = bssid[0]; + fastreassoc->bssid[1] = bssid[1]; + fastreassoc->bssid[2] = bssid[2]; + fastreassoc->bssid[3] = bssid[3]; + fastreassoc->bssid[4] = bssid[4]; + fastreassoc->bssid[5] = bssid[5]; + + status = sme_get_beacon_frm(hal, profile, bssid, + &fastreassoc->frame_buf, + &fastreassoc->frame_len, + &channel); + + if (!channel) { + sme_err("channel retrieval from BSS desc fails!"); + qdf_mem_free(fastreassoc); + return QDF_STATUS_E_FAULT; + } + + fastreassoc->channel = channel; + if (QDF_STATUS_SUCCESS != status) { + sme_warn("sme_get_beacon_frm failed"); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + } + + if (csr_is_auth_type_ese(mac_ctx->roam.roamSession[vdev_id]. + connectedProfile.AuthType)) { + sme_debug("Beacon is not required for ESE"); + if (fastreassoc->frame_len) { + qdf_mem_free(fastreassoc->frame_buf); + fastreassoc->frame_buf = NULL; + fastreassoc->frame_len = 0; + } + } + + msg.type = eWNI_SME_ROAM_INVOKE; + msg.reserved = 0; + msg.bodyptr = fastreassoc; + status = cds_mq_post_message(QDF_MODULE_ID_PE, &msg); + if (QDF_STATUS_SUCCESS != status) { + sme_err("Not able to post ROAM_INVOKE_CMD message to PE"); + qdf_mem_free(fastreassoc); + } + + return status; +} +#endif + /** * csr_roam_offload_per_scan() - populates roam offload scan request and sends * to WMA |