3. PFE固件与驱动加载

S32G 的 PFE(Packet Forwarding Engine)并不是一块“上电即用”的以太网外设,它内部包含可编程的包处理引擎、分类器、HIF 主机接口以及多个 MAC,必须先把固件镜像加载到 PFE 的指令/数据存储区,再由 Linux 驱动完成初始化,数据平面才真正开始工作。理解“固件怎么组成、怎么被加载、驱动如何接管、设备树如何描述、版本如何匹配”这五件事,是后续所有路由与转发调试的前提。

一、固件镜像的组成

PFE 固件通常以 pfe_fw.bin 或类似命名的二进制形式提供,它并不是一段单一代码,而是由多个逻辑段拼接而成。典型组成包括:

  • 固件头(Header):描述镜像版本、目标芯片型号、段数量与校验信息,驱动在加载前会先解析它,用于判断“这份固件是否适用于当前 SoC”。
  • 指令段(Text/Code):PFE 内部处理器执行的包处理微码,决定分类、转发、VLAN、校验和卸载等行为。
  • 数据段(Data):初始化常量、默认表项、缓冲区描述符模板等。
  • 表项/配置段:分类表、路由表初始结构、HIF 通道配置等,驱动在启动阶段会在此基础上继续写入运行时表项。

需要强调的是,固件镜像与驱动是配套发布的:同一份固件往往要求特定版本的驱动与设备树节点结构。把不同来源的固件和驱动混用,最常见的现象就是 PFE 探测失败或 MAC 无法 up。

二、启动流程:从上电到数据平面可用

PFE 的启动可以理解为一条“先复位、再加载、后使能”的链路。上电或复位后,PFE 处于复位/空闲状态,此时它不会转发任何报文。Linux 启动过程中,PFE 驱动被 probe,驱动按以下顺序推进:

  1. 解析设备树节点,获取寄存器基址、中断、时钟、复位、固件文件名等资源。
  2. 使能时钟与电源域,释放复位,确认 PFE 处于可访问状态。
  3. 通过 request_firmware() 从根文件系统加载固件镜像到内核内存。
  4. 校验固件头,将各段写入 PFE 对应的存储区,并触发固件启动。
  5. 等待固件就绪信号,初始化 HIF 通道、MAC 与分类器,注册网络设备。

只有走完第 5 步,ip link 才能看到 PFE 对应的网络接口,数据平面才具备转发能力。

PFE 固件加载与驱动接管链路 固件镜像 pfe_fw.bin Header(版本/型号) Text(包处理微码) Data(常量/描述符) Tables(分类/路由表) request_firmware Linux PFE 驱动 probe 解析设备树资源 时钟/复位/电源使能 写入固件各段 等待固件就绪 of_* 读取 设备树 pfe 节点 compatible reg / interrupts clocks / resets firmware-name 版本匹配 FW 版本 驱动版本 DT 兼容串 SoC 型号 启动状态推进 复位/空闲 PFE 不转发 固件已加载 等待就绪信号 HIF/MAC 初始化 注册 netdev 接口 up 数据平面可用 转发 报文

三、Linux 驱动加载与设备树配置

在 Linux 侧,PFE 通常由 pfe 驱动模块(如 pfe.ko)与网络驱动协同工作。设备树节点是驱动与硬件之间的“契约”,关键属性包括:

  • compatible:必须与驱动中匹配表一致,例如 "nxp,s32g-pfe",否则 probe 不会触发。
  • reg:PFE 寄存器基址与长度,驱动据此映射寄存器空间。
  • interrupts:HIF 与 MAC 的中断号,缺失会导致收发中断无法注册。
  • clocks、resets:时钟与复位句柄,驱动在 probe 中按序使能。
  • firmware-name:指定固件文件名,驱动据此调用 request_firmware()。

一个简化的设备树片段如下(示例,实际以板级 DTS 为准):

pfe: ethernet@40400000 {
    compatible = "nxp,s32g-pfe";
    reg = <0x0 0x40400000 0x0 0x100000>;
    interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clk_pfe>;
    resets = <&rst_pfe>;
    firmware-name = "pfe_fw.bin";
    status = "okay";
};

驱动加载后,可通过 dmesg | grep -i pfe 观察 probe 日志,确认固件是否加载成功、HIF 通道是否建立。若日志停在“waiting for firmware ready”,通常说明固件未正确写入或版本不匹配。

四、固件版本匹配与常见问题

固件版本匹配是本节最容易踩坑的地方。判断依据主要有三:

  1. SoC 型号匹配:S32G2 与 S32G3 的 PFE 固件不可互换,固件头中会标明目标芯片。
  2. 驱动与固件配套:驱动中通常有期望的固件版本号或兼容范围,版本偏差过大时驱动会拒绝加载。
  3. 设备树 compatible 一致:compatible 字符串必须与驱动匹配表完全一致,大小写和连字符都不能错。
若出现“PFE probe failed”或“firmware version mismatch”,优先检查:固件文件是否存在于根文件系统指定路径、firmware-name 是否拼写正确、驱动与固件是否来自同一 BSP 发布包。不要通过强行修改 compatible 来绕过版本检查,这会导致运行时表项写入错位。
调试时建议先确认 /lib/firmware/pfe_fw.bin 存在且可读,再用 ethtool -i 查看驱动与固件版本信息,最后用 ip link set up 验证接口能否正常 up。三步依次通过,说明固件、驱动、设备树三者已经对齐。