--- /dev/null
+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);
+