Linux内核下网卡硬件 MAC 和PHY分析笔记

news2024/12/27 2:31:17

1 简介

通常CPU自带的以太网接口是MAC控制器,为了实现完整的功能,外围硬件还需要增加一个PHY芯片。

PHY芯片在建立网络连接时负责协商确定网速、全双工 或者 半双工等。在正常通讯时负责在MAC控制器的MII信号 与 网线中的信号之间做转换。

本文的内核代码主要来自kernel-5.4.18

2 PHY芯片 和 MDIO bus

2.1 简介

Most network devices consist of set of registers which provide an interface to a MAC layer, which communicates with the physical connection through a PHY.

The PHY concerns itself with negotiating link parameters with the link partner on the other side of the network connection (typically, an ethernet cable), and provides a register interface to allow drivers to determine what settings were chosen, and to configure what settings are allowed.

                                《Documentation/networking/phy.rst》

2.2 驱动分析

2.2.1 数据结构

struct phy_device;
struct phy_driver;

struct class mdio_bus_class;
struct bus_type mdio_bus_type;
struct mii_bus;
struct mdio_device;
struct mdio_driver;

 

2.2.2 mii_bus、phy_device 和 mdio_device 的初始化

mdiobus_register();
    -> __mdiobus_register();     
        -> mdiobus_scan();       
            -> get_phy_device();
                -> get_phy_id();
                    -> mdiobus_read();
                -> phy_device_create();
            -> phy_device_register();
                -> mdiobus_register_device();

struct mii_bus表示一个mdio bus,mdiobus_register()函数用来向内核注册一个mdio bus。在注册mdio bus时会扫描这个mdio bus上连接的所有phy芯片。

一个mdio bus上最多可以连接32个phy芯片,每个phy芯片都有一个唯一的总线地址。驱动代码会通过唯一的总线地址去读取phy芯片的ID,如果在某个总线地址上读到了ID,就意味着发现了一个phy芯片。

发现phy芯片后,会调用phy_device_create()函数创建struct phy_device和struct mdio_device对象,然后调用phy_device_register() 和 mdiobus_register_device()函数向内核注册device。

在注册phy_device后,会遍历内核中的phy_driver,通过结构体中成员变量phy_id来配对。

2.2.3 通⽤phy驱动

//drivers/net/phy/phy_device.c
static struct phy_driver genphy_driver = {
    .phy_id     = 0xffffffff,
    .phy_id_mask    = 0xffffffff,
    .name       = "Generic PHY",
    .soft_reset = genphy_no_soft_reset,
    .get_features   = genphy_read_abilities,
    .aneg_done  = genphy_aneg_done,
    .suspend    = genphy_suspend,
    .resume     = genphy_resume,
    .set_loopback   = genphy_loopback,
};


2.3 查看系统下的相关信息

2.3.1 查看设备和驱动的信息:/sys/bus/mdio_bus/

# ls /sys/bus/mdio_bus/drivers
'Broadcom BCM84881'  'Generic Clause 45 PHY'  'Generic PHY'

2.3.2 设备类信息:/sys/class/phy/

2.3.3 mdio bus的统计信息:/sys/class/mdio_bus/<bus>/statistics/  (kernel-5.6以后的内核才有)

