diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/rc.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 34 | 
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 9e3649a3d5c..4f130188113 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -603,7 +603,8 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,  static u8 ath_rc_get_highest_rix(struct ath_softc *sc,  			         struct ath_rate_priv *ath_rc_priv,  				 const struct ath_rate_table *rate_table, -				 int *is_probing) +				 int *is_probing, +				 bool legacy)  {  	u32 best_thruput, this_thruput, now_msec;  	u8 rate, next_rate, best_rate, maxindex, minindex; @@ -624,6 +625,8 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,  		u8 per_thres;  		rate = ath_rc_priv->valid_rate_index[index]; +		if (legacy && !(rate_table->info[rate].rate_flags & RC_LEGACY)) +			continue;  		if (rate > ath_rc_priv->rate_max_phy)  			continue; @@ -767,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,  	struct ieee80211_tx_rate *rates = tx_info->control.rates;  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;  	__le16 fc = hdr->frame_control; -	u8 try_per_rate, i = 0, rix; +	u8 try_per_rate, i = 0, rix, high_rix;  	int is_probe = 0;  	if (rate_control_send_low(sta, priv_sta, txrc)) @@ -786,7 +789,9 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,  	try_per_rate = 4;  	rate_table = ath_rc_priv->rate_table; -	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); +	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, +				     &is_probe, false); +	high_rix = rix;  	/*  	 * If we're in HT mode and both us and our peer supports LDPC. @@ -822,10 +827,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,  	}  	/* Fill in the other rates for multirate retry */ -	for ( ; i < 4; i++) { -		/* Use twice the number of tries for the last MRR segment. */ -		if (i + 1 == 4) -			try_per_rate = 8; +	for ( ; i < 3; i++) {  		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);  		/* All other rates in the series have RTS enabled */ @@ -833,6 +835,24 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,  				       try_per_rate, rix, 1);  	} +	/* Use twice the number of tries for the last MRR segment. */ +	try_per_rate = 8; + +	/* +	 * Use a legacy rate as last retry to ensure that the frame +	 * is tried in both MCS and legacy rates. +	 */ +	if ((rates[2].flags & IEEE80211_TX_RC_MCS) && +	    (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) || +	    (ath_rc_priv->per[high_rix] > 45))) +		rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, +				&is_probe, true); +	else +		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); + +	/* All other rates in the series have RTS enabled */ +	ath_rc_rate_set_series(rate_table, &rates[i], txrc, +			       try_per_rate, rix, 1);  	/*  	 * NB:Change rate series to enable aggregation when operating  	 * at lower MCS rates. When first rate in series is MCS2  |