☰
RK3568与飞腾D2000平台PHY芯片调试避坑指南:从RGMII到寄存器配置
2026/9/28 5:21:00 网站建设 项目流程

做底层驱动和BSP调试这几年,我最常被问到的其实不是CPU本身,而是PHY芯片。飞腾D2000和RK3568这两个平台,一个是国产化信创场景里的常客,一个是工控、边缘计算和EtherCAT用户手里的香饽饽,芯片架构都是ARM,看着差不多,但真正调起PHY来,踩坑的角度完全不同。我手上一块板子用的是裕太微YT8521,另一块用的是老朋友AR8035,两边都折腾过千兆丢包、CRC错误、冷启动link不上这些破事。这篇就把两个平台上的调试思路、寄存器读写手段、设备树配置要点和排障过程整理成一份能直接抄作业的避坑指南,哪怕你是第一次调PHY,跟着流程走也能少掉几斤头发。

1. 平台底层的差异:D2000和RK3568到底差在哪

1.1 从SoC外设接口看:RGMII、SGMII与PCIe的取舍

先说结论:飞腾D2000虽然有原生的GMAC接口,但实际板卡上很少有直接把PHY挂在GMAC下的,更多是通过PCIe转出网络控制器,或者由国产交换芯片、BMC去承接网络路径。RK3568则完全不同,它自带两个千兆GMAC控制器,分别对应gmac0和gmac1,其中一个还支持TSN(时间敏感网络),通过RGMII接口外接PHY是默认玩法。

这个差异直接决定了你调试PHY时的工作方式。

在RK3568上,PHY挂在MDIO总线上,内核里能看到完整的mdio bus、phy device、phy driver这套链路,设备树里可以清清楚楚指定PHY地址、中断引脚、RGMII延时,想改寄存器直接用mdio-tools读写就行。飞腾D2000这类平台,如果是走PCIe网卡,PHY一般被网卡芯片(比如RTL8111、Intel I210)内部管理,对外不暴露MDIO接口,你想直接读PHY寄存器基本没门。就算D2000集成了GMAC,很多国产板子的固件或PMON(飞腾平台的引导程序)会提前把PHY初始化好,内核驱动拿到的是一份已经配置完的“半成品”,设备树里可能压根没有mdio节点,出了问题只能去翻固件,调试链路长得多。

所以,如果你拿到D2000的板子,第一步不是去挖PHY,而是先搞清楚网络路径到底是“GMAC直连PHY”还是“PCIe网卡”,路径不同,后边所有手段完全不一样。

1.2 PHY驱动框架:内核帮你做了多少事

Linux内核的PHY驱动框架(drivers/net/phy/)已经非常成熟,基本流程是:MAC驱动(或DSA驱动)注册MDIO总线,总线扫描得到PHY ID,匹配PHY driver,然后通过phy_state_machine状态机做自动协商、Link检测、速率切换。这套逻辑在RK3568上跑得很顺畅,因为Rockchip官方内核已经适配好了gmac驱动,你只要在设备树里把PHY节点描述准确,基本开箱就能用。

飞腾平台的BSP则比较多样化。有的用标准内核加补丁,有的直接用厂商定制内核,MDIO控制器驱动可能没完全暴露到用户态,甚至在/sys/class/mdio_bus/下都看不到总线。这时候需要确认内核配置里有没有打开PHYLIB、mdio-bus-mux这类选项,同时检查dmesg里有没有“mdio_bus: mdio@xxx”的初始化打印。如果确实没暴露,建议先在固件侧确认PHY初始化状态,否则你在内核层折腾半天可能是白费力气。

我在飞腾D2000上遇到过一种典型场景:板卡PCIe通道挂了一颗RTL8211F,PHY完全由RTL8168驱动接管,但系统里还残留一个假的mdio节点,导致设备树解析报错。这种问题表面看是PHY配置问题,本质上是平台对网络路径定义不清,属于“平台差异导致的地图开错”。

2. YT8521与AR8035:寄存器世界的两条脉络

2.1 标准寄存器区:0x00到0x1F是通用语言

