diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-04-22 10:14:43 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-04-22 10:16:41 -0400 |
commit | 06d961a8e210035bff7e82f466107f9ab4a8fd94 (patch) | |
tree | 710ff735b499b709c280e88f9f3bda8c46276064 /net/mac80211/rc80211_minstrel.c | |
parent | a85666627b7f10c4229716b6ffaffcf196a128ca (diff) |
mac80211/minstrel: use the new rate control API
Pass the rate selection table to mac80211 from minstrel_update_stats.
Only rates for sample attempts are set in info->control.rates, with deferred
sampling, only the second slot gets changed.
Signed-off-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.c | 200 |
1 files changed, 109 insertions, 91 deletions
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index eda290fb8bd2..ac7ef5414bde 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -84,6 +84,50 @@ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | static void | 86 | static void |
87 | minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *ratetbl, | ||
88 | int offset, int idx) | ||
89 | { | ||
90 | struct minstrel_rate *r = &mi->r[idx]; | ||
91 | |||
92 | ratetbl->rate[offset].idx = r->rix; | ||
93 | ratetbl->rate[offset].count = r->adjusted_retry_count; | ||
94 | ratetbl->rate[offset].count_cts = r->retry_count_cts; | ||
95 | ratetbl->rate[offset].count_rts = r->retry_count_rtscts; | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | ||
100 | { | ||
101 | struct ieee80211_sta_rates *ratetbl; | ||
102 | int i = 0; | ||
103 | |||
104 | ratetbl = kzalloc(sizeof(*ratetbl), GFP_ATOMIC); | ||
105 | if (!ratetbl) | ||
106 | return; | ||
107 | |||
108 | /* Start with max_tp_rate */ | ||
109 | minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[0]); | ||
110 | |||
111 | if (mp->hw->max_rates >= 3) { | ||
112 | /* At least 3 tx rates supported, use max_tp_rate2 next */ | ||
113 | minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[1]); | ||
114 | } | ||
115 | |||
116 | if (mp->hw->max_rates >= 2) { | ||
117 | /* At least 2 tx rates supported, use max_prob_rate next */ | ||
118 | minstrel_set_rate(mi, ratetbl, i++, mi->max_prob_rate); | ||
119 | } | ||
120 | |||
121 | /* Use lowest rate last */ | ||
122 | ratetbl->rate[i].idx = mi->lowest_rix; | ||
123 | ratetbl->rate[i].count = mp->max_retry; | ||
124 | ratetbl->rate[i].count_cts = mp->max_retry; | ||
125 | ratetbl->rate[i].count_rts = mp->max_retry; | ||
126 | |||
127 | rate_control_set_rates(mp->hw, mi->sta, ratetbl); | ||
128 | } | ||
129 | |||
130 | static void | ||
87 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | 131 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) |
88 | { | 132 | { |
89 | u8 tmp_tp_rate[MAX_THR_RATES]; | 133 | u8 tmp_tp_rate[MAX_THR_RATES]; |
@@ -161,6 +205,8 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
161 | 205 | ||
162 | /* Reset update timer */ | 206 | /* Reset update timer */ |
163 | mi->stats_update = jiffies; | 207 | mi->stats_update = jiffies; |
208 | |||
209 | minstrel_update_rates(mp, mi); | ||
164 | } | 210 | } |
165 | 211 | ||
166 | static void | 212 | static void |
@@ -240,13 +286,12 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
240 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 286 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
241 | struct minstrel_sta_info *mi = priv_sta; | 287 | struct minstrel_sta_info *mi = priv_sta; |
242 | struct minstrel_priv *mp = priv; | 288 | struct minstrel_priv *mp = priv; |
243 | struct ieee80211_tx_rate *ar = info->control.rates; | 289 | struct ieee80211_tx_rate *rate = &info->control.rates[0]; |
244 | unsigned int ndx, sample_ndx = 0; | 290 | struct minstrel_rate *msr, *mr; |
291 | unsigned int ndx; | ||
245 | bool mrr_capable; | 292 | bool mrr_capable; |
246 | bool indirect_rate_sampling = false; | 293 | bool prev_sample = mi->prev_sample; |
247 | bool rate_sampling = false; | 294 | int delta; |
248 | int i, delta; | ||
249 | int mrr_ndx[3]; | ||
250 | int sampling_ratio; | 295 | int sampling_ratio; |
251 | 296 | ||
252 | /* management/no-ack frames do not use rate control */ | 297 | /* management/no-ack frames do not use rate control */ |
@@ -262,107 +307,75 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
262 | else | 307 | else |
263 | sampling_ratio = mp->lookaround_rate; | 308 | sampling_ratio = mp->lookaround_rate; |
264 | 309 | ||
265 | /* init rateindex [ndx] with max throughput rate */ | ||
266 | ndx = mi->max_tp_rate[0]; | ||
267 | |||
268 | /* increase sum packet counter */ | 310 | /* increase sum packet counter */ |
269 | mi->packet_count++; | 311 | mi->packet_count++; |
270 | 312 | ||
271 | delta = (mi->packet_count * sampling_ratio / 100) - | 313 | delta = (mi->packet_count * sampling_ratio / 100) - |
272 | (mi->sample_count + mi->sample_deferred / 2); | 314 | (mi->sample_count + mi->sample_deferred / 2); |
273 | 315 | ||
274 | /* delta > 0: sampling required */ | 316 | /* delta < 0: no sampling required */ |
275 | if ((delta > 0) && (mrr_capable || !mi->prev_sample)) { | 317 | mi->prev_sample = false; |
276 | struct minstrel_rate *msr; | 318 | if (delta < 0 || (!mrr_capable && prev_sample)) |
277 | if (mi->packet_count >= 10000) { | 319 | return; |
278 | mi->sample_deferred = 0; | ||
279 | mi->sample_count = 0; | ||
280 | mi->packet_count = 0; | ||
281 | } else if (delta > mi->n_rates * 2) { | ||
282 | /* With multi-rate retry, not every planned sample | ||
283 | * attempt actually gets used, due to the way the retry | ||
284 | * chain is set up - [max_tp,sample,prob,lowest] for | ||
285 | * sample_rate < max_tp. | ||
286 | * | ||
287 | * If there's too much sampling backlog and the link | ||
288 | * starts getting worse, minstrel would start bursting | ||
289 | * out lots of sampling frames, which would result | ||
290 | * in a large throughput loss. */ | ||
291 | mi->sample_count += (delta - mi->n_rates * 2); | ||
292 | } | ||
293 | 320 | ||
294 | /* get next random rate sample */ | 321 | if (mi->packet_count >= 10000) { |
295 | sample_ndx = minstrel_get_next_sample(mi); | 322 | mi->sample_deferred = 0; |
296 | msr = &mi->r[sample_ndx]; | 323 | mi->sample_count = 0; |
297 | rate_sampling = true; | 324 | mi->packet_count = 0; |
298 | 325 | } else if (delta > mi->n_rates * 2) { | |
299 | /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) | 326 | /* With multi-rate retry, not every planned sample |
300 | * rate sampling method should be used. | 327 | * attempt actually gets used, due to the way the retry |
301 | * Respect such rates that are not sampled for 20 interations. | 328 | * chain is set up - [max_tp,sample,prob,lowest] for |
302 | */ | 329 | * sample_rate < max_tp. |
303 | if (mrr_capable && | 330 | * |
304 | msr->perfect_tx_time > mi->r[ndx].perfect_tx_time && | 331 | * If there's too much sampling backlog and the link |
305 | msr->sample_skipped < 20) | 332 | * starts getting worse, minstrel would start bursting |
306 | indirect_rate_sampling = true; | 333 | * out lots of sampling frames, which would result |
307 | 334 | * in a large throughput loss. */ | |
308 | if (!indirect_rate_sampling) { | 335 | mi->sample_count += (delta - mi->n_rates * 2); |
309 | if (msr->sample_limit != 0) { | 336 | } |
310 | ndx = sample_ndx; | 337 | |
311 | mi->sample_count++; | 338 | /* get next random rate sample */ |
312 | if (msr->sample_limit > 0) | 339 | ndx = minstrel_get_next_sample(mi); |
313 | msr->sample_limit--; | 340 | msr = &mi->r[ndx]; |
314 | } else | 341 | mr = &mi->r[mi->max_tp_rate[0]]; |
315 | rate_sampling = false; | 342 | |
316 | } else { | 343 | /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) |
317 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark | 344 | * rate sampling method should be used. |
318 | * packets that have the sampling rate deferred to the | 345 | * Respect such rates that are not sampled for 20 interations. |
319 | * second MRR stage. Increase the sample counter only | 346 | */ |
320 | * if the deferred sample rate was actually used. | 347 | if (mrr_capable && |
321 | * Use the sample_deferred counter to make sure that | 348 | msr->perfect_tx_time > mr->perfect_tx_time && |
322 | * the sampling is not done in large bursts */ | 349 | msr->sample_skipped < 20) { |
323 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 350 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark |
324 | mi->sample_deferred++; | 351 | * packets that have the sampling rate deferred to the |
325 | } | 352 | * second MRR stage. Increase the sample counter only |
353 | * if the deferred sample rate was actually used. | ||
354 | * Use the sample_deferred counter to make sure that | ||
355 | * the sampling is not done in large bursts */ | ||
356 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
357 | rate++; | ||
358 | mi->sample_deferred++; | ||
359 | } else { | ||
360 | if (!msr->sample_limit != 0) | ||
361 | return; | ||
362 | |||
363 | mi->sample_count++; | ||
364 | if (msr->sample_limit > 0) | ||
365 | msr->sample_limit--; | ||
326 | } | 366 | } |
327 | mi->prev_sample = rate_sampling; | ||
328 | 367 | ||
329 | /* If we're not using MRR and the sampling rate already | 368 | /* If we're not using MRR and the sampling rate already |
330 | * has a probability of >95%, we shouldn't be attempting | 369 | * has a probability of >95%, we shouldn't be attempting |
331 | * to use it, as this only wastes precious airtime */ | 370 | * to use it, as this only wastes precious airtime */ |
332 | if (!mrr_capable && rate_sampling && | 371 | if (!mrr_capable && |
333 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) | 372 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) |
334 | ndx = mi->max_tp_rate[0]; | ||
335 | |||
336 | /* mrr setup for 1st stage */ | ||
337 | ar[0].idx = mi->r[ndx].rix; | ||
338 | ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); | ||
339 | |||
340 | /* non mrr setup for 2nd stage */ | ||
341 | if (!mrr_capable) { | ||
342 | if (!rate_sampling) | ||
343 | ar[0].count = mp->max_retry; | ||
344 | ar[1].idx = mi->lowest_rix; | ||
345 | ar[1].count = mp->max_retry; | ||
346 | return; | 373 | return; |
347 | } | ||
348 | 374 | ||
349 | /* mrr setup for 2nd stage */ | 375 | mi->prev_sample = true; |
350 | if (rate_sampling) { | ||
351 | if (indirect_rate_sampling) | ||
352 | mrr_ndx[0] = sample_ndx; | ||
353 | else | ||
354 | mrr_ndx[0] = mi->max_tp_rate[0]; | ||
355 | } else { | ||
356 | mrr_ndx[0] = mi->max_tp_rate[1]; | ||
357 | } | ||
358 | 376 | ||
359 | /* mrr setup for 3rd & 4th stage */ | 377 | rate->idx = mi->r[ndx].rix; |
360 | mrr_ndx[1] = mi->max_prob_rate; | 378 | rate->count = minstrel_get_retry_count(&mi->r[ndx], info); |
361 | mrr_ndx[2] = 0; | ||
362 | for (i = 1; i < 4; i++) { | ||
363 | ar[i].idx = mi->r[mrr_ndx[i - 1]].rix; | ||
364 | ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count; | ||
365 | } | ||
366 | } | 379 | } |
367 | 380 | ||
368 | 381 | ||
@@ -412,12 +425,16 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
412 | unsigned int i, n = 0; | 425 | unsigned int i, n = 0; |
413 | unsigned int t_slot = 9; /* FIXME: get real slot time */ | 426 | unsigned int t_slot = 9; /* FIXME: get real slot time */ |
414 | 427 | ||
428 | mi->sta = sta; | ||
415 | mi->lowest_rix = rate_lowest_index(sband, sta); | 429 | mi->lowest_rix = rate_lowest_index(sband, sta); |
416 | ctl_rate = &sband->bitrates[mi->lowest_rix]; | 430 | ctl_rate = &sband->bitrates[mi->lowest_rix]; |
417 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, | 431 | mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, |
418 | ctl_rate->bitrate, | 432 | ctl_rate->bitrate, |
419 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); | 433 | !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); |
420 | 434 | ||
435 | memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); | ||
436 | mi->max_prob_rate = 0; | ||
437 | |||
421 | for (i = 0; i < sband->n_bitrates; i++) { | 438 | for (i = 0; i < sband->n_bitrates; i++) { |
422 | struct minstrel_rate *mr = &mi->r[n]; | 439 | struct minstrel_rate *mr = &mi->r[n]; |
423 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; | 440 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; |
@@ -473,6 +490,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
473 | mi->stats_update = jiffies; | 490 | mi->stats_update = jiffies; |
474 | 491 | ||
475 | init_sample_table(mi); | 492 | init_sample_table(mi); |
493 | minstrel_update_rates(mp, mi); | ||
476 | } | 494 | } |
477 | 495 | ||
478 | static void * | 496 | static void * |