1. 国产ZYNQ平台网络适配背景最近两年在芯片国产化的大趋势下越来越多的项目开始采用国产ZYNQ替代Xilinx原厂方案。我手头的一个工业控制项目就遇到了这样的需求需要用国产裕太微YT8521 PHY芯片替换原来的Marvell 88E1111。刚开始觉得就是换个PHY芯片而已结果实际移植过程中踩了不少坑特别是RGMII时序调试和驱动适配这两个环节。先说说硬件连接情况。我们的板卡采用RGMII接口PHY地址配置为0x01通过MDIO总线连接。硬件原理图上需要注意两个关键点一是YT8521的TXD0/TXD1需要接49.9Ω电阻到地二是REFCLK需要125MHz时钟输入。这些细节在调试阶段如果没注意后面排查问题会非常痛苦。2. U-Boot阶段的PHY适配2.1 基础配置修改我们用的U-Boot版本是2018.07首先要在配置文件里开启PHYLIB支持。这里有个坑点由于国产PHY的厂商ID比较特殊需要先屏蔽其他厂家的PHY驱动否则会自动匹配到不兼容的驱动。修改include/configs/zynq-common.h文件#define CONFIG_PHYLIB #define CONFIG_PHY_YT8521 #undef CONFIG_PHY_MARVELL #undef CONFIG_PHY_REALTEK2.2 复位电路处理YT8521的硬件复位引脚通过PL侧的GPIO控制需要在U-Boot中添加复位逻辑。我们在board_init()函数里添加了如下代码/* PHY复位引脚配置 */ gpio_request(CONFIG_PHY_RESET_GPIO, phy_reset); gpio_direction_output(CONFIG_PHY_RESET_GPIO, 0); mdelay(50); gpio_set_value(CONFIG_PHY_RESET_GPIO, 1); mdelay(100);2.3 TX Delay关键配置RGMII接口的时序调试是个重头戏。实测发现YT8521的TX时序需要特别配置通过修改PHY寄存器0xA003实现int yt8521_phy_fixup(struct phy_device *phydev) { phy_write(phydev, 0xA003, 0xF9); // 调整TX Delay return 0; }这个值需要根据实际PCB布线长度调整我们通过示波器测量眼图最终确定0xF9最稳定。调试时可以用以下命令测试不同值 mii write 0x1 0xA003 0xF9 ping 192.168.1.1003. 设备树关键配置3.1 基础网络节点配置设备树需要正确配置PHY地址和接口类型。这是我们的实际配置片段gem0 { phy-mode rgmii-id; phy-handle phy0; status okay; mdio { phy0: phy1 { compatible ethernet-phy-id0000.8521; reg 1; reset-gpios gpio0 55 1; reset-assert-us 10000; }; }; };特别注意phy-mode要配置为rgmii-id这个模式表示MAC和PHY两端都需要做延迟调整。如果配置错误会导致百兆能通但千兆不通的奇怪现象。3.2 时钟配置陷阱ZYNQ的GEM时钟配置有个隐藏坑点需要在clk节点中添加如下配置clocks clkc 30, clkc 13, clkc 21; clock-names pclk, hclk, tx_clk;缺少tx_clk会导致PHY协商速率异常这个在官方文档里都没有明确说明是我们通过抓信号发现的。4. Linux内核驱动移植4.1 驱动文件准备内核默认不包含YT8521驱动需要手动添加。我们从厂家要到了驱动源码主要包含两个文件drivers/net/phy/yt8521.c (驱动主体)include/linux/phy/yt8521.h (寄存器定义)文件放置到位后要修改drivers/net/phy/Makefileobj-$(CONFIG_PHYLIB) yt8521.o4.2 PHY初始化配置在yt8521.c中需要实现config_init函数关键配置如下static int yt8521_config_init(struct phy_device *phydev) { int ret; /* 使能千兆模式 */ ret phy_write(phydev, 0x1e, 0x0008); ret | phy_write(phydev, 0x1f, 0x848f); /* 配置RGMII时序 */ ret | phy_write(phydev, 0xa003, 0xf9); return ret; }4.3 内核配置选项在内核menuconfig中需要确保以下选项开启Device Drivers - Network device support - PHY Device support - * Drivers for YT8521 PHYs5. 稳定性调优实战5.1 中断优化默认的中断处理在高负载时会出现丢包我们在设备树中添加了中断限速配置interrupts 0 29 4; interrupt-names macb0; interrupt-parent intc;并在驱动中增加了NAPI支持static int yt8521_probe(struct phy_device *phydev) { phydev-irq PHY_POLL; phydev-supported | SUPPORTED_Pause | SUPPORTED_Asym_Pause; return 0; }5.2 DMA缓冲区调整通过修改内核启动参数增加DMA缓冲区bootargs earlycon consolettyPS0,115200 root/dev/mmcblk0p2 rw earlyprintk mem512M dma_zone_size32M这个配置在传输大文件时特别重要默认配置在传输超过100MB文件时会出现卡顿。5.3 实际测试数据我们使用iperf3进行了72小时稳定性测试关键指标如下测试项目百兆模式千兆模式吞吐量94.3Mbps942Mbps丢包率0.01%0.005%延迟波动2ms1ms最终的ping测试结果也很稳定$ ping 192.168.1.100 -c 1000 --- 192.168.1.100 ping statistics --- 1000 packets transmitted, 1000 received, 0% packet loss round-trip min/avg/max 0.512/0.647/1.234 ms6. 常见问题排查指南6.1 链路无法UP首先检查MDIO通信是否正常# 读取PHY ID miiutil -r 0x1 0x2正常应该返回0x0000.8521。如果读不到检查硬件上拉电阻是否接好MDC/MDIO线路是否有干扰PHY地址是否配置正确6.2 千兆模式不稳定通过示波器检查以下信号质量RGMII_TXCLK的上升沿是否干净TXD[3:0]与TXCLK的时序关系电源纹波是否在3%以内6.3 大数据传输断流在驱动中添加统计信息很有帮助struct yt8521_priv { u64 tx_timeout_count; u64 rx_error_count; };这个项目前后折腾了将近一个月最深的体会是国产PHY的文档和参考设计确实不如国际大厂完善但通过示波器抓信号、寄存器级调试这些硬核方法最终还是能解决问题。现在这套系统已经稳定运行半年多证明国产方案完全可以胜任工业级应用。