排查交换芯片丢包时,最费时间的往往是不知道该看哪里。这篇记录调试 SM5396 时最有用的几个寄存器,以及它们能回答什么问题。SM5396 的手册写明寄存器与 BCM5396 相同,所以细节要查 BCM5396 手册。
值得盯的寄存器
以下寄存器都在 SerDes 页,页号为 0x10 + 端口号。
| 寄存器 | 作用 | 要点 |
|---|---|---|
STS1(0x28) |
看链路状态和发生过的错误 | bit15:7 是锁存错误位,读清;bit6:0 是当前状态,其中 bit1 是 link |
ERR_CNT(0x2E) |
统计误码和 CRC 错误 | 高 8 位是 BER,累加,到 FF 封顶,用 CTRL2 bit14 清零;低 8 位是 CRC,读清,到 FF 封顶 |
CTRL1(0x20) |
决定能不能数到 CRC | bit7 CRC_DIS 默认为 1,也就是 CRC 检查默认关闭;bit11 决定 ERR_CNT 低 8 位计 CRC 还是接收包数 |
MII_STS(0x02) |
看 link 状态 | link 位锁存低,第一次读到的可能是历史状态,要读两次 |
有两点最容易漏掉:
- 不打开
CTRL1的 CRC 检查,CRC 计数就一直数不到,看起来像是链路没有问题。 ERR_CNT的两部分清零方式不同,BER 要写CTRL2清零,CRC 读一次就清零。
STS1 的错误位
STS1 里最关键的是这三个错误位,它们能区分误码有没有造成丢包:
TX_ERR、CRC_ERR:误码落在帧内,这一帧丢失。FALSE_CRS:误码落在帧间空闲,不丢包。
怎么看 BER 和 CRC
BER 反映链路质量,CRC 反映实际丢帧。 BER 高不一定丢包,要看误码是否落在帧内。
两者都是本端口接收方向的统计。 哪个口的计数高,就查发往这个口的那条路径,问题的方向由此确定。
BER 是定位利器。 丢包是低概率事件,要等很久才能碰上一次,而 BER 每秒都有数据。不用等丢包,每秒采样一次各端口的 BER,就能比较各条链路的好坏。有问题的链路通常一眼就能看出来,健康的端口 BER 基本为 0。
ping 的流量小,会掩盖问题。 每秒几百的 BER 也可能只丢一两个包,换成大流量可能严重得多。
排查方法
- 按路径分组看丢包。 对比哪些路径丢包、哪些不丢,找出丢包路径的共同点,能很快缩小范围。
- 把丢包和事件按时间对上。 丢包时刻对应上
CRC_ERR、TX_ERR和 CRC 计数加一,才算证据成立。 - 先排除软件和 CPU 侧。 确认 MAC/DMA 寄存器正常,交换芯片的配置与上电时的快照一致。
- 用 VLAN 隔离代替拆硬件。 硬件不方便动时,把可疑端口隔离出去。如果丢包消失而 BER 还在,就直接证明了丢包来源。
- 多次上电、多块板对比。 同一条链路每次上电的表现可能完全不同,只看一次容易下错结论。
访问寄存器的坑
- SM5396 没有 MIB。 读 BCM5396 的 MIB 页(P20h~P2Fh)不会应答,SPI 控制器的请求会一直挂着,只能复位。不要照搬 BCM5396 的 MIB 读取代码。
- SPI 访问要有超时。 如果驱动一直等待应答,遇到读不回来的寄存器就会永久卡死。
- SPI 访问要加锁。 驱动本身不一定有互斥,多任务访问时要自己保证。
- 读清寄存器只能有一个读者。 两个任务同时读,计数都不准。
- 监控任务的优先级要低于业务任务。 SPI 轮询是忙等,优先级高了会压住业务任务,反而制造新问题。
其他容易踩的坑
- 对端没报错不代表链路没问题。 交换芯片会丢掉坏帧,对端网卡看不到 CRC 错误。普通 ping 只是少一个
icmp_seq,丢包率低时很容易漏看。 - 强制模式下状态不一定可信。 应用指南说明,端口用 override(Page 00h,
0x60 + 端口号)强制后,其状态寄存器 “not meaningful”。 - 隔离时注意环路。 外部互连的两个口放在同一 VLAN 会形成环路,隔离时要各放一个单独的 VLAN。
关于本文
由 Shane 撰写, 采用 CC BY-NC 4.0 许可协议.