Skip to content

Commit

Permalink
mac80211: stop modifying HT SMPS capability
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Berg committed Feb 15, 2013
1 parent 9fb04b5 commit af0ed69
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 48 deletions.
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlegacy/4965-rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
16 changes: 7 additions & 9 deletions drivers/net/wireless/iwlegacy/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/iwlwifi/dvm/rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
17 changes: 7 additions & 10 deletions drivers/net/wireless/iwlwifi/dvm/sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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;
}

Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/iwlwifi/mvm/rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 1 addition & 4 deletions drivers/net/wireless/rt2x00/rt2x00queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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 *));
Expand Down
19 changes: 19 additions & 0 deletions net/mac80211/ht.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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;
}

Expand Down
6 changes: 1 addition & 5 deletions net/mac80211/rc80211_minstrel_ht.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand All @@ -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;

Expand Down
16 changes: 6 additions & 10 deletions net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
2 changes: 2 additions & 0 deletions net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit af0ed69

Please sign in to comment.