From e9706cc3bf8350d26b2b8f118d7105201ec5907b Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Thu, 12 Oct 2017 17:25:06 +0530 Subject: [PATCH] qcacld-3.0: Wait for discon to complete, even if dicon req isn't queued If SME is in disconnecting state disconnect from supplicant will not get queued. Thus supplicant can start a connect req as soon as HDD returns from disconnect req. If this connect req is processed by HDD before the SME disconnect is indicated to HDD, it will cause HDD/supplicant and SME out of sync. This results into scan allowed even when SME is waiting for key. SME will not allow scan until set key is completed, which may not happened as HDD has indicated disconnect to supplicant after connect was received by HDD. This will eventually lead to HDD scan inactivity timer to expire. To fix this wait for WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS time in HDD for SME disconnect to get processed before returning. Change-Id: I21f2c2e2f9b97fc50f9ac43bc5bbb5fd5188f3b7 CRs-Fixed: 2125636 --- core/hdd/inc/wlan_hdd_main.h | 1 + core/hdd/src/wlan_hdd_cfg80211.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index dd92ebe95a12..40af514e8761 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -161,6 +161,7 @@ #else #define WLAN_WAIT_TIME_DISCONNECT 5000 #endif +#define WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS 1000 #define WLAN_WAIT_TIME_STOP_ROAM 4000 #define WLAN_WAIT_TIME_STATS 800 #define WLAN_WAIT_TIME_POWER 800 diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 3f8e565bc14f..e10d60c162f6 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -17207,6 +17207,7 @@ static int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason) struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); eConnectionState prev_conn_state; tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); + uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT; ENTER(); @@ -17264,7 +17265,14 @@ static int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason) prev_conn_state != eConnectionState_Connecting) { hdd_debug("status = %d, already disconnected", status); result = 0; - goto disconnected; + /* + * Wait here instead of returning directly. This will block the + * next connect command and allow processing of the disconnect + * in SME else we might hit some race conditions leading to SME + * and HDD out of sync. As disconnect is already in progress, + * wait here for 1 sec instead of 5 sec. + */ + wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS; } else if (QDF_STATUS_CMD_NOT_QUEUED == status) { /* * Wait here instead of returning directly, this will block the @@ -17281,8 +17289,7 @@ static int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason) } wait_for_disconnect: rc = wait_for_completion_timeout(&adapter->disconnect_comp_var, - msecs_to_jiffies - (WLAN_WAIT_TIME_DISCONNECT)); + msecs_to_jiffies(wait_time)); if (!rc && (QDF_STATUS_CMD_NOT_QUEUED != status)) { hdd_err("Failed to disconnect, timed out");