aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_minstrel.c
diff options
context:
space:
mode:
authorThomas Huehn <thomas@net.t-labs.tu-berlin.de>2015-03-24 16:09:40 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-04-01 14:44:32 -0400
commit6a27b2c40b4829e625bc1dfdd0705c5ece720ab4 (patch)
tree78581e6b867299e807b9d31febe9655ba5579d7e /net/mac80211/rc80211_minstrel.c
parent9134073bc693633b5e1f1a7252c93b3fb262aae4 (diff)
mac80211: restructure per-rate throughput calculation into function
This patch moves Minstrels and Minstrel-HTs per-rate throughput calculation (EWMA(thr)) into a dedicated function to be called. Therefore the variable "unsigned int cur_tp" within struct "minstrel_rate_stats" becomes obsolete. and is removed to free up its space. Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de> Acked-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rc80211_minstrel.c')
-rw-r--r--net/mac80211/rc80211_minstrel.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index c86e42b67908..61a857bca971 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -69,14 +69,32 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
69 return i; 69 return i;
70} 70}
71 71
72/* return current EMWA throughput */
73int minstrel_get_tp_avg(struct minstrel_rate *mr)
74{
75 int usecs;
76
77 usecs = mr->perfect_tx_time;
78 if (!usecs)
79 usecs = 1000000;
80
81 /* reset thr. below 10% success */
82 if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100))
83 return 0;
84 else
85 return MINSTREL_TRUNC(mr->stats.prob_ewma * (100000 / usecs));
86}
87
72/* find & sort topmost throughput rates */ 88/* find & sort topmost throughput rates */
73static inline void 89static inline void
74minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) 90minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
75{ 91{
76 int j = MAX_THR_RATES; 92 int j = MAX_THR_RATES;
77 93
78 while (j > 0 && mi->r[i].stats.cur_tp > mi->r[tp_list[j - 1]].stats.cur_tp) 94 while (j > 0 && (minstrel_get_tp_avg(&mi->r[i]) >
95 minstrel_get_tp_avg(&mi->r[tp_list[j - 1]])))
79 j--; 96 j--;
97
80 if (j < MAX_THR_RATES - 1) 98 if (j < MAX_THR_RATES - 1)
81 memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); 99 memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
82 if (j < MAX_THR_RATES) 100 if (j < MAX_THR_RATES)
@@ -158,8 +176,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
158{ 176{
159 u8 tmp_tp_rate[MAX_THR_RATES]; 177 u8 tmp_tp_rate[MAX_THR_RATES];
160 u8 tmp_prob_rate = 0; 178 u8 tmp_prob_rate = 0;
161 u32 usecs; 179 int i, tmp_cur_tp, tmp_prob_tp;
162 int i;
163 180
164 for (i = 0; i < MAX_THR_RATES; i++) 181 for (i = 0; i < MAX_THR_RATES; i++)
165 tmp_tp_rate[i] = 0; 182 tmp_tp_rate[i] = 0;
@@ -168,19 +185,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
168 struct minstrel_rate *mr = &mi->r[i]; 185 struct minstrel_rate *mr = &mi->r[i];
169 struct minstrel_rate_stats *mrs = &mi->r[i].stats; 186 struct minstrel_rate_stats *mrs = &mi->r[i].stats;
170 187
171 usecs = mr->perfect_tx_time;
172 if (!usecs)
173 usecs = 1000000;
174
175 /* Update success probabilities per rate */ 188 /* Update success probabilities per rate */
176 minstrel_calc_rate_stats(mrs); 189 minstrel_calc_rate_stats(mrs);
177 190
178 /* Update throughput per rate, reset thr. below 10% success */
179 if (mrs->prob_ewma < MINSTREL_FRAC(10, 100))
180 mrs->cur_tp = 0;
181 else
182 mrs->cur_tp = mrs->prob_ewma * (1000000 / usecs);
183
184 /* Sample less often below the 10% chance of success. 191 /* Sample less often below the 10% chance of success.
185 * Sample less often above the 95% chance of success. */ 192 * Sample less often above the 95% chance of success. */
186 if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || 193 if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
@@ -205,7 +212,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
205 * (2) if all success probabilities < 95%, the rate with 212 * (2) if all success probabilities < 95%, the rate with
206 * highest success probability is chosen as max_prob_rate */ 213 * highest success probability is chosen as max_prob_rate */
207 if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) { 214 if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
208 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) 215 tmp_cur_tp = minstrel_get_tp_avg(mr);
216 tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate]);
217 if (tmp_cur_tp >= tmp_prob_tp)
209 tmp_prob_rate = i; 218 tmp_prob_rate = i;
210 } else { 219 } else {
211 if (mrs->prob_ewma >= mi->r[tmp_prob_rate].stats.prob_ewma) 220 if (mrs->prob_ewma >= mi->r[tmp_prob_rate].stats.prob_ewma)
@@ -676,11 +685,15 @@ static u32 minstrel_get_expected_throughput(void *priv_sta)
676{ 685{
677 struct minstrel_sta_info *mi = priv_sta; 686 struct minstrel_sta_info *mi = priv_sta;
678 int idx = mi->max_tp_rate[0]; 687 int idx = mi->max_tp_rate[0];
688 int tmp_cur_tp;
679 689
680 /* convert pkt per sec in kbps (1200 is the average pkt size used for 690 /* convert pkt per sec in kbps (1200 is the average pkt size used for
681 * computing cur_tp 691 * computing cur_tp
682 */ 692 */
683 return MINSTREL_TRUNC(mi->r[idx].stats.cur_tp) * 1200 * 8 / 1024; 693 tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx]);
694 tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
695
696 return tmp_cur_tp;
684} 697}
685 698
686const struct rate_control_ops mac80211_minstrel = { 699const struct rate_control_ops mac80211_minstrel = {