Linux 内核中PHY子系统(网络):PHY设备

一.  简介

前面一篇文章说明了有线网络的网络硬件方案。常用到的一种方案是:内部集成了MAC网络外设的SOC芯片(处理器),外接一个 PHY网络芯片。

注意:Linux内核中的 PHY子系统,就是针对 PHY网络芯片的驱动实现而提供的。

本文开始就来简单了解一下 PHY 子系统。PHY 子系统就是用于 PHY 设备相关内容的,分PHY 设备和 PHY 驱动,和 platform 总线一样,PHY 子系统也是一个设备、总线和驱动模型。

本文具体来学习一下PHY子系统中的 PHY设备相关的驱动代码。

二.  Linux 内核中PHY子系统(网络):PHY设备

1.  phy_device 结构体

首先看一下 PHY
<think>我们正在讨论Linux内核PHY设备的匹配机制,特别是如何通过phy_id来匹配。在Linux内核中,PHY设备网络子系统的一部分,用于管理物理层接口(如以太网PHY)。匹配过程涉及设备树(Device Tree)、总线(如MDIO总线)以及驱动模型。 根据引用[1]和引用[2],我们可以了解到PHY驱动涉及几个关键部分:MDIO总线(mii_bus)、PHY设备phy_device)和PHY驱动(phy_driver)。在初始化过程中,MDIO总线会扫描其上的设备,并为每个地址创建phy_device。然后,内核会尝试为每个phy_device匹配相应的phy_driver。 匹配的核心在于phy_id。每个PHY设备都有一个唯一的标识符(phy_id),通常由制造商ID和设备ID组成。同样,每个PHY驱动都会声明它支持的phy_id(或一个范围)。当内核检测到一个PHY设备时,它会读取设备phy_id,然后与已注册的PHY驱动进行匹配。 具体过程如下: 1. 在MDIO总线初始化时(mdio_bus_init),会注册MDIO总线(类型为mii_bus)和PHY设备类(phy_class)。 2. 当MDIO总线被注册(mdiobus_register)时,总线会扫描其上的每个地址(0到31)。对于每个地址,总线会尝试读取设备PHY标识符(通过mdiobus_read函数读取MII_PHYSID1和MII_PHYSID2寄存器)。 3. 如果读取成功,则会创建一个phy_device(通过get_phy_device函数),并将读取到的phy_id存储在phy_device中。 4. 然后,内核会将该phy_device注册到设备模型中(phy_device_register)。 5. 当PHY驱动被注册(phy_driver_register)时,它会将自己添加到全局的PHY驱动列表中。每个phy_driver结构体包含一个phy_id和一个掩码(phy_id_mask),用于标识该驱动支持的PHY设备。 6. 当phy_device被注册时,设备模型会尝试为其匹配驱动。匹配函数(phy_bus_match)会比较phy_device的phy_id与每个phy_driver的phy_id和掩码。如果满足以下条件,则匹配成功: (phy_device->phy_id & phy_driver->phy_id_mask) == phy_driver->phy_id 7. 匹配成功后,会调用phy_driver的probe函数进行初始化。 引用[2]中提到,如果PHY设备没有被正确识别(例如,由于复位时序问题导致无法读取phy_id),则会导致匹配失败,从而在后续的网络接口打开操作(如fec_enet_open)中无法连接到PHY设备(出现-19错误)。 因此,确保PHY设备能够正确响应MDIO总线的读取操作(即在复位后能够正确读取PHYID寄存器)是匹配成功的关键。 下面是一个简化的代码示例,展示PHY驱动如何定义其支持的phy_id: ```c static struct phy_driver my_phy_driver = { .phy_id = 0x01410de0, // 制造商ID和设备ID的组合 .phy_id_mask = 0xfffffff0, // 掩码,表示只匹配高28位 .name = "My PHY", .probe = my_phy_probe, .config_init = my_phy_config_init, .suspend = my_phy_suspend, .resume = my_phy_resume, .driver = { .owner = THIS_MODULE, }, }; ``` 在这个例子中,该驱动将匹配任何phy_id的高28位等于0x01410de0的PHY设备。 总结:Linux内核通过读取PHY设备phy_id,并与注册的PHY驱动中的phy_id和掩码进行比较,从而完成匹配。这一过程依赖于MDIO总线的设备扫描和内核设备驱动模型。 相关问题: 1. 如何调试Linux内核PHY设备未被识别的问题? 2. 在设备树中如何配置PHY设备? 3. PHY驱动中除了phy_id,还有哪些重要的字段? 4. 当有多个PHY驱动匹配同一个PHY设备时,内核如何处理?</think>### Linux内核PHY设备phy_id的匹配机制 在Linux内核中,PHY设备(物理层网络设备)通过`phy_id`匹配驱动,主要涉及以下核心机制: #### 1. **MDIO总线扫描与设备创建** - MDIO总线初始化时调用`mdiobus_register()`注册总线 - 总线扫描每个地址(0-31),调用`mdiobus_scan()`检测设备 - 通过`get_phy_device()`读取PHY的`phy_id`(组合寄存器MII_PHYSID1和MII_PHYSID2的值) - 创建`phy_device`结构体并存储`phy_id`: ```c struct phy_device { u32 phy_id; // 设备唯一标识符 struct mii_bus *bus; // 所属MDIO总线 ... }; ``` #### 2. **驱动注册与匹配表** - PHY驱动通过`phy_driver_register()`注册 - 驱动定义匹配表声明支持的`phy_id`: ```c static struct phy_driver genphy_driver = { .phy_id = 0xffffffff, // 通配符ID .phy_id_mask = 0xffffffff, // 掩码 .name = "Generic PHY", .match_phy_device = genphy_match_phy_device, // 匹配函数 ... }; ``` - 匹配逻辑:`(phy_device->phy_id & driver->phy_id_mask) == driver->phy_id` #### 3. **设备-驱动绑定流程** 1. 总线扫描时创建`phy_device`对象 2. 驱动注册时添加到全局驱动列表 3. 内核调用`driver->match_phy_device()`进行匹配 4. 匹配成功后绑定驱动,调用`driver->probe()` 5. 创建`/sys/class/net/ethX/phy`设备节点 #### 4. **关键函数调用链** ``` mdiobus_register() └─ mdiobus_scan() └─ get_phy_device() // 读取phy_id └─ phy_device_create() // 创建设备对象 └─ device_register() // 注册到设备模型 └─ driver_probe_device() // 触发驱动匹配 └─ driver->match_phy_device() // 执行匹配 ``` #### 5. **常见匹配失败原因 - PHY复位时序问题(如引用[2]所述) - MDIO总线通信异常(时钟/数据线故障) - `phy_id_mask`配置错误 - 设备树(Device Tree)PHY节点缺失 > 示例:Realtek PHY驱动匹配定义 > ```c > static struct phy_driver rtl8211e_driver = { > .phy_id = 0x001cc915, // Realtek OUI + 设备ID > .phy_id_mask = 0x001fffff, > .name = "RTL8211E Gigabit Ethernet", > ... > }; > ``` ### 相关问题 1. **如何调试PHY设备识别失败的问题?** 2. **设备树中PHY节点如何配置才能正确匹配驱动?** 3. **当多个驱动匹配同一个phy_id时,内核如何处理冲突?** 4. **PHY驱动中的软复位(soft reset)流程如何实现?** 5. **如何通过sysfs查看已注册PHY设备phy_id信息?** [^1]: MDIO总线初始化与PHY设备创建流程 [^2]: PHY复位时序问题导致的识别失败分析 [^3]: 设备资源管理机制在驱动中的应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值