了解ARM的千兆以太网——RK3588

  1. 简介

本文并不重点讲解调试内容,重点了解以太网在ARM设计中的框架以及在设备树以及驱动的一个整体框架。了解作为一个驱动开发人员当拿到一款未开发过的ARM板卡应该怎么去把网卡配置使用起来。

  1. 基础知识介绍

在嵌入式ARM中实现以太网的解决方案通常有以下两种,通常在性能较低的单片机领域其SOC内部是不具备MAC控制器,但又有需求可以使用方案1这种架构,但在高性能的ARM处理器,例如RK3588这种SOC其内部已集成MAC控制器,可以直接选用方案2。

  1. SOC 与外部 MAC+PHY 芯片


2. SOC 内部 MAC 外设与外部 PHY 芯片

本文重点解方案2,那么在开始之前,先了解PHY芯片与MAC控制器之间的的接口协议RGMII。
先了解RGMII的前身 GMII(Gigabit Media Independant Interface)千兆MII接口。GMII采用8位接口数据,工作时钟125MHz,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100Mbps工作方式。GMII接口数据结构符合IEEE以太网标准,该接口定义见IEEE 802.3-2000。信号定义如下。

RGMII(Reduced Gigabit Media Independant Interface)是精简GMII接口,相对于GMII相比,RGMII具有如下特征:

  • 发送/接收数据线由8条改为4条
  • TX_ER和TX_EN复用,通过TX_CTL传送
  • RX_ER与RX_DV复用,通过RX_CTL传送
  • 1 Gbit/s速率下,时钟频率为125MHz
  • 100 Mbit/s速率下,时钟频率为25MHz
  • 10 Mbit/s速率下,时钟频率为2.5MHz

    到了这里如果屏幕前的你产生了疑问,那证明你是真的用心了。有留意的朋友会发现,那数据线减少一半,但是时钟最高还是125MHz,为啥仍然能达到1Gbit/s的数据传输速率,这个很好解决,那就是进行时钟双边沿采样。
    这里我们还需要了解一个接口:MDIO 全称是 Management Data Input/Output ,直译过来就是管理数据输入输出接口,是一 个简单的两线串行接口,一根 MDIO 数据线,一根 MDC 时钟线。驱动程序可以通过 MDIO 和 MDC 这两根线访问 PHY 芯片的任意一个寄存器。
    MDIO 接口支持多达 32 个 PHY 。同一时刻 内只能对一个 PHY 进行操作,那么如何区分这 32 个 PHY 芯片呢?和 IIC 一样,使用器件地址即可,PHY 芯片寄存器地址空间为 5 位。同一 MDIO 接口下的所有 PHY 芯片,其器件地址不能冲突,必须保证唯一,具体器件 地址值要查阅相应的 PHY 数据手册。
    其实上述框架还并不完整,PHY芯片产生的差分信号是不能直接接入到网线的,还需要通过RJ45接口转换成标准的物理接口。RJ45 座要与 PHY 芯片连接在一起,但是中间需要一个网络变压器,网络变压器用于隔离以及滤波等,网络变压器也是一个芯片, 但是现在很多 RJ45 座子内部已经集成了网络变压器。

    完整的嵌入式网络接口硬件如下图所示:
  1. 硬件原理图

有了前面的基础知识铺垫,我们从原理图的硬件连接进一步了解其硬件框架。以RK3588的原理图为例进行讲解:

PHY: YT8521SH-CA

  1. 设备树硬件描述

前面从硬件的角度分析了其框架,那同样我们也可以在设备树硬件描述上也能体现出上述框架。

MAC控制器设备节点:rk3588.dtsi

下面部分通常需要驱动开发人员补充,原因是涉及一些自定义的PHY复位引脚,这些都是自定义的。

先看一下引脚复用:rk3588-vccio3-pinctrl.dtsi

从上述设备树节点先分析也是符和前面分析的框架的,对应以太网框架我们先分析到这里。

  1. 工作定位

到了这里肯能很多朋友会产生疑问,那实际开发过程中我们驱动开发工作人员需要做哪些工作?这里就需要我们清楚我们的定位了,一个千兆网卡在驱动上我们可以划分为两大核心部分:MAC控制器驱动+PHY驱动。

通常MAC控制器驱动由原厂BSP工程师提供,不需要我们手搓。我们需要重点关注的是PHY驱动,当然由于业内早已建立了标准,内核源码已提供了一套通用的PHY驱动,这套PHY驱动至少能让网卡工作起来,不同的PHY厂商也会兼容这套标准。通常不同的厂商还会基于这套通用的驱动自定义属于他们自己的一套驱动实现更加完善的功能。

  1. PHY驱动分析

分析PHY驱动之前先补充一个知识点就是,MDIO 接口支持多达 32 个 PHY,它们是通过地址来区分的,通过不同的 PHY 芯片地址来对不同的 PHY 操作,YT8521SH通过设置PHYAD0引脚来设置其PHY地址。

下拉则地址为0x00000:

上拉则地址为0x00001:

有了上述的PHY地址了解之后,我们再回头看看设备树节点是如何体现PHY地址的,在前面设备树MAC控制器节点里面有"phy-handle"属性指定了phy,而phy节点的定义则挂载在了MDIO总线下。rgmii_phy0: phy@0节点名称的@后面的数值就是 PHY 地址。

