Commit e552af05 authored by Haim Dreyfuss's avatar Haim Dreyfuss Committed by Johannes Berg

mac80211: limit wmm params to comply with ETSI requirements

ETSI has recently added new requirements that restrict the WMM
parameter values for 5GHz frequencies.  We need to take care of the
following scenarios in order to comply with these new requirements:

1. When using mac80211 default values;
2. When the userspace tries to configure its own values;
3. When associating to an AP which advertises WWM IE.

When associating to an AP, the client uses the values in the
advertised WMM IE.  But the AP may not comply with the new ETSI
requirements, so the client needs to check the current regulatory
rules and use those limits accordingly.
Signed-off-by: default avatarHaim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 5bf16a11
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH * Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This file is GPLv2 as found in COPYING. * This file is GPLv2 as found in COPYING.
*/ */
...@@ -2156,6 +2157,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, ...@@ -2156,6 +2157,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
*/ */
p.uapsd = false; p.uapsd = false;
ieee80211_regulatory_limit_wmm_params(sdata, &p, params->ac);
sdata->tx_conf[params->ac] = p; sdata->tx_conf[params->ac] = p;
if (drv_conf_tx(local, sdata, params->ac, &p)) { if (drv_conf_tx(local, sdata, params->ac, &p)) {
wiphy_debug(local->hw.wiphy, wiphy_debug(local->hw.wiphy,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2015 Intel Mobile Communications GmbH * Copyright 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -1869,6 +1870,9 @@ extern const void *const mac80211_wiphy_privid; /* for wiphy privid */ ...@@ -1869,6 +1870,9 @@ extern const void *const mac80211_wiphy_privid; /* for wiphy privid */
int ieee80211_frame_duration(enum nl80211_band band, size_t len, int ieee80211_frame_duration(enum nl80211_band band, size_t len,
int rate, int erp, int short_preamble, int rate, int erp, int short_preamble,
int shift); int shift);
void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_queue_params *qparam,
int ac);
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
bool bss_notify, bool enable_qos); bool bss_notify, bool enable_qos);
void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
......
...@@ -1792,6 +1792,7 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, ...@@ -1792,6 +1792,7 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
params[ac].cw_min, params[ac].cw_max, aci); params[ac].cw_min, params[ac].cw_max, aci);
return false; return false;
} }
ieee80211_regulatory_limit_wmm_params(sdata, &params[ac], ac);
} }
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net> * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -1113,6 +1114,48 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, ...@@ -1113,6 +1114,48 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
return crc; return crc;
} }
void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_queue_params
*qparam, int ac)
{
struct ieee80211_chanctx_conf *chanctx_conf;
const struct ieee80211_reg_rule *rrule;
struct ieee80211_wmm_ac *wmm_ac;
u16 center_freq = 0;
if (sdata->vif.type != NL80211_IFTYPE_AP &&
sdata->vif.type != NL80211_IFTYPE_STATION)
return;
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf)
center_freq = chanctx_conf->def.chan->center_freq;
if (!center_freq) {
rcu_read_unlock();
return;
}
rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq));
if (IS_ERR_OR_NULL(rrule) || !rrule->wmm_rule) {
rcu_read_unlock();
return;
}
if (sdata->vif.type == NL80211_IFTYPE_AP)
wmm_ac = &rrule->wmm_rule->ap[ac];
else
wmm_ac = &rrule->wmm_rule->client[ac];
qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min);
qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max);
qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn);
qparam->txop = !qparam->txop ? wmm_ac->cot / 32 :
min_t(u16, qparam->txop, wmm_ac->cot / 32);
rcu_read_unlock();
}
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
bool bss_notify, bool enable_qos) bool bss_notify, bool enable_qos)
{ {
...@@ -1206,6 +1249,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, ...@@ -1206,6 +1249,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
break; break;
} }
} }
ieee80211_regulatory_limit_wmm_params(sdata, &qparam, ac);
qparam.uapsd = false; qparam.uapsd = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment