3. DPAA1帧管理器硬件资源分配与初始化

DPAA1帧管理器硬件资源分配与初始化 学习卡片

DPAA1 硬件资源模型:BMan、QMan 与 QI 的协作关系

DPAA1 的数据面由三个硬件模块协同完成:BMan(Buffer Manager)管理缓冲区池,QMan(Queue Manager)管理帧队列与通道,QI(Queue Interface)负责帧在软件与硬件队列之间的搬运。LS1046A 上每个 DPAA1 端口(MAC)通过一个 FMan 端口 → QMan 通道 的映射关系收发帧。初始化时必须先建立 Buffer Pool,再建立 Frame Queue,最后把 Channel 与 FQ 绑定,否则硬件无法完成入队/出队。

LS1046A DPAA1 资源分配与数据通路 BMan 缓冲区管理器 BPID 0 · 256B · 512 个 BPID 1 · 2KB · 256 个 BPID 2 · 4KB · 128 个 QMan 队列管理器 FQID 0x100 · 接收队列 FQID 0x101 · 发送队列 FQID 0x102 · 错误队列 QMan 通道 CH 0 · 绑定 FQ 0x100 CH 1 · 绑定 FQ 0x101 CH 2 · 绑定 FQ 0x102 BPID FQID FMan MAC 端口 eTSEC 1 · 10/100/1000 RX / TX 帧 QI 队列接口 帧描述符搬运 BD Ring ↔ FQ CPU / 软件层 dpaa_eth 驱动 NAPI 轮询 / 中断 帧 描述符 入队 / 出队 初始化顺序:① BMan 创建 Buffer Pool → ② QMan 创建 Frame Queue → ③ 绑定 Channel 与 FQ → ④ 配置 FMan 端口指向对应 Channel 验证要点:BPID 可用缓冲区计数 > 0;FQ 入队/出队计数递增;Channel 状态为 Active;MAC 端口收发计数正常

Buffer Pool 与 Frame Queue 的创建

在 LS1046A 上,DPAA1 资源通过 dpaa_eth 驱动和设备树节点暴露给内核。初始化代码通常位于 U-Boot 或内核启动阶段,核心是调用 qman_create_fq() 和 bman_create_pool()。以下示例展示在 U-Boot 阶段通过 fmc 工具或直接寄存器操作完成资源分配的关键逻辑。

/* 示例:在 U-Boot 中初始化 DPAA1 Buffer Pool 与 Frame Queue */
#include <common.h>
#include <fsl_dpaa.h>

/* 1. 定义 Buffer Pool 参数 */
#define BPID_RX     0
#define BP_SIZE     256
#define BP_COUNT    512

/* 2. 定义 Frame Queue 参数 */
#define FQID_RX     0x100
#define FQID_TX     0x101
#define FQID_ERR    0x102

int dpaa1_init(void)
{
    int ret;

    /* 创建接收缓冲区池 */
    ret = bman_create_pool(BPID_RX, BP_SIZE, BP_COUNT);
    if (ret) {
        printf("BMan pool %d create failed: %d\n", BPID_RX, ret);
        return ret;
    }

    /* 创建接收帧队列 */
    ret = qman_create_fq(FQID_RX, QMAN_FQ_FLAG_DYNAMIC_FQID);
    if (ret) {
        printf("QMan FQ 0x%x create failed: %d\n", FQID_RX, ret);
        return ret;
    }

    /* 创建发送帧队列 */
    ret = qman_create_fq(FQID_TX, QMAN_FQ_FLAG_DYNAMIC_FQID);
    if (ret) {
        printf("QMan FQ 0x%x create failed: %d\n", FQID_TX, ret);
        return ret;
    }

    /* 绑定 Channel 0 到接收 FQ */
    ret = qman_bind_channel(0, FQID_RX);
    if (ret) {
        printf("Channel bind failed: %d\n", ret);
        return ret;
    }

    printf("DPAA1 init done: BPID=%d FQID=0x%x/0x%x\n",
           BPID_RX, FQID_RX, FQID_TX);
    return 0;
}

验证数据包在硬件队列中的收发

初始化完成后,通过以下方式验证硬件队列是否正常工作:

  • BMan 计数检查:读取 /sys/kernel/debug/bman/pool_count,确认 BPID 0 的可用缓冲区数量接近 512。
  • QMan 队列状态:读取 /sys/kernel/debug/qman/fq_state,确认 FQID 0x100 和 0x101 处于 Active 状态。
  • Channel 绑定验证:读取 /sys/kernel/debug/qman/channel_state,确认 Channel 0 已绑定到 FQID 0x100。
  • 实际收发测试:使用 ping 或 iperf 产生流量,观察 /sys/kernel/debug/qman/fq_stats 中入队/出队计数是否递增。
在 LS1046A 上,DPAA1 的 Buffer Pool 和 Frame Queue 资源是有限的。BPID 和 FQID 的分配必须与设备树中的 fsl,bman-portals 和 fsl,qman-portals 节点一致,否则驱动无法正确映射硬件资源。
如果 FQ 创建后未绑定 Channel,帧将无法被 CPU 接收,表现为网络接口无收包计数。此时应检查 qman_bind_channel() 的返回值,并确认 Channel 编号与 FMan 端口配置匹配。

关键参数速查

资源标识典型值作用
Buffer PoolBPID 0256B × 512接收小帧缓冲区
Buffer PoolBPID 12KB × 256接收大帧缓冲区
Frame QueueFQID 0x100接收队列存放待 CPU 处理的帧描述符
Frame QueueFQID 0x101发送队列存放待 MAC 发送的帧描述符
ChannelCH 0绑定 FQ 0x100触发 CPU 中断或 NAPI 轮询