blob: 4da50c91d68d15a4312a6accafbf9cd9eb27757d [file] [log] [blame]
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