# ls /sys/class/mdio_bus/fixed-0/statistics/
errors     errors_18  errors_28  reads     reads_18  reads_28  transfers     transfers_18  transfers_28  writes     writes_18  writes_28
errors_0   errors_19  errors_29  reads_0   reads_19  reads_29  transfers_0   transfers_19  transfers_29  writes_0   writes_19  writes_29
errors_1   errors_2   errors_3   reads_1   reads_2   reads_3   transfers_1   transfers_2   transfers_3   writes_1   writes_2   writes_3
errors_10  errors_20  errors_30  reads_10  reads_20  reads_30  transfers_10  transfers_20  transfers_30  writes_10  writes_20  writes_30
errors_11  errors_21  errors_31  reads_11  reads_21  reads_31  transfers_11  transfers_21  transfers_31  writes_11  writes_21  writes_31
errors_12  errors_22  errors_4   reads_12  reads_22  reads_4   transfers_12  transfers_22  transfers_4   writes_12  writes_22  writes_4
errors_13  errors_23  errors_5   reads_13  reads_23  reads_5   transfers_13  transfers_23  transfers_5   writes_13  writes_23  writes_5
errors_14  errors_24  errors_6   reads_14  reads_24  reads_6   transfers_14  transfers_24  transfers_6   writes_14  writes_24  writes_6
errors_15  errors_25  errors_7   reads_15  reads_25  reads_7   transfers_15  transfers_25  transfers_7   writes_15  writes_25  writes_7
errors_16  errors_26  errors_8   reads_16  reads_26  reads_8   transfers_16  transfers_26  transfers_8   writes_16  writes_26  writes_8
errors_17  errors_27  errors_9   reads_17  reads_27  reads_9   transfers_17  transfers_27  transfers_9   writes_17  writes_27  writes_9

文件内容说明:

                                《Documentation/ABI/testing/sysfs-bus-mdio(kernel-5.6)》

2.4 mdio bus调试:/sys/kernel/debug/tracing/events/mdio/mdio_access

__mdiobus_read();
    -> trace_mdio_access();

__mdiobus_write();
    -> trace_mdio_access();

3 MAC 与 PHY之间的网络数据接口(各种MII)

3.1 数据结构

//include/linux/phy.h
struct phy_device {
    ......
    phy_interface_t interface;
    ......
};
//include/linux/phy.h
/* Interface Mode definitions */
typedef enum {
    PHY_INTERFACE_MODE_NA,
    PHY_INTERFACE_MODE_INTERNAL,
    PHY_INTERFACE_MODE_MII,
    PHY_INTERFACE_MODE_GMII,
    PHY_INTERFACE_MODE_SGMII,
    PHY_INTERFACE_MODE_TBI,
    PHY_INTERFACE_MODE_REVMII,
    PHY_INTERFACE_MODE_RMII,
    PHY_INTERFACE_MODE_RGMII,
    PHY_INTERFACE_MODE_RGMII_ID,
    PHY_INTERFACE_MODE_RGMII_RXID,
    PHY_INTERFACE_MODE_RGMII_TXID,
    PHY_INTERFACE_MODE_RTBI,
    PHY_INTERFACE_MODE_SMII,
    PHY_INTERFACE_MODE_XGMII,
    PHY_INTERFACE_MODE_MOCA,
    PHY_INTERFACE_MODE_QSGMII,
    PHY_INTERFACE_MODE_TRGMII,
    PHY_INTERFACE_MODE_1000BASEX,
    PHY_INTERFACE_MODE_2500BASEX,
    PHY_INTERFACE_MODE_RXAUI,
    PHY_INTERFACE_MODE_XAUI,
    /* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */
    PHY_INTERFACE_MODE_10GKR,
    PHY_INTERFACE_MODE_USXGMII,
    PHY_INTERFACE_MODE_MAX,
} phy_interface_t;

3.2 在设备树中指定使用哪种MII

3.2.1 设备树属性“phy-mode” 和 “phy-connection-type”

可选的属性值

//Documentation/devicetree/bindings/net/ethernet-controller.yaml

      - internal
      - mii
      - gmii
      - sgmii
      - qsgmii
      - tbi
      - rev-mii
      - rmii

      # RX and TX delays are added by the MAC when required
      - rgmii

      # RGMII with internal RX and TX delays provided by the PHY,
      # the MAC should not add the RX or TX delays in this case
      - rgmii-id

      # RGMII with internal RX delay provided by the PHY, the MAC
      # should not add an RX delay in this case
      - rgmii-rxid

      # RGMII with internal TX delay provided by the PHY, the MAC
      # should not add an TX delay in this case
      - rgmii-txid
      - rtbi
      - smii
      - xgmii
      - trgmii
      - 1000base-x
      - 2500base-x
      - rxaui
      - xaui

      # 10GBASE-KR, XFI, SFI
      - 10gbase-kr
      - usxgmii

