/* * Update ni->in_txrate. */ void ieee80211_amrr_choose(struct ieee80211_amrr *amrr, struct ieee80211_node *ni, struct ieee80211_amrr_node *amn) { int need_change = 0; uint8_t rate; if (is_success(amn) && is_enough(amn)) { amn->amn_success++; if (amn->amn_success >= amn->amn_success_threshold && !is_max_rate(ni)) { amn->amn_recovery = 1; amn->amn_success = 0; increase_rate(ni); rate = ni->in_rates.ir_rates[ni->in_txrate] & IEEE80211_RATE_VAL; ieee80211_dbg(IEEE80211_MSG_XRATE, "AMRR increasing rate %d (txcnt=%d retrycnt=%d)", rate, amn->amn_txcnt, amn->amn_retrycnt); DTRACE_PROBE4(amrr__increase__rate, struct ieee80211_node *, ni, uint8_t, rate, uint_t, amn->amn_txcnt, uint_t, amn->amn_retrycnt); need_change = 1; } else {
/* * Examine and potentially adjust the transmit rate. */ static void ath_rate_ctl(void *arg, struct ieee80211_node *ni) { struct ath_softc *sc = arg; struct amrr_node *amn = ATH_NODE_AMRR(ATH_NODE (ni)); int old_rate; #define is_success(amn) \ (amn->amn_tx_try1_cnt < (amn->amn_tx_try0_cnt/10)) #define is_enough(amn) \ (amn->amn_tx_try0_cnt > 10) #define is_failure(amn) \ (amn->amn_tx_try1_cnt > (amn->amn_tx_try0_cnt/3)) #define is_max_rate(ni) \ ((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates) #define is_min_rate(ni) \ (ni->ni_txrate == 0) old_rate = ni->ni_txrate; DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n", amn->amn_tx_try0_cnt, amn->amn_tx_try1_cnt, amn->amn_tx_try2_cnt, amn->amn_tx_try3_cnt, amn->amn_success_threshold); if (is_success (amn) && is_enough (amn)) { amn->amn_success++; if (amn->amn_success == amn->amn_success_threshold && !is_max_rate (ni)) { amn->amn_recovery = 1; amn->amn_success = 0; ni->ni_txrate++; DPRINTF (sc, "increase rate to %d\n", ni->ni_txrate); } else { amn->amn_recovery = 0; } } else if (is_failure (amn)) { amn->amn_success = 0; if (!is_min_rate (ni)) { if (amn->amn_recovery) { /* recovery failure. */ amn->amn_success_threshold *= 2; amn->amn_success_threshold = min (amn->amn_success_threshold, (u_int)ath_rate_max_success_threshold); DPRINTF (sc, "decrease rate recovery thr: %d\n", amn->amn_success_threshold); } else { /* simple failure. */ amn->amn_success_threshold = ath_rate_min_success_threshold; DPRINTF (sc, "decrease rate normal thr: %d\n", amn->amn_success_threshold); } amn->amn_recovery = 0; ni->ni_txrate--; } else { amn->amn_recovery = 0; } } if (is_enough (amn) || old_rate != ni->ni_txrate) { /* reset counters. */ amn->amn_tx_try0_cnt = 0; amn->amn_tx_try1_cnt = 0; amn->amn_tx_try2_cnt = 0; amn->amn_tx_try3_cnt = 0; amn->amn_tx_failure_cnt = 0; } if (old_rate != ni->ni_txrate) { ath_rate_update(sc, ni, ni->ni_txrate); } }