summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
authorIdo Yariv <ido@wizery.com>2011-06-06 14:57:05 +0300
committerLuciano Coelho <coelho@ti.com>2011-06-27 15:05:15 +0300
commitbaacb9aed020b890ddf6a57837a169092a25fc9b (patch)
treea961d0ce3773f29b419f97715863fea151f3ecf4 /drivers/net/wireless/wl12xx/main.c
parent842f1a6c71551ac10fbdff4a4e65821228df9ea7 (diff)
wl12xx: Avoid recovery while one is already in progress
During recovery work commands sent to the FW could fail and schedule additional recovery work. Since the chip is going to be powered off, avoid recursive recoveries. Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 2c03b4716d3f..6926d0a3e5c6 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -937,7 +937,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
wl1271_error("watchdog interrupt received! "
"starting recovery.");
- ieee80211_queue_work(wl->hw, &wl->recovery_work);
+ wl12xx_queue_recovery_work(wl);
/* restarting the chip. ignore any other interrupt. */
goto out;
@@ -1099,6 +1099,12 @@ out:
return ret;
}
+void wl12xx_queue_recovery_work(struct wl1271 *wl)
+{
+ if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+}
+
static void wl1271_recovery_work(struct work_struct *work)
{
struct wl1271 *wl =
@@ -1109,6 +1115,9 @@ static void wl1271_recovery_work(struct work_struct *work)
if (wl->state != WL1271_STATE_ON)
goto out;
+ /* Avoid a recursive recovery */
+ set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
+
wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
@@ -1125,6 +1134,9 @@ static void wl1271_recovery_work(struct work_struct *work)
/* reboot the chipset */
__wl1271_op_remove_interface(wl, false);
+
+ clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
+
ieee80211_restart_hw(wl->hw);
/*