4. 端口与PHY管理
在 Broadcom 交换芯片的软件栈中,端口(Port)与 PHY 是连接 MAC 层逻辑与物理介质的关键环节。SDK 通过统一的 Port 抽象管理芯片内部 MAC、SerDes、外部 PHY 以及光模块,向上为 NOS 提供端口属性配置、链路状态查询、自协商控制、PHY 寄存器访问和热插拔事件处理能力。理解这一层的对象模型与调用路径,是实现端口 UP/DOWN 控制和状态查询的基础。
端口对象模型与属性
在 SDK 中,每个物理端口由 bcm_port_t 标识,逻辑端口组由 bcm_trunk_t 或 bcm_port_group_t 管理。端口属性通过 bcm_port_control_set() 和 bcm_port_control_get() 读写,常见属性包括:
- BCM_PORT_CONTROL_ENABLE:端口使能,决定 MAC 是否收发。
- BCM_PORT_CONTROL_SPEED:端口速率,如 1G、10G、25G、100G。
- BCM_PORT_CONTROL_AUTONEG:自协商使能,影响链路建立方式。
- BCM_PORT_CONTROL_DUPLEX:全双工/半双工。
- BCM_PORT_CONTROL_ENCAP:封装模式,如 IEEE、HG、SGMII。
- BCM_PORT_CONTROL_PHY_MASTER:主从模式,用于 SGMII/1000BASE-X。
端口状态通过 bcm_port_info_get() 获取,返回 bcm_port_info_t 结构,其中 linkstatus、speed、duplex、autoneg、phy_link 等字段反映当前链路实际情况。NOS 通常周期性轮询或通过中断方式获取这些状态,并同步到内核网络设备状态。
链路状态与自协商
链路状态(Link Status)表示端口是否与对端成功建立物理连接。对于电口,链路建立依赖自协商(Auto-Negotiation)完成速率、双工和流控能力交换;对于光口,通常通过 SerDes 的 CDR 锁定和信号检测判断链路。SDK 提供 bcm_port_link_status_get() 直接查询链路,也可通过 bcm_port_info_get() 读取完整信息。
自协商配置需要区分 MAC 侧和 PHY 侧。以 1000BASE-T 电口为例,典型配置流程如下:
/* 使能自协商 */
bcm_port_control_set(unit, port, bcmPortControlAutoneg, 1);
/* 设置自协商能力:1000M 全双工 + 100M 全双工 */
bcm_port_autoneg_set(unit, port,
BCM_PORT_ABILITY_1000MB_FD |
BCM_PORT_ABILITY_100MB_FD |
BCM_PORT_ABILITY_10MB_FD);
/* 查询协商结果 */
bcm_port_info_t info;
bcm_port_info_get(unit, port, &info);
printf("link=%d speed=%d duplex=%d\n",
info.linkstatus, info.speed, info.duplex);
若对端为强制模式,本端自协商可能失败或降速。此时应检查 info.autoneg 与 info.speed 是否与预期一致,必要时改为强制速率并关闭自协商。
PHY 寄存器访问
外部 PHY 通过 MDIO/MDC 总线与 MAC 连接,SDK 提供 bcm_port_phy_reg_get() 和 bcm_port_phy_reg_set() 访问 PHY 寄存器。标准寄存器包括:
| 寄存器 | 地址 | 作用 |
|---|---|---|
| BMCR | 0x00 | 基本控制:复位、自协商、速率、双工 |
| BMSR | 0x01 | 基本状态:链路、自协商完成、能力 |
| PHYID1/2 | 0x02/0x03 | PHY 厂商与型号标识 |
| ANAR | 0x04 | 自协商通告能力 |
| ANLPAR | 0x05 | 对端自协商能力 |
访问示例:读取 BMSR 判断链路是否建立:
uint16_t bmsr;
bcm_port_phy_reg_get(unit, port, 0x01, &bmsr);
if (bmsr & 0x0004) {
/* Link up */
}
对于扩展寄存器(如 Broadcom PHY 的 MII 扩展页),需先写寄存器 0x1E 切换页,再访问目标地址。SDK 的 bcm_port_phy_reg_get() 已封装页切换逻辑,直接传入扩展地址即可。
热插拔处理
光模块热插拔通过 SFP/SFP+ 的 MOD_ABS 引脚或 I2C 中断上报。SDK 提供 bcm_port_module_event_register() 注册回调,当模块插入或拔出时触发事件。典型处理流程:
- 检测到 MOD_ABS 变化,读取模块 EEPROM 识别类型(SFP/SFP+/QSFP)。
- 根据模块类型配置 SerDes 模式与速率。
- 使能端口,启动链路训练或自协商。
- 轮询链路状态,更新 NOS 端口状态。
热插拔事件处理必须考虑去抖,通常延时 100~200ms 再读取模块状态,避免误判。拔出时应先关闭端口发送,再清理资源。
端口 UP/DOWN 与状态查询
端口 UP/DOWN 控制通过 bcm_port_control_set(unit, port, bcmPortControlEnable, 0/1) 实现。关闭端口时,MAC 停止收发,但 PHY 可能仍保持链路。若需完全断电,可调用 bcm_port_phy_power_set()。
状态查询建议组合使用:
bcm_port_info_get():获取链路、速率、双工、自协商状态。bcm_port_link_status_get():快速判断链路 UP/DOWN。bcm_port_phy_reg_get():读取 BMSR 确认 PHY 侧链路。bcm_port_module_event_register():异步获取热插拔事件。
端口管理状态流转
下图展示端口从初始化到 UP/DOWN 及热插拔事件的状态流转关系,以及 SDK 各接口在其中的作用位置。
实际调试中,建议先通过 bcm_port_info_get() 确认端口基础状态,再结合 PHY 寄存器读取判断物理层问题。若链路无法 UP,依次检查:端口是否使能、自协商能力是否匹配、SerDes 是否锁定、模块是否兼容、线缆或光模块是否正常。通过分层排查,可以快速定位是 MAC 配置问题、PHY 协商问题还是物理介质问题。