mac80211: stop modifying HT SMPS capability
authorJohannes Berg <johannes.berg@intel.com>
Tue, 12 Feb 2013 13:21:00 +0000 (14:21 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 15 Feb 2013 08:41:41 +0000 (09:41 +0100)
Instead of modifying the HT SMPS capability field
for stations, track the SMPS mode explicitly in a
new field in the station struct and use it in the
drivers that care about it. This simplifies the
code using it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlegacy/4965-rs.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/dvm/rs.c
drivers/net/wireless/iwlwifi/dvm/sta.c
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/rt2x00/rt2x00queue.c
include/net/mac80211.h
net/mac80211/ht.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/sta_info.c

index f3b8e91..e8324b5 100644 (file)
@@ -1183,8 +1183,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) ==
-           WLAN_HT_CAP_SM_PS_STATIC)
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
                return -1;
 
        /* Need both Tx chains/antennas to support MIMO */
index 1f59860..4c9aafb 100644 (file)
@@ -1830,32 +1830,30 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
        __le32 sta_flags;
-       u8 mimo_ps_mode;
 
        if (!sta || !sta_ht_inf->ht_supported)
                goto done;
 
-       mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
        D_ASSOC("spatial multiplexing power save mode: %s\n",
-               (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" :
-               (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? "dynamic" :
+               (sta->smps_mode == IEEE80211_SMPS_STATIC) ? "static" :
+               (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ? "dynamic" :
                "disabled");
 
        sta_flags = il->stations[idx].sta.station_flags;
 
        sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
 
-       switch (mimo_ps_mode) {
-       case WLAN_HT_CAP_SM_PS_STATIC:
+       switch (sta->smps_mode) {
+       case IEEE80211_SMPS_STATIC:
                sta_flags |= STA_FLG_MIMO_DIS_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DYNAMIC:
+       case IEEE80211_SMPS_DYNAMIC:
                sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DISABLED:
+       case IEEE80211_SMPS_OFF:
                break;
        default:
-               IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+               IL_WARN("Invalid MIMO PS mode %d\n", sta->smps_mode);
                break;
        }
 
index b25de02..abe3042 100644 (file)
@@ -1289,8 +1289,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
-                                               == WLAN_HT_CAP_SM_PS_STATIC)
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
                return -1;
 
        /* Need both Tx chains/antennas to support MIMO */
@@ -1345,8 +1344,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
-                                               == WLAN_HT_CAP_SM_PS_STATIC)
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
                return -1;
 
        /* Need both Tx chains/antennas to support MIMO */
index 6deab38..d5faf74 100644 (file)
@@ -196,7 +196,6 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
                                  __le32 *flags, __le32 *mask)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
-       u8 mimo_ps_mode;
 
        *mask = STA_FLG_RTS_MIMO_PROT_MSK |
                STA_FLG_MIMO_DIS_MSK |
@@ -208,26 +207,24 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
        if (!sta || !sta_ht_inf->ht_supported)
                return;
 
-       mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
-
        IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n",
                        sta->addr,
-                       (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
+                       (sta->smps_mode == IEEE80211_SMPS_STATIC) ?
                        "static" :
-                       (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
+                       (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ?
                        "dynamic" : "disabled");
 
-       switch (mimo_ps_mode) {
-       case WLAN_HT_CAP_SM_PS_STATIC:
+       switch (sta->smps_mode) {
+       case IEEE80211_SMPS_STATIC:
                *flags |= STA_FLG_MIMO_DIS_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DYNAMIC:
+       case IEEE80211_SMPS_DYNAMIC:
                *flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DISABLED:
+       case IEEE80211_SMPS_OFF:
                break;
        default:
-               IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
+               IWL_WARN(priv, "Invalid MIMO PS mode %d\n", sta->smps_mode);
                break;
        }
 
index 8ba36e5..56b636d 100644 (file)
@@ -1229,8 +1229,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
        if (!sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
-                                               == WLAN_HT_CAP_SM_PS_STATIC)
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
                return -1;
 
        /* Need both Tx chains/antennas to support MIMO */
@@ -1282,8 +1281,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
        if (!sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
-                                               == WLAN_HT_CAP_SM_PS_STATIC)
+       if (sta->smps_mode == IEEE80211_SMPS_STATIC)
                return -1;
 
        /* Need both Tx chains/antennas to support MIMO */
index f35d85a..9503e69 100644 (file)
@@ -343,10 +343,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
                 * when using more then one tx stream (>MCS7).
                 */
                if (sta && txdesc->u.ht.mcs > 7 &&
-                   ((sta->ht_cap.cap &
-                     IEEE80211_HT_CAP_SM_PS) >>
-                    IEEE80211_HT_CAP_SM_PS_SHIFT) ==
-                   WLAN_HT_CAP_SM_PS_DYNAMIC)
+                   sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
                        __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
        } else {
                txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
index 54e2add..f7eba13 100644 (file)
@@ -1245,6 +1245,7 @@ enum ieee80211_sta_rx_bandwidth {
  *     station can receive at the moment, changed by operating mode
  *     notifications and capabilities. The value is only valid after
  *     the station moves to associated state.
+ * @smps_mode: current SMPS mode (off, static or dynamic)
  */
 struct ieee80211_sta {
        u32 supp_rates[IEEE80211_NUM_BANDS];
@@ -1257,6 +1258,7 @@ struct ieee80211_sta {
        u8 max_sp;
        u8 rx_nss;
        enum ieee80211_sta_rx_bandwidth bandwidth;
+       enum ieee80211_smps_mode smps_mode;
 
        /* must be last */
        u8 drv_priv[0] __aligned(sizeof(void *));
index b84147a..0db25d4 100644 (file)
@@ -102,6 +102,7 @@ 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));
 
@@ -216,6 +217,24 @@ 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;
+
        return changed;
 }
 
index 6176c71..3af141c 100644 (file)
@@ -808,7 +808,6 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
        int ack_dur;
        int stbc;
        int i;
-       unsigned int smps;
 
        /* fall back to the old minstrel for legacy stations */
        if (!sta->ht_cap.ht_supported)
@@ -844,9 +843,6 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
        if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
                mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
 
-       smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >>
-               IEEE80211_HT_CAP_SM_PS_SHIFT;
-
        for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
                mi->groups[i].supported = 0;
                if (i == MINSTREL_CCK_GROUP) {
@@ -869,7 +865,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
                        continue;
 
                /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
-               if (smps == WLAN_HT_CAP_SM_PS_STATIC &&
+               if (sta->smps_mode == IEEE80211_SMPS_STATIC &&
                    minstrel_mcs_groups[i].streams > 1)
                        continue;
 
index 296a4ae..3acb70b 100644 (file)
@@ -2375,31 +2375,27 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                switch (mgmt->u.action.u.ht_smps.action) {
                case WLAN_HT_ACTION_SMPS: {
                        struct ieee80211_supported_band *sband;
-                       u8 smps;
+                       enum ieee80211_smps_mode smps_mode;
 
                        /* convert to HT capability */
                        switch (mgmt->u.action.u.ht_smps.smps_control) {
                        case WLAN_HT_SMPS_CONTROL_DISABLED:
-                               smps = WLAN_HT_CAP_SM_PS_DISABLED;
+                               smps_mode = IEEE80211_SMPS_OFF;
                                break;
                        case WLAN_HT_SMPS_CONTROL_STATIC:
-                               smps = WLAN_HT_CAP_SM_PS_STATIC;
+                               smps_mode = IEEE80211_SMPS_STATIC;
                                break;
                        case WLAN_HT_SMPS_CONTROL_DYNAMIC:
-                               smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
+                               smps_mode = IEEE80211_SMPS_DYNAMIC;
                                break;
                        default:
                                goto invalid;
                        }
-                       smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
 
                        /* if no change do nothing */
-                       if ((rx->sta->sta.ht_cap.cap &
-                                       IEEE80211_HT_CAP_SM_PS) == smps)
+                       if (rx->sta->sta.smps_mode == smps_mode)
                                goto handled;
-
-                       rx->sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS;
-                       rx->sta->sta.ht_cap.cap |= smps;
+                       rx->sta->sta.smps_mode = smps_mode;
 
                        sband = rx->local->hw.wiphy->bands[status->band];
 
index 0794b90..a79ce82 100644 (file)
@@ -375,6 +375,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        for (i = 0; i < IEEE80211_NUM_TIDS; i++)
                sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
 
+       sta->sta.smps_mode = IEEE80211_SMPS_OFF;
+
        sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
 
        return sta;