4. PFE接口与端口抽象

S32G 的 PFE(Packet Forwarding Engine)并不是“一个网口对应一个寄存器”的简单外设,而是一套把物理链路、内部转发逻辑和主机 CPU 解耦的分层抽象。理解这套抽象的关键,是分清四个层次:物理端口(Physical Port)、逻辑接口(Logical Interface)、内部功能块(EMAC / HIF / LLCE),以及端口到主机通道(Host Channel)的映射。只有把“包从哪来、经过谁、最后交给哪个 CPU 队列”这条链路理清,后面的路由、VLAN、ACL 和抓包调试才有落脚点。

物理端口与逻辑接口:一对多的关系

物理端口是 PFE 与外部世界真正相连的引脚与 MAC 资源。S32G 上典型配置包括 PFE_MAC0~PFE_MAC2 三路以太网 MAC,可工作在 RGMII 或 SGMII 模式,分别对应外部 PHY 或 SFP 光模块。每个物理端口有独立的 MAC 地址、速率/双工状态、统计计数器和 FIFO。物理端口编号(如 emac0、emac1、emac2)是硬件层面的标识,通常与引脚复用和 PHY 地址绑定,一旦板级设计确定就不可随意更改。

逻辑接口则是在物理端口之上由软件(Linux 网络栈或 PFE 固件)划分出的可寻址实体。一个物理端口可以承载多个逻辑接口:例如 emac0 上可以同时存在一个不带 VLAN 的接口、若干 VLAN 子接口(emac0.100、emac0.200),以及一个用于 LLCE 的旁路接口。逻辑接口决定“这个包属于哪个网络”,物理端口决定“这个包从哪根线出去”。因此,逻辑接口是路由查找、ACL 匹配和统计归属的基本单位,而物理端口是链路状态和带宽约束的基本单位。

PFE 端口抽象与主机通道映射 外部链路 PHY / SFP RGMII / SGMII PHY / SFP RGMII / SGMII PHY / SFP RGMII / SGMII LLCE 链路 CAN / LIN PFE 内部功能块 EMAC0 物理端口 0 EMAC1 物理端口 1 EMAC2 物理端口 2 LLCE 接口 CAN/LIN 桥接 逻辑接口 emac0 / VLAN 逻辑接口 emac1 / VLAN 逻辑接口 emac2 / VLAN LLCE 逻辑口 can0 / can1 HIF 主机接口 DMA 通道 主机 CPU Host Channel 0 高优先级 / 控制 Host Channel 1 数据面 / 转发 Host Channel 2 LLCE / CAN 事件 Host Channel 3 调试 / 抓包 以太网数据路径 LLCE / CAN 路径 主机 DMA 通道 调试 / 抓包通道

EMAC、HIF 与 LLCE 的分工

EMAC 负责以太网帧的收发、CRC 校验、地址过滤和流控。每个 EMAC 实例对应一个物理端口,内部有独立的 RX/TX FIFO 和 DMA 引擎。EMAC 不关心 IP 地址或路由,它只保证“帧从线上进来、校验通过、交给 PFE 内部交换结构”。在 S32G 中,EMAC 的配置通常通过 PFE 固件加载时的硬件描述(如 pfe_ct.h 中的 emac 模式定义)完成,Linux 侧通过 pfe 驱动暴露的 netdev 操作链路状态。

HIF(Host Interface) 是 PFE 与主机 CPU 之间的桥梁。它把 PFE 内部处理完的包通过 DMA 搬运到主机内存的环形缓冲区(Ring),并把主机要发送的包搬回 PFE。HIF 本身不区分业务类型,但它提供多个主机通道(Host Channel),每个通道有独立的队列、中断和优先级。主机通道是“端口到主机映射”的最终落点:一个逻辑接口的包最终进入哪个 Host Channel,决定了它被哪个 CPU 核、哪个 NAPI 实例、哪个协议栈队列处理。

