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) | ||||
| 		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 */ | ||||
|  | ||||
| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 *)); | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -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]; | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user