不管是裕太微YT8521还是高通Atheros AR8035,第一眼看到的0x00~0x1F这32个寄存器都遵循IEEE 802.3标准。这意味着基本操作完全一致:0x00 BMCR负责复位、自协商开关和速率控制,0x01 BMSR反映Link状态、自协商完成标志和芯片能力,0x02和0x03是PHY ID,0x04和0x05看自协商广告和对端能力。

调试时,我首先会读0x01 bit2判断Link是否建立,读bit5判断自协商是否完成。注意,BMSR的bit2是锁存位,必须读两次或者写1清除才能拿到实时状态,这是很多人排查时容易忽略的细节。然后是0x02/0x03,确认当前PHY的ID是否和预期一致,很多时候设备树里写错了PHY地址,读回来的ID会变成0x0000或0xffff,一眼就能定位。

用mdio-tools临时读一下,比任何驱动日志都快:

mdio read eth0 0x01 # 读BMSR mdio read eth0 0x02 # 读PHY ID1 mdio read eth0 0x03 # 读PHY ID2

标准寄存器区还有一个关键点:0x00 BMCR的bit15是软件复位,写入1会复位整个PHY并重新启动自协商。调试过程中我习惯先写BMCR复位,等500ms再读状态,这样可以排除芯片死锁的干扰。但注意复位后所有扩展寄存器配置都会丢,需要重新初始化,这在调试delay配置时很容易让人心态崩掉。

2.2 YT8521的特殊玩法:扩展页和私有寄存器

YT8521是国产PHY里性价比很高的一款,兼容RGMII和SGMII,但它的私有配置不是全放在标准寄存器区,而是通过扩展页机制访问,典型操作是写0x1E寄存器(页面选择)切页,再通过0x1F读写页面内寄存器。这和Marvell那套MMD思想类似,不过寄存器地址含义完全是自家定义。

调试中遇到最多的是RGMII的RX/TX延时配置。YT8521通过扩展页里的具体bit位控制RXC/TXC的延时,但不同批次的芯片默认值可能不一样,千万不要直接照搬datasheet里的“推荐值”。我在两块RK3568板子上用过同一型号的YT8521,一块必须把RX delay调到固定值,另一块默认值就完美,差一个阻容摆位就能让时序完全变样。

还需要注意的是YT8521和某些MAC配合时,默认的clk output方向和行为可能与预期不符,导致功耗异常或时钟干扰。碰到这种情况,一定要把PHY的“clock output”相关寄存器先关掉,再用示波器看波形,而不是盲目怀疑delay配置。

另外,YT8521这类千兆PHY在EtherCAT场景下很常见,原因之一是它支持在百兆强制模式下稳定工作。但需要注意,如果你用IGH(EtherCAT主站)适配RK3568,PHY的自协商一定要关掉,强制100M全双工,否则EtherCAT的实时帧抖动会让你怀疑人生。这个后面单独展开。

2.3 AR8035的经典坑:delay藏在0x1D/0x1E里

AR8035作为Qualcomm的经典百兆/千兆PHY,在路由器、网络打印机、高端工控板上用了很多年,文档相对完整,坑也相对固定。它一个比较大的特点是RGMII RX/TX delay默认通过硬件strape引脚(RXD2、RXD3、RXD6等)在上电瞬间锁存,之后也支持通过Copper Specific Control寄存器(0x1D、0x1E)覆盖。

我碰到过一种AR8035的典型问题:硬件工程师按照SGMII模式设计,PHY的strap引脚配置成无delay,但实际跑的是RGMII模式,结果千兆下丢包严重,百兆正常。原因是RGMII标准规定发送端应该提供2ns延时(这个在很多MAC上并未实现),而AR8035的上电strap没配delay,接收端又没加,导致建立/保持时间不满足。这种情况光看寄存器状态根本看不出来,必须拿到硬件原理图核对strap电阻。

AR8035还有一个很出名的坑:它的中断是开漏输出,需要外部上拉,很多板子为了省电阻直接悬空,导致PHY中断一直拉高或拉低,驱动侧的link状态变迁检测失灵。表现为系统运行一段时间后网口状态不刷新,但业务流量还在跑。如果你发现网口Link状态和实际不符,先量一下PHY的INT引脚电平,别急着重刷固件。

