aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/rc80211_minstrel.c71
-rw-r--r--net/mac80211/rc80211_minstrel.h8
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c6
3 files changed, 49 insertions, 36 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index f8d99a54798f..1c36c9b4fa4a 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -69,14 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
69 return i; 69 return i;
70} 70}
71 71
72/* find & sort topmost throughput rates */
73static inline void
74minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
75{
76 int j = MAX_THR_RATES;
77
78 while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp)
79 j--;
80 if (j < MAX_THR_RATES - 1)
81 memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
82 if (j < MAX_THR_RATES)
83 tp_list[j] = i;
84}
85
72static void 86static void
73minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) 87minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
74{ 88{
75 u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0; 89 u8 tmp_tp_rate[MAX_THR_RATES];
76 u32 max_prob = 0, index_max_prob = 0; 90 u8 tmp_prob_rate = 0;
77 u32 usecs; 91 u32 usecs;
78 int i; 92 int i;
79 93
94 for (i=0; i < MAX_THR_RATES; i++)
95 tmp_tp_rate[i] = 0;
96
80 for (i = 0; i < mi->n_rates; i++) { 97 for (i = 0; i < mi->n_rates; i++) {
81 struct minstrel_rate *mr = &mi->r[i]; 98 struct minstrel_rate *mr = &mi->r[i];
82 99
@@ -120,35 +137,27 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
120 } 137 }
121 if (!mr->adjusted_retry_count) 138 if (!mr->adjusted_retry_count)
122 mr->adjusted_retry_count = 2; 139 mr->adjusted_retry_count = 2;
123 }
124 140
125 for (i = 0; i < mi->n_rates; i++) { 141 minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate);
126 struct minstrel_rate *mr = &mi->r[i]; 142
127 if (max_tp < mr->cur_tp) { 143 /* To determine the most robust rate (max_prob_rate) used at
128 index_max_tp = i; 144 * 3rd mmr stage we distinct between two cases:
129 max_tp = mr->cur_tp; 145 * (1) if any success probabilitiy >= 95%, out of those rates
130 } 146 * choose the maximum throughput rate as max_prob_rate
131 if (max_prob < mr->probability) { 147 * (2) if all success probabilities < 95%, the rate with
132 index_max_prob = i; 148 * highest success probability is choosen as max_prob_rate */
133 max_prob = mr->probability; 149 if (mr->probability >= MINSTREL_FRAC(95,100)) {
150 if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp)
151 tmp_prob_rate = i;
152 } else {
153 if (mr->probability >= mi->r[tmp_prob_rate].probability)
154 tmp_prob_rate = i;
134 } 155 }
135 } 156 }
136 157
137 max_tp = 0; 158 /* Assign the new rate set */
138 for (i = 0; i < mi->n_rates; i++) { 159 memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate));
139 struct minstrel_rate *mr = &mi->r[i]; 160 mi->max_prob_rate = tmp_prob_rate;
140
141 if (i == index_max_tp)
142 continue;
143
144 if (max_tp < mr->cur_tp) {
145 index_max_tp2 = i;
146 max_tp = mr->cur_tp;
147 }
148 }
149 mi->max_tp_rate = index_max_tp;
150 mi->max_tp_rate2 = index_max_tp2;
151 mi->max_prob_rate = index_max_prob;
152 161
153 /* Reset update timer */ 162 /* Reset update timer */
154 mi->stats_update = jiffies; 163 mi->stats_update = jiffies;
@@ -254,7 +263,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
254 sampling_ratio = mp->lookaround_rate; 263 sampling_ratio = mp->lookaround_rate;
255 264
256 /* init rateindex [ndx] with max throughput rate */ 265 /* init rateindex [ndx] with max throughput rate */
257 ndx = mi->max_tp_rate; 266 ndx = mi->max_tp_rate[0];
258 267
259 /* increase sum packet counter */ 268 /* increase sum packet counter */
260 mi->packet_count++; 269 mi->packet_count++;
@@ -322,7 +331,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
322 * to use it, as this only wastes precious airtime */ 331 * to use it, as this only wastes precious airtime */
323 if (!mrr_capable && rate_sampling && 332 if (!mrr_capable && rate_sampling &&
324 (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) 333 (mi->r[ndx].probability > MINSTREL_FRAC(95, 100)))
325 ndx = mi->max_tp_rate; 334 ndx = mi->max_tp_rate[0];
326 335
327 /* mrr setup for 1st stage */ 336 /* mrr setup for 1st stage */
328 ar[0].idx = mi->r[ndx].rix; 337 ar[0].idx = mi->r[ndx].rix;
@@ -342,9 +351,9 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
342 if (indirect_rate_sampling) 351 if (indirect_rate_sampling)
343 mrr_ndx[0] = sample_ndx; 352 mrr_ndx[0] = sample_ndx;
344 else 353 else
345 mrr_ndx[0] = mi->max_tp_rate; 354 mrr_ndx[0] = mi->max_tp_rate[0];
346 } else { 355 } else {
347 mrr_ndx[0] = mi->max_tp_rate2; 356 mrr_ndx[0] = mi->max_tp_rate[1];
348 } 357 }
349 358
350 /* mrr setup for 3rd & 4th stage */ 359 /* mrr setup for 3rd & 4th stage */
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index a0ccc5779910..85ebf42cb46d 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -18,6 +18,9 @@
18#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) 18#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
19#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) 19#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
20 20
21/* number of highest throughput rates to consider*/
22#define MAX_THR_RATES 4
23
21/* 24/*
22 * Perform EWMA (Exponentially Weighted Moving Average) calculation 25 * Perform EWMA (Exponentially Weighted Moving Average) calculation
23 */ 26 */
@@ -65,9 +68,8 @@ struct minstrel_sta_info {
65 68
66 unsigned int lowest_rix; 69 unsigned int lowest_rix;
67 70
68 unsigned int max_tp_rate; 71 u8 max_tp_rate[MAX_THR_RATES];
69 unsigned int max_tp_rate2; 72 u8 max_prob_rate;
70 unsigned int max_prob_rate;
71 unsigned int packet_count; 73 unsigned int packet_count;
72 unsigned int sample_count; 74 unsigned int sample_count;
73 int sample_deferred; 75 int sample_deferred;
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index c0ebfaca6ba0..d1048348d399 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -73,8 +73,10 @@ minstrel_stats_open(struct inode *inode, struct file *file)
73 for (i = 0; i < mi->n_rates; i++) { 73 for (i = 0; i < mi->n_rates; i++) {
74 struct minstrel_rate *mr = &mi->r[i]; 74 struct minstrel_rate *mr = &mi->r[i];
75 75
76 *(p++) = (i == mi->max_tp_rate) ? 'T' : ' '; 76 *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
77 *(p++) = (i == mi->max_tp_rate2) ? 't' : ' '; 77 *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
78 *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' ';
79 *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' ';
78 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' '; 80 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
79 p += sprintf(p, "%3u%s", mr->bitrate / 2, 81 p += sprintf(p, "%3u%s", mr->bitrate / 2,
80 (mr->bitrate & 1 ? ".5" : " ")); 82 (mr->bitrate & 1 ? ".5" : " "));