捡垃圾,开发发现网口没反应!
RIoTBoard(i.MX6 Solo/DualLite 系,板上千兆 PHY 常见AR8035).官方资料与主线补丁都这么写,且默认 PHY 地址 0x4.
上电就发现现象.
- U-Boot 里 `mii device`/`mdio list` 没有设备
- `mii info 4` 以及 0-31 全扫都没反应
- Linux dmesg 报 "MDIO device at address 4 is missing".
最终定位为PHY 复位未正确释放导致MDIO 完全不应答;手动复位后立即恢复.
快速思路图
- 先证实"工具链没坑":U-Boot 是否启用了 mii/mdio/gpio 等命令;U-Boot 文档有明确的 Kconfig/命令说明.
- Linux 下直扫 MDIO:用
phytool
通过内核 MDIO 接口读寄存器,避开 U-Boot 定制差异.([GitHub][6]) - 强制给 PHY 一个"标准复位时序":GPIO 拉低≥10ms,再拉高;立刻重扫.(U-Boot 的
gpio
命令可直接出手.) - 测链路:读 BMSR(寄存器 1)看 Link 位,但请连续读两次--Link 位是**"低电平锁存(latch low)"**,读一次不准是正常的.
- 如果能读出 PHY ID(常见 AT803x 的 ID),基本可判硬件 OK,后续是 DTS/时序配置层面的活(如
phy-mode = "rgmii-id"
).Linux 设备树对 RGMII 模式的延时有明确指导:绝大多数板都该用rgmii-id
.
现场操作记录(可复用)
A. U-Boot 侧(快检 + 复位)
# 看看命令在不在
=> help mii # 就算没有,也只是说明U-Boot没编译这个工具,不判定硬件问题
=> help mdio
=> gpio status -a
手动复位 PHY(以 RIoTBoard 常见 GPIO3_31 为例;线性编号=3×32+31=127):
=> gpio clear GPIO3_31 # 低有效,拉低 ≥10ms
=> sleep 0.02
=> gpio set GPIO3_31 # 释放复位
gpio
命令的语义与参数见官方文档.
复位后再扫 MDIO:
=> mii device # 应该能看到 MII/MDIO 设备
=> mii info 4 # 读具体地址(RiotBoard 常见 0x4)
B. Linux 侧(内核路径,避开 U-Boot 定制)
用 phytool
扫描 MDIO:
# 先装好 phytool(小单文件工具)
phytool print eth0/0
for a in $(seq 0 31); do phytool read eth0/$a/2 2>/dev/null | sed "s/^/$a: /"; done
# 针对 0x04 直读"常见寄存器集"
phytool print eth0/4
验证链路(BMSR 连读两次):
phytool read eth0/4/1 >/dev/null
phytool read eth0/4/1 # 第二次为"实时值"
为什么要读两次?Link 位是latch-low(有过瞬断也能被检测到),各家 PHY 文档与驱动都强调"读两次取第二次".
这次根因:PHY 复位时序/电平不对
- 复位时刻,PHY 会采样地址拉脚与若干工作模式;复位没拉到位/时序太短,可能导致 MDIO 地址不为预期(0x4) 或干脆不应答.你这里就是典型"复位补一刀,MDIO 立刻活了".
- RIoTBoard 的主线 DTS 其实已经把这堆细节写清楚:
phy@4
,reset-gpios
,interrupts-extended
;- RGMII 内部延时:
phy-mode = "rgmii-id"
; - 还会配置 PHY 的时钟输出给 MAC.
- Linux 设备树的 RGMII 指南明确建议:绝大多数板卡应选
rgmii-id
(由 PHY 或 MAC 提供内部延时),不然就会有收发时序漂的诡异问题.
经验教训 / Checklist
- 先证实工具链:U-Boot 有没开
CMD_MII/CMD_MDIO/CMD_GPIO
;没开就别拿它判硬伤. - 能在 Linux 读 MDIO 就先读:
phytool
是最快的硬件分水岭. - 链路位要读两次:BMSR 的 Link 位是 latch-low,多家 PHY 文档/驱动都这样要求.
- 一旦能读到 PHY ID,大概率硬件没坏;接下来把 DTS 写对:
mdio { phy@4 { reg = <4>; reset-gpios = ...; }};
phy-mode = "rgmii-id"
;必要时补 PHY 私有属性(如 125MHz 时钟输出).
- 需要"无损试机"? 直接 RAM-boot 主线 U-Boot 用
imx_usb_loader
,不改 eMMC/SD 内容,适合纯体检.