由于网络驱动框架比较复杂,如果这里贴代码展开讲解,估计很多朋友就绷不住了,因此我们同样是采样框架学习法,了解驱动框架,重点了解我们作为驱动开发者通常需要做哪些工作即可。

本文我们不展开讲解MAC控制器驱动,这里直接抛出答案:MAC控制器驱动无非就是解析设备树节点,初始化MAC控制器、通过"phy-handle"属性解析PHY节点相关信息,做一系列的RGMII接口初始化,最终注册MDIO总线,注册PHY设备。

讲解PHY驱动之前,先了解PHY子系统。PHY 子系统就是用于 PHY 设备相关内容的,分为 PHY 设备和 PHY 驱动,和 platform 总线一样,PHY 子系统也是一个设备、总线和驱动模型,这里的总线对应的就是MDIO总线。

PHY****设备:

Linux 内核使用 phy_device 结构体来表示 PHY 设备,结构体定义 在 include/linux/phy.h

PHY 设备的注册过程一般是先调用 get_phy_device 函数获取 PHY 设备,在通过函数phy_device_register 注册phy_device。

这里需要注意一点的是,PHY设备与PHY驱动匹配并不是通过compatible属性或name属性进行匹配的,而是通过PHY ID。

PHY****驱动:

PHY 驱动使用结构体 phy_driver 表示,结构体也定义在 include/linux/phy.h 文件中

可以看出,phy_driver 重点是大量的函数,编写 PHY 驱动的主要工作就是实现这些函数, 但是不一定全部实现。PHY 驱动的注册使用 phy_driver_register 函数。

phy_driver 里面有两个 成员变量 phy_id 和 phy_id_mask,表示此驱动所匹配的 PHY 芯片 ID 以及 ID 掩码,PHY 驱动编写人员需要给这两个成员变量赋值。phy_device 也有一个 phy_id 成员变量,表示此 PHY 芯 片的 ID,phy_device 里面的 phy_id 是在注册 PHY 设备的时候调用 get_phy_id 函数直接读取 PHY 芯片内部 ID 寄存器得到的!很明显 PHY 驱动和 PHY 设备中的 ID 要一样,这样才能匹配 起来。如果 PHY 设备和 PHY 驱动匹配,那么就使用指定的 PHY 驱动,如果不匹配的话就使用Linux 内核自带的通用 PHY 驱动。
MDIO 总线:
PHY 子系统也是遵循设备、总线、驱动模型的,设备和驱动就是 phy_device 和 phy_driver。总线就是 MDIO 总线,因为 PHY 芯片是通过 MIDO 接口来管理的, MDIO 总线最主要的工作就是匹配 PHY 设备和 PHY 驱动。MDIO 总线数据结构在文件 drivers/net/phy/mdio_bus.c 中有如下定义。


重点是总线的匹配函数为 mdio_bus_match,主要完成device和driver的匹配工作。

通用 PHY 驱动:

通用的PHY驱动 drivers/net/phy/phy_device.c

phy_init 是整个 PHY 子系统的入口函数,调用 phy_driver_register 函数向内核直接注册一个通用 PHY 驱动:genphy_driver,也就是通用 PHY 驱动,也就是说 Linux 系统启动以后默认就已经存在了通用 PHY 驱动。

PHY 厂商驱动:

YT8521SH PHY驱动: drivers/net/phy/motorcomm.c


此驱动里面的成员函数有一些是 PHY厂商自己编写的,有一些是直接用的通用 PHY 驱动的, 比如genphy_config_aneg 。
总结: 通常驱动人员需要操作的就是PHY驱动。关于MAC控制器是如何回调到PHY驱动的接口函数过程其实我们并不关心,我们更多的关注是如何在PHY驱动配置我们需要的网络功能。

说实话,网口驱动知识内容非常多,讲到这里个人都差点忘了我们写这篇文章的最终目的,两个目的:

  1. 如果要配置PHY芯片的某个功能,直接在PHY驱动操作就可以了。

2.需要学会如何在设备树里面补充完善PHY驱动相关的内容。

第一点上面基本讲解完了,下面重点讲解第二点,回到最开始设备树节点描述。先提出问题?首先我们是如何知道补充以下内容?

以RK3588为例:

参考官方手册,除此之外还可以参考官板对网卡的配置。

Rockchip_Developer_Guide_Linux_GMAC_CN.pdf

Rockchip_Developer_Guide_Linux_GMAC_Mode_Configuration_CN.pdf

相关推荐
freesky1 小时前
Ubuntu软件更新及删除
linux·运维·服务器·ubuntu
草莓奶忻4 小时前
Ubuntu批量修改文件名
linux·运维·ubuntu
xsinlink5 小时前
Windows安全中心(病毒和威胁防护)的注册
c语言·c++·windows·驱动开发·安全
Huazzi.6 小时前
Linux 文件系统目录结构及其简要介绍
linux·服务器·网络·ubuntu
星河梦瑾8 小时前
CTF知识集-SQL注入
linux·运维·python·安全·网络安全
筒栗子8 小时前
复习打卡Linux篇
linux·运维·服务器
vvw&8 小时前
如何在 Debian 12 上安装和使用 Vuls 漏洞扫描器
linux·运维·nginx·ubuntu·debian·论坛
GCTTTTTT8 小时前
linux日常常用命令(AI向)
java·linux·服务器
legend_jz9 小时前
Socket编程UDP
linux