一、引言:驱动开发绕不开的硬件基础
网络接口卡(NIC, Network Interface Card)是现代嵌入式设备与计算平台不可或缺的通信媒介。在 Linux 内核中,网卡驱动属于最活跃的子系统之一,其涉及内容既包括内核的 Netdevice 框架、DMA 缓存管理、软中断等,也深度依赖对底层硬件结构的理解。
本文聚焦于网卡驱动相关的硬件知识点,从 PHY、MAC、接口协议、常用芯片、硬件初始化、地址配置、电路设计,到与驱动代码的衔接,力求讲清原理、用词准确,并辅以清晰的示意和示例,为后续软件驱动的理解打下扎实基础。
二、网络硬件基本结构
2.1 MAC 与 PHY 分层架构
现代以太网接口一般分为:
- MAC(Media Access Control):媒体访问控制层,通常集成在 SoC/主芯片内,负责帧的组织、CRC校验、DMA传输等。
- PHY(Physical Layer Transceiver):物理层收发器,负责信号编码、解码、电平转换,与 RJ45 接口连接。
这两者之间通过标准的硬件接口进行通信,常见的包括:
接口 | 位宽 | 速率支持 | 特征信号线 |
---|---|---|---|
MII | 4 bit | 10/100 Mbps | TXD[3:0] , RXD[3:0] , TX_CLK , RX_CLK , CRS , COL |
RMII | 2 bit | 10/100 Mbps | TXD[1:0] , RXD[1:0] , REF_CLK , CRS_DV |
RGMII | 4 bit DDR | 1 Gbps | TXD[3:0] , RXD[3:0] , TX_CTL , RX_CTL , TXC , RXC |
2.2 PHY芯片功能与种类
常见的 Ethernet PHY 芯片有:
芯片型号 | 接口类型 | 支持速率 | 典型应用 |
---|---|---|---|
LAN8720A | RMII | 10/100Mbps | STM32、NXP i.MX RT |
KSZ8081 | RMII | 10/100Mbps | 嵌入式开发板常见 |
RTL8211F | RGMII | 10/100/1000Mbps | 千兆以太网应用 |
PHY 芯片除数据收发外,还支持:
- 自动协商(Auto-Negotiation):协商速率和双工模式;
- 链路检测(Link Detection):通过 Link LED 显示;
- 寄存器控制:可通过 MDIO 接口配置和读取。
三、常见网卡硬件电路结构
以 LAN8720A 为例,其典型原理图包含如下关键部分:
3.1 电源供电与LDO去耦
- VDDIO、VDDA:分别供给 IO 和模拟电路;
- LDO_CAP:内部1.2V稳压输出,用于模拟核心;
- 推荐使用 0.1μF 与 4.7μF 并联电容去耦;
- 多数 PHY 要求上电顺序满足 0~50ms 范围内一致上电。
3.2 MAC-PHY 接口(RMII)
MCU/SoC PHY芯片(LAN8720A)
--------- -------------------
ENET_TXD0 ----------- TXD0
ENET_TXD1 ----------- TXD1
ENET_TX_EN ----------- TXEN
ENET_RXD0 ----------- RXD0
ENET_RXD1 ----------- RXD1
ENET_CRS_DV ----------- CRS_DV
ENET_REF_CLK ----------- REF_CLK
REF_CLK 是 50MHz 时钟源,必须稳定。
3.3 MDIO/MDC 管理接口
用于配置 PHY 寄存器,如读取 PHY 状态、控制速度/双工、查看链路状态等。
MCU/SoC PHY芯片
--------- --------
ENET_MDIO -----------> MDIO
ENET_MDC -----------> MDC
这些线连接到驱动的 phy_device
模块,通过 phy_read()
、phy_write()
进行访问。
3.4 RESET 引脚与地址配置
RESETn
需延时释放;PHYAD0 ~ PHYAD4
决定该 PHY 的地址;- 默认地址一般为 0x0,也可通过上拉/下拉电阻设置;
- 多 PHY 系统中,地址不可重复。
四、MAC 地址的来源与配置机制
4.1 MAC 地址是什么?
MAC(Media Access Control)地址是 48 位的唯一硬件地址,用于二层通信,格式如:
00:1A:2B:3C:4D:5E
前 3 字节代表厂商 OUI,后 3 字节是设备序列号。
4.2 MAC 地址的存储位置
存储方式 | 优先级 | 说明 |
---|---|---|
EEPROM / EFUSE | 高 | 大多数量产板卡使用 |
Bootloader 环境变量 | 中 | 通过 U-Boot 的 ethaddr |
内核设备树设置 | 中 | local-mac-address 节点 |
驱动代码硬编码或动态生成 | 低 | 开发阶段常见 |
在设备树中设置示例(适用于 i.MX 系列):
&fec1 {
phy-handle = <ðphy0>;
local-mac-address = [00 11 22 33 44 55];
};
五、硬件设计注意事项
5.1 差分线布局规则(RGMII/RMII)
- 差分对阻抗:100Ω;
- 单端线阻抗:50Ω;
- 差分对内匹配:线长误差不超过 5mil;
- 与其他差分对间隔大于 50mil;
- 变压器(magnetics)距 PHY 芯片距离尽量小于 25mm;
5.2 上拉/下拉配置引脚
部分 PHY 芯片如 LAN8720A 启动时通过上拉/下拉电阻配置:
- 自动协商(Auto-Negotiation)
- 速度(10/100Mbps)
- 地址(PHYAD0~4)
需要在 RESETn 拉高前配置完成。
六、从硬件到驱动的衔接:Linux 中的 PHY 识别流程
在 Linux 网卡驱动中,通常使用 phylib
框架管理 PHY 芯片,流程如下:
- 网卡驱动注册
net_device
; - 绑定 MAC 控制器与 PHY(通过 device tree 或 platform data);
- 使用
of_phy_connect()
找到设备树中的 PHY 节点; - 内核通过 MDC/MDIO 读写寄存器确认 PHY;
- 初始化 PHY:协商速率、双工、启动链接;
- 注册中断或轮询链路状态。
七、实际案例分析:i.MX6 + KSZ8081 + RJ45 接口
原理图片段(简化)
- PHY:KSZ8081
- 接口:RMII
- MAC:i.MX6 内部的 FEC(Fast Ethernet Controller)
驱动流程简要
-
设备树绑定 MAC 与 PHY:
&fec1 { phy-handle = <&phy0>; }; &mdio { phy0: ethernet-phy@0 { reg = <0>; }; };
-
内核驱动调用
fec_probe()
; -
调用
of_phy_connect()
→phy_attach()
; -
MDC/MDIO 通信确认 PHY 存在;
-
完成 MAC 与 PHY 的连接和初始化。
八、调试建议与常见问题
问题 | 可能原因 | 检查建议 |
---|---|---|
无法识别 PHY | 地址错误 / MDC/MDIO 未连通 | 用 mdio-tool 或 phytool 探测 |
MAC 地址为 00:00:00:00:00:00 | 没有从 EEPROM/DT/Bootloader 读取成功 | 加设备树字段或设置 ethaddr |
不能上网 | PHY 未协商成功 / 网线问题 | 查看 ethtool 输出链路状态 |
PHY 不工作 | RESETn 未正确拉高 | 检查电平逻辑或延时是否足够 |
九、结语
要写好网卡驱动,光掌握软件 API 是远远不够的。理解网络硬件的基本结构,掌握 PHY 的初始化流程、电气连接方式、MAC 地址配置机制,能大幅提升定位问题的能力,并写出可靠、稳定的驱动程序。
未来的系列文章将进一步介绍:
- Linux 中 Netdevice 架构;
- PHY 驱动框架详解;
- 网卡中断处理机制;
- DMA 与网络缓冲区管理。
如果你正在做实际项目,欢迎在评论区交流你的硬件结构和遇到的问题,我会结合你的平台提供进一步建议。
如需配图版本(PDF/Markdown)、实际设备树示例或 RTL8211F/RGMII 相关内容,也可以告诉我,我可以后续帮你整理完善。是否需要我帮你生成 PDF 或 Markdown 格式版本?