developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 1 | From 8f5062f0a4362f58e57354447ac81924c184db8a Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: Bo Jiao <Bo.Jiao@mediatek.com> |
| 3 | Date: Mon, 6 Nov 2023 11:10:10 +0800 |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 4 | Subject: [PATCH 032/193] mtk: mt76: try more times when send message timeout. |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 6 | Change-Id: Ib7c01e6c9f74f68d8404a3d8bada9e5a10c4e232 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 7 | Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com> |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 8 | --- |
| 9 | dma.c | 7 ++++-- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 10 | mcu.c | 70 +++++++++++++++++++++++++++------------------------- |
| 11 | mt7996/mac.c | 37 +++++++++------------------ |
| 12 | mt7996/mcu.c | 1 + |
| 13 | 4 files changed, 54 insertions(+), 61 deletions(-) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14 | |
| 15 | diff --git a/dma.c b/dma.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 16 | index 5604463..66c000e 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 17 | --- a/dma.c |
| 18 | +++ b/dma.c |
| 19 | @@ -504,9 +504,12 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, |
| 20 | { |
| 21 | struct mt76_queue_buf buf = {}; |
| 22 | dma_addr_t addr; |
| 23 | + int ret = -ENOMEM; |
| 24 | |
| 25 | - if (test_bit(MT76_MCU_RESET, &dev->phy.state)) |
| 26 | + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) { |
| 27 | + ret = -EAGAIN; |
| 28 | goto error; |
| 29 | + } |
| 30 | |
| 31 | if (q->queued + 1 >= q->ndesc - 1) |
| 32 | goto error; |
| 33 | @@ -528,7 +531,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, |
| 34 | |
| 35 | error: |
| 36 | dev_kfree_skb(skb); |
| 37 | - return -ENOMEM; |
| 38 | + return ret; |
| 39 | } |
| 40 | |
| 41 | static int |
| 42 | diff --git a/mcu.c b/mcu.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 43 | index 2bcce21..fed363d 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 44 | --- a/mcu.c |
| 45 | +++ b/mcu.c |
| 46 | @@ -4,6 +4,7 @@ |
| 47 | */ |
| 48 | |
| 49 | #include "mt76.h" |
| 50 | +#include "mt76_connac.h" |
| 51 | #include <linux/moduleparam.h> |
| 52 | |
| 53 | struct sk_buff * |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 54 | @@ -75,7 +76,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 55 | struct sk_buff **ret_skb) |
| 56 | { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 57 | unsigned int retry = 0; |
| 58 | - struct sk_buff *orig_skb = NULL; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 59 | + struct sk_buff *skb_tmp; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 60 | unsigned long expires; |
| 61 | int ret, seq; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 62 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 63 | @@ -84,48 +85,49 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 64 | |
| 65 | mutex_lock(&dev->mcu.mutex); |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 66 | |
| 67 | - if (dev->mcu_ops->mcu_skb_prepare_msg) { |
| 68 | - orig_skb = skb; |
| 69 | - ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq); |
| 70 | - if (ret < 0) |
| 71 | + while (retry < dev->mcu_ops->max_retry) { |
| 72 | + skb_tmp = mt76_mcu_msg_alloc(dev, skb->data, skb->len); |
| 73 | + if (!skb_tmp) |
| 74 | goto out; |
| 75 | - } |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 76 | - |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 77 | -retry: |
| 78 | - /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */ |
| 79 | - if (orig_skb) |
| 80 | - skb_get(orig_skb); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 81 | - ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); |
| 82 | - if (ret < 0) |
| 83 | - goto out; |
| 84 | - |
| 85 | - if (!wait_resp) { |
| 86 | - ret = 0; |
| 87 | - goto out; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 88 | - } |
| 89 | - |
| 90 | - expires = jiffies + dev->mcu.timeout; |
| 91 | |
| 92 | - do { |
| 93 | - skb = mt76_mcu_get_response(dev, expires); |
| 94 | - if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) && |
| 95 | - orig_skb && retry++ < dev->mcu_ops->max_retry) { |
| 96 | + if (wait_resp && retry) { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 97 | + if (test_bit(MT76_MCU_RESET, &dev->phy.state)) |
| 98 | + usleep_range(200000, 500000); |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 99 | dev_err(dev->dev, "Retry message %08x (seq %d)\n", |
| 100 | cmd, seq); |
| 101 | - skb = orig_skb; |
| 102 | - goto retry; |
| 103 | } |
| 104 | |
| 105 | - ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb, seq); |
| 106 | - if (!ret && ret_skb) |
| 107 | - *ret_skb = skb; |
| 108 | - else |
| 109 | - dev_kfree_skb(skb); |
| 110 | - } while (ret == -EAGAIN); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 111 | + ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq); |
| 112 | + if (ret < 0 && ret != -EAGAIN) |
| 113 | + goto out; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 114 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 115 | + if (!wait_resp) { |
| 116 | + ret = 0; |
| 117 | + goto out; |
| 118 | + } |
| 119 | + |
| 120 | + expires = jiffies + dev->mcu.timeout; |
| 121 | + |
| 122 | + do { |
| 123 | + skb_tmp = mt76_mcu_get_response(dev, expires); |
| 124 | + ret = dev->mcu_ops->mcu_parse_response(dev, cmd, skb_tmp, seq); |
| 125 | + if (ret == -ETIMEDOUT) |
| 126 | + break; |
| 127 | + |
| 128 | + if (!ret && ret_skb) |
| 129 | + *ret_skb = skb_tmp; |
| 130 | + else |
| 131 | + dev_kfree_skb(skb_tmp); |
| 132 | + |
| 133 | + if (ret != -EAGAIN) |
| 134 | + goto out; |
| 135 | + } while (ret == -EAGAIN); |
| 136 | + |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 137 | + retry++; |
| 138 | + } |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 139 | |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 140 | out: |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 141 | - dev_kfree_skb(orig_skb); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 142 | + dev_kfree_skb(skb); |
| 143 | mutex_unlock(&dev->mcu.mutex); |
| 144 | |
| 145 | return ret; |
| 146 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 147 | index 428ccb1..3c9ee0c 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 148 | --- a/mt7996/mac.c |
| 149 | +++ b/mt7996/mac.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 150 | @@ -1805,13 +1805,24 @@ mt7996_mac_full_reset(struct mt7996_dev *dev) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 151 | phy3 = mt7996_phy3(dev); |
| 152 | dev->recovery.hw_full_reset = true; |
| 153 | |
| 154 | - wake_up(&dev->mt76.mcu.wait); |
| 155 | ieee80211_stop_queues(mt76_hw(dev)); |
| 156 | if (phy2) |
| 157 | ieee80211_stop_queues(phy2->mt76->hw); |
| 158 | if (phy3) |
| 159 | ieee80211_stop_queues(phy3->mt76->hw); |
| 160 | |
| 161 | + set_bit(MT76_RESET, &dev->mphy.state); |
| 162 | + set_bit(MT76_MCU_RESET, &dev->mphy.state); |
| 163 | + wake_up(&dev->mt76.mcu.wait); |
| 164 | + if (phy2) { |
| 165 | + set_bit(MT76_RESET, &phy2->mt76->state); |
| 166 | + set_bit(MT76_MCU_RESET, &phy2->mt76->state); |
| 167 | + } |
| 168 | + if (phy3) { |
| 169 | + set_bit(MT76_RESET, &phy3->mt76->state); |
| 170 | + set_bit(MT76_MCU_RESET, &phy3->mt76->state); |
| 171 | + } |
| 172 | + |
| 173 | cancel_work_sync(&dev->wed_rro.work); |
| 174 | cancel_delayed_work_sync(&dev->mphy.mac_work); |
| 175 | if (phy2) |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 176 | @@ -1914,16 +1925,6 @@ void mt7996_mac_reset_work(struct work_struct *work) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 177 | set_bit(MT76_MCU_RESET, &dev->mphy.state); |
| 178 | wake_up(&dev->mt76.mcu.wait); |
| 179 | |
| 180 | - cancel_work_sync(&dev->wed_rro.work); |
| 181 | - cancel_delayed_work_sync(&dev->mphy.mac_work); |
| 182 | - if (phy2) { |
| 183 | - set_bit(MT76_RESET, &phy2->mt76->state); |
| 184 | - cancel_delayed_work_sync(&phy2->mt76->mac_work); |
| 185 | - } |
| 186 | - if (phy3) { |
| 187 | - set_bit(MT76_RESET, &phy3->mt76->state); |
| 188 | - cancel_delayed_work_sync(&phy3->mt76->mac_work); |
| 189 | - } |
| 190 | mt76_worker_disable(&dev->mt76.tx_worker); |
| 191 | mt76_for_each_q_rx(&dev->mt76, i) { |
| 192 | if (mtk_wed_device_active(&dev->mt76.mmio.wed) && |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 193 | @@ -1934,8 +1935,6 @@ void mt7996_mac_reset_work(struct work_struct *work) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 194 | } |
| 195 | napi_disable(&dev->mt76.tx_napi); |
| 196 | |
| 197 | - mutex_lock(&dev->mt76.mutex); |
| 198 | - |
| 199 | mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED); |
| 200 | |
| 201 | if (mt7996_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 202 | @@ -2008,20 +2007,8 @@ void mt7996_mac_reset_work(struct work_struct *work) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 203 | if (phy3) |
| 204 | ieee80211_wake_queues(phy3->mt76->hw); |
| 205 | |
| 206 | - mutex_unlock(&dev->mt76.mutex); |
| 207 | - |
| 208 | mt7996_update_beacons(dev); |
| 209 | |
| 210 | - ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work, |
| 211 | - MT7996_WATCHDOG_TIME); |
| 212 | - if (phy2) |
| 213 | - ieee80211_queue_delayed_work(phy2->mt76->hw, |
| 214 | - &phy2->mt76->mac_work, |
| 215 | - MT7996_WATCHDOG_TIME); |
| 216 | - if (phy3) |
| 217 | - ieee80211_queue_delayed_work(phy3->mt76->hw, |
| 218 | - &phy3->mt76->mac_work, |
| 219 | - MT7996_WATCHDOG_TIME); |
| 220 | dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.", |
| 221 | wiphy_name(dev->mt76.hw->wiphy)); |
| 222 | } |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 223 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 224 | index ed41f51..77567d5 100644 |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 225 | --- a/mt7996/mcu.c |
| 226 | +++ b/mt7996/mcu.c |
| 227 | @@ -3139,6 +3139,7 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev) |
| 228 | int mt7996_mcu_init(struct mt7996_dev *dev) |
| 229 | { |
| 230 | static const struct mt76_mcu_ops mt7996_mcu_ops = { |
| 231 | + .max_retry = 3, |
| 232 | .headroom = sizeof(struct mt76_connac2_mcu_txd), /* reuse */ |
| 233 | .mcu_skb_send_msg = mt7996_mcu_send_message, |
| 234 | .mcu_parse_response = mt7996_mcu_parse_response, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 235 | -- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 236 | 2.45.2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 237 | |