以太网驱动
概述
以太网(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 节点,并根据接口类型修改节点内容:
-
若为 RGMII 接口:
- 配置:
phy-mode = "rgmii-id"; - 设置:
v1_8 = <0>;代表以太网使用 1.8V 电压
- 配置:
-
若为 RMII 接口:
- 配置:
phy-mode = "rmii"; - 屏蔽
v1_8 = <0>;,使用默认的 3.3V 电压
- 配置:
-
网速配置:
- 若为千兆网络:
max-speed-mhz = <1000>; - 若为百兆网络:
max-speed-mhz = <100>;
- 若为千兆网络:
步骤 2:配置 ACPI table
以太网的 ACPI table 配置文件位于 uboot 源码中的 board/mthreads/common/AcpiTables/Common/Ethernet.asl。该文件支持 2 路以太网:ETH0 和 ETH1。
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 方法,表示 设备初始化逻辑,但里面调用了两个 非标准的、平台自定义方法:SSID 和 IOSW。_INI 是 ACPI 中每个 Device 或 Scope 对象都可以定义的 初始化方法。操作系统会在设备 被枚举之后、设备驱动绑定之前 调用 _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 文件,查找 gem0 到 gem1 节点,分别对应以太网控制器 eth0 和 eth1。
在节点中配置 PHY 接口模式:
-
RGMII 接口:
- 添加:
phy-mode = "rgmii-id"; - 注释:
no-c45行(适用于 C22 PHY)
- 添加:
-
RMII 接口:
- 添加:
phy-mode = "rmii"; - 打开:
no-c45行(适用于不支持 Clause 45 的 PHY)
- 添加:
步骤 2:配置 pinctrl 引脚
打开 m1000-t021.dts 文件,在 gem0 到 gem1 节点中添加:
pinctrl-names = "default";
pinctrl-0 = <...>; // 引用具体引脚组
RGMII 接口配置:

注意:如果上述 pin 在设备树中未定义,需手动添加定义。
具体请参考 pinctrl 一章,定义时应确保以下属性正确配置。
所有 pin 必须配置:
drive-strength = <8>;
power-source = <1800>;
function-value = <1>;
RMII 接口配置:

注意:如果上述 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 support 和 Cadence MACB/GEM debugfs support。
调试方法说明
以太网常用的调试工具包括 ping、iperf3、ethtool 等。
-
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";表示TX和RX都延时 2ns。 -
phy-mode = "rgmii-txid";表示仅TX延时 2ns。 -
phy-mode = "rgmii-rxid";表示仅RX延时 2ns。 -
phy-mode = "rgmii";表示TX和RX都不延时。

