You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux 80211子系统如何获取WiFi CW参数及验证WMM设置生效?

问题背景与疑问

我是Linux内核与80211子系统的新手,希望动态设置IEEE 802.11e定义的特定访问类别(AC)的WMM参数(如竞争窗口最小值/最大值、AIFSN)。使用环境如下:

  • 路由器:小米AX3600
  • 系统:OpenWRT 23.05(内核版本5.15.134)
  • WiFi芯片:高通Atheros IPQ8074
  • 80211子系统:从6.1.14版本回传
  • WiFi驱动:ath11k

目前已找到net/mac80211/cfg.c中的ieee80211_set_txq_params函数,该函数会调用驱动注册的ieee80211_ops->conf_tx设置WMM参数。我导出了该函数并编写内核模块调用它,代码如下:

static int __init cw_adapt_init(void)
{
    struct net_device* netdev = NULL;
    struct wiphy* wiphy = NULL;
    struct wireless_dev* wdev = NULL;
    struct ieee80211_txq_params txq_params;
    char* ifname = "phy1-ap0";
    int result = 0;

    netdev = dev_get_by_name(&init_net, ifname);

    if (!netdev) {
        pr_warn("can not find wifi device: %s\n", ifname);
        goto out;
    }

    wdev = netdev->ieee80211_ptr;
    if (!wdev) {
        pr_warn("can not get wdev\n");
        goto out;
    }
    wiphy = wdev->wiphy;
    if (!wiphy) {
        pr_warn("can not get wiphy\n");
        goto out;
    }

    if (!netif_running(netdev)) {
        pr_warn("netdev is not running\n");
        goto out;
    }

    wiphy_lock(wiphy);
    wdev_lock(wdev);

    txq_params.ac = NL80211_AC_BK;
    // trying to set txq params of BK as same as VI
    txq_params.link_id = -1; // introduced in kernel 6.x to support MLD, not used in my router
    txq_params.txop = 94;
    txq_params.cwmin = 7;
    txq_params.cwmax = 15;
    txq_params.aifs = 2;
    result = ieee80211_set_txq_params(wiphy, netdev, &txq_params);
    if (result) {
        pr_warn("set txq params failed for ac %d: %d\n", txq_params.ac, result);
    }
 
    wdev_unlock(wdev);
    wiphy_unlock(wiphy);

out:
    return 0;
}

模块运行无报错,但存在以下疑问:

  1. 是否有方法获取特定AC的当前参数,确认新设置已生效?
  2. 抓包发现Beacon帧中的WMM参数仍为默认值,即使修改ieee80211_set_wmm_default函数也无变化。猜测Beacon帧中的该字段无法反映驱动实际WMM参数,是否正确?如果正确,有什么方法验证WMM设置已生效?

抓包得到的Beacon帧WMM参数片段:

Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element
    Tag Number: Vendor Specific (221)
    Tag length: 24
    OUI: 00:50:f2 (Microsoft Corp.)
    Vendor Specific OUI Type: 2
    Type: WMM/WME (0x02)
    WME Subtype: Parameter Element (1)
    WME Version: 1
    WME QoS Info: 0x81
        1... .... = U-APSD: Enabled
        .... 0001 = Parameter Set Count: 0x1
        .000 .... = Reserved: 0x0
    Reserved: 00
    Ac Parameters ACI 0 (Best Effort), ACM no, AIFSN 3, ECWmin/max 4/10 (CWmin/max 15/1023), TXOP 0
        ACI / AIFSN Field: 0x03
        ECW: 0xa4
        TXOP Limit: 0
    Ac Parameters ACI 1 (Background), ACM no, AIFSN 7, ECWmin/max 4/10 (CWmin/max 15/1023), TXOP 0
        ACI / AIFSN Field: 0x27
        ECW: 0xa4
        TXOP Limit: 0
    Ac Parameters ACI 2 (Video), ACM no, AIFSN 2, ECWmin/max 3/4 (CWmin/max 7/15), TXOP 94
        ACI / AIFSN Field: 0x42
        ECW: 0x43
        TXOP Limit: 94
    Ac Parameters ACI 3 (Voice), ACM no, AIFSN 2, ECWmin/max 2/3 (CWmin/max 3/7), TXOP 47
        ACI / AIFSN Field: 0x62
        ECW: 0x32
        TXOP Limit: 47

