Browse Source

qcacld-3.0: Do not allow disconnect during roaming

The roam synch indication processing cleans up the entire stack
with respect to the old peer and establishes the context of
the new peer. A disconnect request from upper layer during the
roam synch processing would cleanup old peer context partially
and request be queued to the PE queue to be processed further.
The roam synch indication processing resumes and picks up the
semi-cleaned context of the old peer.
So, do not allow disconnect if roaming is in progress.
Set the roaming in progress flag when is a ROAM START
is indicated by the firmware. Reset the flag once the
roaming is complete or even if it failed for some reason.
During the period when the flag is set, do not allow
disconnections from upper layers to go through.

Change-Id: If7cc92b25e2330f4280c7bf32c1ddd88fd4a510f
CRs-Fixed: 1091054
Varun Reddy Yeturu 8 years ago
parent
commit
dce1c564b8
3 changed files with 52 additions and 0 deletions
  1. 4 0
      core/hdd/inc/wlan_hdd_main.h
  2. 3 0
      core/hdd/src/wlan_hdd_assoc.c
  3. 45 0
      core/hdd/src/wlan_hdd_main.c

+ 4 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1570,6 +1570,7 @@ struct hdd_context_s {
 	struct hdd_runtime_pm_context runtime_context;
 	/* bit map to set/reset TDLS by different sources */
 	unsigned long tdls_source_bitmap;
+	bool roaming_in_progress;
 };
 
 /*---------------------------------------------------------------------------
@@ -1988,4 +1989,7 @@ static inline int wlan_hdd_validate_session_id(u8 session_id)
 	return -EINVAL;
 }
 
+bool hdd_is_roaming_in_progress(void);
+void hdd_set_roaming_in_progress(bool value);
+
 #endif /* end #if !defined(WLAN_HDD_MAIN_H) */

+ 3 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -4651,6 +4651,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
 	case eCSR_ROAM_NAPI_OFF:
 		hdd_info("After Roam Synch Comp: NAPI Serialize OFF");
 		hdd_napi_serialize(0);
+		hdd_set_roaming_in_progress(false);
 		break;
 	case eCSR_ROAM_SHOULD_ROAM:
 		/* notify apps that we can't pass traffic anymore */
@@ -4938,6 +4939,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
 				WLAN_CONTROL_PATH);
 		hdd_napi_serialize(1);
 		cds_set_connection_in_progress(true);
+		hdd_set_roaming_in_progress(true);
 		cds_restart_opportunistic_timer(true);
 		break;
 	case eCSR_ROAM_ABORT:
@@ -4947,6 +4949,7 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
 				WLAN_WAKE_ALL_NETIF_QUEUE,
 				WLAN_CONTROL_PATH);
 		cds_set_connection_in_progress(false);
+		hdd_set_roaming_in_progress(false);
 		break;
 
 	default:

+ 45 - 0
core/hdd/src/wlan_hdd_main.c

@@ -589,6 +589,11 @@ int wlan_hdd_validate_context(hdd_context_t *hdd_ctx)
 		return -EAGAIN;
 	}
 
+	if (hdd_is_roaming_in_progress()) {
+		hdd_err("Roaming In Progress. Ignore!!!");
+		return -EAGAIN;
+	}
+
 	return 0;
 }
 
@@ -9824,6 +9829,46 @@ int hdd_enable_disable_ca_event(hdd_context_t *hddctx, uint8_t set_value)
 	return 0;
 }
 
+/**
+ * hdd_set_roaming_in_progress() - to set the roaming in progress flag
+ * @value: value to set
+ *
+ * This function will set the passed value to roaming in progress flag.
+ *
+ * Return: None
+ */
+void hdd_set_roaming_in_progress(bool value)
+{
+	hdd_context_t *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	hdd_ctx->roaming_in_progress = value;
+	hdd_info("Roaming in Progress set to %d", value);
+}
+
+/**
+ * hdd_is_roaming_in_progress() - check if roaming is in progress
+ * @hdd_ctx - HDD context
+ *
+ * Return: true if roaming is in progress else false
+ */
+bool hdd_is_roaming_in_progress(void)
+{
+	hdd_context_t *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return false;
+	}
+	return hdd_ctx->roaming_in_progress;
+}
+
 /* Register the module init/exit functions */
 module_init(hdd_module_init);
 module_exit(hdd_module_exit);