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: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
9fb04b501a
commit
af0ed69bad
|
@ -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)
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
__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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
* 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 {
|
||||||
* 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 {
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue