3. mdio-tool 的四大金刚:read、write、dump、list
好了,咱们直接切入正题。mdio-tool 这个工具,说白了就是咱们和 PHY 芯片对话的“对讲机”。它最核心的操作就四个:read、write、dump 和 list。我个人习惯把这四个命令称为“四大金刚”,搞定它们,PHY 调试就入门了。
很多新手一看命令手册,满屏的十六进制就头晕。别急,咱们一个一个拆开揉碎了讲。我会结合我调试 PHY 时的实际场景,让你明白每个命令到底在干什么。
3.1 list:先看看你家门口有几台 PHY
刚开始调试,你总得知道设备上挂了几颗 PHY 吧?它们挂在哪条 MDIO 总线上?list 就是干这个的。
# 查看系统上所有注册的 MDIO 总线及其 PHY 地址
mdio-tool list
输出大概是这样的:
mdio_bus: /sys/bus/mdio_bus/devices/
stmmac-0:00 /sys/bus/mdio_bus/devices/stmmac-0:00
stmmac-0:01 /sys/bus/mdio_bus/devices/stmmac-0:01
stmmac-1:00 /sys/bus/mdio_bus/devices/stmmac-1:00
你看到 stmmac-0:00,stmmac-0 就是 MDIO 总线名(通常是 MAC 驱动注册的),00 是 PHY 地址,一般是 0x00 到 0x1f。嗯,这里要注意,并不是所有的地址都能通信,只有 PHY 芯片真正占用的地址才有反应。
dump 命令快速看一眼每个地址的 PHY ID 寄存器(地址 2 和 3)。Marvell 的 PHY ID 开头一般是 0x0141,Broadcom 是 0x0020。一眼就能分辨出厂家,省得猜半天。
3.2 read:窥探 PHY 的内心世界
这是最常用的命令。你想知道当前网线有没有插上?想知道协商速率是 100M 还是 1G?那就去读对应的寄存器。
# 读取 PHY 地址 0x00 的寄存器 0x01(状态寄存器)
mdio-tool read stmmac-0 0x00 0x01
命令格式我总结了一下:mdio-tool read [总线名] [PHY地址] [寄存器地址]。
返回的是一串 16 位的数据,比如 0x796d。你会问,这 0x796d 是什么意思?你想想看,这需要对照 PHY 芯片的数据手册(Datasheet)去解析每一位。
比如 0x01 寄存器(基本状态寄存器),Bit 13 表示是否 Link Up(链路已建立),Bit 12 表示是否支持自动协商,Bit 9 表示是否处于全双工模式。0x796d 转换成二进制,对应的位就能看出状态了。我刚开始总觉得对着数据手册数 bit 很麻烦,后来习惯了就好了。
3.3 write:给 PHY 发号施令
光读不行,咱们还得能写。比如你想让 PHY 软复位、修改 LED 灯的模式、开启或者关闭某个测试模式,这都需要写寄存器。
# 向 PHY 地址 0x00 的寄存器 0x00(控制寄存器)写入 0x9140,实现软复位+开启自动协商
mdio-tool write stmmac-0 0x00 0x00 0x9140
说白了,就是把你想设置的值直接怼到寄存器里。但这里有个坑,我差点栽跟头:写操作通常只操作寄存器中的某几个 bit,你不能直接写死整个寄存器。比如你要改第 12 位,正确的做法是先读(Read),修改对应的 bit(Modify),再写回去(Write)。这就是 MDIO 驱动的精髓——“读-改-写”。
mdio-tool 没有提供“读-改-写”一条命令,所以你得手动来两步:
read出原始值,记下来。- 用计算器算出要写入的新值,再用
write写进去。
在 Linux 用户态做这个确实有点繁琐,但你如果是写内核驱动,可以用 phy_read 和 phy_write API,并配合 __set_bit 宏来完成。
3.4 dump:一键快照,全盘托出
当你遇到奇怪的问题,比如网口瞬间掉线了,或者协商速率不对,最好的办法是什么?对整个 PHY 做一个快照。 dump 命令就是干这个的。
# 将 PHY 地址 0x00 的所有 32 个寄存器(0x00 ~ 0x1F)一次性全部读出来
mdio-tool dump stmmac-0 0x00
输出会按照地址顺序,列出所有寄存器的值。拿到这个快照,你就可以和“正常情况”下的快照做对比。你想想看,如果能抓到“故障前”和“故障中”两组 dump 数据,基本上问题就定位出七七八八了。
我个人习惯在调试板的网络驱动启动后,先做一次 dump 保存为 phy_dump_good.txt。
dump 命令在常温下抓了一次,又在 85°C 环境下抓了一次。一对比发现,某颗 PHY 的 信号质量检测寄存器(SQI)在高温下跳变得很厉害。借助这个线索,我定位到了电源噪声耦合的问题。所以,dump 命令不仅仅能看到寄存器,还能看到物理层的“健康状况”。
下面这张图,帮你理清这四个命令分别用在调试的哪个阶段:
| 命令 | 功能 | 典型场景 | 避坑提示 |
|---|---|---|---|
list |
枚举总线上所有 PHY | 确认硬件是否识别、地址是否正确 | 无 |
read |
读指定寄存器(16位) | 查看状态、诊断问题 | 注意“读即清除”型寄存器 |
write |
写指定寄存器(16位) | 软复位、配置工作模式、使能测试 | 必须“读-改-写”,别写死保留位 |
dump |
批量读全部寄存器 | 抓快照、对比正常/异常状态 | 快照量大,建议保存到文件 |