我是 Linux 内核和 80211 子系统的新手。出于某种原因,我决定为 IEEE 802.11e 中定义的特定访问类别 (AC) 动态设置 WMM 参数(例如争用窗口最小/最大值、AIFSN)。我使用的是在配备 Qualcomm Atheros IPQ8074 WiFi 芯片组的Xiaomi AX3600 路由器上运行的 OpenWRT 版本 23.05(内核版本 5.15.134)。 80211 子系统是从版本 6.1.14 向后移植的,我使用 ath11k 作为 WiFi 驱动程序。
到目前为止我在ieee80211_set_txq_params
中找到了
function
net/mac80211/cfg.c
,它调用驱动程序注册的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;
}
这个模块似乎工作正常。但我的问题是,有什么方法可以获取特定 AC 的参数,以便我可以确认我的新设置可以正常工作吗? 我使用嗅探器捕获由我的 AP(更具体地说,“phy1-ap0”接口或网络设备)传输的空中帧。在信标帧中,我找到“标签:特定于供应商:Microsoft Corp.:WMM/WME:参数元素”字段,如下所示:
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
WMM参数仍为默认值。更重要的是,即使我直接更改 function
ieee80211_set_wmm_default
,它会在新界面启动时设置默认的 WMM 参数。信标帧中的 WMM 参数仍然没有改变。所以我猜信标帧中的这个字段不能反映驱动程序中实际的WMM参数。我的猜测正确吗?如果是这样,有什么方法可以确认我的 WMM 设置是否有效?
一切都如上所述
在命令行中,您可以检查“mac_params”文件:
$ sudo cat /sys/kernel/debug/ieee80211/phy0/netdev:wlan0/iwlmvm/mac_params
type: ap
mac id/color: 1 / 0
bssid: e4:a7:a0:01:4f:28
Load: 0
QoS:
0: txop:47 - cw_min:3 - cw_max = 7 - aifs = 1 upasd = 0
1: txop:94 - cw_min:7 - cw_max = 15 - aifs = 1 upasd = 0
2: txop:0 - cw_min:15 - cw_max = 63 - aifs = 3 upasd = 0
3: txop:0 - cw_min:15 - cw_max = 1023 - aifs = 7 upasd = 0