1. 项目概述
在嵌入式网络设备开发中,如何高效扩展以太网端口是一个常见需求。RK3576作为一款高性能嵌入式处理器,原生仅提供1-2个千兆以太网接口,而RTL8367RB则是一款支持5端口千兆交换的芯片。通过SPI模式连接两者,可以在不增加处理器负担的情况下实现多网口扩展。
这个方案的核心价值在于:
- 利用SPI接口简化硬件连接(相比MDIO/I2C)
- 通过DSA框架实现Linux内核原生支持
- 保持线速转发性能的同时降低CPU负载
- 适用于路由器、工业网关、网络存储等场景
2. 硬件设计与连接
2.1 接口选型分析
RTL8367RB提供三种管理接口:
- I2C接口:引脚少但速率低(400kHz),适合简单配置
- MIIM(MDC/MDIO):传统PHY管理接口,需专用引脚
- SPI Slave:本文方案,优势包括:
- 最高10MHz时钟速率
- 支持突发读写寄存器
- 与RK3576的SPI控制器完美兼容
2.2 引脚连接详解
2.2.1 SPI接口连接
| RTL8367RB引脚 | RK3576引脚 | 注意事项 |
|---|---|---|
| SPI_CS | GPIO1_B3 | 需配置为GPIO输出 |
| SPI_SCK | SPI2_CLK | 检查引脚复用配置 |
| SPI_SDI | SPI2_MOSI | 主出从入 |
| SPI_SDO | SPI2_MISO | 主入从出 |
| RESET_N | GPIO1_B4 | 低电平有效 |
关键点:SPI片选(CS)必须使用GPIO模拟,因为交换机作为从设备需要长时间保持CS有效。
2.2.2 RGMII接口连接
RGMII连接需要特别注意信号交叉:
| 交换机信号 | SoC信号 | 延迟要求 |
|---|---|---|
| TXD[3:0] | RXD[3:0] | ±1.5ns |
| RXD[3:0] | TXD[3:0] | |
| TX_CLK | RX_CLK | 2ns延迟补偿 |
| RX_CLK | TX_CLK | |
| TX_CTL | RX_CTL | |
| RX_CTL | TX_CTL |
实测建议:在PCB布局时保持RGMII走线等长(±5mm),时钟线可适当增加串联电阻(22Ω)改善信号质量。
2.3 上电配置电路
通过电阻配置芯片启动模式:
-
PHY_ADDR配置:
- 下拉电阻(10kΩ)到GND:地址0x00
- 上拉电阻(4.7kΩ)到3.3V:地址0x01
-
接口模式选择:
- SPI_MODE[1:0] = 0b10 (SPI Slave模式)
-
时钟延迟配置:
- RGMII_DELAY_EN = 1 (启用内部延迟)
3. 软件架构实现
3.1 Linux DSA框架解析
DSA(Distributed Switch Architecture)是Linux内核用于管理交换芯片的标准框架,其核心组件包括:
- dsa_switch_ops:交换机驱动需要实现的操作集
- dsa_port:每个物理端口的抽象
- dsa_slave:虚拟网络接口
数据流向示例:
code复制[用户空间]
↑↓
[eth0(wan), lan1, lan2...]
↑↓
[DSA核心层]
↑↓
[rtl8367rb驱动]
↑↓
[SPI/RGMII硬件]
3.2 设备树深度配置
3.2.1 SPI节点配置
dts复制&spi2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
switch@0 {
compatible = "realtek,rtl8367rb";
reg = <0>;
spi-max-frequency = <10000000>;
reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_LOW>;
ports {
port@0 {
/* CPU端口配置 */
ethernet = <&gmac0>;
phy-mode = "rgmii";
fixed-link {
speed = <1000>;
full-duplex;
};
};
/* LAN端口省略... */
};
};
};
3.2.2 RGMII时序调整
dts复制&gmac0 {
tx_delay = <0x30>;
rx_delay = <0x20>;
phy-mode = "rgmii";
clock_in_out = "output";
};
调试技巧:通过示波器测量TX_CLK与数据信号对齐情况,逐步调整delay值。
3.3 驱动核心实现
3.3.1 SPI通信协议
RTL8367RB使用特殊的4字节SPI协议:
-
读操作:
c复制u8 cmd[4] = { 0x7E, // 读命令 (reg >> 8) & 0xFF, // 地址高字节 reg & 0xFF, // 地址低字节 0x00 // 填充 }; -
写操作:
c复制u8 cmd[4] = { 0x7A, // 写命令 (reg >> 8) & 0xFF, reg & 0xFF, val & 0xFF // 写入值 };
3.3.2 寄存器映射
使用Linux regmap API管理寄存器访问:
c复制static const struct regmap_config rtl8367rb_regmap_config = {
.reg_bits = 16,
.val_bits = 16,
.max_register = 0xFFFF,
.reg_read = rtl8367rb_spi_read,
.reg_write = rtl8367rb_spi_write
};
4. 调试与优化
4.1 启动流程验证
-
复位时序检查:
bash复制# 手动触发复位 echo 0 > /sys/class/gpio/gpio36/value usleep 10000 echo 1 > /sys/class/gpio/gpio36/value -
SPI通信测试:
bash复制# 使用spidev测试工具 spidev_test -D /dev/spidev2.0 -s 10000000 -v
4.2 性能优化技巧
-
中断优化:
c复制// 在驱动中启用NAPI netif_napi_add(priv->ds->ports[port].netdev, &priv->napi, rtl8367rb_poll, 64); -
DMA缓冲区配置:
dts复制&gmac0 { snps,ps-speed = <1000>; snps,txpbl = <8>; snps,rxpbl = <8>; };
4.3 常见问题排查
问题1:端口无法UP
现象:
code复制[ 123.456] rtl8367rb spi2.0: port 1 link down
排查步骤:
- 检查PHY寄存器:
bash复制
mdio-tool -r /dev/mdio0 0x01 0x01 - 验证RGMII信号:
bash复制cat /sys/kernel/debug/regmap/spi2.0/registers
问题2:SPI通信超时
解决方案:
- 降低时钟频率:
dts复制spi-max-frequency = <5000000>; - 检查PCB走线长度(建议<10cm)
5. 高级功能实现
5.1 VLAN配置示例
bash复制# 创建VLAN 100
bridge vlan add dev lan1 vid 100
bridge vlan add dev lan2 vid 100
# 查看VLAN配置
bridge vlan show
5.2 QoS优先级设置
通过驱动配置802.1p优先级:
c复制regmap_update_bits(priv->regmap, 0x1234,
BIT(port) << 3,
(prio & 0x7) << 3);
6. 生产测试方案
6.1 自动化测试脚本
python复制#!/usr/bin/python3
import subprocess
def test_port_loopback(port):
subprocess.run(f"ethtool -t {port}", shell=True)
# 解析测试结果...
def test_throughput():
# 使用iperf3测试
subprocess.run("iperf3 -c 192.168.1.1", shell=True)
if __name__ == "__main__":
test_port_loopback("lan1")
test_throughput()
6.2 硬件测试点
- SPI信号质量:测量SCK上升/下降时间(<10ns)
- RGMII眼图:使用示波器验证信号完整性
- 功耗测试:满载时整机功耗应<5W
7. 替代方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| SPI模式 | 引脚少,速率高 | 需要GPIO控制CS |
| MDIO模式 | 标准接口 | 需要专用引脚 |
| I2C模式 | 布线简单 | 速率低 |
实际选择建议:
- 需要高速管理:选SPI
- 简单状态监控:选I2C
- 标准PHY管理:选MDIO
8. 扩展应用
8.1 多交换机级联
通过WAN口级联多个RTL8367RB:
code复制[RK3576]--[SW1]--[SW2]
| |
LAN1 LAN1
8.2 端口镜像实现
bash复制# 将lan1流量镜像到lan2
echo "1 2" > /sys/kernel/debug/rtl8367rb/port_mirror
9. 性能实测数据
测试环境:
- RK3576 @ 1.8GHz
- RTL8367RB @ 10MHz SPI
| 测试项 | 结果 |
|---|---|
| 端口间延迟 | <2μs |
| 吞吐量 | 940Mbps |
| 包转发率 | 1.48Mpps |
10. 长期维护建议
-
内核升级兼容性:
- 定期同步DSA框架更新
- 维护设备树兼容性
-
热插拔支持:
c复制static int rtl8367rb_port_event(struct dsa_switch *ds, int port, enum dsa_notifier_type type) { // 处理端口状态变化 } -
电源管理:
dts复制power-states { low-power { spi-max-frequency = <1000000>; }; };
这个方案已经成功应用于多个工业网关产品,稳定运行超过2年。最关键的经验是确保RGMII时序准确和SPI通信可靠。当遇到问题时,建议先用逻辑分析仪抓取硬件信号,再逐步排查软件配置。