* [PATCH v1 1/2] wifi: mt76: mt7925: Fix coredump size not enough issue
2026-08-05 9:25 [PATCH v1 0/2] wifi: mt76: mt7925: Fix coredump issue and add coredump end collect mechanism Eason Lai
@ 2026-08-05 9:25 ` Eason Lai
2026-08-05 9:25 ` [PATCH v1 2/2] wifi: mt76: mt7925: Add coredump end collect mechanism Eason Lai
1 sibling, 0 replies; 3+ messages in thread
From: Eason Lai @ 2026-08-05 9:25 UTC (permalink / raw)
To: nbd, lorenzo
Cc: linux-wireless, linux-mediatek, kun.wu, deren.wu, sean.wang,
quan.zhou, ryder.lee, leon.yen, litien.chang, jb.tsai, ck.chang,
eason.lai
From: "ck.chang" <ck.chang@mediatek.com>
Original allocate coredump file size is not enough to save all coredump content, change the code to dynamic allocate the coredump file size which equal to the actual coredump content size.
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: ck.chang <ck.chang@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7925/mac.c | 44 +++++++++++++------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index 101f571b027f..b5dd1b58618c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -1571,11 +1571,14 @@ void mt7925_mac_reset_work(struct work_struct *work)
void mt7925_coredump_work(struct work_struct *work)
{
+ size_t hdr_len = sizeof(struct mt7925_mcu_rxd) + 8;
+ struct sk_buff_head local_list;
struct mt792x_dev *dev;
+ struct sk_buff *skb;
+ size_t total_sz = 0;
char *dump, *data;
- dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev,
- coredump.work.work);
+ dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev, coredump.work.work);
if (time_is_after_jiffies(dev->coredump.last_activity +
4 * MT76_CONNAC_COREDUMP_TIMEOUT)) {
@@ -1584,35 +1587,48 @@ void mt7925_coredump_work(struct work_struct *work)
return;
}
- dump = vzalloc(MT76_CONNAC_COREDUMP_SZ);
+ skb_queue_head_init(&local_list);
+ spin_lock_bh(&dev->mt76.lock);
+ skb_queue_splice_init(&dev->coredump.msg_list, &local_list);
+ spin_unlock_bh(&dev->mt76.lock);
+
+ skb_queue_walk(&local_list, skb) {
+ if (skb->len > hdr_len)
+ total_sz += skb->len - hdr_len;
+ }
+
+ if (!total_sz) {
+ skb_queue_purge(&local_list);
+ goto reset;
+ }
+
+ dump = vzalloc(total_sz);
data = dump;
while (true) {
- struct sk_buff *skb;
-
- spin_lock_bh(&dev->mt76.lock);
- skb = __skb_dequeue(&dev->coredump.msg_list);
- spin_unlock_bh(&dev->mt76.lock);
+ skb = __skb_dequeue(&local_list);
if (!skb)
break;
- skb_pull(skb, sizeof(struct mt7925_mcu_rxd) + 8);
- if (!dump || data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
+ if (skb->len <= hdr_len) {
dev_kfree_skb(skb);
continue;
}
- memcpy(data, skb->data, skb->len);
- data += skb->len;
+ skb_pull(skb, hdr_len);
+ if (dump) {
+ memcpy(data, skb->data, skb->len);
+ data += skb->len;
+ }
dev_kfree_skb(skb);
}
if (dump)
- dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
- GFP_KERNEL);
+ dev_coredumpv(dev->mt76.dev, dump, total_sz, GFP_KERNEL);
+reset:
mt792x_reset(&dev->mt76);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH v1 2/2] wifi: mt76: mt7925: Add coredump end collect mechanism
2026-08-05 9:25 [PATCH v1 0/2] wifi: mt76: mt7925: Fix coredump issue and add coredump end collect mechanism Eason Lai
2026-08-05 9:25 ` [PATCH v1 1/2] wifi: mt76: mt7925: Fix coredump size not enough issue Eason Lai
@ 2026-08-05 9:25 ` Eason Lai
1 sibling, 0 replies; 3+ messages in thread
From: Eason Lai @ 2026-08-05 9:25 UTC (permalink / raw)
To: nbd, lorenzo
Cc: linux-wireless, linux-mediatek, kun.wu, deren.wu, sean.wang,
quan.zhou, ryder.lee, leon.yen, litien.chang, jb.tsai, ck.chang,
eason.lai
From: "ck.chang" <ck.chang@mediatek.com>
Add collect mechanism, when parse to specific coredump string, immediately save the collected coredump content into coredump file
Signed-off-by: ck.chang <ck.chang@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt76_connac.h | 1 +
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 8 +++++++-
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 10 +++++++++-
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index b1677ca24703..6374add14160 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -128,6 +128,7 @@ struct mt76_connac_coredump {
struct sk_buff_head msg_list;
struct delayed_work work;
unsigned long last_activity;
+ bool complete;
};
struct mt76_connac_sta_key_conf {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index b5dd1b58618c..77b6fa34a1ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -1580,12 +1580,18 @@ void mt7925_coredump_work(struct work_struct *work)
dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev, coredump.work.work);
- if (time_is_after_jiffies(dev->coredump.last_activity +
+ /* if received the last coredump payload or timeout, start
+ * saving coredump file and trigger reset.
+ * Otherwise, wait for other coredump payload coming
+ */
+ if (!dev->coredump.complete &&
+ time_is_after_jiffies(dev->coredump.last_activity +
4 * MT76_CONNAC_COREDUMP_TIMEOUT)) {
queue_delayed_work(dev->mt76.wq, &dev->coredump.work,
MT76_CONNAC_COREDUMP_TIMEOUT);
return;
}
+ dev->coredump.complete = false;
skb_queue_head_init(&local_list);
spin_lock_bh(&dev->mt76.lock);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index fa29c486a455..c4194c800dc6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -671,6 +671,7 @@ static void
mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
struct sk_buff *skb)
{
+#define COREDUMP_END_STR "; coredump end"
struct mt7925_mcu_rxd *rxd;
rxd = (struct mt7925_mcu_rxd *)skb->data;
@@ -700,10 +701,17 @@ mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
case MCU_UNI_EVENT_RSSI_MONITOR:
mt7925_mcu_rssi_monitor_event(dev, skb);
break;
- case MCU_UNI_EVENT_COREDUMP:
+ case MCU_UNI_EVENT_COREDUMP: {
+ size_t hdr_len = sizeof(struct mt7925_mcu_rxd) + 8;
+
dev->fw_assert = true;
+ if (skb->len > hdr_len &&
+ strnstr(skb->data + hdr_len, COREDUMP_END_STR,
+ skb->len - hdr_len))
+ dev->coredump.complete = true;
mt76_connac_mcu_coredump_event(&dev->mt76, skb, &dev->coredump);
return;
+ }
case MCU_UNI_EVENT_NAN:
mt7925_nan_mcu_event(dev, skb);
break;
--
2.45.2
^ permalink raw reply related [flat|nested] 3+ messages in thread