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

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

wlcore: Disable interrupts while recovering



In case a recovery is initiated, the FW can no longer be trusted, and
the driver should not handle any new FW events.

Disable the interrupt handler when a recovery is scheduled and balance
it back in the op_stop callback.

Signed-off-by: default avatarIdo Yariv <ido@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 645865fc
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -48,6 +48,12 @@ void wlcore_disable_interrupts(struct wl1271 *wl)
}
EXPORT_SYMBOL_GPL(wlcore_disable_interrupts);

void wlcore_disable_interrupts_nosync(struct wl1271 *wl)
{
	disable_irq_nosync(wl->irq);
}
EXPORT_SYMBOL_GPL(wlcore_disable_interrupts_nosync);

void wlcore_enable_interrupts(struct wl1271 *wl)
{
	enable_irq(wl->irq);
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
struct wl1271;

void wlcore_disable_interrupts(struct wl1271 *wl);
void wlcore_disable_interrupts_nosync(struct wl1271 *wl);
void wlcore_enable_interrupts(struct wl1271 *wl);

void wl1271_io_reset(struct wl1271 *wl);
+15 −6
Original line number Diff line number Diff line
@@ -743,9 +743,12 @@ static void wl1271_fetch_nvs(struct wl1271 *wl)

void wl12xx_queue_recovery_work(struct wl1271 *wl)
{
	if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
	/* Avoid a recursive recovery */
	if (!test_and_set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
		wlcore_disable_interrupts_nosync(wl);
		ieee80211_queue_work(wl->hw, &wl->recovery_work);
	}
}

size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
{
@@ -848,9 +851,6 @@ static void wl1271_recovery_work(struct work_struct *work)
	if (wl->state != WL1271_STATE_ON || wl->plt)
		goto out_unlock;

	/* Avoid a recursive recovery */
	set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);

	wl12xx_read_fwlog_panic(wl);

	/* change partitions momentarily so we can read the FW pc */
@@ -902,8 +902,6 @@ static void wl1271_recovery_work(struct work_struct *work)
	mutex_unlock(&wl->mutex);
	wl1271_op_stop(wl->hw);

	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);

	ieee80211_restart_hw(wl->hw);

	/*
@@ -1706,6 +1704,10 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
	wlcore_disable_interrupts(wl);
	mutex_lock(&wl->mutex);
	if (wl->state == WL1271_STATE_OFF) {
		if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
					&wl->flags))
			wlcore_enable_interrupts(wl);

		mutex_unlock(&wl->mutex);

		/*
@@ -1737,6 +1739,13 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
	mutex_lock(&wl->mutex);

	wl1271_power_off(wl);
	/*
	 * In case a recovery was scheduled, interrupts were disabled to avoid
	 * an interrupt storm. Now that the power is down, it is safe to
	 * re-enable interrupts to balance the disable depth
	 */
	if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
		wlcore_enable_interrupts(wl);

	wl->band = IEEE80211_BAND_2GHZ;