[Linux] 从YT8531SH出发看Linux网络PHY驱动
从YT8531SH出发看Linux网络PHY驱动
博客关联代码下载链接:https://download.csdn.net/download/jz_ddk/91940396
文章目录
- 从YT8531SH出发看Linux网络PHY驱动
- 引言
- 一、Linux网络驱动架构概述
- 二、PHY驱动核心结构:phy_driver
- 关键回调函数解析:
- 三、PHY驱动加载全流程
- 阶段一:基础设施初始化
- 阶段二:设备探测与匹配
- 阶段三:驱动绑定与初始化
- 阶段四:网络子系统集成
- 四、YT8531SH设备树配置详解
- 配置选项详解:
- 五、调试与问题排查
- 常见问题及解决方法:
- 调试工具:
- 六、总结
引言
在嵌入式Linux系统中,网络功能是不可或缺的核心能力。一个完整的网络子系统由MAC控制器和PHY芯片组成,其中PHY(物理层接口)负责数模转换、链路协商等底层物理信号处理。本文将以Motorcomm YT8531SH PHY芯片的驱动为例,深入剖析Linux网络PHY驱动的框架结构、加载机制及设备树配置。
一、Linux网络驱动架构概述
Linux网络子系统采用分层设计架构:
- MAC驱动:控制网络核心控制器,通常集成在SoC中,负责DMA、数据帧处理
- PHY驱动:控制物理层收发器芯片,通过MDIO总线与MAC通信
- MDIO总线:简单的两线串行接口(MDC和MDIO),用于MAC访问PHY寄存器
二、PHY驱动核心结构:phy_driver
Linux内核通过struct phy_driver
抽象PHY驱动,YT8531SH驱动定义如下:
static struct phy_driver motorcomm_phy_drvs[] = {{.phy_id = PHY_ID_YT8531, // 芯片标识符.phy_id_mask = PHY_ID_YT_MASK, // 标识符掩码.name = "YT8531 Gigabit Ethernet", // 驱动名称.features = PHY_GBIT_FEATURES, // 支持的功能特性.probe = &yt8531_probe, // 设备探测函数.config_init = &yt8531_config_init, // 初始化配置.suspend = &genphy_suspend, // 电源管理-挂起.resume = &genphy_resume, // 电源管理-恢复.get_wol = &ytphy_get_wol, // 获取WoL设置.set_wol = &yt8531_set_wol, // 设置WoL设置.link_change_notify = &yt8531_link_change_notify, // 链路变化通知},// ... 其他型号支持
};
关键回调函数解析:
- probe函数:设备初始化时调用,进行硬件检测和私有数据结构设置
- config_init函数:PHY初始化配置,包括:
- RGMII时序调整(解决PCB布线时序问题)
- 驱动强度配置(优化信号完整性)
- 时钟输出配置
- 电源管理函数:处理系统休眠/唤醒时的电源状态管理
- WoL函数:实现网络唤醒功能配置
- link_change_notify:链路状态变化回调,用于动态调整配置
三、PHY驱动加载全流程
PHY驱动的加载是一个从内核到硬件逐层初始化的过程,其完整流程如下:
阶段一:基础设施初始化
-
MDIO总线注册:内核启动时,MDIO总线控制器驱动首先初始化,注册
mdio_bus_type
总线结构。 -
驱动注册:PHY驱动模块通过
module_phy_driver(motorcomm_phy_drvs)
宏注册到内核,实质是调用phy_driver_register
函数。 -
导出设备表:
MODULE_DEVICE_TABLE(mdio, motorcomm_tbl)
创建模块别名信息,供depmod
工具生成modules.alias文件,实现模块自动加载。
阶段二:设备探测与匹配
-
硬件探测:MDIO总线控制器驱动扫描总线上所有可能地址(0-31)。
-
读取PHY ID:读取每个地址的
MII_PHYSID1
和MII_PHYSID2
寄存器,识别有效PHY设备。 -
总线匹配:
mdio_bus_match
函数遍历已注册的phy_driver
,计算phy_id = (PHYID1 << 16 | PHYID2)
并与驱动标识符比较。 -
匹配算法:
(phy_id & phy_driver->phy_id_mask) == (phy_driver->phy_id & phy_driver->phy_id_mask)
阶段三:驱动绑定与初始化
-
创建设备并绑定驱动:匹配成功后创建
phy_device
结构体,与驱动绑定。 -
执行probe函数:调用驱动特定的probe函数(如
yt8531_probe
),完成硬件初始化。
阶段四:网络子系统集成
-
MAC驱动连接PHY:MAC驱动从设备树解析
phy-handle
属性,通过of_phy_connect
函数查找并连接PHY设备。 -
PHY初始化和启动:调用
.config_init
和.config_aneg
函数,启动自动协商。 -
链路就绪:自动协商完成后,链路状态变为UP,网络子系统准备就绪。
四、YT8531SH设备树配置详解
基于驱动代码分析,YT8531SH的完整设备树配置如下:
&mdio0 {status = "okay";yt8531_phy: ethernet-phy@0 {compatible = "motorcomm,yt8531", "ethernet-phy-ieee802.3-c22";reg = <0>; /* PHY地址,根据硬件连接确定 *//* 时钟输出配置 */motorcomm,clk-out-frequency-hz = <125000000>; /* 125MHz输出 *//* RGMII时序调整 - 接收延迟 */rx-internal-delay-ps = <1950>; /* 默认值1.95ns *//* RGMII时序调整 - 发送延迟 */tx-internal-delay-ps = <1950>; /* 默认值1.95ns *//* 驱动强度配置 */motorcomm,rx-clk-drv-microamp = <3970>; /* RX时钟驱动电流 */motorcomm,rx-data-drv-microamp = <3970>; /* RX数据驱动电流 *//* 电源管理配置 */motorcomm,auto-sleep-disabled; /* 禁用自动睡眠 */motorcomm,keep-pll-enabled; /* 保持PLL始终启用 *//* TX时钟调整配置(特定于JH7110 SoC) */motorcomm,tx-clk-adj-enabled; /* 启用TX时钟调整 */motorcomm,tx-clk-10-inverted; /* 10M速度下反转TX时钟 */motorcomm,tx-clk-100-inverted; /* 100M速度下反转TX时钟 */motorcomm,tx-clk-1000-inverted; /* 1000M速度下反转TX时钟 *//* 中断支持(如果连接了中断线) */interrupt-parent = <&gpio0>;interrupts = <12 IRQ_TYPE_EDGE_FALLING>;/* 复位配置(可选) */reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;reset-assert-us = <1000>; /* 复位断言时间1ms */reset-deassert-us = <2000>; /* 复位解除时间2ms */};
};ð0 {status = "okay";phy-handle = <&yt8531_phy>;phy-mode = "rgmii-id"; /* 接口模式,根据硬件连接确定 */
};
配置选项详解:
-
时钟输出配置:驱动通过
motorcomm,clk-out-frequency-hz
属性配置PHY的时钟输出功能,在yt8531_probe
函数中读取并配置YTPHY_SYNCE_CFG_REG
寄存器。 -
RGMII时序调整:
rx-internal-delay-ps
和tx-internal-delay-ps
属性解决PCB布线时序问题,由ytphy_rgmii_clk_delay_config
函数处理。 -
驱动强度配置:
motorcomm,rx-clk-drv-microamp
和motorcomm,rx-data-drv-microamp
属性优化信号完整性,通过yt8531_set_ds
函数配置。 -
电源管理配置:
motorcomm,auto-sleep-disabled
和motorcomm,keep-pll-enabled
属性控制节能特性。 -
TX时钟调整:特定于JH7110 SoC的时序适配功能,由
yt8531_link_change_notify
函数动态调整。
五、调试与问题排查
常见问题及解决方法:
-
PHY无法识别:检查MDIO总线通信、PHY地址配置和电源状态
-
链路不稳定:调整RGMII时序延迟参数,优化驱动强度设置
-
性能下降:检查自动协商结果,确认双工模式和速度设置
-
WoL功能失效:验证中断配置和魔术包设置
调试工具:
ethool -i eth0
:查看PHY信息和驱动状态mdio-tool
:直接读写MDIO寄存器- 示波器:测量MDC/MDIO信号质量,验证时序参数
六、总结
通过分析YT8531SH PHY驱动,我们可以深入理解Linux网络PHY驱动的完整框架和加载机制。PHY驱动遵循标准的driver-bus-device模型,通过MDIO总线与MAC通信,依靠设备树提供硬件配置信息。
现代PHY驱动开发需要注意:
- 正确实现phy_driver结构体中的回调函数
- 充分利用设备树进行硬件配置,提高代码可移植性
- 妥善处理时序敏感操作(如RGMII延迟调整)
- 支持电源管理和网络唤醒等高级功能
YT8531SH驱动代码是一个优秀的范例,涵盖了PHY驱动开发的各个方面,为理解和开发Linux网络驱动提供了宝贵的参考。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)