Skip to content

Commit

Permalink
wl12xx: Avoid recovery while one is already in progress
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ido Yariv authored and Luciano Coelho committed Jun 27, 2011
1 parent 842f1a6 commit baacb9a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 7 deletions.
4 changes: 2 additions & 2 deletions drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,

fail:
WARN_ON(1);
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);
return ret;
}

Expand Down Expand Up @@ -356,7 +356,7 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)

ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask);
if (ret != 0) {
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);
return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/wl12xx/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ static ssize_t start_recovery_write(struct file *file,
struct wl1271 *wl = file->private_data;

mutex_lock(&wl->mutex);
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);
mutex_unlock(&wl->mutex);

return count;
Expand Down
14 changes: 13 additions & 1 deletion drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1099,6 +1099,12 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
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 =
Expand All @@ -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));

Expand All @@ -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);

/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/wl12xx/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
&compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
if (ret == 0) {
wl1271_error("ELP wakeup timeout!");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);
ret = -ETIMEDOUT;
goto err;
} else if (ret < 0) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/wl12xx/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void wl1271_scan_complete_work(struct work_struct *work)

if (wl->scan.failed) {
wl1271_info("Scan completed due to error.");
ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);
}

out:
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/wl12xx/testmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
{
wl1271_debug(DEBUG_TESTMODE, "testmode cmd recover");

ieee80211_queue_work(wl->hw, &wl->recovery_work);
wl12xx_queue_recovery_work(wl);

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/wl12xx/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ enum wl12xx_flags {
WL1271_FLAG_PENDING_WORK,
WL1271_FLAG_SOFT_GEMINI,
WL1271_FLAG_RX_STREAMING_STARTED,
WL1271_FLAG_RECOVERY_IN_PROGRESS,
};

struct wl1271_link {
Expand Down Expand Up @@ -612,6 +613,7 @@ struct wl1271_station {
int wl1271_plt_start(struct wl1271 *wl);
int wl1271_plt_stop(struct wl1271 *wl);
int wl1271_recalc_rx_streaming(struct wl1271 *wl);
void wl12xx_queue_recovery_work(struct wl1271 *wl);

#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */

Expand Down

0 comments on commit baacb9a

Please sign in to comment.