Lines Matching +full:max +full:- +full:sample +full:- +full:rate +full:- +full:hz
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org>
4 * Copyright (C) 2019-2022 Intel Corporation
15 #include "rate.h"
44 * Define group sort order: HT40 -> SGI -> #streams
50 _streams - 1
55 _MAX(0, 16 - __builtin_clz(duration))
57 /* MCS rate information for an MCS group */
90 (_streams) - 1)
203 * To enable sufficiently targeted rate sampling, MCS rates are divided into
208 * BW -> SGI -> #streams
303 switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) { in minstrel_get_valid_vht_rates()
327 * Look up an MCS group index based on mac80211 rate information
330 minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) in minstrel_ht_get_group_idx() argument
332 return GROUP_IDX((rate->idx / 8) + 1, in minstrel_ht_get_group_idx()
333 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), in minstrel_ht_get_group_idx()
334 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); in minstrel_ht_get_group_idx()
341 minstrel_ht_ri_get_group_idx(struct rate_info *rate) in minstrel_ht_ri_get_group_idx() argument
343 return GROUP_IDX((rate->mcs / 8) + 1, in minstrel_ht_ri_get_group_idx()
344 !!(rate->flags & RATE_INFO_FLAGS_SHORT_GI), in minstrel_ht_ri_get_group_idx()
345 !!(rate->bw & RATE_INFO_BW_40)); in minstrel_ht_ri_get_group_idx()
349 minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate) in minstrel_vht_get_group_idx() argument
351 return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate), in minstrel_vht_get_group_idx()
352 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), in minstrel_vht_get_group_idx()
353 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + in minstrel_vht_get_group_idx()
354 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)); in minstrel_vht_get_group_idx()
361 minstrel_vht_ri_get_group_idx(struct rate_info *rate) in minstrel_vht_ri_get_group_idx() argument
363 return VHT_GROUP_IDX(rate->nss, in minstrel_vht_ri_get_group_idx()
364 !!(rate->flags & RATE_INFO_FLAGS_SHORT_GI), in minstrel_vht_ri_get_group_idx()
365 !!(rate->bw & RATE_INFO_BW_40) + in minstrel_vht_ri_get_group_idx()
366 2*!!(rate->bw & RATE_INFO_BW_80)); in minstrel_vht_ri_get_group_idx()
371 struct ieee80211_tx_rate *rate) in minstrel_ht_get_stats() argument
375 if (rate->flags & IEEE80211_TX_RC_MCS) { in minstrel_ht_get_stats()
376 group = minstrel_ht_get_group_idx(rate); in minstrel_ht_get_stats()
377 idx = rate->idx % 8; in minstrel_ht_get_stats()
381 if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { in minstrel_ht_get_stats()
382 group = minstrel_vht_get_group_idx(rate); in minstrel_ht_get_stats()
383 idx = ieee80211_rate_get_vht_mcs(rate); in minstrel_ht_get_stats()
388 for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { in minstrel_ht_get_stats()
389 if (!(mi->supported[group] & BIT(idx))) in minstrel_ht_get_stats()
392 if (rate->idx != mp->cck_rates[idx]) in minstrel_ht_get_stats()
396 if ((mi->supported[group] & BIT(idx + 4)) && in minstrel_ht_get_stats()
397 (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) in minstrel_ht_get_stats()
403 for (idx = 0; idx < ARRAY_SIZE(mp->ofdm_rates[0]); idx++) in minstrel_ht_get_stats()
404 if (rate->idx == mp->ofdm_rates[mi->band][idx]) in minstrel_ht_get_stats()
409 return &mi->groups[group].rates[idx]; in minstrel_ht_get_stats()
413 * Get the minstrel rate statistics for specified STA and rate info.
420 struct rate_info *rate = &rate_status->rate_idx; in minstrel_ht_ri_get_stats() local
422 if (rate->flags & RATE_INFO_FLAGS_MCS) { in minstrel_ht_ri_get_stats()
423 group = minstrel_ht_ri_get_group_idx(rate); in minstrel_ht_ri_get_stats()
424 idx = rate->mcs % 8; in minstrel_ht_ri_get_stats()
428 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) { in minstrel_ht_ri_get_stats()
429 group = minstrel_vht_ri_get_group_idx(rate); in minstrel_ht_ri_get_stats()
430 idx = rate->mcs; in minstrel_ht_ri_get_stats()
435 for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { in minstrel_ht_ri_get_stats()
436 if (rate->legacy != minstrel_cck_bitrates[ mp->cck_rates[idx] ]) in minstrel_ht_ri_get_stats()
440 if ((mi->supported[group] & BIT(idx + 4)) && in minstrel_ht_ri_get_stats()
441 mi->use_short_preamble) in minstrel_ht_ri_get_stats()
447 for (idx = 0; idx < ARRAY_SIZE(mp->ofdm_rates[0]); idx++) in minstrel_ht_ri_get_stats()
448 if (rate->legacy == minstrel_ofdm_bitrates[ mp->ofdm_rates[mi->band][idx] ]) in minstrel_ht_ri_get_stats()
453 return &mi->groups[group].rates[idx]; in minstrel_ht_ri_get_stats()
459 return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)]; in minstrel_get_ratestats()
465 unsigned int duration = group->duration[MI_RATE_IDX(index)]; in minstrel_get_duration()
467 return duration << group->shift; in minstrel_get_duration()
475 if (mi->avg_ampdu_len) in minstrel_ht_avg_ampdu_len()
476 return MINSTREL_TRUNC(mi->avg_ampdu_len); in minstrel_ht_avg_ampdu_len()
478 if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0]))) in minstrel_ht_avg_ampdu_len()
481 duration = minstrel_get_duration(mi->max_tp_rate[0]); in minstrel_ht_avg_ampdu_len()
496 * Return current throughput based on the average A-MPDU length, taking into
500 minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, in minstrel_ht_get_tp_avg() argument
503 unsigned int nsecs = 0, overhead = mi->overhead; in minstrel_ht_get_tp_avg()
511 overhead = mi->overhead_legacy; in minstrel_ht_get_tp_avg()
516 nsecs += minstrel_mcs_groups[group].duration[rate] << in minstrel_ht_get_tp_avg()
521 * account for collision related packet error rate fluctuation in minstrel_ht_get_tp_avg()
522 * (prob is scaled - see MINSTREL_FRAC above) in minstrel_ht_get_tp_avg()
547 cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; in minstrel_ht_sort_best_tp_rates()
551 tmp_group = MI_RATE_GROUP(tp_list[j - 1]); in minstrel_ht_sort_best_tp_rates()
552 tmp_idx = MI_RATE_IDX(tp_list[j - 1]); in minstrel_ht_sort_best_tp_rates()
553 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_sort_best_tp_rates()
559 j--; in minstrel_ht_sort_best_tp_rates()
562 if (j < MAX_THR_RATES - 1) { in minstrel_ht_sort_best_tp_rates()
564 (MAX_THR_RATES - (j + 1)))); in minstrel_ht_sort_best_tp_rates()
571 * Find and set the topmost probability rate per sta and per group
586 mg = &mi->groups[cur_group]; in minstrel_ht_set_best_prob_rate()
587 mrs = &mg->rates[cur_idx]; in minstrel_ht_set_best_prob_rate()
591 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_set_best_prob_rate()
596 max_tp_group = MI_RATE_GROUP(mi->max_tp_rate[0]); in minstrel_ht_set_best_prob_rate()
597 max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]); in minstrel_ht_set_best_prob_rate()
598 max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg; in minstrel_ht_set_best_prob_rate()
604 /* skip rates faster than max tp rate with lower prob */ in minstrel_ht_set_best_prob_rate()
605 if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && in minstrel_ht_set_best_prob_rate()
606 mrs->prob_avg < max_tp_prob) in minstrel_ht_set_best_prob_rate()
609 max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); in minstrel_ht_set_best_prob_rate()
610 max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); in minstrel_ht_set_best_prob_rate()
611 max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; in minstrel_ht_set_best_prob_rate()
613 if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { in minstrel_ht_set_best_prob_rate()
615 mrs->prob_avg); in minstrel_ht_set_best_prob_rate()
623 mg->max_group_prob_rate = index; in minstrel_ht_set_best_prob_rate()
625 if (mrs->prob_avg > tmp_prob) in minstrel_ht_set_best_prob_rate()
627 if (mrs->prob_avg > max_gpr_prob) in minstrel_ht_set_best_prob_rate()
628 mg->max_group_prob_rate = index; in minstrel_ht_set_best_prob_rate()
634 * Assign new rate set per sta and use CCK rates only if the fastest
635 * rate (max_tp_rate[0]) is from CCK group. This prohibits such sorted
636 * rate sets where MCS and CCK rates are mixed, because CCK rates can
649 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_assign_best_tp_rates()
654 tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; in minstrel_ht_assign_best_tp_rates()
667 * Try to increase robustness of max_prob rate by decrease number of
677 if (!mi->sta->deflink.ht_cap.ht_supported) in minstrel_ht_prob_rate_reduce_streams()
680 group = MI_RATE_GROUP(mi->max_tp_rate[0]); in minstrel_ht_prob_rate_reduce_streams()
683 mg = &mi->groups[group]; in minstrel_ht_prob_rate_reduce_streams()
684 if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) in minstrel_ht_prob_rate_reduce_streams()
687 tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); in minstrel_ht_prob_rate_reduce_streams()
688 tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; in minstrel_ht_prob_rate_reduce_streams()
692 mi->max_prob_rate = mg->max_group_prob_rate; in minstrel_ht_prob_rate_reduce_streams()
704 u16 *rates = mi->sample[type].sample_rates; in __minstrel_ht_get_sample_rate()
725 diff = new - old; in minstrel_ewma()
726 incr = (EWMA_DIV - weight) * diff / EWMA_DIV; in minstrel_ewma()
763 * Recalculate statistics and counters of a given rate
771 if (unlikely(mrs->attempts > 0)) { in minstrel_ht_calc_rate_stats()
772 cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); in minstrel_ht_calc_rate_stats()
773 minstrel_filter_avg_add(&mrs->prob_avg, in minstrel_ht_calc_rate_stats()
774 &mrs->prob_avg_1, cur_prob); in minstrel_ht_calc_rate_stats()
775 mrs->att_hist += mrs->attempts; in minstrel_ht_calc_rate_stats()
776 mrs->succ_hist += mrs->success; in minstrel_ht_calc_rate_stats()
779 mrs->last_success = mrs->success; in minstrel_ht_calc_rate_stats()
780 mrs->last_attempts = mrs->attempts; in minstrel_ht_calc_rate_stats()
781 mrs->success = 0; in minstrel_ht_calc_rate_stats()
782 mrs->attempts = 0; in minstrel_ht_calc_rate_stats()
791 u16 cur = mi->sample[type].sample_rates[i]; in minstrel_ht_find_sample_rate()
807 u16 *rates = mi->sample[type].sample_rates; in minstrel_ht_move_sample_rates()
853 u16 supported = mi->supported[group]; in minstrel_ht_group_min_rate_offset()
866 return -1; in minstrel_ht_group_min_rate_offset()
871 * Flip through groups and pick the first group rate that is faster than the
872 * highest currently selected rate
881 group = mi->sample[type].sample_group; in minstrel_ht_next_inc_rate()
897 mi->sample[type].sample_group = group; in minstrel_ht_next_inc_rate()
906 struct minstrel_mcs_group_data *mg = &mi->groups[group]; in minstrel_ht_next_group_sample_rate()
911 idx = sample_table[mg->column][mg->index]; in minstrel_ht_next_group_sample_rate()
912 if (++mg->index >= MCS_GROUP_RATES) { in minstrel_ht_next_group_sample_rate()
913 mg->index = 0; in minstrel_ht_next_group_sample_rate()
914 if (++mg->column >= ARRAY_SIZE(sample_table)) in minstrel_ht_next_group_sample_rate()
915 mg->column = 0; in minstrel_ht_next_group_sample_rate()
927 return -1; in minstrel_ht_next_group_sample_rate()
932 * Sample random rates, use those that are faster than the highest
933 * currently selected rate. Rates between the fastest and the slowest
934 * get sorted into the slow sample bucket, but only if it has room
951 slow_rates = mi->sample[MINSTREL_SAMPLE_TYPE_SLOW].sample_rates; in minstrel_ht_next_jump_rate()
952 group = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group; in minstrel_ht_next_jump_rate()
958 supported = mi->supported[group]; in minstrel_ht_next_jump_rate()
992 if (mrs->prob_avg > MINSTREL_FRAC(95, 100)) in minstrel_ht_next_jump_rate()
1002 mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group = group; in minstrel_ht_next_jump_rate()
1010 u32 prob_dur = minstrel_get_duration(mi->max_prob_rate); in minstrel_ht_refill_sample_rates()
1011 u32 tp_dur = minstrel_get_duration(mi->max_tp_rate[0]); in minstrel_ht_refill_sample_rates()
1012 u32 tp2_dur = minstrel_get_duration(mi->max_tp_rate[1]); in minstrel_ht_refill_sample_rates()
1014 u32 slow_rate_dur = max(max(tp_dur, tp2_dur), prob_dur); in minstrel_ht_refill_sample_rates()
1018 rates = mi->sample[MINSTREL_SAMPLE_TYPE_INC].sample_rates; in minstrel_ht_refill_sample_rates()
1029 rates = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_rates; in minstrel_ht_refill_sample_rates()
1043 for (i = 0; i < ARRAY_SIZE(mi->sample); i++) in minstrel_ht_refill_sample_rates()
1044 memcpy(mi->sample[i].cur_sample_rates, mi->sample[i].sample_rates, in minstrel_ht_refill_sample_rates()
1045 sizeof(mi->sample[i].cur_sample_rates)); in minstrel_ht_refill_sample_rates()
1050 * Update rate statistics and select new primary rates
1052 * Rules for rate selection:
1053 * - max_prob_rate must use only one stream, as a tradeoff between delivery
1055 * - as long as the max prob rate has a probability of more than 75%, pick
1067 bool ht_supported = mi->sta->deflink.ht_cap.ht_supported; in minstrel_ht_update_stats()
1069 if (mi->ampdu_packets > 0) { in minstrel_ht_update_stats()
1070 if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) in minstrel_ht_update_stats()
1071 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, in minstrel_ht_update_stats()
1072 MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), in minstrel_ht_update_stats()
1075 mi->avg_ampdu_len = 0; in minstrel_ht_update_stats()
1076 mi->ampdu_len = 0; in minstrel_ht_update_stats()
1077 mi->ampdu_packets = 0; in minstrel_ht_update_stats()
1080 if (mi->supported[MINSTREL_CCK_GROUP]) in minstrel_ht_update_stats()
1082 else if (mi->supported[MINSTREL_OFDM_GROUP]) in minstrel_ht_update_stats()
1091 if (mi->supported[MINSTREL_VHT_GROUP_0]) in minstrel_ht_update_stats()
1095 else if (mi->supported[MINSTREL_CCK_GROUP]) in minstrel_ht_update_stats()
1105 /* Find best rate sets within all MCS groups*/ in minstrel_ht_update_stats()
1110 mg = &mi->groups[group]; in minstrel_ht_update_stats()
1111 if (!mi->supported[group]) in minstrel_ht_update_stats()
1114 /* (re)Initialize group rate indexes */ in minstrel_ht_update_stats()
1121 for (i = MCS_GROUP_RATES - 1; i >= 0; i--) { in minstrel_ht_update_stats()
1122 if (!(mi->supported[group] & BIT(i))) in minstrel_ht_update_stats()
1127 mrs = &mg->rates[i]; in minstrel_ht_update_stats()
1128 mrs->retry_updated = false; in minstrel_ht_update_stats()
1131 if (mrs->att_hist) in minstrel_ht_update_stats()
1132 last_prob = max(last_prob, mrs->prob_avg); in minstrel_ht_update_stats()
1134 mrs->prob_avg = max(last_prob, mrs->prob_avg); in minstrel_ht_update_stats()
1135 cur_prob = mrs->prob_avg; in minstrel_ht_update_stats()
1140 /* Find max throughput rate set */ in minstrel_ht_update_stats()
1143 /* Find max throughput rate set within a group */ in minstrel_ht_update_stats()
1148 memcpy(mg->max_group_tp_rate, tmp_group_tp_rate, in minstrel_ht_update_stats()
1149 sizeof(mg->max_group_tp_rate)); in minstrel_ht_update_stats()
1152 /* Assign new rate set per sta */ in minstrel_ht_update_stats()
1155 memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); in minstrel_ht_update_stats()
1158 if (!mi->supported[group]) in minstrel_ht_update_stats()
1161 mg = &mi->groups[group]; in minstrel_ht_update_stats()
1162 mg->max_group_prob_rate = MI_RATE(group, 0); in minstrel_ht_update_stats()
1165 if (!(mi->supported[group] & BIT(i))) in minstrel_ht_update_stats()
1170 /* Find max probability rate per group and global */ in minstrel_ht_update_stats()
1176 mi->max_prob_rate = tmp_max_prob_rate; in minstrel_ht_update_stats()
1184 if (mp->fixed_rate_idx != -1) { in minstrel_ht_update_stats()
1186 mi->max_tp_rate[i] = mp->fixed_rate_idx; in minstrel_ht_update_stats()
1187 mi->max_prob_rate = mp->fixed_rate_idx; in minstrel_ht_update_stats()
1192 mi->last_stats_update = jiffies; in minstrel_ht_update_stats()
1193 mi->sample_time = jiffies; in minstrel_ht_update_stats()
1198 struct ieee80211_tx_rate *rate) in minstrel_ht_txstat_valid() argument
1202 if (rate->idx < 0) in minstrel_ht_txstat_valid()
1205 if (!rate->count) in minstrel_ht_txstat_valid()
1208 if (rate->flags & IEEE80211_TX_RC_MCS || in minstrel_ht_txstat_valid()
1209 rate->flags & IEEE80211_TX_RC_VHT_MCS) in minstrel_ht_txstat_valid()
1212 for (i = 0; i < ARRAY_SIZE(mp->cck_rates); i++) in minstrel_ht_txstat_valid()
1213 if (rate->idx == mp->cck_rates[i]) in minstrel_ht_txstat_valid()
1216 for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) in minstrel_ht_txstat_valid()
1217 if (rate->idx == mp->ofdm_rates[mi->band][i]) in minstrel_ht_txstat_valid()
1235 if (!rate_status->try_count) in minstrel_ht_ri_txstat_valid()
1238 if (rate_status->rate_idx.flags & RATE_INFO_FLAGS_MCS || in minstrel_ht_ri_txstat_valid()
1239 rate_status->rate_idx.flags & RATE_INFO_FLAGS_VHT_MCS) in minstrel_ht_ri_txstat_valid()
1242 for (i = 0; i < ARRAY_SIZE(mp->cck_rates); i++) { in minstrel_ht_ri_txstat_valid()
1243 if (rate_status->rate_idx.legacy == in minstrel_ht_ri_txstat_valid()
1244 minstrel_cck_bitrates[ mp->cck_rates[i] ]) in minstrel_ht_ri_txstat_valid()
1248 for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates); i++) { in minstrel_ht_ri_txstat_valid()
1249 if (rate_status->rate_idx.legacy == in minstrel_ht_ri_txstat_valid()
1250 minstrel_ofdm_bitrates[ mp->ofdm_rates[mi->band][i] ]) in minstrel_ht_ri_txstat_valid()
1264 group--; in minstrel_downgrade_rate()
1266 if (!mi->supported[group]) in minstrel_downgrade_rate()
1274 *idx = mi->groups[group].max_group_tp_rate[0]; in minstrel_downgrade_rate()
1276 *idx = mi->groups[group].max_group_tp_rate[1]; in minstrel_downgrade_rate()
1285 struct ieee80211_tx_info *info = st->info; in minstrel_ht_tx_status()
1287 struct ieee80211_tx_rate *ar = info->status.rates; in minstrel_ht_tx_status()
1288 struct minstrel_rate_stats *rate, *rate2; in minstrel_ht_tx_status() local
1290 u32 update_interval = mp->update_interval; in minstrel_ht_tx_status()
1295 if (info->flags & IEEE80211_TX_CTL_NO_ACK) in minstrel_ht_tx_status()
1299 if ((info->flags & IEEE80211_TX_CTL_AMPDU) && in minstrel_ht_tx_status()
1300 !(info->flags & IEEE80211_TX_STAT_AMPDU)) in minstrel_ht_tx_status()
1303 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { in minstrel_ht_tx_status()
1304 info->status.ampdu_ack_len = in minstrel_ht_tx_status()
1305 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); in minstrel_ht_tx_status()
1306 info->status.ampdu_len = 1; in minstrel_ht_tx_status()
1310 if (mi->total_packets >= ~0 - info->status.ampdu_len) { in minstrel_ht_tx_status()
1311 mi->total_packets = 0; in minstrel_ht_tx_status()
1312 mi->sample_packets = 0; in minstrel_ht_tx_status()
1315 mi->total_packets += info->status.ampdu_len; in minstrel_ht_tx_status()
1316 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) in minstrel_ht_tx_status()
1317 mi->sample_packets += info->status.ampdu_len; in minstrel_ht_tx_status()
1319 mi->ampdu_packets++; in minstrel_ht_tx_status()
1320 mi->ampdu_len += info->status.ampdu_len; in minstrel_ht_tx_status()
1322 if (st->rates && st->n_rates) { in minstrel_ht_tx_status()
1323 last = !minstrel_ht_ri_txstat_valid(mp, mi, &(st->rates[0])); in minstrel_ht_tx_status()
1325 last = (i == st->n_rates - 1) || in minstrel_ht_tx_status()
1327 &(st->rates[i + 1])); in minstrel_ht_tx_status()
1329 rate = minstrel_ht_ri_get_stats(mp, mi, in minstrel_ht_tx_status()
1330 &(st->rates[i])); in minstrel_ht_tx_status()
1333 rate->success += info->status.ampdu_ack_len; in minstrel_ht_tx_status()
1335 rate->attempts += st->rates[i].try_count * in minstrel_ht_tx_status()
1336 info->status.ampdu_len; in minstrel_ht_tx_status()
1341 last = (i == IEEE80211_TX_MAX_RATES - 1) || in minstrel_ht_tx_status()
1344 rate = minstrel_ht_get_stats(mp, mi, &ar[i]); in minstrel_ht_tx_status()
1346 rate->success += info->status.ampdu_ack_len; in minstrel_ht_tx_status()
1348 rate->attempts += ar[i].count * info->status.ampdu_len; in minstrel_ht_tx_status()
1352 if (mp->hw->max_rates > 1) { in minstrel_ht_tx_status()
1357 rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); in minstrel_ht_tx_status()
1358 if (rate->attempts > 30 && in minstrel_ht_tx_status()
1359 rate->success < rate->attempts / 4) { in minstrel_ht_tx_status()
1360 minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); in minstrel_ht_tx_status()
1364 rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); in minstrel_ht_tx_status()
1365 if (rate2->attempts > 30 && in minstrel_ht_tx_status()
1366 rate2->success < rate2->attempts / 4) { in minstrel_ht_tx_status()
1367 minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); in minstrel_ht_tx_status()
1372 if (time_after(jiffies, mi->last_stats_update + update_interval)) { in minstrel_ht_tx_status()
1387 unsigned int cw = mp->cw_min; in minstrel_calc_retransmit()
1394 if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) { in minstrel_calc_retransmit()
1395 mrs->retry_count = 1; in minstrel_calc_retransmit()
1396 mrs->retry_count_rtscts = 1; in minstrel_calc_retransmit()
1400 mrs->retry_count = 2; in minstrel_calc_retransmit()
1401 mrs->retry_count_rtscts = 2; in minstrel_calc_retransmit()
1402 mrs->retry_updated = true; in minstrel_calc_retransmit()
1408 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1410 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1413 overhead = mi->overhead_legacy; in minstrel_calc_retransmit()
1414 overhead_rtscts = mi->overhead_legacy_rtscts; in minstrel_calc_retransmit()
1416 overhead = mi->overhead; in minstrel_calc_retransmit()
1417 overhead_rtscts = mi->overhead_rtscts; in minstrel_calc_retransmit()
1428 cw = min((cw << 1) | 1, mp->cw_max); in minstrel_calc_retransmit()
1434 if (tx_time_rtscts < mp->segment_size) in minstrel_calc_retransmit()
1435 mrs->retry_count_rtscts++; in minstrel_calc_retransmit()
1436 } while ((tx_time < mp->segment_size) && in minstrel_calc_retransmit()
1437 (++mrs->retry_count < mp->max_retry)); in minstrel_calc_retransmit()
1449 u16 flags = group->flags; in minstrel_ht_set_rate()
1452 if (!mrs->retry_updated) in minstrel_ht_set_rate()
1455 if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) { in minstrel_ht_set_rate()
1456 ratetbl->rate[offset].count = 2; in minstrel_ht_set_rate()
1457 ratetbl->rate[offset].count_rts = 2; in minstrel_ht_set_rate()
1458 ratetbl->rate[offset].count_cts = 2; in minstrel_ht_set_rate()
1460 ratetbl->rate[offset].count = mrs->retry_count; in minstrel_ht_set_rate()
1461 ratetbl->rate[offset].count_cts = mrs->retry_count; in minstrel_ht_set_rate()
1462 ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; in minstrel_ht_set_rate()
1467 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; in minstrel_ht_set_rate()
1469 idx = mp->ofdm_rates[mi->band][index % in minstrel_ht_set_rate()
1470 ARRAY_SIZE(mp->ofdm_rates[0])]; in minstrel_ht_set_rate()
1472 idx = ((group->streams - 1) << 4) | in minstrel_ht_set_rate()
1475 idx = index + (group->streams - 1) * 8; in minstrel_ht_set_rate()
1478 * - if station is in dynamic SMPS (and streams > 1) in minstrel_ht_set_rate()
1479 * - for fallback rates, to increase chances of getting through in minstrel_ht_set_rate()
1482 (mi->sta->deflink.smps_mode == IEEE80211_SMPS_DYNAMIC && in minstrel_ht_set_rate()
1483 group->streams > 1)) { in minstrel_ht_set_rate()
1484 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; in minstrel_ht_set_rate()
1488 ratetbl->rate[offset].idx = idx; in minstrel_ht_set_rate()
1489 ratetbl->rate[offset].flags = flags; in minstrel_ht_set_rate()
1493 minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate) in minstrel_ht_get_prob_avg() argument
1495 int group = MI_RATE_GROUP(rate); in minstrel_ht_get_prob_avg()
1496 rate = MI_RATE_IDX(rate); in minstrel_ht_get_prob_avg()
1497 return mi->groups[group].rates[rate].prob_avg; in minstrel_ht_get_prob_avg()
1503 int group = MI_RATE_GROUP(mi->max_prob_rate); in minstrel_ht_get_max_amsdu_len()
1505 int rate = MI_RATE_IDX(mi->max_prob_rate); in minstrel_ht_get_max_amsdu_len() local
1508 /* Disable A-MSDU if max_prob_rate is bad */ in minstrel_ht_get_max_amsdu_len()
1509 if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100)) in minstrel_ht_get_max_amsdu_len()
1512 duration = g->duration[rate]; in minstrel_ht_get_max_amsdu_len()
1513 duration <<= g->shift; in minstrel_ht_get_max_amsdu_len()
1515 /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ in minstrel_ht_get_max_amsdu_len()
1520 * If the rate is slower than single-stream MCS4, limit A-MSDU to usual in minstrel_ht_get_max_amsdu_len()
1527 * If the rate is slower than single-stream MCS7, or if the max throughput in minstrel_ht_get_max_amsdu_len()
1528 * rate success probability is less than 75%, limit A-MSDU to twice the usual in minstrel_ht_get_max_amsdu_len()
1532 (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) < in minstrel_ht_get_max_amsdu_len()
1537 * HT A-MPDU limits maximum MPDU size under BA agreement to 4095 bytes. in minstrel_ht_get_max_amsdu_len()
1539 * the limit here to avoid the complexity of having to de-aggregate in minstrel_ht_get_max_amsdu_len()
1542 if (!mi->sta->deflink.vht_cap.vht_supported) in minstrel_ht_get_max_amsdu_len()
1554 int max_rates = min_t(int, mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE); in minstrel_ht_update_rates()
1561 minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); in minstrel_ht_update_rates()
1564 for (; i < (max_rates - 1); i++) in minstrel_ht_update_rates()
1565 minstrel_ht_set_rate(mp, mi, rates, i, mi->max_tp_rate[i]); in minstrel_ht_update_rates()
1568 minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); in minstrel_ht_update_rates()
1571 rates->rate[i].idx = -1; in minstrel_ht_update_rates()
1573 mi->sta->deflink.agg.max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi); in minstrel_ht_update_rates()
1574 ieee80211_sta_recalc_aggregates(mi->sta); in minstrel_ht_update_rates()
1575 rate_control_set_rates(mp->hw, mi->sta, rates); in minstrel_ht_update_rates()
1583 if (mp->hw->max_rates > 1) { in minstrel_ht_get_sample_rate()
1584 seq = mi->sample_seq; in minstrel_ht_get_sample_rate()
1585 mi->sample_seq = (seq + 1) % ARRAY_SIZE(minstrel_sample_seq); in minstrel_ht_get_sample_rate()
1599 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); in minstrel_ht_get_rate()
1600 struct ieee80211_tx_rate *rate = &info->status.rates[0]; in minstrel_ht_get_rate() local
1605 info->flags |= mi->tx_flags; in minstrel_ht_get_rate()
1608 if (mp->fixed_rate_idx != -1) in minstrel_ht_get_rate()
1612 /* Don't use EAPOL frames for sampling on non-mrr hw */ in minstrel_ht_get_rate()
1613 if (mp->hw->max_rates == 1 && in minstrel_ht_get_rate()
1614 (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) in minstrel_ht_get_rate()
1617 if (time_is_after_jiffies(mi->sample_time)) in minstrel_ht_get_rate()
1620 mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL; in minstrel_ht_get_rate()
1629 (sample_idx >= 4) != txrc->short_preamble) in minstrel_ht_get_rate()
1632 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; in minstrel_ht_get_rate()
1633 rate->count = 1; in minstrel_ht_get_rate()
1636 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); in minstrel_ht_get_rate()
1637 rate->idx = mp->cck_rates[idx]; in minstrel_ht_get_rate()
1639 int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]); in minstrel_ht_get_rate()
1640 rate->idx = mp->ofdm_rates[mi->band][idx]; in minstrel_ht_get_rate()
1641 } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { in minstrel_ht_get_rate()
1642 ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx), in minstrel_ht_get_rate()
1643 sample_group->streams); in minstrel_ht_get_rate()
1645 rate->idx = sample_idx + (sample_group->streams - 1) * 8; in minstrel_ht_get_rate()
1648 rate->flags = sample_group->flags; in minstrel_ht_get_rate()
1658 if (sband->band != NL80211_BAND_2GHZ) in minstrel_ht_update_cck()
1661 if (sta->deflink.ht_cap.ht_supported && in minstrel_ht_update_cck()
1662 !ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) in minstrel_ht_update_cck()
1666 if (mp->cck_rates[i] == 0xff || in minstrel_ht_update_cck()
1667 !rate_supported(sta, sband->band, mp->cck_rates[i])) in minstrel_ht_update_cck()
1670 mi->supported[MINSTREL_CCK_GROUP] |= BIT(i); in minstrel_ht_update_cck()
1671 if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) in minstrel_ht_update_cck()
1672 mi->supported[MINSTREL_CCK_GROUP] |= BIT(i + 4); in minstrel_ht_update_cck()
1684 if (sta->deflink.ht_cap.ht_supported) in minstrel_ht_update_ofdm()
1687 rates = mp->ofdm_rates[sband->band]; in minstrel_ht_update_ofdm()
1688 for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) { in minstrel_ht_update_ofdm()
1690 !rate_supported(sta, sband->band, rates[i])) in minstrel_ht_update_ofdm()
1693 mi->supported[MINSTREL_OFDM_GROUP] |= BIT(i); in minstrel_ht_update_ofdm()
1704 struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs; in minstrel_ht_update_caps()
1705 u16 ht_cap = sta->deflink.ht_cap.cap; in minstrel_ht_update_caps()
1706 struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; in minstrel_ht_update_caps()
1717 if (vht_cap->vht_supported) in minstrel_ht_update_caps()
1718 use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); in minstrel_ht_update_caps()
1724 mi->sta = sta; in minstrel_ht_update_caps()
1725 mi->band = sband->band; in minstrel_ht_update_caps()
1726 mi->last_stats_update = jiffies; in minstrel_ht_update_caps()
1728 ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1); in minstrel_ht_update_caps()
1729 mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1); in minstrel_ht_update_caps()
1730 mi->overhead += ack_dur; in minstrel_ht_update_caps()
1731 mi->overhead_rtscts = mi->overhead + 2 * ack_dur; in minstrel_ht_update_caps()
1733 ctl_rate = &sband->bitrates[rate_lowest_index(sband, sta)]; in minstrel_ht_update_caps()
1734 erp = ctl_rate->flags & IEEE80211_RATE_ERP_G; in minstrel_ht_update_caps()
1735 ack_dur = ieee80211_frame_duration(sband->band, 10, in minstrel_ht_update_caps()
1736 ctl_rate->bitrate, erp, 1); in minstrel_ht_update_caps()
1737 mi->overhead_legacy = ack_dur; in minstrel_ht_update_caps()
1738 mi->overhead_legacy_rtscts = mi->overhead_legacy + 2 * ack_dur; in minstrel_ht_update_caps()
1740 mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); in minstrel_ht_update_caps()
1748 stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> in minstrel_ht_update_caps()
1751 ldpc = vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC; in minstrel_ht_update_caps()
1754 mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; in minstrel_ht_update_caps()
1756 mi->tx_flags |= IEEE80211_TX_CTL_LDPC; in minstrel_ht_update_caps()
1758 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { in minstrel_ht_update_caps()
1762 mi->supported[i] = 0; in minstrel_ht_update_caps()
1777 sta->deflink.bandwidth < IEEE80211_STA_RX_BW_40) in minstrel_ht_update_caps()
1783 if (sta->deflink.smps_mode == IEEE80211_SMPS_STATIC && nss > 1) in minstrel_ht_update_caps()
1786 /* HT rate */ in minstrel_ht_update_caps()
1791 mi->supported[i] = mcs->rx_mask[nss - 1]; in minstrel_ht_update_caps()
1795 /* VHT rate */ in minstrel_ht_update_caps()
1796 if (!vht_cap->vht_supported || in minstrel_ht_update_caps()
1802 if (sta->deflink.bandwidth < IEEE80211_STA_RX_BW_80 || in minstrel_ht_update_caps()
1804 !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { in minstrel_ht_update_caps()
1816 mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss, in minstrel_ht_update_caps()
1817 vht_cap->vht_mcs.tx_mcs_map); in minstrel_ht_update_caps()
1821 mi->use_short_preamble = test_sta_flag(sta_info, WLAN_STA_SHORT_PREAMBLE) && in minstrel_ht_update_caps()
1822 sta_info->sdata->vif.bss_conf.use_short_preamble; in minstrel_ht_update_caps()
1827 /* create an initial rate table with the lowest supported rates */ in minstrel_ht_update_caps()
1855 struct ieee80211_hw *hw = mp->hw; in minstrel_ht_alloc_sta()
1860 sband = hw->wiphy->bands[i]; in minstrel_ht_alloc_sta()
1861 if (sband && sband->n_bitrates > max_rates) in minstrel_ht_alloc_sta()
1862 max_rates = sband->n_bitrates; in minstrel_ht_alloc_sta()
1880 for (i = 0; i < sband->n_bitrates; i++) { in minstrel_ht_fill_rate_array()
1881 struct ieee80211_rate *rate = &sband->bitrates[i]; in minstrel_ht_fill_rate_array() local
1883 if ((rate_flags & sband->bitrates[i].flags) != rate_flags) in minstrel_ht_fill_rate_array()
1887 if (rate->bitrate != bitrates[j]) in minstrel_ht_fill_rate_array()
1901 u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); in minstrel_ht_init_cck_rates()
1903 memset(mp->cck_rates, 0xff, sizeof(mp->cck_rates)); in minstrel_ht_init_cck_rates()
1904 sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; in minstrel_ht_init_cck_rates()
1908 BUILD_BUG_ON(ARRAY_SIZE(mp->cck_rates) != ARRAY_SIZE(bitrates)); in minstrel_ht_init_cck_rates()
1909 minstrel_ht_fill_rate_array(mp->cck_rates, sband, in minstrel_ht_init_cck_rates()
1920 u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); in minstrel_ht_init_ofdm_rates()
1922 memset(mp->ofdm_rates[band], 0xff, sizeof(mp->ofdm_rates[band])); in minstrel_ht_init_ofdm_rates()
1923 sband = mp->hw->wiphy->bands[band]; in minstrel_ht_init_ofdm_rates()
1927 BUILD_BUG_ON(ARRAY_SIZE(mp->ofdm_rates[band]) != ARRAY_SIZE(bitrates)); in minstrel_ht_init_ofdm_rates()
1928 minstrel_ht_fill_rate_array(mp->ofdm_rates[band], sband, in minstrel_ht_init_ofdm_rates()
1945 * Just an approximation. Using the per-queue values would complicate in minstrel_ht_alloc()
1947 mp->cw_min = 15; in minstrel_ht_alloc()
1948 mp->cw_max = 1023; in minstrel_ht_alloc()
1951 mp->segment_size = 6000; in minstrel_ht_alloc()
1953 if (hw->max_rate_tries > 0) in minstrel_ht_alloc()
1954 mp->max_retry = hw->max_rate_tries; in minstrel_ht_alloc()
1957 mp->max_retry = 7; in minstrel_ht_alloc()
1959 mp->hw = hw; in minstrel_ht_alloc()
1960 mp->update_interval = HZ / 20; in minstrel_ht_alloc()
1963 for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) in minstrel_ht_alloc()
1975 mp->fixed_rate_idx = (u32) -1; in minstrel_ht_add_debugfs()
1977 &mp->fixed_rate_idx); in minstrel_ht_add_debugfs()
1992 i = MI_RATE_GROUP(mi->max_tp_rate[0]); in minstrel_ht_get_expected_throughput()
1993 j = MI_RATE_IDX(mi->max_tp_rate[0]); in minstrel_ht_get_expected_throughput()
1994 prob = mi->groups[i].rates[j].prob_avg; in minstrel_ht_get_expected_throughput()