跳到主要内容

以太网驱动

概述

以太网(Ethernet)是一种广泛应用于局域网的计算机网络技术,用于实现设备间的高效数据通信。 以太网基于有线介质的网络通信标准,定义了数据帧格式、传输协议及物理层规范。以太网拥有以下优势:

  • 高可靠性
  • 低延迟
  • 强兼容性
  • 成本可控

功能描述

  • 支持两路以太网控制器
  • 支持十兆、百兆和千兆模式
  • 支持 RGMII 和 RMII PHY 接口
    • RGMII 使用 1.8V 电压
    • RMII 使用 3.3V 电压
  • 支持全双工和半双工模式
  • 支持 MAC 自环回调试
  • 支持 Receive Checksum Offload
  • 支持 TCP Segmentation Offload(TSO
  • 支持 UDP Fragmentation Offload(UFO

配置流程

步骤 1:配置 U-Boot 设备树

U-Boot 中目前仅支持以太网控制器 eth0。 MTT E300 的设备树文件路径为:arch/arm/dts/。以下以现有的 aimodule 配置作为板级设备树文件示例。

打开 mthreads-m1000-aimodule.dts,找到 gem0 节点,并根据接口类型修改节点内容:

  1. 若为 RGMII 接口

    • 配置:phy-mode = "rgmii-id";
    • 设置:v1_8 = <0>; 代表以太网使用 1.8V 电压
  2. 若为 RMII 接口

    • 配置:phy-mode = "rmii";
    • 屏蔽 v1_8 = <0>;,使用默认的 3.3V 电压
  3. 网速配置

    • 若为千兆网络:max-speed-mhz = <1000>;
    • 若为百兆网络:max-speed-mhz = <100>;

步骤 2:配置 ACPI table

以太网的 ACPI table 配置文件位于 uboot 源码中的 board/mthreads/common/AcpiTables/Common/Ethernet.asl。该文件支持 2 路以太网:ETH0ETH1

Name (_HID, "CSET0001")

Name: 声明一个名字对象(ACPI 语法)。_HID: 是 ACPI 的 标准设备标识符(Hardware ID)。"CSET0001": 是这个设备的 硬件 ID 字符串。

Name (_UID, Zero)

_UID 是 ACPI 中的 唯一标识符(Unique ID)。它和 _HID(硬件 ID)一起用于唯一标识设备,尤其是当有多个设备具有相同 _HID 时。Zero 是 ACPI 定义的一个常量,代表数值。

Method (_STA)
{
Return (0xf)
}

_STA 是一个标准的 ACPI 方法,表示设备的状态(_STA)。全称为 Status,用于告知操作系统当前设备是否存在、是否已启用、是否可用于子设备枚举。_STA 方法应返回一个位掩码(bitmask),每一位表示设备的某种状态。bit0:设备存在;bit1:设备已启用;bit2:设备可用于 I/O;bit3:子设备应被枚举。此处返回 0xF 表示上述各 bit 均为 1。

Name (_CCA, 0x0) 这是用于 ACPI 设备描述中的一条标准属性,表示该设备的 Cache Coherency Attribute,也就是缓存一致性属性。这里的值是 0 表示该设备不具备缓存一致性,即 non-coherent。

Name (_DEP, Package () // _DEP: Dependencies
{
_SB.CRG
})

是对 _DEP 这一标准 ACPI 对象的定义,它表示该设备对系统中其它设备或对象的依赖关系(Dependencies)。它是一个 Package 类型的对象,列出当前设备在初始化之前所依赖的其它对象(通常是设备)。通常用于告诉操作系统:我需要先有某个设备或对象准备好,我才能正常工作。_SB.CRG 是当前设备所依赖的对象,全路径是 _SB.CRG_SB:系统总线(System Bus)节点。CRG:时钟控制器。

Method (_INI) {
SSID(0x73d500, ETH0_STREAM_ID)
IOSW(GID_ETH0, POWERSTAT_NORMAL)
}

是 ACPI 中设备的 _INI 方法,表示 设备初始化逻辑,但里面调用了两个 非标准的、平台自定义方法:SSIDIOSW_INI 是 ACPI 中每个 DeviceScope 对象都可以定义的 初始化方法。操作系统会在设备 被枚举之后、设备驱动绑定之前 调用 _INI,用于初始化该设备的 ACPI 逻辑状态。SSID(0x73d500, ETH0_STREAM_ID):将 0x73d500 寄存器的值写为 42(这里 ETH0_STREAM_ID 的值是 42)。IOSW(GID_ETH0, POWERSTAT_NORMAL):切换以太网 0 的 gpio 状态为 normal

Name (_CRS, ResourceTemplate ()
{
Memory32Fixed (ReadWrite,
0x734000,
0x2000,
)
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
{
99,
98,
97,
96,
}
})

是定义该设备的 _CRS 方法(Current Resource Settings),其作用是告诉操作系统这个设备所使用的硬件资源(内存、IO、IRQ 等)。Memory32Fixed (ReadWrite, 0x734000, 0x2000) 表示该设备的 MMIO(寄存器映射)地址,驱动会 ioremap() 后访问。Interrupt (...) { 99, 98, 97, 96 } 表示该设备使用了中断资源。ResourceConsumer 表示这是一个使用(而非提供)中断的设备。Level 表示电平触发。ActiveHigh 表示高电平有效。Exclusive 表示中断不可共享。{ 99, 98, 97, 96 } 表示用到的中断号。

Name (_DSD, Package () { [...] }) 是 ACPI 中的 Device Specific Data (_DSD) 描述,用于向操作系统传递设备特定的属性。ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"):这是 Device Properties UUID,这是 ACPI 官方为 _DSD 定义的标准 UUID,用来标识属性是键值对形式。Package () { ... } 包含多个键值对,这些是具体的属性定义,以 "key", value 的形式存在,每个用 Package (0x02) 包裹。

Package () {
"clock-names",
Package () { "pclk", "hclk", "tx_clk", "tsu_clk" }
}

定义设备所需时钟的逻辑名称。和 "clocks" 一一对应。驱动中通常会通过 clk_get(dev, "pclk") 获取对应时钟。

Package () {
"clocks",
Package () {
[...]
}
}

给出实际的时钟控制器引用以及对应的时钟编号。^CRG 表示当前作用域(当前 device)中的父级 CRG 设备(时钟控制器)。后面是该控制器下的具体时钟编号或 ID(PERI_GMAC0_PCLK 等。这些信息通常对应到 Linux 的 clk_get() 框架。

Package () {
"phy-mode",
Package () { "rgmii-id" }
}

指定该以太网设备使用的 PHY 接口类型。"rgmii-id" 表示 RGMII 接口,并开启了 内部延迟(Internal Delay)。如果使用 rmii,可以写为 Package () rgmii-id

下半部分的 ETH1 参照上述描述。

步骤 3:配置 Linux 设备树

如果使用设备树方式启动内核,可以按如下方法配置以太网的设备树。

Linux 中 MTT E300 的设备树文件路径为: arch/arm64/boot/dts/m1000/

以下以 T021 板为板级设备树文件示例:

步骤 1:配置 GEM 控制器节点

打开 m1000-t021.dtsi 文件,查找 gem0gem1 节点,分别对应以太网控制器 eth0eth1

在节点中配置 PHY 接口模式:

  • RGMII 接口

    • 添加:phy-mode = "rgmii-id";
    • 注释:no-c45 行(适用于 C22 PHY)
  • RMII 接口

    • 添加:phy-mode = "rmii";
    • 打开:no-c45 行(适用于不支持 Clause 45 的 PHY)

步骤 2:配置 pinctrl 引脚

打开 m1000-t021.dts 文件,在 gem0gem1 节点中添加:

pinctrl-names = "default";
pinctrl-0 = <...>; // 引用具体引脚组

RGMII 接口配置:

E300 076 图示

提示

注意:如果上述 pin 在设备树中未定义,需手动添加定义。

具体请参考 pinctrl 一章,定义时应确保以下属性正确配置。

所有 pin 必须配置:

drive-strength = <8>;
power-source = <1800>;
function-value = <1>;

RMII 接口配置:

E300 077 图示

提示

注意:如果上述 pin 在设备树中未定义,需手动添加定义。

具体请参考 pinctrl 一章,定义时应确保以下属性正确配置。

所有 pin 必须配置:

drive-strength = <8>;
power-source = <3300>;

以下引脚需设置为 function-value = <2>

  • pin 21–24
  • pin 27–30
  • pin 35–38
  • pin 41–44

其余所有引脚设置为 function-value = <1>


步骤 4:配置内核

linux 内核的配置菜单中要选中 MTT E300 ethernet 的驱动,路径如下:

│ Symbol: MACB
[=y]

│ Type : tristate

│ Defined at drivers/net/ethernet/cadence/Kconfig:22
│ Prompt: Cadence MACB/GEM
support

│ Location:

│ -
> Device Drivers
│ -> Network device support (NETDEVICES [=y])
│ -> Ethernet driver support (ETHERNET [=y])

│ -> Cadence devices (NET_VENDOR_CADENCE
[=y])


│ -> Cadence MACB/GEM support (MACB
[=y])

选中 Cadence devices,然后选中 Cadence MACB/GEM supportCadence MACB/GEM debugfs support


调试方法说明

以太网常用的调试工具包括 pingiperf3ethtool 等。

  • ping 用于检测网络连通性。例如:

    ping -c4 www.example.com

    发送 4 个 ICMP 包,显示延时和丢包率。

  • iperf3 用于网络性能测试。

    • 服务端:

      iperf3 -s
    • 客户端:

      iperf3 -c <服务器 IP>

      常用参数包括:

      • -p 指定端口

      • -t 设定测试时长(秒)

      • -i 定义报告间隔(秒)

  • ethtool 用于查询、配置网卡参数,故障诊断和性能调优。常用命令示例如下:

    ethtool eth0 # 显示设备信息
    ethtool -s eth0 speed 1000 duplex full autoneg off # 设置速率、双工模式和自动协商
    ethtool -i eth0 # 查看驱动及固件信息

常见问题

Q:如何配置 RGMII 接口的 TX 和 RX 延时 2ns?

A: 在设备树中通过设置 phy-mode 来控制延时:

  • phy-mode = "rgmii-id"; 表示 TXRX 都延时 2ns。

  • phy-mode = "rgmii-txid"; 表示仅 TX 延时 2ns。

  • phy-mode = "rgmii-rxid"; 表示仅 RX 延时 2ns。

  • phy-mode = "rgmii"; 表示 TXRX 都不延时。