Browse Source

qcacld-3.0: Wait for driver recovery while WiFi ON/OFF

Currently the driver is not synchronized properly between SSR and wifi
ON/OFF. This causes a potential deadlock resulting in a DSC timeout.

To synchronize, add a wait in wlan_hdd_state_ctrl_param_write
which is called during WiFi ON/OFF. This wait will ensure that the
driver recovery is complete before proceeding with ON/OFF.

Change-Id: Ia1c4f8d7076d77c591276ee380b55a747cf606bd
CRs-Fixed: 2701513
Sourav Mohapatra 4 years ago
parent
commit
f1e669fdc6
3 changed files with 16 additions and 1 deletions
  1. 7 0
      core/hdd/inc/wlan_hdd_main.h
  2. 3 0
      core/hdd/src/wlan_hdd_driver_ops.c
  3. 6 1
      core/hdd/src/wlan_hdd_main.c

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

@@ -4430,4 +4430,11 @@ static inline void hdd_sta_destroy_ctx_all(struct hdd_context *hdd_ctx)
 }
 #endif
 
+/**
+ * hdd_init_start_completion() - Init the completion variable to wait on ON/OFF
+ *
+ * Return: None
+ */
+void hdd_init_start_completion(void);
+
 #endif /* end #if !defined(WLAN_HDD_MAIN_H) */

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

@@ -583,6 +583,7 @@ static int __hdd_soc_recovery_reinit(struct device *dev,
 	cds_set_recovery_in_progress(false);
 
 	hdd_soc_load_unlock(dev);
+	hdd_start_complete(0);
 
 	return 0;
 
@@ -593,6 +594,7 @@ assert_fail_count:
 unlock:
 	cds_set_driver_in_bad_state(true);
 	hdd_soc_load_unlock(dev);
+	hdd_start_complete(errno);
 
 	return check_for_probe_defer(errno);
 }
@@ -798,6 +800,7 @@ static void __hdd_soc_recovery_shutdown(void)
 
 	/* recovery starts via firmware down indication; ensure we got one */
 	QDF_BUG(cds_is_driver_recovering());
+	hdd_init_start_completion();
 
 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
 	if (!hdd_ctx) {

+ 6 - 1
core/hdd/src/wlan_hdd_main.c

@@ -14791,6 +14791,11 @@ static void hdd_inform_wifi_off(void)
 	ucfg_blm_wifi_off(hdd_ctx->pdev);
 }
 
+void hdd_init_start_completion(void)
+{
+	INIT_COMPLETION(wlan_start_comp);
+}
+
 static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
 						const char __user *user_buf,
 						size_t count,
@@ -14822,7 +14827,7 @@ static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
 		goto exit;
 	}
 
-	if (!cds_is_driver_loaded()) {
+	if (!cds_is_driver_loaded() || cds_is_driver_recovering()) {
 		rc = wait_for_completion_timeout(&wlan_start_comp,
 				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
 		if (!rc) {