以太网MAC-PHY简介
以太网接入是嵌入式系统最常见的功能之一。本篇整理 MAC、PHY、MII 接口的基本结构与工作原理,并深入 PHY 内部的 PCS / PMA / PMD 子层、4B/5B 与 MLT-3 编码、自协商(Auto-Negotiation)等核心机制,方便后续在驱动调试和硬件故障排查时快速参考。
参考文章:
一、网口的基本结构
网口由 CPU、MAC 和 PHY 三部分组成。DMA 控制器通常属于 CPU 的一部分,下图用虚线画出只是为了表示 DMA 控制器可能会参与到网口数据传输中。

对于这三部分,并不一定都是独立的芯片。根据组合形式,可分为以下几种类型:
- CPU 集成 MAC 与 PHY
- CPU 集成 MAC,PHY 采用独立芯片
- CPU 不集成 MAC 与 PHY,MAC 与 PHY 采用集成芯片
下面选用第 2 种方案做进一步说明。CPU 总线接口很常见,通常都会做成可以像访问内存一样去访问;MAC 与 PHY 之间的 MII 接口需要多做些说明。

虚框表示 CPU,MAC 集成在 CPU 中。PHY 芯片通过 MII 接口与 CPU 上的 MAC 连接。
二、MAC
MAC 的功能框图

如上图所示,以太网 MAC 芯片的一端接计算机 PCI 总线(或 CPU 内部总线),另外一端接到 PHY 芯片上。CPU 上有两组寄存器用于 MAC:
- 一组用于数据的收发,对应上面的 DMA
- 一组用于 MIIM,用于对 PHY 进行配置
这两组寄存器由于都在 CPU 上,配置方式与其他 CPU 寄存器一样,直接读写即可。数据的转发通过 DMA 完成。
MAC 的功能
MAC 属于 OSI 七层网络模型中的 数据链路层。数据链路层包含 MAC(介质访问控制)子层 和 LLC(逻辑链路控制)子层。
功能一:把数据封装成帧
包括对帧进行界定、实现帧同步、对目的 MAC 地址和源 MAC 地址进行处理,以及在与 PHY 发生传输错误时对帧进行处理。
MAC 从 PCI 总线(或 CPU 总线)收到 IP 数据包(或者其他网络层协议的数据包)后,会将其拆分并重新打包成数据帧。这个数据帧包括:
- 目标 MAC 地址
- 源 MAC 地址
- 数据包里面的协议类型
- DWORD(4 Byte)的 CRC 校验码
打包完成后,这些数据帧通过 MII 接口传递给 PHY。
当 MAC 接收到数据帧时,先做 CRC 校验:
- 如果 CRC 校验错误,则这一帧被丢弃
- 如果 CRC 校验正确,则去掉帧头和帧尾,得到数据包;然后通过标准接口将数据包传递到 TCP/IP 模型的网络层、传输层、应用层逐层处理,最终送到应用软件
功能二:对 PHY 进行控制
CPU 上有一组 MIIM 寄存器,MAC 通过它来控制 PHY(如读写 PHY 的内部寄存器、获取链路状态等)。
三、PHY
PHY 的功能框图

