2、以太网MAC控制器概述:常见SoC中的GMAC/EMAC控制器及其在设备树中的节点表示

以太网MAC(Media Access Control)控制器是SoC内部实现数据链路层功能的核心硬件模块。在嵌入式Linux系统中,常见的MAC控制器包括Synopsys DesignWare GMAC/EMAC、Cadence GEM、TI CPSW、NXP FEC以及Rockchip GMAC等。这些控制器在设备树中通过特定的compatible字符串和寄存器资源进行描述,是驱动与硬件绑定的关键入口。

2.1 主流MAC控制器架构对比

不同SoC厂商的MAC控制器在内部架构、DMA引擎、描述符管理以及PHY接口类型上存在差异。下表总结了常见控制器的关键特性:

控制器类型 常见SoC PHY接口支持 DMA引擎 设备树compatible
Synopsys DW GMAC ST/Allwinner/Rockchip GMII/RGMII/MII/RMII 独立DMA,支持多描述符 snps,dwmac-*
Cadence GEM Xilinx Zynq/Microchip SAMA5 GMII/RGMII/SGMII 集成DMA,支持TDES/RDES cdns,zynq-gem
TI CPSW TI AM335x/AM437x MII/RMII/RGMII 双端口共享DMA ti,cpsw
NXP FEC i.MX6/i.MX8 MII/RMII 简单DMA,环形描述符 fsl,imx6q-fec
Rockchip GMAC RK3288/RK3399 RGMII/RMII Synopsys衍生DMA rockchip,rk3288-gmac
关键概念: 设备树中的 compatible 属性是驱动匹配的"身份证"。内核通过该字符串查找对应的 of_match_table,从而加载正确的MAC驱动。

2.2 MAC控制器的设备树节点结构

一个典型的MAC设备树节点包含寄存器基址、中断号、时钟、复位控制以及PHY绑定信息。以下以Synopsys DW GMAC为例展示其标准结构:

gmac0: ethernet@ff290000 {
    compatible = "snps,dwmac-4.20a", "snps,dwmac";
    reg = <0x0 0xff290000 0x0 0x10000>;
    interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
    interrupt-names = "macirq";
    clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
    clock-names = "stmmaceth", "pclk";
    resets = <&cru SRST_GMAC_A>;
    reset-names = "stmmaceth";
    phy-mode = "rgmii";
    phy-handle = <&phy0>;
    mdio0: mdio {
        compatible = "snps,dwmac-mdio";
        #address-cells = <1>;
        #size-cells = <0>;
        phy0: ethernet-phy@1 {
            reg = <1>;
            compatible = "ethernet-phy-id004d.d074";
            reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
        };
    };
};
节点解析:
  • reg:MAC控制器的寄存器地址空间,通常为64KB。
  • interrupts:MAC中断号,用于通知驱动数据收发完成或错误状态。
  • phy-mode:声明MAC与PHY之间的接口协议,如rgmii、rmii、gmii。
  • phy-handle:指向MDIO子节点中PHY设备的phandle,建立MAC到PHY的绑定关系。
  • mdio子节点:内部MDIO总线控制器,用于扫描和访问外部PHY寄存器。

2.3 MAC控制器内部架构与设备树映射

为了更直观地理解MAC控制器各模块与设备树属性的对应关系,下图展示了Synopsys DW GMAC的内部架构及其在设备树中的映射:

Synopsys DW GMAC 内部架构与设备树映射 MAC 核心 CSR 寄存器组 流控/地址过滤 DMA 引擎 描述符管理器 数据搬运 时钟与复位 ACLK / PCLK 复位控制 MDIO 控制器 PHY 寄存器访问 PHY 接口 RGMII / RMII / MII 外部 PHY 芯片 PHY ID: 0x004d.d074 设备树属性映射关系 • reg → MAC核心CSR寄存器基址 (0xff290000) • clocks / resets → 时钟与复位模块 (ACLK/PCLK) • phy-mode → PHY接口类型 (rgmii) • mdio子节点 → MDIO控制器,用于发现外部PHY • phy-handle → 指向外部PHY节点,建立MAC-PHY绑定

2.4 不同SoC的MAC节点实例

以下列举三种典型SoC的MAC设备树节点,展示不同厂商的命名习惯和属性差异:

2.4.1 TI AM335x CPSW

