Lines Matching +full:ssc +full:- +full:mode
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.
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)
177 const HAL_RATE_TABLE *rt = sc->sc_currates;
179 const struct txschedule *sched = &sn->sched[rix0];
182 int is_ht40 = (an->an_node.ni_chw == IEEE80211_STA_RX_BW_40);
186 if (rt->info[rix0].phy != IEEE80211_T_HT) {
187 return -1;
190 if (! sc->sc_mrretry) {
191 return -1;
194 KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
195 rix0, sched->r0));
198 * Update based on sched->r{0,1,2,3} if sched->t{0,1,2,3}
221 if (sched->t0 != 0) {
223 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r0)]);
225 if (sched->t1 != 0) {
227 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]);
229 if (sched->t2 != 0 && (! is_aggr)) {
231 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]);
233 if (sched->t3 != 0 && (! is_aggr)) {
235 ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]);
278 return NUM_PACKET_SIZE_BINS-1;
296 return -1;
297 return rt->info[rix].phy == IEEE80211_T_HT ?
298 rt->info[rix].dot11Rate : (rt->info[rix].dot11Rate & IEEE80211_RATE_VAL) / 2;
306 return rt->info[rix].phy == IEEE80211_T_HT ? "MCS" : "Mb ";
311 * or -1 if all the average_tx_times are 0.
325 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
329 /* Don't pick a non-HT rate for a HT node */
330 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
331 (rt->info[rix].phy != IEEE80211_T_HT)) {
335 tt = sn->stats[size_bin][rix].average_tx_time;
338 !sn->stats[size_bin][rix].packets_acked))
342 if (sn->stats[size_bin][rix].total_packets > 0) {
343 pct = sn->stats[size_bin][rix].ewma_pct;
345 pct = -1; /* No percent yet to compare against! */
348 /* don't use a bit-rate that has been failing */
349 if (sn->stats[size_bin][rix].successive_failures > 3)
359 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
360 if (pct == -1)
363 IEEE80211_NOTE(an->an_node.ni_vap,
365 &an->an_node,
370 rt->info[best_rate_rix].dot11Rate,
371 sn->stats[size_bin][best_rate_rix].total_packets,
374 rt->info[rix].dot11Rate,
375 sn->stats[size_bin][rix].total_packets,
383 * For non-MCS rates, use the current average txtime for
386 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
399 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
408 return (best_rate_tt ? best_rate_rix : -1);
412 * Pick a good "random" bit-rate to sample other than the current one.
415 pick_sample_rate(struct sample_softc *ssc , struct ath_node *an,
418 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
419 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
425 current_rix = sn->current_rix[size_bin];
427 /* no successes yet, send at the lowest bit-rate */
432 current_tt = sn->stats[size_bin][current_rix].average_tx_time;
434 rix = sn->last_sample_rix[size_bin]+1; /* next sample rate */
435 mask = sn->ratemask &~ ((uint64_t) 1<<current_rix);/* don't sample current rate */
439 if (++rix >= rt->rateCount)
446 * non-MCS rates when speaking to an MCS node.
447 * However, at least for CCK rates in 2.4GHz mode,
448 * the non-MCS rates MAY actually provide better
453 * selected rate is non-MCS, this won't work.
457 * the selected rates are non-MCS.
461 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
462 (rt->info[rix].phy != IEEE80211_T_HT)) {
468 /* this bit-rate is always worse than the current one */
469 if (sn->stats[size_bin][rix].perfect_tx_time > current_tt) {
474 /* rarely sample bit-rates that fail a lot */
475 if (sn->stats[size_bin][rix].successive_failures > ssc->max_successive_failures &&
476 ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout) {
492 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
498 if (rix_mcs < (current_mcs - 2) ||
505 /* Don't sample more than 2 rates higher for rates > 11M for non-HT rates */
506 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
513 sn->last_sample_rix[size_bin] = rix;
524 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
525 #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
526 #define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
527 const struct ieee80211_txparam *tp = ni->ni_txparms;
531 for (srate = ni->ni_htrates.rs_nrates - 1; srate >= 0; srate--) {
532 if (MCS(srate) == tp->ucastrate)
533 return sc->sc_rixmap[tp->ucastrate];
537 for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--) {
538 if (RATE(srate) == tp->ucastrate)
539 return sc->sc_rixmap[tp->ucastrate];
541 return -1;
551 const struct ieee80211_txparam *tp = ni->ni_txparms;
554 if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
562 sn->static_rix = ath_rate_get_static_rix(sc, ni);
564 sn->static_rix = -1;
569 * Pick a non-HT rate to begin using.
575 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
576 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
578 int rix = -1;
579 const HAL_RATE_TABLE *rt = sc->sc_currates;
584 for (rix = rt->rateCount-1; rix > 0; rix--) {
585 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
589 if (rt->info[rix].phy == IEEE80211_T_HT)
597 sn->stats[size_bin][rix].successive_failures == 0) {
610 * Don't use any non-HT rates; only consider HT rates.
616 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
617 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
619 int rix = -1, ht_rix = -1;
620 const HAL_RATE_TABLE *rt = sc->sc_currates;
625 for (rix = rt->rateCount-1; rix > 0; rix--) {
627 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
631 if (rt->info[rix].phy == IEEE80211_T_HT)
634 /* Skip non-HT rates */
635 if (rt->info[rix].phy != IEEE80211_T_HT)
639 * Pick a medium-speed rate at 1 spatial stream
644 sn->stats[size_bin][rix].successive_failures == 0) {
665 #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
666 #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
669 struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
670 struct ieee80211com *ic = &sc->sc_ic;
671 const HAL_RATE_TABLE *rt = sc->sc_currates;
677 ath_rate_update_static_rix(sc, &an->an_node);
681 *maxdur = -1;
688 if (sn->currates != sc->sc_currates) {
689 device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",
696 if (sn->static_rix != -1) {
697 rix = sn->static_rix;
704 sn->static_rix,
713 mrr = sc->sc_mrretry;
716 if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
730 device_printf(sc->sc_dev,
739 average_tx_time = sn->stats[size_bin][best_rix].average_tx_time;
748 if (sn->sample_tt[size_bin] <
750 (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) {
751 rix = pick_sample_rate(ssc, an, rt, size_bin);
752 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
753 &an->an_node, "att %d sample_tt %d size %u "
756 sn->sample_tt[size_bin],
760 dot11rate(rt, sn->current_rix[size_bin]),
761 dot11rate_label(rt, sn->current_rix[size_bin]));
762 if (rix != sn->current_rix[size_bin]) {
763 sn->current_sample_rix[size_bin] = rix;
765 sn->current_sample_rix[size_bin] = -1;
767 sn->packets_since_sample[size_bin] = 0;
770 if (!sn->packets_sent[size_bin] || best_rix == -1) {
773 if (an->an_node.ni_flags & IEEE80211_NODE_HT)
779 } else if (sn->packets_sent[size_bin] < 20) {
780 /* let the bit-rate switch quickly during the first few packets */
781 IEEE80211_NOTE(an->an_node.ni_vap,
782 IEEE80211_MSG_RATECTL, &an->an_node,
785 } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) {
787 IEEE80211_NOTE(an->an_node.ni_vap,
788 IEEE80211_MSG_RATECTL, &an->an_node,
790 __func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]);
792 } else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) &&
793 (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) {
794 /* the current bit-rate is twice as slow as the best one */
795 IEEE80211_NOTE(an->an_node.ni_vap,
796 IEEE80211_MSG_RATECTL, &an->an_node,
799 2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time);
801 } else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) {
802 int cur_rix = sn->current_rix[size_bin];
803 int cur_att = sn->stats[size_bin][cur_rix].average_tx_time;
817 IEEE80211_NOTE(an->an_node.ni_vap,
818 IEEE80211_MSG_RATECTL, &an->an_node,
829 sn->packets_since_sample[size_bin]++;
832 if (best_rix != sn->current_rix[size_bin]) {
833 IEEE80211_NOTE(an->an_node.ni_vap,
835 &an->an_node,
836 "%s: size %d switch rate %d %s (%d/%d) EWMA %d -> %d %s (%d/%d) EWMA %d after %d packets mrr %d",
839 dot11rate(rt, sn->current_rix[size_bin]),
840 dot11rate_label(rt, sn->current_rix[size_bin]),
841 sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time,
842 sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time,
843 sn->stats[size_bin][sn->current_rix[size_bin]].ewma_pct,
846 sn->stats[size_bin][best_rix].average_tx_time,
847 sn->stats[size_bin][best_rix].perfect_tx_time,
848 sn->stats[size_bin][best_rix].ewma_pct,
849 sn->packets_since_switch[size_bin],
852 sn->packets_since_switch[size_bin] = 0;
853 sn->current_rix[size_bin] = best_rix;
854 sn->ticks_since_switch[size_bin] = ticks;
858 an->an_node.ni_txrate =
859 (rt->info[best_rix].phy == IEEE80211_T_HT) ?
862 rix = sn->current_rix[size_bin];
863 sn->packets_since_switch[size_bin]++;
865 *try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY;
874 if (rix < 0 || rix >= rt->rateCount) {
878 rt->rateCount);
881 KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix));
884 *txrate = rt->info[rix].rateCode
885 | (shortPreamble ? rt->info[rix].shortPreamble : 0);
886 sn->packets_sent[size_bin]++;
902 const struct txschedule *sched = &sn->sched[rix0];
904 KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
905 rix0, sched->r0));
909 rc[0].rix = sched->r0;
910 rc[1].rix = sched->r1;
911 rc[2].rix = sched->r2;
912 rc[3].rix = sched->r3;
914 rc[0].tries = sched->t0;
915 rc[1].tries = sched->t1;
920 rc[2].tries = sched->t2;
921 rc[3].tries = sched->t3;
930 const struct txschedule *sched = &sn->sched[rix];
931 const HAL_RATE_TABLE *rt = sc->sc_currates;
935 rix1 = sched->r1;
936 s1code = rt->info[rix1].rateCode
937 | (shortPreamble ? rt->info[rix1].shortPreamble : 0);
938 rix2 = sched->r2;
939 s2code = rt->info[rix2].rateCode
940 | (shortPreamble ? rt->info[rix2].shortPreamble : 0);
941 rix3 = sched->r3;
942 s3code = rt->info[rix3].rateCode
943 | (shortPreamble ? rt->info[rix3].shortPreamble : 0);
944 ath_hal_setupxtxdesc(sc->sc_ah, ds,
945 s1code, sched->t1, /* series 1 */
946 s2code, sched->t2, /* series 2 */
947 s3code, sched->t3); /* series 3 */
970 struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
972 const HAL_RATE_TABLE *rt = sc->sc_currates;
977 int is_ht40 = (an->an_node.ni_chw == IEEE80211_STA_RX_BW_40);
1008 0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40);
1010 if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) {
1012 int avg_tx = sn->stats[size_bin][rix0].average_tx_time;
1013 int packets = sn->stats[size_bin][rix0].total_packets;
1014 sn->stats[size_bin][rix0].average_tx_time = (tt+(avg_tx*packets))/(packets+nframes);
1017 sn->stats[size_bin][rix0].average_tx_time =
1018 ((sn->stats[size_bin][rix0].average_tx_time * ssc->smoothing_rate) +
1019 (tt * (100 - ssc->smoothing_rate))) / 100;
1023 sn->stats[size_bin][rix0].successive_failures += nbad;
1025 sn->stats[size_bin][rix0].packets_acked += (nframes - nbad);
1026 sn->stats[size_bin][rix0].successive_failures = 0;
1028 sn->stats[size_bin][rix0].tries += tries;
1029 sn->stats[size_bin][rix0].last_tx = ticks;
1030 sn->stats[size_bin][rix0].total_packets += nframes;
1037 pct = ((nframes - nbad) * 1000) / nframes;
1039 if (sn->stats[size_bin][rix0].total_packets <
1040 ssc->smoothing_minpackets) {
1042 int a_pct = (sn->stats[size_bin][rix0].packets_acked * 1000) /
1043 (sn->stats[size_bin][rix0].total_packets);
1044 sn->stats[size_bin][rix0].ewma_pct = a_pct;
1047 sn->stats[size_bin][rix0].ewma_pct =
1048 ((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) +
1049 (pct * (100 - ssc->smoothing_rate))) / 100;
1061 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1062 &an->an_node,
1068 rix0 == sn->current_sample_rix[size_bin] ? "sample" : "mrr",
1072 sn->stats[size_bin][rix0].average_tx_time,
1073 sn->stats[size_bin][rix0].perfect_tx_time,
1076 if (rix0 == sn->current_sample_rix[size_bin]) {
1077 sn->sample_tt[size_bin] = tt;
1078 sn->current_sample_rix[size_bin] = -1;
1086 device_printf(sc->sc_dev,
1096 struct ieee80211com *ic = &sc->sc_ic;
1099 const HAL_RATE_TABLE *rt = sc->sc_currates;
1100 int status = ts->ts_status;
1103 final_rix = rt->rateCodeToIndex[ts->ts_rate];
1104 short_tries = ts->ts_shortretry;
1105 long_tries = ts->ts_longretry + 1;
1108 device_printf(sc->sc_dev, "%s: nframes=0?\n", __func__);
1122 * The eternal question here is - which size_bin should it go in?
1125 * Here's the problem - if we use the one that was transmitted,
1141 device_printf(sc->sc_dev,
1149 if (sn->ratemask == 0) {
1150 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1151 &an->an_node,
1159 mrr = sc->sc_mrretry;
1161 if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
1164 if (!mrr || ts->ts_finaltsi == 0) {
1166 device_printf(sc->sc_dev,
1168 __func__, ts->ts_rate, ts->ts_finaltsi, final_rix);
1169 badrate(sc, 0, ts->ts_rate, long_tries, status);
1175 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1176 &an->an_node, "%s: size %d (%d bytes) %s rate/short/long %d %s/%d/%d nframes/nbad [%d/%d]",
1189 int finalTSIdx = ts->ts_finaltsi;
1196 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
1197 &an->an_node,
1233 long_tries -= rc[0].tries;
1242 long_tries -= rc[1].tries;
1251 long_tries -= rc[2].tries;
1268 ath_rate_ctl_reset(sc, &an->an_node);
1297 #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
1298 #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
1299 #define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
1302 const HAL_RATE_TABLE *rt = sc->sc_currates;
1305 KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
1307 KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2,
1308 ("curmode %u", sc->sc_curmode));
1310 sn->sched = mrr_schedules[sc->sc_curmode];
1311 KASSERT(sn->sched != NULL,
1312 ("no mrr schedule for mode %u", sc->sc_curmode));
1314 sn->static_rix = -1;
1317 sn->currates = sc->sc_currates;
1324 sn->ratemask = 0;
1326 if (ni->ni_flags & IEEE80211_NODE_HT) {
1327 for (x = 0; x < ni->ni_htrates.rs_nrates; x++) {
1328 rix = sc->sc_rixmap[MCS(x)];
1332 if (!rt->info[rix].valid)
1336 sn->ratemask |= (uint64_t) 1<<rix;
1341 for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
1342 rix = sc->sc_rixmap[RATE(x)];
1346 if (!rt->info[rix].valid)
1350 sn->ratemask |= (uint64_t) 1<<rix;
1353 if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) {
1356 ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt",
1357 ni->ni_macaddr, ":", __func__);
1358 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
1363 (ni->ni_chw == IEEE80211_STA_RX_BW_40)));
1372 sn->packets_sent[y] = 0;
1373 sn->current_sample_rix[y] = -1;
1374 sn->last_sample_rix[y] = 0;
1376 sn->current_rix[y] = ffs(sn->ratemask)-1;
1382 for (rix = 0, mask = sn->ratemask; mask != 0; rix++, mask >>= 1) {
1385 sn->stats[y][rix].successive_failures = 0;
1386 sn->stats[y][rix].tries = 0;
1387 sn->stats[y][rix].total_packets = 0;
1388 sn->stats[y][rix].packets_acked = 0;
1389 sn->stats[y][rix].last_tx = 0;
1390 sn->stats[y][rix].ewma_pct = 0;
1392 sn->stats[y][rix].perfect_tx_time =
1394 (ni->ni_chw == IEEE80211_STA_RX_BW_40));
1395 sn->stats[y][rix].average_tx_time =
1396 sn->stats[y][rix].perfect_tx_time;
1400 /* XXX 0, num_rates-1 are wrong */
1401 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
1402 "%s: %d rates %d%sMbps (%dus)- %d%sMbps (%dus)", __func__,
1403 sn->num_rates,
1405 sn->stats[1][0].perfect_tx_time,
1406 DOT11RATE(sn->num_rates-1)/2, DOT11RATE(sn->num_rates-1) % 1 ? ".5" : "",
1407 sn->stats[1][sn->num_rates-1].perfect_tx_time
1410 /* set the visible bit-rate */
1411 if (sn->static_rix != -1)
1412 ni->ni_txrate = DOT11RATE(sn->static_rix);
1414 ni->ni_txrate = RATE(0);
1434 const HAL_RATE_TABLE *rt = sc->sc_currates;
1447 if (rs->len <
1452 device_printf(sc->sc_dev, "%s: len=%d, too short\n",
1454 rs->len);
1471 tv->nentries = rt->rateCount;
1472 for (y = 0; y < rt->rateCount; y++) {
1473 tv->ratecode[y] = rt->info[y].dot11Rate & IEEE80211_RATE_VAL;
1474 if (rt->info[y].phy == IEEE80211_T_HT)
1475 tv->ratecode[y] |= IEEE80211_RATE_MCS;
1480 * First TLV - rate code mapping
1484 error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
1488 error = copyout(tv, rs->buf + o, sizeof(struct ath_rateioctl_rt));
1494 * Second TLV - sample node statistics
1498 error = copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
1506 error = copyout(sn, rs->buf + o, sizeof(struct sample_node));
1520 const HAL_RATE_TABLE *rt = sc->sc_currates;
1526 ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni),
1527 dot11rate(rt, sn->static_rix),
1528 dot11rate_label(rt, sn->static_rix),
1529 (uintmax_t)sn->ratemask);
1532 bin_to_size(y), sn->current_rix[y],
1533 dot11rate(rt, sn->current_rix[y]),
1534 dot11rate_label(rt, sn->current_rix[y]),
1535 sn->packets_since_switch[y], sn->ticks_since_switch[y]);
1538 dot11rate(rt, sn->last_sample_rix[y]),
1539 dot11rate_label(rt, sn->last_sample_rix[y]),
1540 dot11rate(rt, sn->current_sample_rix[y]),
1541 dot11rate_label(rt, sn->current_sample_rix[y]),
1542 sn->packets_sent[y]);
1544 bin_to_size(y), sn->packets_since_sample[y],
1545 sn->sample_tt[y]);
1547 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
1551 if (sn->stats[y][rix].total_packets == 0)
1553 printf("[%2u %s:%4u] %8ju:%-8ju (%3d%%) (EWMA %3d.%1d%%) T %8ju F %4d avg %5u last %u\n",
1556 (uintmax_t) sn->stats[y][rix].total_packets,
1557 (uintmax_t) sn->stats[y][rix].packets_acked,
1558 (int) ((sn->stats[y][rix].packets_acked * 100ULL) /
1559 sn->stats[y][rix].total_packets),
1560 sn->stats[y][rix].ewma_pct / 10,
1561 sn->stats[y][rix].ewma_pct % 10,
1562 (uintmax_t) sn->stats[y][rix].tries,
1563 sn->stats[y][rix].successive_failures,
1564 sn->stats[y][rix].average_tx_time,
1565 ticks - sn->stats[y][rix].last_tx);
1574 struct ieee80211com *ic = &sc->sc_ic;
1579 if (error || !req->newptr)
1581 ieee80211_iterate_nodes(&ic->ic_sta, sample_stats, sc);
1588 struct sample_softc *ssc = arg1;
1591 rate = ssc->smoothing_rate;
1593 if (error || !req->newptr)
1597 ssc->smoothing_rate = rate;
1598 ssc->smoothing_minpackets = 100 / (100 - rate);
1605 struct sample_softc *ssc = arg1;
1608 rate = ssc->sample_rate;
1610 if (error || !req->newptr)
1614 ssc->sample_rate = rate;
1619 ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *ssc)
1621 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
1622 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
1626 ssc, 0, ath_rate_sysctl_smoothing_rate, "I",
1630 ssc, 0, ath_rate_sysctl_sample_rate, "I",
1641 struct sample_softc *ssc;
1643 ssc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
1644 if (ssc == NULL)
1646 ssc->arc.arc_space = sizeof(struct sample_node);
1647 ssc->smoothing_rate = 75; /* ewma percentage ([0..99]) */
1648 ssc->smoothing_minpackets = 100 / (100 - ssc->smoothing_rate);
1649 ssc->sample_rate = 10; /* %time to try diff tx rates */
1650 ssc->max_successive_failures = 3; /* threshold for rate sampling*/
1651 ssc->stale_failure_timeout = 10 * hz; /* 10 seconds */
1652 ssc->min_switch = hz; /* 1 second */
1653 ath_rate_sysctlattach(sc, ssc);
1654 return &ssc->arc;
1660 struct sample_softc *ssc = (struct sample_softc *) arc;
1662 free(ssc, M_DEVBUF);