2、网络基础回顾:OSI模型、TCP/IP协议栈、以太网帧格式、MAC与PHY的分工

网络设备驱动开发与PHY芯片调试,本质上是在与“网络数据通路”的底层硬件和协议栈打交道。无论是调试一个千兆网卡无法link up的问题,还是分析一条报文为何在驱动层被丢弃,都离不开对网络分层模型、以太网帧结构以及MAC与PHY职责边界的清晰认知。本章并非简单复述计算机网络教材,而是从驱动工程师与硬件调试者的视角,重新梳理这些基础概念,并重点剖析它们在实际工程中的映射关系。

MAC 与 PHY 在以太网链路中的分工与信号流向 OSI 模型 L7 应用层 L6 表示层 L5 会话层 L4 传输层 (TCP/UDP) L3 网络层 (IP) L2 数据链路层 (MAC) L1 物理层 (PHY) TCP/IP 协议栈 应用层 (HTTP/SSH) 传输层 (TCP/UDP) 网络层 (IP/ICMP) 网络接口层 (含 MAC + PHY 驱动) net_device / phy_device MAC 控制器 (集成在SoC/CPU) 负责:组帧/解帧、地址过滤、CRC校验、流控 MAC 核心功能 · 帧封装/解封装 · 目的MAC过滤 · CRC32 生成/校验 MAC-PHY 接口 MII / RMII / GMII RGMII / SGMII MDIO (管理接口) TX/RX PHY 芯片 (独立芯片或集成) 负责:编码/解码、串并转换、电平适配、时钟恢复、链路检测 PHY 核心功能 PCS / PMA / PMD 介质接口 RJ45 / 光纤 / 变压器 MDIO 管理通道 (寄存器读写) 驱动软件视角 net_device 结构体 phy_device 结构体 中断 / NAPI / DMA ethtool 调试接口 以太网帧格式 (DIX v2 / IEEE 802.3) 前导码 SFD 目的MAC (6B) 源MAC (6B) 类型/长度 Payload (46-1500B) FCS (4B) 图:MAC与PHY的分工、接口关系及以太网帧结构(驱动调试视角)

2.1 分层模型与驱动开发者的“关注边界”

核心原理:OSI与TCP/IP的工程映射

OSI七层模型是理论参考,而TCP/IP四层模型是实际运行的事实标准。对于网络设备驱动开发者而言,真正需要关注的是从“网络接口层”向下到物理介质的这一段。在Linux内核中,net_device结构体代表一个网络接口设备,它上承IP层(dev_queue_xmit发送、netif_rx接收),下接驱动提供的ndo_start_xmit和中断处理函数。而phy_device则通过MDIO总线管理PHY芯片的寄存器,负责链路状态、速率、双工模式、自动协商等物理层参数的配置与监控。

理解分层的关键在于:驱动代码不应越界处理上层协议逻辑,也不应试图绕过PHY直接操作介质。例如,IP分片、TCP校验和是协议栈的工作;而曼彻斯特编码、MLT-3编码、线路电平转换则是PHY的工作。驱动开发者需要做的是正确初始化MAC控制器,配置DMA描述符,并通过MDIO读写PHY寄存器来获取链路状态。

判断方法:如何定位问题所在层

当网络不通时,工程师需要快速判断问题出在物理层、数据链路层还是上层协议。一个实用的排查顺序是:

  1. 物理层检查:使用ethtool eth0查看Link detected: yes/no。如果为no,则问题大概率在PHY、变压器、RJ45连接器或对端设备。
  2. 链路层检查:如果link up但ping不通,查看ip link show eth0确认MAC地址是否有效,ethtool -S eth0查看rx_crc_errors、rx_frame_errors等计数器。
  3. 网络层检查:使用ping网关地址,若不通则检查IP配置、路由表。

这种分层排查法能避免在错误的方向上浪费时间。例如,如果PHY没有link up,那么抓包分析IP层毫无意义。

案例拆解:一次“网卡灯亮但ping不通”的定位

某嵌入式设备使用RTL8211F PHY芯片与SoC内置GMAC连接。现场反馈网口指示灯亮,但无法ping通网关。初步判断物理层可能正常,但实际排查过程如下:

  • 第一步:执行ethtool eth0,输出显示Speed: 1000Mb/s,Duplex: Full,Link detected: yes。物理层看似正常。
  • 第二步:查看/proc/interrupts,发现网卡中断计数没有增加,说明驱动可能没有收到数据包。
  • 第三步:使用ethtool -S eth0查看统计,发现rx_crc_errors持续增长,而rx_packets为0。
  • 第四步:进一步检查PHY寄存器,发现RTL8211F的PHYCR1(寄存器0x1F)中,SELRGV位被错误配置为RGMII到MII的转换模式,导致MAC与PHY之间的接口模式不匹配。

