[][MAC80211][WiFi6][mt76][Fix TX/RX hang and SER hw bit didn't detect issue]
[Description]
Fix TX/RX hang and SER hw bit didn't detect issue
1. TXD from Host to WA, CTXD will send TXD to WA in WFDMA because the TXD request has reached the upper limit of Cascade and Timeout occurs.
At this time, WA does not receive TXD because the Ring of TX free done event from WA to Host is full, and the TXD Ring is full and blocks back.
[Release-log]
Change-Id: I3091877a153994af12fd74853bd19949e2ca13ce
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9629321
diff --git a/autobuild/autobuild_5.4_mac80211_release/package/kernel/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch b/autobuild/autobuild_5.4_mac80211_release/package/kernel/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch
new file mode 100644
index 0000000..4da50c9
--- /dev/null
+++ b/autobuild/autobuild_5.4_mac80211_release/package/kernel/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch
@@ -0,0 +1,109 @@
+From 7a5aec3bea2904c15137b3293a37cef67ab7c9b4 Mon Sep 17 00:00:00 2001
+From: Rex Lu <rex.lu@mediatek.com>
+Date: Thu, 12 Sep 2024 16:17:51 +0800
+Subject: [PATCH] wifi: mt76: mt7915: fix TX/RX hang without SER hw bit to do
+ L1 recovery issue
+
+---
+ mcu.c | 4 +++-
+ mt76.h | 2 +-
+ mt76_connac_mcu.c | 2 +-
+ mt7915/mcu.c | 10 +++++++++-
+ mt7915/regs.h | 2 +-
+ 5 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/mcu.c b/mcu.c
+index 1bc94e8..d331d81 100644
+--- a/mcu.c
++++ b/mcu.c
+@@ -82,6 +82,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
+ int ret, seq, retry_cnt;
+ struct sk_buff *skb_tmp;
+ bool retry = wait_resp && is_connac_v2(dev);
++ bool force_ser = false;
+
+ if (ret_skb)
+ *ret_skb = NULL;
+@@ -99,9 +100,10 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
+ usleep_range(200000, 500000);
+ dev_err(dev->dev, "send message %08x timeout, try again(%d).\n",
+ cmd, (MT76_MSG_MAX_RETRY_CNT - retry_cnt));
++ force_ser = true;
+ }
+
+- ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq);
++ ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq, force_ser);
+ if (ret < 0 && ret != -EAGAIN)
+ goto out;
+
+diff --git a/mt76.h b/mt76.h
+index fd59fdf..dbf0fba 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -245,7 +245,7 @@ struct mt76_mcu_ops {
+ int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data,
+ int len, bool wait_resp);
+ int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb,
+- int cmd, int *seq);
++ int cmd, int *seq, bool force_ser);
+ int (*mcu_parse_response)(struct mt76_dev *dev, int cmd,
+ struct sk_buff *skb, int seq);
+ u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset);
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 0ce7ecd..e1f598f 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -3076,7 +3076,7 @@ int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb,
+ u8 seq;
+
+ /* TODO: make dynamic based on msg type */
+- dev->mcu.timeout = 20 * HZ;
++ dev->mcu.timeout = 3 * HZ;
+
+ seq = ++dev->mcu.msg_seq & 0xf;
+ if (!seq)
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 250b05e..bd32b0a 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -192,7 +192,7 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+
+ static int
+ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+- int cmd, int *wait_seq)
++ int cmd, int *wait_seq, bool force_ser)
+ {
+ struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
+ enum mt76_mcuq_id qid;
+@@ -205,6 +205,14 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+ return -EPERM;
+ }
+
++ if (force_ser && mdev->recovery_state == MT76_RECOVERY_INIT) {
++ dev_info(dev->mt76.dev,"\n%s TX/RX hang force trigger L1 SER recovery, drop message %08x.",
++ wiphy_name(dev->mt76.hw->wiphy), cmd);
++ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_SER_TRIGGER);
++ dev_kfree_skb(skb);
++ return -EPERM;
++ }
++
+ ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq);
+
+ if (ret)
+diff --git a/mt7915/regs.h b/mt7915/regs.h
+index ca355d1..24778d3 100644
+--- a/mt7915/regs.h
++++ b/mt7915/regs.h
+@@ -141,8 +141,8 @@ enum offs_rev {
+ #define MT_MCU_INT_EVENT __REG(INT_MCU_CMD_EVENT)
+ #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
+ #define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
+-#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2)
+ #define MT_MCU_INT_EVENT_RESET_DONE BIT(3)
++#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(4)
+
+ /* PLE */
+ #define MT_PLE_BASE 0x820c0000
+--
+2.45.2
+