Browse Source

qcacld-3.0: wait for driver recovery to complete before driver unload

As part driver shutdown cds recovery inprogress is set and it is cleared
once the driver recovery is completed. In the case of the SAP ssr
network manager tries to unload/reload once the network queues/carrier
is turned off. In the module exit the driver is unregistering the
driver ops because of which platform driver is not able to invoke the
re-init of the driver and re-init completed flag is never set.
Once the driver unregisters with platform driver it invokes the
remove function in which driver is waiting infinitely for the
reinit to complete.

To mitigate the issue wait for driver recovery to complete before starting
the driver unload.

Change-Id: I1879f7dc4b09d3eef6475252f6209339351c5737
CRs-Fixed: 1072677
Arunk Khandavalli 8 years ago
parent
commit
07ec8f6eda
3 changed files with 27 additions and 5 deletions
  1. 3 0
      core/hdd/inc/wlan_hdd_main.h
  2. 0 5
      core/hdd/src/wlan_hdd_driver_ops.c
  3. 24 0
      core/hdd/src/wlan_hdd_main.c

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

@@ -156,6 +156,9 @@
 
 #define MAX_CFG_STRING_LEN  255
 
+/* SSR Retry Count */
+#define HDD_MOD_EXIT_SSR_MAX_RETRIES 75
+
 #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 /** Mac Address string **/
 #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"

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

@@ -417,11 +417,6 @@ static void wlan_hdd_remove(struct device *dev)
 	pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
 		QWLAN_VERSIONSTR);
 
-	/* Wait for recovery to complete */
-	while (cds_is_driver_recovering()) {
-		hdd_alert("Recovery in progress; wait here!!!");
-		msleep(1000);
-	}
 
 	cds_set_driver_loaded(false);
 	cds_set_unload_in_progress(true);

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

@@ -8765,6 +8765,28 @@ out:
 	return ret;
 }
 
+/**
+ * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
+ *
+ * Block the unloading of the driver until the cds recovery is completed
+ *
+ * Return: None
+ */
+static void hdd_wait_for_recovery_completion(void)
+{
+	int retry = 0;
+
+	/* Wait for recovery to complete */
+	while (cds_is_driver_recovering()) {
+		hdd_alert("Recovery in progress; wait here!!!");
+		msleep(1000);
+		if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
+			hdd_alert("SSR never completed, fatal error");
+			QDF_BUG(0);
+		}
+	}
+}
+
 /**
  * __hdd_module_exit - Module exit helper
  *
@@ -8775,6 +8797,8 @@ static void __hdd_module_exit(void)
 	pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
 		QWLAN_VERSIONSTR);
 
+	hdd_wait_for_recovery_completion();
+
 	wlan_hdd_unregister_driver();
 
 	qdf_wake_lock_destroy(&wlan_wake_lock);