3.2.2 获取“phy-mode” 和 “phy-connection-type”属性的函数

of_get_phy_mode();
    -> of_property_read_string(np, "phy-mode", &pm);
    -> of_property_read_string(np, "phy-connection-type", &pm);

 3.3 RGMII信号中的 delay

The Reduced Gigabit Medium Independent Interface (RGMII) is a 12-pin
electrical signal interface using a synchronous 125Mhz clock signal and several
data lines. Due to this design decision, a 1.5ns to 2ns delay must be added
between the clock line (RXC or TXC) and the data lines to let the PHY (clock
sink) have enough setup and hold times to sample the data lines correctly. The 
PHY library offers different types of PHY_INTERFACE_MODE_RGMII* values to let 
the PHY driver and optionally the MAC driver, implement the required delay. The 
values of phy_interface_t must be understood from the perspective of the PHY 
device itself, leading to the following:

* PHY_INTERFACE_MODE_RGMII: the PHY is not responsible for inserting any 
  internal delay by itself, it assumes that either the Ethernet MAC (if capable
  or the PCB traces) insert the correct 1.5-2ns delay

* PHY_INTERFACE_MODE_RGMII_TXID: the PHY should insert an internal delay
  for the transmit data lines (TXD[3:0]) processed by the PHY device

* PHY_INTERFACE_MODE_RGMII_RXID: the PHY should insert an internal delay
  for the receive data lines (RXD[3:0]) processed by the PHY device

* PHY_INTERFACE_MODE_RGMII_ID: the PHY should insert internal delays for 
  both transmit AND receive data lines from/to the PHY device

Whenever possible, use the PHY side RGMII delay for these reasons:

* PHY devices may offer sub-nanosecond granularity in how they allow a
  receiver/transmitter side delay (e.g: 0.5, 1.0, 1.5ns) to be specified. Such
  precision may be required to account for differences in PCB trace lengths

* PHY devices are typically qualified for a large range of applications
  (industrial, medical, automotive...), and they provide a constant and 
  reliable delay across temperature/pressure/voltage ranges

* PHY device drivers in PHYLIB being reusable by nature, being able to
  configure correctly a specified delay enables more designs with similar delay
  requirements to be operate correctly

For cases where the PHY is not capable of providing this delay, but the
Ethernet MAC driver is capable of doing so, the correct phy_interface_t value
should be PHY_INTERFACE_MODE_RGMII, and the Ethernet MAC driver should be
configured correctly in order to provide the required transmit and/or receive
side delay from the perspective of the PHY device. Conversely, if the Ethernet
MAC driver looks at the phy_interface_t value, for any other mode but
PHY_INTERFACE_MODE_RGMII, it should make sure that the MAC-level delays are
disabled.

In case neither the Ethernet MAC, nor the PHY are capable of providing the
required delays, as defined per the RGMII standard, several options may be
available:

* Some SoCs may offer a pin pad/mux/controller capable of configuring a given
  set of pins'strength, delays, and voltage; and it may be a suitable
  option to insert the expected 2ns RGMII delay.

* Modifying the PCB design to include a fixed delay (e.g: using a specifically
  designed serpentine), which may not require software configuration at all.

                                《Documentation/networking/phy.rst》

3.4 查看当前系统下MAC和PHY之间正在使用的是哪种MII

/sys/class/mdio_bus/<bus>/<device>/phy_interface

                                《Documentation/ABI/testing/sysfs-class-net-phydev》

3.5 特殊用法:两个MAC控制器通过MII直连,不经过PHY芯片

在这种情况下因为没有PHY芯片,硬件上无法通过协商确定网速、全/半双工等状态信息,需要通过其他方式来获取这些信息,请看下面的“fixed-link”相关的章节。

4 物理链路的状态

4.1 简介

