aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_minstrel.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rc80211_minstrel.c')
-rw-r--r--net/mac80211/rc80211_minstrel.c109
1 files changed, 55 insertions, 54 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index f6d69dab07a3..2b3b490a6073 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -126,7 +126,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
126 mr->adjusted_retry_count = mr->retry_count >> 1; 126 mr->adjusted_retry_count = mr->retry_count >> 1;
127 if (mr->adjusted_retry_count > 2) 127 if (mr->adjusted_retry_count > 2)
128 mr->adjusted_retry_count = 2; 128 mr->adjusted_retry_count = 2;
129 mr->sample_limit = 4;
129 } else { 130 } else {
131 mr->sample_limit = -1;
130 mr->adjusted_retry_count = mr->retry_count; 132 mr->adjusted_retry_count = mr->retry_count;
131 } 133 }
132 if (!mr->adjusted_retry_count) 134 if (!mr->adjusted_retry_count)
@@ -169,30 +171,20 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
169{ 171{
170 struct minstrel_sta_info *mi = priv_sta; 172 struct minstrel_sta_info *mi = priv_sta;
171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 173 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
172 struct ieee80211_tx_altrate *ar = info->status.retries; 174 struct ieee80211_tx_rate *ar = info->status.rates;
173 struct minstrel_priv *mp = priv; 175 int i, ndx;
174 int i, ndx, tries; 176 int success;
175 int success = 0;
176
177 if (!info->status.excessive_retries)
178 success = 1;
179 177
180 if (!mp->has_mrr || (ar[0].rate_idx < 0)) { 178 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
181 ndx = rix_to_ndx(mi, info->tx_rate_idx);
182 tries = info->status.retry_count + 1;
183 mi->r[ndx].success += success;
184 mi->r[ndx].attempts += tries;
185 return;
186 }
187 179
188 for (i = 0; i < 4; i++) { 180 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
189 if (ar[i].rate_idx < 0) 181 if (ar[i].idx < 0)
190 break; 182 break;
191 183
192 ndx = rix_to_ndx(mi, ar[i].rate_idx); 184 ndx = rix_to_ndx(mi, ar[i].idx);
193 mi->r[ndx].attempts += ar[i].limit + 1; 185 mi->r[ndx].attempts += ar[i].count;
194 186
195 if ((i != 3) && (ar[i + 1].rate_idx < 0)) 187 if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
196 mi->r[ndx].success += success; 188 mi->r[ndx].success += success;
197 } 189 }
198 190
@@ -210,9 +202,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr,
210{ 202{
211 unsigned int retry = mr->adjusted_retry_count; 203 unsigned int retry = mr->adjusted_retry_count;
212 204
213 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) 205 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
214 retry = max(2U, min(mr->retry_count_rtscts, retry)); 206 retry = max(2U, min(mr->retry_count_rtscts, retry));
215 else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) 207 else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
216 retry = max(2U, min(mr->retry_count_cts, retry)); 208 retry = max(2U, min(mr->retry_count_cts, retry));
217 return retry; 209 return retry;
218} 210}
@@ -233,15 +225,16 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi)
233 return sample_ndx; 225 return sample_ndx;
234} 226}
235 227
236void 228static void
237minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, 229minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
238 struct ieee80211_sta *sta, void *priv_sta, 230 void *priv_sta, struct ieee80211_tx_rate_control *txrc)
239 struct sk_buff *skb, struct rate_selection *sel)
240{ 231{
232 struct sk_buff *skb = txrc->skb;
233 struct ieee80211_supported_band *sband = txrc->sband;
241 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 234 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
242 struct minstrel_sta_info *mi = priv_sta; 235 struct minstrel_sta_info *mi = priv_sta;
243 struct minstrel_priv *mp = priv; 236 struct minstrel_priv *mp = priv;
244 struct ieee80211_tx_altrate *ar = info->control.retries; 237 struct ieee80211_tx_rate *ar = info->control.rates;
245 unsigned int ndx, sample_ndx = 0; 238 unsigned int ndx, sample_ndx = 0;
246 bool mrr; 239 bool mrr;
247 bool sample_slower = false; 240 bool sample_slower = false;
@@ -251,16 +244,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
251 int sample_rate; 244 int sample_rate;
252 245
253 if (!sta || !mi || use_low_rate(skb)) { 246 if (!sta || !mi || use_low_rate(skb)) {
254 sel->rate_idx = rate_lowest_index(sband, sta); 247 ar[0].idx = rate_lowest_index(sband, sta);
248 ar[0].count = mp->max_retry;
255 return; 249 return;
256 } 250 }
257 251
258 mrr = mp->has_mrr; 252 mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
259
260 /* mac80211 does not allow mrr for RTS/CTS */
261 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
262 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
263 mrr = false;
264 253
265 if (time_after(jiffies, mi->stats_update + (mp->update_interval * 254 if (time_after(jiffies, mi->stats_update + (mp->update_interval *
266 HZ) / 1000)) 255 HZ) / 1000))
@@ -278,7 +267,8 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
278 (mi->sample_count + mi->sample_deferred / 2); 267 (mi->sample_count + mi->sample_deferred / 2);
279 268
280 /* delta > 0: sampling required */ 269 /* delta > 0: sampling required */
281 if (delta > 0) { 270 if ((delta > 0) && (mrr || !mi->prev_sample)) {
271 struct minstrel_rate *msr;
282 if (mi->packet_count >= 10000) { 272 if (mi->packet_count >= 10000) {
283 mi->sample_deferred = 0; 273 mi->sample_deferred = 0;
284 mi->sample_count = 0; 274 mi->sample_count = 0;
@@ -297,13 +287,20 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
297 } 287 }
298 288
299 sample_ndx = minstrel_get_next_sample(mi); 289 sample_ndx = minstrel_get_next_sample(mi);
290 msr = &mi->r[sample_ndx];
300 sample = true; 291 sample = true;
301 sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time > 292 sample_slower = mrr && (msr->perfect_tx_time >
302 mi->r[ndx].perfect_tx_time); 293 mi->r[ndx].perfect_tx_time);
303 294
304 if (!sample_slower) { 295 if (!sample_slower) {
305 ndx = sample_ndx; 296 if (msr->sample_limit != 0) {
306 mi->sample_count++; 297 ndx = sample_ndx;
298 mi->sample_count++;
299 if (msr->sample_limit > 0)
300 msr->sample_limit--;
301 } else {
302 sample = false;
303 }
307 } else { 304 } else {
308 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark 305 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
309 * packets that have the sampling rate deferred to the 306 * packets that have the sampling rate deferred to the
@@ -315,13 +312,22 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
315 mi->sample_deferred++; 312 mi->sample_deferred++;
316 } 313 }
317 } 314 }
318 sel->rate_idx = mi->r[ndx].rix; 315 mi->prev_sample = sample;
319 info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info); 316
317 /* If we're not using MRR and the sampling rate already
318 * has a probability of >95%, we shouldn't be attempting
319 * to use it, as this only wastes precious airtime */
320 if (!mrr && sample && (mi->r[ndx].probability > 17100))
321 ndx = mi->max_tp_rate;
322
323 ar[0].idx = mi->r[ndx].rix;
324 ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
320 325
321 if (!mrr) { 326 if (!mrr) {
322 ar[0].rate_idx = mi->lowest_rix; 327 if (!sample)
323 ar[0].limit = mp->max_retry; 328 ar[0].count = mp->max_retry;
324 ar[1].rate_idx = -1; 329 ar[1].idx = mi->lowest_rix;
330 ar[1].count = mp->max_retry;
325 return; 331 return;
326 } 332 }
327 333
@@ -336,9 +342,9 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
336 } 342 }
337 mrr_ndx[1] = mi->max_prob_rate; 343 mrr_ndx[1] = mi->max_prob_rate;
338 mrr_ndx[2] = 0; 344 mrr_ndx[2] = 0;
339 for (i = 0; i < 3; i++) { 345 for (i = 1; i < 4; i++) {
340 ar[i].rate_idx = mi->r[mrr_ndx[i]].rix; 346 ar[i].idx = mi->r[mrr_ndx[i - 1]].rix;
341 ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count; 347 ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count;
342 } 348 }
343} 349}
344 350
@@ -415,6 +421,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
415 421
416 /* calculate maximum number of retransmissions before 422 /* calculate maximum number of retransmissions before
417 * fallback (based on maximum segment size) */ 423 * fallback (based on maximum segment size) */
424 mr->sample_limit = -1;
418 mr->retry_count = 1; 425 mr->retry_count = 1;
419 mr->retry_count_cts = 1; 426 mr->retry_count_cts = 1;
420 mr->retry_count_rtscts = 1; 427 mr->retry_count_rtscts = 1;
@@ -500,11 +507,6 @@ minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
500 kfree(mi); 507 kfree(mi);
501} 508}
502 509
503static void
504minstrel_clear(void *priv)
505{
506}
507
508static void * 510static void *
509minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 511minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
510{ 512{
@@ -532,13 +534,13 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
532 /* maximum time that the hw is allowed to stay in one MRR segment */ 534 /* maximum time that the hw is allowed to stay in one MRR segment */
533 mp->segment_size = 6000; 535 mp->segment_size = 6000;
534 536
535 if (hw->max_altrate_tries > 0) 537 if (hw->max_rate_tries > 0)
536 mp->max_retry = hw->max_altrate_tries; 538 mp->max_retry = hw->max_rate_tries;
537 else 539 else
538 /* safe default, does not necessarily have to match hw properties */ 540 /* safe default, does not necessarily have to match hw properties */
539 mp->max_retry = 7; 541 mp->max_retry = 7;
540 542
541 if (hw->max_altrates >= 3) 543 if (hw->max_rates >= 4)
542 mp->has_mrr = true; 544 mp->has_mrr = true;
543 545
544 mp->hw = hw; 546 mp->hw = hw;
@@ -558,7 +560,6 @@ static struct rate_control_ops mac80211_minstrel = {
558 .tx_status = minstrel_tx_status, 560 .tx_status = minstrel_tx_status,
559 .get_rate = minstrel_get_rate, 561 .get_rate = minstrel_get_rate,
560 .rate_init = minstrel_rate_init, 562 .rate_init = minstrel_rate_init,
561 .clear = minstrel_clear,
562 .alloc = minstrel_alloc, 563 .alloc = minstrel_alloc,
563 .free = minstrel_free, 564 .free = minstrel_free,
564 .alloc_sta = minstrel_alloc_sta, 565 .alloc_sta = minstrel_alloc_sta,