mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-04 04:54:18 +00:00
79 lines
2.6 KiB
Diff
79 lines
2.6 KiB
Diff
|
From 69708fbb2c698f262e03360d064c7066e0679953 Mon Sep 17 00:00:00 2001
|
||
|
From: Shiji Yang <yangshiji66@outlook.com>
|
||
|
Date: Sat, 14 Oct 2023 14:55:01 +0800
|
||
|
Subject: wifi: rt2x00: fix rt2800 watchdog function
|
||
|
|
||
|
The watchdog function is broken on rt2800 series SoCs. This patch
|
||
|
fixes the incorrect watchdog logic to make it work again.
|
||
|
|
||
|
1. Update current wdt queue index if it's not equal to the previous
|
||
|
index. Watchdog compares the current and previous queue index to
|
||
|
judge if the queue hung.
|
||
|
2. Make sure hung_{rx,tx} 'true' status won't be override by the
|
||
|
normal queue. Any queue hangs should trigger a reset action.
|
||
|
3. Clear the watchdog counter of all queues before resetting the
|
||
|
hardware. This change may help to avoid the reset loop.
|
||
|
4. Change hang check function return type to bool as we only need
|
||
|
to return two status, yes or no.
|
||
|
|
||
|
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
|
||
|
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
|
||
|
Signed-off-by: Kalle Valo <kvalo@kernel.org>
|
||
|
Link: https://lore.kernel.org/r/TYAP286MB0315BC1D83D31154924F0D39BCD1A@TYAP286MB0315.JPNP286.PROD.OUTLOOK.COM
|
||
|
---
|
||
|
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 17 +++++++++++------
|
||
|
1 file changed, 11 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||
|
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||
|
@@ -1237,13 +1237,14 @@ void rt2800_txdone_nostatus(struct rt2x0
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus);
|
||
|
|
||
|
-static int rt2800_check_hung(struct data_queue *queue)
|
||
|
+static bool rt2800_check_hung(struct data_queue *queue)
|
||
|
{
|
||
|
unsigned int cur_idx = rt2800_drv_get_dma_done(queue);
|
||
|
|
||
|
- if (queue->wd_idx != cur_idx)
|
||
|
+ if (queue->wd_idx != cur_idx) {
|
||
|
+ queue->wd_idx = cur_idx;
|
||
|
queue->wd_count = 0;
|
||
|
- else
|
||
|
+ } else
|
||
|
queue->wd_count++;
|
||
|
|
||
|
return queue->wd_count > 16;
|
||
|
@@ -1280,7 +1281,7 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||
|
case QID_MGMT:
|
||
|
if (rt2x00queue_empty(queue))
|
||
|
continue;
|
||
|
- hung_tx = rt2800_check_hung(queue);
|
||
|
+ hung_tx = hung_tx || rt2800_check_hung(queue);
|
||
|
break;
|
||
|
case QID_RX:
|
||
|
/* For station mode we should reactive at least
|
||
|
@@ -1289,7 +1290,7 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||
|
*/
|
||
|
if (rt2x00dev->intf_sta_count == 0)
|
||
|
continue;
|
||
|
- hung_rx = rt2800_check_hung(queue);
|
||
|
+ hung_rx = hung_rx || rt2800_check_hung(queue);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
@@ -1302,8 +1303,12 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||
|
if (hung_rx)
|
||
|
rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n");
|
||
|
|
||
|
- if (hung_tx || hung_rx)
|
||
|
+ if (hung_tx || hung_rx) {
|
||
|
+ queue_for_each(rt2x00dev, queue)
|
||
|
+ queue->wd_count = 0;
|
||
|
+
|
||
|
ieee80211_restart_hw(rt2x00dev->hw);
|
||
|
+ }
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(rt2800_watchdog);
|
||
|
|