3. 网卡硬件架构概览:MAC层、PHY层、DMA引擎、描述符环
在编写网卡驱动之前,必须理解硬件内部的数据流动路径。现代网卡(NIC)并非一个简单的“插网线就能收发”的黑盒,而是由多个专用硬件模块组成的协同系统。本章从驱动开发者的视角,拆解MAC、PHY、DMA引擎和描述符环(Descriptor Ring)这四大核心模块的职责与交互方式。
3.1 网卡硬件分层模型
从OSI模型映射到硬件芯片,网卡内部可划分为三个主要层次:
- PHY层(物理层):负责模拟信号的编码/解码、时钟恢复、线路协商(如10/100/1000Mbps自适应)。
- MAC层(介质访问控制层):负责成帧、CRC校验、地址过滤、冲突检测(半双工)或流量控制(全双工)。
- DMA引擎与描述符环:负责在MAC层和主机内存之间高速搬运数据包,无需CPU逐字节干预。
下图展示了数据包从网线到达主机内存的完整硬件路径:
3.2 PHY层:模拟世界的守门员
PHY(Physical Layer)是网卡与物理介质的接口。驱动开发者通常不直接控制PHY的模拟电路,但需要通过MDIO/MDC总线(Management Data Input/Output)读写PHY寄存器,完成以下任务:
| 功能 | 说明 | 驱动关注点 |
|---|---|---|
| 链路检测 | 检测网线是否插入、对端是否协商成功 | 轮询PHY状态寄存器,触发中断或定时器 |
| 速率/双工协商 | 自动协商10/100/1000Mbps、全双工/半双工 | 读取协商结果,配置MAC层匹配 |
| 信号编码 | 将数字比特流编码为模拟信号(如MLT-3、PAM5) | 无需干预,硬件自动完成 |
| 中断上报 | 链路状态变化时向MAC/主机发送中断 | 注册中断处理函数,更新网络设备状态 |
3.3 MAC层:数据帧的加工厂
MAC(Media Access Control)层负责处理完整的以太网帧。从驱动角度看,MAC层提供以下关键能力:
- 帧封装/解封装:添加/移除前导码、帧起始定界符(SFD)、CRC校验码。
- 地址过滤:根据MAC地址表决定是否接收帧(单播、多播、广播、混杂模式)。
- 流量控制:支持暂停帧(Pause Frame)实现链路层流控。
- 统计计数器:记录收/发帧数、CRC错误、冲突次数等。
MAC层通过内部总线(如PCIe、AXI)与DMA引擎连接。驱动通过MMIO(Memory-Mapped I/O)读写MAC控制寄存器,配置MAC地址、帧过滤规则、中断使能等。
3.4 DMA引擎:数据搬运的核心
DMA(Direct Memory Access)引擎是网卡中最重要的性能模块。它负责在不占用CPU的情况下,将接收到的数据包从MAC层FIFO搬运到主机内存中的预分配缓冲区,或将待发送数据从主机内存搬运到MAC层FIFO。
DMA引擎的关键特性:
| 特性 | 描述 | 对驱动的影响 |
|---|---|---|
| 总线主控 | DMA引擎作为PCIe主设备发起读写事务 | 驱动需分配物理连续内存或使用IOMMU映射 |
| 描述符驱动 | DMA引擎通过读取描述符环获取传输参数 | 驱动必须正确初始化描述符环并通知硬件 |
| 中断聚合 | 可配置每N个包或每T微秒产生一次中断 | 减少CPU中断负载,但增加延迟 |
| 校验和卸载 | 硬件自动计算/校验IP/TCP/UDP校验和 | 驱动需在描述符中标记卸载标志 |
dma_alloc_coherent)或流式DMA映射(如dma_map_single),并确保缓冲区在DMA操作期间不被CPU缓存污染。
3.5 描述符环(Descriptor Ring):驱动与硬件的契约
描述符环是驱动与DMA引擎之间共享的环形数据结构,位于主机内存中。每个描述符(Descriptor)描述一个数据包缓冲区的位置、长度、状态和控制信息。描述符环是驱动与硬件通信的核心通道。
3.5.1 描述符结构
一个典型的接收描述符包含以下字段(以Intel I210为例):
struct rx_desc {
__le64 addr; // 缓冲区物理地址(64位)
__le16 length; // 接收到的数据长度(由硬件写入)
__le16 csum; // 校验和状态
__le8 status; // 完成状态(DD位:描述符完成)
__le8 errors; // 错误标志
__le16 special; // VLAN/哈希等信息
} __attribute__((packed));
发送描述符类似,但包含命令字段(如插入校验和、报告完成等)和数据长度(由驱动写入)。
3.5.2 环的工作原理
描述符环是一个循环队列,驱动和硬件通过头指针(Head)和尾指针(Tail)协作:
- 驱动在环中填充空闲描述符,指向可用的DMA缓冲区,然后更新尾指针寄存器通知硬件。
- DMA引擎从尾指针位置开始读取描述符,执行DMA传输,完成后设置描述符的完成位(DD)。
- 驱动在中断处理或轮询中扫描描述符环,找到DD位为1的描述符,处理数据包,然后回收描述符供硬件重用。
3.6 各模块协同工作流程
以接收一个以太网帧为例,完整流程如下:
| 步骤 | 执行者 | 操作 |
|---|---|---|
| 1 | PHY | 接收模拟信号,解码为数字比特流,恢复时钟 |
| 2 | MAC | 检测帧起始,去除前导码和SFD,进行CRC校验 |
| 3 | MAC | 检查目的MAC地址是否匹配(或混杂模式),通过则送入FIFO |
| 4 | DMA引擎 | 从描述符环读取下一个空闲描述符,获取缓冲区物理地址 |
| 5 | DMA引擎 | 通过PCIe总线将FIFO中的数据写入主机内存缓冲区 |
| 6 | DMA引擎 | 更新描述符状态(写入长度、设置DD位),可选触发中断 |
| 7 | 驱动 | 在中断处理或NAPI轮询中扫描描述符环,处理数据包 |
| 8 | 驱动 | 将数据包上送网络协议栈,回收描述符供硬件重用 |
3.7 本章小结
网卡硬件架构的核心是分层协作:PHY处理模拟信号,MAC处理数据帧,DMA引擎通过描述符环与主机内存交互。驱动开发者的主要战场在描述符环的管理和DMA缓冲区的分配/回收。理解这些硬件模块的角色和交互方式,是后续实现环形缓冲区驱动的基础。
| 模块 | 驱动交互方式 | 关键寄存器/数据结构 |
|---|---|---|
| PHY | MDIO/MDC总线读写PHY寄存器 | PHY ID寄存器、链路状态寄存器 |
| MAC | MMIO读写MAC控制寄存器 | MAC地址寄存器、帧过滤寄存器、中断寄存器 |
| DMA引擎 | 通过描述符环间接控制 | 描述符基址寄存器、头/尾指针寄存器、中断聚合寄存器 |
| 描述符环 | 驱动分配并维护环形队列 | 描述符数组(主机内存)、DD位、缓冲区地址 |