最终通过修改设备树中phy-mode = "rgmii-id"并调整驱动初始化时序,问题解决。这个案例说明:即使链路层link up,MAC与PHY之间的接口配置错误也会导致数据通路异常,这正是驱动开发者需要同时理解MAC和PHY的原因。

常见误区:不要认为“PHY link up”就等于“网络可用”。PHY只负责物理信号的建立,而MAC还需要正确配置接口模式(MII/RGMII/SGMII)、时钟延迟(TX delay/RX delay)、以及DMA描述符。很多调试者看到link灯亮就放弃检查物理层,转而盲目抓包,浪费大量时间。

2.2 以太网帧格式:驱动收发缓冲区的“字节视图”

核心原理:帧结构各字段的硬件处理边界

以太网帧是MAC层处理的基本单位。标准DIX v2帧格式包含:前导码(7字节)、帧起始定界符SFD(1字节)、目的MAC地址(6字节)、源MAC地址(6字节)、类型/长度字段(2字节)、负载(46-1500字节)、帧校验序列FCS(4字节)。在驱动开发中,需要特别注意:前导码和SFD由PHY硬件生成或移除,FCS通常由MAC硬件计算和校验。因此,驱动软件在发送时只需要提供从目的MAC到负载的数据;在接收时,驱动拿到的数据包已经去除了前导码和FCS(除非开启CRC offload并选择保留)。

对于接收路径,MAC控制器会根据目的MAC地址进行过滤(单播、组播、广播、混杂模式)。驱动需要正确设置net_device的flags(如IFF_PROMISC)来影响MAC的过滤行为。此外,最小帧长64字节(不含前导码)的约束意味着如果上层负载不足46字节,MAC硬件会自动填充Padding字节。驱动在计算DMA缓冲区大小时,必须考虑这个填充。

操作流程:从DMA描述符到sk_buff的映射

在Linux驱动中,接收路径的典型流程是:

  1. 驱动在初始化时分配DMA接收缓冲区,并建立描述符环。
  2. MAC收到帧后,通过DMA将数据写入缓冲区,并更新描述符状态位。
  3. 驱动在NAPI poll函数中检查描述符,若OWN位被清0(表示CPU拥有数据),则构造sk_buff,调用eth_type_trans识别协议类型,最终交给netif_receive_skb。
  4. 驱动需要重新分配新的缓冲区并挂入描述符,以维持接收环的连续性。

发送路径则相反:驱动从ndo_start_xmit拿到sk_buff,将其映射到DMA地址,填充发送描述符,并触发MAC发送。发送完成后,中断处理程序负责释放sk_buff并回收DMA映射。

实战场景:抓包分析中的帧字段解读

使用Wireshark或tcpdump抓包时,看到的帧通常已经去除了前导码和FCS。例如,一个典型的ARP请求帧:

ff:ff:ff:ff:ff:ff > 00:11:22:33:44:55, ethertype ARP (0x0806), length 42:
  arp who-has 192.168.1.1 tell 192.168.1.100

这里ff:ff:ff:ff:ff:ff是广播目的MAC,0x0806是EtherType字段,表示上层为ARP协议。驱动开发者需要理解:EtherType大于等于0x0600时表示上层协议类型,小于该值时表示负载长度(802.3格式)。在驱动中,eth_type_trans函数正是通过判断这个字段来决定sk_buff->protocol的值。

经验提醒:在调试DMA环异常时,可以打印接收描述符中的length字段,与抓包工具显示的帧长度对比。如果驱动报告的length比实际抓包长度多4字节,说明MAC保留了FCS;如果少4字节,说明FCS已被硬件剥离。这种细微差异往往是驱动与硬件行为不匹配的线索。

2.3 MAC与PHY的分工:从寄存器到信号

核心原理:职责边界与接口信号

MAC(Media Access Control)和PHY(Physical Layer)是数据链路层与物理层的典型分工。MAC负责逻辑功能:帧的封装与解封装、地址过滤、流控(PAUSE帧)、以及CRC校验。PHY负责物理功能:数据的编码(如8B/10B、64B/66B)、串并转换、模拟信号驱动、时钟恢复、以及自动协商(Auto-Negotiation)。两者之间通过标准接口连接,常见的有:

接口类型数据位宽时钟频率引脚数典型应用
MII4位25MHz (100Mbps)16旧式100M以太网
RMII2位50MHz7低成本100M方案
GMII8位125MHz24千兆以太网
RGMII4位125MHz (DDR)12主流千兆SoC方案
SGMII1位串行1.25Gbps4高速背板/交换芯片