3. 调试第一课:把工具链准备好再动手

3.1 mdio-tools加ethtool的组合拳

调试PHY寄存器,最顺手的工具是mdio-tools,它由mii-tool的作者维护,提供了mdio和mdio-netlink两个命令,支持通过netlink直接访问MDIO总线,比老的phycalc好用太多。安装方式很简单,一般直接apt或源码编译:

git clone https://github.com/wkz/mdio-tools.git cd mdio-tools make sudo make install

使用上最频繁的是读和写:

mdio read eth0 0x01 mdio write eth0 0x00 0x8000 # 复位PHY mdio read eth0 0x02 mdio read eth0 0x03

注意mdio命令操作的是net_device对应的PHY,写寄存器前先确认网口是up状态,否则部分驱动会直接把mdio操作丢弃。如果遇到“Operation not supported”,大概率是网卡驱动没有实现mdio控制函数,需要换用devmem直接操作MDIO控制器(这个方法比较粗暴,不推荐新手)。在调试阶段,每次读写寄存器的间隔最好控制在100ms以上,尤其是写BMCR复位后,立刻读状态大概率读到的是复位中间态。

ethtool则是从驱动和协议层看全局:

ethtool eth0 # 查看速率、双工、自协商状态 ethtool -S eth0 # 查看硬件计数,重点关注rx_crc_errors、rx_errors、tx_errors ethtool -s eth0 speed 100 duplex full autoneg off # 强制百兆全双工(调试EtherCAT常用) ethtool --phy-statistics eth0 # 有的驱动支持输出PHY统计信息

建议把这两个工具配合dmesg一起用:PHY初始化阶段dmesg会打印link up/down、协商模式、PHY ID注册信息,ethtool看协议层协商结果,mdio看底层寄存器真实状态。三层数据对照,才能准确定位是MAC问题还是PHY问题,或者是物理链路问题。

3.2 一张随时能查的寄存器速查表

调试过程中最烦的就是翻datasheet,几千页文档翻到眼花。我结合YT8521和AR8035的常用需求,整理了一份速查表,至少在现场能快速定位问题方向:

寄存器地址作用调试时怎么用
BMCR0x00控制复位、自协商、速率、双工写0x8000复位;写0x1000开自协商
BMSR0x01Link状态、自协商完成、能力读bit5和bit2,注意link位是锁存位
PHY ID10x02芯片厂商ID高16位判断当前PHY是否被正确识别
PHY ID20x03芯片厂商ID低16位与0x02配合确认PHY型号
ANAR0x04本端自协商能力确认是否广播1000M/100M能力
ANLPAR0x05对端自协商能力确认对端广播了哪些能力,判断协商不一致
1000BASE-T Control0x09千兆master/slave、test mode遇到千兆协商不稳定时可读,少改
1000BASE-T Status0x0A千兆协商状态、master/slave结果排查千兆降级为百兆的问题

对于YT8521,还要补充一个关键点:0x1E是扩展页选择寄存器,0x1F是数据端口。不同page里的bit定义差异很大,我通常会在拿到新批次芯片后先把0x1E设置成0x0000,再读0x1F,把默认值记录下来,再和datasheet比对,确认芯片不是翻新料。

AR8035则重点关注0x1D和0x1E这两个铜缆控制寄存器,delay配置和配对极性检测都在里面。但这两颗芯片的私有寄存器地址不通用,千万不要把YT8521的经验原封不动套到AR8035上。曾经有人在AR8035上照搬了YT8521的delay寄存器地址,结果把AR8035的某个测试模式打开,网口彻底闷死,最后只能断电重启。

4. 设备树与固件配置:让PHY正确的“进场”

4.1 RK3568设备树MDIO与PHY节点

RK3568官方内核里,gmac1的典型设备树是这样组织的:

