4. MC(Management Complex)固件与DPRC容器

在 Layerscape 数据面工程中,DPAA 的硬件资源(DPNI、DPBP、DPIO、DPRC、DPMAC、DPSECI 等)并不是由 Linux 内核直接枚举和管理的,而是由一颗独立的 Cortex-M 核运行 MC(Management Complex)固件统一掌管。Linux 侧看到的每一个网络接口、每一个 BMan 缓冲池、每一个 QMan 通道,本质上都是 MC 固件根据一份描述文件“造”出来的对象。理解 MC 固件与 DPRC 容器,是后续做 DPDK 绑定、VF 切分、多租户隔离的前提。

MC 固件与 DPRC 的角色定位

MC 固件运行在 SoC 内部的 Management Complex 处理器上,它对外提供两类接口:一是通过 MC 命令门户(command portal)接收来自内核或用户态的“对象管理命令”,二是通过 DPRC 容器把已创建的对象按“容器”分组暴露出来。DPRC(Data Path Resource Container)可以理解为一个资源命名空间:每个容器有独立的 ID、自己的对象列表和资源配额,容器之间默认隔离。LS1046A、LS2088A 这类芯片上,MC 固件通常把资源划分成若干 DPRC,例如 dprc.1 给 Linux 内核使用,dprc.2 留给用户态 DPDK 或某个虚拟机。

关键点在于:DPRC 不是硬件实体,而是 MC 固件维护的软件抽象。一个 DPNI 对象被创建后,必须被“放入”某个 DPRC 才能被该容器的使用者访问。因此“对象创建”和“容器归属”是两件独立的事,这也是很多初学者在 ls-addni 之后发现接口出现在错误容器里的原因。

MC 固件启动与 DPRC 资源分配链路 ① 上电 / 复位 BootROM 加载 MC 固件 itb 镜像 → MC 内存 ② MC 固件运行 初始化 AIOP / QMan / BMan 建立命令门户 ③ 解析 DPL 读取 DPL 二进制 按描述创建对象 ④ 容器就绪 DPRC 可被内核/用户态 通过门户访问 DPL(Data Path Layout)描述内容 • dprc@1:容器 ID、父容器、资源配额 • dpni@0:MAC 地址、链路速率、队列数 • dpbp@0:BMan 缓冲池,池大小 / 对齐 • dpio@0:QMan 门户,通道数、优先级 • dpmac@1:物理口与 DPNI 的绑定关系 对象创建与容器归属 1. MC 按 DPL 逐条执行 create 命令 2. 每个对象获得全局唯一 object ID 3. 对象被挂入指定 DPRC 的 resource list 4. 未指定容器的对象默认归 dprc.1 5. 容器配额不足 → create 失败并回滚 运行时资源分配与访问路径 Linux 内核 fsl-mc 总线驱动 枚举 dprc.1 对象 生成 netdev / 字符设备 用户态 DPDK vfio-fsl-mc 绑定 访问 dprc.2 门户 直接操作 DPNI/DPIO MC 命令门户 MC_CMD_GET_OBJECT MC_CMD_SET_OBJ_LABEL MC_CMD_GET_CONTAINER 硬件资源 QMan / BMan DPNI / DPMAC DPBP / DPSECI

DPL 配置:对象从描述到实体

DPL 是 MC 固件的“施工图”。它通常由 restool 工具或 NXP 提供的 dpl-*.dtb 生成,本质是一份二进制描述,内容与设备树类似但字段更贴近 DPAA 硬件。一个典型的 DPNI 条目会声明:dpni@0 的 MAC 地址、最大接收帧长、发送/接收队列数、与哪个 DPMAC 绑定、属于哪个 DPRC。MC 固件在启动时逐条解析,调用内部 create 例程,把对象实例化到硬件资源池中。

需要特别注意的是 DPL 中的“容器归属”字段。如果 DPNI 条目里写了 dprc@2,那么该 DPNI 创建后直接进入 dprc.2;如果没写,默认进入 dprc.1。很多工程问题就出在这里:用户用 restool dpni create 动态创建了一个 DPNI,却没有指定 --container,结果它出现在 dprc.1,而 DPDK 绑定的是 dprc.2,自然看不到设备。

运行时资源分配与访问路径

MC 固件启动完成后,Linux 内核的 fsl-mc 总线驱动会扫描 dprc.1,把其中的 DPNI 注册成 netdev,把 DPIO 注册成字符设备。用户态 DPDK 则通过 vfio-fsl-mc 绑定到另一个 DPRC,绕过内核网络栈直接访问门户。两条路径共享同一套 MC 固件,但容器隔离保证了互不干扰。

运行时还可以动态调整资源。例如通过 restool dpni update 修改队列数,或通过 restool dprc set-obj-label 给对象打标签便于识别。这些操作最终都转化为 MC 命令,由固件在硬件层面生效。下面是一段典型的 DPL 片段与对应的 restool 查询命令,可作为配置参考:

/* DPL 片段:dprc@2 中创建一个 DPNI */
dprc@2 {
    compatible = "fsl,dprc";
    container-id = <2>;
    parent-container = <1>;
    dpni@0 {
        compatible = "fsl,dpni";
        mac-addr = [00 1e 64 00 00 01];
        max-rx-frame = <9600>;
        num-tx-queues = <8>;
        num-rx-queues = <8>;
        dpmac = <1>;
    };
};

# 查询 dprc.2 中的对象
restool dprc show dprc.2
# 输出示例:
# dprc.2 contains 3 objects:
#   dpni.0  (DPNI)  mac=00:1e:64:00:00:01
#   dpio.0  (DPIO)  channels=4
#   dpbp.0  (DPBP)  pool-size=1024
DPL 中的 container-id 必须与 MC 固件实际分配的容器编号一致。若手工修改 DPL 后重新烧写,建议先用 restool dprc list 确认现有容器拓扑,再决定对象归属,避免容器 ID 冲突导致 MC 启动失败。

常见排障要点

当 DPNI 未按预期出现时,按以下顺序排查:第一,确认 MC 固件版本与 DPL 版本匹配,restool mc info 可查看固件版本;第二,确认对象是否创建成功,restool dpni list 会列出所有 DPNI 及其所属容器;第三,确认容器是否被正确绑定,ls /sys/bus/fsl-mc/devices/ 下应出现对应 dprc 目录;第四,若使用 DPDK,检查 vfio-fsl-mc 是否已绑定到目标容器,且该容器未被内核驱动占用。这四步覆盖了从固件到用户态的完整链路,能定位绝大多数“设备找不到”的问题。