02 stmmac_main 核心驱动

02 stmmac_main 核心驱动

源码:stmmac_main.c(约 8360 行)
头文件:stmmac.hcommon.h

1. 模块职责

stmmac_main.c 是 STMMAC 驱动的 控制面与数据面中枢,负责:

  • 设备 probe/remove/suspend/resume
  • net_device_ops 完整实现
  • DMA descriptor ring 分配与回收
  • TX/RX 数据路径
  • 中断分发与 NAPI
  • phylink 集成、EEE、WoL、VLAN、RSS
  • 与 PTP/TC/XDP 子模块协作

2. 对外入口函数

函数 调用者 说明
stmmac_dvr_probe() Platform/PCI glue 核心 probe
stmmac_dvr_remove() Platform/PCI glue 核心 remove
stmmac_resume() / stmmac_suspend() PM 框架 电源管理
stmmac_bus_clks_config() glue / PM 总线时钟门控

3. net_device_ops 映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static const struct net_device_ops stmmac_netdev_ops = {
.ndo_open = stmmac_open,
.ndo_stop = stmmac_release,
.ndo_start_xmit = stmmac_xmit,
.ndo_change_mtu = stmmac_change_mtu,
.ndo_fix_features = stmmac_fix_features,
.ndo_set_features = stmmac_set_features,
.ndo_set_rx_mode = stmmac_set_rx_mode,
.ndo_tx_timeout = stmmac_tx_timeout,
.ndo_eth_ioctl = stmmac_ioctl,
.ndo_setup_tc = stmmac_setup_tc,
.ndo_select_queue = stmmac_select_queue,
.ndo_bpf = stmmac_bpf,
.ndo_xdp_xmit = stmmac_xdp_xmit,
.ndo_xsk_wakeup = stmmac_xsk_wakeup,
.ndo_vlan_rx_add_vid = stmmac_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = stmmac_vlan_rx_kill_vid,
// ...
};

4. Probe 流程详解

stmmac_dvr_probe() 主要步骤:

register_netdevstmmac_phy_setupstmmac_hw_initstmmac_dvr_proberegister_netdevstmmac_phy_setupstmmac_hw_initstmmac_dvr_probedevm_alloc_etherdev_mqs()绑定 ioaddr/irq/platcreate workqueue (service_task)stmmac_hwif_init + get_hw_features设置 hw_features (TSO/GRO/VLAN/TC)dma_set_mask_and_coherent()phylink + MDIO 注册register_netdev()

4.1 硬件能力探测

stmmac_hw_init() 调用 stmmac_get_hw_features() 填充 priv->dma_cap

  • TSO、RX/TX checksum、RSS、VLAN、SPH
  • 队列数量、hash 表大小
  • 64 位 DMA 地址宽度

平台参数可被 HW capability 覆盖(如 enh_descrx_coe)。

5. Open / Release

5.1 stmmac_open()

1
2
3
4
5
6
7
8
9
10
11
stmmac_open(dev)
→ stmmac_setup_dma_desc(priv, mtu) # 按 MTU 计算 buffer/ring
→ __stmmac_open(dev, dma_conf)
→ alloc_dma_desc_resources()
→ stmmac_init_rx_buffers() # page_pool 预填 RX
→ stmmac_hw_setup() # MAC/DMA/MTL 寄存器
→ stmmac_request_irq()
→ stmmac_napi_add() + napi_enable()
→ phylink_start()
→ netif_tx_start_all_queues()
→ stmmac_start_all_dma()

5.2 stmmac_release()

逆序关闭:phylink_stop → disable queues → free_irq → stop DMA → free ring → MAC disable。

6. TX 路径

6.1 stmmac_xmit()

入口:ndo_start_xmit,由 dev_queue_xmit() 触发。

关键步骤:

  1. skb_get_queue_mapping() 选择 tx_queue
  2. EEE:若在 LPI 模式则先 stmmac_disable_eee_mode()
  3. GSO 分流 → stmmac_tso_xmit()(TCP/UDP TSO)
  4. 检查 ring 空间 stmmac_tx_avail()
  5. 可选 VLAN 硬件插入 stmmac_vlan_insert()
  6. DMA map skb 各段(linear + frags)
  7. stmmac_prepare_tx_desc() 填描述符
  8. stmmac_set_tx_owner() 交 ownership 给 DMA
  9. stmmac_set_tx_tail_ptr() 通知硬件

6.2 stmmac_tx_clean()

NAPI TX poll 中调用:

  • 扫描已完成 descriptor(owner bit 归还 CPU)
  • stmmac_tx_status() 检查错误
  • unmap DMA、释放 skb
  • 更新 dirty_tx,必要时 netif_wake_queue()

6.3 中断合并

  • tx_coal_frames / tx_coal_timer:每 N 帧或超时设 IC bit
  • hrtimer txtimer:TX 完成延迟唤醒

7. RX 路径

7.1 stmmac_rx()

NAPI RX poll 主循环:

  1. 读 descriptor status(stmmac_rx_status()
  2. owner 仍属 DMA 则 break
  3. 错误帧 discard 或统计
  4. 多段帧组装 skb(state_saved 跨 poll 保存中间状态)
  5. XDP:bpf_prog_run() → PASS/DROP/REDIRECT/TX
  6. 正常路径:napi_gro_receive() 上交协议栈
  7. stmmac_alloc_rx_buffers() 补充 RX 描述符

7.2 page_pool

RX 使用 page_pool 分配页:

  • 减少 alloc/free 开销
  • 与 XDP 共享页框架
  • rx_copybreak:小帧可 copy 到 skb 头(非 zero-copy 路径)

7.3 stmmac_rx_zc()

AF_XDP zero-copy 专用 RX,DMA 直接写入 XSK umem。

8. 中断与 NAPI

hardirq: stmmac_interruptstmmac_dma_interrupt()stmmac_napi_check() per channeldisable_dma_irq__napi_schedulesoftirq: napi_pollstmmac_napi_poll_rx → stmmac_rxstmmac_napi_poll_tx → stmmac_tx_cleannapi_complete → enable_dma_irq

支持 单 IRQper-queue MSImulti_msi_en)。

回调 作用
stmmac_mac_config 接口模式变化(RGMII/SGMII 等)
stmmac_mac_link_up 链路 up:速率、双工、流控、启动 DMA
stmmac_mac_link_down 链路 down:停 DMA、carrier off

stmmac_phy_setup() 创建 phylink 实例并连接 PHY/PCS。

10. 错误恢复

机制 触发
stmmac_tx_timeout TX watchdog 超时
stmmac_global_err 调度 service_task 异步复位
stmmac_tx_err DMA TX hard error

service_task workqueue 避免在 IRQ 上下文做完整 reset。

11. 其它内嵌功能

功能 主要函数
EEE LPI stmmac_enable_eee_mode, stmmac_eee_ctrl_timer
VLAN stmmac_vlan_rx_add_vid, HW filter
RSS stmmac_set_rxfh, stmmac_rss_configure
FPE stmmac_fpe_handshake, fpe_wq
debugfs stmmac_init_fs

12. 关键文件内函数索引

行号区间(约) 内容
4000–4100 open/release
4470–4700 xmit
5300–5700 rx / rx_zc
2530–2720 tx_clean
2770–2850 dma_interrupt / napi_check
5750–5840 napi_poll_rx/tx/rxtx
7100–7260 netdev_ops
7290–7390 hw_init
7560–7900 dvr_probe

13. 相关文档

文章互动

阅读 --

留言

0 条留言

正在加载留言…