From d240c74b6a887299747209aad8e168ac3d5ffce3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 23 Jan 2020 14:13:33 +0100 Subject: [PATCH] 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. Fixes: 636c02c6e9 ("nl80211: Add regulatory wmm_limit to hostapd_channel_data") Signed-off-by: Felix Fietkau --- src/drivers/driver_nl80211_capa.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 59d06bcc9..31e7cbfe5 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -1368,6 +1368,20 @@ static int phy_info_edmg_capa(struct hostapd_hw_modes *mode, } +static 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, struct nlattr *tb_freq[]) @@ -1475,9 +1489,11 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, 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 =