From 59049c498647de524dc531cfe297c6c7d9de1905 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Tue, 21 Jan 2020 15:07:33 -0800 Subject: [PATCH 1/2] cnss2: Avoid idle restart completely if reboot is in progress Check if reboot is in progress at the beginning of idle restart in order to avoid it completely. Also check if reboot is in progress after wait_for_completion since the event can be completed in the same context of reboot notification and it needs to return failure for such cases to caller to avoid other issues. Change-Id: Iff250df5971ca4c9b885f52250547e2b45d89ac3 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 6971f7b94d1b..05a0f923ad22 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -628,6 +628,14 @@ int cnss_idle_restart(struct device *dev) cnss_pr_dbg("Doing idle restart\n"); + reinit_completion(&plat_priv->power_up_complete); + + if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) { + cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n"); + ret = -EINVAL; + goto out; + } + ret = cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_IDLE_RESTART, CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); @@ -640,20 +648,18 @@ int cnss_idle_restart(struct device *dev) } timeout = cnss_get_boot_timeout(dev); - - reinit_completion(&plat_priv->power_up_complete); - - if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) { - cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n"); - ret = -EINVAL; - goto out; - } - ret = wait_for_completion_timeout(&plat_priv->power_up_complete, msecs_to_jiffies(timeout) << 2); if (!ret) { cnss_pr_err("Timeout waiting for idle restart to complete\n"); - ret = -EAGAIN; + ret = -ETIMEDOUT; + goto out; + } + + if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) { + cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n"); + del_timer(&plat_priv->fw_boot_timer); + ret = -EINVAL; goto out; } From dcf8badf559d7d5fc68db5a1baff92fceb3e2bf6 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Wed, 5 Feb 2020 12:28:39 -0800 Subject: [PATCH 2/2] cnss2: Extend idle restart timeout WLAN driver has its own watchdog timer for idle restart, so extend idle restart timeout in platform driver to avoid timing out before WLAN driver. Change-Id: I4bab19fce7b30c59e9ecc0f0a8923a3693fdec12 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 05a0f923ad22..2b43c4c670b6 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -32,6 +32,7 @@ #define FW_ASSERT_TIMEOUT 5000 #define CNSS_EVENT_PENDING 2989 #define COLD_BOOT_CAL_SHUTDOWN_DELAY_MS 50 +#define WLAN_WD_TIMEOUT_MS 60000 #define CNSS_QUIRKS_DEFAULT BIT(DISABLE_IO_COHERENCY) #ifdef CONFIG_CNSS_EMULATION @@ -649,7 +650,8 @@ int cnss_idle_restart(struct device *dev) timeout = cnss_get_boot_timeout(dev); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, - msecs_to_jiffies(timeout) << 2); + msecs_to_jiffies((timeout << 1) + + WLAN_WD_TIMEOUT_MS)); if (!ret) { cnss_pr_err("Timeout waiting for idle restart to complete\n"); ret = -ETIMEDOUT;