summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-09-27 22:10:26 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-09-27 22:10:26 +0000
commit79c848159252bf44638153cf28dae39cc4ca26eb (patch)
tree910ddaef7cffa8560dfe9e2eefd2f45586000b5f /sys/dev/ic
parent89f8c27268c8ff730e1d013603d743a768e2b7ea (diff)
Add automatic rate control (AMRR).
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/bwi.c64
-rw-r--r--sys/dev/ic/bwivar.h10
2 files changed, 70 insertions, 4 deletions
diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c
index 6e6e6e20876..246cd163c15 100644
--- a/sys/dev/ic/bwi.c
+++ b/sys/dev/ic/bwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwi.c,v 1.48 2007/09/27 09:19:21 mglocker Exp $ */
+/* $OpenBSD: bwi.c,v 1.49 2007/09/27 22:10:25 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -68,6 +68,7 @@
#include <netinet/if_ether.h>
#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/ic/bwireg.h>
@@ -274,6 +275,10 @@ void bwi_watchdog(struct ifnet *);
int bwi_stop(struct bwi_softc *);
int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
int bwi_media_change(struct ifnet *);
+void bwi_iter_func(void *, struct ieee80211_node *);
+void bwi_amrr_timeout(void *);
+void bwi_newassoc(struct ieee80211com *, struct ieee80211_node *,
+ int);
int bwi_dma_alloc(struct bwi_softc *);
void bwi_dma_free(struct bwi_softc *);
int bwi_dma_ring_alloc(struct bwi_softc *,
@@ -617,6 +622,11 @@ bwi_attach(struct bwi_softc *sc)
printf("\n");
+ /* AMRR rate control */
+ sc->sc_amrr.amrr_min_success_threshold = 1;
+ sc->sc_amrr.amrr_max_success_threshold = 15;
+ timeout_set(&sc->sc_amrr_ch, bwi_amrr_timeout, sc);
+
timeout_set(&sc->sc_scan_ch, bwi_next_scan, sc);
timeout_set(&sc->sc_calib_ch, bwi_calibrate, sc);
@@ -761,6 +771,7 @@ bwi_attach(struct bwi_softc *sc)
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = bwi_newstate;
+ ic->ic_newassoc = bwi_newassoc;
ieee80211_media_init(ifp, bwi_media_change, ieee80211_media_status);
@@ -6646,6 +6657,7 @@ bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
int error;
uint8_t chan;
+ timeout_del(&sc->sc_amrr_ch);
timeout_del(&sc->sc_scan_ch);
timeout_del(&sc->sc_calib_ch);
@@ -6685,6 +6697,12 @@ back:
} else if (nstate == IEEE80211_S_RUN) {
/* XXX 15 seconds */
timeout_add(&sc->sc_calib_ch, hz * 15);
+
+ if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+ /* start automatic rate control timer */
+ if (ic->ic_fixed_rate == -1)
+ timeout_add(&sc->sc_amrr_ch, hz / 2);
+ }
}
return (error);
@@ -6705,6 +6723,46 @@ bwi_media_change(struct ifnet *ifp)
return (0);
}
+void
+bwi_iter_func(void *arg, struct ieee80211_node *ni)
+{
+ struct bwi_softc *sc = arg;
+ struct bwi_node *bn = (struct bwi_node *)ni;
+
+ ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn);
+}
+
+void
+bwi_amrr_timeout(void *arg)
+{
+ struct bwi_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (ic->ic_opmode == IEEE80211_M_STA)
+ bwi_iter_func(sc, ic->ic_bss);
+ else
+ ieee80211_iterate_nodes(ic, bwi_iter_func, sc);
+
+ timeout_add(&sc->sc_amrr_ch, hz / 2);
+}
+
+void
+bwi_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
+{
+ struct bwi_softc *sc = ic->ic_if.if_softc;
+ int i;
+
+ DPRINTF(1, "%s\n", __func__);
+
+ ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn);
+
+ /* set rate to some reasonable initial value */
+ for (i = ni->ni_rates.rs_nrates - 1;
+ i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; i--);
+
+ ni->ni_txrate = i;
+}
+
int
bwi_dma_alloc(struct bwi_softc *sc)
{
@@ -7939,8 +7997,8 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
rate = ic->ic_sup_rates[ic->ic_curmode].
rs_rates[ic->ic_fixed_rate];
} else {
- /* TODO: TX rate control */
- rate = rate_fb = (1 * 2);
+ /* AMRR rate control */
+ rate = ni->ni_rates.rs_rates[ni->ni_txrate];
}
} else {
/* Fixed at 1Mbytes/s for mgt frames */
diff --git a/sys/dev/ic/bwivar.h b/sys/dev/ic/bwivar.h
index 2ec1a91b910..74b89f09cf9 100644
--- a/sys/dev/ic/bwivar.h
+++ b/sys/dev/ic/bwivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwivar.h,v 1.14 2007/09/27 09:19:21 mglocker Exp $ */
+/* $OpenBSD: bwivar.h,v 1.15 2007/09/27 22:10:25 mglocker Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -460,6 +460,11 @@ struct bwi_rx_radiotap_hdr {
/* TODO: sq */
};
+struct bwi_node {
+ struct ieee80211_node ni;
+ struct ieee80211_amrr_node amn;
+};
+
struct bwi_softc {
struct device sc_dev;
struct ieee80211com sc_ic;
@@ -491,6 +496,9 @@ struct bwi_softc {
struct timeout sc_scan_ch;
struct timeout sc_calib_ch;
+ struct timeout sc_amrr_ch;
+
+ struct ieee80211_amrr sc_amrr;
struct bwi_regwin *sc_cur_regwin;
struct bwi_regwin sc_com_regwin;