blob: b646d6751df65d59d86ff8825d43ceceef4104e5 [file] [log] [blame]
From a15a9b160d9bb9b52cb697251777c5c39f842f24 Mon Sep 17 00:00:00 2001
From: Bo Jiao <Bo.Jiao@mediatek.com>
Date: Mon, 22 May 2023 13:49:37 +0800
Subject: [PATCH] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
---
mt76.h | 11 +++
mt76_connac_mcu.c | 9 +++
mt7915/coredump.c | 169 +++++++++++++++++++++++++++++++---------------
mt7915/coredump.h | 34 +++++++---
mt7915/mac.c | 33 ++++++---
mt7915/mt7915.h | 2 +-
mt7915/regs.h | 20 ++++++
7 files changed, 207 insertions(+), 71 deletions(-)
diff --git a/mt76.h b/mt76.h
index 3f13cec6..354acc09 100644
--- a/mt76.h
+++ b/mt76.h
@@ -27,6 +27,8 @@
#define MT76_TOKEN_FREE_THR 64
+#define MT76_BUILD_TIME_LEN 24
+
#define MT_QFLAG_WED_RING GENMASK(1, 0)
#define MT_QFLAG_WED_TYPE GENMASK(3, 2)
#define MT_QFLAG_WED BIT(4)
@@ -54,6 +56,12 @@ enum mt76_bus_type {
MT76_BUS_SDIO,
};
+enum mt76_ram_type {
+ MT76_RAM_TYPE_WM,
+ MT76_RAM_TYPE_WA,
+ __MT76_RAM_TYPE_MAX,
+};
+
enum mt76_wed_type {
MT76_WED_Q_TX,
MT76_WED_Q_TXFREE,
@@ -776,6 +784,9 @@ struct mt76_dev {
struct device *dma_dev;
struct mt76_mcu mcu;
+ struct mt76_connac2_patch_hdr *patch_hdr;
+ struct mt76_connac2_fw_trailer *wm_hdr;
+ struct mt76_connac2_fw_trailer *wa_hdr;
struct net_device napi_dev;
struct net_device tx_napi_dev;
diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
index 46f69aa8..913bad95 100644
--- a/mt76_connac_mcu.c
+++ b/mt76_connac_mcu.c
@@ -3017,6 +3017,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
goto out;
}
+ dev->wm_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
+ memcpy(dev->wm_hdr, hdr, sizeof(*hdr));
+
snprintf(dev->hw->wiphy->fw_version,
sizeof(dev->hw->wiphy->fw_version),
"%.10s-%.15s", hdr->fw_ver, hdr->build_date);
@@ -3046,6 +3049,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
goto out;
}
+ dev->wa_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
+ memcpy(dev->wa_hdr, hdr, sizeof(*hdr));
+
snprintf(dev->hw->wiphy->fw_version,
sizeof(dev->hw->wiphy->fw_version),
"%.10s-%.15s", hdr->fw_ver, hdr->build_date);
@@ -3116,6 +3122,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
+ dev->patch_hdr = devm_kzalloc(dev->dev, sizeof(*hdr), GFP_KERNEL);
+ memcpy(dev->patch_hdr, hdr, sizeof(*hdr));
+
for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
struct mt76_connac2_patch_sec *sec;
u32 len, addr, mode;
diff --git a/mt7915/coredump.c b/mt7915/coredump.c
index 5daf2258..298c1cad 100644
--- a/mt7915/coredump.c
+++ b/mt7915/coredump.c
@@ -7,7 +7,7 @@
#include <linux/utsname.h>
#include "coredump.h"
-static bool coredump_memdump;
+static bool coredump_memdump = true;
module_param(coredump_memdump, bool, 0644);
MODULE_PARM_DESC(coredump_memdump, "Optional ability to dump firmware memory");
@@ -86,8 +86,11 @@ static const struct mt7915_mem_region mt798x_mem_regions[] = {
};
const struct mt7915_mem_region*
-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num)
{
+ if (type == MT76_RAM_TYPE_WA)
+ return NULL;
+
switch (mt76_chip(&dev->mt76)) {
case 0x7915:
*num = ARRAY_SIZE(mt7915_mem_regions);
@@ -104,14 +107,14 @@ mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
}
}
-static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev)
+static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev, u8 type)
{
const struct mt7915_mem_region *mem_region;
size_t size = 0;
u32 num;
int i;
- mem_region = mt7915_coredump_get_mem_layout(dev, &num);
+ mem_region = mt7915_coredump_get_mem_layout(dev, type, &num);
if (!mem_region)
return 0;
@@ -128,9 +131,9 @@ static int mt7915_coredump_get_mem_size(struct mt7915_dev *dev)
return size;
}
-struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
+struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type)
{
- struct mt7915_crash_data *crash_data = dev->coredump.crash_data;
+ struct mt7915_crash_data *crash_data = dev->coredump.crash_data[type];
lockdep_assert_held(&dev->dump_mutex);
@@ -141,12 +144,15 @@ struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
}
static void
-mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
+mt7915_coredump_fw_state(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
bool *exception)
{
- u32 state, count, type;
+ u32 state, count, category;
+
+ if (type == MT76_RAM_TYPE_WA)
+ return;
- type = (u32)mt76_get_field(dev, MT_FW_EXCEPT_TYPE, GENMASK(7, 0));
+ category = (u32)mt76_get_field(dev, MT_FW_EXCEPT_TYPE, GENMASK(7, 0));
state = (u32)mt76_get_field(dev, MT_FW_ASSERT_STAT, GENMASK(7, 0));
count = is_mt7915(&dev->mt76) ?
(u32)mt76_get_field(dev, MT_FW_EXCEPT_COUNT, GENMASK(15, 8)) :
@@ -155,7 +161,7 @@ mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
/* normal mode: driver can manually trigger assertĀ for detail info */
if (!count)
strscpy(dump->fw_state, "normal", sizeof(dump->fw_state));
- else if (state > 1 && (count == 1) && type == 5)
+ else if (state > 1 && (count == 1) && category == 5)
strscpy(dump->fw_state, "assert", sizeof(dump->fw_state));
else if ((state > 1 && count == 1) || count > 1)
strscpy(dump->fw_state, "exception", sizeof(dump->fw_state));
@@ -164,11 +170,14 @@ mt7915_coredump_fw_state(struct mt7915_dev *dev, struct mt7915_coredump *dump,
}
static void
-mt7915_coredump_fw_trace(struct mt7915_dev *dev, struct mt7915_coredump *dump,
+mt7915_coredump_fw_trace(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
bool exception)
{
u32 n, irq, sch, base = MT_FW_EINT_INFO;
+ if (type == MT76_RAM_TYPE_WA)
+ return;
+
/* trap or run? */
dump->last_msg_id = mt76_rr(dev, MT_FW_LAST_MSG_ID);
@@ -221,31 +230,61 @@ mt7915_coredump_fw_trace(struct mt7915_dev *dev, struct mt7915_coredump *dump,
}
static void
-mt7915_coredump_fw_stack(struct mt7915_dev *dev, struct mt7915_coredump *dump,
+mt7915_coredump_fw_stack(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump,
bool exception)
{
- u32 oldest, i, idx;
+ u32 reg, i;
+
+ if (type == MT76_RAM_TYPE_WA)
+ return;
+
+ /* read current PC */
+ mt76_rmw_field(dev, MT_CONN_DBG_CTL_LOG_SEL,
+ MT_CONN_DBG_CTL_PC_LOG_SEL, 0x22);
+ for (i = 0; i < 10; i++) {
+ dump->pc_cur[i] = mt76_rr(dev, MT_CONN_DBG_CTL_PC_LOG);
+ usleep_range(100, 500);
+ }
/* stop call stack record */
- if (!exception)
- mt76_clear(dev, 0x89050200, BIT(0));
+ if (!exception) {
+ mt76_clear(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
+ mt76_clear(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
+ }
- oldest = (u32)mt76_get_field(dev, 0x89050200, GENMASK(20, 16)) + 2;
- for (i = 0; i < 16; i++) {
- idx = ((oldest + 2 * i + 1) % 32);
- dump->call_stack[i] = mt76_rr(dev, 0x89050204 + idx * 4);
+ /* read PC log */
+ dump->pc_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_PC_CTRL);
+ dump->pc_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS,
+ dump->pc_dbg_ctrl);
+ for (i = 0; i < 32; i++) {
+ reg = MT_MCU_WM_EXCP_PC_LOG + i * 4;
+ dump->pc_stack[i] = mt76_rr(dev, reg);
+ }
+
+ /* read LR log */
+ dump->lr_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_LR_CTRL);
+ dump->lr_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS,
+ dump->lr_dbg_ctrl);
+ for (i = 0; i < 32; i++) {
+ reg = MT_MCU_WM_EXCP_LR_LOG + i * 4;
+ dump->lr_stack[i] = mt76_rr(dev, reg);
}
/* start call stack record */
- if (!exception)
- mt76_set(dev, 0x89050200, BIT(0));
+ if (!exception) {
+ mt76_set(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
+ mt76_set(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
+ }
}
static void
-mt7915_coredump_fw_task(struct mt7915_dev *dev, struct mt7915_coredump *dump)
+mt7915_coredump_fw_task(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump)
{
u32 offs = is_mt7915(&dev->mt76) ? 0xe0 : 0x170;
+ if (type == MT76_RAM_TYPE_WA)
+ return;
+
strscpy(dump->task_qid, "(task queue id) read, write",
sizeof(dump->task_qid));
@@ -266,10 +305,13 @@ mt7915_coredump_fw_task(struct mt7915_dev *dev, struct mt7915_coredump *dump)
}
static void
-mt7915_coredump_fw_context(struct mt7915_dev *dev, struct mt7915_coredump *dump)
+mt7915_coredump_fw_context(struct mt7915_dev *dev, u8 type, struct mt7915_coredump *dump)
{
u32 count, idx, id;
+ if (type == MT76_RAM_TYPE_WA)
+ return;
+
count = mt76_rr(dev, MT_FW_CIRQ_COUNT);
/* current context */
@@ -299,9 +341,10 @@ mt7915_coredump_fw_context(struct mt7915_dev *dev, struct mt7915_coredump *dump)
}
}
-static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
+static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev, u8 type)
{
- struct mt7915_crash_data *crash_data = dev->coredump.crash_data;
+ struct mt76_dev *mdev = &dev->mt76;
+ struct mt7915_crash_data *crash_data = dev->coredump.crash_data[type];
struct mt7915_coredump *dump;
struct mt7915_coredump_mem *dump_mem;
size_t len, sofar = 0, hdr_len = sizeof(*dump);
@@ -326,23 +369,34 @@ static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
dump = (struct mt7915_coredump *)(buf);
dump->len = len;
+ dump->hdr_len = hdr_len;
/* plain text */
strscpy(dump->magic, "mt76-crash-dump", sizeof(dump->magic));
strscpy(dump->kernel, init_utsname()->release, sizeof(dump->kernel));
- strscpy(dump->fw_ver, dev->mt76.hw->wiphy->fw_version,
+ strscpy(dump->fw_ver, mdev->hw->wiphy->fw_version,
sizeof(dump->fw_ver));
+ strscpy(dump->fw_type, ((type == MT76_RAM_TYPE_WA) ? "WA" : "WM"),
+ sizeof(dump->fw_type));
+ strscpy(dump->fw_patch_date, mdev->patch_hdr->build_date,
+ sizeof(dump->fw_patch_date));
+ strscpy(dump->fw_ram_date[MT76_RAM_TYPE_WM],
+ mdev->wm_hdr->build_date,
+ sizeof(mdev->wm_hdr->build_date));
+ strscpy(dump->fw_ram_date[MT76_RAM_TYPE_WA],
+ mdev->wa_hdr->build_date,
+ sizeof(mdev->wa_hdr->build_date));
guid_copy(&dump->guid, &crash_data->guid);
dump->tv_sec = crash_data->timestamp.tv_sec;
dump->tv_nsec = crash_data->timestamp.tv_nsec;
dump->device_id = mt76_chip(&dev->mt76);
- mt7915_coredump_fw_state(dev, dump, &exception);
- mt7915_coredump_fw_trace(dev, dump, exception);
- mt7915_coredump_fw_task(dev, dump);
- mt7915_coredump_fw_context(dev, dump);
- mt7915_coredump_fw_stack(dev, dump, exception);
+ mt7915_coredump_fw_state(dev, type, dump, &exception);
+ mt7915_coredump_fw_trace(dev, type, dump, exception);
+ mt7915_coredump_fw_task(dev, type, dump);
+ mt7915_coredump_fw_context(dev, type, dump);
+ mt7915_coredump_fw_stack(dev, type, dump, exception);
/* gather memory content */
dump_mem = (struct mt7915_coredump_mem *)(buf + sofar);
@@ -356,17 +410,19 @@ static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
return dump;
}
-int mt7915_coredump_submit(struct mt7915_dev *dev)
+int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type)
{
struct mt7915_coredump *dump;
- dump = mt7915_coredump_build(dev);
+ dump = mt7915_coredump_build(dev, type);
if (!dump) {
dev_warn(dev->mt76.dev, "no crash dump data found\n");
return -ENODATA;
}
dev_coredumpv(dev->mt76.dev, dump, dump->len, GFP_KERNEL);
+ dev_info(dev->mt76.dev, "%s coredump completed\n",
+ wiphy_name(dev->mt76.hw->wiphy));
return 0;
}
@@ -374,23 +430,26 @@ int mt7915_coredump_submit(struct mt7915_dev *dev)
int mt7915_coredump_register(struct mt7915_dev *dev)
{
struct mt7915_crash_data *crash_data;
+ int i;
- crash_data = vzalloc(sizeof(*dev->coredump.crash_data));
- if (!crash_data)
- return -ENOMEM;
+ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) {
+ crash_data = vzalloc(sizeof(*dev->coredump.crash_data[i]));
+ if (!crash_data)
+ return -ENOMEM;
- dev->coredump.crash_data = crash_data;
+ dev->coredump.crash_data[i] = crash_data;
- if (coredump_memdump) {
- crash_data->memdump_buf_len = mt7915_coredump_get_mem_size(dev);
- if (!crash_data->memdump_buf_len)
- /* no memory content */
- return 0;
+ if (coredump_memdump) {
+ crash_data->memdump_buf_len = mt7915_coredump_get_mem_size(dev, i);
+ if (!crash_data->memdump_buf_len)
+ /* no memory content */
+ return 0;
- crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
- if (!crash_data->memdump_buf) {
- vfree(crash_data);
- return -ENOMEM;
+ crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
+ if (!crash_data->memdump_buf) {
+ vfree(crash_data);
+ return -ENOMEM;
+ }
}
}
@@ -399,13 +458,17 @@ int mt7915_coredump_register(struct mt7915_dev *dev)
void mt7915_coredump_unregister(struct mt7915_dev *dev)
{
- if (dev->coredump.crash_data->memdump_buf) {
- vfree(dev->coredump.crash_data->memdump_buf);
- dev->coredump.crash_data->memdump_buf = NULL;
- dev->coredump.crash_data->memdump_buf_len = 0;
- }
+ int i;
- vfree(dev->coredump.crash_data);
- dev->coredump.crash_data = NULL;
+ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) {
+ if (dev->coredump.crash_data[i]->memdump_buf) {
+ vfree(dev->coredump.crash_data[i]->memdump_buf);
+ dev->coredump.crash_data[i]->memdump_buf = NULL;
+ dev->coredump.crash_data[i]->memdump_buf_len = 0;
+ }
+
+ vfree(dev->coredump.crash_data[i]);
+ dev->coredump.crash_data[i] = NULL;
+ }
}
diff --git a/mt7915/coredump.h b/mt7915/coredump.h
index 709f8e9c..809ccbdf 100644
--- a/mt7915/coredump.h
+++ b/mt7915/coredump.h
@@ -4,6 +4,7 @@
#ifndef _COREDUMP_H_
#define _COREDUMP_H_
+#include "../mt76_connac_mcu.h"
#include "mt7915.h"
struct trace {
@@ -15,6 +16,7 @@ struct mt7915_coredump {
char magic[16];
u32 len;
+ u32 hdr_len;
guid_t guid;
@@ -26,12 +28,28 @@ struct mt7915_coredump {
char kernel[64];
/* firmware version */
char fw_ver[ETHTOOL_FWVERS_LEN];
+ char fw_patch_date[MT76_BUILD_TIME_LEN];
+ char fw_ram_date[__MT76_RAM_TYPE_MAX][MT76_BUILD_TIME_LEN];
u32 device_id;
+ /* fw type */
+ char fw_type[8];
/* exception state */
char fw_state[12];
+ /* program counters */
+ u32 pc_dbg_ctrl;
+ u32 pc_cur_idx;
+ u32 pc_cur[10];
+ /* PC registers */
+ u32 pc_stack[32];
+
+ u32 lr_dbg_ctrl;
+ u32 lr_cur_idx;
+ /* LR registers */
+ u32 lr_stack[32];
+
u32 last_msg_id;
u32 eint_info_idx;
u32 irq_info_idx;
@@ -70,9 +88,6 @@ struct mt7915_coredump {
u32 handler;
} context;
- /* link registers calltrace */
- u32 call_stack[16];
-
/* memory content */
u8 data[];
} __packed;
@@ -83,6 +98,7 @@ struct mt7915_coredump_mem {
} __packed;
struct mt7915_mem_hdr {
+ char name[64];
u32 start;
u32 len;
u8 data[];
@@ -98,26 +114,26 @@ struct mt7915_mem_region {
#ifdef CONFIG_DEV_COREDUMP
const struct mt7915_mem_region *
-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num);
-struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev);
-int mt7915_coredump_submit(struct mt7915_dev *dev);
+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num);
+struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type);
+int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type);
int mt7915_coredump_register(struct mt7915_dev *dev);
void mt7915_coredump_unregister(struct mt7915_dev *dev);
#else /* CONFIG_DEV_COREDUMP */
static inline const struct mt7915_mem_region *
-mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
+mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u8 type, u32 *num)
{
return NULL;
}
-static inline int mt7915_coredump_submit(struct mt7915_dev *dev)
+static inline int mt7915_coredump_submit(struct mt7915_dev *dev, u8 type)
{
return 0;
}
-static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
+static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev, u8 type)
{
return NULL;
}
diff --git a/mt7915/mac.c b/mt7915/mac.c
index a3ed4ddf..2a87b506 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -1653,28 +1653,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
}
/* firmware coredump */
-void mt7915_mac_dump_work(struct work_struct *work)
+static void mt7915_mac_fw_coredump(struct mt7915_dev *dev, u8 type)
{
const struct mt7915_mem_region *mem_region;
struct mt7915_crash_data *crash_data;
- struct mt7915_dev *dev;
struct mt7915_mem_hdr *hdr;
size_t buf_len;
int i;
u32 num;
u8 *buf;
- dev = container_of(work, struct mt7915_dev, dump_work);
+ if (type != MT76_RAM_TYPE_WM) {
+ dev_warn(dev->mt76.dev, "%s currently only supports WM coredump!\n",
+ wiphy_name(dev->mt76.hw->wiphy));
+ return;
+ }
mutex_lock(&dev->dump_mutex);
- crash_data = mt7915_coredump_new(dev);
+ crash_data = mt7915_coredump_new(dev, type);
if (!crash_data) {
mutex_unlock(&dev->dump_mutex);
- goto skip_coredump;
+ return;
}
- mem_region = mt7915_coredump_get_mem_layout(dev, &num);
+ mem_region = mt7915_coredump_get_mem_layout(dev, type, &num);
if (!mem_region || !crash_data->memdump_buf_len) {
mutex_unlock(&dev->dump_mutex);
goto skip_memdump;
@@ -1684,6 +1687,9 @@ void mt7915_mac_dump_work(struct work_struct *work)
buf_len = crash_data->memdump_buf_len;
/* dumping memory content... */
+ dev_info(dev->mt76.dev, "%s start coredump for %s\n",
+ wiphy_name(dev->mt76.hw->wiphy),
+ ((type == MT76_RAM_TYPE_WA) ? "WA" : "WM"));
memset(buf, 0, buf_len);
for (i = 0; i < num; i++) {
if (mem_region->len > buf_len) {
@@ -1701,6 +1707,7 @@ void mt7915_mac_dump_work(struct work_struct *work)
mt7915_memcpy_fromio(dev, buf, mem_region->start,
mem_region->len);
+ strscpy(hdr->name, mem_region->name, sizeof(mem_region->name));
hdr->start = mem_region->start;
hdr->len = mem_region->len;
@@ -1717,8 +1724,18 @@ void mt7915_mac_dump_work(struct work_struct *work)
mutex_unlock(&dev->dump_mutex);
skip_memdump:
- mt7915_coredump_submit(dev);
-skip_coredump:
+ mt7915_coredump_submit(dev, type);
+}
+
+void mt7915_mac_dump_work(struct work_struct *work)
+{
+ struct mt7915_dev *dev;
+
+ dev = container_of(work, struct mt7915_dev, dump_work);
+
+ if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WM_WDT)
+ mt7915_mac_fw_coredump(dev, MT76_RAM_TYPE_WM);
+
queue_work(dev->mt76.wq, &dev->reset_work);
}
diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
index 54510245..4fb0a375 100644
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -335,7 +335,7 @@ struct mt7915_dev {
struct mutex dump_mutex;
#ifdef CONFIG_DEV_COREDUMP
struct {
- struct mt7915_crash_data *crash_data;
+ struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX];
} coredump;
#endif
diff --git a/mt7915/regs.h b/mt7915/regs.h
index 374677f7..636b12da 100644
--- a/mt7915/regs.h
+++ b/mt7915/regs.h
@@ -1215,4 +1215,24 @@ enum offs_rev {
#define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x108)
#define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR MT_MCU_WM_CIRQ(0x118)
+/* CONN DBG */
+#define MT_CONN_DBG_CTL_BASE 0x18060000
+#define MT_CONN_DBG_CTL(ofs) (MT_CONN_DBG_CTL_BASE + (ofs))
+#define MT_CONN_DBG_CTL_LOG_SEL MT_CONN_DBG_CTL(0x090)
+#define MT_CONN_DBG_CTL_PC_LOG_SEL GENMASK(7, 2)
+#define MT_CONN_DBG_CTL_GPR_LOG_SEL GENMASK(13, 8)
+#define MT_CONN_DBG_CTL_PC_LOG MT_CONN_DBG_CTL(0x204)
+#define MT_CONN_DBG_CTL_GPR_LOG MT_CONN_DBG_CTL(0x204)
+
+/* CONN MCU EXCP CON */
+#define MT_MCU_WM_EXCP_BASE 0x89050000
+
+#define MT_MCU_WM_EXCP(ofs) (MT_MCU_WM_EXCP_BASE + (ofs))
+#define MT_MCU_WM_EXCP_PC_CTRL MT_MCU_WM_EXCP(0x100)
+#define MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS GENMASK(20, 16)
+#define MT_MCU_WM_EXCP_PC_LOG MT_MCU_WM_EXCP(0x104)
+#define MT_MCU_WM_EXCP_LR_CTRL MT_MCU_WM_EXCP(0x200)
+#define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS GENMASK(20, 16)
+#define MT_MCU_WM_EXCP_LR_LOG MT_MCU_WM_EXCP(0x204)
+
#endif
--
2.18.0