wlcore: cancel Tx watchdog on suspend and rearm on first Tx after
Sometimes a tx_flush during suspend fails, but the FW manages to flush out the packets during the time when the host is supsended. Cancel the Tx-watchdog on suspend to not cause a spurious recovery on resume for that case. Set a flag to reinit the watchdog on the first Tx after resume, so we'll still recover if the FW is not empty and there's indeed a problem. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
02d0727ca3
commit
9be86cf067
|
@ -1767,6 +1767,12 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
|
|||
flush_work(&wl->tx_work);
|
||||
flush_delayed_work(&wl->elp_work);
|
||||
|
||||
/*
|
||||
* Cancel the watchdog even if above tx_flush failed. We will detect
|
||||
* it on resume anyway.
|
||||
*/
|
||||
cancel_delayed_work(&wl->tx_watchdog_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1824,6 +1830,13 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
|
|||
|
||||
out:
|
||||
wl->wow_enabled = false;
|
||||
|
||||
/*
|
||||
* Set a flag to re-init the watchdog on the first Tx after resume.
|
||||
* That way we avoid possible conditions where Tx-complete interrupts
|
||||
* fail to arrive and we perform a spurious recovery.
|
||||
*/
|
||||
set_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags);
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -234,8 +234,13 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||
wl->tx_blocks_available -= total_blocks;
|
||||
wl->tx_allocated_blocks += total_blocks;
|
||||
|
||||
/* If the FW was empty before, arm the Tx watchdog */
|
||||
if (wl->tx_allocated_blocks == total_blocks)
|
||||
/*
|
||||
* If the FW was empty before, arm the Tx watchdog. Also do
|
||||
* this on the first Tx after resume, as we always cancel the
|
||||
* watchdog on suspend.
|
||||
*/
|
||||
if (wl->tx_allocated_blocks == total_blocks ||
|
||||
test_and_clear_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags))
|
||||
wl12xx_rearm_tx_watchdog_locked(wl);
|
||||
|
||||
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
|
||||
|
|
|
@ -240,6 +240,7 @@ enum wl12xx_flags {
|
|||
WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
|
||||
WL1271_FLAG_INTENDED_FW_RECOVERY,
|
||||
WL1271_FLAG_IO_FAILED,
|
||||
WL1271_FLAG_REINIT_TX_WDOG,
|
||||
};
|
||||
|
||||
enum wl12xx_vif_flags {
|
||||
|
|
Loading…
Reference in New Issue