LLCE(Low Latency Communication Engine) 是 S32G 中处理 CAN/LIN 等车载总线的独立引擎。它与 PFE 的交互体现在:LLCE 收到的 CAN 帧可以通过 PFE 的 LLCE 接口注入到以太网侧(例如 CAN-to-Ethernet 网关),反之以太网帧也可以被路由到 LLCE 发送到 CAN 总线。在端口抽象上,LLCE 接口通常表现为一个特殊的逻辑接口(如 can0),其包不经过 EMAC,而是直接进入 HIF 的某个专用 Host Channel。

端口到主机通道的映射

映射关系是本节最需要动手确认的部分。在 PFE 固件中,每个逻辑接口通过 pfe_phy_if 和 pfe_log_if 对象描述,并绑定到一个 pfe_interface。当包需要上送主机时,PFE 根据包所属的逻辑接口查找对应的 pfe_hif_chnl,然后写入该通道的 DMA 描述符。映射通常通过以下方式建立:

  • 默认映射:每个 EMAC 逻辑接口默认绑定到一个 Host Channel,例如 emac0 → HIF Channel 0,emac1 → HIF Channel 1,emac2 → HIF Channel 2。
  • VLAN 细分:在 emac0 上创建 VLAN 子接口时,可以为每个 VLAN 指定不同的 Host Channel,实现“控制流量走 Channel 0、数据流量走 Channel 1”的分离。
  • LLCE 专用通道:LLCE 逻辑接口通常绑定到独立的 Host Channel(如 Channel 2),避免 CAN 事件与以太网数据争抢同一队列。
  • 调试通道:可以配置一个 Host Channel 专门用于镜像或抓包,把指定逻辑接口的包复制到该通道,供主机侧 tcpdump 或自定义工具分析。

在 Linux 侧,映射结果体现为不同的网络设备队列。例如,当 emac0 绑定到 HIF Channel 0 时,ethtool -S emac0 会显示该通道的 RX/TX 计数;当 VLAN 子接口绑定到 Channel 1 时,ip -s link show emac0.100 的统计来自 Channel 1 的队列。如果发现某个接口的包没有出现在预期的 CPU 队列中,首先应检查 PFE 固件的接口-通道绑定表,而不是先怀疑路由或防火墙。

实际调试时,可以通过 PFE 的调试寄存器或 pfe_ct.h 中的 PFE_HIF_CHNL 定义确认通道编号。S32G 的 HIF 通常支持 4~8 个通道,具体数量取决于芯片型号和固件配置。通道编号与 CPU 核的亲和性可以通过中断路由(GIC 配置)进一步绑定,从而让特定通道的包固定由某个 A53 核处理。

一个可参考的映射配置示例

假设一块 S32G 板卡有三路以太网和一路 CAN,需求是:emac0 作为管理口,emac1 和 emac2 作为数据口,CAN 事件需要低延迟上送。可以按如下方式规划映射:

逻辑接口 物理端口 Host Channel 用途 CPU 亲和
emac0 EMAC0 HIF Channel 0 管理 / SSH / 诊断 A53 Core 0
emac1 EMAC1 HIF Channel 1 数据面转发 A53 Core 1
emac2 EMAC2 HIF Channel 2 数据面转发 A53 Core 2
can0 LLCE HIF Channel 3 CAN 事件 / 网关 A53 Core 3
emac1.100 EMAC1 HIF Channel 4 VLAN 100 控制流 A53 Core 0

这张表不是“配置命令”,而是设计意图的落地表达。实际写入 PFE 固件时,需要把每个逻辑接口的 pfe_log_if 与对应的 pfe_hif_chnl 关联,并在设备树或固件配置中声明通道数量、队列深度和中断号。完成之后,可以用 cat /proc/interrupts | grep pfe 观察各通道中断是否均匀分布,用 ethtool -S 确认各接口的 RX/TX 计数是否随流量增长,从而验证映射是否按预期生效。

常见误区:把“物理端口 up”等同于“逻辑接口可用”。物理端口 up 只说明 PHY 链路和 EMAC 就绪;如果逻辑接口没有正确绑定 Host Channel,包会在 PFE 内部被丢弃或滞留在队列中,主机侧看不到任何计数增长。排查时应先确认 pfe_log_if 的通道绑定,再检查 VLAN 过滤和 ACL 规则。