diff options
Diffstat (limited to 'net/mac80211/rc80211_minstrel.c')
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 109 |
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 | ||
236 | void | 228 | static void |
237 | minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | 229 | minstrel_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 | ||
503 | static void | ||
504 | minstrel_clear(void *priv) | ||
505 | { | ||
506 | } | ||
507 | |||
508 | static void * | 510 | static void * |
509 | minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 511 | minstrel_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, |