深入分析Linux网络之PHY 驱动框架 一
在讲解之前我们首先要知道的是在 Linux 内核中,“PHY 子系统”实际上是一个统称,它主要包含两个功能不同但紧密协作的核心子系统:以太网 PHY 抽象层(PHY Abstraction Layer, PAL)和 通用 PHY 框架(Generic PHY Framework)。
1 以太网 PHY 抽象层 (PHY Abstraction Layer, PAL)
这是最常被提及的“PHY 子系统”,专门用于管理通过 MDIO 总线 连接的以太网物理层芯片(如 LAN8720, RTL8211 等)。它位于网络驱动层,负责 PHY 芯片的探测、配置、状态监控和自动协商。
核心功能:作为函数库,将网络设备的底层硬件交互与上层网络协议栈解耦。它负责自动协商(Auto-negotiation)、链路状态监控、中断处理以及配置 MAC 与 PHY 之间的通信参数(如速率、双工模式)。
硬件接口:
MDIO/MDC 接口:用于 MAC 控制器对 PHY 芯片内部寄存器进行读写、状态监控和配置管理。
MII/RMII/GMII 等接口:用于 MAC 和 PHY 之间进行实际的数据帧传输。
核心数据结构:
PHY 设备 (struct phy_device):代表一个具体的 PHY 硬件设备,记录了 PHY ID、当前链路状态、速率、双工模式等信息。
PHY 驱动 (struct phy_driver):代表 PHY 设备的驱动程序,包含针对特定 PHY 芯片的操作函数(如配置中断、读取状态等)。
MDIO 总线 (struct mii_bus):抽象了 MDIO 总线,一个总线上最多可以挂载 32 个 PHY 设备。
MAC 与 PHY 的协作流程:
在嵌入式 Linux 中,MAC 通常集成在 SoC 内部,而 PHY 是外部芯片。它们的典型协作流程如下:
探测与识别:MAC 驱动通过 MDIO 总线扫描并读取 PHY 的 ID 寄存器,确认连接的 PHY 型号。
连接与配置:MAC 驱动调用 phy_connect() 将 net_device 与 phy_device 绑定,并启动 PHY 的软件状态机。
自动协商:PHY 硬件与对端设备(如交换机)协商最佳的传输速率和双工模式。
链路状态回调:当链路状态发生变化(如网线插拔、速率改变)时,PHY 子系统会触发 MAC 驱动注册的回调函数(如 adjust_link),MAC 据此调整自身的工作模式。
数据传输:协商完成后,MAC 通过 MII/RMII/GMII 等数据接口与 PHY 进行以太网帧的收发。
2 通用 PHY 框架 (Generic PHY Framework)
这是一个更底层的、与以太网无关的通用框架,用于管理各种串行/解串器(SerDes)和物理层接口,例如 USB、SATA、PCIe、DisplayPort 等。它的目标是统一内核中分散的 PHY 驱动,提高代码复用性。
核心概念:
PHY 提供者 (Provider):实现一个或多个 PHY 实例的驱动,负责创建和管理 PHY。
PHY 消费者 (Consumer):使用 PHY 的外设控制器驱动(如 USB 控制器、SATA 控制器)。
PHY 实例 (struct phy):代表一个具体的物理层接口实例。
标准 API 调用顺序
消费者驱动使用 PHY 时,必须遵循严格的调用顺序:
获取引用:devm_phy_get() 或 phy_get()
初始化:phy_init()
上电:phy_power_on()
设置模式 (可选):phy_set_mode()
下电:phy_power_off()
退出:phy_exit()
释放引用:phy_put()
| 特性 | 以太网 PHY 框架 (PHYLIB) | 通用 PHY 框架 |
|---|---|---|
| 应用场景 | 以太网 PHY 芯片 (MDIO) | USB, SATA, PCIe, DisplayPort 等 |
| 核心结构 | struct phy_device,struct phy_driver | struct phy,struct phy_provider |
| 通信总线 | MDIO / MII | 无特定总线,由 Provider 定义 |
| 状态管理 | 内置状态机,自动协商 | 由 Consumer 驱动手动控制 |
| 主要 API | phy_connect(),phy_start() | phy_get(),phy_power_on() |
通用 PHY 框架侧重于硬件设备的电源与初始化生命周期管理,而以太网 PHY 抽象层则侧重于网络链路状态的维护与数据通信协议的适配。两者共同构成了 Linux 下完整的网络物理层支持。