链路建立过程:Auto-Negotiation、Link Up、Speed/Duplex 协商
链路建立不是一蹴而就的,它分三步走:自动协商检测对端能力,Link Up 确认信号稳定,最后Speed/Duplex 把结果应用起来。很多人只在软件层面配寄存器,链路不通就抓瞎。我个人习惯从物理层开始排查,一步一步拆解。
一、自动协商(Auto-Negotiation)原理
自动协商说白了就是两个 PHY 互相喊话:「你能跑多快?是全双工还是半双工?」喊话的媒介是 FLP Burst(Fast Link Pulse Burst)。你的 PHY 发一串脉冲,对端回应自己的能力集,双方取交集里的最优组合。
我曾经遇到过一块板子,插上网线死活不 Link Up。抓 MDIO 发现自动协商没有完成,PHY 状态寄存器一直是 0x01(Auto-Negotiation in progress)。换了一根短网线就好了。原因是 PCB 走线太长,FLP 信号畸变,对端收不到完整的 Burst。所以排查时别忘了检查物理介质质量。
协商优先级由标准规定,IEEE 802.3 里定义了一张表。我贴出来方便对照:
| 优先级 | 速度/双工模式 |
|---|---|
| 1(最高) | 1000BASE-T 全双工 |
| 2 | 100BASE-T2 全双工 |
| 3 | 100BASE-TX 全双工 |
| 4 | 100BASE-T4 |
| 5 | 100BASE-TX 半双工 |
| 6 | 10BASE-T 全双工 |
| 7(最低) | 10BASE-T 半双工 |
取交集时,双方各自选择一个能力位图,然后选优先级最高的那项。注意如果一方不支持自动协商,另一方也会尝试用 并行检测(Parallel Detection) 来锁定链路速度。这很容易出问题——我调试过几个案例,一方强制 100M 全双工,另一方自动协商,结果只能跑 100M 半双工,丢包率飙升。
二、Link Up 信号检测
自动协商完成后,PHY 会输出 Link 脉冲 或持续的信号以维持连接。Link Up 的标志是寄存器 Bit 0(Link Status)变成 1。但注意——这个位可能被自清除,所以读取时要读两次或开启自动协商完成中断。我习惯在驱动里用轮询加超时机制,每 10ms 读一次,连续三次为 1 才认为 Link Up 稳定。
你真的以为 Link Up 就万事大吉了吗?不一定。有一次我在调试一款交换芯片,Link Up 指示灯亮了,MDIO 寄存器也显示 0x786D(Link OK, 1000M full duplex),但板上 FPGA 就是收不到数据。最后发现是 MAC 侧的 RGMII 时钟相位没对准,RX 时钟反相了。所以 Link Up 只说明物理层信号存在,不代表数据通道正常。
PHY_ANEG_COMPLETE 和 PHY_LINK_UP 混合标志为准。
我曾经用 示波器测量差分对 来辅助判断:
- Link Down 时,差分线对一般无信号或只有微弱噪声。
- Link Up 且空闲时,会看到连续的空闲码(Idle Code)或链路脉冲。
- Link Up 且传数据时,差分信号幅值稳定在规范范围内(例如 100BASE-TX 约 ±1V)。
示波器探头用 10× 挡,地线尽量短,最好用差分探头。我见过太多人用单端探头测不到波形就断言 PHY 坏了,其实是地线太长引入了共模噪声。
三、Speed/Duplex 协商结果应用
自动协商完成后,PHY 内部会把协商好的速度和双工模式写入 PHY 控制寄存器(通常是 Register 0)和 状态寄存器(Register 1)。MAC 侧一般通过 GMII/RGMII/SGMII 接口 的时钟频率和信号线来识别的:
- RGMII 时钟频率:1000M 时 125MHz,100M 时 25MHz,10M 时 2.5MHz。
- SGMII 比较特殊:它会在低速模式下插入流水线控制码,以保持线速。
你可以通过 MDIO 读取 Register 0 的 Bit 13(Speed bit1)和 Bit 6(Speed bit0)来确认速度。下面这张表是常见结果:
| Bit13 | Bit6 | 协商速度 |
|---|---|---|
| 0 | 0 | 10Mbps |
| 0 | 1 | 100Mbps |
| 1 | 0 | 1000Mbps |
| 1 | 1 | 保留 |
双工模式看 Bit 8:0 为半双工,1 为全双工。
注意,有些 PHY 允许 强制设置 速度和双工模式,绕过自动协商。这需要两侧手动配置一致,否则会出现 双工不匹配——一侧全双工,另一侧半双工,链路能通但丢包严重。我曾在某车载项目里遇到过,工厂测试时强制 PHY 为 100M 全双工,但车载交换机侧是自动协商,结果跑着跑着 Link dropped,最后全部改成自动协商才稳定。
以上就是链路建立的完整过程。你调试的时候,建议按这个流程走:先确认自动协商是否完成(读 Register 1 Bit 5),再确认 Link Up 信号(Register 1 Bit 2),最后读速度和双工寄存器验证应用结果。三者都对上了,物理层问题基本可以排除。剩下的就是 MAC 侧配置和 PCB 走线了。