blob: b646d6751df65d59d86ff8825d43ceceef4104e5 [file] [log] [blame]
developerb3b54a62023-05-23 16:01:51 +08001From a15a9b160d9bb9b52cb697251777c5c39f842f24 Mon Sep 17 00:00:00 2001
2From: Bo Jiao <Bo.Jiao@mediatek.com>
3Date: Mon, 22 May 2023 13:49:37 +0800
4Subject: [PATCH] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
5
6Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
7---
8 mt76.h | 11 +++
9 mt76_connac_mcu.c | 9 +++
10 mt7915/coredump.c | 169 +++++++++++++++++++++++++++++++---------------
11 mt7915/coredump.h | 34 +++++++---
12 mt7915/mac.c | 33 ++++++---
13 mt7915/mt7915.h | 2 +-
14 mt7915/regs.h | 20 ++++++
15 7 files changed, 207 insertions(+), 71 deletions(-)
16
17diff --git a/mt76.h b/mt76.h
18index 3f13cec6..354acc09 100644
19--- a/mt76.h
20+++ b/mt76.h
21@@ -27,6 +27,8 @@
22
23 #define MT76_TOKEN_FREE_THR 64
24
25+#define MT76_BUILD_TIME_LEN 24
26+
27 #define MT_QFLAG_WED_RING GENMASK(1, 0)
28 #define MT_QFLAG_WED_TYPE GENMASK(3, 2)
29 #define MT_QFLAG_WED BIT(4)
30@@ -54,6 +56,12 @@ enum mt76_bus_type {
31 MT76_BUS_SDIO,
32 };
33
34+enum mt76_ram_type {
35+ MT76_RAM_TYPE_WM,
36+ MT76_RAM_TYPE_WA,
37+ __MT76_RAM_TYPE_MAX,
38+};
39+
40 enum mt76_wed_type {
41 MT76_WED_Q_TX,
42 MT76_WED_Q_TXFREE,
43@@ -776,6 +784,9 @@ struct mt76_dev {
44 struct device *dma_dev;
45
46 struct mt76_mcu mcu;
47+ struct mt76_connac2_patch_hdr *patch_hdr;
48+ struct mt76_connac2_fw_trailer *wm_hdr;
49+ struct mt76_connac2_fw_trailer *wa_hdr;
50
51 struct net_device napi_dev;
52 struct net_device tx_napi_dev;
53diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
54index 46f69aa8..913bad95 100644
55--- a/mt76_connac_mcu.c
56+++ b/mt76_connac_mcu.c
57@@ -3017,6 +3017,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
58 goto out;
59 }
60
61+ dev->wm_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
62+ memcpy(dev->wm_hdr, hdr, sizeof(*hdr));
63+
64 snprintf(dev->hw->wiphy->fw_version,
65 sizeof(dev->hw->wiphy->fw_version),
66 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
67@@ -3046,6 +3049,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
68 goto out;
69 }
70
71+ dev->wa_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
72+ memcpy(dev->wa_hdr, hdr, sizeof(*hdr));
73+
74 snprintf(dev->hw->wiphy->fw_version,
75 sizeof(dev->hw->wiphy->fw_version),
76 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
77@@ -3116,6 +3122,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
78 dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
79 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
80
81+ dev->patch_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
82+ memcpy(dev->patch_hdr, hdr, sizeof(*hdr));
83+
84 for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
85 struct mt76_connac2_patch_sec *sec;
86 u32 len, addr, mode;
87diff --git a/mt7915/coredump.c b/mt7915/coredump.c
88index 5daf2258..298c1cad 100644
89--- a/mt7915/coredump.c
90+++ b/mt7915/coredump.c
91@@ -7,7 +7,7 @@
92 #include <linux/utsname.h>
93 #include "coredump.h"
94
95-static bool coredump_memdump;
96+static bool coredump_memdump = true;
97 module_param(coredump_memdump, bool, 0644);
98 MODULE_PARM_DESC(coredump_memdump, "Optional ability to dump firmware memory");
99
100@@ -86,8 +86,11 @@ static const struct mt7915_mem_region mt798x_mem_regions[] = {
101 };
102
103 const struct mt7915_mem_region*
104-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
105+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num)
106 {
107+ if (type == MT76_RAM_TYPE_WA)
108+ return NULL;
109+
110 switch (mt76_chip(&dev->mt76)) {
111 case 0x7915:
112 *num = ARRAY_SIZE(mt7915_mem_regions);
113@@ -104,14 +107,14 @@ mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
114 }
115 }
116
117-static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev)
118+static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev, u8 type)
119 {
120 const struct mt7915_mem_region *mem_region;
121 size_t size = 0;
122 u32 num;
123 int i;
124
125- mem_region = mt7915_coredump_get_mem_layout(dev, &num);
126+ mem_region = mt7915_coredump_get_mem_layout(dev, type, &num);
127 if (!mem_region)
128 return 0;
129
130@@ -128,9 +131,9 @@ static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev)
131 return size;
132 }
133
134-struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
135+struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type)
136 {
137- struct mt7915_crash_data *crash_data = dev->coredump.crash_data;
138+ struct mt7915_crash_data *crash_data = dev->coredump.crash_data[type];
139
140 lockdep_assert_held(&dev->dump_mutex);
141
142@@ -141,12 +144,15 @@ struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
143 }
144
145 static void
146-mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
147+mt7915_coredump_fw_state(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
148 bool *exception)
149 {
150- u32 state, count, type;
151+ u32 state, count, category;
152+
153+ if (type == MT76_RAM_TYPE_WA)
154+ return;
155
156- type = (u32)mt76_get_field(dev, MT_FW_EXCEPT_TYPE, GENMASK(7, 0));
157+ category = (u32)mt76_get_field(dev, MT_FW_EXCEPT_TYPE, GENMASK(7, 0));
158 state = (u32)mt76_get_field(dev, MT_FW_ASSERT_STAT, GENMASK(7, 0));
159 count = is_mt7915(&dev->mt76) ?
160 (u32)mt76_get_field(dev, MT_FW_EXCEPT_COUNT, GENMASK(15, 8)) :
161@@ -155,7 +161,7 @@ mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
162 /* normal mode: driver can manually trigger assertĀ for detail info */
163 if (!count)
164 strscpy(dump->fw_state, "normal", sizeof(dump->fw_state));
165- else if (state > 1 && (count == 1) && type == 5)
166+ else if (state > 1 && (count == 1) && category == 5)
167 strscpy(dump->fw_state, "assert", sizeof(dump->fw_state));
168 else if ((state > 1 && count == 1) || count > 1)
169 strscpy(dump->fw_state, "exception", sizeof(dump->fw_state));
170@@ -164,11 +170,14 @@ mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
171 }
172
173 static void
174-mt7915_coredump_fw_trace(struct mt7915_dev *dev, struct mt7915_coredump *dump,
175+mt7915_coredump_fw_trace(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
176 bool exception)
177 {
178 u32 n, irq, sch, base = MT_FW_EINT_INFO;
179
180+ if (type == MT76_RAM_TYPE_WA)
181+ return;
182+
183 /* trap or run? */
184 dump->last_msg_id = mt76_rr(dev, MT_FW_LAST_MSG_ID);
185
186@@ -221,31 +230,61 @@ mt7915_coredump_fw_trace(struct mt7915_dev *dev, struct mt7915_coredump *dump,
187 }
188
189 static void
190-mt7915_coredump_fw_stack(struct mt7915_dev *dev, struct mt7915_coredump *dump,
191+mt7915_coredump_fw_stack(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
192 bool exception)
193 {
194- u32 oldest, i, idx;
195+ u32 reg, i;
196+
197+ if (type == MT76_RAM_TYPE_WA)
198+ return;
199+
200+ /* read current PC */
201+ mt76_rmw_field(dev, MT_CONN_DBG_CTL_LOG_SEL,
202+ MT_CONN_DBG_CTL_PC_LOG_SEL, 0x22);
203+ for (i = 0; i < 10; i++) {
204+ dump->pc_cur[i] = mt76_rr(dev, MT_CONN_DBG_CTL_PC_LOG);
205+ usleep_range(100, 500);
206+ }
207
208 /* stop call stack record */
209- if (!exception)
210- mt76_clear(dev, 0x89050200, BIT(0));
211+ if (!exception) {
212+ mt76_clear(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
213+ mt76_clear(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
214+ }
215
216- oldest = (u32)mt76_get_field(dev, 0x89050200, GENMASK(20, 16)) + 2;
217- for (i = 0; i < 16; i++) {
218- idx = ((oldest + 2 * i + 1) % 32);
219- dump->call_stack[i] = mt76_rr(dev, 0x89050204 + idx * 4);
220+ /* read PC log */
221+ dump->pc_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_PC_CTRL);
222+ dump->pc_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS,
223+ dump->pc_dbg_ctrl);
224+ for (i = 0; i < 32; i++) {
225+ reg = MT_MCU_WM_EXCP_PC_LOG + i * 4;
226+ dump->pc_stack[i] = mt76_rr(dev, reg);
227+ }
228+
229+ /* read LR log */
230+ dump->lr_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_LR_CTRL);
231+ dump->lr_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS,
232+ dump->lr_dbg_ctrl);
233+ for (i = 0; i < 32; i++) {
234+ reg = MT_MCU_WM_EXCP_LR_LOG + i * 4;
235+ dump->lr_stack[i] = mt76_rr(dev, reg);
236 }
237
238 /* start call stack record */
239- if (!exception)
240- mt76_set(dev, 0x89050200, BIT(0));
241+ if (!exception) {
242+ mt76_set(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
243+ mt76_set(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
244+ }
245 }
246
247 static void
248-mt7915_coredump_fw_task(struct mt7915_dev *dev, struct mt7915_coredump *dump)
249+mt7915_coredump_fw_task(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump)
250 {
251 u32 offs = is_mt7915(&dev->mt76) ? 0xe0 : 0x170;
252
253+ if (type == MT76_RAM_TYPE_WA)
254+ return;
255+
256 strscpy(dump->task_qid, "(task queue id) read, write",
257 sizeof(dump->task_qid));
258
259@@ -266,10 +305,13 @@ mt7915_coredump_fw_task(struct mt7915_dev *dev, struct mt7915_coredump *dump)
260 }
261
262 static void
263-mt7915_coredump_fw_context(struct mt7915_dev *dev, struct mt7915_coredump *dump)
264+mt7915_coredump_fw_context(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump)
265 {
266 u32 count, idx, id;
267
268+ if (type == MT76_RAM_TYPE_WA)
269+ return;
270+
271 count = mt76_rr(dev, MT_FW_CIRQ_COUNT);
272
273 /* current context */
274@@ -299,9 +341,10 @@ mt7915_coredump_fw_context(struct mt7915_dev *dev, struct mt7915_coredump *dump)
275 }
276 }
277
278-static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
279+static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev, u8 type)
280 {
281- struct mt7915_crash_data *crash_data = dev->coredump.crash_data;
282+ struct mt76_dev *mdev = &dev->mt76;
283+ struct mt7915_crash_data *crash_data = dev->coredump.crash_data[type];
284 struct mt7915_coredump *dump;
285 struct mt7915_coredump_mem *dump_mem;
286 size_t len, sofar = 0, hdr_len = sizeof(*dump);
287@@ -326,23 +369,34 @@ static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
288
289 dump = (struct mt7915_coredump *)(buf);
290 dump->len = len;
291+ dump->hdr_len = hdr_len;
292
293 /* plain text */
294 strscpy(dump->magic, "mt76-crash-dump", sizeof(dump->magic));
295 strscpy(dump->kernel, init_utsname()->release, sizeof(dump->kernel));
296- strscpy(dump->fw_ver, dev->mt76.hw->wiphy->fw_version,
297+ strscpy(dump->fw_ver, mdev->hw->wiphy->fw_version,
298 sizeof(dump->fw_ver));
299+ strscpy(dump->fw_type, ((type == MT76_RAM_TYPE_WA) ? "WA" : "WM"),
300+ sizeof(dump->fw_type));
301+ strscpy(dump->fw_patch_date, mdev->patch_hdr->build_date,
302+ sizeof(dump->fw_patch_date));
303+ strscpy(dump->fw_ram_date[MT76_RAM_TYPE_WM],
304+ mdev->wm_hdr->build_date,
305+ sizeof(mdev->wm_hdr->build_date));
306+ strscpy(dump->fw_ram_date[MT76_RAM_TYPE_WA],
307+ mdev->wa_hdr->build_date,
308+ sizeof(mdev->wa_hdr->build_date));
309
310 guid_copy(&dump->guid, &crash_data->guid);
311 dump->tv_sec = crash_data->timestamp.tv_sec;
312 dump->tv_nsec = crash_data->timestamp.tv_nsec;
313 dump->device_id = mt76_chip(&dev->mt76);
314
315- mt7915_coredump_fw_state(dev, dump, &exception);
316- mt7915_coredump_fw_trace(dev, dump, exception);
317- mt7915_coredump_fw_task(dev, dump);
318- mt7915_coredump_fw_context(dev, dump);
319- mt7915_coredump_fw_stack(dev, dump, exception);
320+ mt7915_coredump_fw_state(dev, type, dump, &exception);
321+ mt7915_coredump_fw_trace(dev, type, dump, exception);
322+ mt7915_coredump_fw_task(dev, type, dump);
323+ mt7915_coredump_fw_context(dev, type, dump);
324+ mt7915_coredump_fw_stack(dev, type, dump, exception);
325
326 /* gather memory content */
327 dump_mem = (struct mt7915_coredump_mem *)(buf + sofar);
328@@ -356,17 +410,19 @@ static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
329 return dump;
330 }
331
332-int mt7915_coredump_submit(struct mt7915_dev *dev)
333+int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type)
334 {
335 struct mt7915_coredump *dump;
336
337- dump = mt7915_coredump_build(dev);
338+ dump = mt7915_coredump_build(dev, type);
339 if (!dump) {
340 dev_warn(dev->mt76.dev, "no crash dump data found\n");
341 return -ENODATA;
342 }
343
344 dev_coredumpv(dev->mt76.dev, dump, dump->len, GFP_KERNEL);
345+ dev_info(dev->mt76.dev, "%s coredump completed\n",
346+ wiphy_name(dev->mt76.hw->wiphy));
347
348 return 0;
349 }
350@@ -374,23 +430,26 @@ int mt7915_coredump_submit(struct mt7915_dev *dev)
351 int mt7915_coredump_register(struct mt7915_dev *dev)
352 {
353 struct mt7915_crash_data *crash_data;
354+ int i;
355
356- crash_data = vzalloc(sizeof(*dev->coredump.crash_data));
357- if (!crash_data)
358- return -ENOMEM;
359+ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) {
360+ crash_data = vzalloc(sizeof(*dev->coredump.crash_data[i]));
361+ if (!crash_data)
362+ return -ENOMEM;
363
364- dev->coredump.crash_data = crash_data;
365+ dev->coredump.crash_data[i] = crash_data;
366
367- if (coredump_memdump) {
368- crash_data->memdump_buf_len = mt7915_coredump_get_mem_size(dev);
369- if (!crash_data->memdump_buf_len)
370- /* no memory content */
371- return 0;
372+ if (coredump_memdump) {
373+ crash_data->memdump_buf_len = mt7915_coredump_get_mem_size(dev, i);
374+ if (!crash_data->memdump_buf_len)
375+ /* no memory content */
376+ return 0;
377
378- crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
379- if (!crash_data->memdump_buf) {
380- vfree(crash_data);
381- return -ENOMEM;
382+ crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
383+ if (!crash_data->memdump_buf) {
384+ vfree(crash_data);
385+ return -ENOMEM;
386+ }
387 }
388 }
389
390@@ -399,13 +458,17 @@ int mt7915_coredump_register(struct mt7915_dev *dev)
391
392 void mt7915_coredump_unregister(struct mt7915_dev *dev)
393 {
394- if (dev->coredump.crash_data->memdump_buf) {
395- vfree(dev->coredump.crash_data->memdump_buf);
396- dev->coredump.crash_data->memdump_buf = NULL;
397- dev->coredump.crash_data->memdump_buf_len = 0;
398- }
399+ int i;
400
401- vfree(dev->coredump.crash_data);
402- dev->coredump.crash_data = NULL;
403+ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) {
404+ if (dev->coredump.crash_data[i]->memdump_buf) {
405+ vfree(dev->coredump.crash_data[i]->memdump_buf);
406+ dev->coredump.crash_data[i]->memdump_buf = NULL;
407+ dev->coredump.crash_data[i]->memdump_buf_len = 0;
408+ }
409+
410+ vfree(dev->coredump.crash_data[i]);
411+ dev->coredump.crash_data[i] = NULL;
412+ }
413 }
414
415diff --git a/mt7915/coredump.h b/mt7915/coredump.h
416index 709f8e9c..809ccbdf 100644
417--- a/mt7915/coredump.h
418+++ b/mt7915/coredump.h
419@@ -4,6 +4,7 @@
420 #ifndef _COREDUMP_H_
421 #define _COREDUMP_H_
422
423+#include "../mt76_connac_mcu.h"
424 #include "mt7915.h"
425
426 struct trace {
427@@ -15,6 +16,7 @@ struct mt7915_coredump {
428 char magic[16];
429
430 u32 len;
431+ u32 hdr_len;
432
433 guid_t guid;
434
435@@ -26,12 +28,28 @@ struct mt7915_coredump {
436 char kernel[64];
437 /* firmware version */
438 char fw_ver[ETHTOOL_FWVERS_LEN];
439+ char fw_patch_date[MT76_BUILD_TIME_LEN];
440+ char fw_ram_date[__MT76_RAM_TYPE_MAX][MT76_BUILD_TIME_LEN];
441
442 u32 device_id;
443
444+ /* fw type */
445+ char fw_type[8];
446 /* exception state */
447 char fw_state[12];
448
449+ /* program counters */
450+ u32 pc_dbg_ctrl;
451+ u32 pc_cur_idx;
452+ u32 pc_cur[10];
453+ /* PC registers */
454+ u32 pc_stack[32];
455+
456+ u32 lr_dbg_ctrl;
457+ u32 lr_cur_idx;
458+ /* LR registers */
459+ u32 lr_stack[32];
460+
461 u32 last_msg_id;
462 u32 eint_info_idx;
463 u32 irq_info_idx;
464@@ -70,9 +88,6 @@ struct mt7915_coredump {
465 u32 handler;
466 } context;
467
468- /* link registers calltrace */
469- u32 call_stack[16];
470-
471 /* memory content */
472 u8 data[];
473 } __packed;
474@@ -83,6 +98,7 @@ struct mt7915_coredump_mem {
475 } __packed;
476
477 struct mt7915_mem_hdr {
478+ char name[64];
479 u32 start;
480 u32 len;
481 u8 data[];
482@@ -98,26 +114,26 @@ struct mt7915_mem_region {
483 #ifdef CONFIG_DEV_COREDUMP
484
485 const struct mt7915_mem_region *
486-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num);
487-struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev);
488-int mt7915_coredump_submit(struct mt7915_dev *dev);
489+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num);
490+struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type);
491+int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type);
492 int mt7915_coredump_register(struct mt7915_dev *dev);
493 void mt7915_coredump_unregister(struct mt7915_dev *dev);
494
495 #else /* CONFIG_DEV_COREDUMP */
496
497 static inline const struct mt7915_mem_region *
498-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
499+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num)
500 {
501 return NULL;
502 }
503
504-static inline int mt7915_coredump_submit(struct mt7915_dev *dev)
505+static inline int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type)
506 {
507 return 0;
508 }
509
510-static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
511+static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type)
512 {
513 return NULL;
514 }
515diff --git a/mt7915/mac.c b/mt7915/mac.c
516index a3ed4ddf..2a87b506 100644
517--- a/mt7915/mac.c
518+++ b/mt7915/mac.c
519@@ -1653,28 +1653,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
520 }
521
522 /* firmware coredump */
523-void mt7915_mac_dump_work(struct work_struct *work)
524+static void mt7915_mac_fw_coredump(struct mt7915_dev *dev, u8 type)
525 {
526 const struct mt7915_mem_region *mem_region;
527 struct mt7915_crash_data *crash_data;
528- struct mt7915_dev *dev;
529 struct mt7915_mem_hdr *hdr;
530 size_t buf_len;
531 int i;
532 u32 num;
533 u8 *buf;
534
535- dev = container_of(work, struct mt7915_dev, dump_work);
536+ if (type != MT76_RAM_TYPE_WM) {
537+ dev_warn(dev->mt76.dev, "%s currently only supports WM coredump!\n",
538+ wiphy_name(dev->mt76.hw->wiphy));
539+ return;
540+ }
541
542 mutex_lock(&dev->dump_mutex);
543
544- crash_data = mt7915_coredump_new(dev);
545+ crash_data = mt7915_coredump_new(dev, type);
546 if (!crash_data) {
547 mutex_unlock(&dev->dump_mutex);
548- goto skip_coredump;
549+ return;
550 }
551
552- mem_region = mt7915_coredump_get_mem_layout(dev, &num);
553+ mem_region = mt7915_coredump_get_mem_layout(dev, type, &num);
554 if (!mem_region || !crash_data->memdump_buf_len) {
555 mutex_unlock(&dev->dump_mutex);
556 goto skip_memdump;
557@@ -1684,6 +1687,9 @@ void mt7915_mac_dump_work(struct work_struct *work)
558 buf_len = crash_data->memdump_buf_len;
559
560 /* dumping memory content... */
561+ dev_info(dev->mt76.dev, "%s start coredump for %s\n",
562+ wiphy_name(dev->mt76.hw->wiphy),
563+ ((type == MT76_RAM_TYPE_WA) ? "WA" : "WM"));
564 memset(buf, 0, buf_len);
565 for (i = 0; i < num; i++) {
566 if (mem_region->len > buf_len) {
567@@ -1701,6 +1707,7 @@ void mt7915_mac_dump_work(struct work_struct *work)
568 mt7915_memcpy_fromio(dev, buf, mem_region->start,
569 mem_region->len);
570
571+ strscpy(hdr->name, mem_region->name, sizeof(mem_region->name));
572 hdr->start = mem_region->start;
573 hdr->len = mem_region->len;
574
575@@ -1717,8 +1724,18 @@ void mt7915_mac_dump_work(struct work_struct *work)
576 mutex_unlock(&dev->dump_mutex);
577
578 skip_memdump:
579- mt7915_coredump_submit(dev);
580-skip_coredump:
581+ mt7915_coredump_submit(dev, type);
582+}
583+
584+void mt7915_mac_dump_work(struct work_struct *work)
585+{
586+ struct mt7915_dev *dev;
587+
588+ dev = container_of(work, struct mt7915_dev, dump_work);
589+
590+ if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WM_WDT)
591+ mt7915_mac_fw_coredump(dev, MT76_RAM_TYPE_WM);
592+
593 queue_work(dev->mt76.wq, &dev->reset_work);
594 }
595
596diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
597index 54510245..4fb0a375 100644
598--- a/mt7915/mt7915.h
599+++ b/mt7915/mt7915.h
600@@ -335,7 +335,7 @@ struct mt7915_dev {
601 struct mutex dump_mutex;
602 #ifdef CONFIG_DEV_COREDUMP
603 struct {
604- struct mt7915_crash_data *crash_data;
605+ struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX];
606 } coredump;
607 #endif
608
609diff --git a/mt7915/regs.h b/mt7915/regs.h
610index 374677f7..636b12da 100644
611--- a/mt7915/regs.h
612+++ b/mt7915/regs.h
613@@ -1215,4 +1215,24 @@ enum offs_rev {
614 #define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x108)
615 #define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR MT_MCU_WM_CIRQ(0x118)
616
617+/* CONN DBG */
618+#define MT_CONN_DBG_CTL_BASE 0x18060000
619+#define MT_CONN_DBG_CTL(ofs) (MT_CONN_DBG_CTL_BASE + (ofs))
620+#define MT_CONN_DBG_CTL_LOG_SEL MT_CONN_DBG_CTL(0x090)
621+#define MT_CONN_DBG_CTL_PC_LOG_SEL GENMASK(7, 2)
622+#define MT_CONN_DBG_CTL_GPR_LOG_SEL GENMASK(13, 8)
623+#define MT_CONN_DBG_CTL_PC_LOG MT_CONN_DBG_CTL(0x204)
624+#define MT_CONN_DBG_CTL_GPR_LOG MT_CONN_DBG_CTL(0x204)
625+
626+/* CONN MCU EXCP CON */
627+#define MT_MCU_WM_EXCP_BASE 0x89050000
628+
629+#define MT_MCU_WM_EXCP(ofs) (MT_MCU_WM_EXCP_BASE + (ofs))
630+#define MT_MCU_WM_EXCP_PC_CTRL MT_MCU_WM_EXCP(0x100)
631+#define MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS GENMASK(20, 16)
632+#define MT_MCU_WM_EXCP_PC_LOG MT_MCU_WM_EXCP(0x104)
633+#define MT_MCU_WM_EXCP_LR_CTRL MT_MCU_WM_EXCP(0x200)
634+#define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS GENMASK(20, 16)
635+#define MT_MCU_WM_EXCP_LR_LOG MT_MCU_WM_EXCP(0x204)
636+
637 #endif
638--
6392.18.0
640