summaryrefslogtreecommitdiffstats
path: root/sys/dev/ath/ath_rate/onoe/onoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ath/ath_rate/onoe/onoe.c')
-rw-r--r--sys/dev/ath/ath_rate/onoe/onoe.c117
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);
}
OpenPOWER on IntegriCloud