| 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 |
| |