Commit cf1e05c6 authored by Eyal Shapira's avatar Eyal Shapira Committed by Johannes Berg

mac80211: handle width changes from opmode notification IE in beacon

An AP can send an operating channel width change in a beacon
opmode notification IE as long as there's a change in the nss as
well (See 802.11ac-2013 section 10.41).
So don't limit updating to nss only from an opmode notification IE.
Signed-off-by: default avatarEyal Shapira <eyalx.shapira@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a87da0cb
...@@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, ...@@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
* rc isn't initialized here yet, so ignore it * rc isn't initialized here yet, so ignore it
*/ */
__ieee80211_vht_handle_opmode(sdata, sta, __ieee80211_vht_handle_opmode(sdata, sta,
params->opmode_notif, params->opmode_notif, band);
band, false);
} }
if (ieee80211_vif_is_mesh(&sdata->vif)) if (ieee80211_vif_is_mesh(&sdata->vif))
......
...@@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); ...@@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
void ieee80211_sta_set_rx_nss(struct sta_info *sta); void ieee80211_sta_set_rx_nss(struct sta_info *sta);
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, u8 opmode, struct sta_info *sta, u8 opmode,
enum ieee80211_band band, bool nss_only); enum ieee80211_band band);
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, u8 opmode, struct sta_info *sta, u8 opmode,
enum ieee80211_band band, bool nss_only); enum ieee80211_band band);
void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta_vht_cap *vht_cap); struct ieee80211_sta_vht_cap *vht_cap);
void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
......
...@@ -3580,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -3580,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if (sta && elems.opmode_notif) if (sta && elems.opmode_notif)
ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
rx_status->band, true); rx_status->band);
mutex_unlock(&local->sta_mtx); mutex_unlock(&local->sta_mtx);
changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
......
...@@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ...@@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
ieee80211_vht_handle_opmode(rx->sdata, rx->sta, ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
opmode, status->band, opmode, status->band);
false);
goto handled; goto handled;
} }
default: default:
......
...@@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta) ...@@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta)
u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, u8 opmode, struct sta_info *sta, u8 opmode,
enum ieee80211_band band, bool nss_only) enum ieee80211_band band)
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
...@@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, ...@@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
changed |= IEEE80211_RC_NSS_CHANGED; changed |= IEEE80211_RC_NSS_CHANGED;
} }
if (nss_only)
return changed;
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
...@@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, ...@@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, u8 opmode, struct sta_info *sta, u8 opmode,
enum ieee80211_band band, bool nss_only) enum ieee80211_band band)
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
band, nss_only);
if (changed > 0) if (changed > 0)
rate_control_rate_update(local, sband, sta, changed); rate_control_rate_update(local, sband, sta, changed);
......
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