wil6210: fix no_fw_recovery mode with change_virtual_intf
authorLior David <qca_liord@qca.qualcomm.com>
Tue, 1 Mar 2016 17:18:16 +0000 (19:18 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 7 Mar 2016 09:43:20 +0000 (11:43 +0200)
When FW crashed with no_fw_recovery mode enabled, user space
could still call wil_cfg80211_change_iface quickly to change
interface type, and this would cause recovery to proceed and
FW crash logs may be lost.
Fix this problem by not resetting the FW in case no_fw_recovery
is enabled.

Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/cfg80211.c
drivers/net/wireless/ath/wil6210/interrupt.c
drivers/net/wireless/ath/wil6210/main.c
drivers/net/wireless/ath/wil6210/wil6210.h

index e867c76a4197c1b1f8eced41bdceb6128ba2bd98..33e54519602fabf5c6eb9be68bb434f13088aafd 100644 (file)
@@ -306,7 +306,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
 
        wil_dbg_misc(wil, "%s() type=%d\n", __func__, type);
 
-       if (netif_running(wil_to_ndev(wil))) {
+       if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) {
                wil_dbg_misc(wil, "interface is up. resetting...\n");
                mutex_lock(&wil->mutex);
                __wil_down(wil);
index ae902958bf552bceae7055747c2e5e845da83f88..fe66b2b646f0c10aa2dc07c84da31c30d9e02cc3 100644 (file)
@@ -391,6 +391,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
        wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
 
        if (isr & ISR_MISC_FW_ERROR) {
+               wil->recovery_state = fw_recovery_pending;
                wil_fw_core_dump(wil);
                wil_notify_fw_error(wil);
                isr &= ~ISR_MISC_FW_ERROR;
index 05a4ae7a77650bbab2d141670b574be56e93b737..c2a0a662525255c2db5e404d2f02dc0f6bdcb5cd 100644 (file)
@@ -305,6 +305,11 @@ void wil_set_recovery_state(struct wil6210_priv *wil, int state)
        wake_up_interruptible(&wil->wq);
 }
 
+bool wil_is_recovery_blocked(struct wil6210_priv *wil)
+{
+       return no_fw_recovery && (wil->recovery_state == fw_recovery_pending);
+}
+
 static void wil_fw_error_worker(struct work_struct *work)
 {
        struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
index 68f60eadde13344aa90881ff1e7d1b7f5bf94550..a23dcee886a05601c0c392de8e4c64c03c7ccaa7 100644 (file)
@@ -716,6 +716,7 @@ void wil_priv_deinit(struct wil6210_priv *wil);
 int wil_reset(struct wil6210_priv *wil, bool no_fw);
 void wil_fw_error_recovery(struct wil6210_priv *wil);
 void wil_set_recovery_state(struct wil6210_priv *wil, int state);
+bool wil_is_recovery_blocked(struct wil6210_priv *wil);
 int wil_up(struct wil6210_priv *wil);
 int __wil_up(struct wil6210_priv *wil);
 int wil_down(struct wil6210_priv *wil);
This page took 0.027508 seconds and 5 git commands to generate.