网络物理链路状态在发生改变时,需要确定 UP/DOWN、网速、全双工还是半双工等关键状态信息。

多数时候网络物理链路的状态是通过phy硬件协商确定的,还有另一种方法就是直接指定物理链路的状态。

在某些特殊的硬件设计中,直接将两个MAC控制器的MII信号直连,不使用PHY芯片,这导致硬件无法协商确定物理链路状态,这种情况下也需要直接指定物理链路状态。

4.2 通过phy芯片获取物理链路状态

4.2.1 状态处理工作项

在创建phy_device时会创建工作项,处理函数是phy_state_machine();

phy_device_create();
    -> INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);

 

4.2.2 向内核添加工作项

轮训模式:
        当phydev->irq == PHY_POLL时,采用轮训模式,轮训间隔是1秒,轮训间隔由宏 PHY_STATE_TIME 控制。


中断模式:

phy_request_interrupt();
    -> request_threaded_irq(phydev->irq, NULL, phy_interrupt, ...);

phy_interrupt();
​​​​​​​    -> phy_trigger_machine();

4.3 Fixed MDIO bus

4.3.1 简介

内核配置:CONFIG_FIXED_PHY

MDIO Bus/PHY emulation with fixed speed/link PHYs
Adds the platform "fixed" MDIO Bus to cover the boards that use PHYs that are not connected to the real MDIO bus.

                                drivers/net/phy/Kconfig

4.3.2 初始化

static int __init fixed_mdio_bus_init(void)
{
    struct fixed_mdio_bus *fmb = &platform_fmb;
    int ret;

    pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
    ......
    snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
    fmb->mii_bus->name = "Fixed MDIO Bus";
    fmb->mii_bus->priv = fmb;
    fmb->mii_bus->parent = &pdev->dev;
    fmb->mii_bus->read = &fixed_mdio_read;
    fmb->mii_bus->write = &fixed_mdio_write;

    ret = mdiobus_register(fmb->mii_bus);
    ......
}
module_init(fixed_mdio_bus_init);

4.3.3 查看系统下的Fixed MDIO bus信息

/sys/class/mdio_bus/fixed-0/
/sys/bus/platform/devices/Fixed\ MDIO\ bus.0/

 

4.4 通过设备树节点“fixed-link”指定物理链路的状态

4.4.1 设备树“fixed-link”节点的属性

"full-duplex"
"speed"
"pause"
"asym-pause"
“link-gpios”

含义如下(Documentation/devicetree/bindings/net/ethernet-controller.yaml)

          properties:
            speed:
              allOf:
                - $ref: /schemas/types.yaml#definitions/uint32
                - enum: [10, 100, 1000]
              description:
                Link speed.

            full-duplex:
              $ref: /schemas/types.yaml#definitions/flag
              description:
                Indicates that full-duplex is used. When absent, half
                duplex is assumed.

            asym-pause:
              $ref: /schemas/types.yaml#definitions/flag
              description:
                Indicates that asym_pause should be enabled.

            link-gpios:
              maxItems: 1
              description:
                GPIO to determine if the link is up

4.4.2 对应的数据结构

struct fixed_phy_status {
    int link;
    int speed;
    int duplex;
    int pause;
    int asym_pause;
};

4.4.3 获取设备树中“fixed-link”内容的代码

of_phy_register_fixed_link();
    -> fixed_phy_register();
        -> __fixed_phy_register();

4.5 通过ethtool命令设置物理链路状态

例如:ethtool -s enp0s31f6 speed 100 duplex full autoneg off

内核中对应的代码:struct ethtool_ops->set_link_ksettings();

4.6 查看网络物理链路的状态信息

方法一、ethtool enp0s31f6

方法二、
                /sys/class/net/<net_dev>/duplex
                /sys/class/net/<net_dev>/speed

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1804147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyinstall 打包 paddleocr 成为.exe文件步骤