除了数据接口,MAC与PHY之间还有一条管理接口——MDIO(Management Data Input/Output),用于读写PHY的寄存器。MDIO由两根线组成:MDC(时钟)和MDIO(数据),通过它驱动可以读取PHY的状态(如链路状态、协商结果)或配置PHY的工作模式(如强制百兆全双工)。

判断方法:通过寄存器区分MAC与PHY问题

当网络异常时,可以通过以下寄存器快速定位:

  • PHY寄存器0(BMCR):控制复位、回环、速率、自动协商开关。
  • PHY寄存器1(BMSR):指示链路状态、协商完成、支持的能力。
  • MAC寄存器(如DMA控制、中断状态):反映MAC侧FIFO状态、DMA错误、帧接收计数。

例如,如果BMSR的bit2(Link Status)为0,说明PHY没有检测到对端信号,问题在物理介质或对端设备。如果Link Status为1但MAC的接收计数不增加,则问题可能在MAC配置或DMA环。

案例拆解:RGMII接口的时钟延迟调试

某项目使用i.MX6ULL SoC内置MAC搭配KSZ8081 PHY,采用RGMII接口。板卡量产时发现部分设备千兆协商失败,百兆正常。分析过程:

  • 现象:约5%的板卡在千兆模式下ping丢包严重,降级到百兆后稳定。
  • 关键数据:通过MDIO读取PHY寄存器,发现协商结果为1000Mbps Full,但BMSR的链路状态不稳定,频繁翻转。
  • 分析:RGMII接口在千兆模式下使用DDR采样(上升沿和下降沿都采样),对时钟延迟非常敏感。SoC的TX_CLK与PHY的RX_CLK之间需要满足建立/保持时间。由于PCB走线长度差异,部分板卡的时钟延迟不满足要求。
  • 操作步骤:在设备树中调整phy-mode为rgmii-id(内部延迟),或在驱动中通过PHY寄存器配置TX/RX delay。最终通过软件配置KSZ8081的pad skew寄存器,将TX delay增加0.2ns,问题解决。

这个案例说明:MAC与PHY之间的接口不仅仅是逻辑连接,还涉及高速信号的时序完整性。驱动开发者需要理解RGMII的时序要求,并知道如何通过寄存器调整延迟。

风险提示:不要随意修改PHY的延迟配置。过大的TX delay会导致对端接收错误,过小的delay则无法满足建立时间。建议在调试时使用示波器测量RGMII接口的时钟与数据相位关系,以数据手册的时序参数为基准进行微调。

2.4 常见误区与总结复盘

误区一:混淆MAC地址过滤与IP层过滤

MAC地址过滤是硬件行为,发生在数据进入DMA之前。如果目的MAC不是本机地址(且未开启混杂模式),帧会被MAC直接丢弃,驱动根本看不到。而IP层过滤是软件行为,发生在netif_receive_skb之后。调试时,如果发现驱动收不到某些报文,先检查MAC过滤配置,而不是怀疑IP层。

误区二:忽视PHY的自动协商与主从配置

对于千兆以太网,PHY之间的自动协商不仅包括速率和双工,还包括Master/Slave时钟配置。如果两个PHY都配置为Master,会导致时钟冲突,链路无法建立。驱动开发者需要确保PHY的Master-Slave配置正确,通常建议设置为自动协商模式。

误区三:将FCS错误全部归咎于物理层

虽然FCS错误通常由信号质量差引起,但MAC侧的DMA配置错误(如缓冲区长度不足)也可能导致接收帧被截断,从而产生FCS错误。排查时应同时检查PHY的信号完整性和MAC的DMA配置。

总结复盘

本章的核心在于建立“分层调试”的思维框架。驱动开发者必须清楚:PHY负责让信号在介质上可靠传输,MAC负责让数据在逻辑上正确交换。当问题出现时,先通过ethtool确认物理层状态,再通过寄存器区分MAC与PHY的故障边界,最后结合帧格式分析数据通路的正确性。这种系统化的方法能显著缩短排障时间,避免在错误层次上反复尝试。

关键要点回顾:
  • OSI模型是参考,TCP/IP是现实;驱动开发聚焦网络接口层及以下。
  • 以太网帧的前导码和FCS由硬件处理,驱动只关心从目的MAC到负载的部分。
  • MAC与PHY通过MII/RGMII/SGMII等接口连接,MDIO是管理通道。
  • RGMII的时钟延迟是千兆调试的高频故障点,需结合示波器和寄存器调整。
  • 分层排查法:物理层(link状态)→ 链路层(MAC计数)→ 网络层(ping)→ 应用层。