ARTICLE DETAIL

资讯详情

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

RK3568适配YT8521S千兆PHY驱动实战指南

RK3568适配YT8521S千兆PHY驱动实战指南 简介本资源是针对RK3568平台适配YT8521S千兆以太网PHY芯片的完整驱动补丁包面向嵌入式Linux内核开发者、BSP工程师及硬件驱动调试人员解决RK3568在实际项目中接入YT8521S PHY时缺乏官方支持、链路无法建立或loopback测试失败等典型问题。压缩包共11个文件含6个C源码如dwmac-rk-tool.c、motorcomm.c、2个头文件motorcomm_phy.h等、2个说明类txt文档及1个关键patch文件0001_yt8521s_loopback_test.patch覆盖驱动适配、寄存器配置、环回测试及内核4.4/4.19双版本兼容性处理。资源仅52KB轻量高效结构紧凑便于快速集成与验证。目前已有1644人学习下载读者可直接获取经过实测的PHY初始化序列、MAC-PHY联动调试要点、以及针对RK平台定制的phy_device.c修改逻辑显著降低自研PHY驱动的开发门槛与排错周期。1. RK3568 上跑通 YT8521S PHY不是加个 .ko 就能亮灯而是要捅穿 DWMAC 驱动层的三道墙你手上有块 RK3568 开发板网口插上 YT8521S 千兆 PHY 芯片ifconfig eth0 up后ethtool eth0显示 link downdmesg | grep phy里反复刷出phy_read failed或no PHY found——这不是线没插好也不是 PHY 没供电而是 RK 原生 kernel4.4/4.19压根不认识 YT8521S 这颗国产 PHY。RK_YTPHY_20210906.zip就是专治这个“认不出”的黑匣子补丁包它不只提供motorcomm.c驱动源码更关键的是把dwmac-rk-tool.c工具链、0001_yt8521s_loopback_test.patch回环测试补丁、以及适配 kernel4.4 和 kernel4.19 的两套phy_device.c修改逻辑全打包塞进一个 ZIP。它解决的不是“能不能用”而是“怎么让 RK 的 DWMAC 控制器主动去握手 YT8521S 的寄存器地址、正确读取 MII 状态、并支持 loopback 自检”——这三步卡在绝大多数 RK3568 客户的量产前夜。适合正在做工业网关、边缘盒子、或国产化替代项目的嵌入式工程师尤其当你已经试过CONFIG_REALTEK_PHYy却发现根本没卵用时这份补丁就是后悔药。2. 从 ZIP 解包到内核编译四步落地 YT8521S 驱动2.1 解压与目录结构还原别直接make modules先看清补丁层级unzip RK_YTPHY_20210906.zip -d rk_ytphy_work cd rk_ytphy_work ls -R输出会显示两个并行路径kernel4.4/和kernel4.19/各自包含dwmac-rk-tool.c、motorcomm_phy.h、motorcomm.c、phy_device.c、readme.txt。注意这不是两个独立驱动包而是同一套逻辑在不同 kernel 版本下的适配分支。kernel4.4下的phy_device.c修改集中在drivers/net/phy/realtek.c的兼容层注入而kernel4.19则直接 patchdrivers/net/phy/motorcomm.c并 hook 进phy_init_driver()。readme.txt里那句 “apply patch first, then copy motorcomm.c” 是血泪经验——很多人跳过 patch 直接替换.c文件结果编译报undefined reference to yt8521s_config_init因为 patch 才真正注册了PHY_ID_MATCH_EXACT(0x00221710)这个 ID。提示0001_yt8521s_loopback_test.patch是独立补丁必须先git apply到你当前 kernel 源码树的drivers/net/ethernet/stmicro/stmmac/目录下它修改的是stmmac_main.c中的stmmac_set_mac_loopback()函数为后续dwmac-rk-tool发送 loopback 命令铺路。2.2dwmac-rk-tool.c不只是调试工具它是 PHY 寄存器级操作的唯一入口dwmac-rk-tool.c编译后生成的可执行文件才是验证 YT8521S 是否真正“活过来”的终极手段。它绕过 kernel PHY 子系统直接通过 RK3568 的 GMAC 寄存器GMAC_MAC_MDIO_ADDR,GMAC_MAC_MDIO_DATA读写 PHY 地址0x00PHY ID1、0x01PHY ID2、0x10YT8521S 特有寄存器Extended Status// dwmac-rk-tool.c 关键片段kernel4.19 分支 int mdio_read(int phy_addr, int reg) { writel((phy_addr 8) | reg, base GMAC_MAC_MDIO_ADDR); while (readl(base GMAC_MAC_MDIO_ADDR) 0x1); // wait busy return readl(base GMAC_MAC_MDIO_DATA) 0xffff; }编译命令需交叉工具链aarch64-linux-gnu-gcc -o dwmac-rk-tool dwmac-rk-tool.c -static运行前确保CONFIG_STMMAC_ETH和CONFIG_DWMAC_ROCKCHIP已启用且stmmac模块已加载insmod stmmac.ko ./dwmac-rk-tool -p 0 -r 0x00 # 读 PHY ID1应返回 0x0022 ./dwmac-rk-tool -p 0 -r 0x01 # 读 PHY ID2应返回 0x1710 → 合起来就是 0x00221710YT8521S 的标准 ID如果0x00和0x01返回值不对说明硬件连接MDIO clock/data 线或 PHY 地址拨码默认 0x00有问题此时 kernel 驱动再完善也无济于事。2.3motorcomm.c编译与模块插入两套 kernel 的 Makefile 写法差异kernel4.4和kernel4.19的motorcomm.c不能混用Makefile 写法也不同kernel4.4需在drivers/net/phy/Makefile中追加obj-$(CONFIG_MOTORCOMM_PHY) motorcomm.o并在drivers/net/phy/Kconfig中添加config MOTORCOMM_PHY tristate Motorcomm YT8521S PHY support depends on PHYLIB ---help--- Support for Motorcomm YT8521S Gigabit Ethernet PHY.kernel4.19motorcomm.c已被纳入主线drivers/net/phy/motorcomm.c只需在drivers/net/phy/Makefile中确认obj-$(CONFIG_MOTORCOMM_PHY) motorcomm.o且CONFIG_MOTORCOMM_PHYm模块化或y内置。编译后插入模块# kernel4.19 示例 make modules Mdrivers/net/phy/ insmod drivers/net/phy/motorcomm.ko # 观察 dmesg 输出是否出现 yt8521s: probed on mdio bus若dmesg无输出检查phy_device.c是否已按补丁修改kernel4.19分支中phy_drivers[]数组末尾必须新增{ .phy_id 0x00221710, .phy_id_mask 0xffffffff, .name Motorcomm YT8521S, .driver yt8521s_driver, },3. PHY 初始化失败的五大避坑指南现象、原因、解法全对齐3.1 现象dmesg显示phy phy-ff290000.mdio:00: attached PHY driver [Motorcomm YT8521S]但ethtool eth0仍Link detected: no原因PHY 初始化函数yt8521s_config_init()中未正确配置 YT8521S 的0x1f寄存器Page Select导致后续0x10Extended Status读取失败link status 无法上报。解决检查motorcomm.c中yt8521s_config_init()是否包含以下 page 切换逻辑phy_write(phydev, 0x1f, 0x0000); // 切回 Page 0 phy_write(phydev, 0x1f, 0x0001); // 切到 Page 1YT8521S 特有页 phy_write(phydev, 0x10, 0x0001); // Page 1 的 0x10 寄存器使能 auto-negotiation phy_write(phydev, 0x1f, 0x0000); // 切回 Page 03.2 现象dwmac-rk-tool -p 0 -r 0x00返回0xffff且mdio_read超时原因RK3568 的 MDIO clock 引脚通常是 GPIO0_A0未在 device tree 中配置为mdio_clk功能或 PHY 供电AVDD/3.3V未稳定。解决检查rk3568-evb.dtsi中gmac节点是否包含pinctrl-names default; pinctrl-0 gmac_mdio; ... gmac_mdio { gmac_mdio: mdio-pins { pins gpio0_a0; function mdio_clk; }; };并用万用表实测 PHY 的 AVDD 引脚电压是否为 3.3V ±5%。3.3 现象insmod motorcomm.ko成功但cat /sys/bus/mdio_bus/devices/xxx:00/phy_status显示link: down且phy_read在yt8521s_read_status()中返回-1原因YT8521S 的0x00Basic Control寄存器 bit12AN Enable未置位auto-negotiation 被禁用。解决在yt8521s_config_init()结尾强制写入phy_modify(phydev, MII_BMCR, 0, BMCR_ANENABLE | BMCR_SPEED1000 | BMCR_FULLDPLX);注意BMCR_SPEED1000对应千兆模式YT8521S 不支持百兆强制模式必须走 AN。3.4 现象0001_yt8521s_loopback_test.patch应用后make报错stmmac_main.c:1234: undefined reference to stmmac_set_mac_loopback原因patch 修改了stmmac_main.c的函数声明但未同步更新stmmac.h中的函数原型声明。解决手动在include/linux/stmmac.h中添加int stmmac_set_mac_loopback(struct net_device *dev, bool enable);3.5 现象ethtool -s eth0 speed 1000 duplex full autoneg off手动设速后 link 仍 up 不了原因YT8521S 不支持强制模式Forced Mode其 datasheet 明确要求AN Enable 1否则 PHY 内部状态机不工作。解决删除所有autoneg off的尝试改用ethtool -s eth0 autoneg on ethtool eth0 # 等待 5 秒观察 Link detected: yes4. Loopback 测试用dwmac-rk-tool验证 PHY 寄存器级连通性4.1 为什么必须做 loopback因为ethtool只验 linkdwmac-rk-tool才验 PHY 内部通路ethtool的Link detected: yes只表示 PHY 检测到远端信号不代表 PHY 自身收发通道正常。YT8521S 的 loopback 模式分两级PHY internal loopback寄存器0x00bit14TX 信号在 PHY 内部直连 RX不经过外部 PINMAC loopbackstmmac_set_mac_loopback()GMAC 内部 TX 直连 RXPHY 完全旁路。只有PHY internal loopback通过才能证明 YT8521S 的模拟前端SerDes和数字控制逻辑全部就绪。4.2 执行 loopback 测试的完整命令流# 步骤1确保 PHY 已初始化且 link up ethtool eth0 | grep Link detected # 步骤2启用 PHY internal loopback写 0x00 寄存器 bit14 ./dwmac-rk-tool -p 0 -w 0x00 -v 0x4140 # 0x4140 0x2140 | (114)保留 AN 使能 # 步骤3读取 0x01 寄存器BMSRbit11 应为 1Jabber Detectbit2 应为 1Link Status ./dwmac-rk-tool -p 0 -r 0x01 # 返回值应含 0x0400bit10和 0x0004bit2 # 步骤4发送 dummy packet 并捕获回环帧需提前启动 tcpdump tcpdump -i eth0 -c 1 icmp ping -c 1 192.168.1.1 # 若 ping 通说明 loopback 数据通路闭环注意-v 0x4140中的0x2140是 YT8521S 默认的BMCR值AN Enable Speed1000 Full Duplex| (114)是置位 loopback 位。硬编码此值比phy_modify更可靠避免 kernel PHY 子系统干扰。4.3 Loopback 失败时的寄存器诊断表寄存器地址期望值Loopback ON实际值含义排查方向0x00(BMCR)0x4140若为0x3140bit140loopback 位未写入检查dwmac-rk-tool写操作是否成功0x01(BMSR)0x796dbit15~0 全 set若 bit110PHY 内部时钟未锁定检查 AVDD 和 REFCLK0x10(Ext Status)0x00011000BASE-T capable若为0x0000Page 1 未正确切换检查0x1f寄存器写入顺序0x1f(Page Select)0x0000Page 0若为0x0001page 切换后未切回导致后续寄存器读写错位5. 进阶技巧把dwmac-rk-tool改造成自动校准脚本省掉每次手动dmesg | grep5.1 为什么需要自动校准因为量产时每块板的 PHY 供电纹波不同导致0x10寄存器读取稳定性差异YT8521S 的0x10Extended Status寄存器在电源噪声大时会偶发读取失败返回0x0000但0x00/0x01总是稳定的。因此一个健壮的初始化脚本不应只依赖单次读取而应做三次重试 校验#!/bin/bash # yt8521s_calibrate.sh PHY_ADDR0 MAX_RETRY3 read_ext_status() { for i in $(seq 1 $MAX_RETRY); do val$(./dwmac-rk-tool -p $PHY_ADDR -r 0x10 2/dev/null) if [ -n $val ] [ $val ! 0x0000 ]; then echo $val return 0 fi sleep 0.1 done echo FAIL: 0x10 read timeout return 1 } # 主流程 echo YT8521S Calibration Start if ! ./dwmac-rk-tool -p $PHY_ADDR -r 0x00 | grep -q 0x0022; then echo ERROR: PHY ID1 mismatch exit 1 fi ext_val$(read_ext_status) if [ $ext_val FAIL: 0x10 read timeout ]; then echo CRITICAL: Extended Status unstable, check AVDD ripple exit 1 else echo OK: Extended Status $ext_val fi # 启用 loopback 并验证 ./dwmac-rk-tool -p $PHY_ADDR -w 0x00 -v 0x4140 sleep 0.5 if ./dwmac-rk-tool -p $PHY_ADDR -r 0x01 | grep -q 0x.*0400; then echo SUCCESS: Loopback enabled and link stable else echo FAIL: Loopback not confirmed exit 1 fi5.2 如何集成进 buildroot三步搞定开机自检将dwmac-rk-tool和yt8521s_calibrate.sh放入board/rockchip/rk3568/rootfs_overlay/在board/rockchip/rk3568/post-build.sh中添加install -m 0755 ${BOARD_DIR}/rootfs_overlay/dwmac-rk-tool ${TARGET_DIR}/usr/bin/ install -m 0755 ${BOARD_DIR}/rootfs_overlay/yt8521s_calibrate.sh ${TARGET_DIR}/etc/init.d/S99yt8521s-calibrate创建/etc/init.d/S99yt8521s-calibrate#!/bin/sh /usr/bin/yt8521s_calibrate.sh /var/log/yt8521s.log 21这样每台设备上电后都会自动执行 PHY 校准并将结果记入日志。产线工人只需看/var/log/yt8521s.log最后一行是否为SUCCESS无需懂dmesg或ethtool。5.3 一个血泪习惯每次改motorcomm.c必先git diff drivers/net/phy/motorcomm.c对比原始补丁我见过太多人在kernel4.19分支上修完yt8521s_config_init()却忘了kernel4.4分支的phy_device.c也要同步 patch。更糟的是有人把kernel4.19的motorcomm.c直接拷进kernel4.4目录结果编译时struct phy_driver成员名对不上kernel4.4用phy_idkernel4.19用phy_id_mask。从那以后我每次打开motorcomm.c第一件事就是git diff看改动是否严格对应当前 kernel 版本的补丁内容第二件事是grep -r 0x00221710 .确认 PHY ID 在phy_drivers[]中只出现一次。这多花 30 秒但能省掉 3 小时 debug 时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表