ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RK3566以太网DMA初始化失败排查:从设备树到PHY链路

RK3566以太网DMA初始化失败排查:从设备树到PHY链路 1. 报错的现场先搞清楚日志从哪来、意味着什么先直接看报错日志长什么样。常见是在 Android 11 启动阶段的内核日志里也就是 dmesg 或者串口 log刷出这么一行rk_gmac-dwmac fe2a0000.ethernet: DMA engine initialization failed注意前面还有个驱动前缀不同 SDK 版本可能略有差异。有的平台打印是stmmaceth: DMA engine initialization failed也有的把地址段换了比如 fe010000.ethernet、fe2a0000.ethernet这都正常取决于 RK3566 上你到底用的是哪个 MAC 控制器。看到这行日志后不要慌它只是最终结果真正原因在这行日志之前的十几行里。先讲日志怎么抓。正常情况下RK3566 的 Android 11 系统开机时网口驱动就已经在跑如果你有串口直接在串口终端看到全部启动日志是最省事的。如果没有串口那就进系统后用 adb shell 抓adb shell dmesg | grep -i eth\|dma\|stmmac\|gmac\|rk_gmac如果要看完整启动阶段的网络初始化日志最好在驱动加载的时间点抓不然等系统完全起来dmesg 的 ring buffer 可能已经被刷掉一部分。这里有个实操小技巧Android 系统里 dmesg 权限通常受限制需要 root 或者至少是 userdebug 版本否则看不到内核日志。我一般习惯在 BoardConfig.mk 里把内核 cmdline 加上 ignore_loglevel同时把 consolettyFIQ0,115200 保留方便串口完整输出。另外Android 11 上主网口驱动以太网是跑在 kernel 里的所以 logcat 里基本看不到这个报错除非上层 EthernetService 在尝试打开网络时失败会出现类似 Ethernet network is lost 之类的提示。核心还是看 dmesg。拿到日志后关键不只是最后一行而是从“probe”开始的所有网络相关输出。我一般会这样过滤把所有网络初始化相关的行一次列出dmesg | grep -iE eth|gmac|stmmac|dma|clk|mdio|phy|reset | head -100这样能很快定位问题发生的阶段。2. “DMA engine initialization failed”背后的完整链路解析要解决这个报错咱们得先搞明白这行日志到底在说什么。2.1 RK3566 上其实有两个 MAC 控制器别搞混RK3566 的 TRM 里写得很清楚这个 SoC 集成了两个以太网 MACGMAC1对应设备树节点通常是 gmac1基地址一般是 fe010000.ethernet不同 SDK 可能叫法不同。GMAC0基地址一般是 fe2a0000.ethernet在部分开发板上被配置成 RMII 接口也有配置成 RGMII 的。你看到的报错地址是 fe2a0000那就是 GMAC0。是 fe010000就是 GMAC1。这两个控制器在软件配置上都要走 stmmac 驱动硬件上内部集成了 DMA 引擎、MAC 核、以及 MDIO 控制器只是对外接口和时钟源不一样。DMA engine 这个词就是 stmmac 驱动框架里的 DMA 控制器模块。RK3566 的 GMAC 使用的是 Synopsys DesignWare MAC 的 IP驱动是内核标准驱动 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c。这个驱动框架里有一个函数叫 stmmac_dma_engine_init专门负责初始化 DMA 控制器。如果这个函数里面发生任何失败驱动就会直接打出 “DMA engine initialization failed” 然后 probe 失败。所以可以初步判定这行日志是在驱动 probe 流程中打印的不是网络运行时的错误。也就是说网口驱动根本没有初始化成功网口自然也不会出现。2.2 stmmac 驱动的启动时序把 stmmac 驱动的 probe 流程理清楚排查才能有的放矢。核心过程大致是平台驱动匹配设备树节点解析 reg、interrupt、phy-mode、clock-names 等属性。获取时钟资源通过 clk_prepare_enable 启动相关时钟。获取复位信号deassert 复位如果有。MDIO 总线注册扫描总线上的 PHY。PHY 连接协商模式配置RGMII/RMII、速率。stmmac_open 或 probe 阶段的 DMA 初始化。stmmac 驱动的 DMA 初始化函数核心路径长这样源码摘自内核 stmmac_main.cstatic int stmmac_dma_engine_init(struct stmmac_priv *priv) { /* 初始化 DMA 接收/发送描述符 */ ret stmmac_init_dma_engine(priv); if (ret 0) { dev_err(priv-device, DMA engine initialization failed\n); return ret; } ... }而 stmmac_init_dma_engine 内部做的事情大体是初始化 DMA 控制器的描述符、使能 DMA 中断、配置总线模式还有 DMA 控制器的几个关键寄存器写入。很多人在这个阶段犯迷糊以为 DMA engine 报错就是硬件 DMA 坏了。实际上这个函数失败的原因非常多样最常见的是 ** 基础资源根本没有就绪 **比如时钟没起来、PHY 没有探测到、复位信号一直拉死都会导致后续 DMA 初始化没有意义或者直接失败。2.3 日志中出现 DMA 失败之前到底还发生了什么实战中看日志最有价值的不是那一行最终错误而是它前面的信息。举个例子一份典型的失败日志如下[rootrockchip-rk3566:/]# dmesg | grep -iE eth|gmac|stmmac|dma|mdio|phy [ 1.238974] rk_gmac-dwmac fe2a0000.ethernet: no reset control found [ 1.246014] rk_gmac-dwmac fe2a0000.ethernet: IRQ eth_wake_irq not found [ 1.253666] rk_gmac-dwmac fe2a0000.ethernet: no reset control found [ 1.260997] rk_gmac-dwmac fe2a0000.ethernet: device MAC address xx:xx:xx:xx:xx:xx [ 1.270063] rk_gmac-dwmac fe2a0000.ethernet: clock input frequency is 125000000 [ 1.278140] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk tx [ 1.284452] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk rx [ 1.291227] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk ref [ 1.298159] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk phy [ 1.305841] rk_gmac-dwmac fe2a0000.ethernet: failed to get clks [ 1.313477] rk_gmac-dwmac fe2a0000.ethernet: DMA engine initialization failed这种情况下根因一目了然 —— 时钟没配好。驱动要的 clock-names 在设备树里没给全导致 clk_get 返回错误最终 DMA 初始化失败。这基本是设备树问题不是硬件问题。还有一种类似情况[ 1.238974] rk_gmac-dwmac fe2a0000.ethernet: clk tx not found [ 1.245032] rk_gmac-dwmac fe2a0000.ethernet: PHY ID not found at address 1 [ 1.253056] rk_gmac-dwmac fe2a0000.ethernet: stmmac_open: Cannot attach to PHY (error -19)PHY 没被找到网口数据通路建立不起来DMA 初始化自然也会失败或后续无法正常发包收包。这是第二大类根因** 物理层链路问题 **。所以遇到 DMA 报错第一步不是怀疑 DMA 本身而是要顺着日志往前找看基础资源是不是齐了。这就好比开车打不着火你查了半天火花塞结果发现油箱是空的。3. 排查思路全拆解从设备树到时钟配置一步步验证下面这套排查思路是我自己在 RK3566 多款板卡上反复用过的遇到类似报错基本能定位到根因。不要一上来就改内核代码先从最简单的环节查起。3.1 确认设备树节点与使用端口拿到板子先确认你用的是哪个 GMAC 口。RK3566 的 evb 公版设备树一般同时有 gmac0 和 gmac1 两个节点。但市面上的核心板未必都引出了两个口很多底板只做了一个网口。查设备树里的以太网节点cat /proc/device-tree/gmac1/status cat /proc/device-tree/gmac0/status如果 status 是 disabled驱动不会跑自然也没有 DMA 报错。这个报错出现的前提是 status 为 okay。如果两个节点都是 okay但硬件上只接了一个口另一个口会因为缺少 PHY 或时钟配置报各种错误扫一眼就能分辨。设备树里最关键的属性phy-mode rgmii; // 或 rmii clock_in_out input; // 或 output snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; // PHY 复位 snps,reset-delays-us 0 10000 50000; // 复位时序还要看 mdio 节点下的 PHY 描述mdio { compatible snps,dwmac-mdio; #address-cells 1; #size-cells 0; phy: ethernet-phy0 { reg 0; ... }; };如果这里 PHY 地址和硬件实际地址不匹配后面会反复 PHY probe 失败。先插一句我的经验RK3566 的方案里** 90% 的 DMA engine initialization failed 都不是 DMA 本身的问题**。要么是时钟没配好要么是 PHY 没贴好或地址不对要么是网口变压器到 MAC 的走线有问题导致 MDIO 读到全 F。建议先用一个最简单的检查看 CPU 能不能通过 MDIO 读到 PHY 的 ID。很多 SDK 的驱动在 stmmac_mdio_register 失败时会打日志mdio_bus: mdiofe2a0000: mdio probe failed如果没有这行说明 MDIO 总线本身是通的。如果连这行都没有大概率是设备树里 mdio 子节点配置不对或者 MAC 的 MDIO 引脚配置有问题。3.2 时钟配置是最常见的坑一条条对RK3566 GMAC 的时钟体系是排查重点。和别的 SoC 相比RK3566 的 GMAC 时钟比较麻烦因为它的 RMII/RGMII 参考时钟源选择很灵活既可以从 SoC 内部输出也可以从外部 PHY 回传。时钟是否正常第一步看启动日志里的频率信息clock input frequency is 125000000如果这个频率不对比如 RGMII 应该 125MHz你看到了 25MHz说明时钟树配置有问题DMA 初始化不会成功。然后看驱动到底拿没拿到时钟。RK3566 的公版设备树里网口节点的时钟定义大致如下clocks cru CLK_GMAC0, cru CLK_GMAC0_PTP; clock-names stmmaceth, ptp_ref;但有些 SDK 版本把 GMAC0 的时钟拆得比较细比如clocks cru CLK_GMAC0, cru CLK_GMAC0_PTP; assigned-clocks cru CLK_GMAC0, cru CLK_GMAC0_PTP; assigned-clock-rates 125000000, 125000000;另一部分版本则要求辅助时钟比如clocks cru CLK_GMAC0, cru SCLK_GMAC0, cru PCLK_GMAC0; clock-names stmmaceth, mac_clk, pclk;这里就是问题高发区。如果设备树里代码是从某个 3568 的 SDK 拷贝过来的或者是从旧内核版本切过来的clock-names 对不上驱动在 clk_get 时就会失败然后在代码里直接跳过时钟配置后面就可能出 DMA 初始化失败。这种排查看日志最直接。如果在启动日志里有cannot get clk tx cannot get clk rx cannot get clk ref cannot get clk phy那就是设备树 clk 配置与驱动代码不匹配。你去看内核源码 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 或者 RK 自己维护的 dwmac-rk.c里面会列出它需要的 clock-names。RK3566 的 dwmac-rk.c 中常见时钟名包括stmmacethMAC 主时钟。mac_clkMAC 时钟。pclk外设总线时钟。clk_mac_ref参考时钟。clk_mac_speed速率时钟。ptp_refPTP 参考时钟。如果设备树没给全驱动会一边打 warning 一边继续跑。有些版本的驱动对某些时钟要求是“必须”缺失就会后续报错有些是“可选”缺失只打一行 warning。具体要看代码里的 devm_clk_get 返回值处理是if (IS_ERR()) return PTR_ERR()还是只打日志。一句话总结 ** 遇到 DMA 报错先确认设备树节点里 clocks 和 clock-names 与当前 SDK 的 dwmac-rk.c 完全一致 **。这是命中率最高的根因。3.3 PHY 链路与复位时序核查PHY 是 DMA 报错之外的第二个重灾区。很多 RK3566 方案使用的 PHY 是裕太微的 YT8531、瑞昱的 RTL8211F、或者国产的 IP101GRI 等不同 PHY 对复位时序、参考时钟要求差别很大。先说最简单也是最容易忽略的PHY 的复位 GPIO。在设备树里RK 的 GMAC 驱动支持通过 snps,reset-gpio 等属性来控制 PHY 复位。但如果你的 PHY 复位引脚没有接到 SoC 的 GPIO而是用 RC 延时电路或者由其他器件控制那么设备树里就不应该配置 reset-gpio否则驱动在初始化 PHY 时会先做一次复位而这次复位如果和电源时序冲突会导致 PHY 一直处于复位或者未就绪状态。检查 PHY 有没有被正确识别可以在板子上电后通过 MDIO 工具直接读。RK3566 的 Linux 内核通常打开 mdio 工具支持。如果没有工具也可以在内核启动日志里找[ 1.305841] rk_gmac-dwmac fe2a0000.ethernet: PHY [stmmac-0:02] driver [YT8531] (irqPOLL)如果能看到 PHY 驱动被正确绑定说明链路是通的。如果看到mdio_bus: mdiofe2a0000: PHY ID 0xffffffff at address 2说明 MDIO 读不到 PHY 的 ID那就是硬件问题要么 PHY 没上电要么复位一直有效要么 MDIO/时钟线虚焊。这时候 DMA 初始化报错只是结果不是原因。还有一类情况是 PHY 地址冲突。YT8531 的地址由硬件引脚决定一般为 0、1、2、3。如果设备树里写的是 reg 0但硬件实际是 reg 1驱动会在地址 0 上找不到 PHY然后可能继续扫描别的地址也可能直接失败。注意有些 PHY 芯片支持地址自动协商但行为因厂家而异。我实际调试过一次特别典型的案例硬件上 PHY 的地址是 0但软件里 mdio 子节点写的是 reg 1结果启动日志里反复出现找不到 PHY最终网络接口起不来。改回 reg 0 后问题消失。所以这个点一定要先核对。PHY 的参考时钟方向也是一个大坑。RK3566 的 GMAC0 在某些方案里CLK_MAC_REF 是从 SoC 输出的也就是 clock_in_out output。如果硬件上 PHY 的 XI 引脚恰好也接了 25MHz 晶振而 SoC 又在往这个网络灌 125MHz两边打架PHY 工作一定不正常。反过来如果 clock_in_out input就必须保证外部 PHY 或晶振把时钟送到了 SoC 的 MAC 参考时钟引脚上否则 MAC 的时钟源也是乱的。在设备树里这个属性一般叫clock_in_out。公版 evb 是这样配置的gmac0: ethernetfe2a0000 { ... phy-mode rgmii; clock_in_out output; snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 10000 50000; };如果你不确定自己的板子是 input 还是 output看原理图上 PHY 的 REF_CLK 是谁提供的即可。这个方向错误导致的症状五花八门有的直接 DMA 报错有的能 link 上但 ping 不通有的速率只有 100M。3.4 电源域与复位检查RK3566 的 GMAC 还有独立的电源域和复位控制。在设备树里一般会有 power-domains 属性power-domains power RK3568_PD_GMAC;如果这里写错或者驱动没有成功把电源域拉起来后续 MAC 寄存器读写全是 0 或全 FDMA 初始化自然失败。检查方式也比较简单启动日志里如果有rk_gmac-dwmac fe2a0000.ethernet: failed to get power domain那就是电源域配置有问题。注意 RK3566 和 RK3568 的 power 域宏可能定义不一致如果你是在 3568 SDK 的基础上改 3566这里也容易踩坑。复位资源的检查看日志里有没有这样一行no reset control found有些版本的 RK 驱动会把 MAC 控制器内部复位也作为一个 reset 资源如果设备树没配驱动会跳过。如果你在设备树里根本不需要 SoC 侧复位那这行日志可以忽略。但如果硬件上 PHY 的复位脚被接到了 SoC 的某个 GPIO而你在设备树里没配PHY 可能一直处于复位态。这种情况查起来更隐蔽因为日志不会直接提示。我自己常用的排查方式在板子起来后手动操作 GPIO看 PHY 是否恢复。比如 PHY 复位脚接到了 GPIO3_B7设备树里是 gpio3 RK_PB7 GPIO_ACTIVE_LOW那可以echo 119 /sys/class/gpio/export echo out /sys/class/gpio/gpio119/direction echo 0 /sys/class/gpio/gpio119/value sleep 0.1 echo 1 /sys/class/gpio/gpio119/value不同 SDK 的 GPIO 编号算法不一样我这里只是演示思路。通过手动复位 PHY 后再看 dmesg 是否有 PHY 驱动重新 probe 的日志就能确认 PHY 本身是否还活着。3.5 确认驱动配置项除了设备树内核的 defconfig 里也必须打开对应驱动。RK3566 的网口驱动是 stmmac 平台驱动在 defconfig 里一般体现为CONFIG_STMMAC_ETHy CONFIG_STMMAC_PLATFORMy CONFIG_DWMAC_GENERICy CONFIG_DWMAC_ROCKCHIPy CONFIG_PHYLIBy CONFIG_MICREL_PHYy // 如果用 KSZ9031 CONFIG_RTL8211F_PHYy // 如果用 RTL8211F CONFIG_MOTORCOMM_PHYy // 如果用裕太微 YT8531如果 CONFIG_DWMAC_ROCKCHIP 没开驱动会退回到通用的 dwmac-generic 路径对 RK3566 的时钟和电源域支持是不完整的也会出现怪异的初始化失败。检查当前内核实际开的配置zcat /proc/config.gz | grep -iE STMMAC|DWMAC|PHYLIB|MOTORCOMM|RTL8211有的 SDK 把 proc config 关掉了那就直接在 kernel 源码目录下查 .config。如果在设备树里配了 PHY 驱动但内核里对应的 PHY 驱动没编进去PHY 芯片会以通用 PHY 的形式存在能 link 但可能丢特性。严重的情况下PHY 的配置寄存器初始值不对也可能导致传输异常但一般不会直接导致 DMA 初始化失败。4. 典型问题复现与处理案例为了更有参照性我把实际调试中碰到的几个和 DMA 报错强相关的场景整理一下都是可以按图索骥的。4.1 案例一CLK_GMAC0 频率被设成 25MHzRGMII 跑出 DMA 报错某方案用 GMAC0 RGMIIPHY 是 RTL8211F。启动日志如下[ 1.270063] rk_gmac-dwmac fe2a0000.ethernet: clock input frequency is 25000000 [ 1.278140] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk tx [ 1.284452] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk rx [ 1.291227] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk ref [ 1.298159] rk_gmac-dwmac fe2a0000.ethernet: cannot get clk phy [ 1.305841] rk_gmac-dwmac fe2a0000.ethernet: DMA engine initialization failed这个日志的根因有两点一个是时钟频率不对另一个是 clk tx/rx/ref/phy 全拿不到。后者说明设备树里的 clocks 和 clock-names 没有匹配上驱动代码。解决方法是先改设备树把 assigned-clock-rates 设成正确的 125MHz并且补全驱动需要的所有时钟项。RK3566 的 evb 设备树里 GMAC0 的时钟配置参考如下assigned-clocks cru CLK_GMAC0, cru CLK_GMAC0_PTP; assigned-clock-rates 125000000, 125000000;同时确认clock_in_out output还是input。RTL8211F 在多数 RK3566 底板上是 SoC output 模式也就是由 SoC 提供 125MHz 参考时钟给 PHY。修改后重新编译内核烧录后日志变成[ 1.270063] rk_gmac-dwmac fe2a0000.ethernet: clock input frequency is 125000000 [ 1.278140] rk_gmac-dwmac fe2a0000.ethernet: PHY [stmmac-0:00] driver [RTL8211F] (irqPOLL)DMA 报错消失网口正常起来。这个案例希望能说明一件事 ** 不要只盯着最后一行报错要看完整日志链 **。4.2 案例二PHY 芯片 YT8531 的 25MHz 晶振没贴导致 DMA 初始化失败还有一个很常见的硬件现象PHY 是 YT8531原理图上要求外部 25MHz 晶振但贴片漏贴或贴错。此时 PHY 完全不上工MDIO 也读不到驱动在探测 PHY 时失败最终 DMA 初始化失败。这个案例的日志中MAC 的时钟频率可能是对的125MHz但 PHY 没就绪。在 dmesg 里你会发现mdio_bus: mdiofe2a0000: MDIO device at address 0 is missing或者rk_gmac-dwmac fe2a0000.ethernet: Cannot attach to PHY (error -19)这种只能硬件排查用示波器量 PHY 的 XI/XO 引脚有没有 25MHz 波形量 PHY 电源是否正常量复位脚电平。软件上能做的就是把设备树里的 PHY 地址挨个试一遍但归根到底要排除硬件问题。我自己在这个坑上浪费过两天时间后来发现是核心板厂给错了物料封装。4.3 案例三RK3568 的 SDK 改的 RK3566power-domains 索引越界有客户拿 RK3568 的 SDK 改 RK3566 方案设备树里 gmac 节点的 power-domains 直接复制了 RK3568 的写法和索引。RK3566 的 PD_GMAC 索引在 pmu 的 power-controller 里的编号和 RK3568 不一样导致 pm_genpd_init 失败。日志表现rk_gmac-dwmac fe010000.ethernet: failed to get power domain rk_gmac-dwmac fe010000.ethernet: DMA engine initialization failed原因是 stmmac_platform.c 在 probe 里调用 dev_pm_domain_attach 失败后会返回错误DMA 初始化根本没走到还是走到了但寄存器读写异常。解决方法是把 power-domains 属性对照 RK3566 TRM 修正。如果你的设备树里根本没有 power-domains 属性驱动也能跑但有些低功耗状态下 MAC 可能不会正确唤醒。所以这个属性建议保留且必须正确。4.4 案例四双网口模式两个 GMAC 同时开启导致引脚冲突RK3566 支持双网口但两个 GMAC 的一些引脚会复用同一条 IO 或者同一条时钟线。如果两个节点都配了 okay但底板实际上只接了一个 PHY另一个 MAC 的 MDIO 地址会冲突或时钟冲突。表现是一个网口正常起来另一个网口报 DMA 初始化失败。比如 GMAC0 正常GMAC1 报错。查设备树里 GMAC1 的 pinctrl看引脚是否和 GMAC0 或其它外设冲突cat /proc/device-tree/gmac1/pinctrl-0然后对照 TRM 的 GPIO 复用表。这类问题往往是硬件工程师只设计了一个网口但软件人员直接从公版设备树开了两个 GMAC第二个节点自然失败。如果确实只需要一个网口就把未使用的 GMAC 节点 status 改为 disabled干净利落。5. 排查这个报错需要具备的工具与资料意识最后聊几句平时调试这个报错时我手边会准备的资料和工具不一定全是软件层面的但对快速定位很有帮助。第一个是 RK3566/RK3568 的 TRMTechnical Reference Manual。查 DMA 控制器寄存器、GMAC 时钟树、复位寄存器都需要它。特别是 RGMII 的时钟树那几页建议直接打印出来放桌上。第二个是芯片原厂Rockchip的 SDK 设备树 diff。如果你手上有公版 evb 的设备树先和你的底板设备树做 diff重点看 gmac 节点、相关的 io-domain、pmu 节点。很多时候问题就是改设备树时抄漏了一行。第三个是 PHY 芯片的 datasheet。RTL8211F、YT8531、IP101GRI 的 datasheet 里都有寄存器映射和地址配置说明调试 MDIO 时会用到。比如 YT8531 的 PHY 地址默认由 AD0/AD1/AD2 引脚决定和 RTL8211F 的地址译码逻辑还不完全一样。第四个是一个 USB 转网口的调试工具或者一个能上网的路由器。网口起来后先用 static IP 直连电脑测 ping不要一上来就插公司网络不然你分不清是 DHCP 问题还是网口问题。我自己习惯在板子上配静态 IPifconfig eth0 192.168.1.88 netmask 255.255.255.0 up ping -I eth0 192.168.1.1如果 MAC 起来但是 ping 不通可以用 ethtool 查 link 状态和速率ethtool eth0如果 link 是 no说明 PHY 协商本身有问题走 MDIO 排查如果 link 是 yes 但 ping 不通重点查 RX/TX 的引脚配置、时钟方向、以及设备树里 phy-mode。6. 最后的经验谈我自己调试 RK3566 网口问题的过程中最深的体会是这个报错把太多人误导到 DMA 寄存器方向去了。实际上SoC 的 DMA 引擎本身很少出问题绝大多数是它依赖的时钟、PHY、复位、电源没就绪。所以当你看到 “DMA engine initialization failed”第一反应应该是前面哪个基础资源缺失了而不是去看 DMA 控制器寄存器。按我现在的习惯拿到这个日志后先做三件事第一看整段 dmesg 里有没有 cannot get clk 或 failed to get 字样第二确认 PHY 是否被 MDIO 扫描到第三核对设备树里 clocks、power-domains、snps reset-gpio 和 phy-mode。做完这三步九成以上的问题都能定位出来。如果这三步都查不出问题再回头检查硬件用示波器量 PHY 的 XI 时钟波形、复位引脚电平、MDIO/MDC 信号。在很多合作厂商的项目里最后查出来是 PHY 芯片贴错或者 PCB 走线反了也不算罕见。另外再提一个调试效率问题很多工程师喜欢在驱动里加 printk一行一行打日志看走到哪。这个方法不是不行但效率偏低。更好的方式是把设备树调好之后先用 dmesg ethtool 验证硬件链路再决定要不要动内核代码。因为 stmmac 框架本身已经很成熟RK 的 dwmac-rk.c 也相对固定真正需要你改内核驱动的场景很少大部分都是在设备树层面就能搞定。调试网络的另一个小技巧是打开 phy 的调试模式。有些 PHY 驱动支持查看内部寄存器比如cat /sys/kernel/debug/mdio/0/regs或者使用 mdio-tools 直接读写 PHY 寄存器。通过读取 PHY ID 寄存器寄存器 2 和 3可以快速判断 PHY 是否响应。如果读出来是 0xffff那说明 MDIO 链路有问题如果读出来是 0x1cc1 之类至少能确认 PHY 活着。还有一点值得提醒替换 PHY 型号时不要只改设备树里的 compatible 或者 PHY 驱动还要留意 PHY 芯片的电源引脚是否兼容。RTL8211F 和 YT8531 的引脚定义并不完全一样有的板子直接替换后PHY 的 LED、中断引脚和复位极性可能对不上软件怎么调都没用。总结下来这份报错日志本身只是一个报警器。真正的工作是顺着报警器找到真正失火的房间。RK3566 平台上的网口驱动链路实际上很成熟只要抓住设备树、时钟、PHY、电源域这几个核心点按顺序排查基本上都能在半天内解决。希望这篇文章能把排查顺序和验证方法讲清楚帮你少走一些弯路。
返回列表