&mac {
    compatible = "ti,cpsw";
    reg = <0x4a100000 0x800>;
    interrupts = <40 41 42>;
    cpdma_channels = <8>;
    ale_entries = <1024>;
    bd_ram_size = <0x2000>;
    mac_control = <0x20>;
    slaves = <1>;
    cpsw_emac0: slave@0 {
        phy-mode = "rmii";
        phy-handle = <&phy0>;
    };
    mdio: mdio@4a101000 {
        compatible = "ti,cpsw-mdio";
        reg = <0x4a101000 0x1000>;
        #address-cells = <1>;
        #size-cells = <0>;
        phy0: ethernet-phy@0 {
            reg = <0>;
        };
    };
};

2.4.2 Xilinx Zynq Cadence GEM

&gem0 {
    compatible = "cdns,zynq-gem", "cdns,gem";
    reg = <0xe000b000 0x1000>;
    interrupts = <0 22 4>;
    clocks = <&clkc 30>, <&clkc 30>, <&clkc 31>;
    clock-names = "pclk", "hclk", "tx_clk";
    phy-mode = "rgmii-id";
    phy-handle = <&phy0>;
    mdio: mdio {
        #address-cells = <1>;
        #size-cells = <0>;
        phy0: ethernet-phy@7 {
            reg = <7>;
            ti,rx-internal-delay = <0x8>;
            ti,tx-internal-delay = <0xa>;
        };
    };
};

2.4.3 Rockchip RK3399 GMAC

&gmac {
    compatible = "rockchip,rk3399-gmac";
    reg = <0x0 0xfe300000 0x0 0x10000>;
    interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>;
    clock-names = "stmmaceth", "mac_clk_rx", "mac_clk_tx";
    phy-mode = "rgmii";
    phy-handle = <&phy0>;
    mdio: mdio {
        compatible = "snps,dwmac-mdio";
        #address-cells = <1>;
        #size-cells = <0>;
        phy0: ethernet-phy@0 {
            reg = <0>;
            compatible = "ethernet-phy-id1234.d567";
            reset-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
        };
    };
};
常见陷阱:
  • phy-mode 必须与硬件连线严格一致。例如,如果实际使用RGMII但配置为RMII,驱动将无法正确配置接口延迟和时钟极性。
  • MDIO子节点的 #address-cells 和 #size-cells 必须正确设置,否则PHY扫描会失败。
  • 多个MAC控制器共享同一个MDIO总线时,MDIO节点应放在外部,避免重复注册。

2.5 MAC节点中的关键属性速查表

下表汇总了MAC设备树节点中最常用的属性及其含义,供开发者在编写或调试设备树时快速参考:

属性名 类型 必选/可选 说明
compatible 字符串列表 必选 驱动匹配标识,通常包含SoC特定和通用版本
reg 地址/长度对 必选 MAC控制器寄存器基址和地址范围
interrupts 中断描述 必选 MAC中断号,通常为SPI类型
phy-mode 字符串 必选 MAC与PHY之间的接口协议
phy-handle phandle 必选 指向PHY设备节点的引用
clocks 时钟列表 可选 MAC工作时钟,通常包含AXI/APB时钟
resets 复位列表 可选 MAC复位信号,用于驱动初始化时复位硬件
mac-address 字节数组 可选 预设MAC地址,若未提供则驱动从EEPROM或随机生成
local-mac-address 字节数组 可选 与mac-address类似,某些SoC使用此属性
snps,reset-gpio GPIO描述 可选 Synopsys专用:PHY复位GPIO

2.6 驱动适配流程概览

从设备树节点到驱动加载的完整流程可以概括为以下步骤:

  1. 内核解析设备树:启动时,内核遍历所有节点,将 compatible 属性与驱动注册的 of_match_table 进行匹配。
  2. 驱动probe调用:匹配成功后,内核调用驱动的 probe() 函数,传入 struct platform_device 指针。
  3. 资源获取:驱动通过 platform_get_resource() 获取寄存器地址和中断号;通过 of_property_read_* 系列函数读取时钟、复位、phy-mode等属性。
  4. PHY绑定:驱动解析 phy-handle 属性,通过MDIO总线找到对应的PHY设备,并调用 phy_connect() 建立连接。
  5. 网络设备注册:完成硬件初始化和PHY协商后,驱动调用 register_netdev() 将网络设备注册到内核网络栈。
实践要点: 在调试MAC驱动时,建议首先检查设备树节点是否被内核正确识别。可以通过 ls /sys/firmware/devicetree/base/ 查看设备树内容,或使用 dtc -I fs -O dts /sys/firmware/devicetree/base/ 反编译当前设备树进行验证。