From: Daniel Golle Date: Tue, 18 Feb 2025 04:31:05 +0000 (+0000) Subject: generic: mtk_eth_soc: dump registers on forced reset X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=31dc43daf5e5fa11055806f6f23168b89487f812;p=openwrt%2Fopenwrt.git generic: mtk_eth_soc: dump registers on forced reset Import patch from MediaTek's SDK to hack-6.6 which dumps all relevant registers of the Ethernet controller in case of a forced reset. This can help to debug and find the cause for sporadic resets seen on Filogic SoCs when used with OpenWrt's Linux 6.6. Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/73d44392b8556c5fdd13728c1b56ce2abfe280df Signed-off-by: Daniel Golle --- diff --git a/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch b/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch new file mode 100644 index 0000000000..8a8a5c061a --- /dev/null +++ b/target/linux/generic/hack-6.6/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch @@ -0,0 +1,115 @@ +From bc51c337a3147c4a02c743489885a6657bc5371c Mon Sep 17 00:00:00 2001 +From: Bo-Cun Chen +Date: Wed, 27 Nov 2024 13:36:49 +0800 +Subject: [PATCH] net: ethernet: mtk_eth_soc: add hw dump for forced reset + +Without this patch, the ETH driver is unable to dump the registers +before triggering a forced reset. + +Signed-off-by: Bo-Cun Chen +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++++++++++++ + 1 files changed, 55 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -66,6 +66,7 @@ static const struct mtk_reg_map mtk_reg_ + .rx_ptr = 0x1900, + .rx_cnt_cfg = 0x1904, + .qcrx_ptr = 0x1908, ++ .page = 0x19f0, + .glo_cfg = 0x1a04, + .rst_idx = 0x1a08, + .delay_irq = 0x1a0c, +@@ -132,6 +133,7 @@ static const struct mtk_reg_map mt7986_r + .rx_ptr = 0x4500, + .rx_cnt_cfg = 0x4504, + .qcrx_ptr = 0x4508, ++ .page = 0x45f0, + .glo_cfg = 0x4604, + .rst_idx = 0x4608, + .delay_irq = 0x460c, +@@ -183,6 +185,7 @@ static const struct mtk_reg_map mt7988_r + .rx_ptr = 0x4500, + .rx_cnt_cfg = 0x4504, + .qcrx_ptr = 0x4508, ++ .page = 0x45f0, + .glo_cfg = 0x4604, + .rst_idx = 0x4608, + .delay_irq = 0x460c, +@@ -3885,6 +3888,56 @@ static void mtk_set_mcr_max_rx(struct mt + mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); + } + ++static void mtk_hw_dump_reg(struct mtk_eth *eth, char *name, u32 offset, u32 range) ++{ ++ u32 cur = offset; ++ ++ pr_info("\n==================== %s ====================\n", name); ++ while (cur < offset + range) { ++ pr_info("0x%08x: %08x %08x %08x %08x\n", ++ cur, mtk_r32(eth, cur), mtk_r32(eth, cur + 0x4), ++ mtk_r32(eth, cur + 0x8), mtk_r32(eth, cur + 0xc)); ++ cur += 0x10; ++ } ++} ++ ++static void mtk_hw_dump(struct mtk_eth *eth) ++{ ++ const struct mtk_reg_map *reg_map = eth->soc->reg_map; ++ u32 id; ++ ++ mtk_hw_dump_reg(eth, "FE", 0x0, 0x600); ++ mtk_hw_dump_reg(eth, "FE", 0x1400, 0x300); ++ mtk_hw_dump_reg(eth, "ADMA", reg_map->pdma.rx_ptr, 0x300); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { ++ for (id = 0; id < MTK_QDMA_NUM_QUEUES / 16; id++) { ++ mtk_w32(eth, id, reg_map->qdma.page); ++ pr_info("\nQDMA PAGE:%x ", mtk_r32(eth, reg_map->qdma.page)); ++ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.qtx_cfg, 0x100); ++ mtk_w32(eth, 0, reg_map->qdma.page); ++ } ++ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.rx_ptr, 0x300); ++ } ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { ++ mtk_hw_dump_reg(eth, "WDMA0", reg_map->wdma_base[0], 0x400); ++ mtk_hw_dump_reg(eth, "WDMA1", reg_map->wdma_base[1], 0x400); ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ mtk_hw_dump_reg(eth, "WDMA2", reg_map->wdma_base[2], 0x400); ++ } ++ mtk_hw_dump_reg(eth, "PPE0", reg_map->ppe_base + 0x200, 0x200); ++ if (!mtk_is_netsys_v1(eth)) ++ mtk_hw_dump_reg(eth, "PPE1", reg_map->ppe_base + 0x600, 0x200); ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ mtk_hw_dump_reg(eth, "PPE2", reg_map->ppe_base + 0xE00, 0x200); ++ mtk_hw_dump_reg(eth, "GMAC", 0x10000, 0x300); ++ if (mtk_is_netsys_v3_or_greater(eth)) ++ mtk_hw_dump_reg(eth, "GMAC", 0x10300, 0x100); ++ if (mtk_is_netsys_v3_or_greater(eth)) { ++ mtk_hw_dump_reg(eth, "XGMAC0", 0x12000, 0x300); ++ mtk_hw_dump_reg(eth, "XGMAC1", 0x13000, 0x300); ++ } ++} ++ + static void mtk_hw_reset(struct mtk_eth *eth) + { + u32 val; +@@ -4344,6 +4397,8 @@ static void mtk_pending_work(struct work + rtnl_lock(); + set_bit(MTK_RESETTING, ð->state); + ++ mtk_hw_dump(eth); ++ + mtk_prepare_for_reset(eth); + mtk_wed_fe_reset(); + /* Run again reset preliminary configuration in order to avoid any +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1172,6 +1172,7 @@ struct mtk_reg_map { + u32 rx_ptr; /* rx base pointer */ + u32 rx_cnt_cfg; /* rx max count configuration */ + u32 qcrx_ptr; /* rx cpu pointer */ ++ u32 page; /* page configuration */ + u32 glo_cfg; /* global configuration */ + u32 rst_idx; /* reset index */ + u32 delay_irq; /* delay interrupt */