一、首先进入虚拟环境 使用pip安装pyinstaller pip install pyinstaller我的已经安装完成 二、用cmd进入当前打包文件夹下&#xff0c;新建使spec文件内容如下 注意&#xff1a;其中需要修改的部分是pathex中文件所在路径文件内容摘抄自另一篇博文(❄点击可查看❄) # -*- m…

第二讲笔记:隐私计算助力数据要素流通

1、数据要素流转与数据 2、数据外循环中的信任 焦虑 信任焦虑背后的代表性案例 内鬼门 &#xff1a; 2023 年 &#xff0c; 美国科技公司 Ubiquiti在2021年1月曝出数据泄露事 件&#xff0c; “攻击者”在随后的“谈判”中试 图向该企业勒索近200万美元&#xff08;50比特 币&…

Steam游戏如何选择适合的服务器

在Steam平台上&#xff0c;玩家可以享受到来自世界各地开发者的游戏作品。然而&#xff0c;要获得最佳的游戏体验&#xff0c;选择合适的服务器至关重要。本文将从网络延迟、服务器位置、游戏类型和个人偏好等多个方面&#xff0c;为玩家提供选择Steam游戏服务器的实用指南。 如…

设计模式-中介者(调停者)模式(行为型)

中介者模式 中介者模式是一种行为型模式&#xff0c;又叫调停者模式&#xff0c;它是为了解决多个对象之间&#xff0c;多个类之间通信的复杂性&#xff0c;定义一个中介者对象来封装一些列对象之间的交互&#xff0c;使各个对象之间不同持有对方的引用就可以实现交互&#xf…

湖南源点(市场研究咨询)如何产出更加有意义的竞品调研

湖南源点咨询认为&#xff1a;当前&#xff0c;任何项目都不能盲目开始&#xff0c;前期的准备工作必不可少。在基础架构搭建的同时&#xff0c;设计上对于前端功能、用户体验的调研就优先开始了。在这个阶段&#xff0c;大部分设计师都会分配很多调研任务&#xff0c;疯狂对竞…

BC C language

题目汇总 No.1 打印有规律的字符(牛牛的字符菱形) 代码展示 #include<stdio.h> int main() {char ch0;scanf("%c",&ch);for(int i0;i<5;i){for(int j0;j<5;j){if((i0||i4)&&j2)printf("%c", ch);else if ((i 1||i3) &&…

大疆智图_空三二维重建成果传输

一、软件环境 1.1 所需软件 1、 大疆智图&#xff1a;点击下载&#xff1b;   2、 ArcGIS Pro 3.1.5&#xff1a;点击下载&#xff0c;建议使用IDM或Aria2等多线程下载器&#xff1b;   3、 IDM下载器&#xff1a;点击下载&#xff0c;或自行搜索&#xff1b;   4、 Fas…

最近一直没动静的Pika Labs原来在筹集融资,加快构建视频基础模型

Pika 筹集了 8000 万美元&#xff0c;因此任何人都可以根据命令制作视频。 今天对我们来说是一个重要的日子。自从我们从斯坦福大学退学去构建 Pika 以来已经一年了&#xff0c;在这段时间里&#xff0c;我们在 Discord 上进行了秘密发布&#xff0c;发布了我们的 1.0 模型和 …

找了半天,还不如自己写一个图片转ico格式的程序

关于jpg、png等图片转ICO格式 最近突然急需一张ico格式的文件&#xff0c;就拿着处理好的png图片出网上找在线转换器&#xff0c;找了一个小时&#xff0c;绝了&#xff0c;不是需要注册充钱就是下载不下来&#xff0c;好不容易下载下来还是个文件错误。想着找个PS插件直接导出…

2024 cicsn ezbuf

文章目录 参考protobuf逆向学习复原结构思路exp 参考 https://www.y4ng.cn/posts/pwn/protobuf/#ciscn-2024-ezbuf protobuf 当时压根不知道用了protobuf这个玩意&#xff0c;提取工具也没提取出来&#xff0c;还是做题做太少了&#xff0c;很多关键性的结构都没看出来是pro…

WEB漏洞服务能提供哪些帮助

