summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2019-05-29 08:25:35 -0400
committerJohannes Berg <johannes.berg@intel.com>2019-06-14 08:17:37 -0400
commitbd718fc11d5b184701e7fd8302033e31a3a03ba8 (patch)
tree83fb561f5c39948a26c101642cdbb62e1683ce79
parent1e87fec9fa52a6f7c223998d6bfbd3464eb37e31 (diff)
mac80211: use STA info in rate_control_send_low()
Even if we have a station, we currently call rate_control_send_low() with the NULL station unless further rate control (driver, minstrel) has been initialized. Change this so we can use more information about the station to use a better rate. For example, when we associate with an AP, we will now use the lowest rate it advertised as supported (that we can) rather than the lowest mandatory rate. This aligns our behaviour with most other 802.11 implementations. To make this possible, we need to also ensure that we have non-zero rates at all times, so in case we really have *nothing* pre-fill the supp_rates bitmap with the very lowest mandatory bitmap (11b and 11a on 2.4 and 5 GHz respectively). Additionally, hostapd appears to be giving us an empty supported rates bitmap (it can and should do better, since the STA must have supported for at least the basic rates in the BSS), so ignore any such bitmaps that would actually zero out the supp_rates, and in that case just keep the pre-filled mandatory rates. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/mlme.c7
-rw-r--r--net/mac80211/rate.c12
-rw-r--r--net/mac80211/sta_info.c43
4 files changed, 56 insertions, 10 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 023e8751d223..fcf1dfc3a1cc 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -4,7 +4,7 @@
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2013-2015 Intel Mobile Communications GmbH 5 * Copyright 2013-2015 Intel Mobile Communications GmbH
6 * Copyright (C) 2015-2017 Intel Deutschland GmbH 6 * Copyright (C) 2015-2017 Intel Deutschland GmbH
7 * Copyright (C) 2018 Intel Corporation 7 * Copyright (C) 2018-2019 Intel Corporation
8 * 8 *
9 * This file is GPLv2 as found in COPYING. 9 * This file is GPLv2 as found in COPYING.
10 */ 10 */
@@ -1468,7 +1468,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1468 return ret; 1468 return ret;
1469 } 1469 }
1470 1470
1471 if (params->supported_rates) { 1471 if (params->supported_rates && params->supported_rates_len) {
1472 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef, 1472 ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
1473 sband, params->supported_rates, 1473 sband, params->supported_rates,
1474 params->supported_rates_len, 1474 params->supported_rates_len,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 281319c826dd..b971b02d0d60 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4955,7 +4955,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
4955 basic_rates = BIT(min_rate_index); 4955 basic_rates = BIT(min_rate_index);
4956 } 4956 }
4957 4957
4958 new_sta->sta.supp_rates[cbss->channel->band] = rates; 4958 if (rates)
4959 new_sta->sta.supp_rates[cbss->channel->band] = rates;
4960 else
4961 sdata_info(sdata,
4962 "No rates found, keeping mandatory only\n");
4963
4959 sdata->vif.bss_conf.basic_rates = basic_rates; 4964 sdata->vif.bss_conf.basic_rates = basic_rates;
4960 4965
4961 /* cf. IEEE 802.11 9.2.12 */ 4966 /* cf. IEEE 802.11 9.2.12 */
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 09f89d004a70..bc3cedc653f0 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -886,11 +886,6 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
886 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); 886 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
887 int i; 887 int i;
888 888
889 if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
890 ista = &sta->sta;
891 priv_sta = sta->rate_ctrl_priv;
892 }
893
894 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 889 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
895 info->control.rates[i].idx = -1; 890 info->control.rates[i].idx = -1;
896 info->control.rates[i].flags = 0; 891 info->control.rates[i].flags = 0;
@@ -900,9 +895,14 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
900 if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL)) 895 if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL))
901 return; 896 return;
902 897
903 if (rate_control_send_low(ista, txrc)) 898 if (rate_control_send_low(sta ? &sta->sta : NULL, txrc))
904 return; 899 return;
905 900
901 if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
902 ista = &sta->sta;
903 priv_sta = sta->rate_ctrl_priv;
904 }
905
906 if (ista) { 906 if (ista) {
907 spin_lock_bh(&sta->rate_ctrl_lock); 907 spin_lock_bh(&sta->rate_ctrl_lock);
908 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); 908 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a4932ee3595c..315adb473e2c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -3,7 +3,7 @@
3 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 3 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
4 * Copyright 2013-2014 Intel Mobile Communications GmbH 4 * Copyright 2013-2014 Intel Mobile Communications GmbH
5 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 5 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
6 * Copyright (C) 2018 Intel Corporation 6 * Copyright (C) 2018-2019 Intel Corporation
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -404,6 +404,47 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
404 for (i = 0; i < IEEE80211_NUM_TIDS; i++) 404 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
405 sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); 405 sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
406 406
407 for (i = 0; i < NUM_NL80211_BANDS; i++) {
408 u32 mandatory = 0;
409 int r;
410
411 if (!hw->wiphy->bands[i])
412 continue;
413
414 switch (i) {
415 case NL80211_BAND_2GHZ:
416 /*
417 * We use both here, even if we cannot really know for
418 * sure the station will support both, but the only use
419 * for this is when we don't know anything yet and send
420 * management frames, and then we'll pick the lowest
421 * possible rate anyway.
422 * If we don't include _G here, we cannot find a rate
423 * in P2P, and thus trigger the WARN_ONCE() in rate.c
424 */
425 mandatory = IEEE80211_RATE_MANDATORY_B |
426 IEEE80211_RATE_MANDATORY_G;
427 break;
428 case NL80211_BAND_5GHZ:
429 mandatory = IEEE80211_RATE_MANDATORY_A;
430 break;
431 case NL80211_BAND_60GHZ:
432 WARN_ON(1);
433 mandatory = 0;
434 break;
435 }
436
437 for (r = 0; r < hw->wiphy->bands[i]->n_bitrates; r++) {
438 struct ieee80211_rate *rate;
439
440 rate = &hw->wiphy->bands[i]->bitrates[r];
441
442 if (!(rate->flags & mandatory))
443 continue;
444 sta->sta.supp_rates[i] |= BIT(r);
445 }
446 }
447
407 sta->sta.smps_mode = IEEE80211_SMPS_OFF; 448 sta->sta.smps_mode = IEEE80211_SMPS_OFF;
408 if (sdata->vif.type == NL80211_IFTYPE_AP || 449 if (sdata->vif.type == NL80211_IFTYPE_AP ||
409 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 450 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {