Browse Source

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
Abhishek Singh 7 years ago
parent
commit
e9706cc3bf
2 changed files with 11 additions and 3 deletions
  1. 1 0
      core/hdd/inc/wlan_hdd_main.h
  2. 10 3
      core/hdd/src/wlan_hdd_cfg80211.c

+ 1 - 0
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

+ 10 - 3
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");