Browse Source

qcacld-3.0: Drop roam sync indication if user disconnect is in progress

Roam sync indication checks for csr roam state to determine if user
disconnect is not in progress. But there can be a race condition
where the csr roam state is not updated by disconnect and while
roam sync check the state and proceed.

To fix this set the disconnect in progress flag in sme session
as soon as disconnect starts in HDD and use that to determine if user
disconnect is not in progress when roam sync is received.

Change-Id: Icf541b698eb194621d19b03f281ec3dfd552e373
CRs-Fixed: 2112912
Abhishek Singh 7 years ago
parent
commit
d568647705

+ 2 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -16690,6 +16690,7 @@ int wlan_hdd_try_disconnect(struct hdd_adapter *pAdapter)
 	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 	hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
 	if (pAdapter->device_mode ==  QDF_STA_MODE) {
+		sme_indicate_disconnect_inprogress(hal, pAdapter->sessionId);
 		hdd_debug("Stop firmware roaming");
 		sme_stop_roaming(hal, pAdapter->sessionId, eCsrForcedDisassoc);
 
@@ -17083,6 +17084,7 @@ static int wlan_hdd_disconnect(struct hdd_adapter *pAdapter, u16 reason)
 	if (0 != status)
 		return status;
 	if (pAdapter->device_mode ==  QDF_STA_MODE) {
+		sme_indicate_disconnect_inprogress(hal, pAdapter->sessionId);
 		hdd_debug("Stop firmware roaming");
 		status = sme_stop_roaming(hal, pAdapter->sessionId,
 				eCsrForcedDisassoc);

+ 1 - 0
core/sme/inc/csr_internal.h

@@ -988,6 +988,7 @@ struct csr_roam_session {
 	qdf_mc_timer_t roaming_offload_timer;
 	bool is_fils_connection;
 	uint16_t fils_seq_num;
+	bool discon_in_progress;
 	struct csr_disconnect_stats disconnect_stats;
 };
 

+ 10 - 0
core/sme/inc/sme_api.h

@@ -595,6 +595,16 @@ QDF_STATUS sme_config_fast_roaming(tHalHandle hal, uint8_t session_id,
 QDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal,
 		const bool MAWCEnabled);
 QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason);
+
+/**
+ * sme_indicate_disconnect_inprogress() - Indicate to csr that disconnect is in
+ * progress
+ * @hal: The handle returned by mac_open
+ * @session_id: sessionId on which disconenct has started
+ *
+ * Return: void
+ */
+void sme_indicate_disconnect_inprogress(tHalHandle hal, uint8_t session_id);
 QDF_STATUS sme_start_roaming(tHalHandle hHal, uint8_t sessionId,
 		uint8_t reason);
 QDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal,

+ 17 - 0
core/sme/src/common/sme_api.c

@@ -7997,6 +7997,23 @@ QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason)
 	return QDF_STATUS_SUCCESS;
 }
 
+void sme_indicate_disconnect_inprogress(tHalHandle hal, uint8_t session_id)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct csr_roam_session *session;
+
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+			session = CSR_GET_SESSION(mac_ctx, session_id);
+			if (session)
+				session->discon_in_progress = true;
+		}
+		sme_release_global_lock(&mac_ctx->sme);
+	}
+}
+
 /*--------------------------------------------------------------------------
    \brief sme_start_roaming() - Start roaming for a given sessionId
    This is a synchronous call

+ 5 - 2
core/sme/src/csr/csr_api_roam.c

@@ -8318,6 +8318,7 @@ QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
 
 	/* Initialize the count before proceeding with the Join requests */
 	pSession->join_bssid_count = 0;
+	pSession->discon_in_progress = false;
 	pSession->is_fils_connection = csr_is_fils_connection(pProfile);
 	sme_debug(
 		"called  BSSType = %s (%d) authtype = %d  encryType = %d",
@@ -20546,9 +20547,11 @@ static QDF_STATUS csr_process_roam_sync_callback(tpAniSirGlobal mac_ctx,
 		 */
 		csr_roam_roaming_offload_timer_action(mac_ctx,
 				0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
-		if (!CSR_IS_ROAM_JOINED(mac_ctx, session_id)) {
+		if (session->discon_in_progress ||
+		    !CSR_IS_ROAM_JOINED(mac_ctx, session_id)) {
 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-				FL("LFR3: Session not in connected state"));
+				FL("LFR3: Session not in connected state or disconnect is in progress %d"),
+				session->discon_in_progress);
 			return QDF_STATUS_E_FAILURE;
 		}
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,