欢迎光临散文网 会员登陆 & 注册

带你一文搞懂 Linux 网络 Phy 驱动

2023-11-06 16:35 作者:补给站Linux内核  | 我要投稿

概述

上图来自 瑞昱半导体 (RealTek) 的 RTL8201F 系列网卡 PHY 芯片手册。按OSI 7层网络模型划分,网卡PHY 芯片(图中的RTL8201F)位于物理层,对应的软件层就是本文讨论的 PHY 驱动层;而 MAC 位于 数据链路层,也是通常软件上所说的网卡驱动层,它不是本文的重点,不做展开。另外,可通过 MDIO 接口对 PHY 芯片进行配置(如PHY芯片寄存器读写),而 PHY 和 MAC 通过 MII/RMII 进行数据传输。

PHY芯片通过MII/GMII/RMII/SGMII/XGMII等多种媒体独立接口(介质无关接口)与数据链路层的MAC芯片相连,并通过MDIO接口实现对PHY 状态的监控、配置和管理。

PHY与MAC整体的连接框图:

数据结构

每个 phy 芯片会创建一个 struct phy_device 类型的设备,对应的有 struct phy_driver 类型的驱动,这两者实际上是挂载在 mdio_bus_type 总线上的,mac 会被注册成 struct net_device。

phy_device

phy_driver

mii_bus

net_device


【文章福利】小编推荐自己的Linux内核技术交流群:【749907784】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)   

零声白金VIP体验卡(含基础架构/高性能存储/golang/QT/音视频/Linux内核)课程: 



phy 设备的注册

以网卡 Fec 为例,网卡驱动在初始化 fec_probe() 时遍历 dts 的定义,创建相应 struct phy_device 类型的设备,主要步骤为:

  1. 注册网络设备 net_device

  2. 申请队列和 DMA

  3. 申请 MDIO 总线

  4. 创建并注册 Phy 设备

phy 驱动的注册

genphy_driver 通用驱动

内核中有 genphy_driver 通用驱动,以及专有驱动(这里以 NXP TJA 驱动为例),分别如下:

genphy_driver 的 struct phy_driver 的注册过程如下:

其中一个关键点是 mdio driver 的 probe 函数是一个通用函数 phy_probe:


其中通用 phy 驱动会调用函数 genphy_read_abilities 来读取状态寄存器来确定 phy 芯片的能力:


NXP TJA 专有驱动

NXP TJA 驱动的 struct phy_driver 的注册过程如下:

根据上面的分析,由于存在 phydev->drv->probe,所以会调用其注册的函数 tja11xx_probe。

网卡 fec 和 Phy 的协作

在 linux 内核中,以太网 mac 会被注册成 struct net_device,phy 芯片会被注册成 struct phy_device。 phy_device 的状态怎么传递给 net_device,让其在 link 状态变化时做出对应的配置改变,这个任务就落在上述的 struct phylink 中介身上。

下面就以 fec 网口驱动为例,展示一下网卡 fec 和 phy 的协作过程。整个 phy 驱动的主要调用流程如下图所示:

一个 phy 驱动的原理其实是非常简单的,一般流程如下:

  1. 用轮询/中断的方式通过 mdio 总线读取 phy 芯片的状态。

  2. 在 phy link 状态变化的情况下,正确配置 mac 的状态。(例如:根据 phy 自协商的速率 10/100/1000M 把 mac 配置成对应速率)

phy 芯片状态在 phy 设备注册的时候已经体现,这里详细讲下如何在 phy link 状态变化的情况下,正确配置 mac 的状态。



自协商配置

具体启动 phy 自协商的代码流程如下:

link 状态读取

phy link 状态读取的代码流程如下:


link 状态通知

phy 的 link 状态变化怎么通知给 netdev,并且让 mac 做出相应的配置改变,这个是通过一个中介 phylink 来实现的。


原文作者:人人极客社区




带你一文搞懂 Linux 网络 Phy 驱动的评论 (共 条)

分享到微博请遵守国家法律