Commit af0ed69b authored by Johannes Berg's avatar Johannes Berg

mac80211: stop modifying HT SMPS capability

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