| From 6a7e30cf77280b1eb10fd17347ba33759f0d9148 Mon Sep 17 00:00:00 2001 |
| From: Bo Jiao <Bo.Jiao@mediatek.com> |
| Date: Mon, 6 Nov 2023 11:10:10 +0800 |
| Subject: [PATCH 032/223] mtk: mt76: try more times when send message timeout. |
| |
| Change-Id: Ib7c01e6c9f74f68d8404a3d8bada9e5a10c4e232 |
| Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com> |
| --- |
| dma.c | 7 ++++-- |
| mcu.c | 70 +++++++++++++++++++++++++++------------------------- |
| mt7996/mac.c | 37 +++++++++------------------ |
| mt7996/mcu.c | 1 + |
| 4 files changed, 54 insertions(+), 61 deletions(-) |
| |
| diff --git a/dma.c b/dma.c |
| index 56044639..66c000ef 100644 |
| --- a/dma.c |
| +++ b/dma.c |
| @@ -504,9 +504,12 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, |
| { |
| struct mt76_queue_buf buf = {}; |
| dma_addr_t addr; |
| + int ret = -ENOMEM; |
| |
| - if (test_bit(MT76_MCU_RESET, &dev->phy.state)) |
| + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) { |
| + ret = -EAGAIN; |
| goto error; |
| + } |
| |
| if (q->queued + 1 >= q->ndesc - 1) |
| goto error; |
| @@ -528,7 +531,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, |
| |
| error: |
| dev_kfree_skb(skb); |
| - return -ENOMEM; |
| + return ret; |
| } |
| |
| static int |
| diff --git a/mcu.c b/mcu.c |
| index 2bcce21f..fed363d0 100644 |
| --- a/mcu.c |
| +++ b/mcu.c |
| @@ -4,6 +4,7 @@ |
| */ |
| |
| #include "mt76.h" |
| +#include "mt76_connac.h" |
| #include <linux/moduleparam.h> |
| |
| struct sk_buff * |
| @@ -75,7 +76,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, |
| struct sk_buff **ret_skb) |
| { |
| unsigned int retry = 0; |
| - struct sk_buff *orig_skb = NULL; |
| + struct sk_buff *skb_tmp; |
| unsigned long expires; |
| int ret, seq; |
| |
| @@ -84,48 +85,49 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, |
| |
| mutex_lock(&dev->mcu.mutex); |
| |
| - if (dev->mcu_ops->mcu_skb_prepare_msg) { |
| - orig_skb = skb; |
| - ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq); |
| - if (ret < 0) |
| + while (retry < dev->mcu_ops->max_retry) { |
| + skb_tmp = mt76_mcu_msg_alloc(dev, skb->data, skb->len); |
| + if (!skb_tmp) |
| goto out; |
| - } |
| - |
| -retry: |
| - /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */ |
| - if (orig_skb) |
| - skb_get(orig_skb); |
| - ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); |
| - if (ret < 0) |
| - goto out; |
| - |
| - if (!wait_resp) { |
| - ret = 0; |
| - goto out; |
| - } |
| - |
| - expires = jiffies + dev->mcu.timeout; |
| |
| - do { |
| - skb = mt76_mcu_get_response(dev, expires); |
| - if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) && |
| - orig_skb && retry++ < dev->mcu_ops->max_retry) { |
| + if (wait_resp && retry) { |
| + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) |
| + usleep_range(200000, 500000); |
| dev_err(dev->dev, "Retry message %08x (seq %d)\n", |
| cmd, seq); |
| - skb = orig_skb; |
| - goto retry; |
| } |
| |
| - ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq); |
| - if (!ret && ret_skb) |
| - *ret_skb = skb; |
| - else |
| - dev_kfree_skb(skb); |
| - } while (ret == -EAGAIN); |
| + ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq); |
| + if (ret < 0 && ret != -EAGAIN) |
| + goto out; |
| |
| + if (!wait_resp) { |
| + ret = 0; |
| + goto out; |
| + } |
| + |
| + expires = jiffies + dev->mcu.timeout; |
| + |
| + do { |
| + skb_tmp = mt76_mcu_get_response(dev, expires); |
| + ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb_tmp, seq); |
| + if (ret == -ETIMEDOUT) |
| + break; |
| + |
| + if (!ret && ret_skb) |
| + *ret_skb = skb_tmp; |
| + else |
| + dev_kfree_skb(skb_tmp); |
| + |
| + if (ret != -EAGAIN) |
| + goto out; |
| + } while (ret == -EAGAIN); |
| + |
| + retry++; |
| + } |
| |
| out: |
| - dev_kfree_skb(orig_skb); |
| + dev_kfree_skb(skb); |
| mutex_unlock(&dev->mcu.mutex); |
| |
| return ret; |
| diff --git a/mt7996/mac.c b/mt7996/mac.c |
| index 428ccb1a..3c9ee0c8 100644 |
| --- a/mt7996/mac.c |
| +++ b/mt7996/mac.c |
| @@ -1805,13 +1805,24 @@ mt7996_mac_full_reset(struct mt7996_dev *dev) |
| phy3 = mt7996_phy3(dev); |
| dev->recovery.hw_full_reset = true; |
| |
| - wake_up(&dev->mt76.mcu.wait); |
| ieee80211_stop_queues(mt76_hw(dev)); |
| if (phy2) |
| ieee80211_stop_queues(phy2->mt76->hw); |
| if (phy3) |
| ieee80211_stop_queues(phy3->mt76->hw); |
| |
| + set_bit(MT76_RESET, &dev->mphy.state); |
| + set_bit(MT76_MCU_RESET, &dev->mphy.state); |
| + wake_up(&dev->mt76.mcu.wait); |
| + if (phy2) { |
| + set_bit(MT76_RESET, &phy2->mt76->state); |
| + set_bit(MT76_MCU_RESET, &phy2->mt76->state); |
| + } |
| + if (phy3) { |
| + set_bit(MT76_RESET, &phy3->mt76->state); |
| + set_bit(MT76_MCU_RESET, &phy3->mt76->state); |
| + } |
| + |
| cancel_work_sync(&dev->wed_rro.work); |
| cancel_delayed_work_sync(&dev->mphy.mac_work); |
| if (phy2) |
| @@ -1914,16 +1925,6 @@ void mt7996_mac_reset_work(struct work_struct *work) |
| set_bit(MT76_MCU_RESET, &dev->mphy.state); |
| wake_up(&dev->mt76.mcu.wait); |
| |
| - cancel_work_sync(&dev->wed_rro.work); |
| - cancel_delayed_work_sync(&dev->mphy.mac_work); |
| - if (phy2) { |
| - set_bit(MT76_RESET, &phy2->mt76->state); |
| - cancel_delayed_work_sync(&phy2->mt76->mac_work); |
| - } |
| - if (phy3) { |
| - set_bit(MT76_RESET, &phy3->mt76->state); |
| - cancel_delayed_work_sync(&phy3->mt76->mac_work); |
| - } |
| mt76_worker_disable(&dev->mt76.tx_worker); |
| mt76_for_each_q_rx(&dev->mt76, i) { |
| if (mtk_wed_device_active(&dev->mt76.mmio.wed) && |
| @@ -1934,8 +1935,6 @@ void mt7996_mac_reset_work(struct work_struct *work) |
| } |
| napi_disable(&dev->mt76.tx_napi); |
| |
| - mutex_lock(&dev->mt76.mutex); |
| - |
| mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED); |
| |
| if (mt7996_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { |
| @@ -2008,20 +2007,8 @@ void mt7996_mac_reset_work(struct work_struct *work) |
| if (phy3) |
| ieee80211_wake_queues(phy3->mt76->hw); |
| |
| - mutex_unlock(&dev->mt76.mutex); |
| - |
| mt7996_update_beacons(dev); |
| |
| - ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work, |
| - MT7996_WATCHDOG_TIME); |
| - if (phy2) |
| - ieee80211_queue_delayed_work(phy2->mt76->hw, |
| - &phy2->mt76->mac_work, |
| - MT7996_WATCHDOG_TIME); |
| - if (phy3) |
| - ieee80211_queue_delayed_work(phy3->mt76->hw, |
| - &phy3->mt76->mac_work, |
| - MT7996_WATCHDOG_TIME); |
| dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.", |
| wiphy_name(dev->mt76.hw->wiphy)); |
| } |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index 9e6f4d13..08234b3a 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -3139,6 +3139,7 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev) |
| int mt7996_mcu_init(struct mt7996_dev *dev) |
| { |
| static const struct mt76_mcu_ops mt7996_mcu_ops = { |
| + .max_retry = 3, |
| .headroom = sizeof(struct mt76_connac2_mcu_txd), /* reuse */ |
| .mcu_skb_send_msg = mt7996_mcu_send_message, |
| .mcu_parse_response = mt7996_mcu_parse_response, |
| -- |
| 2.45.2 |
| |