1、以太网PHY基础知识:PHY的作用、MII接口、MDIO管理接口
各位好,咱们今天聊以太网PHY。说实话,这玩意儿在调试自动协商失败时,往往是第一个被忽略的坑。我这些年处理过不下几十起协商失败的问题,最后发现有一大半都跟PHY的配置、接口时序或者管理通道有关。所以,咱们先把基础打扎实。
1.1 PHY到底管什么?
PHY的全称是Physical Layer transceiver,物理层收发器。它的任务说白了就两件:把MAC发过来的数字信号变成能在网线上跑的模拟信号,反过来再把网线上的模拟信号还原成数字信号给MAC。
听起来简单,对吧?但这里面门道不少。
- 编码/解码:比如100BASE-TX用的MLT-3编码
- 时钟恢复:从接收信号中提取时钟
- 线路驱动:提供足够的驱动能力把信号推出去
- 自动协商:和对端设备商量出一个双方都能跑的速度和双工模式
- 链路状态监测:检测Link是否up、是否有错误
我个人习惯把PHY比作一个翻译官——MAC说数字世界的语言,网线说模拟世界的语言,PHY就在中间做翻译。翻译不好,两边都听不懂。
| 角色 | 负责内容 | 常见问题 |
|---|---|---|
| MAC | 数据帧封装、流控、地址过滤 | 驱动配置错误、FIFO溢出 |
| PHY | 信号编解码、时钟恢复、协商 | 焊接不良、电源噪声、寄存器配置错 |
| 介质 | 网线/光纤 | 线序错误、长度超限、电磁干扰 |
我在项目中遇到过最离谱的一次,板子回来怎么都ping不通。示波器一测,PHY根本没输出时钟。查了半天,结果是PHY的电源去耦电容焊反了。嗯,从那以后我每次画板子都要检查三遍去耦电容的极性。
1.2 MII接口——MAC和PHY之间的桥梁
MII接口就是MAC和PHY之间的数据通道。最早的MII只有4位数据线,跑100M时时钟25MHz,10M时2.5MHz。后来带宽不够用了,就出了GMII(8位数据,125MHz时钟)、RGMII(双沿采样,减少引脚数)、SGMII(串行差分,引脚更少)等等。
你想想看,这么多接口类型,接线稍微差一根或者时序稍微偏一点,自动协商直接就废了。
我建议初学者先从GMII入手调试,毕竟信号线都是独立的,好分析问题。等把GMII调通了,再折腾RGMII或者SGMII——后者的时序约束更紧,出了问题你都不知道从哪查起。
| 接口类型 | 数据位宽 | 时钟频率 | 引脚数 | 典型应用 |
|---|---|---|---|---|
| MII | 4位 | 25MHz/2.5MHz | 18 | 100Mbps以太网 |
| GMII | 8位 | 125MHz | 24 | 1000Mbps以太网 |
| RGMII | 4位(DDR) | 125MHz | 12 | 低成本千兆方案 |
| SGMII | 1位(串行) | 1.25Gbps | 4 | 高速/远距离应用 |
1.3 MDIO管理接口——PHY的控制通道
MDIO接口是用来读写PHY内部寄存器的。MAC通过MDIO去配置PHY的工作模式、查询链路状态、获取协商结果。这个名字可能你更熟悉:SMI(Serial Management Interface)。
MDIO只有两条线:MDC(时钟)和MDIO(数据)。帧结构是固定的,每次读写都需要32位的帧,包含前导码、操作码、PHY地址、寄存器地址、数据和转态位。
// MDIO帧格式(Clause 22)
// 32位帧结构
// 前导码(32个1) + 起始码(01) + 操作码(10写/01读)
// + PHY地址(5位) + 寄存器地址(5位) + 转态(2位)
// + 数据(16位)
// 读操作示例(伪代码)
uint16_t mdio_read(uint8_t phy_addr, uint8_t reg_addr) {
// 发送前导码
// 发送起始码 + 操作码(01)
// 发送PHY地址 + 寄存器地址
// 插入转态位
// 读取16位数据
// 返回结果
}
别看这协议简单,调试起来坑不少。我在项目中见过工程师反复读寄存器都返回0,气得差点把板子砸了。其实原因特别简单——MDIO的上拉电阻没焊。MDIO是个开漏输出,必须有上拉才能正常工作。
Clause 22 vs Clause 45
Clause 22是IEEE 802.3里最早定义的MDIO标准,只能管理32个PHY地址,每个PHY有32个寄存器。后来功能越来越多,寄存器不够用了,于是有了Clause 45,把地址空间扩展到了32个设备地址,每个设备又有32个MMD地址,每个MMD又有65536个寄存器。
- 看启动配置:一般PHY的strap引脚会决定地址映射模式
- 读标准寄存器:Clause 45的PHY在标准寄存器地址上会有不同的实现
- 查看软件驱动:驱动里会明确定义使用的MDIO协议版本
我曾经遇到一个案子,PHY死活不肯协商成千兆。量了MDIO波形,读写好像都正常。后来仔细一看,驱动用的是Clause 45,但PHY只支持Clause 22。驱动里写了个Clause 45的帧去读Clause 22的寄存器,读回来的数据当然全是乱的。这个例子告诉各位,先确认协议版本再动手,省得绕弯路。
好吧,咱们来张图,把这三者的关系捋一捋。
这张图把MAC、MII接口、PHY、MDIO和物理介质的关系都画出来了。从上往下看,MAC通过MII接口把数据交给PHY,PHY编解码后再驱动到网线上。而MDIO则是一条旁路的管理通道,专门用来配置和监控PHY。
在实际调试中,我一般按这个顺序排查:先看MDIO能不能读写寄存器、再看MII接口的时钟和数据是否正常、最后看PHY的协商状态寄存器。遇到问题别慌,按链路一层层剥,总能找到症结。