ARTICLE DETAIL

资讯详情

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

RK3588 GMAC调试实战:国产PHY替换从踩坑到修通全记录

RK3588 GMAC调试实战:国产PHY替换从踩坑到修通全记录 RK3588的GMAC调试说难不难说简单也真不简单。我这块核心板原本用的是参考设计的RTL8211F千兆PHY原厂SDK适配得比较完善网络都是“一次点亮”。结果中途因为供货和成本原因我把默认的RTL8211F换成了一颗国产PHY芯片接下来就是连续几天的“水逆”期——PHY ID读不到、link起来了ping不通、千兆变百兆、速率一高就疯狂掉包……这篇文章就把我在RK3588网络调试过程中换PHY踩到的坑以及最终怎么一一排查、修通的完整记录分享出来希望对正在做国产化替换或者调试RK3588 GMAC的朋友有所帮助。1. 内容整体设计与思路拆解1.1 RK3588 GMAC硬件架构回顾RK3588这颗SoC上集成了两路GMAC控制器兼容RGMII和RMII两种MAC-PHY接口模式。我这边用的是GMAC1走的是标准RGMII接口通过MDIO总线管理PHY芯片。默认参考设计里挂的就是RTL8211F属于Realtek的千兆PHY支持10/100/1000Mbps自适应RGMII接口内置了完整的物理层收发功能。原厂SDK里针对这颗PHY做了完整的适配包括驱动支持、设备树参数、时钟配置、延迟补偿等等。所以如果你不动这个方案网络部分基本是0调试成本的。但问题在于RTL8211F这颗PHY在当前市场环境下供货周期和价格都不太理想。我这次因为项目批量生产需求决定把它替换成一颗国产PHY——裕太微的YT8531同样是千兆PHY同样支持RGMII理论上是可以做到pin-to-pin兼容替换的。当然实际做起来远没有“理论”那么顺利。提醒一下如果你也在做RK3588网络调试先确认你用的是哪一路GMACGMAC0和GMAC1在设备树中的节点名不一样管脚也不一样。别改了半天发现自己调的节点根本不是板子上走的那一路。1.2 替换PHY需要考虑哪些维度换PHY不是把芯片焊上去就能用至少要过一遍以下几个维度电气兼容性供电电压是否一致常见3.3V或1.8VRGMII信号电平是否匹配时钟引脚是输入还是输出模式。RTL8211F和YT8531在这点上基本兼容但还是要看具体封装和外围电路。MDIO地址PHY芯片的MDIO地址由芯片引脚上下拉决定。RTL8211F常见地址是0x01而YT8531的默认地址可能不同。如果两者不一致MDIO总线扫描时就读不到PHY ID驱动加载会失败。RGMII内部延迟Delay这是换PHY最容易翻车的地方。RGMII接口标准要求TX和RX方向各加约2ns的延迟用来补偿时钟和数据的相位差。问题是这颗延迟可以在PCB上走线实现也可以在PHY芯片内部实现由寄存器或strap引脚配置。RTL8211F的内部延迟默认开启所以原厂SDK往往不额外配置MAC侧的延迟。而很多国产PHY的延迟默认配置不一样如果两者没有对齐就会出现“link能up但数据全错”的诡异现象。参考时钟方向RGMII模式下125MHz千兆/25MHz百兆参考时钟可以由MAC提供也可以由PHY提供取决于CLK方向配置。RK3588的设备树里有对应配置项换PHY后需要重新确认。硬件复位与供电时序PHY芯片的复位引脚、供电时序、时钟稳定时间都要和MAC驱动匹配。如果复位时间太短PHY内部还没准备好驱动扫描MDIO就会失败。驱动适配SDK默认可能只编译了RTL8211F的驱动或者把PHY识别为Generic PHY。你需要确认新PHY的驱动是否编译进内核必要时需要修改内核配置甚至添加自研PHY驱动。我把需要确认的项目整理成了一个表格替换前建议逐项打勾检查项RTL8211F原方案YT8531替换方案是否需改动MDIO地址0x01由strap决定0x00/0x01由strap决定可能需改设备树RGMII内部TX Delay默认开启默认关闭设备树或寄存器需调整RGMII内部RX Delay默认开启默认开启一般无需改动参考时钟方向PHY提供Slave模式PHY提供Slave模式一般无需改动复位电平/时序低有效复位脉宽10ms低有效复位脉宽10ms检查实际电路内核PHY驱动Realtek专用驱动裕太微专用/Generic需确认编译配置1.3 为什么原厂默认配置“一把就亮”很多搞RK3588的朋友刚拿到开发板时网络都得很顺利接线、插电、配IPping通收工。这其实是原厂SDK和参考设计共同作用的结果。RK3588的SDK里设备树针对RTL8211F做了专门的适配比如gmac1节点里的phy-mode rgmii、tx_delay和rx_delay参数都调到了合适值。同时Realtek PHY的驱动在Linux内核里已经很成熟phy_id匹配后自动加载正确驱动。但这恰恰是风险所在默认配置的“专一性”太强了。一旦你换了PHY这些参数全部变成“错误预设”。而且这些问题很隐蔽——硬件能上电MDIO偶尔能读到ID但网络始终不通。你甚至会怀疑是不是PCB坏了而不是配置问题。我这次就是在这个环节耗了不少时间。2. 核心细节解析与实操要点2.1 设备树里到底哪些参数管PHYRK3588的GMAC节点在设备树里长这样默认RTL8211F配置gmac1 { status okay; phy-mode rgmii; clock_in_out input; snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 10000 50000; tx_delay 0x3b; rx_delay 0x2a; pinctrl-names default; pinctrl-0 gmac1_miim gmac1_tx_bus2 gmac1_rx_bus2 gmac1_rgmii_clk gmac1_rgmii_bus; phy-handle phy0; }; mdio1 { status okay; phy0: ethernet-phy1 { reg 0x1; compatible ethernet-phy-id001c.c916; clocks cru CLK_GMAC1_RMII_125M; ... }; };其中compatible ethernet-phy-id001c.c916是RTL8211F的PHY IDreg 0x1是MDIO地址。tx_delay和rx_delay的单位是纳秒这两个值专门用来调整RK3588 MAC侧RGMII信号的延迟。换PHY之后最需要动的就是这三处。YT8531的PHY ID是4f51.e91a如果驱动按ID匹配失败还可以直接留空让内核按Generic PHY处理或者去掉compatible字段。注意设备树里clock_in_out input表示125MHz参考时钟由外部PHY提供给MAC也就是PHY做主时钟。如果你的板子在设计时改成了MAC提供时钟给PHY这里要改成output同时检查对应的时钟配置。这个参数搞错PHY大概率起不来或者link状态反复跳。2.2 RGMII延迟补偿机制解读这是全文最值得细看的部分。RGMII接口之所以难调核心就在这个2ns延迟上。我们知道RGMII在千兆模式下用125MHz的DDR时钟沿同时采样数据和控制信号。PCB走线长度不同、PHY芯片不同时钟和数据到达MAC的时间就会有偏差。如果偏差太大采样点就不稳定数据就会出错。为了统一解决这个问题RGMII标准规定发送端要把时钟或数据延迟约2ns接收端再根据实际情况做补偿。具体到RK3588MAC侧可以调tx_delay和rx_delayPHY侧也可以通过寄存器或者外部电阻配置内部延迟。麻烦在于MAC侧调了PHY侧也调了到底是谁加谁、谁减谁不同芯片的组合结果完全不一样。RTL8211F的做法是内部已经默认开启了TX和RX的延迟所以原厂SDK里就把MAC侧的tx_delay调得比较大0x3b59个单位约2ns左右。而YT8531默认的延迟配置和RTL8211F不同特别是TX方向延迟默认是关闭的。如果你沿用RTL8211F的参数MAC和PHY两边的延迟叠加起来信号就错了。这个延迟问题在现象上非常有迷惑性链路能协商成功速率也是1000Mbps但ping包大量丢包或完全不通。如果只是偶尔丢包大概率就是延迟边界问题。排查时可以这样操作先用ethtool eth0看link和速率如果link正常但ping不通优先把设备树里的tx_delay/rx_delay降到较小值或设为0让PHY侧负责延迟。以YT8531为例我最终的配置是tx_delay 0x1f; rx_delay 0x1f;这个值把延迟主要交给PHY内部处理MAC侧只做微调。当然具体值每个板子的PCB走线不一样建议用二分法逐步尝试每次修改后重启网络并做压力测试。2.3 MDIO地址不对会怎样MDIO地址没对上现象特别干脆dmesg里报PHY ID not found at address 1或者干脆MDIO扫描不到任何设备/sys/bus/mdio_bus/devices/目录下空无一物。RTL8211F的地址由PHYADD0引脚决定常见参考设计接地地址是0x01。YT8531也有类似引脚但我这块模块上YT8531的地址被我误以为是0x01其实是0x00。结果驱动在地址1上扫描始终找不到PHY网络节点直接failed to find PHY.定位这一步最简单在板子启动后用mdio-tools需要CONFIG_MDIO_BUS相关工具扫描总线或者直接看kernel启动日志里MDIO总线枚举到了哪些设备。比如rootrk3588:~# cat /sys/bus/mdio_bus/devices/*/phy_id 0x4f51e91a如果总线地址是对的这里就能直接看到PHY ID。如果看不到先自查复位引脚是否拉高、MDIO上拉电阻是否正常、PHY供电是否稳定。实操心得MDIO总线很多时候是因为PHY还在复位状态才读不到ID。RK3588的设备树里有snps,reset-delays-us 0 10000 50000含义是复位后延迟10ms释放释放后再等50ms才去扫描MDIO。如果PHY上电初始化时间比较长有些国产PHY要100ms需要把这个50ms调大。3. 实操过程与核心环节实现3.1 从换芯片到故障复现我这个项目在替换PHY之前原RTL8211F方案是稳定运行的。替换成YT8531后第一次上电dmesg里已经有异常苗头rk_gmac-dwmac fe1c0000.ethernet eth0: no phy at mdio address 1 rk_gmac-dwmac fe1c0000.ethernet eth0: __stmmac_open: Cannot attach to PHY (error: -19)这里两个关键信息一是MDIO地址1上没找到PHY二是网卡没能挂载PHY驱动。我把设备树的reg 0x1改成了reg 0x0之后MDIO能读到PHY ID了网络节点也能正常附着。但紧接着又出现第二个问题rk_gmac-dwmac fe1c0000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/txlink是1Gbps全双工看起来一切正常但ping 192.168.1.1直接100%丢包。如果你也遇到“link up但ping不通”请把注意力优先放到RGMII延迟上而不是怀疑PHY芯片坏了。3.2 DTS设备树改造实录最终我改完的gmac1节点关键参数如下gmac1 { status okay; phy-mode rgmii; clock_in_out input; snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 10000 100000; // 复位后多等100ms tx_delay 0x1f; rx_delay 0x1f; pinctrl-names default; pinctrl-0 gmac1_miim gmac1_tx_bus2 gmac1_rx_bus2 gmac1_rgmii_clk gmac1_rgmii_bus; phy-handle phy0; }; mdio1 { status okay; phy0: ethernet-phy0 { reg 0x0; compatible ethernet-phy-id4f51.e91a; // YT8531的PHY ID clocks cru CLK_GMAC1_RMII_125M; reset-gpios gpio3 RK_PB7 GPIO_ACTIVE_LOW; reset-assert-us 10000; reset-deassert-us 50000; }; };这里有几个点值得展开。第一compatible字段我显式填了ethernet-phy-id4f51.e91a让内核能直接匹配到裕太微的PHY驱动。如果SDK里没有对应驱动可以去掉这个字段内核会把它当作Generic PHY处理基本功能也能用但可能有些厂商特有寄存器没法配置比如厂商自定义的延迟调节、LED闪烁模式等。第二reset-delays-us和PHY节点里的reset-assert-us/reset-deassert-us有些重复但建议都保留。实践中发现snps,reset-delays-us是MAC驱动框架去控制复位而PHY节点里的reset-gpios则是PHY驱动自己控制复位。某些SDK版本下只写其中一处可能不生效。双保险更稳妥。第三tx_delay 0x1f如果换算成纳秒大约是1ns左右实际上等于把MAC侧的TX延迟减半让PHY内部补齐剩下的。这是通过反复试出来的最优值。你可以从0x0开始往上加每一档ping 100个包看丢包率找到丢包率最低的那个档位。3.3 内核配置与驱动匹配确认除了设备树内核里的PHY驱动也要确认。进入内核目录cd kernel make menuconfig在Device Drivers - PHY Device support and infrastructure下确认以下几项Realtek PHY drivers对应RTL8211F如果你已经彻底不用它可以不勾选但建议保留方便后续回退对比。Motorcomm PHY drivers或者Broadcom PHY drivers等看你的SDK支持哪些。如果SDK里没有裕太微的驱动先确认Generic PHY类型是开启的一般位于PHY Device support and infrastructure - Generic PHY driver。这里有个容易踩的坑如果SDK自带的PHY驱动文件里没有YT8531具体型号但drivers/net/phy/motorcomm.c已经存在那么大概率通过PHY ID匹配还是能找到。但如果完全没有对应驱动即使MDIO能读到ID也会报unrecognized PHY错误。这种情况不要慌Generic PHY通常也能让网络跑起来只是延迟调节等功能可能要手动通过mdio-tools命令去操作PHY寄存器。注意内核配置改完一定要重新编译并烧录boot.img或kernel镜像只改设备树不够。我见过有人只改了DTS并重新打包resource.img结果内核还是老版本PHY驱动完全不生效白白排查了大半天。3.4 第一次完整ping通后的验证设备树和内核改完重新烧录启动后先确认基本状态rootrk3588:~# dmesg | grep -i phy [ 1.896491] mdio_bus fe1c0000.ethernet: MDIO device at address 0 is: 4f51 e91a [ 2.531282] motorcomm-mdio 4f51.e91a: probe successful rootrk3588:~# ethtool eth0 Settings for eth0: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Speed: 1000Mb/s Duplex: Full Port: Twisted Pair PHYAD: 0 Transceiver: internal Auto-negotiation: on看到4f51 e91a被正确识别Speed: 1000Mb/s链路全双工说明PHY基本已经工作。这时候再pingrootrk3588:~# ping -c 100 -i 0.2 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq1 ttl64 time0.428 ms 64 bytes from 192.168.1.1: icmp_seq2 ttl64 time0.398 ms ... --- 192.168.1.1 ping statistics --- 100 packets transmitted, 100 received, 0% packet loss, time 19902ms rtt min/avg/max/mdev 0.365/0.402/0.485/0.028 ms0%丢包且平均延迟0.4ms说明延迟配置已基本到位。3.5 UDP传输和网络调试助手验证做嵌入式网络调试很多时候不只是ping通那么简单。比如我在调一个视频推流方案需要验证UDP链路的稳定性。这里推荐命令行环境下直接用网络调试助手或者iperf3做UDP测试。我个人的习惯是先在PC端开一个软件形式的网络调试助手Windows下的UDP调试工具都行设置本地端口为5000然后在RK3588板子上往PC的IP和端口发UDP数据rootrk3588:~# echo rk3588 udp test packet | nc -u -w1 192.168.1.100 5000PC端如果收到了字符串说明UDP通路完全正常。如果只是ping通但UDP丢包严重多半还是PHY的延迟配置在边界上要微调tx_delay/rx_delay。如果要测吞吐量建议用iperf3# 在PC端开启服务 iperf3 -s -u -p 5001 # 在RK3588端打流 iperf3 -c 192.168.1.100 -u -b 100M -t 30 -p 5001测出来的UDP丢包率如果长时间为0说明链路已经足够稳定。我改完延迟参数后持续用500Mbps速率打流30分钟丢包率为0这才算真正修通。4. 常见问题与排查技巧实录4.1 踩坑速查表先把我经历过的、以及周围同行常见的问题整理成一张表现象可能原因排查方向MDIO扫描不到PHYMDIO地址不对复位未释放供电异常确认strap引脚确认复位时序量PHY供电PHY ID读到了但驱动不加载内核无对应PHY驱动用Generic PHY或编译对应驱动link up了但ping不通RGMII延迟配置不对调整tx_delay/rx_delay优先降低TX侧延迟千兆速率上不去只有百兆网络变压器/线缆问题PHY自动协商问题换网线查变压器中心抽头配置检查PHY寄存器协商结果丢包率随速率升高而增大RGMII延迟边界不稳用二分法微调延迟跑UDP压力测试拔插网线后link恢复不了复位/中断脚配置问题检查PHY interrupt是否接入MAC确认二次协商逻辑两个网口同时用冲突GMAC1/GMAC0管脚复用冲突检查pinctrl同一组IO不能同时配给两个MAC这些现象如果放在一起看会发现大部分问题都出在“配置”而不是“硬件”。这也提醒我们换PHY芯片时硬件改版固然要紧但软件适配必须同步推进否则就是给自己挖坑。4.2 RGMII延迟微调的实操手法延迟参数没有“绝对正确”的值它依赖PCB走线、PHY型号、MAC芯片内部结构。建议按以下步骤系统化调第一步把设备树里tx_delay和rx_delay都设为0x1f左右让PHY内部默认延迟承担大部分任务。第二步iperf3打流观察丢包率。如果丢包率高把tx_delay往大调比如0x3b重新打流。记录每个值对应的丢包率。第三步如果tx_delay调到最大依然丢包再调整rx_delay。通常TX和RX延迟一个负责上行一个负责下行通过打UDP双向流可以区分是哪一方向出了问题。这里有一个小技巧RK3588设备树里tx_delay单位是picoseconds还是nanoseconds在不同SDK版本里不一致。有的是直接写纳秒0x3b有的版本里写的是延迟单位数量。最好先读一下当前内核的stmmac驱动源码确认这个值最终是怎么被换算的再决定怎么写。提示不要同时把MAC侧和PHY侧的延迟都拉满。RGMII标准里TX方向总的延迟要接近2ns如果MAC加了2ns、PHY内部又加了2ns总延迟变成了4ns反而会采到错误的数据边沿。这就是为什么RTL8211F的默认配置下设备树里tx_delay不能加太多。4.3 硬件层面的排查小技巧软件配置查到头了还不行就要回到硬件。我常用的排查顺序是万用表量PHY供电确认3.3V和1.8V如有是否稳定纹波是否过大。PHY这类模拟混合芯片对电源纹波比较敏感纹波太大时可能link状态会反复跳变。示波器看MDIO波形MDIO是双向总线调试时用示波器抓MDC时钟周期和MDIO数据线上的响应。如果PHY在MDC上升沿之后没有正确驱动MDIO很可能是PHY没真正进入正常工作状态。量125MHz参考时钟如果PHY做主时钟给MAC用示波器确认PHY的CLK_OUT引脚真的有125MHz输出且相位抖动不大。如果时钟输出异常MAC侧大概率收不到有效数据即使link起来了也跑不通。检查网络变压器很多国产PHY对网络变压器的中心抽头电压有不同的要求。RTL8211F常用的是中心抽头接2.5V或3.3VYT8531可能类似但也有差异。如果变压器抽头电压不对会导致信号幅度偏低或偏压不对link不稳定或者根本协商不上。我在这次调试中遇到过百兆正常但千兆不通的情况最终排查发现是变压器中心抽头电容虚焊导致千兆模式下信号质量不达标。这种硬件问题在软件配置全部正确时尤其让人抓狂但好在通过回环测试和信号量测最终定位了。4.4 一劳永逸的PHY驱动注册技巧如果你要经常换不同PHY做测试强烈建议在设备树里不要写死compatible而是让它走PHY ID自动匹配。比如这样mdio1 { status okay; phy0: ethernet-phy0 { reg 0x0; compatible ethernet-phy-id4f51.e91a; ... }; };这个写法问题和解决思路其实在于如果SDK内核里对应的PHY驱动确实存在并注册了PHY_ID_MATCH_EXACT(0x4f51e91a)这类宏它就能自动匹配。如果没有驱动又显式填了compatible某些内核版本反而会报“unsupported PHY ID”然后拒绝绑定。更稳妥的做法是先用compatible ethernet-phy-id4f51.e91a让内核自主识别如果不起作用直接去掉这一行只保留reg和reset相关属性让内核用Generic PHY驱动兜底。等网络能通之后再慢慢细化驱动配置。我自己一般会准备两套DTS一套用原厂参考配置RTL8211F一套是新PHY的配置YT8531烧录前用U-Boot环境变量切换设备树。这样出问题可以快速对比排查效率高很多。结语这次把RK3588默认的RTL8211F换成国产YT8531整个过程折腾了大约三天。回头看核心问题其实就集中在MDIO地址和RGMII延迟这两处但牵扯出来的知识链条非常长从设备树的PHY参数到内核的驱动匹配再到硬件层面的信号完整性。如果你也在做类似的PHY替换或者正在开发基于RK3588的网络方案希望这篇笔记能帮你少走点弯路。最后再分享一个习惯换任何PHY芯片我都会先把新芯片的数据手册翻一遍特别关注延迟配置、MDIO地址、参考时钟这三个章节。这些信息通常在数据手册里写得很清楚只是容易被忽略。别看网上说“某某芯片和某某芯片可以pin-to-pin兼容”电气上兼容不代表软件上兼容。提前把软件配置准备好再动手改硬件效率会高很多。
返回列表