aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-06-21 11:10:49 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-23 02:32:31 -0400
commitea0a3cf95ed8839ce6f11bf9a050e6333bfc27d6 (patch)
tree0875b9b16efc71867399521662eb208f9147844a
parent1d23396d9df0a9543b2ba5c288f4914ad1f19e46 (diff)
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: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 0df28d5cb331..0b51522d8eae 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1707,7 +1707,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1707 struct wl1271 *wl = hw->priv; 1707 struct wl1271 *wl = hw->priv;
1708 struct wl12xx_vif *wlvif; 1708 struct wl12xx_vif *wlvif;
1709 unsigned long flags; 1709 unsigned long flags;
1710 bool run_irq_work = false; 1710 bool run_irq_work = false, pending_recovery;
1711 1711
1712 wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", 1712 wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
1713 wl->wow_enabled); 1713 wl->wow_enabled);
@@ -1723,17 +1723,33 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1723 run_irq_work = true; 1723 run_irq_work = true;
1724 spin_unlock_irqrestore(&wl->wl_lock, flags); 1724 spin_unlock_irqrestore(&wl->wl_lock, flags);
1725 1725
1726 /* test the recovery flag before calling any SDIO functions */
1727 pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
1728 &wl->flags);
1729
1726 if (run_irq_work) { 1730 if (run_irq_work) {
1727 wl1271_debug(DEBUG_MAC80211, 1731 wl1271_debug(DEBUG_MAC80211,
1728 "run postponed irq_work directly"); 1732 "run postponed irq_work directly");
1729 wl1271_irq(0, wl); 1733
1734 /* don't talk to the HW if recovery is pending */
1735 if (!pending_recovery)
1736 wl1271_irq(0, wl);
1737
1730 wlcore_enable_interrupts(wl); 1738 wlcore_enable_interrupts(wl);
1731 } 1739 }
1732 1740
1733 mutex_lock(&wl->mutex); 1741 mutex_lock(&wl->mutex);
1742 if (pending_recovery) {
1743 wl1271_warning("queuing forgotten recovery on resume");
1744 ieee80211_queue_work(wl->hw, &wl->recovery_work);
1745 goto out;
1746 }
1747
1734 wl12xx_for_each_wlvif(wl, wlvif) { 1748 wl12xx_for_each_wlvif(wl, wlvif) {
1735 wl1271_configure_resume(wl, wlvif); 1749 wl1271_configure_resume(wl, wlvif);
1736 } 1750 }
1751
1752out:
1737 wl->wow_enabled = false; 1753 wl->wow_enabled = false;
1738 mutex_unlock(&wl->mutex); 1754 mutex_unlock(&wl->mutex);
1739 1755