&gmac1 { phy-mode = "rgmii"; clock_in_out = "input"; snps,reset-gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>; snps,reset-active-low; snps,reset-delays-us = <0 20000 50000>; pinctrl-names = "default"; pinctrl-0 = <&gmac1_rgmii_pins>; status = "okay"; mdio1: mdio { compatible = "snps,dwmac-mdio"; #address-cells = <1>; #size-cells = <0>; phy0: ethernet-phy@0 { reg = <0>; reset-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>; reset-delay-us = <20000>; }; }; };

这里最值得注意的坑有三处。

第一,phy-mode到底用rgmii还是rgmii-id,直接影响MAC侧和PHY侧谁负责延时。如果你在PHY里已经通过寄存器配了RX/TX delay,并且硬件上PHY不负责额外延时,那么这里应该写“rgmii”,避免两边同时加延时而导致时序翻倍。反过来,如果PHY采用默认加延时模式,而MAC侧也配了delay,就会出现双倍延时,千兆直接跑出大量CRC错误,百兆可能侥幸能跑。

第二,snps,reset-gpio和PHY节点里的reset-gpios要统一。我见过有人MAC层配了一个GPIO,PHY节点又配了另一个,结果PHY被反复复位,状态机一直处于重新启动自协商的状态。建议只保留PHY节点里的reset定义,时序控制更清晰。

第三,PHY地址reg必须和硬件电路一致,常见的是0、1、4、7。如果读PHY ID读到0x0000或0xffff,首先检查reg地址,其次检查reset引脚是否拉了足够长时间,有些PHY要拉低50ms以上才算彻底复位,配置里的reset-delay-us不要太抠门。

4.2 飞腾D2000平台的特殊性

飞腾平台在网口配置上不像RK3568那样标准化,很多时候PMON或UEFI固件里已经把PHY初始化流程写死了。比如固件里跑了一段自协商,内核启动后又重新复位PHY再自协商一次,两次配置不同就会导致Link状态不稳定,表现为开机后前几秒能上网,之后网口就通了但丢包。

如果遇到这种情况,优先检查固件里是否设置了“auto-negotiation disable”或者“force link speed”。飞腾D2000的GMAC如果走SGMII对接交换芯片,PHY往往是管理型交换芯片内置的,而不是独立PHY芯片,寄存器访问路径更加隐蔽。我的经验是:先看固件源码里的serdes配置,确认SGMII/QSGMII通道对应的PHY地址范围,再用示波器量serdes参考时钟,不要一上来就怀疑内核dts。

另外,飞腾D2000平台上如果走PCIe网卡,PHY的寄存器基本没法通过标准mdio总线访问,这时候要在网卡驱动的私有ioctl上下功夫。比如某些国产PCIe网卡的PHY是挂在内部MDIO上的,驱动支持通过ethtool register dump间接读取。遇到问题先用ethtool -d eth0 dump一份寄存器现场,比瞎猜强得多。

4.3 RX/TX Delay 到底该怎么配

这是千兆RGMII最核心、最玄学的部分。RGMII标准原始定义是发送端加2ns延时,接收端不加,这样可以避免PCB走线带来的偏差。但实际MAC和PHY厂商各有各的做法,导致“谁负责延时”成了千古难题。

我自己的判断方法是先用排除法。第一步,把MAC和PHY的所有delay全部关掉,用短网线(30cm以内)直连交换机,跑千兆,看是否通。如果全关能通,说明PCB走线非常干净,后边只是小修小补。如果全关不通,第二步,打开PHY端的TX delay(也就是MAC接收方向),只开这一个,再测。如果通了,说明问题出在MAC侧接收采样窗口,可以尝试微调RX delay。第三步,如果只开TX delay还不够,再逐步开RX delay,注意每次只改一个变量。

在RK3568上,可以在设备树里通过tx_delay和rx_delay属性调整(单位是ns或0~15的档位),但这只影响MAC内部的delay,不会自动匹配PHY的配置。我通常把MAC侧的全关掉,完全通过PHY寄存器做delay微调,这样更可控。YT8521的delay调整在扩展页里,AR8035在0x1D/0x1E里,两边要多试几组值,记录下来,最后选一版在高温和低温下都稳定的参数。

另外,delay调完之后要用iperf或者ping -f做长时间压力测试,单纯ping通不算数。我遇到过RK3568配好之后ping能通,但跑iperf到800Mbps就疯狂掉包,最后发现是TX delay多加了0.5ns导致高速传输时窗口抖动。

5. 千兆CRC错误:一场典型的信号与时序排障

5.1 从现象定性开始

“百兆正常,千兆出现接收硬件CRC很多错误”,这个现象背后通常不是芯片坏了,而是物理层的某种不匹配。我拿到这种问题,第一步不是动代码,而是先看错误计数分布:

ifconfig eth0 ethtool -S eth0 | grep -E "crc|error"

如果RX方向的rx_crc_errors持续增长,而TX方向是干净的,问题大概率在PHY接收链路:可能是RGMII RX delay不对、PCB走线过长、PHY的1000BASE-T信号质量差、或者对端交换机端口能力不足。如果rx_errors和rx_crc_errors同时涨,还要考虑MDI/MDIX配对问题,也就是TX/RX线对是否被错误识别。

千万不要忽略一种安静的场景:百兆正常,千兆CRC错误高发,但dmesg里没有任何异常,ethtool里Link依然是1000M。这说明自协商已经完成,物理层能建立千兆链路,但数据采样边缘靠近临界区域,属于“能通但随时可能崩”的状态,必须靠调整delay或检查时钟来解决。

5.2 排查步骤实录

我通常按下面的顺序排查,性价比最高,每一步都能排除一个变量。

第一步,强制降速到百兆:

ethtool -s eth0 speed 100 duplex full autoneg off

如果降到百兆后CRC计数归零,说明MAC侧的DMA配置基本没问题,问题集中在千兆特有部分,也就是RGMII的三组时钟/数据线时序,或者1000BASE-T的物理层协商细节。

第二步,用mdio读取0x0A(1000BASE-T Status Register),看master/slave配置和link partner的协商结果。正常情况下,两个设备之间master/slave必须一主一从,如果都认为自己是master,千兆协商会反复抖动。这种场景多出现在两块板卡直连时,一端PHY配置强制master,另一端也强制master。

第三步,逐项调整delay。我把delay调整想象成“在一个时间窗口里找采样点”,一点点移。每次调整后,用下面这个命令打流量:

iperf3 -c 192.168.1.2 -t 60 -u -b 900M

如果UDP丢包和CRC计数都下来,说明时序窗口对了。只ping不通不代表延时没问题,必须用UDP或TCP高压测试验证。

第四步,如果delay调完还是有问题,回到硬件。示波器量PHY的125MHz时钟,看上升沿是否干净、有没有明显振铃。RGMII千兆模式下,PHY输出时钟抖动如果超过200ps,数据线时序基本都会崩。时钟源来自晶振还是SoC的CLKOUT,两种场景下的容忍度不同。我遇到过YT8521用SoC时钟输出做参考源时,由于CLKOUT驱动能力不够导致时钟边沿变缓,CRC错误高发,换成外部有源晶振后问题消失。这已经不是软件能解决的了。

5.3 一例真实排障过程

说一个例子:RK3568 + YT8521,设备树rgmii模式,全默认配置跑千兆,ping包正常,但iperf3打流后rx_crc_errors每秒掉几千个。

我先强制百兆,CRC清零。然后用mdio读0x0A,发现master/slave协商结果是slave,正常。然后我将MAC侧tx_delay从默认值逐档往下调,同时监控rx_crc_errors。调到某几个档位时,CRC瞬间降了一大截。最终把tx_delay设为0、通过YT8521扩展页打开RX delay生效,同时关闭MAC侧delay,CRC归零。之后用高低温箱验证,-10℃到70℃都稳定。

这个案例的关键是“双击”问题:默认配置下MAC侧和PHY侧对delay的归属不清晰,等于两边都没有提供有效延时或不一致延时,导致千兆的RX采样窗口正好卡在数据跳变边缘。百兆速率低,窗口宽,不影响;千兆速率高,窗口窄,直接崩。

6. 常见问题与避坑速查表

6.1 冷启动Link不上但复位后正常

这种问题在YT8521和AR8035上都遇到过,典型特征是断电重启后网口无法link,但加载驱动后手动reset一下又好了。根源往往是PHY的上电时序和SoC的GPIO reset时序不满足要求:PHY要求上电后至少等待一定时间才能释放reset,否则内部配置加载不完整。

解决方法是确保设备树或驱动里reset-delay时间足够。我见过有人把reset-delay-us设置为2000us,结果PHY的供电电容还没充满就拉高了reset,所以网口早上起不来。建议至少给20ms。还有一些板子在PHY的电源轨上加了大电容,上电瞬间电压爬升慢,reset释放后PHY在内核配置时还没ready,此时可以通过检查dmesg来看是否是reset GPIO反复触发。

如果复用GPIO有问题,要确认GPIO的默认方向和默认电平。有些GPIO控制器在系统启动前默认输出低,导致PHY一直被复位,直到驱动加载后才正常。

6.2 百兆正常千兆错误

这个基本可以锁定在RGMII接口的延时配置上,具体排查逻辑在第5章已经写透。这里补充一个容易忽略的变量:对端设备的PHY能力。有些老交换机千兆口是“只支持1000BASE-T但不支持EEE节能以太网”,如果本端PHY开启了EEE,可能造成兼容性问题。排查时可以强制关闭EEE试试,一般在ethtool里:

ethtool --set-eee eth0 eee off

另外,网线质量也很重要。千兆跑在4对线上,其中任何一对接触电阻过大或线序错误,都会造成CRC错误。如果调整delay后依然不达标,换一根短一点的六类网线重新测试,至少能排除物理线缆的干扰。

6.3 EtherCAT场景下的额外功课

最近很多人在RK3568上适配EtherCAT IGH主站,我也折腾过一遍。EtherCAT对以太网链路的要求比较苛刻,不要求高带宽,但要求低延迟和低抖动。所以PHY这边要做几个固定动作:

  • 关闭自协商,强制100M全双工:
ethtool -s eth0 speed 100 duplex full autoneg off
  • 在驱动侧关闭中断合并(如e1000e的int_moderation,或Rockchip GMAC的napi weight调小)。
  • PHY的中断引脚尽量不要使用轮询模式,IGH对时间敏感,轮询会造成抖动。
  • 如果使用YT8521,还需要关注它在100M模式下的时钟行为,有些版本默认对外输出25MHz,如果电路上没做隔离,可能干扰相邻走线。

EtherCAT调试时如果出现周期性丢帧,不要只盯PHY,建议在IGH主站日志里同时打开周期统计。通过观察实际周期误差进一步定位是MAC侧的中断延迟,还是PHY在link切换时的额外开销。

6.4 速查表:遇到的坑和对应解法

现象可能原因优先排查动作
读PHY ID为0x0000PHY地址错误或复位未完成写BMCR复位,等50ms再读;核对reg地址
读PHY ID为0xffffMDIO总线通信失败、MDC/MDIO引脚极性错误用示波器量MDC/MDIO,确认驱动是否注册mdio bus
Link up但ping丢包延时配置不匹配、对端协商异常ethtool -S看CRC和error计数,调整delay
千兆降到百兆master/slave协商不一致、线缆不支持千兆读0x0A,检查master/slave,换线测试
冷启动link不上reset时序不满足、供电电容未充满加大reset-delay-us到20ms以上
CRC错误随温度变化加剧delay余量不足、时钟抖动过大高低温下测delay窗口,调整PHY侧delay
EtherCAT周期性丢帧中断合并、PHY轮询、自协商抖动关闭自协商和中断合并,IG日志看周期误差
寄存器写入不生效PHY处于隔离模式或电源down读0x00,确认bit10和bit11状态

最后再分享一点个人经验:PHY调试最大的敌人不是芯片,而是“默认值”三个字。YT8521和AR8035的默认寄存器配置,放在不同的MAC、不同的PCB走线、不同的时钟源下,表现天差地别。拿到一块新板子,第一步一定是完整dump一遍全部PHY寄存器,保存成baseline,以后每次出问题都能对比“默认状态”和“异常状态”。不要凭经验一上来就改这改那,先把现场留档,再去动手术。这个习惯帮我省下了大量时间,也让我在换批次芯片后,能快速发现是芯片默认值变了,还是板子走线出了问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询