hostapd sets minimum values for CWmin/CWmax/AIFS and maximum for TXOP. The code for applying those values had a few bugs leading to bogus values, which caused significant latency and packet loss. Signed-off-by: Felix Fietkau <nbd@nbd.name>master
parent
abaf329dad
commit
4a58a871c4
@ -0,0 +1,41 @@ |
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 23 Jan 2020 13:50:47 +0100
|
||||||
|
Subject: [PATCH] driver_nl80211: fix WMM queue mapping for regulatory
|
||||||
|
limit
|
||||||
|
|
||||||
|
nl80211 uses a different queue mapping from hostap, so AC indexes need to
|
||||||
|
be converted.
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/src/drivers/driver_nl80211_capa.c
|
||||||
|
+++ b/src/drivers/driver_nl80211_capa.c
|
||||||
|
@@ -1403,6 +1403,12 @@ static void phy_info_freq(struct hostapd
|
||||||
|
[NL80211_WMMR_AIFSN] = { .type = NLA_U8 },
|
||||||
|
[NL80211_WMMR_TXOP] = { .type = NLA_U16 },
|
||||||
|
};
|
||||||
|
+ static const u8 wmm_map[4] = {
|
||||||
|
+ [NL80211_AC_BE] = WMM_AC_BE,
|
||||||
|
+ [NL80211_AC_BK] = WMM_AC_BK,
|
||||||
|
+ [NL80211_AC_VI] = WMM_AC_VI,
|
||||||
|
+ [NL80211_AC_VO] = WMM_AC_VO,
|
||||||
|
+ };
|
||||||
|
struct nlattr *nl_wmm;
|
||||||
|
struct nlattr *tb_wmm[NL80211_WMMR_MAX + 1];
|
||||||
|
int rem_wmm, ac, count = 0;
|
||||||
|
@@ -1424,12 +1430,13 @@ static void phy_info_freq(struct hostapd
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ac = nl_wmm->nla_type;
|
||||||
|
- if (ac < 0 || ac >= WMM_AC_NUM) {
|
||||||
|
+ if (ac >= ARRAY_SIZE(wmm_map)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Invalid AC value %d", ac);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ac = wmm_map[ac];
|
||||||
|
chan->wmm_rules[ac].min_cwmin =
|
||||||
|
nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]);
|
||||||
|
chan->wmm_rules[ac].min_cwmax =
|
@ -0,0 +1,47 @@ |
|||||||
|
From: Felix Fietkau <nbd@nbd.name>
|
||||||
|
Date: Thu, 23 Jan 2020 14:10:20 +0100
|
||||||
|
Subject: [PATCH] driver_nl80211: fix regulatory limits for wmm cwmin/cwmax
|
||||||
|
values
|
||||||
|
|
||||||
|
The internal WMM AC parameters use just the exponent of the CW value, while
|
||||||
|
nl80211 reports the full CW value.
|
||||||
|
This led to completely bogus CWmin/CWmax values in the WMM IE when a regulatory
|
||||||
|
limit was present. Fix this by converting the value to the exponent before
|
||||||
|
passing it on
|
||||||
|
|
||||||
|
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/src/drivers/driver_nl80211_capa.c
|
||||||
|
+++ b/src/drivers/driver_nl80211_capa.c
|
||||||
|
@@ -1336,6 +1336,18 @@ static void phy_info_vht_capa(struct hos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline int cw2ecw(unsigned int cw)
|
||||||
|
+{
|
||||||
|
+ int bit;
|
||||||
|
+
|
||||||
|
+ if (cw == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ for (bit = 1; cw != 1; bit++)
|
||||||
|
+ cw >>= 1;
|
||||||
|
+
|
||||||
|
+ return bit;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void phy_info_freq(struct hostapd_hw_modes *mode,
|
||||||
|
struct hostapd_channel_data *chan,
|
||||||
|
@@ -1438,9 +1450,9 @@ static void phy_info_freq(struct hostapd
|
||||||
|
|
||||||
|
ac = wmm_map[ac];
|
||||||
|
chan->wmm_rules[ac].min_cwmin =
|
||||||
|
- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]);
|
||||||
|
+ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]));
|
||||||
|
chan->wmm_rules[ac].min_cwmax =
|
||||||
|
- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX]);
|
||||||
|
+ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX]));
|
||||||
|
chan->wmm_rules[ac].min_aifs =
|
||||||
|
nla_get_u8(tb_wmm[NL80211_WMMR_AIFSN]);
|
||||||
|
chan->wmm_rules[ac].max_txop =
|
Loading…
Reference in new issue