Lines Matching +full:rates +full:- +full:mcs
3 /*-
22 /*-
27 * INRIA Sophia - Projet Planete
28 * http://www-sop.inria.fr/rapports/sophia/RR-5208.html
57 ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
59 ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
61 ((amn)->amn_txcnt > 10)
103 struct ieee80211_amrr *amrr = vap->iv_rs; in amrr_setinterval()
110 amrr->amrr_interval = msecs_to_ticks(msecs); in amrr_setinterval()
118 KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__)); in amrr_init()
121 amrr = vap->iv_rs = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr), in amrr_init()
124 if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n"); in amrr_init()
127 amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD; in amrr_init()
128 amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD; in amrr_init()
130 amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); in amrr_init()
137 IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL); in amrr_deinit()
138 vap->iv_rs = NULL; /* guard */ in amrr_deinit()
139 nrefs--; /* XXX locking */ in amrr_deinit()
145 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_node_init_vht()
147 /* Default to VHT NSS 1 MCS 2; should be reliable! */ in amrr_node_init_vht()
148 amn->amn_vht_mcs = 2; in amrr_node_init_vht()
149 amn->amn_vht_nss = 1; in amrr_node_init_vht()
150 ieee80211_node_set_txrate_vht_rate(ni, amn->amn_vht_nss, in amrr_node_init_vht()
151 amn->amn_vht_mcs); in amrr_node_init_vht()
153 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_node_init_vht()
154 "AMRR: VHT: initial rate NSS %d MCS %d", in amrr_node_init_vht()
155 amn->amn_vht_nss, in amrr_node_init_vht()
156 amn->amn_vht_mcs); in amrr_node_init_vht()
163 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_node_init_ht()
166 rs = (struct ieee80211_rateset *) &ni->ni_htrates; in amrr_node_init_ht()
167 /* Initial rate - lowest */ in amrr_node_init_ht()
168 rate = rs->rs_rates[0]; in amrr_node_init_ht()
171 for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0; in amrr_node_init_ht()
172 amn->amn_rix--) { in amrr_node_init_ht()
173 /* 11n - stop at MCS4 */ in amrr_node_init_ht()
174 if ((rs->rs_rates[amn->amn_rix] & 0x1f) < 4) in amrr_node_init_ht()
177 rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL; in amrr_node_init_ht()
179 /* Ensure the MCS bit is set */ in amrr_node_init_ht()
185 /* XXX TODO: we really need a rate-to-string method */ in amrr_node_init_ht()
186 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_node_init_ht()
187 "AMRR: nrates=%d, initial rate MCS %d", in amrr_node_init_ht()
188 rs->rs_nrates, in amrr_node_init_ht()
196 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_node_init_legacy()
199 rs = &ni->ni_rates; in amrr_node_init_legacy()
200 /* Initial rate - lowest */ in amrr_node_init_legacy()
201 rate = rs->rs_rates[0]; in amrr_node_init_legacy()
207 for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0; in amrr_node_init_legacy()
208 amn->amn_rix--) { in amrr_node_init_legacy()
209 /* legacy - anything < 36mbit, stop searching */ in amrr_node_init_legacy()
210 if ((rs->rs_rates[amn->amn_rix] & in amrr_node_init_legacy()
214 rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL; in amrr_node_init_legacy()
219 /* XXX TODO: we really need a rate-to-string method */ in amrr_node_init_legacy()
220 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_node_init_legacy()
222 rs->rs_nrates, in amrr_node_init_legacy()
229 struct ieee80211vap *vap = ni->ni_vap; in amrr_node_init()
230 struct ieee80211_amrr *amrr = vap->iv_rs; in amrr_node_init()
234 if_printf(vap->iv_ifp, "ratectl structure was not allocated, " in amrr_node_init()
235 "per-node structure allocation skipped\n"); in amrr_node_init()
239 if (ni->ni_rctls == NULL) { in amrr_node_init()
240 ni->ni_rctls = amn = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr_node), in amrr_node_init()
243 if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " in amrr_node_init()
248 amn = ni->ni_rctls; in amrr_node_init()
251 amn->amn_amrr = amrr; in amrr_node_init()
252 amn->amn_success = 0; in amrr_node_init()
253 amn->amn_recovery = 0; in amrr_node_init()
254 amn->amn_txcnt = amn->amn_retrycnt = 0; in amrr_node_init()
255 amn->amn_success_threshold = amrr->amrr_min_success_threshold; in amrr_node_init()
256 amn->amn_ticks = ticks; in amrr_node_init()
270 IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL); in amrr_node_deinit()
276 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_update_vht_inc()
277 uint8_t nss, mcs; in amrr_update_vht_inc() local
280 * For now just keep looping over MCS to 9, then NSS up, checking if in amrr_update_vht_inc()
282 * until we hit max. This at least tests the VHT MCS rates, in amrr_update_vht_inc()
283 * but definitely is suboptimal (in the same way the 11n MCS selection in amrr_update_vht_inc()
286 nss = amn->amn_vht_nss; in amrr_update_vht_inc()
287 mcs = amn->amn_vht_mcs; in amrr_update_vht_inc()
289 while (nss <= 8 && mcs <= 9) { in amrr_update_vht_inc()
290 /* Increment MCS 0..9, NSS 1..8 */ in amrr_update_vht_inc()
291 if (mcs == 9) { in amrr_update_vht_inc()
292 mcs = 0; in amrr_update_vht_inc()
295 mcs++; in amrr_update_vht_inc()
299 if (ieee80211_vht_node_check_tx_valid_mcs(ni, ni->ni_chw, nss, in amrr_update_vht_inc()
300 mcs)) { in amrr_update_vht_inc()
301 amn->amn_vht_nss = nss; in amrr_update_vht_inc()
302 amn->amn_vht_mcs = mcs; in amrr_update_vht_inc()
311 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_update_vht_dec()
312 uint8_t nss, mcs; in amrr_update_vht_dec() local
315 * For now just keep looping over MCS 9 .. 0 then NSS down, checking if in amrr_update_vht_dec()
317 * until we hit min. This at least tests the VHT MCS rates, in amrr_update_vht_dec()
318 * but definitely is suboptimal (in the same way the 11n MCS selection in amrr_update_vht_dec()
321 nss = amn->amn_vht_nss; in amrr_update_vht_dec()
322 mcs = amn->amn_vht_mcs; in amrr_update_vht_dec()
324 while (nss >= 1 && mcs >= 0) { in amrr_update_vht_dec()
326 if (mcs == 0) { in amrr_update_vht_dec()
327 mcs = 9; in amrr_update_vht_dec()
328 nss--; in amrr_update_vht_dec()
330 mcs--; in amrr_update_vht_dec()
334 if (ieee80211_vht_node_check_tx_valid_mcs(ni, ni->ni_chw, nss, in amrr_update_vht_dec()
335 mcs)) { in amrr_update_vht_dec()
336 amn->amn_vht_nss = nss; in amrr_update_vht_dec()
337 amn->amn_vht_mcs = mcs; in amrr_update_vht_dec()
346 * Use the available MCS rates at the current node bandwidth
347 * and configured / negotiated MCS rates.
352 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_update_vht()
353 struct ieee80211_amrr *amrr = ni->ni_vap->iv_rs; in amrr_update_vht()
355 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_vht()
356 "AMRR: VHT: current rate NSS %d MCS %d, txcnt=%d, retrycnt=%d", in amrr_update_vht()
357 amn->amn_vht_nss, amn->amn_vht_mcs, amn->amn_txcnt, in amrr_update_vht()
358 amn->amn_retrycnt); in amrr_update_vht()
361 amn->amn_success++; in amrr_update_vht()
362 if (amn->amn_success >= amn->amn_success_threshold) { in amrr_update_vht()
363 amn->amn_recovery = 1; in amrr_update_vht()
364 amn->amn_success = 0; in amrr_update_vht()
366 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_vht()
368 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_vht()
372 amn->amn_recovery = 0; in amrr_update_vht()
375 amn->amn_success = 0; in amrr_update_vht()
377 if (amn->amn_recovery) { in amrr_update_vht()
378 amn->amn_success_threshold *= 2; in amrr_update_vht()
379 if (amn->amn_success_threshold > in amrr_update_vht()
380 amrr->amrr_max_success_threshold) in amrr_update_vht()
381 amn->amn_success_threshold = in amrr_update_vht()
382 amrr->amrr_max_success_threshold; in amrr_update_vht()
384 amn->amn_success_threshold = in amrr_update_vht()
385 amrr->amrr_min_success_threshold; in amrr_update_vht()
387 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_vht()
389 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_vht()
393 amn->amn_recovery = 0; in amrr_update_vht()
397 amn->amn_txcnt = 0; in amrr_update_vht()
398 amn->amn_retrycnt = 0; in amrr_update_vht()
408 int rix = amn->amn_rix; in amrr_update_ht()
411 rs = (struct ieee80211_rateset *)&ni->ni_htrates; in amrr_update_ht()
413 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_ht()
414 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_ht()
415 "AMRR: current rate MCS %d, txcnt=%d, retrycnt=%d", in amrr_update_ht()
416 rs->rs_rates[rix] & IEEE80211_RATE_VAL, in amrr_update_ht()
417 amn->amn_txcnt, in amrr_update_ht()
418 amn->amn_retrycnt); in amrr_update_ht()
421 * XXX This is totally bogus for 11n, as although high MCS in amrr_update_ht()
422 * rates for each stream may be failing, the next stream in amrr_update_ht()
429 amn->amn_success++; in amrr_update_ht()
430 if (amn->amn_success >= amn->amn_success_threshold && in amrr_update_ht()
431 rix + 1 < rs->rs_nrates) { in amrr_update_ht()
432 amn->amn_recovery = 1; in amrr_update_ht()
433 amn->amn_success = 0; in amrr_update_ht()
435 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_ht()
436 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_ht()
437 "AMRR increasing rate MCS %d " in amrr_update_ht()
439 rs->rs_rates[rix] & IEEE80211_RATE_VAL, in amrr_update_ht()
440 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_ht()
442 amn->amn_recovery = 0; in amrr_update_ht()
445 amn->amn_success = 0; in amrr_update_ht()
447 if (amn->amn_recovery) { in amrr_update_ht()
448 amn->amn_success_threshold *= 2; in amrr_update_ht()
449 if (amn->amn_success_threshold > in amrr_update_ht()
450 amrr->amrr_max_success_threshold) in amrr_update_ht()
451 amn->amn_success_threshold = in amrr_update_ht()
452 amrr->amrr_max_success_threshold; in amrr_update_ht()
454 amn->amn_success_threshold = in amrr_update_ht()
455 amrr->amrr_min_success_threshold; in amrr_update_ht()
457 rix--; in amrr_update_ht()
458 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_ht()
459 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_ht()
460 "AMRR decreasing rate MCS %d " in amrr_update_ht()
462 rs->rs_rates[rix] & IEEE80211_RATE_VAL, in amrr_update_ht()
463 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_ht()
465 amn->amn_recovery = 0; in amrr_update_ht()
475 int rix = amn->amn_rix; in amrr_update_legacy()
478 rs = &ni->ni_rates; in amrr_update_legacy()
480 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_legacy()
481 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_legacy()
483 (rs->rs_rates[rix] & IEEE80211_RATE_VAL) / 2, in amrr_update_legacy()
484 amn->amn_txcnt, in amrr_update_legacy()
485 amn->amn_retrycnt); in amrr_update_legacy()
488 amn->amn_success++; in amrr_update_legacy()
489 if (amn->amn_success >= amn->amn_success_threshold && in amrr_update_legacy()
490 rix + 1 < rs->rs_nrates) { in amrr_update_legacy()
491 amn->amn_recovery = 1; in amrr_update_legacy()
492 amn->amn_success = 0; in amrr_update_legacy()
494 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_legacy()
495 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_legacy()
497 (rs->rs_rates[rix] & IEEE80211_RATE_VAL) / 2, in amrr_update_legacy()
498 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_legacy()
500 amn->amn_recovery = 0; in amrr_update_legacy()
503 amn->amn_success = 0; in amrr_update_legacy()
505 if (amn->amn_recovery) { in amrr_update_legacy()
506 amn->amn_success_threshold *= 2; in amrr_update_legacy()
507 if (amn->amn_success_threshold > in amrr_update_legacy()
508 amrr->amrr_max_success_threshold) in amrr_update_legacy()
509 amn->amn_success_threshold = in amrr_update_legacy()
510 amrr->amrr_max_success_threshold; in amrr_update_legacy()
512 amn->amn_success_threshold = in amrr_update_legacy()
513 amrr->amrr_min_success_threshold; in amrr_update_legacy()
515 rix--; in amrr_update_legacy()
516 /* XXX TODO: we really need a rate-to-string method */ in amrr_update_legacy()
517 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, in amrr_update_legacy()
519 (rs->rs_rates[rix] & IEEE80211_RATE_VAL) / 2, in amrr_update_legacy()
520 amn->amn_txcnt, amn->amn_retrycnt); in amrr_update_legacy()
522 amn->amn_recovery = 0; in amrr_update_legacy()
534 KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt)); in amrr_update()
545 amn->amn_txcnt = 0; in amrr_update()
546 amn->amn_retrycnt = 0; in amrr_update()
554 struct ieee80211_amrr *amrr = ni->ni_vap->iv_rs; in amrr_rate_vht()
555 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_rate_vht()
557 if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) in amrr_rate_vht()
560 ieee80211_node_set_txrate_vht_rate(ni, amn->amn_vht_nss, in amrr_rate_vht()
561 amn->amn_vht_mcs); in amrr_rate_vht()
575 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_rate()
580 /* XXX should return -1 here, but drivers may not expect this... */ in amrr_rate()
584 ni->ni_rates.rs_rates[0]); in amrr_rate()
594 rs = (struct ieee80211_rateset *) &ni->ni_htrates; in amrr_rate()
596 rs = &ni->ni_rates; in amrr_rate()
599 amrr = amn->amn_amrr; in amrr_rate()
600 if (is_enough(amn) && (ticks - amn->amn_ticks) > amrr->amrr_interval) { in amrr_rate()
602 if (rix != amn->amn_rix) { in amrr_rate()
605 dot11Rate = rs->rs_rates[rix]; in amrr_rate()
606 /* XXX strip basic rate flag from txrate, if non-11n */ in amrr_rate()
613 amn->amn_rix = rix; in amrr_rate()
615 amn->amn_ticks = ticks; in amrr_rate()
617 rix = amn->amn_rix; in amrr_rate()
622 * Update statistics with tx complete status. Ok is non-zero
624 * retransmissions (i.e. xmit attempts - 1).
630 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_tx_complete()
637 if (status->flags & IEEE80211_RATECTL_STATUS_LONG_RETRY) in amrr_tx_complete()
638 retries = status->long_retries; in amrr_tx_complete()
640 amn->amn_txcnt++; in amrr_tx_complete()
641 if (status->status == IEEE80211_RATECTL_TX_SUCCESS) in amrr_tx_complete()
642 amn->amn_success++; in amrr_tx_complete()
643 amn->amn_retrycnt += retries; in amrr_tx_complete()
650 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_tx_update_cb()
656 txcnt = stats->nframes; in amrr_tx_update_cb()
657 success = stats->nsuccess; in amrr_tx_update_cb()
659 if (stats->flags & IEEE80211_RATECTL_TX_STATS_RETRIES) in amrr_tx_update_cb()
660 retrycnt = stats->nretries; in amrr_tx_update_cb()
662 amn->amn_txcnt += txcnt; in amrr_tx_update_cb()
663 amn->amn_success += success; in amrr_tx_update_cb()
664 amn->amn_retrycnt += retrycnt; in amrr_tx_update_cb()
677 if (stats->flags & IEEE80211_RATECTL_TX_STATS_NODE) in amrr_tx_update()
678 amrr_tx_update_cb(stats, stats->ni); in amrr_tx_update()
680 ieee80211_iterate_nodes_vap(&vap->iv_ic->ic_sta, vap, in amrr_tx_update()
689 struct ieee80211_amrr *amrr = vap->iv_rs; in amrr_sysctl_interval()
695 msecs = ticks_to_msecs(amrr->amrr_interval); in amrr_sysctl_interval()
697 if (error || !req->newptr) in amrr_sysctl_interval()
707 struct ieee80211_amrr *amrr = vap->iv_rs; in amrr_sysctlattach()
718 &amrr->amrr_max_success_threshold, 0, ""); in amrr_sysctlattach()
721 &amrr->amrr_min_success_threshold, 0, ""); in amrr_sysctlattach()
732 rs = (struct ieee80211_rateset *) &ni->ni_htrates; in amrr_print_node_rate()
733 rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL; in amrr_print_node_rate()
734 sbuf_printf(s, "rate: MCS %d\n", rate); in amrr_print_node_rate()
736 rs = &ni->ni_rates; in amrr_print_node_rate()
737 rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL; in amrr_print_node_rate()
745 struct ieee80211_amrr_node *amn = ni->ni_rctls; in amrr_node_stats()
753 sbuf_printf(s, "ticks: %d\n", amn->amn_ticks); in amrr_node_stats()
754 sbuf_printf(s, "txcnt: %u\n", amn->amn_txcnt); in amrr_node_stats()
755 sbuf_printf(s, "success: %u\n", amn->amn_success); in amrr_node_stats()
756 sbuf_printf(s, "success_threshold: %u\n", amn->amn_success_threshold); in amrr_node_stats()
757 sbuf_printf(s, "recovery: %u\n", amn->amn_recovery); in amrr_node_stats()
758 sbuf_printf(s, "retry_cnt: %u\n", amn->amn_retrycnt); in amrr_node_stats()