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

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.fi


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 85b27ef7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+24 −18
Original line number Diff line number Diff line
@@ -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,6 +270,10 @@ 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;

	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:
@@ -287,7 +291,9 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
		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;
}

+5 −1
Original line number Diff line number Diff line
@@ -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: