blob: 4da50c91d68d15a4312a6accafbf9cd9eb27757d [file] [log] [blame]
developer1f55fcf2024-10-17 14:52:33 +08001From 7a5aec3bea2904c15137b3293a37cef67ab7c9b4 Mon Sep 17 00:00:00 2001
2From: Rex Lu <rex.lu@mediatek.com>
3Date: Thu, 12 Sep 2024 16:17:51 +0800
4Subject: [PATCH] wifi: mt76: mt7915: fix TX/RX hang without SER hw bit to do
5 L1 recovery issue
6
7---
8 mcu.c | 4 +++-
9 mt76.h | 2 +-
10 mt76_connac_mcu.c | 2 +-
11 mt7915/mcu.c | 10 +++++++++-
12 mt7915/regs.h | 2 +-
13 5 files changed, 15 insertions(+), 5 deletions(-)
14
15diff --git a/mcu.c b/mcu.c
16index 1bc94e8..d331d81 100644
17--- a/mcu.c
18+++ b/mcu.c
19@@ -82,6 +82,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
20 int ret, seq, retry_cnt;
21 struct sk_buff *skb_tmp;
22 bool retry = wait_resp && is_connac_v2(dev);
23+ bool force_ser = false;
24
25 if (ret_skb)
26 *ret_skb = NULL;
27@@ -99,9 +100,10 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
28 usleep_range(200000, 500000);
29 dev_err(dev->dev, "send message %08x timeout, try again(%d).\n",
30 cmd, (MT76_MSG_MAX_RETRY_CNT - retry_cnt));
31+ force_ser = true;
32 }
33
34- ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq);
35+ ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq, force_ser);
36 if (ret < 0 && ret != -EAGAIN)
37 goto out;
38
39diff --git a/mt76.h b/mt76.h
40index fd59fdf..dbf0fba 100644
41--- a/mt76.h
42+++ b/mt76.h
43@@ -245,7 +245,7 @@ struct mt76_mcu_ops {
44 int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data,
45 int len, bool wait_resp);
46 int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb,
47- int cmd, int *seq);
48+ int cmd, int *seq, bool force_ser);
49 int (*mcu_parse_response)(struct mt76_dev *dev, int cmd,
50 struct sk_buff *skb, int seq);
51 u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset);
52diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
53index 0ce7ecd..e1f598f 100644
54--- a/mt76_connac_mcu.c
55+++ b/mt76_connac_mcu.c
56@@ -3076,7 +3076,7 @@ int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb,
57 u8 seq;
58
59 /* TODO: make dynamic based on msg type */
60- dev->mcu.timeout = 20 * HZ;
61+ dev->mcu.timeout = 3 * HZ;
62
63 seq = ++dev->mcu.msg_seq & 0xf;
64 if (!seq)
65diff --git a/mt7915/mcu.c b/mt7915/mcu.c
66index 250b05e..bd32b0a 100644
67--- a/mt7915/mcu.c
68+++ b/mt7915/mcu.c
69@@ -192,7 +192,7 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
70
71 static int
72 mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
73- int cmd, int *wait_seq)
74+ int cmd, int *wait_seq, bool force_ser)
75 {
76 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
77 enum mt76_mcuq_id qid;
78@@ -205,6 +205,14 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
79 return -EPERM;
80 }
81
82+ if (force_ser && mdev->recovery_state == MT76_RECOVERY_INIT) {
83+ dev_info(dev->mt76.dev,"\n%s TX/RX hang force trigger L1 SER recovery, drop message %08x.",
84+ wiphy_name(dev->mt76.hw->wiphy), cmd);
85+ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_SER_TRIGGER);
86+ dev_kfree_skb(skb);
87+ return -EPERM;
88+ }
89+
90 ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq);
91
92 if (ret)
93diff --git a/mt7915/regs.h b/mt7915/regs.h
94index ca355d1..24778d3 100644
95--- a/mt7915/regs.h
96+++ b/mt7915/regs.h
97@@ -141,8 +141,8 @@ enum offs_rev {
98 #define MT_MCU_INT_EVENT __REG(INT_MCU_CMD_EVENT)
99 #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
100 #define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
101-#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2)
102 #define MT_MCU_INT_EVENT_RESET_DONE BIT(3)
103+#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(4)
104
105 /* PLE */
106 #define MT_PLE_BASE 0x820c0000
107--
1082.45.2
109