STMMAC 网卡驱动机制与原理详解
源码:rk3588/kernel-6.1/drivers/net/ethernet/stmicro/stmmac/
适用平台:Synopsys DesignWare Ethernet MAC(DWMAC),RK3588 使用 GMAC4 (Core 4.10+)。
1. 驱动定位
STMMAC 是 Linux 内核中对 Synopsys DWMAC IP 的通用 netdev 驱动,最初由 STMicroelectronics 维护,现由 Synopsys/社区共同演进。Rockchip RK3588 内置两个 GMAC 控制器,通过 dwmac-rockchip.ko(dwmac-rk.c)接入本驱动栈。
| 属性 |
说明 |
| 总线 |
Platform(SoC 内置)、PCI(部分 x86/Intel) |
| 网络接口 |
标准 struct net_device,多 TX/RX 队列 |
| 链路管理 |
phylink(统一 RGMII/RMII/SGMII/PCS) |
| RX 缓冲 |
page_pool(页级分配,支持 GRO/XDP) |
| 硬件抽象 |
HWIF ops 表(按 Synopsys Core ID 选择实现) |
2. 硬件 IP 结构
Synopsys DWMAC 自 Core 4.0 起采用 MAC + MTL + DMA 三层结构:
- MAC:地址过滤、VLAN、流控、RSS、PTP 时间戳
- MTL(MAC Transaction Layer):TX/RX 队列、调度算法(DWRR/WRR/SP 等)
- DMA:descriptor ring 管理,与 Linux DMA API 对接
3. 软件分层架构
flowchart TB
subgraph L1["L1 Platform Glue"]
RK["dwmac-rk.c"]
PLAT["stmmac_platform.c"]
end
subgraph L2["L2 Core Driver"]
MAIN["stmmac_main.c"]
FEAT["mdio / ptp / tc / xdp / ethtool"]
end
subgraph L3["L3 HWIF"]
HWIF["hwif.c"]
IMPL["dwmac4_* / dwxgmac2_*"]
end
L1 -->|"stmmac_dvr_probe()"| L2
L2 -->|"stmmac_hwif_init()"| L3
L3 --> HW["Synopsys IP 寄存器"]
各层职责
| 层级 |
代表文件 |
职责 |
| L1 Glue |
dwmac-rk.c |
DT、时钟、复位、GRF 引脚复用、MAC 地址 |
| L2 Core |
stmmac_main.c |
netdev 生命周期、DMA ring、NAPI、数据路径 |
| L3 HWIF |
hwif.c + dwmac4_*.c |
屏蔽 IP 版本差异,提供 ops 回调 |
4. 核心数据结构
4.1 stmmac_priv
驱动私有上下文,挂载在 netdev_priv():
ioaddr:MMIO 基址
hw → mac_device_info:HWIF ops 集合
dma_conf:TX/RX queue 与 descriptor ring
channel[]:每通道 NAPI 结构
phylink:链路状态机
plat → plat_stmmacenet_data:平台配置与回调
4.2 mac_device_info
聚合六类 ops:
| ops |
职责 |
mac |
MAC 寄存器:过滤、流控、MTL、VLAN、RSS |
dma |
DMA 启停、IRQ、tail pointer |
desc |
描述符格式:init/prepare/status |
mode |
Ring/Chain 模式 desc3 管理 |
ptp |
硬件时间戳寄存器 |
tc |
Traffic Control 硬件卸载 |
mmc |
管理计数器 |
4.3 plat_stmmacenet_data
定义于 include/linux/stmmac.h,Platform Glue 填充后传入 stmmac_dvr_probe(),包含队列数、DMA 大小、PHY 接口、fix_mac_speed() 等回调。
5. 生命周期
5.1 Probe(以 RK3588 为例)
1 2 3 4 5 6 7 8
| rk_gmac_probe() → stmmac_get_platform_resources() # MMIO/IRQ → stmmac_probe_config_dt() # plat_stmmacenet_data → rk_gmac_setup() # 时钟/GRF/bsp_priv → stmmac_dvr_probe() → stmmac_hw_init() / stmmac_hwif_init() → stmmac_phy_setup() # phylink + MDIO → register_netdev()
|
5.2 Open / Stop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ip link set eth0 up → stmmac_open() → stmmac_setup_dma_desc() # 分配 ring → __stmmac_open() → init RX buffers (page_pool) → 配置 MAC/DMA/MTL → request_irq + napi_enable → phylink_start() → stmmac_start_all_dma()
ip link set eth0 down → stmmac_release() → phylink_stop / disable queues → free_irq / napi_disable → stmmac_stop_all_dma() → free_dma_desc_resources()
|
6. 数据路径概要
6.1 TX
1 2 3 4 5 6 7 8
| dev_queue_xmit() → stmmac_xmit() → [TSO] stmmac_tso_xmit() → DMA map skb → stmmac_prepare_tx_desc() → set_tx_owner + set_tx_tail_ptr ← TX IRQ → stmmac_napi_poll_tx() → stmmac_tx_clean() → 释放 skb
|
6.2 RX
1 2 3 4 5 6
| RX DMA 写 descriptor → RX IRQ → stmmac_napi_poll_rx() → stmmac_rx() → [XDP] bpf 程序 → build skb → napi_gro_receive() → refill RX descriptor
|
7. 特性支持矩阵(RK3588 / GMAC4)
| 特性 |
支持 |
模块 |
| 多队列 TX/RX |
✓ |
stmmac_main + dwmac4 |
| TSO/GSO |
✓(需 tso_en) |
stmmac_xmit |
| RX checksum offload |
✓ |
dwmac4_descs |
| VLAN HW filter/insert |
✓ |
dwmac4_core |
| RSS |
✓(需 rss_en) |
dwmac4_core |
| PTP 1588 |
✓ |
stmmac_ptp |
| TC CBS/TAPRIO |
✓(Core 5.10+) |
stmmac_tc |
| XDP / AF_XDP |
✓ |
stmmac_xdp + stmmac_main |
| EEE LPI |
✓ |
stmmac_main |
| WoL |
✓(平台配置) |
stmmac_main |
8. RK3588 平台要点
- DT compatible:
rockchip,rk3588-gmac
- Glue ops:
rk3588_ops(RGMII/RMII 引脚复用、时钟、速率)
- 双 GMAC:
gmac0 / gmac1,独立 rk_priv_data
- 常见接口:RGMII(外接 PHY)、SGMII/QSGMII(经 XPCS)
- 平台默认:
plat_dat->sph_disable = true(禁用 Split Header)
9. 调试入口
| 手段 |
说明 |
ethtool -S eth0 |
驱动统计 + MMC |
ethtool -g/-G eth0 |
ring 参数 |
ethtool -k eth0 |
offload 开关 |
debugfs |
CONFIG_DEBUG_FS 下寄存器 dump |
dynamic_debug |
netif_msg_* 控制 |
dwmac-rk-tool |
RK 环回 sysfs 测试 |
10. 专题文档索引
详见 README.md 中编号 01–12 专题文档。
正在加载留言…