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