解答

关于Beacon帧WMM参数的猜测验证

你的猜测是正确的。Beacon帧中的WMM参数属于网络侧对外广播的协商参数,用于告知STA(客户端)AP支持的WMM能力范围,一旦AP启动后,该字段通常不会随驱动内部参数的动态修改而更新——除非主动触发Beacon帧内容的重新生成与广播。

mac80211中,Beacon帧的WMM参数是在接口初始化时基于默认WMM配置生成的,之后动态修改驱动内部的TXQ参数不会自动同步到Beacon的广播内容里。修改ieee80211_set_wmm_default后需要重启AP接口才能让Beacon参数更新,但这也只是修改了初始广播值,无法反映后续的动态调整。

获取当前AC参数的方法

1. 内核debugfs接口查看

mac80211提供了debugfs接口可以查看每个AC的当前参数,路径通常是/sys/kernel/debug/ieee80211/<wiphyX>/netdev:<ifname>/txqueues。

进入对应目录后,每个AC(如ac_bk、ac_be、ac_vi、ac_vo)都有单独的子目录,里面的文件会记录当前的cwmin、cwmax、aifs、txop等参数。例如:

cat /sys/kernel/debug/ieee80211/phy1/netdev:phy1-ap0/txqueues/ac_bk/cwmin

如果系统未挂载debugfs,先执行:

mount -t debugfs none /sys/kernel/debug

2. 内核模块中添加参数读取逻辑

可以在模块中添加读取逻辑,通过访问struct ieee80211_sub_if_data中的txq_params数组获取当前参数。示例代码片段:

#include <net/mac80211.h>

// 获取netdev后执行:
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
struct ieee80211_txq_params *params = &sdata->txq_params[NL80211_AC_BK];

pr_info("BK AC current params: cwmin=%d, cwmax=%d, aifs=%d, txop=%d\n",
        params->cwmin, params->cwmax, params->aifs, params->txop);

注意需要确保CONFIG_MAC80211_DEBUGFS已开启,且代码需在mac80211上下文允许范围内访问这些结构体。

验证WMM设置生效的方法

1. 驱动侧日志打印

修改ath11k驱动的conf_tx函数(通常在ath11k/mac.c中),添加日志打印,确认驱动是否接收到mac80211传递的新参数,并且是否成功配置到硬件中。例如:

int ath11k_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       u16 queue, const struct ieee80211_txq_params *params)
{
    // 原代码逻辑...
    pr_debug("ath11k: set AC %d params: cwmin=%d, cwmax=%d, aifs=%d, txop=%d\n",
             queue, params->cwmin, params->cwmax, params->aifs, params->txop);
    // 原代码逻辑...
}

重新编译驱动后加载,通过dmesg查看日志,确认参数是否被正确接收并配置。

2. 空口性能测试

通过实际流量测试验证参数变化带来的性能差异:

  • 用iperf3等工具发送BK类别的流量(可通过tc qdisc或应用层标记DSCP值映射到BK AC)
  • 对比修改参数前后的吞吐量、延迟、丢包率:如果把BK参数改成和VI一致,理论上BK流量的优先级会提升,延迟降低,吞吐量上升
  • 使用tcpdump或wireshark捕获空口帧,观察BK类别的帧在竞争信道时的行为变化(比如退避次数减少)

3. 硬件寄存器读取(高级)

如果熟悉IPQ8074的硬件手册,可通过内核模块读取WiFi芯片中对应AC的配置寄存器,直接确认硬件是否应用了新的参数。这种方法需要芯片技术文档支持,适合深度调试。

内容的提问来源于stack exchange,提问作者Yuhan Zhou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:10:55