在数字化浪潮的推动下&#xff0c;Web应用程序已成为企业展示形象、提供服务、与用户进行交互的重要平台。然而&#xff0c;随着技术的飞速发展&#xff0c;Web应用程序中的安全漏洞也日益显现&#xff0c;成为网络安全的重大隐患。这些漏洞一旦被恶意攻击者利用&#xff0c;可…

极简主义在UI设计中的应用及解析

极简主义&#xff0c;即“少就是多”。在设计中&#xff0c;极简主义是许多艺术概念之一&#xff0c;它描述了一种内容形式&#xff0c;可以在许多方面使用。现在移动UI界面和网页设计中的极简主义设计越来越多。即时设计认为&#xff0c;极简主义UI界面不仅美观&#xff0c;而…

The 18th Northeast Collegiate Programming Contest(5/9/13)

心得 赛中ac&#xff1a;5&#xff0c;目前ac&#xff1a;9&#xff0c;题目总数&#xff1a;13 中档可做题还是很多的&#xff0c;可惜遇到了难绷的queueforces&#xff0c; 最后15min才判出来&#xff0c;oi赛制5wa4遗憾离场&#xff0c;赛后把几个题都给调过了&#xff0…

mysql (事物)

一.什么是事物 事物是一组操作的集合&#xff0c;不可分割的工作单位&#xff0c;事物会把所有的操作当作一个整体一起向系统提交或撤销操作请求&#xff0c;就是这些操作要么一起成功要么一起失败。 二.事物操作 &#xff08;这个就是一个理解&#xff09; 1.事务特性 原子性…

MongoDB CRUD操作:可重试写入

MongoDB CRUD操作&#xff1a;可重试写入 文章目录 MongoDB CRUD操作&#xff1a;可重试写入使用的先决条件部署的限制支持的存储引擎3.6 MongoDB 驱动程序MongoDB 版本写确认 可重试写入和多文档事务启用可重试写入MongoDB驱动mongosh 可重试的写操作行为持续的网络错误故障切…

46-1 护网溯源 - 钓鱼邮件溯源

一、客户提供钓鱼邮件样本 二、行为分析 三、样本分析 对钓鱼邮件中的木马程序1111.exe文件进行了分析,提交了360安全大脑沙箱云和微步在线云沙箱。 360安全大脑沙箱云显示,该1111.exe文件存在危险,因此在解压时需要谨慎操作,以免触发木马程序。 建议使用360压缩软件进行…

Chrome DevTools

Console 面板 此章节请打开 justwe7.github.io/devtools/console/console.html 一起食用 一方面用来记录页面在执行过程中的信息&#xff08;一般通过各种 console 语句来实现&#xff09;&#xff0c;另一方面用来当做 shell 窗口来执行脚本以及与页面文档、DevTools 等进行交…

Linux云计算架构师涨薪班就业服务有哪些?

学员一站式就业服务:一次学习&#xff0c;薪资翻倍 简历制作与指导 学员在培训期间&#xff0c;人才顾问会提供简历制作和指导服务&#xff0c;帮助学员制作出一份专业、有吸引力的简历。简历是求职者给招聘单位的第一印象&#xff0c;因此非常重要 模拟面试与技巧指导 为了让…

一种方法实现latex公式中显示空格

要解决的问题 我想要实现latex中出现空格。比如打出 Dice coefficients,然而一般情况下是不会显示出这两个单词之间的空格的&#xff0c;对吧。 解决方法 使用 \verb| |。 D i c e c o e f f i c i e n t s Dice coefficients Dicecoefficients D i c e c o e f f i c i e …

还不会线程池?JUC线程池源码级万字解析

线程池主要解决了两个问题&#xff1a; 第一个是当大量执行异步任务的时候提供较好的性能&#xff1b;在不使用线程池的时候&#xff0c;每次需要执行一个异步任务都需要新建一个 Thread 来进行&#xff0c;而线程的创建和销毁都是需要时间的&#xff0c;所以可以通过线程池来实…