Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit baacb9ae authored by Ido Yariv's avatar Ido Yariv Committed by Luciano Coelho
Browse files

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: default avatarIdo Yariv <ido@wizery.com>
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 842f1a6c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
	}

+1 −1
Original line number Diff line number Diff line
@@ -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;
+13 −1
Original line number Diff line number Diff line
@@ -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 @@ 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 =
@@ -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);

	/*
+1 −1
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -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:
Loading