1. MDIO协议概述:作用、历史与基本概念

做嵌入式的人,谁没跟PHY芯片打过交道?你想想看,CPU要联网,得经过MAC和PHY,而PHY就像个“黑盒子”。怎么跟它对话?怎么配置它的模式、读取它的状态?MDIO协议,就是干这个的。说白了,它是一条串行总线,专门用来管理以太网PHY和部分交换芯片。

我个人习惯把MDIO比作“数字外科医生的探针”——不打乱数据传输,却能精准地读写内部寄存器。嗯,这里要注意:MDIO和MDC是配套的,一个数据线,一个时钟线,典型的主从结构。

1.1 为什么需要MDIO?

早期的PHY芯片,配置全靠外部引脚。比如某款10M PHY,用二进制跳线选择速度和双工模式。一旦量产,想改配置?只能换电阻。我当初做过一个产品,现场出了问题想远程调PHY,结果只能派人去拨开关……后来换了带MDIO的PHY,一句话就能搞定。

所以MDIO的核心作用是:在运行期间对PHY进行实时监控和动态配置。包括:

  • 读取链路状态(Link up/down、速率、双工模式)
  • 配置休眠/唤醒、节能模式
  • 管理自动协商(Auto-Negotiation)
  • 调试网络异常(比如CRC错误计数)

划重点:没有MDIO,你就是个“睁眼瞎”。有了它,PHY所有内部寄存器都展现在你面前。

1.2 历史片段:从慢速到高速

MDIO最初出现在IEEE 802.3u(1995年)中,当时叫MII管理接口。那时候PHY只有几个基本寄存器。后来随着千兆、万兆以太网发展,标准升级到Clause 45(2000年),支持更多设备(MMD)和更大地址空间。

标准版本出台年份最大设备数寄存器空间典型场景
Clause 22(MII)19953232(5位地址)百兆以下PHY
Clause 45(MMD)200032个设备×256路65536(16位地址)千兆/万兆PHY、PMA/PMD

你看,2000年已经过去二十多年,但Clause 45依然是主流。我在调试一款25G以太网PHY时,就用Clause 45协议访问内部的PMA寄存器——地址空间大,用起来很爽。

1.3 基本概念:帧结构

MDIO通信是通过固定格式的帧来完成的。每次操作,主设备(通常是MAC或CPU)发出一个帧,从设备(PHY或MMD)在特定时钟沿回应。帧结构长这样(我手写个伪代码你就明白了):

// MDIO管理帧结构(Clause 22写操作示例)
// 32位前导码 + 起始码(2) + OP码(2) + PHY地址(5) + REG地址(5) + 转向(2) + 数据(16)
// 总长度:32 + 2 + 2 + 5 + 5 + 2 + 16 = 64位

bit[31:0]  preample  = 0xFFFFFFFF  // 32个连续1
bit[1:0]   start     = 2'b01      // 起始码固定01
bit[1:0]   op        = 2'b01      // 01=写, 10=读
bit[4:0]   phy_addr  = 5'b00001   // 目标PHY编号
bit[4:0]   reg_addr  = 5'b01010   // 寄存器地址
bit[1:0]   ta        = 2'b10      // 转向周期:主发10,从发在后半段
bit[15:0]  data      = 16'hA5A5   // 写入的数据

嗯,这里要注意:读操作时,转向周期的第1个时钟由主设备驱动高阻(Z),第2个时钟由从设备驱动数据位。所以读取的帧会在TA阶段多一个小变化。

经验之谈:我刚开始写MDIO驱动时,总搞混OP码和TA的时序。后来画了个时序图贴在工位上——对着波形数时钟,一次就调通了。

1.4 基本概念:寄存器模型

每个PHY至少包含16个基本寄存器(Clause 22),地址0x00~0x0F。其中前几个是固定的:

  • 寄存器0x00:控制寄存器(复位、自协商、回环)
  • 寄存器0x01:状态寄存器(Link up、速率、全双工)
  • 寄存器0x02~0x04:PHY标识符(两个字节的厂商ID和型号)
  • 寄存器0x05~0x0F:厂商自定义寄存器

Clause 45将寄存器空间扩展到16位地址,分设备类型(Device Type),每个设备又有独立的地址空间。比如设备3是PMA/PMD,设备7是PCS。我在调试某款Marvell PHY时,发现需要同时读Clause 22的基本寄存器(用于链路状态)和Clause 45的PMA寄存器(用于信号质量)。

注意:Clause 22和Clause 45的地址编码方式不同,不能混用。很多PHY芯片同时支持两种模式,但需要通过操作码(OP码)来区分。如果发错了帧,PHY可能没有反应,甚至返回错误数据。

1.5 电气特性:别让信号失真

MDIO是双向半双工总线,MDC由主设备产生。电气参数主要参考IEEE 802.3标准:

参数最小值典型值最大值单位
MDC频率—2.525MHz
MDIO上升/下降时间—3—ns
高电平输入2.03.35.0V
低电平输入0—0.8V
输出驱动电流48—mA

实际项目中,2.5MHz是比较稳妥的选择。我曾经把MDC提到10MHz,结果在长线缆上读到错误校验——波形已经变形了。后来降低到2.5MHz,稳稳地搞定。

还有一个容易忽略的点:MDIO上拉电阻。标准要求MDIO必须通过一个1.5kΩ~10kΩ的电阻上拉到VDD。否则空闲时总线浮空,会导致通信冲突。我见过一个烂设计,工程师忘了加上拉,结果PHY偶尔能读偶尔不能读——排查了半天。

一句话总结:MDIO的电气层面并不复杂,但频率、上拉和PCB走线直接影响稳定性。调不通时,先拿示波器看看MDC和MDIO的波形——数字工程师最该信任的,就是波形。

好了,到这里MDIO协议的基本骨架你应该心里有数了。我们接下来用一张图梳理一下本章的知识脉络——画得比较简,但核心关系都在。

MDIO协议知识体系 MDIO管理接口 帧结构 前导码+起始码 OP码+地址+数据 历史版本 Clause 22 (MII) Clause 45 (MMD) 电气特性与寄存器 时序/上拉/频率 寄存器模型 实际调试中三项缺一不可 不理解帧结构 → 解析失败;搞不清版本 → 协议不兼容;电气参数不对 → 通信不稳定

这张图把MDIO协议的核心维度都串起来了。底层是管理接口,上面分出帧结构、版本演化和电气三大部分,每个部分又细化到具体知识点。你品一品:无论以后遇到什么PHY,只要你能搞清楚这三个维度,基本就能搞定。