Skip to content

Commit d2941df

Browse files
committed
mac80211: recalculate min channel width on VHT opmode changes
When an associated station changes its VHT operating mode this can/will affect the bandwidth it's using, and consequently we must recalculate the minimum bandwidth we need to use. Failure to do so can lead to one of two scenarios: 1) we use a too high bandwidth, this is benign 2) we use a too narrow bandwidth, causing rate control and actual PHY configuration to be out of sync, which can in turn cause problems/crashes Signed-off-by: Johannes Berg <[email protected]>
1 parent 96aa2e7 commit d2941df

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

net/mac80211/iface.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Copyright (c) 2006 Jiri Benc <[email protected]>
77
* Copyright 2008, Johannes Berg <[email protected]>
88
* Copyright 2013-2014 Intel Mobile Communications GmbH
9+
* Copyright (c) 2016 Intel Deutschland GmbH
910
*
1011
* This program is free software; you can redistribute it and/or modify
1112
* it under the terms of the GNU General Public License version 2 as
@@ -1295,6 +1296,26 @@ static void ieee80211_iface_work(struct work_struct *work)
12951296
} else if (ieee80211_is_action(mgmt->frame_control) &&
12961297
mgmt->u.action.category == WLAN_CATEGORY_VHT) {
12971298
switch (mgmt->u.action.u.vht_group_notif.action_code) {
1299+
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
1300+
struct ieee80211_rx_status *status;
1301+
enum nl80211_band band;
1302+
u8 opmode;
1303+
1304+
status = IEEE80211_SKB_RXCB(skb);
1305+
band = status->band;
1306+
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
1307+
1308+
mutex_lock(&local->sta_mtx);
1309+
sta = sta_info_get_bss(sdata, mgmt->sa);
1310+
1311+
if (sta)
1312+
ieee80211_vht_handle_opmode(sdata, sta,
1313+
opmode,
1314+
band);
1315+
1316+
mutex_unlock(&local->sta_mtx);
1317+
break;
1318+
}
12981319
case WLAN_VHT_ACTION_GROUPID_MGMT:
12991320
ieee80211_process_mu_groups(sdata, mgmt);
13001321
break;

net/mac80211/rx.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2881,17 +2881,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
28812881

28822882
switch (mgmt->u.action.u.vht_opmode_notif.action_code) {
28832883
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
2884-
u8 opmode;
2885-
28862884
/* verify opmode is present */
28872885
if (len < IEEE80211_MIN_ACTION_SIZE + 2)
28882886
goto invalid;
2889-
2890-
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
2891-
2892-
ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
2893-
opmode, status->band);
2894-
goto handled;
2887+
goto queue;
28952888
}
28962889
case WLAN_VHT_ACTION_GROUPID_MGMT: {
28972890
if (len < IEEE80211_MIN_ACTION_SIZE + 25)

net/mac80211/vht.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,10 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
527527

528528
u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
529529

530-
if (changed > 0)
530+
if (changed > 0) {
531+
ieee80211_recalc_min_chandef(sdata);
531532
rate_control_rate_update(local, sband, sta, changed);
533+
}
532534
}
533535

534536
void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,

0 commit comments

Comments
 (0)