mac80211: Handle SMPS mode changes only in AP mode
authorIlan Peer <ilan.peer@intel.com>
Fri, 31 Jan 2020 11:12:53 +0000 (13:12 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 7 Feb 2020 11:47:30 +0000 (12:47 +0100)
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: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/20200131111300.891737-17-luca@coelho.fi
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/he.c
net/mac80211/ht.c
net/mac80211/rx.c

index 5245c19f39bf568f2d1624758287f23d0e5c0bd5..1087f715338b5626e81e15bd3c1bfc83bbff5b4a 100644 (file)
@@ -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"
index a2e4d6b8fd98f964e3babe352132ba7dc6575a13..a8e144fd02f126305b8a132e69e8aae6cb0ddaea 100644 (file)
@@ -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;
 }
 
index 619c223f1cded9249db7d3f0b29679fe540b1eeb..ec3a04a1db202984659b1fd67e8250d2dcab5eed 100644 (file)
@@ -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: