Lines Matching +full:rates +full:- +full:mcs

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
17 * 3. Neither the names of the above-listed copyright holders nor the names
86 * in "Bit-rate Selection in Wireless Networks"
87 * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps)
89 * SampleRate chooses the bit-rate it predicts will provide the most
90 * throughput based on estimates of the expected per-packet
91 * transmission time for each bit-rate. SampleRate periodically sends
92 * packets at bit-rates other than the current one to estimate when
93 * another bit-rate will provide better performance. SampleRate
94 * switches to another bit-rate when its estimated per-packet
95 * transmission time becomes smaller than the current bit-rate's.
96 * SampleRate reduces the number of bit-rates it must sample by
98 * currently being used. SampleRate also stops probing at a bit-rate
119 * given rate. For now this ignores SGI/LGI and will assume long-GI.
120 * This only matters for lower rates that can't fill a full 64k A-MPDU.
125 * When selecting a set of rates the rate control code will iterate
163 * MCS rate in the transmit schedule.
165 * Returns -1 if it's a legacy rate or no MRR.
170 * XXX TODO: apply per-node max-ampdu size and driver ampdu size limits too.
176 #define MCS_IDX(ix) (rt->info[ix].dot11Rate) in ath_rate_sample_find_min_pktlength()
177 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_sample_find_min_pktlength()
179 const struct txschedule *sched = &sn->sched[rix0]; in ath_rate_sample_find_min_pktlength()
182 int is_ht40 = (an->an_node.ni_chw == IEEE80211_STA_RX_BW_40); in ath_rate_sample_find_min_pktlength()
186 if (rt->info[rix0].phy != IEEE80211_T_HT) { in ath_rate_sample_find_min_pktlength()
187 return -1; in ath_rate_sample_find_min_pktlength()
190 if (! sc->sc_mrretry) { in ath_rate_sample_find_min_pktlength()
191 return -1; in ath_rate_sample_find_min_pktlength()
194 KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n", in ath_rate_sample_find_min_pktlength()
195 rix0, sched->r0)); in ath_rate_sample_find_min_pktlength()
198 * Update based on sched->r{0,1,2,3} if sched->t{0,1,2,3} in ath_rate_sample_find_min_pktlength()
204 * rates 2 and 3 in the tx schedule are ignored. This is important in ath_rate_sample_find_min_pktlength()
207 * higher rates kinda needs a lower MCS rate in there somewhere. in ath_rate_sample_find_min_pktlength()
221 if (sched->t0 != 0) { in ath_rate_sample_find_min_pktlength()
223 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r0)]); in ath_rate_sample_find_min_pktlength()
225 if (sched->t1 != 0) { in ath_rate_sample_find_min_pktlength()
227 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]); in ath_rate_sample_find_min_pktlength()
229 if (sched->t2 != 0 && (! is_aggr)) { in ath_rate_sample_find_min_pktlength()
231 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]); in ath_rate_sample_find_min_pktlength()
233 if (sched->t3 != 0 && (! is_aggr)) { in ath_rate_sample_find_min_pktlength()
235 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]); in ath_rate_sample_find_min_pktlength()
239 #undef MCS in ath_rate_sample_find_min_pktlength()
278 return NUM_PACKET_SIZE_BINS-1; in size_to_bin()
296 return -1; in dot11rate()
297 return rt->info[rix].phy == IEEE80211_T_HT ? in dot11rate()
298 rt->info[rix].dot11Rate : (rt->info[rix].dot11Rate & IEEE80211_RATE_VAL) / 2; in dot11rate()
306 return rt->info[rix].phy == IEEE80211_T_HT ? "MCS" : "Mb "; in dot11rate_label()
311 * or -1 if all the average_tx_times are 0.
325 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { in pick_best_rate()
329 /* Don't pick a non-HT rate for a HT node */ in pick_best_rate()
330 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) && in pick_best_rate()
331 (rt->info[rix].phy != IEEE80211_T_HT)) { in pick_best_rate()
335 tt = sn->stats[size_bin][rix].average_tx_time; in pick_best_rate()
338 !sn->stats[size_bin][rix].packets_acked)) in pick_best_rate()
342 if (sn->stats[size_bin][rix].total_packets > 0) { in pick_best_rate()
343 pct = sn->stats[size_bin][rix].ewma_pct; in pick_best_rate()
345 pct = -1; /* No percent yet to compare against! */ in pick_best_rate()
348 /* don't use a bit-rate that has been failing */ in pick_best_rate()
349 if (sn->stats[size_bin][rix].successive_failures > 3) in pick_best_rate()
356 * Don't consider best rates that we haven't seen in pick_best_rate()
359 if (an->an_node.ni_flags & IEEE80211_NODE_HT) { in pick_best_rate()
360 if (pct == -1) in pick_best_rate()
363 IEEE80211_NOTE(an->an_node.ni_vap, in pick_best_rate()
365 &an->an_node, in pick_best_rate()
370 rt->info[best_rate_rix].dot11Rate, in pick_best_rate()
371 sn->stats[size_bin][best_rate_rix].total_packets, in pick_best_rate()
374 rt->info[rix].dot11Rate, in pick_best_rate()
375 sn->stats[size_bin][rix].total_packets, in pick_best_rate()
383 * For non-MCS rates, use the current average txtime for in pick_best_rate()
386 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) { in pick_best_rate()
395 * Since 2 and 3 stream rates have slightly higher TX times, in pick_best_rate()
399 if (an->an_node.ni_flags & IEEE80211_NODE_HT) { in pick_best_rate()
408 return (best_rate_tt ? best_rate_rix : -1); in pick_best_rate()
412 * Pick a good "random" bit-rate to sample other than the current one.
418 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) in pick_sample_rate()
419 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) in pick_sample_rate() macro
425 current_rix = sn->current_rix[size_bin]; in pick_sample_rate()
427 /* no successes yet, send at the lowest bit-rate */ in pick_sample_rate()
432 current_tt = sn->stats[size_bin][current_rix].average_tx_time; in pick_sample_rate()
434 rix = sn->last_sample_rix[size_bin]+1; /* next sample rate */ in pick_sample_rate()
435 mask = sn->ratemask &~ ((uint64_t) 1<<current_rix);/* don't sample current rate */ in pick_sample_rate()
439 if (++rix >= rt->rateCount) in pick_sample_rate()
446 * non-MCS rates when speaking to an MCS node. in pick_sample_rate()
447 * However, at least for CCK rates in 2.4GHz mode, in pick_sample_rate()
448 * the non-MCS rates MAY actually provide better in pick_sample_rate()
453 * selected rate is non-MCS, this won't work. in pick_sample_rate()
457 * the selected rates are non-MCS. in pick_sample_rate()
461 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) && in pick_sample_rate()
462 (rt->info[rix].phy != IEEE80211_T_HT)) { in pick_sample_rate()
468 /* this bit-rate is always worse than the current one */ in pick_sample_rate()
469 if (sn->stats[size_bin][rix].perfect_tx_time > current_tt) { in pick_sample_rate()
474 /* rarely sample bit-rates that fail a lot */ in pick_sample_rate()
475 if (sn->stats[size_bin][rix].successive_failures > ssc->max_successive_failures && in pick_sample_rate()
476 ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout) { in pick_sample_rate()
482 * For HT, only sample a few rates on either side of the in pick_sample_rate()
486 * this MCS, but for all spatial streams. in pick_sample_rate()
488 * Otherwise we'll (a) never really sample higher MCS in pick_sample_rate()
489 * rates if we're stuck low, and we'll make weird moves in pick_sample_rate()
492 if (an->an_node.ni_flags & IEEE80211_NODE_HT) { in pick_sample_rate()
495 current_mcs = MCS(current_rix) & 0x7; in pick_sample_rate()
496 rix_mcs = MCS(rix) & 0x7; in pick_sample_rate()
498 if (rix_mcs < (current_mcs - 2) || in pick_sample_rate()
505 /* Don't sample more than 2 rates higher for rates > 11M for non-HT rates */ in pick_sample_rate()
506 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) { in pick_sample_rate()
513 sn->last_sample_rix[size_bin] = rix; in pick_sample_rate()
518 #undef MCS in pick_sample_rate()
524 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) in ath_rate_get_static_rix()
525 #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL) in ath_rate_get_static_rix()
526 #define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS) in ath_rate_get_static_rix() macro
527 const struct ieee80211_txparam *tp = ni->ni_txparms; in ath_rate_get_static_rix()
530 /* Check MCS rates */ in ath_rate_get_static_rix()
531 for (srate = ni->ni_htrates.rs_nrates - 1; srate >= 0; srate--) { in ath_rate_get_static_rix()
532 if (MCS(srate) == tp->ucastrate) in ath_rate_get_static_rix()
533 return sc->sc_rixmap[tp->ucastrate]; in ath_rate_get_static_rix()
536 /* Check legacy rates */ in ath_rate_get_static_rix()
537 for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--) { in ath_rate_get_static_rix()
538 if (RATE(srate) == tp->ucastrate) in ath_rate_get_static_rix()
539 return sc->sc_rixmap[tp->ucastrate]; in ath_rate_get_static_rix()
541 return -1; in ath_rate_get_static_rix()
544 #undef MCS in ath_rate_get_static_rix()
551 const struct ieee80211_txparam *tp = ni->ni_txparms; in ath_rate_update_static_rix()
554 if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { in ath_rate_update_static_rix()
562 sn->static_rix = ath_rate_get_static_rix(sc, ni); in ath_rate_update_static_rix()
564 sn->static_rix = -1; in ath_rate_update_static_rix()
569 * Pick a non-HT rate to begin using.
575 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) in ath_rate_pick_seed_rate_legacy()
576 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) in ath_rate_pick_seed_rate_legacy() macro
578 int rix = -1; in ath_rate_pick_seed_rate_legacy()
579 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_pick_seed_rate_legacy()
584 for (rix = rt->rateCount-1; rix > 0; rix--) { in ath_rate_pick_seed_rate_legacy()
585 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0) in ath_rate_pick_seed_rate_legacy()
588 /* Skip HT rates */ in ath_rate_pick_seed_rate_legacy()
589 if (rt->info[rix].phy == IEEE80211_T_HT) in ath_rate_pick_seed_rate_legacy()
597 sn->stats[size_bin][rix].successive_failures == 0) { in ath_rate_pick_seed_rate_legacy()
603 #undef MCS in ath_rate_pick_seed_rate_legacy()
610 * Don't use any non-HT rates; only consider HT rates.
616 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) in ath_rate_pick_seed_rate_ht()
617 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) in ath_rate_pick_seed_rate_ht() macro
619 int rix = -1, ht_rix = -1; in ath_rate_pick_seed_rate_ht()
620 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_pick_seed_rate_ht()
625 for (rix = rt->rateCount-1; rix > 0; rix--) { in ath_rate_pick_seed_rate_ht()
626 /* Skip rates we can't use */ in ath_rate_pick_seed_rate_ht()
627 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0) in ath_rate_pick_seed_rate_ht()
631 if (rt->info[rix].phy == IEEE80211_T_HT) in ath_rate_pick_seed_rate_ht()
634 /* Skip non-HT rates */ in ath_rate_pick_seed_rate_ht()
635 if (rt->info[rix].phy != IEEE80211_T_HT) in ath_rate_pick_seed_rate_ht()
639 * Pick a medium-speed rate at 1 spatial stream in ath_rate_pick_seed_rate_ht()
641 * Higher rates may fail; we'll try them later. in ath_rate_pick_seed_rate_ht()
643 if (((MCS(rix)& 0x7f) <= 4) && in ath_rate_pick_seed_rate_ht()
644 sn->stats[size_bin][rix].successive_failures == 0) { in ath_rate_pick_seed_rate_ht()
650 * If all the MCS rates have successive failures, rix should be in ath_rate_pick_seed_rate_ht()
651 * > 0; otherwise use the lowest MCS rix (hopefully MCS 0.) in ath_rate_pick_seed_rate_ht()
655 #undef MCS in ath_rate_pick_seed_rate_ht()
665 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) in ath_rate_findrate()
666 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) in ath_rate_findrate() macro
670 struct ieee80211com *ic = &sc->sc_ic; in ath_rate_findrate()
671 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_findrate()
677 ath_rate_update_static_rix(sc, &an->an_node); in ath_rate_findrate()
681 *maxdur = -1; in ath_rate_findrate()
688 if (sn->currates != sc->sc_currates) { in ath_rate_findrate()
689 device_printf(sc->sc_dev, "%s: currates != sc_currates!\n", in ath_rate_findrate()
696 if (sn->static_rix != -1) { in ath_rate_findrate()
697 rix = sn->static_rix; in ath_rate_findrate()
704 sn->static_rix, in ath_rate_findrate()
713 mrr = sc->sc_mrretry; in ath_rate_findrate()
716 if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot)) in ath_rate_findrate()
724 * and size_bin if we're doing 11n rates. in ath_rate_findrate()
730 device_printf(sc->sc_dev, in ath_rate_findrate()
739 average_tx_time = sn->stats[size_bin][best_rix].average_tx_time; in ath_rate_findrate()
746 * rates to sample_rate% of the total transmission time. in ath_rate_findrate()
748 if (sn->sample_tt[size_bin] < in ath_rate_findrate()
750 (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) { in ath_rate_findrate()
752 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, in ath_rate_findrate()
753 &an->an_node, "att %d sample_tt %d size %u " in ath_rate_findrate()
756 sn->sample_tt[size_bin], in ath_rate_findrate()
760 dot11rate(rt, sn->current_rix[size_bin]), in ath_rate_findrate()
761 dot11rate_label(rt, sn->current_rix[size_bin])); in ath_rate_findrate()
762 if (rix != sn->current_rix[size_bin]) { in ath_rate_findrate()
763 sn->current_sample_rix[size_bin] = rix; in ath_rate_findrate()
765 sn->current_sample_rix[size_bin] = -1; in ath_rate_findrate()
767 sn->packets_since_sample[size_bin] = 0; in ath_rate_findrate()
770 if (!sn->packets_sent[size_bin] || best_rix == -1) { in ath_rate_findrate()
773 if (an->an_node.ni_flags & IEEE80211_NODE_HT) in ath_rate_findrate()
779 } else if (sn->packets_sent[size_bin] < 20) { in ath_rate_findrate()
780 /* let the bit-rate switch quickly during the first few packets */ in ath_rate_findrate()
781 IEEE80211_NOTE(an->an_node.ni_vap, in ath_rate_findrate()
782 IEEE80211_MSG_RATECTL, &an->an_node, in ath_rate_findrate()
785 } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) { in ath_rate_findrate()
787 IEEE80211_NOTE(an->an_node.ni_vap, in ath_rate_findrate()
788 IEEE80211_MSG_RATECTL, &an->an_node, in ath_rate_findrate()
790 __func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]); in ath_rate_findrate()
792 } else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) && in ath_rate_findrate()
793 (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) { in ath_rate_findrate()
794 /* the current bit-rate is twice as slow as the best one */ in ath_rate_findrate()
795 IEEE80211_NOTE(an->an_node.ni_vap, in ath_rate_findrate()
796 IEEE80211_MSG_RATECTL, &an->an_node, in ath_rate_findrate()
799 2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time); in ath_rate_findrate()
801 } else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) { in ath_rate_findrate()
802 int cur_rix = sn->current_rix[size_bin]; in ath_rate_findrate()
803 int cur_att = sn->stats[size_bin][cur_rix].average_tx_time; in ath_rate_findrate()
813 MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time); in ath_rate_findrate()
817 IEEE80211_NOTE(an->an_node.ni_vap, in ath_rate_findrate()
818 IEEE80211_MSG_RATECTL, &an->an_node, in ath_rate_findrate()
823 MCS(best_rix), MCS(cur_rix), in ath_rate_findrate()
829 sn->packets_since_sample[size_bin]++; in ath_rate_findrate()
832 if (best_rix != sn->current_rix[size_bin]) { in ath_rate_findrate()
833 IEEE80211_NOTE(an->an_node.ni_vap, in ath_rate_findrate()
835 &an->an_node, in ath_rate_findrate()
836 "%s: size %d switch rate %d %s (%d/%d) EWMA %d -> %d %s (%d/%d) EWMA %d after %d packets mrr %d", in ath_rate_findrate()
839 dot11rate(rt, sn->current_rix[size_bin]), in ath_rate_findrate()
840 dot11rate_label(rt, sn->current_rix[size_bin]), in ath_rate_findrate()
841 sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time, in ath_rate_findrate()
842 sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time, in ath_rate_findrate()
843 sn->stats[size_bin][sn->current_rix[size_bin]].ewma_pct, in ath_rate_findrate()
846 sn->stats[size_bin][best_rix].average_tx_time, in ath_rate_findrate()
847 sn->stats[size_bin][best_rix].perfect_tx_time, in ath_rate_findrate()
848 sn->stats[size_bin][best_rix].ewma_pct, in ath_rate_findrate()
849 sn->packets_since_switch[size_bin], in ath_rate_findrate()
852 sn->packets_since_switch[size_bin] = 0; in ath_rate_findrate()
853 sn->current_rix[size_bin] = best_rix; in ath_rate_findrate()
854 sn->ticks_since_switch[size_bin] = ticks; in ath_rate_findrate()
858 an->an_node.ni_txrate = in ath_rate_findrate()
859 (rt->info[best_rix].phy == IEEE80211_T_HT) ? in ath_rate_findrate()
860 MCS(best_rix) : DOT11RATE(best_rix); in ath_rate_findrate()
862 rix = sn->current_rix[size_bin]; in ath_rate_findrate()
863 sn->packets_since_switch[size_bin]++; in ath_rate_findrate()
865 *try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY; in ath_rate_findrate()
874 if (rix < 0 || rix >= rt->rateCount) { in ath_rate_findrate()
878 rt->rateCount); in ath_rate_findrate()
881 KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix)); in ath_rate_findrate()
884 *txrate = rt->info[rix].rateCode in ath_rate_findrate()
885 | (shortPreamble ? rt->info[rix].shortPreamble : 0); in ath_rate_findrate()
886 sn->packets_sent[size_bin]++; in ath_rate_findrate()
889 #undef MCS in ath_rate_findrate()
894 * Get the TX rates. Don't fiddle with short preamble flags for them;
902 const struct txschedule *sched = &sn->sched[rix0]; in ath_rate_getxtxrates()
904 KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n", in ath_rate_getxtxrates()
905 rix0, sched->r0)); in ath_rate_getxtxrates()
909 rc[0].rix = sched->r0; in ath_rate_getxtxrates()
910 rc[1].rix = sched->r1; in ath_rate_getxtxrates()
911 rc[2].rix = sched->r2; in ath_rate_getxtxrates()
912 rc[3].rix = sched->r3; in ath_rate_getxtxrates()
914 rc[0].tries = sched->t0; in ath_rate_getxtxrates()
915 rc[1].tries = sched->t1; in ath_rate_getxtxrates()
920 rc[2].tries = sched->t2; in ath_rate_getxtxrates()
921 rc[3].tries = sched->t3; in ath_rate_getxtxrates()
930 const struct txschedule *sched = &sn->sched[rix]; in ath_rate_setupxtxdesc()
931 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_setupxtxdesc()
935 rix1 = sched->r1; in ath_rate_setupxtxdesc()
936 s1code = rt->info[rix1].rateCode in ath_rate_setupxtxdesc()
937 | (shortPreamble ? rt->info[rix1].shortPreamble : 0); in ath_rate_setupxtxdesc()
938 rix2 = sched->r2; in ath_rate_setupxtxdesc()
939 s2code = rt->info[rix2].rateCode in ath_rate_setupxtxdesc()
940 | (shortPreamble ? rt->info[rix2].shortPreamble : 0); in ath_rate_setupxtxdesc()
941 rix3 = sched->r3; in ath_rate_setupxtxdesc()
942 s3code = rt->info[rix3].rateCode in ath_rate_setupxtxdesc()
943 | (shortPreamble ? rt->info[rix3].shortPreamble : 0); in ath_rate_setupxtxdesc()
944 ath_hal_setupxtxdesc(sc->sc_ah, ds, in ath_rate_setupxtxdesc()
945 s1code, sched->t1, /* series 1 */ in ath_rate_setupxtxdesc()
946 s2code, sched->t2, /* series 2 */ in ath_rate_setupxtxdesc()
947 s3code, sched->t3); /* series 3 */ in ath_rate_setupxtxdesc()
972 const HAL_RATE_TABLE *rt = sc->sc_currates; in update_stats()
977 int is_ht40 = (an->an_node.ni_chw == IEEE80211_STA_RX_BW_40); in update_stats()
1008 0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40); in update_stats()
1010 if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) { in update_stats()
1012 int avg_tx = sn->stats[size_bin][rix0].average_tx_time; in update_stats()
1013 int packets = sn->stats[size_bin][rix0].total_packets; in update_stats()
1014 sn->stats[size_bin][rix0].average_tx_time = (tt+(avg_tx*packets))/(packets+nframes); in update_stats()
1017 sn->stats[size_bin][rix0].average_tx_time = in update_stats()
1018 ((sn->stats[size_bin][rix0].average_tx_time * ssc->smoothing_rate) + in update_stats()
1019 (tt * (100 - ssc->smoothing_rate))) / 100; in update_stats()
1023 sn->stats[size_bin][rix0].successive_failures += nbad; in update_stats()
1025 sn->stats[size_bin][rix0].packets_acked += (nframes - nbad); in update_stats()
1026 sn->stats[size_bin][rix0].successive_failures = 0; in update_stats()
1028 sn->stats[size_bin][rix0].tries += tries; in update_stats()
1029 sn->stats[size_bin][rix0].last_tx = ticks; in update_stats()
1030 sn->stats[size_bin][rix0].total_packets += nframes; in update_stats()
1037 pct = ((nframes - nbad) * 1000) / nframes; in update_stats()
1039 if (sn->stats[size_bin][rix0].total_packets < in update_stats()
1040 ssc->smoothing_minpackets) { in update_stats()
1042 int a_pct = (sn->stats[size_bin][rix0].packets_acked * 1000) / in update_stats()
1043 (sn->stats[size_bin][rix0].total_packets); in update_stats()
1044 sn->stats[size_bin][rix0].ewma_pct = a_pct; in update_stats()
1047 sn->stats[size_bin][rix0].ewma_pct = in update_stats()
1048 ((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) + in update_stats()
1049 (pct * (100 - ssc->smoothing_rate))) / 100; in update_stats()
1061 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, in update_stats()
1062 &an->an_node, in update_stats()
1068 rix0 == sn->current_sample_rix[size_bin] ? "sample" : "mrr", in update_stats()
1072 sn->stats[size_bin][rix0].average_tx_time, in update_stats()
1073 sn->stats[size_bin][rix0].perfect_tx_time, in update_stats()
1076 if (rix0 == sn->current_sample_rix[size_bin]) { in update_stats()
1077 sn->sample_tt[size_bin] = tt; in update_stats()
1078 sn->current_sample_rix[size_bin] = -1; in update_stats()
1086 device_printf(sc->sc_dev, in badrate()
1096 struct ieee80211com *ic = &sc->sc_ic; in ath_rate_tx_complete()
1099 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_tx_complete()
1100 int status = ts->ts_status; in ath_rate_tx_complete()
1103 final_rix = rt->rateCodeToIndex[ts->ts_rate]; in ath_rate_tx_complete()
1104 short_tries = ts->ts_shortretry; in ath_rate_tx_complete()
1105 long_tries = ts->ts_longretry + 1; in ath_rate_tx_complete()
1108 device_printf(sc->sc_dev, "%s: nframes=0?\n", __func__); in ath_rate_tx_complete()
1122 * The eternal question here is - which size_bin should it go in? in ath_rate_tx_complete()
1125 * Here's the problem - if we use the one that was transmitted, in ath_rate_tx_complete()
1141 device_printf(sc->sc_dev, in ath_rate_tx_complete()
1149 if (sn->ratemask == 0) { in ath_rate_tx_complete()
1150 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, in ath_rate_tx_complete()
1151 &an->an_node, in ath_rate_tx_complete()
1152 "%s: size %d %s rate/try %d/%d no rates yet", in ath_rate_tx_complete()
1159 mrr = sc->sc_mrretry; in ath_rate_tx_complete()
1161 if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot)) in ath_rate_tx_complete()
1164 if (!mrr || ts->ts_finaltsi == 0) { in ath_rate_tx_complete()
1166 device_printf(sc->sc_dev, in ath_rate_tx_complete()
1168 __func__, ts->ts_rate, ts->ts_finaltsi, final_rix); in ath_rate_tx_complete()
1169 badrate(sc, 0, ts->ts_rate, long_tries, status); in ath_rate_tx_complete()
1175 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, in ath_rate_tx_complete()
1176 &an->an_node, "%s: size %d (%d bytes) %s rate/short/long %d %s/%d/%d nframes/nbad [%d/%d]", in ath_rate_tx_complete()
1189 int finalTSIdx = ts->ts_finaltsi; in ath_rate_tx_complete()
1193 * Process intermediate rates that failed. in ath_rate_tx_complete()
1196 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, in ath_rate_tx_complete()
1197 &an->an_node, in ath_rate_tx_complete()
1233 long_tries -= rc[0].tries; in ath_rate_tx_complete()
1242 long_tries -= rc[1].tries; in ath_rate_tx_complete()
1251 long_tries -= rc[2].tries; in ath_rate_tx_complete()
1268 ath_rate_ctl_reset(sc, &an->an_node); in ath_rate_newassoc()
1297 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) in ath_rate_ctl_reset()
1298 #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL) in ath_rate_ctl_reset()
1299 #define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS) in ath_rate_ctl_reset() macro
1302 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_ctl_reset()
1305 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); in ath_rate_ctl_reset()
1307 KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2, in ath_rate_ctl_reset()
1308 ("curmode %u", sc->sc_curmode)); in ath_rate_ctl_reset()
1310 sn->sched = mrr_schedules[sc->sc_curmode]; in ath_rate_ctl_reset()
1311 KASSERT(sn->sched != NULL, in ath_rate_ctl_reset()
1312 ("no mrr schedule for mode %u", sc->sc_curmode)); in ath_rate_ctl_reset()
1314 sn->static_rix = -1; in ath_rate_ctl_reset()
1317 sn->currates = sc->sc_currates; in ath_rate_ctl_reset()
1320 * Construct a bitmask of usable rates. This has all in ath_rate_ctl_reset()
1321 * negotiated rates minus those marked by the hal as in ath_rate_ctl_reset()
1324 sn->ratemask = 0; in ath_rate_ctl_reset()
1325 /* MCS rates */ in ath_rate_ctl_reset()
1326 if (ni->ni_flags & IEEE80211_NODE_HT) { in ath_rate_ctl_reset()
1327 for (x = 0; x < ni->ni_htrates.rs_nrates; x++) { in ath_rate_ctl_reset()
1328 rix = sc->sc_rixmap[MCS(x)]; in ath_rate_ctl_reset()
1331 /* skip rates marked broken by hal */ in ath_rate_ctl_reset()
1332 if (!rt->info[rix].valid) in ath_rate_ctl_reset()
1335 ("mcs %u has rix %d", MCS(x), rix)); in ath_rate_ctl_reset()
1336 sn->ratemask |= (uint64_t) 1<<rix; in ath_rate_ctl_reset()
1340 /* Legacy rates */ in ath_rate_ctl_reset()
1341 for (x = 0; x < ni->ni_rates.rs_nrates; x++) { in ath_rate_ctl_reset()
1342 rix = sc->sc_rixmap[RATE(x)]; in ath_rate_ctl_reset()
1345 /* skip rates marked broken by hal */ in ath_rate_ctl_reset()
1346 if (!rt->info[rix].valid) in ath_rate_ctl_reset()
1350 sn->ratemask |= (uint64_t) 1<<rix; in ath_rate_ctl_reset()
1353 if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) { in ath_rate_ctl_reset()
1356 ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt", in ath_rate_ctl_reset()
1357 ni->ni_macaddr, ":", __func__); in ath_rate_ctl_reset()
1358 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { in ath_rate_ctl_reset()
1363 (ni->ni_chw == IEEE80211_STA_RX_BW_40))); in ath_rate_ctl_reset()
1372 sn->packets_sent[y] = 0; in ath_rate_ctl_reset()
1373 sn->current_sample_rix[y] = -1; in ath_rate_ctl_reset()
1374 sn->last_sample_rix[y] = 0; in ath_rate_ctl_reset()
1376 sn->current_rix[y] = ffs(sn->ratemask)-1; in ath_rate_ctl_reset()
1382 for (rix = 0, mask = sn->ratemask; mask != 0; rix++, mask >>= 1) { in ath_rate_ctl_reset()
1385 sn->stats[y][rix].successive_failures = 0; in ath_rate_ctl_reset()
1386 sn->stats[y][rix].tries = 0; in ath_rate_ctl_reset()
1387 sn->stats[y][rix].total_packets = 0; in ath_rate_ctl_reset()
1388 sn->stats[y][rix].packets_acked = 0; in ath_rate_ctl_reset()
1389 sn->stats[y][rix].last_tx = 0; in ath_rate_ctl_reset()
1390 sn->stats[y][rix].ewma_pct = 0; in ath_rate_ctl_reset()
1392 sn->stats[y][rix].perfect_tx_time = in ath_rate_ctl_reset()
1394 (ni->ni_chw == IEEE80211_STA_RX_BW_40)); in ath_rate_ctl_reset()
1395 sn->stats[y][rix].average_tx_time = in ath_rate_ctl_reset()
1396 sn->stats[y][rix].perfect_tx_time; in ath_rate_ctl_reset()
1400 /* XXX 0, num_rates-1 are wrong */ in ath_rate_ctl_reset()
1401 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in ath_rate_ctl_reset()
1402 "%s: %d rates %d%sMbps (%dus)- %d%sMbps (%dus)", __func__, in ath_rate_ctl_reset()
1403 sn->num_rates, in ath_rate_ctl_reset()
1405 sn->stats[1][0].perfect_tx_time, in ath_rate_ctl_reset()
1406 DOT11RATE(sn->num_rates-1)/2, DOT11RATE(sn->num_rates-1) % 1 ? ".5" : "", in ath_rate_ctl_reset()
1407 sn->stats[1][sn->num_rates-1].perfect_tx_time in ath_rate_ctl_reset()
1410 /* set the visible bit-rate */ in ath_rate_ctl_reset()
1411 if (sn->static_rix != -1) in ath_rate_ctl_reset()
1412 ni->ni_txrate = DOT11RATE(sn->static_rix); in ath_rate_ctl_reset()
1414 ni->ni_txrate = RATE(0); in ath_rate_ctl_reset()
1426 * to 802.11 rates, or the userland output won't make much sense
1434 const HAL_RATE_TABLE *rt = sc->sc_currates; in ath_rate_fetch_node_stats()
1447 if (rs->len < in ath_rate_fetch_node_stats()
1452 device_printf(sc->sc_dev, "%s: len=%d, too short\n", in ath_rate_fetch_node_stats()
1454 rs->len); in ath_rate_fetch_node_stats()
1471 tv->nentries = rt->rateCount; in ath_rate_fetch_node_stats()
1472 for (y = 0; y < rt->rateCount; y++) { in ath_rate_fetch_node_stats()
1473 tv->ratecode[y] = rt->info[y].dot11Rate & IEEE80211_RATE_VAL; in ath_rate_fetch_node_stats()
1474 if (rt->info[y].phy == IEEE80211_T_HT) in ath_rate_fetch_node_stats()
1475 tv->ratecode[y] |= IEEE80211_RATE_MCS; in ath_rate_fetch_node_stats()
1480 * First TLV - rate code mapping in ath_rate_fetch_node_stats()
1484 error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv)); in ath_rate_fetch_node_stats()
1488 error = copyout(tv, rs->buf + o, sizeof(struct ath_rateioctl_rt)); in ath_rate_fetch_node_stats()
1494 * Second TLV - sample node statistics in ath_rate_fetch_node_stats()
1498 error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv)); in ath_rate_fetch_node_stats()
1506 error = copyout(sn, rs->buf + o, sizeof(struct sample_node)); in ath_rate_fetch_node_stats()
1520 const HAL_RATE_TABLE *rt = sc->sc_currates; in sample_stats()
1526 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni), in sample_stats()
1527 dot11rate(rt, sn->static_rix), in sample_stats()
1528 dot11rate_label(rt, sn->static_rix), in sample_stats()
1529 (uintmax_t)sn->ratemask); in sample_stats()
1532 bin_to_size(y), sn->current_rix[y], in sample_stats()
1533 dot11rate(rt, sn->current_rix[y]), in sample_stats()
1534 dot11rate_label(rt, sn->current_rix[y]), in sample_stats()
1535 sn->packets_since_switch[y], sn->ticks_since_switch[y]); in sample_stats()
1538 dot11rate(rt, sn->last_sample_rix[y]), in sample_stats()
1539 dot11rate_label(rt, sn->last_sample_rix[y]), in sample_stats()
1540 dot11rate(rt, sn->current_sample_rix[y]), in sample_stats()
1541 dot11rate_label(rt, sn->current_sample_rix[y]), in sample_stats()
1542 sn->packets_sent[y]); in sample_stats()
1544 bin_to_size(y), sn->packets_since_sample[y], in sample_stats()
1545 sn->sample_tt[y]); in sample_stats()
1547 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { in sample_stats()
1551 if (sn->stats[y][rix].total_packets == 0) in sample_stats()
1553 printf("[%2u %s:%4u] %8ju:%-8ju (%3d%%) (EWMA %3d.%1d%%) T %8ju F %4d avg %5u last %u\n", in sample_stats()
1556 (uintmax_t) sn->stats[y][rix].total_packets, in sample_stats()
1557 (uintmax_t) sn->stats[y][rix].packets_acked, in sample_stats()
1558 (int) ((sn->stats[y][rix].packets_acked * 100ULL) / in sample_stats()
1559 sn->stats[y][rix].total_packets), in sample_stats()
1560 sn->stats[y][rix].ewma_pct / 10, in sample_stats()
1561 sn->stats[y][rix].ewma_pct % 10, in sample_stats()
1562 (uintmax_t) sn->stats[y][rix].tries, in sample_stats()
1563 sn->stats[y][rix].successive_failures, in sample_stats()
1564 sn->stats[y][rix].average_tx_time, in sample_stats()
1565 ticks - sn->stats[y][rix].last_tx); in sample_stats()
1574 struct ieee80211com *ic = &sc->sc_ic; in ath_rate_sysctl_stats()
1579 if (error || !req->newptr) in ath_rate_sysctl_stats()
1581 ieee80211_iterate_nodes(&ic->ic_sta, sample_stats, sc); in ath_rate_sysctl_stats()
1591 rate = ssc->smoothing_rate; in ath_rate_sysctl_smoothing_rate()
1593 if (error || !req->newptr) in ath_rate_sysctl_smoothing_rate()
1597 ssc->smoothing_rate = rate; in ath_rate_sysctl_smoothing_rate()
1598 ssc->smoothing_minpackets = 100 / (100 - rate); in ath_rate_sysctl_smoothing_rate()
1608 rate = ssc->sample_rate; in ath_rate_sysctl_sample_rate()
1610 if (error || !req->newptr) in ath_rate_sysctl_sample_rate()
1614 ssc->sample_rate = rate; in ath_rate_sysctl_sample_rate()
1621 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); in ath_rate_sysctlattach()
1622 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); in ath_rate_sysctlattach()
1631 "sample: percent air time devoted to sampling new rates (%%)"); in ath_rate_sysctlattach()
1646 ssc->arc.arc_space = sizeof(struct sample_node); in ath_rate_attach()
1647 ssc->smoothing_rate = 75; /* ewma percentage ([0..99]) */ in ath_rate_attach()
1648 ssc->smoothing_minpackets = 100 / (100 - ssc->smoothing_rate); in ath_rate_attach()
1649 ssc->sample_rate = 10; /* %time to try diff tx rates */ in ath_rate_attach()
1650 ssc->max_successive_failures = 3; /* threshold for rate sampling*/ in ath_rate_attach()
1651 ssc->stale_failure_timeout = 10 * hz; /* 10 seconds */ in ath_rate_attach()
1652 ssc->min_switch = hz; /* 1 second */ in ath_rate_attach()
1654 return &ssc->arc; in ath_rate_attach()