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 @@ -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);