aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_minstrel_ht.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rc80211_minstrel_ht.c')
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c138
1 files changed, 96 insertions, 42 deletions
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..333b5118be6d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -259,7 +259,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
259 } 259 }
260 } 260 }
261 261
262 /* try to sample up to half of the availble rates during each interval */ 262 /* try to sample up to half of the available rates during each interval */
263 mi->sample_count *= 4; 263 mi->sample_count *= 4;
264 264
265 cur_prob = 0; 265 cur_prob = 0;
@@ -371,7 +371,10 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru
371 if (likely(sta->ampdu_mlme.tid_tx[tid])) 371 if (likely(sta->ampdu_mlme.tid_tx[tid]))
372 return; 372 return;
373 373
374 ieee80211_start_tx_ba_session(pubsta, tid); 374 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
375 return;
376
377 ieee80211_start_tx_ba_session(pubsta, tid, 5000);
375} 378}
376 379
377static void 380static void
@@ -397,8 +400,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
397 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 400 !(info->flags & IEEE80211_TX_STAT_AMPDU))
398 return; 401 return;
399 402
400 if (!info->status.ampdu_len) { 403 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
401 info->status.ampdu_ack_len = 1; 404 info->status.ampdu_ack_len =
405 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
402 info->status.ampdu_len = 1; 406 info->status.ampdu_len = 1;
403 } 407 }
404 408
@@ -406,15 +410,13 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
406 mi->ampdu_len += info->status.ampdu_len; 410 mi->ampdu_len += info->status.ampdu_len;
407 411
408 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { 412 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
409 mi->sample_wait = 4 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); 413 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
410 mi->sample_tries = 3; 414 mi->sample_tries = 2;
411 mi->sample_count--; 415 mi->sample_count--;
412 } 416 }
413 417
414 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { 418 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
415 mi->sample_packets += info->status.ampdu_len; 419 mi->sample_packets += info->status.ampdu_len;
416 minstrel_next_sample_idx(mi);
417 }
418 420
419 for (i = 0; !last; i++) { 421 for (i = 0; !last; i++) {
420 last = (i == IEEE80211_TX_MAX_RATES - 1) || 422 last = (i == IEEE80211_TX_MAX_RATES - 1) ||
@@ -426,7 +428,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
426 group = minstrel_ht_get_group_idx(&ar[i]); 428 group = minstrel_ht_get_group_idx(&ar[i]);
427 rate = &mi->groups[group].rates[ar[i].idx % 8]; 429 rate = &mi->groups[group].rates[ar[i].idx % 8];
428 430
429 if (last && (info->flags & IEEE80211_TX_STAT_ACK)) 431 if (last)
430 rate->success += info->status.ampdu_ack_len; 432 rate->success += info->status.ampdu_ack_len;
431 433
432 rate->attempts += ar[i].count * info->status.ampdu_len; 434 rate->attempts += ar[i].count * info->status.ampdu_len;
@@ -462,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
462 const struct mcs_group *group; 464 const struct mcs_group *group;
463 unsigned int tx_time, tx_time_rtscts, tx_time_data; 465 unsigned int tx_time, tx_time_rtscts, tx_time_data;
464 unsigned int cw = mp->cw_min; 466 unsigned int cw = mp->cw_min;
467 unsigned int ctime = 0;
465 unsigned int t_slot = 9; /* FIXME */ 468 unsigned int t_slot = 9; /* FIXME */
466 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); 469 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
467 470
@@ -478,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
478 481
479 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 482 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
480 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; 483 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
481 tx_time = 2 * (t_slot + mi->overhead + tx_time_data); 484
482 tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data); 485 /* Contention time for first 2 tries */
486 ctime = (t_slot * cw) >> 1;
487 cw = min((cw << 1) | 1, mp->cw_max);
488 ctime += (t_slot * cw) >> 1;
489 cw = min((cw << 1) | 1, mp->cw_max);
490
491 /* Total TX time for data and Contention after first 2 tries */
492 tx_time = ctime + 2 * (mi->overhead + tx_time_data);
493 tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
494
495 /* See how many more tries we can fit inside segment size */
483 do { 496 do {
484 cw = (cw << 1) | 1; 497 /* Contention time for this try */
485 cw = min(cw, mp->cw_max); 498 ctime = (t_slot * cw) >> 1;
486 tx_time += cw + t_slot + mi->overhead; 499 cw = min((cw << 1) | 1, mp->cw_max);
487 tx_time_rtscts += cw + t_slot + mi->overhead_rtscts; 500
501 /* Total TX time after this try */
502 tx_time += ctime + mi->overhead + tx_time_data;
503 tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
504
488 if (tx_time_rtscts < mp->segment_size) 505 if (tx_time_rtscts < mp->segment_size)
489 mr->retry_count_rtscts++; 506 mr->retry_count_rtscts++;
490 } while ((tx_time < mp->segment_size) && 507 } while ((tx_time < mp->segment_size) &&
@@ -505,7 +522,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
505 if (!mr->retry_updated) 522 if (!mr->retry_updated)
506 minstrel_calc_retransmit(mp, mi, index); 523 minstrel_calc_retransmit(mp, mi, index);
507 524
508 if (mr->probability < MINSTREL_FRAC(20, 100)) 525 if (sample)
526 rate->count = 1;
527 else if (mr->probability < MINSTREL_FRAC(20, 100))
509 rate->count = 2; 528 rate->count = 2;
510 else if (rtscts) 529 else if (rtscts)
511 rate->count = mr->retry_count_rtscts; 530 rate->count = mr->retry_count_rtscts;
@@ -513,9 +532,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
513 rate->count = mr->retry_count; 532 rate->count = mr->retry_count;
514 533
515 rate->flags = IEEE80211_TX_RC_MCS | group->flags; 534 rate->flags = IEEE80211_TX_RC_MCS | group->flags;
516 if (txrc->short_preamble) 535 if (rtscts)
517 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
518 if (txrc->rts || rtscts)
519 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 536 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
520 rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; 537 rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES;
521} 538}
@@ -547,13 +564,14 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
547 sample_idx = sample_table[mg->column][mg->index]; 564 sample_idx = sample_table[mg->column][mg->index];
548 mr = &mg->rates[sample_idx]; 565 mr = &mg->rates[sample_idx];
549 sample_idx += mi->sample_group * MCS_GROUP_RATES; 566 sample_idx += mi->sample_group * MCS_GROUP_RATES;
567 minstrel_next_sample_idx(mi);
550 568
551 /* 569 /*
552 * When not using MRR, do not sample if the probability is already 570 * When not using MRR, do not sample if the probability is already
553 * higher than 95% to avoid wasting airtime 571 * higher than 95% to avoid wasting airtime
554 */ 572 */
555 if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) 573 if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100)))
556 goto next; 574 return -1;
557 575
558 /* 576 /*
559 * Make sure that lower rates get sampled only occasionally, 577 * Make sure that lower rates get sampled only occasionally,
@@ -561,18 +579,14 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
561 */ 579 */
562 if (minstrel_get_duration(sample_idx) > 580 if (minstrel_get_duration(sample_idx) >
563 minstrel_get_duration(mi->max_tp_rate)) { 581 minstrel_get_duration(mi->max_tp_rate)) {
564 if (mr->sample_skipped < 10) 582 if (mr->sample_skipped < 20)
565 goto next; 583 return -1;
566 584
567 if (mi->sample_slow++ > 2) 585 if (mi->sample_slow++ > 2)
568 goto next; 586 return -1;
569 } 587 }
570 588
571 return sample_idx; 589 return sample_idx;
572
573next:
574 minstrel_next_sample_idx(mi);
575 return -1;
576} 590}
577 591
578static void 592static void
@@ -585,6 +599,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
585 struct minstrel_ht_sta *mi = &msp->ht; 599 struct minstrel_ht_sta *mi = &msp->ht;
586 struct minstrel_priv *mp = priv; 600 struct minstrel_priv *mp = priv;
587 int sample_idx; 601 int sample_idx;
602 bool sample = false;
588 603
589 if (rate_control_send_low(sta, priv_sta, txrc)) 604 if (rate_control_send_low(sta, priv_sta, txrc))
590 return; 605 return;
@@ -595,21 +610,49 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
595 info->flags |= mi->tx_flags; 610 info->flags |= mi->tx_flags;
596 sample_idx = minstrel_get_sample_rate(mp, mi); 611 sample_idx = minstrel_get_sample_rate(mp, mi);
597 if (sample_idx >= 0) { 612 if (sample_idx >= 0) {
613 sample = true;
598 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, 614 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
599 txrc, true, false); 615 txrc, true, false);
600 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
601 txrc, false, true);
602 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 616 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
603 } else { 617 } else {
604 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, 618 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
605 txrc, false, false); 619 txrc, false, false);
606 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
607 txrc, false, true);
608 } 620 }
609 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, true);
610 621
611 ar[3].count = 0; 622 if (mp->hw->max_rates >= 3) {
612 ar[3].idx = -1; 623 /*
624 * At least 3 tx rates supported, use
625 * sample_rate -> max_tp_rate -> max_prob_rate for sampling and
626 * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default.
627 */
628 if (sample_idx >= 0)
629 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
630 txrc, false, false);
631 else
632 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
633 txrc, false, true);
634
635 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate,
636 txrc, false, !sample);
637
638 ar[3].count = 0;
639 ar[3].idx = -1;
640 } else if (mp->hw->max_rates == 2) {
641 /*
642 * Only 2 tx rates supported, use
643 * sample_rate -> max_prob_rate for sampling and
644 * max_tp_rate -> max_prob_rate by default.
645 */
646 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate,
647 txrc, false, !sample);
648
649 ar[2].count = 0;
650 ar[2].idx = -1;
651 } else {
652 /* Not using MRR, only use the first rate */
653 ar[1].count = 0;
654 ar[1].idx = -1;
655 }
613 656
614 mi->total_packets++; 657 mi->total_packets++;
615 658
@@ -631,18 +674,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
631 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; 674 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
632 struct ieee80211_local *local = hw_to_local(mp->hw); 675 struct ieee80211_local *local = hw_to_local(mp->hw);
633 u16 sta_cap = sta->ht_cap.cap; 676 u16 sta_cap = sta->ht_cap.cap;
677 int n_supported = 0;
634 int ack_dur; 678 int ack_dur;
635 int stbc; 679 int stbc;
636 int i; 680 int i;
637 681
638 /* fall back to the old minstrel for legacy stations */ 682 /* fall back to the old minstrel for legacy stations */
639 if (!sta->ht_cap.ht_supported) { 683 if (!sta->ht_cap.ht_supported)
640 msp->is_ht = false; 684 goto use_legacy;
641 memset(&msp->legacy, 0, sizeof(msp->legacy));
642 msp->legacy.r = msp->ratelist;
643 msp->legacy.sample_table = msp->sample_table;
644 return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
645 }
646 685
647 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != 686 BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) !=
648 MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS); 687 MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS);
@@ -697,7 +736,22 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
697 736
698 mi->groups[i].supported = 737 mi->groups[i].supported =
699 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; 738 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
739
740 if (mi->groups[i].supported)
741 n_supported++;
700 } 742 }
743
744 if (!n_supported)
745 goto use_legacy;
746
747 return;
748
749use_legacy:
750 msp->is_ht = false;
751 memset(&msp->legacy, 0, sizeof(msp->legacy));
752 msp->legacy.r = msp->ratelist;
753 msp->legacy.sample_table = msp->sample_table;
754 return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
701} 755}
702 756
703static void 757static void