2. PHY寄存器标准:IEEE 802.3 Clause 22与Clause 45寄存器模型
PHY(物理层)芯片的寄存器接口是软件与硬件交互的核心通道。IEEE 802.3 标准定义了两套主流的寄存器访问模型:Clause 22(传统MII管理接口)和 Clause 45(扩展管理接口)。理解这两套模型的差异、地址空间布局以及基本寄存器的含义,是进行PHY驱动开发和调试的第一步。
2.1 Clause 22 寄存器模型
Clause 22 是最早定义的PHY寄存器访问标准,通过 MDC(管理时钟)和 MDIO(管理数据输入输出)两条线实现。它使用 5 位 PHY 地址(支持最多 32 个 PHY)和 5 位寄存器地址(支持最多 32 个寄存器,地址 0x00~0x1F)。
Clause 22 的寄存器地址空间分为两个区域:
- 基本寄存器(0x00~0x0F): 由 IEEE 802.3 标准强制定义,所有兼容 PHY 必须实现。
- 扩展寄存器(0x10~0x1F): 由各 PHY 厂商自定义,用于芯片特定功能(如 LED 控制、中断配置、高级诊断)。
2.2 Clause 45 寄存器模型
随着万兆(10G)、25G、40G 等高速以太网的出现,Clause 22 的 32 个寄存器空间严重不足。Clause 45 应运而生,它引入了 设备类型(Device Type) 和 地址(Address) 两级寻址机制。
Clause 45 的帧格式包含 5 位 PHY 地址、5 位设备类型(支持最多 32 个设备类型)和 16 位寄存器地址(支持每个设备类型内最多 65536 个寄存器)。这使得总寄存器空间从 Clause 22 的 32 个扩展到 32 × 65536 = 2,097,152 个。
| 对比维度 | Clause 22 | Clause 45 |
|---|---|---|
| 标准出处 | IEEE 802.3-2005 第22条 | IEEE 802.3-2005 第45条 |
| PHY地址宽度 | 5位(0~31) | 5位(0~31) |
| 寄存器地址宽度 | 5位(0~31) | 16位(0~65535) |
| 设备类型 | 无 | 5位(0~31) |
| 最大寄存器数 | 32 | 2,097,152 |
| 典型应用 | 10/100Mbps, 部分1Gbps | 1Gbps, 10Gbps, 25Gbps, 40Gbps+ |
| 访问帧格式 | 简单两阶段(地址+数据) | 四阶段(地址+设备类型+数据) |
2.3 基本寄存器详解
无论 Clause 22 还是 Clause 45,以下 5 个基本寄存器是所有 PHY 驱动必须理解和操作的。它们在 Clause 22 中映射到固定地址(0x00~0x05),在 Clause 45 中位于设备类型 1(PMA/PMD)或设备类型 3(PCS)的特定地址。
2.3.1 BMCR(基本模式控制寄存器,地址 0x00)
BMCR 是 PHY 的“总开关”,控制复位、环回、速度、双工模式、自动协商使能等核心行为。
| 位域 | 名称 | 描述 |
|---|---|---|
| 15 | Reset | 软件复位(1=复位,自清零) |
| 14 | Loopback | 环回使能(1=内部环回) |
| 13 | Speed Selection (LSB) | 与位6组合选择速度 |
| 12 | Auto-Negotiation Enable | 自动协商使能(1=使能) |
| 11 | Power Down | 省电模式(1=掉电) |
| 10 | Isolate | 隔离(1=隔离MII/GMII接口) |
| 9 | Restart Auto-Negotiation | 重启自动协商(1=触发,自清零) |
| 8 | Duplex Mode | 双工模式(1=全双工,0=半双工) |
| 6 | Speed Selection (MSB) | 与位13组合:00=10M, 01=100M, 10=1000M, 11=保留 |
2.3.2 BMSR(基本模式状态寄存器,地址 0x01)
BMSR 反映 PHY 的当前状态和能力,包括链接状态、自动协商完成状态、支持的速度/双工能力等。
| 位域 | 名称 | 描述 |
|---|---|---|
| 15 | 100BASE-T4 | 支持T4模式 |
| 14 | 100BASE-TX Full Duplex | 支持100M全双工 |
| 13 | 100BASE-TX Half Duplex | 支持100M半双工 |
| 12 | 10BASE-T Full Duplex | 支持10M全双工 |
| 11 | 10BASE-T Half Duplex | 支持10M半双工 |
| 10 | 100BASE-T2 Full Duplex | 支持100M T2全双工 |
| 9 | 100BASE-T2 Half Duplex | 支持100M T2半双工 |
| 8 | Extended Status | 扩展状态寄存器存在 |
| 7 | Unidirectional Ability | 单向能力支持 |
| 6 | MF Preamble Suppression | 管理帧前导码抑制 |
| 5 | Auto-Negotiation Complete | 自动协商完成(1=完成) |
| 4 | Remote Fault | 远端故障指示 |
| 3 | Auto-Negotiation Ability | 自动协商能力支持 |
| 2 | Link Status | 链接状态(1=已链接,0=断开) |
| 1 | Jabber Detect | Jabber检测 |
| 0 | Extended Capability | 扩展寄存器能力 |
2.3.3 PHYIDR(PHY标识寄存器,地址 0x02~0x03)
PHYIDR 由两个 16 位寄存器组成,共同构成 32 位的 PHY 唯一标识符(OUI + 型号 + 版本)。
- PHY ID High (0x02): 包含 OUI(组织唯一标识符)的高 22 位和型号的 6 位。
- PHY ID Low (0x03): 包含型号的低 6 位和版本号的 4 位。
驱动通过读取 PHYIDR 来识别 PHY 型号,从而加载对应的驱动或配置参数。例如,Realtek RTL8211F 的 PHY ID 为 0x001CC916。
2.3.4 ANAR(自动协商通告寄存器,地址 0x04)
ANAR 用于通告本端 PHY 支持的能力(速度、双工、流控等),并参与自动协商过程。对端 PHY 通过接收这些信息来决定最终的链接参数。
| 位域 | 名称 | 描述 |
|---|---|---|
| 15 | Next Page | 下一页使能 |
| 14 | Ack | 确认位(协商过程中硬件维护) |
| 13 | Remote Fault | 远端故障指示 |
| 12 | Technology Ability | 技术能力(保留) |
| 11~10 | Selector Field | 选择字段(通常为 00001 表示 IEEE 802.3) |
| 9 | 100BASE-T4 | 通告 T4 能力 |
| 8 | 100BASE-TX Full Duplex | 通告 100M 全双工 |
| 7 | 100BASE-TX Half Duplex | 通告 100M 半双工 |
| 6 | 10BASE-T Full Duplex | 通告 10M 全双工 |
| 5 | 10BASE-T Half Duplex | 通告 10M 半双工 |
| 4~0 | PAUSE / ASM_DIR | 流控能力通告(对称/非对称暂停) |
2.3.5 LPAR(链路伙伴能力寄存器,地址 0x05)
LPAR 与 ANAR 结构相同,但内容由对端 PHY 通过自动协商过程写入。驱动读取 LPAR 可以获知对端 PHY 支持的能力,从而判断最终的链接模式。
2.4 Clause 22 与 Clause 45 寄存器访问流程对比
下面的 SVG 图展示了两种标准在 Linux 内核驱动中的典型访问流程差异。
2.5 Linux 内核中的 PHY 寄存器访问接口
Linux 内核的 PHY 子系统(drivers/net/phy/)对 Clause 22 和 Clause 45 进行了抽象。驱动开发者主要使用以下 API:
// Clause 22 访问(传统接口)
int phy_read(struct phy_device *phydev, u32 regnum);
int phy_write(struct phy_device *phydev, u32 regnum, u16 val);
// Clause 45 访问(扩展接口)
int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val);
// 辅助宏:读取基本寄存器
#define phy_read_bmcr(phydev) phy_read(phydev, MII_BMCR)
#define phy_read_bmsr(phydev) phy_read(phydev, MII_BMSR)
#define phy_read_anar(phydev) phy_read(phydev, MII_ADVERTISE)
#define phy_read_lpar(phydev) phy_read(phydev, MII_LPA)
phy_read_mmd() 时,如果底层总线只支持 Clause 22,内核会自动尝试使用 Clause 22 的“MMD 访问陷阱”机制(通过写入特定寄存器 0x0D 和 0x0E 来模拟 Clause 45 访问)。这种兼容模式在调试时可能引入额外的延迟,需要注意。
2.6 调试实战:通过基本寄存器诊断链接问题
当网络链接出现异常时,以下步骤可以帮助快速定位问题:
- 读取 PHYIDR (0x02~0x03): 确认 PHY 芯片是否被正确识别。如果读到 0xFFFF 或 0x0000,说明 MDIO 通信异常或 PHY 地址错误。
- 读取 BMSR (0x01): 检查 Link Status 位(位2)。如果为 0,检查线缆连接和对端设备是否上电。
- 读取 BMCR (0x00): 确认 Auto-Negotiation Enable 位(位12)是否置位。如果强制模式,检查 Speed 和 Duplex 设置是否正确。
- 读取 ANAR (0x04) 和 LPAR (0x05): 对比本端和对端的能力通告。如果 LPAR 为 0,说明自动协商未完成;如果两者无交集,说明能力不匹配。
- 读取扩展状态寄存器 (0x0F): 对于千兆 PHY,检查 Master-Slave 配置和 1000BASE-T 能力。
msleep(100) 延时。
下表总结了基本寄存器在链接调试中的关键作用:
| 寄存器 | 地址 | 调试关注点 | 异常值含义 |
|---|---|---|---|
| BMCR | 0x00 | 复位位、自动协商使能、速度/双工 | 复位位自清零失败 → PHY 硬件故障 |
| BMSR | 0x01 | 链接状态、自动协商完成 | 链接状态为 0 → 物理层断开 |
| PHYIDR | 0x02~0x03 | PHY 型号识别 | 0xFFFF → MDIO 总线故障或地址错误 |
| ANAR | 0x04 | 本端能力通告 | 全 0 → 自动协商未使能或 PHY 未初始化 |
| LPAR | 0x05 | 对端能力通告 | 全 0 → 对端未响应或协商未完成 |