Commit c4d800dc authored by Ilan Peer's avatar Ilan Peer Committed by Johannes Berg

mac80211: Handle SMPS mode changes only in AP mode

According to IEEE802.11 specifications the SM power save field
in the HT capability IE and the HE extended capability IE is valid
only in (re)association frames and should be ignored otherwise.
Remove code paths that handled this also for non AP modes.
Signed-off-by: default avatarIlan Peer <ilan.peer@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/20200131111300.891737-17-luca@coelho.fiSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 85b27ef7
......@@ -3,7 +3,7 @@
* HE handling
*
* Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2019 Intel Corporation
* Copyright(c) 2019 - 2020 Intel Corporation
*/
#include "ieee80211_i.h"
......
......@@ -9,6 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright 2017 Intel Deutschland GmbH
* Copyright(c) 2020 Intel Corporation
*/
#include <linux/ieee80211.h>
......@@ -144,7 +145,6 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
int i, max_tx_streams;
bool changed;
enum ieee80211_sta_rx_bandwidth bw;
enum ieee80211_smps_mode smps_mode;
memset(&ht_cap, 0, sizeof(ht_cap));
......@@ -270,24 +270,30 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
switch ((ht_cap.cap & IEEE80211_HT_CAP_SM_PS)
>> IEEE80211_HT_CAP_SM_PS_SHIFT) {
case WLAN_HT_CAP_SM_PS_INVALID:
case WLAN_HT_CAP_SM_PS_STATIC:
smps_mode = IEEE80211_SMPS_STATIC;
break;
case WLAN_HT_CAP_SM_PS_DYNAMIC:
smps_mode = IEEE80211_SMPS_DYNAMIC;
break;
case WLAN_HT_CAP_SM_PS_DISABLED:
smps_mode = IEEE80211_SMPS_OFF;
break;
}
if (smps_mode != sta->sta.smps_mode)
changed = true;
sta->sta.smps_mode = smps_mode;
if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
enum ieee80211_smps_mode smps_mode;
switch ((ht_cap.cap & IEEE80211_HT_CAP_SM_PS)
>> IEEE80211_HT_CAP_SM_PS_SHIFT) {
case WLAN_HT_CAP_SM_PS_INVALID:
case WLAN_HT_CAP_SM_PS_STATIC:
smps_mode = IEEE80211_SMPS_STATIC;
break;
case WLAN_HT_CAP_SM_PS_DYNAMIC:
smps_mode = IEEE80211_SMPS_DYNAMIC;
break;
case WLAN_HT_CAP_SM_PS_DISABLED:
smps_mode = IEEE80211_SMPS_OFF;
break;
}
if (smps_mode != sta->sta.smps_mode)
changed = true;
sta->sta.smps_mode = smps_mode;
} else {
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
}
return changed;
}
......
......@@ -6,7 +6,7 @@
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018-2019 Intel Corporation
* Copyright (C) 2018-2020 Intel Corporation
*/
#include <linux/jiffies.h>
......@@ -3082,6 +3082,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
enum ieee80211_smps_mode smps_mode;
struct sta_opmode_info sta_opmode = {};
if (sdata->vif.type != NL80211_IFTYPE_AP &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
goto handled;
/* convert to HT capability */
switch (mgmt->u.action.u.ht_smps.smps_control) {
case WLAN_HT_SMPS_CONTROL_DISABLED:
......
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