blob: bd6cc1945b4e7f07ee779fa0595627454f5c602d [file] [log] [blame]
developer20d67712022-03-02 14:09:32 +08001From 60822f57c815c088dca838f12e8b6e909fbea497 Mon Sep 17 00:00:00 2001
2From: Bo Jiao <Bo.Jiao@mediatek.com>
3Date: Thu, 17 Feb 2022 00:35:03 +0800
4Subject: [PATCH 2001/2001] mt76: mt7915: add L0.5 SER for mt7986
5
6Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
7---
8 .../wireless/mediatek/mt76/mt7915/debugfs.c | 168 ++++++++++++-
9 .../net/wireless/mediatek/mt76/mt7915/dma.c | 49 ++++
10 .../net/wireless/mediatek/mt76/mt7915/init.c | 16 +-
11 .../net/wireless/mediatek/mt76/mt7915/mac.c | 231 +++++++++++++++++-
12 .../net/wireless/mediatek/mt76/mt7915/main.c | 16 +-
13 .../net/wireless/mediatek/mt76/mt7915/mcu.c | 52 +++-
14 .../net/wireless/mediatek/mt76/mt7915/mmio.c | 12 +-
15 .../wireless/mediatek/mt76/mt7915/mt7915.h | 27 ++
16 .../net/wireless/mediatek/mt76/mt7915/regs.h | 37 ++-
17 9 files changed, 578 insertions(+), 30 deletions(-)
18
19diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
20index 1857420..ea0b4a5 100644
21--- a/mt7915/debugfs.c
22+++ b/mt7915/debugfs.c
23@@ -47,7 +47,8 @@ mt7915_implicit_txbf_get(void *data, u64 *val)
24 DEFINE_DEBUGFS_ATTRIBUTE(fops_implicit_txbf, mt7915_implicit_txbf_get,
25 mt7915_implicit_txbf_set, "%lld\n");
26
27-/* test knob of system layer 1/2 error recovery */
28+/* test knob of system layer 0.5/1/2 error recovery */
29+/*
30 static int mt7915_ser_trigger_set(void *data, u64 val)
31 {
32 enum {
33@@ -74,9 +75,172 @@ static int mt7915_ser_trigger_set(void *data, u64 val)
34 return ret;
35 }
36
37+*/
38+static int mt7915_ser_trigger_set(void *data, u64 val)
39+{
40+#define SER_SET GENMASK(3, 0)
41+#define SER_BAND GENMASK(7, 4)
42+#define SER_ACTION GENMASK(11, 8)
43+ enum {
44+ SER_ACTION_SET = 1,
45+ SER_ACTION_SET_MASK = 2,
46+ SER_ACTION_TRIGGER = 3,
47+ };
48+
49+ struct mt7915_dev *dev = data;
50+ u8 ser_action, ser_band, ser_set, set_val;
51+
52+ ser_action = FIELD_GET(SER_ACTION, val);
53+ ser_set = set_val = FIELD_GET(SER_SET, val);
54+ ser_band = (ser_action == SER_ACTION_TRIGGER) ?
55+ FIELD_GET(SER_BAND, val) : 0;
56+
57+ if (ser_band > 1)
58+ return -1;
59+
60+ switch (ser_action) {
61+ case SER_ACTION_SET:
62+ /*
63+ * 0x100: disable system error recovery function.
64+ * 0x101: enable system error recovery function.
65+ */
66+ ser_set = !!set_val;
67+ break;
68+ case SER_ACTION_SET_MASK:
69+ /*
70+ * 0x200: enable system error tracking.
71+ * 0x201: enable system error L1 recover.
72+ * 0x202: enable system error L2 recover.
73+ * 0x203: enable system error L3 rx abort.
74+ * 0x204: enable system error L3 tx abort.
75+ * 0x205: enable system error L3 tx disable.
76+ * 0x206: enable system error L3 bf recover.
77+ * 0x207: enable system error all recover.
78+ */
79+ ser_set = set_val > 7 ? 0x7f : BIT(set_val);
80+ break;
81+ case SER_ACTION_TRIGGER:
82+ /*
83+ * 0x300: trigger L0 recover.
84+ * 0x301/0x311: trigger L1 recover for band0/band1.
85+ * 0x302/0x312: trigger L2 recover for band0/band1.
86+ * 0x303/0x313: trigger L3 rx abort for band0/band1.
87+ * 0x304/0x314: trigger L3 tx abort for band0/band1.
88+ * 0x305/0x315: trigger L3 tx disable for band0/band1.
89+ * 0x306/0x316: trigger L3 bf recover for band0/band1.
90+ */
91+ if (0x300 == val || 0x310 == val) {
92+ mt7915_reset(dev, SER_TYPE_FULL_RESET);
93+ return 0;
94+ }
95+
96+ if (ser_set > 6)
97+ return -1;
98+ break;
99+ default:
100+ return -1;
101+ }
102+
103+ return mt7915_mcu_set_ser(dev, ser_action, ser_set, ser_band);
104+}
105+
106 DEFINE_DEBUGFS_ATTRIBUTE(fops_ser_trigger, NULL,
107 mt7915_ser_trigger_set, "%lld\n");
108
109+static int
110+mt7915_ser_stats_show(struct seq_file *s, void *data)
111+{
112+#define SER_ACTION_QUERY 0
113+ struct mt7915_dev *dev = dev_get_drvdata(s->private);
114+ int ret = 0;
115+
116+ /* get more info from firmware */
117+ ret = mt7915_mcu_set_ser(dev, SER_ACTION_QUERY, 0, 0);
118+ msleep(100);
119+
120+ seq_printf(s, "::E R , SER_STATUS = 0x%08X\n",
121+ MT_SWDEF_SER_STATUS);
122+ seq_printf(s, "::E R , SER_PLE_ERR = 0x%08X\n",
123+ MT_SWDEF_PLE_STATUS);
124+ seq_printf(s, "::E R , SER_PLE_ERR_1 = 0x%08X\n",
125+ MT_SWDEF_PLE1_STATUS);
126+ seq_printf(s, "::E R , SER_PLE_ERR_AMSDU = 0x%08X\n",
127+ MT_SWDEF_PLE_AMSDU_STATUS);
128+ seq_printf(s, "::E R , SER_PSE_ERR = 0x%08X\n",
129+ MT_SWDEF_PSE_STATUS);
130+ seq_printf(s, "::E R , SER_PSE_ERR_1 = 0x%08X\n",
131+ MT_SWDEF_PSE1_STATUS);
132+ seq_printf(s, "::E R , SER_LMAC_WISR6_B0 = 0x%08X\n",
133+ MT_SWDEF_LAMC_WISR6_BN0_STATUS);
134+ seq_printf(s, "::E R , SER_LMAC_WISR6_B1 = 0x%08X\n",
135+ MT_SWDEF_LAMC_WISR6_BN1_STATUS);
136+ seq_printf(s, "::E R , SER_LMAC_WISR7_B0 = 0x%08X\n",
137+ MT_SWDEF_LAMC_WISR7_BN0_STATUS);
138+ seq_printf(s, "::E R , SER_LMAC_WISR7_B1 = 0x%08X\n",
139+ MT_SWDEF_LAMC_WISR7_BN1_STATUS);
140+
141+ seq_printf(s, "\nWF RESET STATUS: WM %d, WA %d, WO %d\n",
142+ dev->ser.wf_reset_wm_count,
143+ dev->ser.wf_reset_wa_count,
144+ dev->ser.wf_reset_wo_count);
145+
146+ return ret;
147+}
148+
149+
150+int mt7915_fw_exception_chk(struct mt7915_dev *dev)
151+{
152+ u32 reg_val;
153+
154+ reg_val = mt76_rr(dev, MT_EXCEPTION_ADDR);
155+
156+ if (is_mt7915(&dev->mt76))
157+ reg_val >>= 8;
158+
159+ return !!(reg_val & 0xff);
160+}
161+
162+void mt7915_fw_heart_beat_chk(struct mt7915_dev *dev)
163+{
164+#define WM_TIMEOUT_COUNT_CHECK 5
165+#define WM_HANG_COUNT_CHECK 9
166+ u32 cnt, cidx, didx, queue;
167+ u32 idx, i;
168+ static struct {
169+ u32 cidx;
170+ u32 didx;
171+ } dma_rec[5];
172+
173+ if (dev->ser.hw_full_reset)
174+ return;
175+
176+ if (dev->ser.cmd_fail_cnt >= WM_TIMEOUT_COUNT_CHECK) {
177+
178+ cnt = mt76_rr(dev, WF_WFDMA_MEM_DMA_RX_RING_CTL + 4);
179+ cidx = mt76_rr(dev, WF_WFDMA_MEM_DMA_RX_RING_CTL + 8);
180+ didx = mt76_rr(dev, WF_WFDMA_MEM_DMA_RX_RING_CTL + 12);
181+ queue = (didx > cidx) ?
182+ (didx - cidx - 1) : (didx - cidx + cnt - 1);
183+
184+ idx = (dev->ser.cmd_fail_cnt - WM_TIMEOUT_COUNT_CHECK) % 5;
185+ dma_rec[idx].cidx = cidx;
186+ dma_rec[idx].cidx = didx;
187+
188+ if (((cnt - 1) == queue) &&
189+ (dev->ser.cmd_fail_cnt >= WM_HANG_COUNT_CHECK)) {
190+
191+ for (i = 0; i < 5; i++) {
192+ if ((dma_rec[i].cidx != cidx) ||
193+ (dma_rec[i].didx != didx))
194+ return;
195+ }
196+
197+ mt7915_reset(dev, SER_TYPE_FULL_RESET);
198+ dev->ser.cmd_fail_cnt = 0;
199+ }
200+ }
201+}
202+
203 static int
204 mt7915_radar_trigger(void *data, u64 val)
205 {
206@@ -914,6 +1078,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
207 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
208 mt7915_twt_stats);
209 debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger);
210+ debugfs_create_devm_seqfile(dev->mt76.dev, "ser_show", dir,
211+ mt7915_ser_stats_show);
212 if (!dev->dbdc_support || phy->band_idx) {
213 debugfs_create_u32("dfs_hw_pattern", 0400, dir,
214 &dev->hw_pattern);
215diff --git a/mt7915/dma.c b/mt7915/dma.c
216index 49b4d8a..b6144b6 100644
217--- a/mt7915/dma.c
218+++ b/mt7915/dma.c
219@@ -443,6 +443,55 @@ int mt7915_dma_init(struct mt7915_dev *dev)
220 return 0;
221 }
222
223+
224+int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
225+{
226+ struct mt76_phy *mphy_ext = dev->mt76.phy2;
227+ int i;
228+
229+ /* clean up hw queues */
230+ for (i = 0; i < ARRAY_SIZE(dev->mt76.phy.q_tx); i++) {
231+ mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[i], true);
232+ if (mphy_ext)
233+ mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[i], true);
234+ }
235+
236+ for (i = 0; i < ARRAY_SIZE(dev->mt76.q_mcu); i++)
237+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[i], true);
238+
239+ for (i = 0; i < __MT_RXQ_MAX; i++)
240+ mt76_queue_rx_cleanup(dev, &dev->mt76.q_rx[i]);
241+
242+ /* reset wfsys */
243+ if (force)
244+ mt7915_wfsys_reset(dev);
245+
246+ /* disable wfdma */
247+ mt7915_dma_disable(dev, force);
248+
249+ /* reset hw queues */
250+ for (i = 0; i < __MT_TXQ_MAX; i++) {
251+ mt76_queue_reset(dev, dev->mphy.q_tx[i]);
252+ if (mphy_ext)
253+ mt76_queue_reset(dev, mphy_ext->q_tx[i]);
254+ }
255+
256+ for (i = 0; i < __MT_MCUQ_MAX; i++)
257+ mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
258+
259+ for (i = 0; i < __MT_RXQ_MAX; i++)
260+ mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
261+
262+ mt76_tx_status_check(&dev->mt76, true);
263+
264+ mt7915_dma_enable(dev);
265+
266+ for (i = 0; i < __MT_RXQ_MAX; i++)
267+ mt76_queue_rx_reset(dev, i);
268+
269+ return 0;
270+}
271+
272 void mt7915_dma_cleanup(struct mt7915_dev *dev)
273 {
274 mt7915_dma_disable(dev, true);
275diff --git a/mt7915/init.c b/mt7915/init.c
276index 6323744..6606e19 100644
277--- a/mt7915/init.c
278+++ b/mt7915/init.c
279@@ -262,7 +262,7 @@ static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
280 mt7915_led_set_config(led_cdev, 0xff, 0);
281 }
282
283-static void
284+void
285 mt7915_init_txpower(struct mt7915_dev *dev,
286 struct ieee80211_supported_band *sband)
287 {
288@@ -447,7 +447,7 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
289 mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);
290 }
291
292-static void mt7915_mac_init(struct mt7915_dev *dev)
293+void mt7915_mac_init(struct mt7915_dev *dev)
294 {
295 int i;
296 u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680;
297@@ -474,7 +474,7 @@ static void mt7915_mac_init(struct mt7915_dev *dev)
298 }
299 }
300
301-static int mt7915_txbf_init(struct mt7915_dev *dev)
302+int mt7915_txbf_init(struct mt7915_dev *dev)
303 {
304 int ret;
305
306@@ -581,7 +581,7 @@ static void mt7915_init_work(struct work_struct *work)
307 dev->dbg.muru_onoff = OFDMA_DL | MUMIMO_UL | MUMIMO_DL;
308 }
309
310-static void mt7915_wfsys_reset(struct mt7915_dev *dev)
311+void mt7915_wfsys_reset(struct mt7915_dev *dev)
312 {
313 #define MT_MCU_DUMMY_RANDOM GENMASK(15, 0)
314 #define MT_MCU_DUMMY_DEFAULT GENMASK(31, 16)
315@@ -1144,7 +1144,13 @@ int mt7915_register_device(struct mt7915_dev *dev)
316 if (ret)
317 return ret;
318
319- return mt7915_init_debugfs(&dev->phy);
320+ ret = mt7915_init_debugfs(&dev->phy);
321+ if (ret)
322+ return ret;
323+
324+ dev->ser.hw_init_done = true;
325+
326+ return 0;
327 }
328
329 void mt7915_unregister_device(struct mt7915_dev *dev)
330diff --git a/mt7915/mac.c b/mt7915/mac.c
331index 94579e4..0f4084b 100644
332--- a/mt7915/mac.c
333+++ b/mt7915/mac.c
334@@ -3,6 +3,7 @@
335
336 #include <linux/etherdevice.h>
337 #include <linux/timekeeping.h>
338+#include <linux/pci.h>
339 #include "mt7915.h"
340 #include "../dma.h"
341 #include "mac.h"
342@@ -1968,9 +1969,9 @@ mt7915_update_beacons(struct mt7915_dev *dev)
343 IEEE80211_IFACE_ITER_RESUME_ALL,
344 mt7915_update_vif_beacon, dev->mt76.phy2->hw);
345 }
346-
347+#if 0
348 static void
349-mt7915_dma_reset(struct mt7915_dev *dev)
350+mt7915_dma_reset(struct mt7915_dev *dev, bool force)
351 {
352 struct mt76_phy *mphy_ext = dev->mt76.phy2;
353 u32 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
354@@ -2035,6 +2036,7 @@ mt7915_dma_reset(struct mt7915_dev *dev)
355 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
356 }
357 }
358+#endif
359
360 void mt7915_tx_token_put(struct mt7915_dev *dev)
361 {
362@@ -2050,6 +2052,172 @@ void mt7915_tx_token_put(struct mt7915_dev *dev)
363 idr_destroy(&dev->mt76.token);
364 }
365
366+static int
367+mt7915_mac_reset(struct mt7915_dev *dev)
368+{
369+ struct mt7915_phy *phy2;
370+ struct mt76_phy *ext_phy;
371+ struct mt76_dev *mdev = &dev->mt76;
372+ int i, ret;
373+ u32 irq_mask;
374+
375+ ext_phy = dev->mt76.phy2;
376+ phy2 = ext_phy ? ext_phy->priv : NULL;
377+
378+ /* irq disable */
379+ mt76_wr(dev, MT_INT_MASK_CSR, 0x0);
380+ mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
381+ if (dev->hif2) {
382+ mt76_wr(dev, MT_INT1_MASK_CSR, 0x0);
383+ mt76_wr(dev, MT_INT1_SOURCE_CSR, ~0);
384+ }
385+ if (dev_is_pci(mdev->dev)) {
386+ mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
387+ if (dev->hif2)
388+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
389+ }
390+
391+ set_bit(MT76_RESET, &dev->mphy.state);
392+ wake_up(&dev->mt76.mcu.wait);
393+ if (ext_phy)
394+ set_bit(MT76_RESET, &ext_phy->state);
395+
396+ /* lock/unlock all queues to ensure that no tx is pending */
397+ mt76_txq_schedule_all(&dev->mphy);
398+ if (ext_phy)
399+ mt76_txq_schedule_all(ext_phy);
400+
401+ /* disable all tx/rx napi */
402+ mt76_worker_disable(&dev->mt76.tx_worker);
403+ mt76_for_each_q_rx(mdev, i) {
404+ if (mdev->q_rx[i].ndesc)
405+ napi_disable(&dev->mt76.napi[i]);
406+ }
407+ napi_disable(&dev->mt76.tx_napi);
408+
409+ /* token reinit */
410+ mt7915_tx_token_put(dev);
411+ idr_init(&dev->mt76.token);
412+
413+ mt7915_dma_reset(dev, true);
414+ mt76_for_each_q_rx(mdev, i) {
415+ if (mdev->q_rx[i].ndesc) {
416+ napi_enable(&dev->mt76.napi[i]);
417+ napi_schedule(&dev->mt76.napi[i]);
418+ }
419+ }
420+ clear_bit(MT76_MCU_RESET, &dev->mphy.state);
421+ clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
422+
423+ mt76_wr(dev, MT_INT_MASK_CSR, dev->mt76.mmio.irqmask);
424+ mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
425+ if (dev->hif2) {
426+ mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
427+ mt76_wr(dev, MT_INT1_SOURCE_CSR, ~0);
428+ }
429+ if (dev_is_pci(mdev->dev)) {
430+ mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
431+ if (dev->hif2)
432+ mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
433+ }
434+
435+ /* load firmware */
436+ ret = mt7915_run_firmware(dev);
437+ if (ret)
438+ goto out;
439+
440+ /* set the necessary init items */
441+ ret = mt7915_mcu_set_eeprom(dev, dev->flash_mode);
442+ if (ret)
443+ goto out;
444+
445+ mt7915_mac_init(dev);
446+ mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
447+ mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
448+ ret = mt7915_txbf_init(dev);
449+
450+out:
451+ /* reset done */
452+ clear_bit(MT76_RESET, &dev->mphy.state);
453+ if (phy2)
454+ clear_bit(MT76_RESET, &phy2->mt76->state);
455+
456+ napi_enable(&dev->mt76.tx_napi);
457+ napi_schedule(&dev->mt76.tx_napi);
458+ mt76_worker_enable(&dev->mt76.tx_worker);
459+
460+ return ret;
461+}
462+
463+static void
464+mt7915_mac_full_reset(struct mt7915_dev *dev)
465+{
466+ struct mt7915_phy *phy2;
467+ struct mt76_phy *ext_phy;
468+ int i;
469+ struct cfg80211_scan_info info = {
470+ .aborted = true,
471+ };
472+
473+ ext_phy = dev->mt76.phy2;
474+ phy2 = ext_phy ? ext_phy->priv : NULL;
475+
476+ dev->ser.hw_full_reset = true;
477+ if (READ_ONCE(dev->reset_state) & MT_MCU_CMD_WA_WDT)
478+ dev->ser.wf_reset_wa_count++;
479+ else
480+ dev->ser.wf_reset_wm_count++;
481+
482+ wake_up(&dev->mt76.mcu.wait);
483+ ieee80211_stop_queues(mt76_hw(dev));
484+ if (ext_phy)
485+ ieee80211_stop_queues(ext_phy->hw);
486+
487+ cancel_delayed_work_sync(&dev->mphy.mac_work);
488+ if (ext_phy)
489+ cancel_delayed_work_sync(&ext_phy->mac_work);
490+
491+ mutex_lock(&dev->mt76.mutex);
492+ for (i = 0; i < 10; i++) {
493+ if (!mt7915_mac_reset(dev))
494+ break;
495+ }
496+ mutex_unlock(&dev->mt76.mutex);
497+
498+ if (i == 10)
499+ dev_err(dev->mt76.dev, "chip full reset failed\n");
500+
501+ if (test_and_clear_bit(MT76_HW_SCANNING, &dev->mphy.state))
502+ ieee80211_scan_completed(dev->mphy.hw, &info);
503+
504+ if (test_and_clear_bit(MT76_HW_SCANNING, &ext_phy->state))
505+ ieee80211_scan_completed(ext_phy->hw, &info);
506+
507+ ieee80211_wake_queues(mt76_hw(dev));
508+ if (ext_phy)
509+ ieee80211_wake_queues(ext_phy->hw);
510+
511+ if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
512+ __mt7915_start(dev->mphy.hw);
513+
514+ if (ext_phy &&
515+ test_bit(MT76_STATE_RUNNING, &ext_phy->state))
516+ __mt7915_start(ext_phy->hw);
517+
518+ dev->ser.hw_full_reset = false;
519+
520+ ieee80211_restart_hw(mt76_hw(dev));
521+ if (ext_phy)
522+ ieee80211_restart_hw(ext_phy->hw);
523+
524+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
525+ MT7915_WATCHDOG_TIME);
526+ if (ext_phy)
527+ ieee80211_queue_delayed_work(ext_phy->hw,
528+ &ext_phy->mac_work,
529+ MT7915_WATCHDOG_TIME);
530+}
531+
532 /* system error recovery */
533 void mt7915_mac_reset_work(struct work_struct *work)
534 {
535@@ -2061,6 +2229,25 @@ void mt7915_mac_reset_work(struct work_struct *work)
536 ext_phy = dev->mt76.phy2;
537 phy2 = ext_phy ? ext_phy->priv : NULL;
538
539+ /* chip full reset */
540+ if (dev->ser.reset_type == SER_TYPE_FULL_RESET) {
541+ u32 val;
542+
543+ /* disable wa/wm watchdog interuppt */
544+ val = mt76_rr(dev, MT_WFDMA0_MCU_HOST_INT_ENA);
545+ val &= ~(MT_MCU_CMD_WA_WDT | MT_MCU_CMD_WM_WDT);
546+ mt76_set(dev, MT_WFDMA0_MCU_HOST_INT_ENA, val);
547+
548+ mt7915_mac_full_reset(dev);
549+
550+ /* enable the mcu irq*/
551+ mt7915_irq_enable(dev, MT_INT_MCU_CMD);
552+ mt7915_irq_disable(dev, 0);
553+ return;
554+ }
555+
556+ /* chip partial reset */
557+ dev->ser.reset_type = SER_TYPE_NONE;
558 if (!(READ_ONCE(dev->reset_state) & MT_MCU_CMD_STOP_DMA))
559 return;
560
561@@ -2087,7 +2274,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
562 mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED);
563
564 if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
565- mt7915_dma_reset(dev);
566+ mt7915_dma_reset(dev, false);
567
568 mt7915_tx_token_put(dev);
569 idr_init(&dev->mt76.token);
570@@ -2138,6 +2325,44 @@ void mt7915_mac_reset_work(struct work_struct *work)
571 MT7915_WATCHDOG_TIME);
572 }
573
574+
575+void mt7915_reset(struct mt7915_dev *dev, u8 type)
576+{
577+ struct mt76_phy *ext_phy = dev->mt76.phy2;
578+
579+ if (!dev->ser.hw_init_done)
580+ return;
581+
582+ if (dev->ser.hw_full_reset)
583+ return;
584+
585+ dev_err(dev->mt76.dev, "SER: reset_state(0x%08X) type(0x%08X)\n",
586+ READ_ONCE(dev->reset_state), type);
587+
588+ /* WM/WA exception: do full recovery */
589+ if ((READ_ONCE(dev->reset_state) & MT_MCU_CMD_WDT_MASK) ||
590+ type == SER_TYPE_FULL_RESET) {
591+
592+ if (!is_mt7986(&dev->mt76))
593+ return;
594+
595+ dev->ser.reset_type = SER_TYPE_FULL_RESET;
596+ set_bit(MT76_MCU_RESET, &dev->mphy.state);
597+ if (ext_phy)
598+ set_bit(MT76_MCU_RESET, &ext_phy->state);
599+
600+ ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
601+ return;
602+ }
603+
604+ /* do partial recovery */
605+ mt7915_irq_enable(dev, MT_INT_MCU_CMD);
606+ mt7915_irq_disable(dev, 0);
607+ dev->ser.reset_type = SER_TYPE_PARTIAL_RESET;
608+ ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
609+ wake_up(&dev->reset_wait);
610+}
611+
612 void mt7915_mac_update_stats(struct mt7915_phy *phy)
613 {
614 struct mt7915_dev *dev = phy->dev;
615diff --git a/mt7915/main.c b/mt7915/main.c
616index 1a384f1..7f148a3 100644
617--- a/mt7915/main.c
618+++ b/mt7915/main.c
619@@ -20,7 +20,7 @@ static bool mt7915_dev_running(struct mt7915_dev *dev)
620 return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);
621 }
622
623-static int mt7915_start(struct ieee80211_hw *hw)
624+int __mt7915_start(struct ieee80211_hw *hw)
625 {
626 struct mt7915_dev *dev = mt7915_hw_dev(hw);
627 struct mt7915_phy *phy = mt7915_hw_phy(hw);
628@@ -29,8 +29,6 @@ static int mt7915_start(struct ieee80211_hw *hw)
629
630 flush_work(&dev->init_work);
631
632- mutex_lock(&dev->mt76.mutex);
633-
634 running = mt7915_dev_running(dev);
635
636 if (!running) {
637@@ -95,6 +93,18 @@ out:
638 return ret;
639 }
640
641+static int mt7915_start(struct ieee80211_hw *hw)
642+{
643+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
644+ int ret;
645+
646+ mutex_lock(&dev->mt76.mutex);
647+ ret = __mt7915_start(hw);
648+ mutex_unlock(&dev->mt76.mutex);
649+
650+ return ret;
651+}
652+
653 static void mt7915_stop(struct ieee80211_hw *hw)
654 {
655 struct mt7915_dev *dev = mt7915_hw_dev(hw);
656diff --git a/mt7915/mcu.c b/mt7915/mcu.c
657index 9033125..e0fcc8f 100644
658--- a/mt7915/mcu.c
659+++ b/mt7915/mcu.c
660@@ -212,14 +212,31 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
661 struct sk_buff *skb, int seq)
662 {
663 struct mt7915_mcu_rxd *rxd;
664+ struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
665 int ret = 0;
666
667 if (!skb) {
668 dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
669 cmd, seq);
670+
671+ dev->ser.cmd_fail_cnt++;
672+
673+ if (dev->ser.cmd_fail_cnt < 5) {
674+ int exp_type = mt7915_fw_exception_chk(dev);
675+
676+ dev_err(mdev->dev, "Fw is status(%d)\n", exp_type);
677+ if (exp_type) {
678+ dev->ser.reset_type = SER_TYPE_FULL_RESET;
679+ mt7915_reset(dev, SER_TYPE_FULL_RESET);
680+ }
681+ }
682+ mt7915_fw_heart_beat_chk(dev);
683+
684 return -ETIMEDOUT;
685 }
686
687+ dev->ser.cmd_fail_cnt = 0;
688+
689 rxd = (struct mt7915_mcu_rxd *)skb->data;
690 if (seq != rxd->seq)
691 return -EAGAIN;
692@@ -243,11 +260,17 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
693 {
694 struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
695 struct mt7915_mcu_txd *mcu_txd;
696+ //struct mt76_phy *ext_phy = mdev->phy2;
697 enum mt76_mcuq_id qid;
698 __le32 *txd;
699 u32 val;
700 u8 seq;
701
702+ if (test_bit(MT76_MCU_RESET, &mdev->phy.state)) {
703+ dev_err(mdev->dev, "%s assert\n", __func__);
704+ return -EBUSY;
705+ }
706+
707 /* TODO: make dynamic based on msg type */
708 mdev->mcu.timeout = 20 * HZ;
709
710@@ -2420,25 +2443,14 @@ mt7915_mcu_init_rx_airtime(struct mt7915_dev *dev)
711 sizeof(req), true);
712 }
713
714-int mt7915_mcu_init(struct mt7915_dev *dev)
715+int mt7915_run_firmware(struct mt7915_dev *dev)
716 {
717- static const struct mt76_mcu_ops mt7915_mcu_ops = {
718- .headroom = sizeof(struct mt7915_mcu_txd),
719- .mcu_skb_send_msg = mt7915_mcu_send_message,
720- .mcu_parse_response = mt7915_mcu_parse_response,
721- .mcu_restart = mt76_connac_mcu_restart,
722- };
723 int ret;
724
725- dev->mt76.mcu_ops = &mt7915_mcu_ops;
726-
727 /* force firmware operation mode into normal state,
728 * which should be set before firmware download stage.
729 */
730- if (is_mt7915(&dev->mt76))
731- mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
732- else
733- mt76_wr(dev, MT_SWDEF_MODE_MT7916, MT_SWDEF_NORMAL_MODE);
734+ mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
735
736 ret = mt7915_driver_own(dev, 0);
737 if (ret)
738@@ -2480,6 +2492,20 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
739 MCU_WA_PARAM_RED, 0, 0);
740 }
741
742+int mt7915_mcu_init(struct mt7915_dev *dev)
743+{
744+ static const struct mt76_mcu_ops mt7915_mcu_ops = {
745+ .headroom = sizeof(struct mt7915_mcu_txd),
746+ .mcu_skb_send_msg = mt7915_mcu_send_message,
747+ .mcu_parse_response = mt7915_mcu_parse_response,
748+ .mcu_restart = mt76_connac_mcu_restart,
749+ };
750+
751+ dev->mt76.mcu_ops = &mt7915_mcu_ops;
752+
753+ return mt7915_run_firmware(dev);
754+}
755+
756 void mt7915_mcu_exit(struct mt7915_dev *dev)
757 {
758 __mt76_mcu_restart(&dev->mt76);
759diff --git a/mt7915/mmio.c b/mt7915/mmio.c
760index 2466907..561ac65 100644
761--- a/mt7915/mmio.c
762+++ b/mt7915/mmio.c
763@@ -22,6 +22,8 @@ static const u32 mt7915_reg[] = {
764 [WFDMA_EXT_CSR_ADDR] = 0xd7000,
765 [CBTOP1_PHY_END] = 0x77ffffff,
766 [INFRA_MCU_ADDR_END] = 0x7c3fffff,
767+ [EXCEPTION_BASE_ADDR] = 0x219848,
768+ [SWDEF_BASE_ADDR] = 0x41f200,
769 };
770
771 static const u32 mt7916_reg[] = {
772@@ -36,6 +38,8 @@ static const u32 mt7916_reg[] = {
773 [WFDMA_EXT_CSR_ADDR] = 0xd7000,
774 [CBTOP1_PHY_END] = 0x7fffffff,
775 [INFRA_MCU_ADDR_END] = 0x7c085fff,
776+ [EXCEPTION_BASE_ADDR] = 0x022050BC,
777+ [SWDEF_BASE_ADDR] = 0x411400,
778 };
779
780 static const u32 mt7986_reg[] = {
781@@ -50,6 +54,8 @@ static const u32 mt7986_reg[] = {
782 [WFDMA_EXT_CSR_ADDR] = 0x27000,
783 [CBTOP1_PHY_END] = 0x7fffffff,
784 [INFRA_MCU_ADDR_END] = 0x7c085fff,
785+ [EXCEPTION_BASE_ADDR] = 0x02204FFC,
786+ [SWDEF_BASE_ADDR] = 0x411400,
787 };
788
789 static const u32 mt7915_offs[] = {
790@@ -601,10 +607,10 @@ static void mt7915_irq_tasklet(struct tasklet_struct *t)
791 u32 val = mt76_rr(dev, MT_MCU_CMD);
792
793 mt76_wr(dev, MT_MCU_CMD, val);
794- if (val & MT_MCU_CMD_ERROR_MASK) {
795+ mt7915_irq_disable(dev, MT_INT_MCU_CMD);
796+ if (val & MT_MCU_CMD_ALL_ERROR_MASK) {
797 dev->reset_state = val;
798- ieee80211_queue_work(mt76_hw(dev), &dev->reset_work);
799- wake_up(&dev->reset_wait);
800+ mt7915_reset(dev, SER_TYPE_UNKNOWN);
801 }
802 }
803 }
804diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
805index 436ae35..219cec8 100644
806--- a/mt7915/mt7915.h
807+++ b/mt7915/mt7915.h
808@@ -342,6 +342,15 @@ struct mt7915_dev {
809 struct work_struct reset_work;
810 wait_queue_head_t reset_wait;
811 u32 reset_state;
812+ struct {
813+ bool hw_full_reset:1;
814+ bool hw_init_done:1;
815+ u32 reset_type;
816+ u32 cmd_fail_cnt;
817+ u32 wf_reset_wm_count;
818+ u32 wf_reset_wa_count;
819+ u32 wf_reset_wo_count;
820+ }ser;
821
822 struct list_head sta_rc_list;
823 struct list_head sta_poll_list;
824@@ -433,6 +442,13 @@ enum mt7915_rdd_cmd {
825 RDD_IRQ_OFF,
826 };
827
828+enum {
829+ SER_TYPE_NONE,
830+ SER_TYPE_PARTIAL_RESET,
831+ SER_TYPE_FULL_RESET,
832+ SER_TYPE_UNKNOWN,
833+};
834+
835 static inline struct mt7915_phy *
836 mt7915_hw_phy(struct ieee80211_hw *hw)
837 {
838@@ -650,6 +666,17 @@ int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms);
839 int mt7915_init_debugfs(struct mt7915_phy *phy);
840 void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len);
841 bool mt7915_debugfs_rx_log(struct mt7915_dev *dev, const void *data, int len);
842+int mt7915_fw_exception_chk(struct mt7915_dev *dev);
843+void mt7915_fw_heart_beat_chk(struct mt7915_dev *dev);
844+void mt7915_wfsys_reset(struct mt7915_dev *dev);
845+void mt7915_reset(struct mt7915_dev *dev, u8 type);
846+int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
847+int __mt7915_start(struct ieee80211_hw *hw);
848+void mt7915_init_txpower(struct mt7915_dev *dev,
849+ struct ieee80211_supported_band *sband);
850+int mt7915_txbf_init(struct mt7915_dev *dev);
851+void mt7915_mac_init(struct mt7915_dev *dev);
852+int mt7915_run_firmware(struct mt7915_dev *dev);
853 #ifdef CONFIG_MAC80211_DEBUGFS
854 void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
855 struct ieee80211_sta *sta, struct dentry *dir);
856diff --git a/mt7915/regs.h b/mt7915/regs.h
857index 2f3d170..e283702 100644
858--- a/mt7915/regs.h
859+++ b/mt7915/regs.h
860@@ -30,6 +30,8 @@ enum reg_rev {
861 WFDMA_EXT_CSR_ADDR,
862 CBTOP1_PHY_END,
863 INFRA_MCU_ADDR_END,
864+ EXCEPTION_BASE_ADDR,
865+ SWDEF_BASE_ADDR,
866 __MT_REG_MAX,
867 };
868
869@@ -111,6 +113,11 @@ enum offs_rev {
870 #define __REG(id) (dev->reg.reg_rev[(id)])
871 #define __OFFS(id) (dev->reg.offs_rev[(id)])
872
873+/* MEM WFDMA */
874+#define WF_WFDMA_MEM_DMA 0x58000000
875+
876+#define WF_WFDMA_MEM_DMA_RX_RING_CTL (WF_WFDMA_MEM_DMA + (0x510))
877+
878 /* MCU WFDMA0 */
879 #define MT_MCU_WFDMA0_BASE 0x2000
880 #define MT_MCU_WFDMA0(ofs) (MT_MCU_WFDMA0_BASE + (ofs))
881@@ -552,6 +559,10 @@ enum offs_rev {
882 #define MT_WFDMA0_PRI_DLY_INT_CFG1 MT_WFDMA0(0x2f4)
883 #define MT_WFDMA0_PRI_DLY_INT_CFG2 MT_WFDMA0(0x2f8)
884
885+#define MT_WFDMA0_MCU_HOST_INT_ENA MT_WFDMA0(0x1f4)
886+#define MT_WFDMA0_MT_WA_WDT_INT BIT(31)
887+#define MT_WFDMA0_MT_WM_WDT_INT BIT(30)
888+
889 /* WFDMA1 */
890 #define MT_WFDMA1_BASE 0xd5000
891 #define MT_WFDMA1(ofs) (MT_WFDMA1_BASE + (ofs))
892@@ -684,6 +695,12 @@ enum offs_rev {
893 #define MT_MCU_CMD_NORMAL_STATE BIT(5)
894 #define MT_MCU_CMD_ERROR_MASK GENMASK(5, 1)
895
896+#define MT_MCU_CMD_WA_WDT BIT(31)
897+#define MT_MCU_CMD_WM_WDT BIT(30)
898+#define MT_MCU_CMD_WDT_MASK GENMASK(31, 30)
899+#define MT_MCU_CMD_ALL_ERROR_MASK (MT_MCU_CMD_ERROR_MASK | \
900+ MT_MCU_CMD_WDT_MASK)
901+
902 /* TOP RGU */
903 #define MT_TOP_RGU_BASE 0x18000000
904 #define MT_TOP_PWR_CTRL (MT_TOP_RGU_BASE + (0x0))
905@@ -924,12 +941,25 @@ enum offs_rev {
906 #define MT_ADIE_TYPE_MASK BIT(1)
907
908 /* FW MODE SYNC */
909-#define MT_SWDEF_MODE 0x41f23c
910-#define MT_SWDEF_MODE_MT7916 0x41143c
911+#define MT_SWDEF_BASE __REG(SWDEF_BASE_ADDR)
912+
913+#define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs))
914+#define MT_SWDEF_MODE MT_SWDEF(0x3c)
915 #define MT_SWDEF_NORMAL_MODE 0
916 #define MT_SWDEF_ICAP_MODE 1
917 #define MT_SWDEF_SPECTRUM_MODE 2
918
919+#define MT_SWDEF_SER_STATUS MT_SWDEF(0x040)
920+#define MT_SWDEF_PLE_STATUS MT_SWDEF(0x044)
921+#define MT_SWDEF_PLE1_STATUS MT_SWDEF(0x048)
922+#define MT_SWDEF_PLE_AMSDU_STATUS MT_SWDEF(0x04C)
923+#define MT_SWDEF_PSE_STATUS MT_SWDEF(0x050)
924+#define MT_SWDEF_PSE1_STATUS MT_SWDEF(0x054)
925+#define MT_SWDEF_LAMC_WISR6_BN0_STATUS MT_SWDEF(0x058)
926+#define MT_SWDEF_LAMC_WISR6_BN1_STATUS MT_SWDEF(0x05C)
927+#define MT_SWDEF_LAMC_WISR7_BN0_STATUS MT_SWDEF(0x060)
928+#define MT_SWDEF_LAMC_WISR7_BN1_STATUS MT_SWDEF(0x064)
929+
930 #define MT_DIC_CMD_REG_BASE 0x41f000
931 #define MT_DIC_CMD_REG(ofs) (MT_DIC_CMD_REG_BASE + (ofs))
932 #define MT_DIC_CMD_REG_CMD MT_DIC_CMD_REG(0x10)
933@@ -1011,6 +1041,9 @@ enum offs_rev {
934
935 #define MT_MCU_BUS_REMAP MT_MCU_BUS(0x120)
936
937+/* MISC */
938+#define MT_EXCEPTION_ADDR __REG(EXCEPTION_BASE_ADDR)
939+
940 /* TOP CFG */
941 #define MT_TOP_CFG_BASE 0x184b0000
942 #define MT_TOP_CFG(ofs) (MT_TOP_CFG_BASE + (ofs))
943--
9442.25.1
945