Bläddra i källkod

qcacld-3.0: Stop MC thread during recovery

As part of Dynamic Mode change, optimization is added to not to
stop the MC thread but just to flush the message queues but that
doesn't help in case of recovery where in MC thread is the one
which needs to be stopped first so that lower layers doesn't try
to post any messages and try to process them while firmware
doesn't exist. Processing such messages may cause stability
issues.
Stop the MC thread as part of recovery and bring-up thread again
during re-init.

Change-Id: Ie1cfbfa74f6b3e849361f2213a9d29f277aa09cc
CRs-fixed: 1075224
Prashanth Bhatta 8 år sedan
förälder
incheckning
2ac92bda55

+ 2 - 1
core/cds/src/cds_api.c

@@ -247,7 +247,8 @@ QDF_STATUS cds_open(void)
 	}
 	/* Now Open the CDS Scheduler */
 
-	if (pHddCtx->driver_status == DRIVER_MODULES_UNINITIALIZED) {
+	if (pHddCtx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
+	    cds_is_driver_recovering()) {
 		qdf_status = cds_sched_open(gp_cds_context,
 					    &gp_cds_context->qdf_sched,
 					    sizeof(cds_sched_context));

+ 1 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -1865,7 +1865,7 @@ int hdd_start_ftm_adapter(hdd_adapter_t *adapter);
 int hdd_set_fw_params(hdd_adapter_t *adapter);
 int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
 			   bool reinit);
-int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown);
+int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx);
 int hdd_start_adapter(hdd_adapter_t *adapter);
 void hdd_connect_result(struct net_device *dev, const u8 *bssid,
 			tCsrRoamInfo *roam_info, const u8 *req_ie,

+ 8 - 8
core/hdd/src/wlan_hdd_main.c

@@ -4751,7 +4751,7 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx)
 		hdd_stop_all_adapters(hdd_ctx);
 	}
 
-	hdd_wlan_stop_modules(hdd_ctx, false);
+	hdd_wlan_stop_modules(hdd_ctx);
 	/*
 	 * Close the scheduler before calling cds_close to make sure no thread
 	 * is scheduled after the each module close is called i.e after all the
@@ -7618,7 +7618,6 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
 /**
  * hdd_wlan_stop_modules - Single driver state machine for stoping modules
  * @hdd_ctx: HDD context
- * @shutdown: flag to indicate from SSR or normal path
  *
  * This function maintains the driver state machine it will be invoked from
  * exit, shutdown and con_mode change handler. Depending on the driver state
@@ -7626,7 +7625,7 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx)
  *
  * Return: 0 for success; non-zero for failure
  */
-int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown)
+int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
 {
 	void *hif_ctx;
 	qdf_device_t qdf_ctx;
@@ -7688,7 +7687,8 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown)
 		QDF_ASSERT(0);
 	}
 	/* Clean up message queues of TX, RX and MC thread */
-	cds_sched_flush_mc_mqs(cds_sched_context);
+	if (!cds_is_driver_recovering())
+		cds_sched_flush_mc_mqs(cds_sched_context);
 
 	hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
 	if (!hif_ctx) {
@@ -7701,7 +7701,7 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool shutdown)
 
 	ol_cds_free();
 
-	if (!shutdown) {
+	if (!cds_is_driver_recovering()) {
 		ret = pld_power_off(qdf_ctx->dev);
 		if (ret)
 			hdd_err("CNSS power down failed put device into Low power mode:%d",
@@ -7738,7 +7738,7 @@ static void hdd_iface_change_callback(void *priv)
 
 	ENTER();
 	hdd_info("Interface change timer expired close the modules!");
-	ret = hdd_wlan_stop_modules(hdd_ctx, false);
+	ret = hdd_wlan_stop_modules(hdd_ctx);
 	if (ret)
 		hdd_alert("Failed to stop modules");
 	EXIT();
@@ -7990,7 +7990,7 @@ err_wiphy_unregister:
 	wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
 
 err_stop_modules:
-	hdd_wlan_stop_modules(hdd_ctx, false);
+	hdd_wlan_stop_modules(hdd_ctx);
 
 
 	status = cds_sched_close(hdd_ctx->pcds_context);
@@ -9289,7 +9289,7 @@ static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
 	hdd_stop_all_adapters(hdd_ctx);
 	hdd_deinit_all_adapters(hdd_ctx, false);
 
-	ret = hdd_wlan_stop_modules(hdd_ctx, false);
+	ret = hdd_wlan_stop_modules(hdd_ctx);
 	if (ret) {
 		hdd_err("Stop wlan modules failed");
 		return -EINVAL;

+ 9 - 4
core/hdd/src/wlan_hdd_power.c

@@ -1423,6 +1423,7 @@ QDF_STATUS hdd_wlan_shutdown(void)
 	v_CONTEXT_t p_cds_context = NULL;
 	hdd_context_t *pHddCtx;
 	p_cds_sched_context cds_sched_context = NULL;
+	QDF_STATUS qdf_status;
 
 	hdd_alert("WLAN driver shutting down!");
 
@@ -1444,8 +1445,6 @@ QDF_STATUS hdd_wlan_shutdown(void)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	cds_set_recovery_in_progress(true);
-
 	cds_clear_concurrent_session_count();
 	hdd_cleanup_scan_queue(pHddCtx);
 	hdd_reset_all_adapters(pHddCtx);
@@ -1471,8 +1470,14 @@ QDF_STATUS hdd_wlan_shutdown(void)
 	}
 #endif
 
+	qdf_status = cds_sched_close(p_cds_context);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		hdd_err("Failed to close CDS Scheduler");
+		QDF_ASSERT(false);
+	}
+
 	wlansap_global_deinit();
-	hdd_wlan_stop_modules(pHddCtx, true);
+	hdd_wlan_stop_modules(pHddCtx);
 
 	hdd_lpass_notify_stop(pHddCtx);
 
@@ -1574,7 +1579,7 @@ QDF_STATUS hdd_wlan_re_init(void)
 	goto success;
 
 err_cds_disable:
-	hdd_wlan_stop_modules(pHddCtx, true);
+	hdd_wlan_stop_modules(pHddCtx);
 
 err_wiphy_unregister:
 	if (pHddCtx) {