01 总体架构与分层设计
源码:
drivers/net/ethernet/stmicro/stmmac/
关联:stmmac.h、common.h、hwif.h、hwif.c
1. 设计目标
STMMAC 驱动需同时支持:
- 多代 Synopsys IP(GMAC3 → GMAC4 → DWMAC5 → XGMAC/XLGMAC)
- 数十种 SoC Platform Glue(Rockchip、NXP、Qualcomm、ST 等)
- 完整 netdev 特性(多队列、offload、PTP、TC、XDP)
核心策略:核心逻辑与硬件/平台解耦,通过 ops 表和平台数据注入实现扩展。
2. 三层架构
flowchart TB
subgraph App["Linux 网络栈"]
NET["net/core/dev.c"]
TC["net/sched"]
end
subgraph L2["L2 核心驱动 stmmac_main.c"]
NDO["net_device_ops"]
DMA["DMA Ring 管理"]
NAPI["NAPI / IRQ"]
end
subgraph L3["L3 HWIF"]
OPS["mac/dma/desc/ptp/tc/mmc ops"]
end
subgraph L1["L1 Platform Glue"]
PLAT["plat_stmmacenet_data"]
BSP["bsp_priv 回调"]
end
NET --> NDO
TC --> NDO
NDO --> DMA
DMA --> OPS
L1 --> L2
OPS --> REG["MMIO 寄存器"]2.1 L1 — Platform Glue
输入:Device Tree / ACPI / 平台数据
输出:plat_stmmacenet_data + stmmac_resources
| 回调字段 | 典型用途 |
|---|---|
fix_mac_speed |
切换 RGMII/RMII 时钟分频 |
get_eth_addr |
从 OTP/eFuse 读 MAC |
integrated_phy_power |
内置 PHY 上下电 |
clks_config |
运行时门控 MAC 时钟 |
bsp_priv |
SoC 私有数据(如 rk_priv_data) |
统一入口:所有 Glue 最终调用 stmmac_dvr_probe(device, plat_dat, res)。
2.2 L2 — Core Driver
stmmac_main.c 是驱动中枢(约 8360 行),职责:
- 实现
net_device_ops全套回调 - 管理 TX/RX descriptor ring 与 buffer 生命周期
- 调度 NAPI、处理中断、错误恢复
- 协调 phylink、PTP、TC、XDP 等子模块
不直接操作版本相关寄存器,而是通过 HWIF 宏调用 L3。
2.3 L3 — HWIF(Hardware Interface)
hwif.c 在 probe 时:
- 读取
GMAC_VERSION或GMAC4_VERSION寄存器 - 在
stmmac_hw[]表中匹配 Synopsys ID - 将对应 ops 指针填入
mac_device_info - 调用版本专用
setup()(如dwmac4_setup())
调用示例:
1 | stmmac_start_tx(priv, priv->ioaddr, chan); |
3. 核心数据结构关系
classDiagram
class net_device {
+netdev_ops
+features
}
class stmmac_priv {
+ioaddr
+hw
+dma_conf
+channel[]
+phylink
+plat
}
class mac_device_info {
+mac ops
+dma ops
+desc ops
+ptp ops
+tc ops
+mmc ops
}
class plat_stmmacenet_data {
+tx_queues_to_use
+rx_queues_to_use
+fix_mac_speed()
+bsp_priv
}
class stmmac_dma_conf {
+tx_queue[]
+rx_queue[]
}
net_device --> stmmac_priv : netdev_priv
stmmac_priv --> mac_device_info : hw
stmmac_priv --> plat_stmmacenet_data : plat
stmmac_priv --> stmmac_dma_conf : dma_conf4. 队列与 NAPI 模型
每个 channel 对应一对(或合并)NAPI:
| 结构体 | 关键字段 | 作用 |
|---|---|---|
stmmac_tx_queue |
cur_tx, dirty_tx, dma_tx |
TX ring 与 skb 映射 |
stmmac_rx_queue |
cur_rx, page_pool, buf_pool |
RX ring 与页缓冲 |
stmmac_channel |
rx_napi, tx_napi, rxtx_napi |
软中断上下文 |
AF_XDP zero-copy 启用时,同一 channel 使用 rxtx_napi 合并 poll。
5. 设计模式
| 模式 | 实现 |
|---|---|
| Strategy | mac_device_info 下各 ops 表 |
| Template Method | probe 固定流程,HW 步骤由 ops 填充 |
| Dependency Injection | plat_stmmacenet_data 回调 |
| Per-CPU / cacheline | 热路径结构体 ____cacheline_aligned |
6. 编译与配置关系
1 | CONFIG_STMMAC_ETH → stmmac.ko(必选) |
RK3588 典型 defconfig 会同时启用 ETH + PLATFORM + ROCKCHIP + FULL + ETHTOOL。
7. 与内核网络栈边界
| 方向 | 接口 |
|---|---|
| 下行(栈→驱动) | ndo_start_xmit、ndo_open、ndo_setup_tc、ndo_bpf |
| 上行(驱动→栈) | napi_gro_receive、netif_receive_skb |
| 链路 | phylink → phylib / PCS |
| 管理 | ethtool_ops、rtnetlink |
8. 扩展新平台步骤
- 新增
dwmac-xxx.c,实现 probe/remove - 填充
plat_stmmacenet_data(队列、接口类型、回调) - 调用
stmmac_dvr_probe() - 在
Makefile/Kconfig注册 - 提供 DTS binding(
snps,dwmac或厂商 compatible)
无需修改 stmmac_main.c,除非有新硬件特性需核心支持。
正在加载留言…