--- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h @@ -70,6 +70,8 @@ struct minstrel_mcs_group_data { }; struct minstrel_ht_sta { + struct ieee80211_tx_rate tx_rates[3]; + /* ampdu length (average, per sampling interval) */ unsigned int ampdu_len; unsigned int ampdu_packets; --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -87,6 +87,10 @@ const struct mcs_group minstrel_mcs_grou static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; +static void +minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + struct ieee80211_tx_rate *rate, int index, + bool sample, bool rtscts); /* * Perform EWMA (Exponentially Weighted Moving Average) calculation */ @@ -174,6 +178,17 @@ minstrel_ht_calc_tp(struct minstrel_priv mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); } +static void +minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) +{ + minstrel_ht_set_rate(mp, mi, &mi->tx_rates[0], mi->max_tp_rate, + false, false); + minstrel_ht_set_rate(mp, mi, &mi->tx_rates[1], mi->max_tp_rate2, + false, true); + minstrel_ht_set_rate(mp, mi, &mi->tx_rates[2], mi->max_prob_rate, + false, true); +} + /* * Update rate statistics and select new primary rates * @@ -292,6 +307,7 @@ minstrel_ht_update_stats(struct minstrel } } + minstrel_ht_update_rates(mp, mi); mi->stats_update = jiffies; } @@ -330,8 +346,8 @@ minstrel_next_sample_idx(struct minstrel } static void -minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, - bool primary) +minstrel_downgrade_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + unsigned int *idx, bool primary) { int group, orig_group; @@ -350,6 +366,7 @@ minstrel_downgrade_rate(struct minstrel_ *idx = mi->groups[group].max_tp_rate; else *idx = mi->groups[group].max_tp_rate2; + minstrel_ht_update_rates(mp, mi); break; } } @@ -450,13 +467,13 @@ minstrel_ht_tx_status(void *priv, struct if (rate->attempts > 30 && MINSTREL_FRAC(rate->success, rate->attempts) < MINSTREL_FRAC(20, 100)) - minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); + minstrel_downgrade_rate(mp, mi, &mi->max_tp_rate, true); rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); if (rate2->attempts > 30 && MINSTREL_FRAC(rate2->success, rate2->attempts) < MINSTREL_FRAC(20, 100)) - minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); + minstrel_downgrade_rate(mp, mi, &mi->max_tp_rate2, false); if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { minstrel_ht_update_stats(mp, mi); @@ -521,7 +538,6 @@ minstrel_calc_retransmit(struct minstrel static void minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, struct ieee80211_tx_rate *rate, int index, - struct ieee80211_tx_rate_control *txrc, bool sample, bool rtscts) { const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; @@ -609,6 +625,7 @@ minstrel_ht_get_rate(void *priv, struct struct minstrel_priv *mp = priv; int sample_idx; bool sample = false; + int last = 0; if (rate_control_send_low(sta, priv_sta, txrc)) return; @@ -634,11 +651,10 @@ minstrel_ht_get_rate(void *priv, struct if (sample_idx >= 0) { sample = true; minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, - txrc, true, false); + true, false); info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { - minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, - txrc, false, false); + ar[0] = mi->tx_rates[0]; } if (mp->hw->max_rates >= 3) { @@ -648,33 +664,27 @@ minstrel_ht_get_rate(void *priv, struct * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default. */ if (sample_idx >= 0) - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, - txrc, false, false); + ar[1] = mi->tx_rates[0]; else - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, - txrc, false, true); - - minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, - txrc, false, !sample); + ar[1] = mi->tx_rates[1]; - ar[3].count = 0; - ar[3].idx = -1; + ar[2] = mi->tx_rates[2]; + last = 3; } else if (mp->hw->max_rates == 2) { /* * Only 2 tx rates supported, use * sample_rate -> max_prob_rate for sampling and * max_tp_rate -> max_prob_rate by default. */ - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate, - txrc, false, !sample); - - ar[2].count = 0; - ar[2].idx = -1; + ar[1] = mi->tx_rates[2]; + last = 2; } else { /* Not using MRR, only use the first rate */ - ar[1].count = 0; - ar[1].idx = -1; + last = 1; + } + ar[last].count = 0; + ar[last].idx = -1; mi->total_packets++; @@ -766,6 +776,7 @@ minstrel_ht_update_caps(void *priv, stru if (!n_supported) goto use_legacy; + minstrel_ht_update_rates(mp, mi); return; use_legacy: