summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAbhinav Kumar <abhikuma@codeaurora.org>2020-03-05 15:02:30 +0530
committerIsaac Chiou <isaacchiou@google.com>2020-07-15 06:24:51 +0000
commitc2a7e0a86ae97290f1eb9a42ddc2ed0c62c63c7a (patch)
tree70aac813d70f2b05c35fca9f891a621d0369dbcb /core
parente6b769be80938e5a974a2ac96d2cb70ae5ed3ef9 (diff)
downloadqcacld-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.c7
-rw-r--r--core/sme/inc/csr_neighbor_roam.h27
-rw-r--r--core/sme/src/common/sme_api.c67
-rw-r--r--core/sme/src/csr/csr_api_roam.c89
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