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)。

关键特征: 地址空间小(32个寄存器)、访问速度快、兼容性最广。几乎所有10/100Mbps PHY和部分千兆PHY都支持 Clause 22。

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+
访问帧格式 简单两阶段(地址+数据) 四阶段(地址+设备类型+数据)
工程提示: 许多现代千兆PHY(如 Marvell 88E1512、Broadcom BCM54616)同时支持 Clause 22 和 Clause 45 两种访问模式。驱动初始化时通常先尝试 Clause 22,如果读取 PHY ID 失败,再切换到 Clause 45 模式。

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 扩展寄存器能力
调试陷阱: BMSR 的位 2(Link Status)是 锁存位。当链接断开时,该位清零;但链接恢复后,该位不会自动置位,必须通过读取 BMSR 两次才能获取真实状态。驱动中通常采用“读两次”或“读后写1清零”的方式处理。

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 支持的能力,从而判断最终的链接模式。

调试技巧: 当链接异常时,同时读取 ANAR 和 LPAR 进行对比。如果 LPAR 全为 0,说明自动协商未完成或对端未响应;如果 LPAR 与 ANAR 没有交集,说明两端能力不匹配,需要检查线缆或强制设置速度/双工。

2.4 Clause 22 与 Clause 45 寄存器访问流程对比

下面的 SVG 图展示了两种标准在 Linux 内核驱动中的典型访问流程差异。

Clause 22 vs Clause 45 寄存器访问流程对比 Clause 22 访问流程 步骤1: 写入 PHY 地址 + 寄存器地址 步骤2: 写入/读取 16 位数据 步骤3: 完成单次寄存器操作 Clause 45 访问流程 步骤1: 写入 PHY 地址 + 设备类型 步骤2: 写入 16 位寄存器地址 步骤3: 写入/读取 16 位数据 步骤4: 完成单次寄存器操作 关键差异说明 • Clause 22: 一次 MDIO 帧完成地址+数据操作,效率高,但寄存器空间仅 32 个。 • Clause 45: 需要两次 MDIO 帧(地址帧+数据帧),但支持 32 个设备类型 × 65536 个寄存器。 • Linux 内核通过 phy_read()/phy_write() 封装差异,驱动开发者通常无需直接处理帧细节。 • 调试时可通过 mdio-tool 或 ethtool -d 直接访问 Clause 45 的扩展寄存器。

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 驱动调用 phy_read_mmd() 时,如果底层总线只支持 Clause 22,内核会自动尝试使用 Clause 22 的“MMD 访问陷阱”机制(通过写入特定寄存器 0x0D 和 0x0E 来模拟 Clause 45 访问)。这种兼容模式在调试时可能引入额外的延迟,需要注意。

2.6 调试实战:通过基本寄存器诊断链接问题

当网络链接出现异常时,以下步骤可以帮助快速定位问题:

  1. 读取 PHYIDR (0x02~0x03): 确认 PHY 芯片是否被正确识别。如果读到 0xFFFF 或 0x0000,说明 MDIO 通信异常或 PHY 地址错误。
  2. 读取 BMSR (0x01): 检查 Link Status 位(位2)。如果为 0,检查线缆连接和对端设备是否上电。
  3. 读取 BMCR (0x00): 确认 Auto-Negotiation Enable 位(位12)是否置位。如果强制模式,检查 Speed 和 Duplex 设置是否正确。
  4. 读取 ANAR (0x04) 和 LPAR (0x05): 对比本端和对端的能力通告。如果 LPAR 为 0,说明自动协商未完成;如果两者无交集,说明能力不匹配。
  5. 读取扩展状态寄存器 (0x0F): 对于千兆 PHY,检查 Master-Slave 配置和 1000BASE-T 能力。
常见陷阱: 某些 PHY 在复位后需要等待一段时间(通常 50~100ms)才能稳定访问寄存器。在驱动初始化时,如果立即读取 PHYIDR 可能得到错误值。建议在复位后加入 msleep(100) 延时。

下表总结了基本寄存器在链接调试中的关键作用:

寄存器 地址 调试关注点 异常值含义
BMCR 0x00 复位位、自动协商使能、速度/双工 复位位自清零失败 → PHY 硬件故障
BMSR 0x01 链接状态、自动协商完成 链接状态为 0 → 物理层断开
PHYIDR 0x02~0x03 PHY 型号识别 0xFFFF → MDIO 总线故障或地址错误
ANAR 0x04 本端能力通告 全 0 → 自动协商未使能或 PHY 未初始化
LPAR 0x05 对端能力通告 全 0 → 对端未响应或协商未完成