summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArunk Khandavalli <akhandav@codeaurora.org>2016-09-27 21:51:01 +0530
committerqcabuildsw <qcabuildsw@localhost>2016-10-03 16:47:46 -0700
commit07ec8f6edae26b37a1c11ada6227fe91c262e318 (patch)
tree0b0733c55a954b1dbfe68a5c9ec700b84463a717
parent353be2f00dcd3a43e2df91cd16c34fd59f8ec238 (diff)
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
-rw-r--r--core/hdd/inc/wlan_hdd_main.h3
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c5
-rw-r--r--core/hdd/src/wlan_hdd_main.c24
3 files changed, 27 insertions, 5 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index b91fa4485477..76be402b99a8 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/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"
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index b42be5634d69..3a8a06dc156a 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/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);
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index ee901e69c39c..5049f1394b1b 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -8766,6 +8766,28 @@ out:
}
/**
+ * 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
*
* Module exit helper function used by both module and static driver.
@@ -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);