mac80211: rebase ontop of v4.18.5
[openwrt/staging/chunkeey.git] / package / kernel / mac80211 / patches / 391-mac80211-Fix-station-bandwidth-setting-after-channel.patch
1 From: Ilan Peer <ilan.peer@intel.com>
2 Date: Fri, 31 Aug 2018 11:31:10 +0300
3 Subject: [PATCH] mac80211: Fix station bandwidth setting after channel
4 switch
5
6 When performing a channel switch flow for a managed interface, the
7 flow did not update the bandwidth of the AP station and the rate
8 scale algorithm. In case of a channel width downgrade, this would
9 result with the rate scale algorithm using a bandwidth that does not
10 match the interface channel configuration.
11
12 Fix this by updating the AP station bandwidth and rate scaling algorithm
13 before the actual channel change in case of a bandwidth downgrade, or
14 after the actual channel change in case of a bandwidth upgrade.
15
16 Signed-off-by: Ilan Peer <ilan.peer@intel.com>
17 Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
18 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
19 ---
20
21 --- a/net/mac80211/mlme.c
22 +++ b/net/mac80211/mlme.c
23 @@ -975,6 +975,10 @@ static void ieee80211_chswitch_work(stru
24 */
25
26 if (sdata->reserved_chanctx) {
27 + struct ieee80211_supported_band *sband = NULL;
28 + struct sta_info *mgd_sta = NULL;
29 + enum ieee80211_sta_rx_bandwidth bw = IEEE80211_STA_RX_BW_20;
30 +
31 /*
32 * with multi-vif csa driver may call ieee80211_csa_finish()
33 * many times while waiting for other interfaces to use their
34 @@ -983,6 +987,48 @@ static void ieee80211_chswitch_work(stru
35 if (sdata->reserved_ready)
36 goto out;
37
38 + if (sdata->vif.bss_conf.chandef.width !=
39 + sdata->csa_chandef.width) {
40 + /*
41 + * For managed interface, we need to also update the AP
42 + * station bandwidth and align the rate scale algorithm
43 + * on the bandwidth change. Here we only consider the
44 + * bandwidth of the new channel definition (as channel
45 + * switch flow does not have the full HT/VHT/HE
46 + * information), assuming that if additional changes are
47 + * required they would be done as part of the processing
48 + * of the next beacon from the AP.
49 + */
50 + switch (sdata->csa_chandef.width) {
51 + case NL80211_CHAN_WIDTH_20_NOHT:
52 + case NL80211_CHAN_WIDTH_20:
53 + default:
54 + bw = IEEE80211_STA_RX_BW_20;
55 + break;
56 + case NL80211_CHAN_WIDTH_40:
57 + bw = IEEE80211_STA_RX_BW_40;
58 + break;
59 + case NL80211_CHAN_WIDTH_80:
60 + bw = IEEE80211_STA_RX_BW_80;
61 + break;
62 + case NL80211_CHAN_WIDTH_80P80:
63 + case NL80211_CHAN_WIDTH_160:
64 + bw = IEEE80211_STA_RX_BW_160;
65 + break;
66 + }
67 +
68 + mgd_sta = sta_info_get(sdata, ifmgd->bssid);
69 + sband =
70 + local->hw.wiphy->bands[sdata->csa_chandef.chan->band];
71 + }
72 +
73 + if (sdata->vif.bss_conf.chandef.width >
74 + sdata->csa_chandef.width) {
75 + mgd_sta->sta.bandwidth = bw;
76 + rate_control_rate_update(local, sband, mgd_sta,
77 + IEEE80211_RC_BW_CHANGED);
78 + }
79 +
80 ret = ieee80211_vif_use_reserved_context(sdata);
81 if (ret) {
82 sdata_info(sdata,
83 @@ -993,6 +1039,13 @@ static void ieee80211_chswitch_work(stru
84 goto out;
85 }
86
87 + if (sdata->vif.bss_conf.chandef.width <
88 + sdata->csa_chandef.width) {
89 + mgd_sta->sta.bandwidth = bw;
90 + rate_control_rate_update(local, sband, mgd_sta,
91 + IEEE80211_RC_BW_CHANGED);
92 + }
93 +
94 goto out;
95 }
96