Lines Matching +full:min +full:- +full:sample +full:- +full:time +full:- +full:nsecs
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
4 * Copyright (C) 2019-2020 Intel Corporation
30 /* Transmission time (nanoseconds) for a packet containing (syms) symbols */
46 * Define group sort order: HT40 -> SGI -> #streams
52 _streams - 1
57 _MAX(0, 16 - __builtin_clz(duration))
92 (_streams) - 1)
182 * BW -> SGI -> #streams
266 switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) { in minstrel_get_valid_vht_rates()
288 return GROUP_IDX((rate->idx / 8) + 1, in minstrel_ht_get_group_idx()
289 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), in minstrel_ht_get_group_idx()
290 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); in minstrel_ht_get_group_idx()
297 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), in minstrel_vht_get_group_idx()
298 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + in minstrel_vht_get_group_idx()
299 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)); in minstrel_vht_get_group_idx()
308 if (rate->flags & IEEE80211_TX_RC_MCS) { in minstrel_ht_get_stats()
310 idx = rate->idx % 8; in minstrel_ht_get_stats()
311 } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { in minstrel_ht_get_stats()
317 for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) in minstrel_ht_get_stats()
318 if (rate->idx == mp->cck_rates[idx]) in minstrel_ht_get_stats()
322 if ((mi->supported[group] & BIT(idx + 4)) && in minstrel_ht_get_stats()
323 (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) in minstrel_ht_get_stats()
326 return &mi->groups[group].rates[idx]; in minstrel_ht_get_stats()
332 return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; in minstrel_get_ratestats()
338 if (!mi->avg_ampdu_len) in minstrel_ht_avg_ampdu_len()
341 return MINSTREL_TRUNC(mi->avg_ampdu_len); in minstrel_ht_avg_ampdu_len()
345 * Return current throughput based on the average A-MPDU length, taking into
352 unsigned int nsecs = 0; in minstrel_ht_get_tp_avg() local
359 nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); in minstrel_ht_get_tp_avg()
361 nsecs += minstrel_mcs_groups[group].duration[rate] << in minstrel_ht_get_tp_avg()
367 * (prob is scaled - see MINSTREL_FRAC above) in minstrel_ht_get_tp_avg()
371 / nsecs)); in minstrel_ht_get_tp_avg()
373 return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs)); in minstrel_ht_get_tp_avg()
393 cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; in minstrel_ht_sort_best_tp_rates()
397 tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; in minstrel_ht_sort_best_tp_rates()
398 tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; in minstrel_ht_sort_best_tp_rates()
399 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_sort_best_tp_rates()
405 j--; in minstrel_ht_sort_best_tp_rates()
408 if (j < MAX_THR_RATES - 1) { in minstrel_ht_sort_best_tp_rates()
410 (MAX_THR_RATES - (j + 1)))); in minstrel_ht_sort_best_tp_rates()
431 mg = &mi->groups[index / MCS_GROUP_RATES]; in minstrel_ht_set_best_prob_rate()
432 mrs = &mg->rates[index % MCS_GROUP_RATES]; in minstrel_ht_set_best_prob_rate()
434 tmp_group = mi->max_prob_rate / MCS_GROUP_RATES; in minstrel_ht_set_best_prob_rate()
435 tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES; in minstrel_ht_set_best_prob_rate()
436 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_set_best_prob_rate()
441 max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; in minstrel_ht_set_best_prob_rate()
446 max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; in minstrel_ht_set_best_prob_rate()
447 max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; in minstrel_ht_set_best_prob_rate()
448 max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; in minstrel_ht_set_best_prob_rate()
450 if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { in minstrel_ht_set_best_prob_rate()
452 mrs->prob_avg); in minstrel_ht_set_best_prob_rate()
454 mi->max_prob_rate = index; in minstrel_ht_set_best_prob_rate()
460 mg->max_group_prob_rate = index; in minstrel_ht_set_best_prob_rate()
462 if (mrs->prob_avg > tmp_prob) in minstrel_ht_set_best_prob_rate()
463 mi->max_prob_rate = index; in minstrel_ht_set_best_prob_rate()
464 if (mrs->prob_avg > max_gpr_prob) in minstrel_ht_set_best_prob_rate()
465 mg->max_group_prob_rate = index; in minstrel_ht_set_best_prob_rate()
486 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_assign_best_tp_rates()
491 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_assign_best_tp_rates()
514 tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / in minstrel_ht_prob_rate_reduce_streams()
517 mg = &mi->groups[group]; in minstrel_ht_prob_rate_reduce_streams()
518 if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) in minstrel_ht_prob_rate_reduce_streams()
521 tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; in minstrel_ht_prob_rate_reduce_streams()
522 tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; in minstrel_ht_prob_rate_reduce_streams()
526 mi->max_prob_rate = mg->max_group_prob_rate; in minstrel_ht_prob_rate_reduce_streams()
538 unsigned int duration = group->duration[index % MCS_GROUP_RATES]; in minstrel_get_duration()
539 return duration << group->shift; in minstrel_get_duration()
546 if (group->bw < tp_group->bw) in minstrel_ht_probe_group()
549 if (group->streams == tp_group->streams) in minstrel_ht_probe_group()
552 if (tp_idx < 4 && group->streams == tp_group->streams - 1) in minstrel_ht_probe_group()
555 return group->streams == tp_group->streams + 1; in minstrel_ht_probe_group()
566 tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; in minstrel_ht_find_probe_rates()
567 tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; in minstrel_ht_find_probe_rates()
569 max_dur = minstrel_get_duration(mi->max_tp_rate[0]); in minstrel_ht_find_probe_rates()
571 max_dur -= max_dur / 16; in minstrel_ht_find_probe_rates()
574 u16 supported = mi->supported[g]; in minstrel_ht_find_probe_rates()
589 if ((group->duration[i] << group->shift) > max_dur) in minstrel_ht_find_probe_rates()
593 if (idx == mi->max_tp_rate[0]) in minstrel_ht_find_probe_rates()
618 if (mp->hw->max_rates > 1) in minstrel_ht_rate_sample_switch()
626 mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); in minstrel_ht_rate_sample_switch()
627 faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100); in minstrel_ht_rate_sample_switch()
634 int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; in minstrel_ht_rate_sample_switch()
635 u16 supported = mi->supported[g_idx]; in minstrel_ht_rate_sample_switch()
637 supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; in minstrel_ht_rate_sample_switch()
642 probe_rate = mi->max_tp_rate[0] + i; in minstrel_ht_rate_sample_switch()
657 mi->sample_rate = probe_rate; in minstrel_ht_rate_sample_switch()
658 mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; in minstrel_ht_rate_sample_switch()
665 * - max_prob_rate must use only one stream, as a tradeoff between delivery
667 * - as long as the max prob rate has a probability of more than 75%, pick
672 bool sample) in minstrel_ht_update_stats() argument
680 mi->sample_mode = MINSTREL_SAMPLE_IDLE; in minstrel_ht_update_stats()
682 if (sample) { in minstrel_ht_update_stats()
683 mi->total_packets_cur = mi->total_packets - in minstrel_ht_update_stats()
684 mi->total_packets_last; in minstrel_ht_update_stats()
685 mi->total_packets_last = mi->total_packets; in minstrel_ht_update_stats()
687 if (!mp->sample_switch) in minstrel_ht_update_stats()
688 sample = false; in minstrel_ht_update_stats()
689 if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1) in minstrel_ht_update_stats()
690 sample = false; in minstrel_ht_update_stats()
692 if (mi->ampdu_packets > 0) { in minstrel_ht_update_stats()
693 if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) in minstrel_ht_update_stats()
694 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, in minstrel_ht_update_stats()
695 MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), in minstrel_ht_update_stats()
698 mi->avg_ampdu_len = 0; in minstrel_ht_update_stats()
699 mi->ampdu_len = 0; in minstrel_ht_update_stats()
700 mi->ampdu_packets = 0; in minstrel_ht_update_stats()
703 mi->sample_slow = 0; in minstrel_ht_update_stats()
704 mi->sample_count = 0; in minstrel_ht_update_stats()
708 if (mi->supported[MINSTREL_CCK_GROUP]) in minstrel_ht_update_stats()
712 if (mi->supported[MINSTREL_VHT_GROUP_0]) in minstrel_ht_update_stats()
723 mg = &mi->groups[group]; in minstrel_ht_update_stats()
724 if (!mi->supported[group]) in minstrel_ht_update_stats()
727 mi->sample_count++; in minstrel_ht_update_stats()
734 if (!(mi->supported[group] & BIT(i))) in minstrel_ht_update_stats()
739 mrs = &mg->rates[i]; in minstrel_ht_update_stats()
740 mrs->retry_updated = false; in minstrel_ht_update_stats()
742 cur_prob = mrs->prob_avg; in minstrel_ht_update_stats()
764 memcpy(mg->max_group_tp_rate, tmp_group_tp_rate, in minstrel_ht_update_stats()
765 sizeof(mg->max_group_tp_rate)); in minstrel_ht_update_stats()
770 memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); in minstrel_ht_update_stats()
775 /* try to sample all available rates during each interval */ in minstrel_ht_update_stats()
776 mi->sample_count *= 8; in minstrel_ht_update_stats()
777 if (mp->new_avg) in minstrel_ht_update_stats()
778 mi->sample_count /= 2; in minstrel_ht_update_stats()
780 if (sample) in minstrel_ht_update_stats()
785 if (mp->fixed_rate_idx != -1) { in minstrel_ht_update_stats()
787 mi->max_tp_rate[i] = mp->fixed_rate_idx; in minstrel_ht_update_stats()
788 mi->max_prob_rate = mp->fixed_rate_idx; in minstrel_ht_update_stats()
789 mi->sample_mode = MINSTREL_SAMPLE_IDLE; in minstrel_ht_update_stats()
794 mi->last_stats_update = jiffies; in minstrel_ht_update_stats()
800 if (rate->idx < 0) in minstrel_ht_txstat_valid()
803 if (!rate->count) in minstrel_ht_txstat_valid()
806 if (rate->flags & IEEE80211_TX_RC_MCS || in minstrel_ht_txstat_valid()
807 rate->flags & IEEE80211_TX_RC_VHT_MCS) in minstrel_ht_txstat_valid()
810 return rate->idx == mp->cck_rates[0] || in minstrel_ht_txstat_valid()
811 rate->idx == mp->cck_rates[1] || in minstrel_ht_txstat_valid()
812 rate->idx == mp->cck_rates[2] || in minstrel_ht_txstat_valid()
813 rate->idx == mp->cck_rates[3]; in minstrel_ht_txstat_valid()
822 mi->sample_group++; in minstrel_set_next_sample_idx()
823 mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups); in minstrel_set_next_sample_idx()
824 mg = &mi->groups[mi->sample_group]; in minstrel_set_next_sample_idx()
826 if (!mi->supported[mi->sample_group]) in minstrel_set_next_sample_idx()
829 if (++mg->index >= MCS_GROUP_RATES) { in minstrel_set_next_sample_idx()
830 mg->index = 0; in minstrel_set_next_sample_idx()
831 if (++mg->column >= ARRAY_SIZE(sample_table)) in minstrel_set_next_sample_idx()
832 mg->column = 0; in minstrel_set_next_sample_idx()
845 group--; in minstrel_downgrade_rate()
847 if (!mi->supported[group]) in minstrel_downgrade_rate()
855 *idx = mi->groups[group].max_group_tp_rate[0]; in minstrel_downgrade_rate()
857 *idx = mi->groups[group].max_group_tp_rate[1]; in minstrel_downgrade_rate()
865 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; in minstrel_aggr_check()
872 if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) in minstrel_aggr_check()
875 if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) in minstrel_aggr_check()
879 if (likely(sta->ampdu_mlme.tid_tx[tid])) in minstrel_aggr_check()
889 struct ieee80211_tx_info *info = st->info; in minstrel_ht_tx_status()
891 struct minstrel_ht_sta *mi = &msp->ht; in minstrel_ht_tx_status()
892 struct ieee80211_tx_rate *ar = info->status.rates; in minstrel_ht_tx_status()
895 u32 update_interval = mp->update_interval / 2; in minstrel_ht_tx_status()
900 if (!msp->is_ht) in minstrel_ht_tx_status()
902 &msp->legacy, st); in minstrel_ht_tx_status()
906 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && in minstrel_ht_tx_status()
907 !(info->flags & IEEE80211_TX_STAT_AMPDU)) in minstrel_ht_tx_status()
910 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { in minstrel_ht_tx_status()
911 info->status.ampdu_ack_len = in minstrel_ht_tx_status()
912 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); in minstrel_ht_tx_status()
913 info->status.ampdu_len = 1; in minstrel_ht_tx_status()
916 mi->ampdu_packets++; in minstrel_ht_tx_status()
917 mi->ampdu_len += info->status.ampdu_len; in minstrel_ht_tx_status()
919 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { in minstrel_ht_tx_status()
922 mi->sample_wait = 16 + 2 * avg_ampdu_len; in minstrel_ht_tx_status()
923 mi->sample_tries = 1; in minstrel_ht_tx_status()
924 mi->sample_count--; in minstrel_ht_tx_status()
927 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) in minstrel_ht_tx_status()
928 mi->sample_packets += info->status.ampdu_len; in minstrel_ht_tx_status()
930 if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) in minstrel_ht_tx_status()
931 rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); in minstrel_ht_tx_status()
935 last = (i == IEEE80211_TX_MAX_RATES - 1) || in minstrel_ht_tx_status()
943 rate->success += info->status.ampdu_ack_len; in minstrel_ht_tx_status()
945 rate->attempts += ar[i].count * info->status.ampdu_len; in minstrel_ht_tx_status()
948 switch (mi->sample_mode) { in minstrel_ht_tx_status()
950 if (mp->new_avg && in minstrel_ht_tx_status()
951 (mp->hw->max_rates > 1 || in minstrel_ht_tx_status()
952 mi->total_packets_cur < SAMPLE_SWITCH_THR)) in minstrel_ht_tx_status()
960 mi->sample_mode = MINSTREL_SAMPLE_PENDING; in minstrel_ht_tx_status()
974 if (mp->hw->max_rates > 1) { in minstrel_ht_tx_status()
979 rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); in minstrel_ht_tx_status()
980 if (rate->attempts > 30 && in minstrel_ht_tx_status()
981 rate->success < rate->attempts / 4) { in minstrel_ht_tx_status()
982 minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); in minstrel_ht_tx_status()
986 rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); in minstrel_ht_tx_status()
987 if (rate2->attempts > 30 && in minstrel_ht_tx_status()
988 rate2->success < rate2->attempts / 4) { in minstrel_ht_tx_status()
989 minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); in minstrel_ht_tx_status()
994 if (time_after(jiffies, mi->last_stats_update + update_interval)) { in minstrel_ht_tx_status()
1009 unsigned int cw = mp->cw_min; in minstrel_calc_retransmit()
1016 if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) { in minstrel_calc_retransmit()
1017 mrs->retry_count = 1; in minstrel_calc_retransmit()
1018 mrs->retry_count_rtscts = 1; in minstrel_calc_retransmit()
1022 mrs->retry_count = 2; in minstrel_calc_retransmit()
1023 mrs->retry_count_rtscts = 2; in minstrel_calc_retransmit()
1024 mrs->retry_updated = true; in minstrel_calc_retransmit()
1028 /* Contention time for first 2 tries */ in minstrel_calc_retransmit()
1030 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1032 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1035 overhead = mi->overhead; in minstrel_calc_retransmit()
1036 overhead_rtscts = mi->overhead_rtscts; in minstrel_calc_retransmit()
1039 /* Total TX time for data and Contention after first 2 tries */ in minstrel_calc_retransmit()
1045 /* Contention time for this try */ in minstrel_calc_retransmit()
1047 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1049 /* Total TX time after this try */ in minstrel_calc_retransmit()
1053 if (tx_time_rtscts < mp->segment_size) in minstrel_calc_retransmit()
1054 mrs->retry_count_rtscts++; in minstrel_calc_retransmit()
1055 } while ((tx_time < mp->segment_size) && in minstrel_calc_retransmit()
1056 (++mrs->retry_count < mp->max_retry)); in minstrel_calc_retransmit()
1067 u16 flags = group->flags; in minstrel_ht_set_rate()
1070 if (!mrs->retry_updated) in minstrel_ht_set_rate()
1073 if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) { in minstrel_ht_set_rate()
1074 ratetbl->rate[offset].count = 2; in minstrel_ht_set_rate()
1075 ratetbl->rate[offset].count_rts = 2; in minstrel_ht_set_rate()
1076 ratetbl->rate[offset].count_cts = 2; in minstrel_ht_set_rate()
1078 ratetbl->rate[offset].count = mrs->retry_count; in minstrel_ht_set_rate()
1079 ratetbl->rate[offset].count_cts = mrs->retry_count; in minstrel_ht_set_rate()
1080 ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; in minstrel_ht_set_rate()
1084 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; in minstrel_ht_set_rate()
1086 idx = ((group->streams - 1) << 4) | in minstrel_ht_set_rate()
1089 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; in minstrel_ht_set_rate()
1092 * - if station is in dynamic SMPS (and streams > 1) in minstrel_ht_set_rate()
1093 * - for fallback rates, to increase chances of getting through in minstrel_ht_set_rate()
1096 (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC && in minstrel_ht_set_rate()
1097 group->streams > 1)) { in minstrel_ht_set_rate()
1098 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; in minstrel_ht_set_rate()
1102 ratetbl->rate[offset].idx = idx; in minstrel_ht_set_rate()
1103 ratetbl->rate[offset].flags = flags; in minstrel_ht_set_rate()
1111 return mi->groups[group].rates[rate].prob_avg; in minstrel_ht_get_prob_avg()
1117 int group = mi->max_prob_rate / MCS_GROUP_RATES; in minstrel_ht_get_max_amsdu_len()
1119 int rate = mi->max_prob_rate % MCS_GROUP_RATES; in minstrel_ht_get_max_amsdu_len()
1122 /* Disable A-MSDU if max_prob_rate is bad */ in minstrel_ht_get_max_amsdu_len()
1123 if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100)) in minstrel_ht_get_max_amsdu_len()
1126 duration = g->duration[rate]; in minstrel_ht_get_max_amsdu_len()
1127 duration <<= g->shift; in minstrel_ht_get_max_amsdu_len()
1129 /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ in minstrel_ht_get_max_amsdu_len()
1134 * If the rate is slower than single-stream MCS4, limit A-MSDU to usual in minstrel_ht_get_max_amsdu_len()
1141 * If the rate is slower than single-stream MCS7, or if the max throughput in minstrel_ht_get_max_amsdu_len()
1142 * rate success probability is less than 75%, limit A-MSDU to twice the usual in minstrel_ht_get_max_amsdu_len()
1146 (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) < in minstrel_ht_get_max_amsdu_len()
1151 * HT A-MPDU limits maximum MPDU size under BA agreement to 4095 bytes. in minstrel_ht_get_max_amsdu_len()
1153 * the limit here to avoid the complexity of having to de-aggregate in minstrel_ht_get_max_amsdu_len()
1156 if (!mi->sta->vht_cap.vht_supported) in minstrel_ht_get_max_amsdu_len()
1167 u16 first_rate = mi->max_tp_rate[0]; in minstrel_ht_update_rates()
1170 if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE) in minstrel_ht_update_rates()
1171 first_rate = mi->sample_rate; in minstrel_ht_update_rates()
1180 if (mp->hw->max_rates >= 3) { in minstrel_ht_update_rates()
1182 minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[1]); in minstrel_ht_update_rates()
1185 if (mp->hw->max_rates >= 2) { in minstrel_ht_update_rates()
1186 minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); in minstrel_ht_update_rates()
1189 mi->sta->max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi); in minstrel_ht_update_rates()
1190 rates->rate[i].idx = -1; in minstrel_ht_update_rates()
1191 rate_control_set_rates(mp->hw, mi->sta, rates); in minstrel_ht_update_rates()
1203 if (mp->hw->max_rates == 1 && mp->sample_switch && in minstrel_get_sample_rate()
1204 (mi->total_packets_cur >= SAMPLE_SWITCH_THR || in minstrel_get_sample_rate()
1205 mp->sample_switch == 1)) in minstrel_get_sample_rate()
1206 return -1; in minstrel_get_sample_rate()
1208 if (mi->sample_wait > 0) { in minstrel_get_sample_rate()
1209 mi->sample_wait--; in minstrel_get_sample_rate()
1210 return -1; in minstrel_get_sample_rate()
1213 if (!mi->sample_tries) in minstrel_get_sample_rate()
1214 return -1; in minstrel_get_sample_rate()
1216 sample_group = mi->sample_group; in minstrel_get_sample_rate()
1217 mg = &mi->groups[sample_group]; in minstrel_get_sample_rate()
1218 sample_idx = sample_table[mg->column][mg->index]; in minstrel_get_sample_rate()
1221 if (!(mi->supported[sample_group] & BIT(sample_idx))) in minstrel_get_sample_rate()
1222 return -1; in minstrel_get_sample_rate()
1224 mrs = &mg->rates[sample_idx]; in minstrel_get_sample_rate()
1228 if (minstrel_get_duration(mi->max_tp_rate[0]) > in minstrel_get_sample_rate()
1229 minstrel_get_duration(mi->max_tp_rate[1])) { in minstrel_get_sample_rate()
1230 tp_rate1 = mi->max_tp_rate[1]; in minstrel_get_sample_rate()
1231 tp_rate2 = mi->max_tp_rate[0]; in minstrel_get_sample_rate()
1233 tp_rate1 = mi->max_tp_rate[0]; in minstrel_get_sample_rate()
1234 tp_rate2 = mi->max_tp_rate[1]; in minstrel_get_sample_rate()
1242 if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate) in minstrel_get_sample_rate()
1243 return -1; in minstrel_get_sample_rate()
1246 * Do not sample if the probability is already higher than 95%, in minstrel_get_sample_rate()
1251 if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || in minstrel_get_sample_rate()
1252 minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) in minstrel_get_sample_rate()
1253 return -1; in minstrel_get_sample_rate()
1257 * For devices with no configurable multi-rate retry, skip sampling in minstrel_get_sample_rate()
1258 * below the per-group max throughput rate, and only use one sampling in minstrel_get_sample_rate()
1261 if (mp->hw->max_rates == 1 && in minstrel_get_sample_rate()
1262 (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur || in minstrel_get_sample_rate()
1263 mrs->attempts)) in minstrel_get_sample_rate()
1264 return -1; in minstrel_get_sample_rate()
1267 if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts) in minstrel_get_sample_rate()
1268 return -1; in minstrel_get_sample_rate()
1278 (cur_max_tp_streams - 1 < in minstrel_get_sample_rate()
1280 sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { in minstrel_get_sample_rate()
1281 if (mrs->sample_skipped < 20) in minstrel_get_sample_rate()
1282 return -1; in minstrel_get_sample_rate()
1284 if (mi->sample_slow++ > 2) in minstrel_get_sample_rate()
1285 return -1; in minstrel_get_sample_rate()
1287 mi->sample_tries--; in minstrel_get_sample_rate()
1297 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); in minstrel_ht_get_rate()
1298 struct ieee80211_tx_rate *rate = &info->status.rates[0]; in minstrel_ht_get_rate()
1300 struct minstrel_ht_sta *mi = &msp->ht; in minstrel_ht_get_rate()
1304 if (!msp->is_ht) in minstrel_ht_get_rate()
1305 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); in minstrel_ht_get_rate()
1307 if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && in minstrel_ht_get_rate()
1308 mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) in minstrel_ht_get_rate()
1309 minstrel_aggr_check(sta, txrc->skb); in minstrel_ht_get_rate()
1311 info->flags |= mi->tx_flags; in minstrel_ht_get_rate()
1314 if (mp->fixed_rate_idx != -1) in minstrel_ht_get_rate()
1318 /* Don't use EAPOL frames for sampling on non-mrr hw */ in minstrel_ht_get_rate()
1319 if (mp->hw->max_rates == 1 && in minstrel_ht_get_rate()
1320 (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) in minstrel_ht_get_rate()
1321 sample_idx = -1; in minstrel_ht_get_rate()
1325 mi->total_packets++; in minstrel_ht_get_rate()
1328 if (mi->total_packets == ~0) { in minstrel_ht_get_rate()
1329 mi->total_packets = 0; in minstrel_ht_get_rate()
1330 mi->sample_packets = 0; in minstrel_ht_get_rate()
1340 (sample_idx >= 4) != txrc->short_preamble) in minstrel_ht_get_rate()
1343 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; in minstrel_ht_get_rate()
1344 rate->count = 1; in minstrel_ht_get_rate()
1347 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); in minstrel_ht_get_rate()
1348 rate->idx = mp->cck_rates[idx]; in minstrel_ht_get_rate()
1349 } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { in minstrel_ht_get_rate()
1351 sample_group->streams); in minstrel_ht_get_rate()
1353 rate->idx = sample_idx + (sample_group->streams - 1) * 8; in minstrel_ht_get_rate()
1356 rate->flags = sample_group->flags; in minstrel_ht_get_rate()
1366 if (sband->band != NL80211_BAND_2GHZ) in minstrel_ht_update_cck()
1369 if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) in minstrel_ht_update_cck()
1372 mi->cck_supported = 0; in minstrel_ht_update_cck()
1373 mi->cck_supported_short = 0; in minstrel_ht_update_cck()
1375 if (!rate_supported(sta, sband->band, mp->cck_rates[i])) in minstrel_ht_update_cck()
1378 mi->cck_supported |= BIT(i); in minstrel_ht_update_cck()
1379 if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) in minstrel_ht_update_cck()
1380 mi->cck_supported_short |= BIT(i); in minstrel_ht_update_cck()
1383 mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported; in minstrel_ht_update_cck()
1393 struct minstrel_ht_sta *mi = &msp->ht; in minstrel_ht_update_caps()
1394 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; in minstrel_ht_update_caps()
1395 u16 ht_cap = sta->ht_cap.cap; in minstrel_ht_update_caps()
1396 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; in minstrel_ht_update_caps()
1405 if (!sta->ht_cap.ht_supported) in minstrel_ht_update_caps()
1410 if (vht_cap->vht_supported) in minstrel_ht_update_caps()
1411 use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); in minstrel_ht_update_caps()
1415 msp->is_ht = true; in minstrel_ht_update_caps()
1418 mi->sta = sta; in minstrel_ht_update_caps()
1419 mi->last_stats_update = jiffies; in minstrel_ht_update_caps()
1421 ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0); in minstrel_ht_update_caps()
1422 mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1, 0); in minstrel_ht_update_caps()
1423 mi->overhead += ack_dur; in minstrel_ht_update_caps()
1424 mi->overhead_rtscts = mi->overhead + 2 * ack_dur; in minstrel_ht_update_caps()
1426 mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); in minstrel_ht_update_caps()
1428 /* When using MRR, sample more on the first attempt, without delay */ in minstrel_ht_update_caps()
1429 if (mp->has_mrr) { in minstrel_ht_update_caps()
1430 mi->sample_count = 16; in minstrel_ht_update_caps()
1431 mi->sample_wait = 0; in minstrel_ht_update_caps()
1433 mi->sample_count = 8; in minstrel_ht_update_caps()
1434 mi->sample_wait = 8; in minstrel_ht_update_caps()
1436 mi->sample_tries = 4; in minstrel_ht_update_caps()
1444 stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> in minstrel_ht_update_caps()
1447 ldpc = vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC; in minstrel_ht_update_caps()
1450 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; in minstrel_ht_update_caps()
1452 mi->tx_flags |= IEEE80211_TX_CTL_LDPC; in minstrel_ht_update_caps()
1454 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { in minstrel_ht_update_caps()
1458 mi->supported[i] = 0; in minstrel_ht_update_caps()
1475 sta->bandwidth < IEEE80211_STA_RX_BW_40) in minstrel_ht_update_caps()
1481 if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) in minstrel_ht_update_caps()
1489 mi->supported[i] = mcs->rx_mask[nss - 1]; in minstrel_ht_update_caps()
1490 if (mi->supported[i]) in minstrel_ht_update_caps()
1496 if (!vht_cap->vht_supported || in minstrel_ht_update_caps()
1502 if (sta->bandwidth < IEEE80211_STA_RX_BW_80 || in minstrel_ht_update_caps()
1504 !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { in minstrel_ht_update_caps()
1516 mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss, in minstrel_ht_update_caps()
1517 vht_cap->vht_mcs.tx_mcs_map); in minstrel_ht_update_caps()
1519 if (mi->supported[i]) in minstrel_ht_update_caps()
1526 mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; in minstrel_ht_update_caps()
1535 msp->is_ht = false; in minstrel_ht_update_caps()
1536 memset(&msp->legacy, 0, sizeof(msp->legacy)); in minstrel_ht_update_caps()
1537 msp->legacy.r = msp->ratelist; in minstrel_ht_update_caps()
1538 msp->legacy.sample_table = msp->sample_table; in minstrel_ht_update_caps()
1540 &msp->legacy); in minstrel_ht_update_caps()
1566 struct ieee80211_hw *hw = mp->hw; in minstrel_ht_alloc_sta()
1571 sband = hw->wiphy->bands[i]; in minstrel_ht_alloc_sta()
1572 if (sband && sband->n_bitrates > max_rates) in minstrel_ht_alloc_sta()
1573 max_rates = sband->n_bitrates; in minstrel_ht_alloc_sta()
1580 msp->ratelist = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); in minstrel_ht_alloc_sta()
1581 if (!msp->ratelist) in minstrel_ht_alloc_sta()
1584 msp->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); in minstrel_ht_alloc_sta()
1585 if (!msp->sample_table) in minstrel_ht_alloc_sta()
1591 kfree(msp->ratelist); in minstrel_ht_alloc_sta()
1602 kfree(msp->sample_table); in minstrel_ht_free_sta()
1603 kfree(msp->ratelist); in minstrel_ht_free_sta()
1612 u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); in minstrel_ht_init_cck_rates()
1615 sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; in minstrel_ht_init_cck_rates()
1619 for (i = 0; i < sband->n_bitrates; i++) { in minstrel_ht_init_cck_rates()
1620 struct ieee80211_rate *rate = &sband->bitrates[i]; in minstrel_ht_init_cck_rates()
1622 if (rate->flags & IEEE80211_RATE_ERP_G) in minstrel_ht_init_cck_rates()
1625 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in minstrel_ht_init_cck_rates()
1629 if (rate->bitrate != bitrates[j]) in minstrel_ht_init_cck_rates()
1632 mp->cck_rates[j] = i; in minstrel_ht_init_cck_rates()
1647 mp->sample_switch = -1; in minstrel_ht_alloc()
1650 * Just an approximation. Using the per-queue values would complicate in minstrel_ht_alloc()
1652 mp->cw_min = 15; in minstrel_ht_alloc()
1653 mp->cw_max = 1023; in minstrel_ht_alloc()
1656 * sample less often for non-mrr packets, because the overhead in minstrel_ht_alloc()
1658 mp->lookaround_rate = 5; in minstrel_ht_alloc()
1659 mp->lookaround_rate_mrr = 10; in minstrel_ht_alloc()
1661 /* maximum time that the hw is allowed to stay in one MRR segment */ in minstrel_ht_alloc()
1662 mp->segment_size = 6000; in minstrel_ht_alloc()
1664 if (hw->max_rate_tries > 0) in minstrel_ht_alloc()
1665 mp->max_retry = hw->max_rate_tries; in minstrel_ht_alloc()
1668 mp->max_retry = 7; in minstrel_ht_alloc()
1670 if (hw->max_rates >= 4) in minstrel_ht_alloc()
1671 mp->has_mrr = true; in minstrel_ht_alloc()
1673 mp->hw = hw; in minstrel_ht_alloc()
1674 mp->update_interval = HZ / 10; in minstrel_ht_alloc()
1675 mp->new_avg = true; in minstrel_ht_alloc()
1688 mp->fixed_rate_idx = (u32) -1; in minstrel_ht_add_debugfs()
1690 &mp->fixed_rate_idx); in minstrel_ht_add_debugfs()
1692 &mp->sample_switch); in minstrel_ht_add_debugfs()
1694 &mp->new_avg); in minstrel_ht_add_debugfs()
1707 struct minstrel_ht_sta *mi = &msp->ht; in minstrel_ht_get_expected_throughput()
1710 if (!msp->is_ht) in minstrel_ht_get_expected_throughput()
1713 i = mi->max_tp_rate[0] / MCS_GROUP_RATES; in minstrel_ht_get_expected_throughput()
1714 j = mi->max_tp_rate[0] % MCS_GROUP_RATES; in minstrel_ht_get_expected_throughput()
1715 prob = mi->groups[i].rates[j].prob_avg; in minstrel_ht_get_expected_throughput()