Commit ea0a3cf9 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho

wlcore: force recovery on resume if suspended without recovering

If an error is detected after mac80211 is already suspended, the recovery
work will not be queued. This will leave the driver in a bad state on
resume.

Detect this in the resume op and re-queue a recovery.
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 1d23396d
...@@ -1707,7 +1707,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) ...@@ -1707,7 +1707,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
struct wl1271 *wl = hw->priv; struct wl1271 *wl = hw->priv;
struct wl12xx_vif *wlvif; struct wl12xx_vif *wlvif;
unsigned long flags; unsigned long flags;
bool run_irq_work = false; bool run_irq_work = false, pending_recovery;
wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
wl->wow_enabled); wl->wow_enabled);
...@@ -1723,17 +1723,33 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) ...@@ -1723,17 +1723,33 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
run_irq_work = true; run_irq_work = true;
spin_unlock_irqrestore(&wl->wl_lock, flags); spin_unlock_irqrestore(&wl->wl_lock, flags);
/* test the recovery flag before calling any SDIO functions */
pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
&wl->flags);
if (run_irq_work) { if (run_irq_work) {
wl1271_debug(DEBUG_MAC80211, wl1271_debug(DEBUG_MAC80211,
"run postponed irq_work directly"); "run postponed irq_work directly");
/* don't talk to the HW if recovery is pending */
if (!pending_recovery)
wl1271_irq(0, wl); wl1271_irq(0, wl);
wlcore_enable_interrupts(wl); wlcore_enable_interrupts(wl);
} }
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
if (pending_recovery) {
wl1271_warning("queuing forgotten recovery on resume");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
goto out;
}
wl12xx_for_each_wlvif(wl, wlvif) { wl12xx_for_each_wlvif(wl, wlvif) {
wl1271_configure_resume(wl, wlvif); wl1271_configure_resume(wl, wlvif);
} }
out:
wl->wow_enabled = false; wl->wow_enabled = false;
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment