168 lines
4.9 KiB
Diff
168 lines
4.9 KiB
Diff
|
--- 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:
|