物理层位于 OSI 最底层,物理层协议定义电气信号、线的状态、时钟要求、数据编码和数据传输用的连接器。物理层的器件称为 PHY。
PHY 的功能
功能一:与 MAC 通过 MII 接口进行数据传递
PHY 在发送数据时,收到 MAC 过来的数据(对 PHY 来说,没有帧的概念,只是一串数据,不管地址、数据还是 CRC),每 4 bit 增加 1 bit 的检错码,然后把并行数据转化为串行流数据,再按照物理层的编码规则(如 4B/5B 编码)把数据编码,最后变为模拟信号送到双绞线上。
PHY 接收数据时的流程与之相反:模拟信号 → 解码 → 解扰 → 并串转换 → 通过 MII 接口送给 MAC。
功能二:CSMA/CD 的部分功能
PHY 还能实现 CSMA/CD 协议的一部分功能:
- 检测网络上是否有数据在传送,如果有就等待
- 一旦检测到网络空闲,再等待一个随机时间后将数据送出
- 如果两块网卡碰巧同时送出了数据,造成冲突,冲突检测机构可以检测到冲突
- 检测到冲突后,各等待一个随机时间重新发送
这个“随机时间”并不是常数。不同的时刻计算出的随机时间不同,并且采用多种退避算法(如二进制指数退避)来应对出现概率很低的同两台主机之间的二次冲突。
四、PHY 与 MAC 的通信接口
PHY 与 MAC 通过 MII(Media Independent Interface) 通信,包括两类信号:
- 数据接口:RX / TX 两条独立的通道
- 管理接口:由时钟信号和数据信号组成(MDC / MDIO),可用来控制和监视 PHY 的工作
在 MII 的基础上,后来又衍生出了以下几种接口:
| 接口 | 全称 | 特点 |
|---|---|---|
| MII | Media Independent Interface | 标准接口,信号线较多 |
| RMII | Reduced Media Independent Interface | 简化版 MII,信号线更少 |
| GMII | Gigabit Media Independent Interface | 千兆 MII |
| RGMII | Reduced Gigabit Media Independent Interface | 简化版千兆 MII |
五、深入 PHY:从 4B/5B 编码到自动协商
上面介绍的是 MAC / PHY 的基本结构和接口。下面深入 PHY 内部,解析信号是如何在双绞线上被可靠传输的。这一部分以 LAN9303(一个三端口以太网交换芯片)为例展开。
5.1 数据进入 PHY 的第一站:PCS 与 4B/5B 编码
当 MAC 层通过 MII、RMII 或 GMII 接口将数据帧发送给 PHY 时,数据首先进入的是 物理编码子层(Physical Coding Sublayer, PCS)。这是 PHY 的数字逻辑前端,负责一系列“格式化”操作。
对于 100Base-TX,PCS 层核心任务之一是执行 4B/5B 编码。为什么需要这个步骤?直接发送原始 NRZ 编码的数据会遇到两个问题:
- 直流平衡:原始数据中可能出现长连 0 或长连 1,导致信号中存在较大直流分量。网络变压器具有隔直特性,过大的直流分量会引起信号基线漂移。
- 时钟恢复:接收端需要从数据流中提取时钟信息同步采样,如果数据长时间不变,接收端的 PLL 可能失锁。
4B/5B 编码将每 4 bit 数据映射成 5 bit 码组,保证在任何码组中 0 和 1 的转换足够频繁(最多不超过 3 个连续相同比特),从而保证足够的跳变边沿用于时钟恢复,并减少直流偏移。
注意:对于千兆以太网(1000Base-T)使用 8B/10B 编码,原理类似但开销和逻辑更复杂。10Base-T(十兆)则使用 曼彻斯特编码。LAN9303 的每个端口独立支持 10/100 Mbps,因此其 PCS 层包含 4B/5B(100M)和曼彻斯特编码(10M)两套逻辑。
5.2 PMA:信号的整形与时钟关联
物理介质连接子层(PMA) 充当 PCS 和最终模拟前端之间的桥梁,核心职责与时钟和串行化密切相关:
- 并行转串行:将来自 PCS 的并行数据(如 5 bit 宽)转换成串行比特流
- 发送时钟合成:通常从 PHY 外接的参考时钟(如 25 MHz 晶振)通过 PLL 倍频产生所需的发送时钟(100Base-TX 需要 125 MHz)
- NRZI 编码:将数据信息承载在电平变化(边沿)上,为 MLT-3 编码做准备
接收路径上,PMA 的核心任务是 时钟和数据恢复(CDR)——从含有噪声和畸变的串行数据流中恢复出精确的采样时钟和数据比特。
实操心得:PHY 参考时钟至关重要。必须选择低抖动的晶振或时钟发生器,并确保时钟走线短、远离噪声源。时钟抖动过大会直接导致 PLL 输出时钟抖动增大,进而使发送信号的眼图闭合,接收端 CDR 困难。我曾遇到一个案例:设备在高温下网络时断时续,最终排查发现是时钟芯片的电源滤波不足,温度升高后时钟抖动超标。
5.3 PMD:扰码、MLT-3 编码与自适应均衡
数据流经过 PMA 串行化后,进入 物理介质相关子层(PMD),即 PHY 的模拟电路核心。其中最关键的三项技术:
5.3.1 扰码(Scrambling)
尽管 4B/5B 编码已经消除了长连 0/1,但其输出的码流仍可能呈现出周期性模式。这种周期性会在信号频谱上产生较强的离散谱线,导致 EMI 问题,并可能使接收端的自适应均衡器训练困难。
扰码器用一个伪随机二进制序列(PRBS)与发送数据进行异或运算,将原始数据“随机化”。接收端再用相同的 PRBS 序列进行解扰。
5.3.2 MLT-3 编码
100Base-TX 的标志性编码。NRZI 编码后的信号是二进制的,其基频分量在 62.5 MHz 左右(125 Mbaud 的一半)。MLT-3 采用三电平(+V, 0, -V)降低基频:
| 输入比特 | MLT-3 状态变化 | 输出电平 |
|---|---|---|
| 1 | 0 → +V | +V |
| 1 | +V → 0 | 0 |
| 1 | 0 → -V | -V |
| 1 | -V → 0 | 0 |
| 0 | 0 → 0 | 0 |
| 1 | 0 → +V | +V |
输出电平每次变化只移动到“下一个”电平,而不是在 +V 和 -V 之间直接跳变。基频大幅降低后,信号能在 Cat5 双绞线上传输更远的距离(100 米),同时显著降低 EMI。
5.3.3 自适应均衡与基线漂移校正
信号在双绞线中传输会随频率升高衰减加剧(皮肤效应),导致 码间干扰(ISI)。自适应均衡器 就是一个可调的滤波器,能够动态补偿线缆造成的频率失真,在接收端“打开”被闭合的信号眼图。
此外,MLT-3 编码不可能完全消除直流分量,变压器隔直后微小的直流不平衡会累积成接收信号基线的缓慢漂移。基线漂移校正 电路会动态监测并补偿这种漂移。
踩坑记录:自适应均衡器的性能与链路训练过程紧密相关。如果链路噪声极大或训练序列受到严重干扰,可能导致均衡器收敛到错误的参数上,造成链路虽能建立但误码率奇高。我曾调试过一个工业现场设备,网线靠近大功率电机,链路时通时断,后来强制将 PHY 配置为 10M 全双工模式(信号频率更低、抗干扰更强)解决了问题。
六、自动协商(Auto-Negotiation)
自协商的目标是让链路两端的设备在不依赖人工配置的情况下,自动选择双方都支持的最高性能通信模式(速率、双工)。
6.1 协商载体:FLP 脉冲
在链路未建立时,PHY 周期性地发送 快速链路脉冲(FLP)。一个 FLP 突发由 33 个脉冲位置组成,持续约 2 ms:
- 17 个时钟脉冲(奇数位)—— 等间距排列,提供定时基准
- 16 个数据脉冲(偶数位)—— 存在与否代表逻辑 1 / 0
17 个时钟脉冲 + 16 个数据脉冲共同编码了一个 16 位的 链路码字(Link Code Word):
| 位 | 字段 | 含义 |
|---|---|---|
| 15:0 | Selector Field | 选择器(如 IEEE 802.3) |
| 14:13 | Technology Ability | 技术能力(如 100BASE-TX FD) |
| 12 | Remote Fault | 远程故障指示 |
| 11 | Acknowledgment | 确认位 |
| 10 | Next Page | 下一页指示 |
6.2 三次握手流程
- 能力宣告:每个设备持续发送 FLP,其中包含自己的技术能力码字(Ack 位 = 0)
- 能力接收与确认:当设备连续收到 3 个完全相同的、包含对端能力的 FLP 后,它在发送的 FLP 中将 Ack 位置 1
- 共识与链路建立:两端都确认对端能力时,按预定义优先级(100BASE-TX 全双工 > 100BASE-TX 半双工 > 10BASE-T 全双工 > 10BASE-T 半双工)选择双方都支持的最高优先级模式
6.3 常见故障模式
一端强制,一端协商
经典问题:交换机端口强制为 100M 全双工,电脑网卡自动协商。强制端不发 FLP,只发 IDLE 信号。协商端会进入“并行检测”模式,它只能检测出速率(100M),但无法知道双工模式。作为保守策略,它会降级为半双工。
后果:双工不匹配。一端全双工,一端半双工,网络速度极慢、丢包严重。全双工端可以同时收发,半双工端发送时会阻塞接收,造成冲突和帧丢弃。
FLP 脉冲受干扰
电源噪声或数字信号串扰干扰敏感的模拟电路,导致 FLP 脉冲畸变。表现为链路反复 Up / Down,或者根本无法建立。
PHY 寄存器配置错误
错误地禁用了自协商(AN_ENABLE = 0),或错误地限制了自协商通告的能力(如只通告 10M 模式),就会导致协商结果不符合预期。
6.4 调试建议
- 先看 Link 灯:Link 灯不亮,问题多在物理层(FLP、电缆、端口)
- 用
ethtool eth0查看协商结果:能清晰显示当前链路的速率、双工模式以及自协商是否开启,这是判断双工是否匹配的最快方法 - 统一两端配置:最简单的做法是将两端都设置为“自动协商”。如必须强制,确保两端强制为相同的速率和双工模式
- 示波器观察 FLP:在链路未建立时,应该能看到周期性的约 2 ms 一组的 FLP 脉冲串。观察其幅度、形状是否规整,这是诊断物理层问题的终极手段
七、LAN9303 PHY 寄存器配置要点
LAN9303 的配置和管理主要通过 SMI(MDC / MDIO)接口进行。每个端口的 PHY 都有独立的寄存器组,地址通常为 0、1、2。
7.1 关键寄存器
| 寄存器 | 地址 | 关键位 | 说明 |
|---|---|---|---|
| BMCR(基本控制) | 0x00 | AN_ENABLE (位 12) | 必须置 1 以使能自协商 |
| BMCR | 0x00 | SPEED_SELECT (位 8) / DUPLEX_MODE (位 6) | AN_ENABLE = 0 时用于强制设置速率和双工;开启自协商时切勿同时设置 |
| BMCR | 0x00 | RESTART_AN (位 9) | 写入 1 可重启自协商 |
| BMSR(基本状态) | 0x01 | AUTO_NEGOTIATION_COMPLETE (位 5) | 判断自协商是否完成 |
| BMSR | 0x01 | AUTO_NEGOTIATION_ABILITY (位 3) | 判断本端是否支持自协商 |
| BMSR | 0x01 | LINK_STATUS (位 2) | 最重要的位之一,判断物理链路是否已建立 |
| ANAR(自协商通告) | 0x04 | Technology Ability 位 | 配置本端要向对端通告的能力 |
7.2 典型问题排查链路
假设遇到“LAN9303 某个端口 Link 灯不亮”的问题,可按以下链路排查:
软件配置检查
- 通过 MDIO 读取 BMCR,确认
AN_ENABLE是否为 1 - 读取 BMSR,查看
LINK_STATUS和AUTO_NEGOTIATION_COMPLETE - 如果自协商未完成,检查 ANAR 是否合理(是否支持任何模式)
- 通过 MDIO 读取 BMCR,确认
物理连接检查
- 更换网线,排除网线故障
- 检查对端设备端口状态和配置
- 使用电缆测试仪检查线缆的连通性、长度和串扰
硬件电路检查
- 电源与复位:测量 PHY 的 AVDD、DVDD 是否稳定(通常要求纹波 < 50 mV);检查复位信号时序
- 时钟:测量输入时钟波形和频率精度,确保时钟抖动在 ps 级别
- 网络变压器与匹配:检查变压器中心抽头的对地去耦电容(通常 0.1 μF + 10 μF)是否良好;TX/RX 差分线是否严格差分走线,阻抗是否控制在 100 Ω ± 10%;检查 BOB-SMITH 终端电路(75 Ω 电阻串联 0.01 μF 电容到地)是否正确
- MDIO 上拉:MDC 和 MDIO 信号线通常需要上拉电阻(如 1.5 kΩ ~ 4.7 kΩ)
信号观测
- 在端口未连接时,用差分探头测量 TX+ 和 TX-。应该能看到周期性的 FLP 脉冲串。如果没有,可能是 PHY 未工作或发送通道损坏
- 连接对端设备后,观察链路建立瞬间的信号变化,是否从 FLP 切换成了连续的数据/空闲信号