531dc9fe42
Signed-off-by: Imre Kaloz <kaloz@openwrt.org> SVN-Revision: 39947
74 lines
2.4 KiB
Diff
74 lines
2.4 KiB
Diff
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>
|
|
|
|
---
|
|
drivers/net/wireless/ti/wlcore/main.c | 13 +++++++++++++
|
|
drivers/net/wireless/ti/wlcore/tx.c | 9 +++++++--
|
|
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
|
|
3 files changed, 21 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ti/wlcore/main.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/main.c
|
|
@@ -1767,6 +1767,12 @@ static int wl1271_op_suspend(struct ieee
|
|
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 ieee8
|
|
|
|
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;
|
|
--- a/drivers/net/wireless/ti/wlcore/tx.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/tx.c
|
|
@@ -234,8 +234,13 @@ static int wl1271_tx_allocate(struct wl1
|
|
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));
|
|
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
|
|
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
|
|
@@ -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 {
|