wil6210: prevent access to 11AD device if resume fails
authorMaya Erez <qca_merez@qca.qualcomm.com>
Wed, 5 Apr 2017 11:58:14 +0000 (14:58 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 13 Apr 2017 12:46:26 +0000 (15:46 +0300)
In case wil6210 resume fails, wil6210 suspend function will try
to access the suspended device in the next kernel suspend.
To prevent that, add wil_status_suspended flag to indicate if the
device is already suspended and clear it only if the resume succeeds.

Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/pm.c
drivers/net/wireless/ath/wil6210/wil6210.h

index 7260bef..2ae4fe8 100644 (file)
@@ -71,6 +71,11 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
 
        wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
 
+       if (test_bit(wil_status_suspended, wil->status)) {
+               wil_dbg_pm(wil, "trying to suspend while suspended\n");
+               return 0;
+       }
+
        /* if netif up, hardware is alive, shut it down */
        if (ndev->flags & IFF_UP) {
                rc = wil_down(wil);
@@ -86,10 +91,14 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
 
        if (wil->platform_ops.suspend) {
                rc = wil->platform_ops.suspend(wil->platform_handle);
-               if (rc)
+               if (rc) {
                        wil_enable_irq(wil);
+                       goto out;
+               }
        }
 
+       set_bit(wil_status_suspended, wil->status);
+
 out:
        wil_dbg_pm(wil, "suspend: %s => %d\n",
                   is_runtime ? "runtime" : "system", rc);
@@ -117,10 +126,13 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
 
        /* if netif up, bring hardware up
         * During open(), IFF_UP set after actual device method
-        * invocation. This prevent recursive call to wil_up()
+        * invocation. This prevent recursive call to wil_up().
+        * wil_status_suspended will be cleared in wil_reset
         */
        if (ndev->flags & IFF_UP)
                rc = wil_up(wil);
+       else
+               clear_bit(wil_status_suspended, wil->status);
 
 out:
        wil_dbg_pm(wil, "resume: %s => %d\n",
index ec646d7..b00c803 100644 (file)
@@ -412,6 +412,7 @@ enum { /* for wil6210_priv.status */
        wil_status_irqen, /* FIXME: interrupts enabled - for debug */
        wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
        wil_status_resetting, /* reset in progress */
+       wil_status_suspended, /* suspend completed, device is suspended */
        wil_status_last /* keep last */
 };