Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211/minstrel_ht: use the new rate control API

Pass the rate selection table to mac80211 from minstrel_ht_update_stats.
Only rates for sample attempts are set in info->control.rates.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Felix Fietkau and committed by
Johannes Berg
a8566662 0d528d85

+87 -71
+85 -71
net/mac80211/rc80211_minstrel_ht.c
··· 126 126 127 127 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES]; 128 128 129 + static void 130 + minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); 131 + 129 132 /* 130 133 * Look up an MCS group index based on mac80211 rate information 131 134 */ ··· 468 465 struct ieee80211_tx_rate *ar = info->status.rates; 469 466 struct minstrel_rate_stats *rate, *rate2; 470 467 struct minstrel_priv *mp = priv; 471 - bool last; 468 + bool last, update = false; 472 469 int i; 473 470 474 471 if (!msp->is_ht) ··· 517 514 rate = minstrel_get_ratestats(mi, mi->max_tp_rate); 518 515 if (rate->attempts > 30 && 519 516 MINSTREL_FRAC(rate->success, rate->attempts) < 520 - MINSTREL_FRAC(20, 100)) 517 + MINSTREL_FRAC(20, 100)) { 521 518 minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); 519 + update = true; 520 + } 522 521 523 522 rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); 524 523 if (rate2->attempts > 30 && 525 524 MINSTREL_FRAC(rate2->success, rate2->attempts) < 526 - MINSTREL_FRAC(20, 100)) 525 + MINSTREL_FRAC(20, 100)) { 527 526 minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); 527 + update = true; 528 + } 528 529 529 530 if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { 531 + update = true; 530 532 minstrel_ht_update_stats(mp, mi); 531 533 if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && 532 534 mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) 533 535 minstrel_aggr_check(sta, skb); 534 536 } 537 + 538 + if (update) 539 + minstrel_ht_update_rates(mp, mi); 535 540 } 536 541 537 542 static void ··· 603 592 604 593 static void 605 594 minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, 606 - struct ieee80211_tx_rate *rate, int index, 607 - bool sample, bool rtscts) 595 + struct ieee80211_sta_rates *ratetbl, int offset, int index) 608 596 { 609 597 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 610 598 struct minstrel_rate_stats *mr; 599 + u8 idx; 600 + u16 flags; 611 601 612 602 mr = minstrel_get_ratestats(mi, index); 613 603 if (!mr->retry_updated) 614 604 minstrel_calc_retransmit(mp, mi, index); 615 605 616 - if (sample) 617 - rate->count = 1; 618 - else if (mr->probability < MINSTREL_FRAC(20, 100)) 619 - rate->count = 2; 620 - else if (rtscts) 621 - rate->count = mr->retry_count_rtscts; 622 - else 623 - rate->count = mr->retry_count; 624 - 625 - rate->flags = 0; 626 - if (rtscts) 627 - rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 628 - 629 - if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 630 - rate->idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 631 - return; 606 + if (mr->probability < MINSTREL_FRAC(20, 100) || !mr->retry_count) { 607 + ratetbl->rate[offset].count = 2; 608 + ratetbl->rate[offset].count_rts = 2; 609 + ratetbl->rate[offset].count_cts = 2; 610 + } else { 611 + ratetbl->rate[offset].count = mr->retry_count; 612 + ratetbl->rate[offset].count_cts = mr->retry_count; 613 + ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; 632 614 } 633 615 634 - rate->flags |= IEEE80211_TX_RC_MCS | group->flags; 635 - rate->idx = index % MCS_GROUP_RATES + (group->streams - 1) * MCS_GROUP_RATES; 616 + if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 617 + idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 618 + flags = 0; 619 + } else { 620 + idx = index % MCS_GROUP_RATES + 621 + (group->streams - 1) * MCS_GROUP_RATES; 622 + flags = IEEE80211_TX_RC_MCS | group->flags; 623 + } 624 + 625 + if (offset > 0) { 626 + ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; 627 + flags |= IEEE80211_TX_RC_USE_RTS_CTS; 628 + } 629 + 630 + ratetbl->rate[offset].idx = idx; 631 + ratetbl->rate[offset].flags = flags; 632 + } 633 + 634 + static void 635 + minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) 636 + { 637 + struct ieee80211_sta_rates *rates; 638 + int i = 0; 639 + 640 + rates = kzalloc(sizeof(*rates), GFP_ATOMIC); 641 + if (!rates) 642 + return; 643 + 644 + /* Start with max_tp_rate */ 645 + minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate); 646 + 647 + if (mp->hw->max_rates >= 3) { 648 + /* At least 3 tx rates supported, use max_tp_rate2 next */ 649 + minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate2); 650 + } 651 + 652 + if (mp->hw->max_rates >= 2) { 653 + /* 654 + * At least 2 tx rates supported, use max_prob_rate next */ 655 + minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); 656 + } 657 + 658 + rates->rate[i].idx = -1; 659 + rate_control_set_rates(mp->hw, mi->sta, rates); 636 660 } 637 661 638 662 static inline int ··· 757 711 minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, 758 712 struct ieee80211_tx_rate_control *txrc) 759 713 { 714 + const struct mcs_group *sample_group; 760 715 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); 761 - struct ieee80211_tx_rate *ar = info->status.rates; 716 + struct ieee80211_tx_rate *rate = &info->status.rates[0]; 762 717 struct minstrel_ht_sta_priv *msp = priv_sta; 763 718 struct minstrel_ht_sta *mi = &msp->ht; 764 719 struct minstrel_priv *mp = priv; 765 720 int sample_idx; 766 - bool sample = false; 767 721 768 722 if (rate_control_send_low(sta, priv_sta, txrc)) 769 723 return; ··· 791 745 } 792 746 #endif 793 747 794 - if (sample_idx >= 0) { 795 - sample = true; 796 - minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, 797 - true, false); 798 - info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 799 - } else { 800 - minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, 801 - false, false); 802 - } 803 - 804 - if (mp->hw->max_rates >= 3) { 805 - /* 806 - * At least 3 tx rates supported, use 807 - * sample_rate -> max_tp_rate -> max_prob_rate for sampling and 808 - * max_tp_rate -> max_tp_rate2 -> max_prob_rate by default. 809 - */ 810 - if (sample_idx >= 0) 811 - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, 812 - false, false); 813 - else 814 - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, 815 - false, true); 816 - 817 - minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, 818 - false, !sample); 819 - 820 - ar[3].count = 0; 821 - ar[3].idx = -1; 822 - } else if (mp->hw->max_rates == 2) { 823 - /* 824 - * Only 2 tx rates supported, use 825 - * sample_rate -> max_prob_rate for sampling and 826 - * max_tp_rate -> max_prob_rate by default. 827 - */ 828 - minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate, 829 - false, !sample); 830 - 831 - ar[2].count = 0; 832 - ar[2].idx = -1; 833 - } else { 834 - /* Not using MRR, only use the first rate */ 835 - ar[1].count = 0; 836 - ar[1].idx = -1; 837 - } 838 - 839 748 mi->total_packets++; 840 749 841 750 /* wraparound */ ··· 798 797 mi->total_packets = 0; 799 798 mi->sample_packets = 0; 800 799 } 800 + 801 + if (sample_idx < 0) 802 + return; 803 + 804 + sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; 805 + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 806 + rate->idx = sample_idx % MCS_GROUP_RATES + 807 + (sample_group->streams - 1) * MCS_GROUP_RATES; 808 + rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; 809 + rate->count = 1; 801 810 } 802 811 803 812 static void ··· 857 846 858 847 msp->is_ht = true; 859 848 memset(mi, 0, sizeof(*mi)); 849 + 850 + mi->sta = sta; 860 851 mi->stats_update = jiffies; 861 852 862 853 ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); ··· 920 907 if (!n_supported) 921 908 goto use_legacy; 922 909 923 - /* init {mi,mi->groups[*]}->{max_tp_rate,max_tp_rate2,max_prob_rate} */ 910 + /* create an initial rate table with the lowest supported rates */ 924 911 minstrel_ht_update_stats(mp, mi); 912 + minstrel_ht_update_rates(mp, mi); 925 913 926 914 return; 927 915
+2
net/mac80211/rc80211_minstrel_ht.h
··· 65 65 }; 66 66 67 67 struct minstrel_ht_sta { 68 + struct ieee80211_sta *sta; 69 + 68 70 /* ampdu length (average, per sampling interval) */ 69 71 unsigned int ampdu_len; 70 72 unsigned int ampdu_packets;