diff options
Diffstat (limited to 'sys/dev/ath/ath_rate/onoe/onoe.c')
-rw-r--r-- | sys/dev/ath/ath_rate/onoe/onoe.c | 117 |
1 files changed, 36 insertions, 81 deletions
diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c index eb5759e..25bac09 100644 --- a/sys/dev/ath/ath_rate/onoe/onoe.c +++ b/sys/dev/ath/ath_rate/onoe/onoe.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); * Atsushi Onoe's rate control algorithm. */ #include "opt_inet.h" +#include "opt_wlan.h" #include <sys/param.h> #include <sys/systm.h> @@ -68,19 +69,6 @@ __FBSDID("$FreeBSD$"); #include <dev/ath/ath_rate/onoe/onoe.h> #include <contrib/dev/ath/ah_desc.h> -#define ONOE_DEBUG -#ifdef ONOE_DEBUG -enum { - ATH_DEBUG_RATE = 0x00000010, /* rate control */ -}; -#define DPRINTF(sc, _fmt, ...) do { \ - if (sc->sc_debug & ATH_DEBUG_RATE) \ - printf(_fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, _fmt, ...) -#endif - /* * Default parameters for the rate control algorithm. These are * all tunable with sysctls. The rate controller runs periodically @@ -104,7 +92,6 @@ static int ath_rateinterval = 1000; /* rate ctl interval (ms) */ static int ath_rate_raise = 10; /* add credit threshold */ static int ath_rate_raise_threshold = 10; /* rate ctl raise threshold */ -static void ath_ratectl(void *); static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, int rate); static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); @@ -114,7 +101,6 @@ void ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) { /* NB: assumed to be zero'd by caller */ - ath_rate_update(sc, &an->an_node, 0); } void @@ -163,6 +149,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, on->on_tx_err++; on->on_tx_retr += ts->ts_shortretry + ts->ts_longretry; + if (on->on_interval != 0 && ticks - on->on_ticks > on->on_interval) { + ath_rate_ctl(sc, &an->an_node); + on->on_ticks = ticks; + } } void @@ -177,17 +167,17 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) { struct ath_node *an = ATH_NODE(ni); struct onoe_node *on = ATH_NODE_ONOE(an); + struct ieee80211vap *vap = ni->ni_vap; const HAL_RATE_TABLE *rt = sc->sc_currates; u_int8_t rix; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - DPRINTF(sc, "%s: set xmit rate for %s to %dM\n", - __func__, ether_sprintf(ni->ni_macaddr), - ni->ni_rates.rs_nrates > 0 ? + IEEE80211_NOTE(vap, IEEE80211_MSG_RATECTL, ni, + "%s: set xmit rate to %dM", __func__, + ni->ni_rates.rs_nrates > 0 ? (ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0); - ni->ni_txrate = rate; /* * Before associating a node has no rate set setup * so we can't calculate any transmit codes to use. @@ -197,8 +187,9 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) */ if (ni->ni_rates.rs_nrates == 0) goto done; - on->on_tx_rix0 = sc->sc_rixmap[ - ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL]; + on->on_rix = rate; + ni->ni_txrate = ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL; + on->on_tx_rix0 = sc->sc_rixmap[ni->ni_txrate]; on->on_tx_rate0 = rt->info[on->on_tx_rix0].rateCode; on->on_tx_rate0sp = on->on_tx_rate0 | @@ -246,6 +237,11 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) } done: on->on_tx_ok = on->on_tx_err = on->on_tx_retr = on->on_tx_upper = 0; + + on->on_interval = ath_rateinterval; + if (vap->iv_opmode == IEEE80211_M_STA) + on->on_interval /= 2; + on->on_interval = (on->on_interval * hz) / 1000; } /* @@ -255,11 +251,12 @@ static void ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ath_node *an = ATH_NODE(ni); + const struct ieee80211_txparam *tp = an->an_tp; int srate; KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { + if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { /* * No fixed rate is requested. For 11b start with * the highest negotiated rate; otherwise, for 11g @@ -285,7 +282,7 @@ ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) */ /* NB: the rate set is assumed sorted */ srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != ic->ic_fixed_rate; srate--) + for (; srate >= 0 && RATE(srate) != tp->ucastrate; srate--) ; } /* @@ -310,22 +307,20 @@ ath_rate_cb(void *arg, struct ieee80211_node *ni) * Reset the rate control state for each 802.11 state transition. */ void -ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) +ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state) { - struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_node *ni; - if (state == IEEE80211_S_INIT) { - callout_stop(&osc->timer); + if (state == IEEE80211_S_INIT) return; - } - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* * Reset local xmit state; this is really only * meaningful when operating in station mode. */ - ni = ic->ic_bss; + ni = vap->iv_bss; if (state == IEEE80211_S_RUN) { ath_rate_ctl_start(sc, ni); } else { @@ -339,20 +334,7 @@ ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) * tx rate state of each node. */ ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc); - ath_rate_update(sc, ic->ic_bss, 0); - } - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE && - state == IEEE80211_S_RUN) { - int interval; - /* - * Start the background rate control thread if we - * are not configured to use a fixed xmit rate. - */ - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); + ath_rate_update(sc, vap->iv_bss, 0); } } @@ -386,12 +368,11 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100) dir = 1; - DPRINTF(sc, "%s: ok %d err %d retr %d upper %d dir %d\n", - ether_sprintf(ni->ni_macaddr), - on->on_tx_ok, on->on_tx_err, on->on_tx_retr, - on->on_tx_upper, dir); + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "ok %d err %d retr %d upper %d dir %d", + on->on_tx_ok, on->on_tx_err, on->on_tx_retr, on->on_tx_upper, dir); - nrate = ni->ni_txrate; + nrate = on->on_rix; switch (dir) { case 0: if (enough && on->on_tx_upper > 0) @@ -416,10 +397,10 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) break; } - if (nrate != ni->ni_txrate) { - DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n", - __func__, - (rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2, + if (nrate != on->on_rix) { + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "%s: %dM -> %dM (%d ok, %d err, %d retr)", __func__, + ni->ni_txrate / 2, (rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2, on->on_tx_ok, on->on_tx_err, on->on_tx_retr); ath_rate_update(sc, ni, nrate); @@ -428,30 +409,6 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) } static void -ath_ratectl(void *arg) -{ - struct ifnet *ifp = arg; - struct ath_softc *sc = ifp->if_softc; - struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; - int interval; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - sc->sc_stats.ast_rate_calls++; - - if (ic->ic_opmode == IEEE80211_M_STA) - ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */ - else - ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc); - } - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); -} - -static void ath_rate_sysctlattach(struct ath_softc *sc) { struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); @@ -478,7 +435,6 @@ ath_rate_attach(struct ath_softc *sc) if (osc == NULL) return NULL; osc->arc.arc_space = sizeof(struct onoe_node); - callout_init(&osc->timer, CALLOUT_MPSAFE); ath_rate_sysctlattach(sc); return &osc->arc; @@ -489,7 +445,6 @@ ath_rate_detach(struct ath_ratectrl *arc) { struct onoe_softc *osc = (struct onoe_softc *) arc; - callout_drain(&osc->timer); free(osc, M_DEVBUF); } |