记一次 IPQ60XX 芯片路由器 OpenWrt NSS 硬件加速固件编译的排查与调优

ZN M2(IPQ6000)路由器编译 OpenWrt 时 NSS 硬件加速未生效,速度卡在 200Mbps。排查 firmware 缺失、kernel config 与 ECM 规则后打通 900Mbps+ 转发。

问题背景

ZN M2(Qualcomm IPQ6000/IPQ6010 方案)是我近期主力调试的家用/轻 NAS 路由器平台。该芯片内置 NSS(Network SubSystem)协处理器,理论上可将 NAT/转发/加密等数据面任务卸载到硬件,实测单核 CPU 也可跑到 900Mbps+。但我用 OpenWrt 官方 master + community feed 编译的固件刷机后,ethtool -k eth0 显示所有 offload 均为 off [fixed],实测 iperf3 仅 220Mbps,CPU 跑满 95% 仍上不去。必须解决 NSS 加速问题,否则这台路由器就失去了存在价值。

故障现象

  1. cat /proc/net/nss/stats 为空,qca-nss-drv 模块虽已加载但 nss stats 全 0。
  2. tc -s qdisc show dev eth0fq_codelcake offload 标记,软件队列仍在 CPU。
  3. iptables -t mangle -L 缺少 MARK --set-mark 0x1 规则,ECM(Enhanced Connection Manager)未接管 flow。
  4. 编译日志里反复出现:
    1
    
    WARNING: NSS firmware qca-nss.* not found under /lib/firmware/qca/
    
  5. 刷机后 dmesg 可见:
    1
    
    qca-nss: NSS core 0 booted but ECM init failed (-2)
    

排查过程

1. 确认 NSS 驱动与固件路径

先在路由器上检查模块:

1
2
3
lsmod | grep -E 'qca-nss|ecm'
# 只有 qca-nss-drv  98304  0
# 缺少 qca-nss-ecm

再看固件目录:

1
2
ls /lib/firmware/qca/
# 只有 qca-cnss.*,没有 qca-nss.* blob

NSS firmware 是高通闭源 blob,必须从 vendor SDK(或 LibWrt 已打包的 feed)提取。官方 OpenWrt feed 里默认不带这些二进制文件。

2. 检查 kernel config 与 NSS 编译选项

回到 buildroot 目录,检查 .config

1
2
3
grep -E 'CONFIG_QCA_NSS|CONFIG_QCA_NSS_DRV' .config
# CONFIG_QCA_NSS_DRV=m
# CONFIG_QCA_NSS_DRV_64BIT=y

CONFIG_QCA_NSS_ECM 却是 is not set。ECM 是 NSS 真正接管流表的模块,少了它 NSS 只是空壳。

3. 定位 build 脚本缺失 proprietary feed

翻阅 feeds.conf.default,发现缺少 LibWrt 特有的 nss-packages feed:

1
src-git nss https://github.com/LibWrt/nss-packages.git;master

而我用的是官方 openwrt/packages + luci,根本没有 NSS blob 下载脚本。

4. 提取 firmware 并打 kernel patch

从 ZN M2 原厂 SDK 里抠出 qca-nss.* 系列 blob,放到 package/firmware/qca-nss-firmware/files/,同时打上 LibWrt 的 kernel patch(target/linux/ipq60xx/patches-6.6/999-nss-support.patch)。

关键 patch 片段:

1
2
3
4
+config QCA_NSS_ECM
+    tristate "QCA NSS Enhanced Connection Manager"
+    depends on QCA_NSS_DRV
+    default m

重新 make menuconfig 选中 NSS ECM 后,make -j$(nproc) 重新编译。

解决方案

  1. feeds.conf 增加 LibWrt NSS feed 并 scripts/feeds update -a
  2. 把提取的 NSS firmware 做成独立 package,make package/qca-nss-firmware/compile
  3. 确保 CONFIG_QCA_NSS_ECM=yCONFIG_NF_CONNTRACK_MARK=y
  4. 固件里添加开机脚本 /etc/init.d/nss-ecm
1
2
3
4
5
6
7
#!/bin/sh /etc/rc.common
START=19
start() {
    insmod qca-nss-ecm || true
    echo 1 > /proc/net/nss/ecm_enable
    iptables -t mangle -A PREROUTING -j MARK --set-mark 0x1
}
  1. 刷机后验证:
1
2
3
4
5
6
ethtool -k eth0 | grep -E 'tx-tcp|rx-gro'
# tx-tcp-segmentation: on [fixed]
# rx-gro: on [fixed]

cat /proc/net/nss/stats | head -5
# NSS packet stats: 12458392 forwarded, 0 dropped

实测 iperf3 双向 940Mbps,CPU 占用降到 18%。

根因分析

NSS 硬件加速生效需要三件套同时满足:

  • 正确加载的 qca-nss-drv + qca-nss-ecm 模块
  • /lib/firmware/qca/ 下存在 vendor 闭源 blob
  • ECM 通过 conntrack mark 把 flow 标记后接管

缺任何一个都会导致回退到纯软件转发。官方 OpenWrt 对 IPQ60xx 的支持仍停留在“能跑”,并未默认集成 NSS 加速路径,必须手动补齐 proprietary 部分。

预防措施

  1. 把 NSS firmware 提取脚本与 kernel patch 固化到个人 build 仓库,make clean && make 一键出片。
  2. CI 里增加 ethtool -k + iperf3 冒烟测试,低于 700Mbps 直接 fail。
  3. 版本锁定 nss-packages feed,避免高通突然更换 blob 格式导致兼容性问题。
  4. 建立 NSS 加速 checklist:firmware 存在 → ECM 加载 → mark 规则 → offload 标志全 on → 实测速度达标。

总结

IPQ60XX 的 NSS 加速本质上是“用正确姿势喂闭源 blob”。只要把 firmware、ECM、mark 规则三件事做全,900Mbps+ 转发轻而易举。后续计划把这套 build 脚本开源,方便更多 ZN M2 / Redmi AX6000 / 小米 BE3600 用户白嫖硬件加速。

延伸阅读

使用 Hugo 构建
主题 StackJimmy 设计