summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2010-04-07 15:29:13 +0000
committerrpaulo <rpaulo@FreeBSD.org>2010-04-07 15:29:13 +0000
commit69bf804b50328bc699737db57c5d38691d59780a (patch)
treeea8a3480b8652bfecee1f73168674b2f28571e3b
parent1db184691b1abeac975b128c17b5c4997b7bcf6c (diff)
downloadFreeBSD-src-69bf804b50328bc699737db57c5d38691d59780a.zip
FreeBSD-src-69bf804b50328bc699737db57c5d38691d59780a.tar.gz
net80211 rate control framework (net80211 ratectl).
This framework allows drivers to abstract the rate control algorithm and just feed the framework with the usable parameters. The rate control framework will now deal with passing the parameters to the selected algorithm. Right now we have AMRR (the default) and RSSADAPT but there's no way to select one with ifconfig, yet. The objective is to have more rate control algorithms in the net80211 stack so all drivers[0] can use it. Ideally, we'll have the well-known sample rate control algorithm in the net80211 at some point so all drivers can use it (not just ath). [0] all drivers that do rate control in software, that is. Reviewed by: bschmidt, thompsa, weyongo MFC after: 1 months
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/bwi/if_bwi.c44
-rw-r--r--sys/dev/bwi/if_bwivar.h7
-rw-r--r--sys/dev/bwn/if_bwn.c79
-rw-r--r--sys/dev/bwn/if_bwnvar.h7
-rw-r--r--sys/dev/iwn/if_iwn.c32
-rw-r--r--sys/dev/iwn/if_iwnvar.h3
-rw-r--r--sys/dev/ral/rt2560.c57
-rw-r--r--sys/dev/ral/rt2560var.h7
-rw-r--r--sys/dev/ral/rt2661.c48
-rw-r--r--sys/dev/ral/rt2661var.h7
-rw-r--r--sys/dev/usb/wlan/if_rum.c76
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h11
-rw-r--r--sys/dev/usb/wlan/if_run.c88
-rw-r--r--sys/dev/usb/wlan/if_runvar.h12
-rw-r--r--sys/dev/usb/wlan/if_ural.c75
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h11
-rw-r--r--sys/dev/usb/wlan/if_urtw.c1
-rw-r--r--sys/dev/usb/wlan/if_zyd.c50
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h7
-rw-r--r--sys/dev/wpi/if_wpi.c47
-rw-r--r--sys/dev/wpi/if_wpivar.h7
-rw-r--r--sys/modules/wlan/Makefile3
-rw-r--r--sys/net80211/ieee80211.c3
-rw-r--r--sys/net80211/ieee80211_amrr.c142
-rw-r--r--sys/net80211/ieee80211_amrr.h40
-rw-r--r--sys/net80211/ieee80211_freebsd.h13
-rw-r--r--sys/net80211/ieee80211_node.c2
-rw-r--r--sys/net80211/ieee80211_node.h3
-rw-r--r--sys/net80211/ieee80211_ratectl.c66
-rw-r--r--sys/net80211/ieee80211_ratectl.h127
-rw-r--r--sys/net80211/ieee80211_rssadapt.c128
-rw-r--r--sys/net80211/ieee80211_rssadapt.h32
-rw-r--r--sys/net80211/ieee80211_var.h5
34 files changed, 633 insertions, 608 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 845c83f..1f95ed8 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2380,6 +2380,7 @@ net80211/ieee80211_phy.c optional wlan
net80211/ieee80211_power.c optional wlan
net80211/ieee80211_proto.c optional wlan
net80211/ieee80211_radiotap.c optional wlan
+net80211/ieee80211_ratectl.c optional wlan
net80211/ieee80211_regdomain.c optional wlan
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
net80211/ieee80211_scan.c optional wlan
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index 2604d83..c77004d 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -64,8 +64,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -112,9 +112,6 @@ static void bwi_set_channel(struct ieee80211com *);
static void bwi_scan_end(struct ieee80211com *);
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void bwi_updateslot(struct ifnet *);
-static struct ieee80211_node *bwi_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
-static void bwi_newassoc(struct ieee80211_node *, int);
static int bwi_media_change(struct ifnet *);
static void bwi_calibrate(void *);
@@ -525,7 +522,6 @@ bwi_attach(struct bwi_softc *sc)
ic->ic_vap_delete = bwi_vap_delete;
ic->ic_raw_xmit = bwi_raw_xmit;
ic->ic_updateslot = bwi_updateslot;
- ic->ic_node_alloc = bwi_node_alloc;
ic->ic_scan_start = bwi_scan_start;
ic->ic_scan_end = bwi_scan_end;
ic->ic_set_channel = bwi_set_channel;
@@ -621,10 +617,7 @@ bwi_vap_create(struct ieee80211com *ic,
#if 0
vap->iv_update_beacon = bwi_beacon_update;
#endif
- ieee80211_amrr_init(&bvp->bv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status);
@@ -637,7 +630,7 @@ bwi_vap_delete(struct ieee80211vap *vap)
{
struct bwi_vap *bvp = BWI_VAP(vap);
- ieee80211_amrr_cleanup(&bvp->bv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@@ -1831,7 +1824,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
#endif
if (vap->iv_opmode == IEEE80211_M_STA) {
/* fake a join to init the tx rate */
- bwi_newassoc(ni, 1);
+ ic->ic_newassoc(ni, 1);
}
callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
@@ -1842,25 +1835,6 @@ back:
return error;
}
-/* ARGUSED */
-static struct ieee80211_node *
-bwi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct bwi_node *bn;
-
- bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return bn != NULL ? &bn->ni : NULL;
-}
-
-static void
-bwi_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&BWI_VAP(vap)->bv_amrr,
- &BWI_NODE(ni)->amn, ni);
-}
-
static int
bwi_media_change(struct ifnet *ifp)
{
@@ -3012,7 +2986,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = rate_fb = tp->ucastrate;
} else {
- rix = ieee80211_amrr_choose(ni, &BWI_NODE(ni)->amn);
+ rix = ieee80211_ratectl_rate(ni, NULL, pkt_len);
rate = ni->ni_txrate;
if (rix > 0) {
@@ -3369,6 +3343,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
struct bwi_txbuf *tb;
int ring_idx, buf_idx;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
if (tx_id == 0) {
if_printf(ifp, "%s: zero tx id\n", __func__);
@@ -3393,8 +3368,8 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap);
ni = tb->tb_ni;
+ vap = ni->ni_vap;
if (tb->tb_ni != NULL) {
- struct bwi_node *bn = (struct bwi_node *) tb->tb_ni;
const struct bwi_txbuf_hdr *hdr =
mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *);
@@ -3407,8 +3382,9 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
* well so to avoid over-aggressive downshifting we
* treat any number of retries as "1".
*/
- ieee80211_amrr_tx_complete(&bn->amn, acked,
- data_txcnt > 1);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ (data_txcnt > 1) ? IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE, &acked, NULL);
}
/*
diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h
index 22a1b1e..d5f09da 100644
--- a/sys/dev/bwi/if_bwivar.h
+++ b/sys/dev/bwi/if_bwivar.h
@@ -533,15 +533,8 @@ struct bwi_rx_radiotap_hdr {
/* TODO: sq */
};
-struct bwi_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define BWI_NODE(ni) ((struct bwi_node *)(ni))
-
struct bwi_vap {
struct ieee80211vap bv_vap;
- struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index a48548b..983f997 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -67,8 +67,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/bwn/if_bwnreg.h>
#include <dev/bwn/if_bwnvar.h>
@@ -180,18 +180,14 @@ static void bwn_addchannels(struct ieee80211_channel [], int, int *,
const struct bwn_channelinfo *, int);
static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void bwn_newassoc(struct ieee80211_node *, int);
static void bwn_updateslot(struct ifnet *);
static void bwn_update_promisc(struct ifnet *);
static void bwn_wme_init(struct bwn_mac *);
static int bwn_wme_update(struct ieee80211com *);
-static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void bwn_wme_clear(struct bwn_softc *);
static void bwn_wme_load(struct bwn_mac *);
static void bwn_wme_loadparams(struct bwn_mac *,
const struct wmeParams *, uint16_t);
-static void bwn_node_cleanup(struct ieee80211_node *);
static void bwn_scan_start(struct ieee80211com *);
static void bwn_scan_end(struct ieee80211com *);
static void bwn_set_channel(struct ieee80211com *);
@@ -1088,15 +1084,10 @@ bwn_attach_post(struct bwn_softc *sc)
/* override default methods */
ic->ic_raw_xmit = bwn_raw_xmit;
- ic->ic_newassoc = bwn_newassoc;
ic->ic_updateslot = bwn_updateslot;
ic->ic_update_promisc = bwn_update_promisc;
ic->ic_wme.wme_update = bwn_wme_update;
- ic->ic_node_alloc = bwn_node_alloc;
- sc->sc_node_cleanup = ic->ic_node_cleanup;
- ic->ic_node_cleanup = bwn_node_cleanup;
-
ic->ic_scan_start = bwn_scan_start;
ic->ic_scan_end = bwn_scan_end;
ic->ic_set_channel = bwn_set_channel;
@@ -2772,20 +2763,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
/*
- * Setup driver-specific state for a newly associated node.
- * Note that we're called also on a re-associate, the isnew
- * param tells us if this is the first time or not.
- */
-static void
-bwn_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
- &BWN_NODE(ni)->bn_amn, ni);
-}
-
-/*
* Callback from the 802.11 layer to update the slot time
* based on the current setting. We use it to notify the
* firmware of ERP changes and the f/w takes care of things
@@ -2857,32 +2834,6 @@ bwn_wme_update(struct ieee80211com *ic)
return (0);
}
-static struct ieee80211_node *
-bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct ieee80211com *ic = vap->iv_ic;
- struct bwn_softc *sc = ic->ic_ifp->if_softc;
- const size_t space = sizeof(struct bwn_node);
- struct bwn_node *bn;
-
- bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
- if (bn == NULL) {
- /* XXX stat+msg */
- return (NULL);
- }
- DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
- return (&bn->bn_node);
-}
-
-static void
-bwn_node_cleanup(struct ieee80211_node *ni)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct bwn_softc *sc = ic->ic_ifp->if_softc;
-
- sc->sc_node_cleanup(ni);
-}
-
static void
bwn_scan_start(struct ieee80211com *ic)
{
@@ -3018,10 +2969,7 @@ bwn_vap_create(struct ieee80211com *ic,
/* override max aid so sta's cannot assoc when we're out of sta id's */
vap->iv_max_aid = BWN_STAID_MAX;
- ieee80211_amrr_init(&bvp->bv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@@ -3034,7 +2982,7 @@ bwn_vap_delete(struct ieee80211vap *vap)
{
struct bwn_vap *bvp = BWN_VAP(vap);
- ieee80211_amrr_cleanup(&bvp->bv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@@ -9040,12 +8988,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
struct bwn_dma_ring *dr;
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
- struct bwn_node *bn;
struct bwn_pio_txqueue *tq;
struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
struct bwn_stats *stats = &mac->mac_stats;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
int slot;
BWN_ASSERT_LOCKED(mac->mac_sc);
@@ -9074,9 +9022,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
dr->getdesc(dr, slot, &desc, &meta);
if (meta->mt_islast) {
ni = meta->mt_ni;
- bn = (struct bwn_node *)ni;
- ieee80211_amrr_tx_complete(&bn->bn_amn,
- status->ack, 0);
+ vap = ni->ni_vap;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ NULL, 0);
break;
}
slot = bwn_dma_nextslot(dr, slot);
@@ -9092,8 +9043,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
return;
}
ni = tp->tp_ni;
- bn = (struct bwn_node *)ni;
- ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
+ vap = ni->ni_vap;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ status->ack ?
+ IEEE80211_RATECTL_TX_SUCCESS :
+ IEEE80211_RATECTL_TX_FAILURE,
+ NULL, 0);
}
bwn_pio_handle_txeof(mac, status);
}
@@ -9678,7 +9633,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = rate_fb = tp->ucastrate;
else {
- rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
+ rix = ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
if (rix > 0)
diff --git a/sys/dev/bwn/if_bwnvar.h b/sys/dev/bwn/if_bwnvar.h
index 16934c3..461587d 100644
--- a/sys/dev/bwn/if_bwnvar.h
+++ b/sys/dev/bwn/if_bwnvar.h
@@ -883,18 +883,11 @@ struct bwn_mac {
TAILQ_ENTRY(bwn_mac) mac_list;
};
-struct bwn_node {
- struct ieee80211_node bn_node; /* must be the first */
- struct ieee80211_amrr_node bn_amn;
-};
-#define BWN_NODE(ni) ((struct bwn_node *)(ni))
-
/*
* Driver-specific vap state.
*/
struct bwn_vap {
struct ieee80211vap bv_vap; /* base class */
- struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index b6af7b8..ebafc9c 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -65,9 +65,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip.h>
#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/iwn/if_iwnreg.h>
#include <dev/iwn/if_iwnvar.h>
@@ -755,11 +755,7 @@ iwn_vap_create(struct ieee80211com *ic,
ivp->iv_newstate = vap->iv_newstate;
vap->iv_newstate = iwn_newstate;
- ieee80211_amrr_init(&ivp->iv_amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* Complete setup. */
ieee80211_vap_attach(vap, ieee80211_media_change,
ieee80211_media_status);
@@ -772,7 +768,7 @@ iwn_vap_delete(struct ieee80211vap *vap)
{
struct iwn_vap *ivp = IWN_VAP(vap);
- ieee80211_amrr_cleanup(&ivp->iv_amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(ivp, M_80211_VAP);
}
@@ -1858,11 +1854,8 @@ iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
void
iwn_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
- struct iwn_node *wn = (void *)ni;
-
- ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
- &wn->amn, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
int
@@ -2291,9 +2284,9 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
struct iwn_tx_data *data = &ring->data[desc->idx];
- struct iwn_node *wn = (void *)data->ni;
struct mbuf *m;
struct ieee80211_node *ni;
+ struct ieee80211vap *vap;
KASSERT(data->ni != NULL, ("no node"));
@@ -2302,6 +2295,7 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
bus_dmamap_unload(ring->data_dmat, data->map);
m = data->m, data->m = NULL;
ni = data->ni, data->ni = NULL;
+ vap = ni->ni_vap;
if (m->m_flags & M_TXCB) {
/*
@@ -2331,11 +2325,11 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
*/
if (status & 0x80) {
ifp->if_oerrors++;
- ieee80211_amrr_tx_complete(&wn->amn,
- IEEE80211_AMRR_FAILURE, ackfailcnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
} else {
- ieee80211_amrr_tx_complete(&wn->amn,
- IEEE80211_AMRR_SUCCESS, ackfailcnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
}
m_freem(m);
ieee80211_free_node(ni);
@@ -2851,7 +2845,8 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else {
- (void) ieee80211_amrr_choose(ni, &wn->amn);
+ /* XXX pass pktlen */
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
ridx = iwn_plcp_signal(rate);
@@ -6434,4 +6429,3 @@ DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
MODULE_DEPEND(iwn, pci, 1, 1, 1);
MODULE_DEPEND(iwn, firmware, 1, 1, 1);
MODULE_DEPEND(iwn, wlan, 1, 1, 1);
-MODULE_DEPEND(iwn, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h
index 98c9c94..fe68ec9 100644
--- a/sys/dev/iwn/if_iwnvar.h
+++ b/sys/dev/iwn/if_iwnvar.h
@@ -99,7 +99,6 @@ struct iwn_rx_ring {
struct iwn_node {
struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
uint16_t disable_tid;
uint8_t id;
uint8_t ridx[IEEE80211_RATE_MAXSIZE];
@@ -193,8 +192,6 @@ struct iwn_hal {
struct iwn_vap {
struct ieee80211vap iv_vap;
- struct ieee80211_amrr iv_amrr;
- struct callout iv_amrr_to;
uint8_t iv_ridx;
int (*iv_newstate)(struct ieee80211vap *,
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index 455b5ad..2fe1ac8 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -103,8 +103,6 @@ static void rt2560_reset_rx_ring(struct rt2560_softc *,
struct rt2560_rx_ring *);
static void rt2560_free_rx_ring(struct rt2560_softc *,
struct rt2560_rx_ring *);
-static struct ieee80211_node *rt2560_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void rt2560_newassoc(struct ieee80211_node *, int);
static int rt2560_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -307,7 +305,6 @@ rt2560_attach(device_t dev, int id)
ic->ic_raw_xmit = rt2560_raw_xmit;
ic->ic_updateslot = rt2560_update_slot;
ic->ic_update_promisc = rt2560_update_promisc;
- ic->ic_node_alloc = rt2560_node_alloc;
ic->ic_scan_start = rt2560_scan_start;
ic->ic_scan_end = rt2560_scan_end;
ic->ic_set_channel = rt2560_set_channel;
@@ -430,11 +427,7 @@ rt2560_vap_create(struct ieee80211com *ic,
vap->iv_newstate = rt2560_newstate;
vap->iv_update_beacon = rt2560_beacon_update;
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
@@ -447,7 +440,7 @@ rt2560_vap_delete(struct ieee80211vap *vap)
{
struct rt2560_vap *rvp = RT2560_VAP(vap);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -764,25 +757,11 @@ rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
bus_dma_tag_destroy(ring->data_dmat);
}
-static struct ieee80211_node *
-rt2560_node_alloc(struct ieee80211vap *vap,
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rt2560_node *rn;
-
- rn = malloc(sizeof (struct rt2560_node), M_80211_NODE,
- M_NOWAIT | M_ZERO);
-
- return (rn != NULL) ? &rn->ni : NULL;
-}
-
static void
rt2560_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RT2560_VAP(vap)->amrr,
- &RT2560_NODE(ni)->amrr, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
static int
@@ -955,10 +934,11 @@ rt2560_tx_intr(struct rt2560_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
- struct rt2560_node *rn;
struct mbuf *m;
uint32_t flags;
int retrycnt;
+ struct ieee80211vap *vap;
+ struct ieee80211_node *ni;
bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
BUS_DMASYNC_POSTREAD);
@@ -973,15 +953,19 @@ rt2560_tx_intr(struct rt2560_softc *sc)
!(flags & RT2560_TX_VALID))
break;
- rn = (struct rt2560_node *)data->ni;
m = data->m;
+ ni = data->ni;
+ vap = ni->ni_vap;
switch (flags & RT2560_TX_RESULT_MASK) {
case RT2560_TX_SUCCESS:
+ retrycnt = 0;
+
DPRINTFN(sc, 10, "%s\n", "data frame sent successfully");
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, 0);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -991,8 +975,9 @@ rt2560_tx_intr(struct rt2560_softc *sc)
DPRINTFN(sc, 9, "data frame sent after %u retries\n",
retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -1002,8 +987,9 @@ rt2560_tx_intr(struct rt2560_softc *sc)
DPRINTFN(sc, 9, "data frame failed after %d retries\n",
retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_FAILURE, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ifp->if_oerrors++;
break;
@@ -1022,6 +1008,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
data->m = NULL;
ieee80211_free_node(data->ni);
data->ni = NULL;
+ ni = NULL;
/* descriptor is no longer valid */
desc->flags &= ~htole32(RT2560_TX_VALID);
@@ -1821,7 +1808,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &RT2560_NODE(ni)->amrr);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index 288577b..b6a8d68 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -95,16 +95,9 @@ struct rt2560_rx_ring {
int cur_decrypt;
};
-struct rt2560_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amrr;
-};
-#define RT2560_NODE(ni) ((struct rt2560_node *)(ni))
-
struct rt2560_vap {
struct ieee80211vap ral_vap;
struct ieee80211_beacon_offsets ral_bo;
- struct ieee80211_amrr amrr;
int (*ral_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index 9e6693f..94ab9ca 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -100,8 +100,6 @@ static void rt2661_reset_rx_ring(struct rt2661_softc *,
struct rt2661_rx_ring *);
static void rt2661_free_rx_ring(struct rt2661_softc *,
struct rt2661_rx_ring *);
-static struct ieee80211_node *rt2661_node_alloc(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
static void rt2661_newassoc(struct ieee80211_node *, int);
static int rt2661_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -307,7 +305,6 @@ rt2661_attach(device_t dev, int id)
ieee80211_ifattach(ic, macaddr);
ic->ic_newassoc = rt2661_newassoc;
- ic->ic_node_alloc = rt2661_node_alloc;
#if 0
ic->ic_wme.wme_update = rt2661_wme_update;
#endif
@@ -428,11 +425,7 @@ rt2661_vap_create(struct ieee80211com *ic,
vap->iv_update_beacon = rt2661_beacon_update;
#endif
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /* ms */);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
@@ -445,7 +438,7 @@ rt2661_vap_delete(struct ieee80211vap *vap)
{
struct rt2661_vap *rvp = RT2661_VAP(vap);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -771,25 +764,11 @@ rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
bus_dma_tag_destroy(ring->data_dmat);
}
-static struct ieee80211_node *
-rt2661_node_alloc(struct ieee80211vap *vap,
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rt2661_node *rn;
-
- rn = malloc(sizeof (struct rt2661_node), M_80211_NODE,
- M_NOWAIT | M_ZERO);
-
- return (rn != NULL) ? &rn->ni : NULL;
-}
-
static void
rt2661_newassoc(struct ieee80211_node *ni, int isnew)
{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RT2661_VAP(vap)->amrr,
- &RT2661_NODE(ni)->amrr, ni);
+ /* XXX move */
+ ieee80211_ratectl_node_init(ni);
}
static int
@@ -899,9 +878,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
struct ifnet *ifp = sc->sc_ifp;
struct rt2661_tx_ring *txq;
struct rt2661_tx_data *data;
- struct rt2661_node *rn;
uint32_t val;
int qid, retrycnt;
+ struct ieee80211vap *vap;
for (;;) {
struct ieee80211_node *ni;
@@ -921,13 +900,12 @@ rt2661_tx_intr(struct rt2661_softc *sc)
data->m = NULL;
ni = data->ni;
data->ni = NULL;
+ vap = ni->ni_vap;
/* if no frame has been sent, ignore */
if (ni == NULL)
continue;
- rn = RT2661_NODE(ni);
-
switch (RT2661_TX_RESULT(val)) {
case RT2661_TX_SUCCESS:
retrycnt = RT2661_TX_RETRYCNT(val);
@@ -935,8 +913,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
DPRINTFN(sc, 10, "data frame sent successfully after "
"%d retries\n", retrycnt);
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_SUCCESS, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_opackets++;
break;
@@ -946,8 +925,9 @@ rt2661_tx_intr(struct rt2661_softc *sc)
DPRINTFN(sc, 9, "%s\n",
"sending data frame failed (too much retries)");
if (data->rix != IEEE80211_FIXED_RATE_NONE)
- ieee80211_amrr_tx_complete(&rn->amrr,
- IEEE80211_AMRR_FAILURE, retrycnt);
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ifp->if_oerrors++;
break;
@@ -1511,7 +1491,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &RT2661_NODE(ni)->amrr);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
rate &= IEEE80211_RATE_VAL;
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index db1d4de..9927d13 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -88,15 +88,8 @@ struct rt2661_rx_ring {
int next;
};
-struct rt2661_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amrr;
-};
-#define RT2661_NODE(ni) ((struct rt2661_node *)(ni))
-
struct rt2661_vap {
struct ieee80211vap ral_vap;
- struct ieee80211_amrr amrr;
int (*ral_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index 0cd394d..5b3441b 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -140,7 +140,6 @@ static const struct usb_device_id rum_devs[] = {
};
MODULE_DEPEND(rum, wlan, 1, 1, 1);
-MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
MODULE_DEPEND(rum, usb, 1, 1, 1);
static device_probe_t rum_match;
@@ -212,17 +211,14 @@ static int rum_prepare_beacon(struct rum_softc *,
struct ieee80211vap *);
static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_newassoc(struct ieee80211_node *, int);
static void rum_scan_start(struct ieee80211com *);
static void rum_scan_end(struct ieee80211com *);
static void rum_set_channel(struct ieee80211com *);
static int rum_get_rssi(struct rum_softc *, uint8_t);
-static void rum_amrr_start(struct rum_softc *,
+static void rum_ratectl_start(struct rum_softc *,
struct ieee80211_node *);
-static void rum_amrr_timeout(void *);
-static void rum_amrr_task(void *, int);
+static void rum_ratectl_timeout(void *);
+static void rum_ratectl_task(void *, int);
static int rum_pause(struct rum_softc *, int);
static const struct {
@@ -511,9 +507,7 @@ rum_attach(device_t self)
ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_update_promisc = rum_update_promisc;
- ic->ic_newassoc = rum_newassoc;
ic->ic_raw_xmit = rum_raw_xmit;
- ic->ic_node_alloc = rum_node_alloc;
ic->ic_scan_start = rum_scan_start;
ic->ic_scan_end = rum_scan_end;
ic->ic_set_channel = rum_set_channel;
@@ -608,13 +602,10 @@ rum_vap_create(struct ieee80211com *ic,
rvp->newstate = vap->iv_newstate;
vap->iv_newstate = rum_newstate;
- usb_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
- TASK_INIT(&rvp->amrr_task, 0, rum_amrr_task, rvp);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
+ usb_callout_init_mtx(&rvp->ratectl_ch, &sc->sc_mtx, 0);
+ TASK_INIT(&rvp->ratectl_task, 0, rum_ratectl_task, rvp);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
@@ -627,9 +618,9 @@ rum_vap_delete(struct ieee80211vap *vap)
struct rum_vap *rvp = RUM_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- usb_callout_drain(&rvp->amrr_ch);
- ieee80211_draintask(ic, &rvp->amrr_task);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ usb_callout_drain(&rvp->ratectl_ch);
+ ieee80211_draintask(ic, &rvp->ratectl_task);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
}
@@ -716,7 +707,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RUM_LOCK(sc);
- usb_callout_stop(&rvp->amrr_ch);
+ usb_callout_stop(&rvp->ratectl_ch);
switch (nstate) {
case IEEE80211_S_INIT:
@@ -751,7 +742,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* enable automatic rate adaptation */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- rum_amrr_start(sc, ni);
+ rum_ratectl_start(sc, ni);
break;
default:
break;
@@ -2194,7 +2185,7 @@ bad:
}
static void
-rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
+rum_ratectl_start(struct rum_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct rum_vap *rvp = RUM_VAP(vap);
@@ -2202,23 +2193,23 @@ rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
/* clear statistic registers (STA_CSR0 to STA_CSR5) */
rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
- ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
+ ieee80211_ratectl_node_init(ni);
- usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+ usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
}
static void
-rum_amrr_timeout(void *arg)
+rum_ratectl_timeout(void *arg)
{
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- ieee80211_runtask(ic, &rvp->amrr_task);
+ ieee80211_runtask(ic, &rvp->ratectl_task);
}
static void
-rum_amrr_task(void *arg, int pending)
+rum_ratectl_task(void *arg, int pending)
{
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
@@ -2227,6 +2218,7 @@ rum_amrr_task(void *arg, int pending)
struct rum_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss;
int ok, fail;
+ int sum, retrycnt;
RUM_LOCK(sc);
/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
@@ -2235,36 +2227,18 @@ rum_amrr_task(void *arg, int pending)
ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */
(le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */
fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
+ sum = ok+fail;
+ retrycnt = (le32toh(sc->sta[5]) & 0xffff) + fail;
- ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn,
- ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
- (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
+ ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
- usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+ usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
RUM_UNLOCK(sc);
}
-/* ARGUSED */
-static struct ieee80211_node *
-rum_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct rum_node *rn;
-
- rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return rn != NULL ? &rn->ni : NULL;
-}
-
-static void
-rum_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
-}
-
static void
rum_scan_start(struct ieee80211com *ic)
{
diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h
index 82bb117..f46634c 100644
--- a/sys/dev/usb/wlan/if_rumvar.h
+++ b/sys/dev/usb/wlan/if_rumvar.h
@@ -67,18 +67,11 @@ struct rum_tx_data {
};
typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead;
-struct rum_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define RUM_NODE(ni) ((struct rum_node *)(ni))
-
struct rum_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb_callout amrr_ch;
- struct task amrr_task;
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 65f48e4..e69cb06 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -290,7 +290,6 @@ static const struct usb_device_id run_devs[] = {
};
MODULE_DEPEND(run, wlan, 1, 1, 1);
-MODULE_DEPEND(run, wlan_amrr, 1, 1, 1);
MODULE_DEPEND(run, usb, 1, 1, 1);
MODULE_DEPEND(run, firmware, 1, 1, 1);
@@ -350,9 +349,9 @@ static int run_key_set(struct ieee80211vap *, const struct ieee80211_key *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
static int run_key_delete(struct ieee80211vap *,
const struct ieee80211_key *);
-static void run_amrr_start(struct run_softc *, struct ieee80211_node *);
-static void run_amrr_to(void *);
-static void run_amrr_cb(void *, int);
+static void run_ratectl_start(struct run_softc *, struct ieee80211_node *);
+static void run_ratectl_to(void *);
+static void run_ratectl_cb(void *, int);
static void run_iter_func(void *, struct ieee80211_node *);
static void run_newassoc(struct ieee80211_node *, int);
static void run_rx_frame(struct run_softc *, struct mbuf *, uint32_t);
@@ -754,14 +753,12 @@ run_vap_create(struct ieee80211com *ic,
rvp->newstate = vap->iv_newstate;
vap->iv_newstate = run_newstate;
- TASK_INIT(&rvp->amrr_task, 0, run_amrr_cb, rvp);
+ TASK_INIT(&rvp->ratectl_task, 0, run_ratectl_cb, rvp);
TASK_INIT(&sc->wme_task, 0, run_wme_update_cb, ic);
TASK_INIT(&sc->usb_timeout_task, 0, run_usb_timeout_cb, sc);
- callout_init((struct callout *)&rvp->amrr_ch, 1);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ callout_init((struct callout *)&rvp->ratectl_ch, 1);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
@@ -786,16 +783,16 @@ run_vap_delete(struct ieee80211vap *vap)
sc = ifp->if_softc;
RUN_LOCK(sc);
- sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
RUN_UNLOCK(sc);
/* drain them all */
- usb_callout_drain(&sc->sc_rvp->amrr_ch);
- ieee80211_draintask(ic, &sc->sc_rvp->amrr_task);
+ usb_callout_drain(&sc->sc_rvp->ratectl_ch);
+ ieee80211_draintask(ic, &sc->sc_rvp->ratectl_task);
ieee80211_draintask(ic, &sc->wme_task);
ieee80211_draintask(ic, &sc->usb_timeout_task);
- ieee80211_amrr_cleanup(&rvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(rvp, M_80211_VAP);
sc->sc_rvp = NULL;
@@ -1632,8 +1629,8 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RUN_LOCK(sc);
- sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
- usb_callout_stop(&rvp->amrr_ch);
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
+ usb_callout_stop(&rvp->ratectl_ch);
if (ostate == IEEE80211_S_RUN) {
/* turn link LED off */
@@ -1681,7 +1678,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* enable automatic rate adaptation */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- run_amrr_start(sc, ni);
+ run_ratectl_start(sc, ni);
/* turn link LED on */
run_set_leds(sc, RT2860_LED_RADIO |
@@ -1961,12 +1958,14 @@ fail:
}
static void
-run_amrr_start(struct run_softc *sc, struct ieee80211_node *ni)
+run_ratectl_start(struct run_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct run_vap *rvp = RUN_VAP(vap);
uint32_t sta[3];
+#if 0
uint8_t wcid;
+#endif
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -1974,30 +1973,33 @@ run_amrr_start(struct run_softc *sc, struct ieee80211_node *ni)
run_read_region_1(sc, RT2860_TX_STA_CNT0,
(uint8_t *)sta, sizeof sta);
+#if 0
wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
ieee80211_amrr_node_init(&rvp->amrr, &rvp->amn[wcid], ni);
+#endif
+ ieee80211_ratectl_node_init(ni);
/* start at lowest available bit-rate, AMRR will raise */
ni->ni_txrate = 2;
/* start calibration timer */
- rvp->amrr_run = RUN_AMRR_ON;
- usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
+ rvp->ratectl_run = RUN_RATECTL_ON;
+ usb_callout_reset(&rvp->ratectl_ch, hz, run_ratectl_to, rvp);
}
static void
-run_amrr_to(void *arg)
+run_ratectl_to(void *arg)
{
struct run_vap *rvp = arg;
/* do it in a process context, so it can go sleep */
- ieee80211_runtask(rvp->vap.iv_ic, &rvp->amrr_task);
+ ieee80211_runtask(rvp->vap.iv_ic, &rvp->ratectl_task);
/* next timeout will be rescheduled in the callback task */
}
/* ARGSUSED */
static void
-run_amrr_cb(void *arg, int pending)
+run_ratectl_cb(void *arg, int pending)
{
struct run_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
@@ -2020,8 +2022,8 @@ run_amrr_cb(void *arg, int pending)
ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, rvp);
}
- if(rvp->amrr_run == RUN_AMRR_ON)
- usb_callout_reset(&rvp->amrr_ch, hz, run_amrr_to, rvp);
+ if(rvp->ratectl_run == RUN_RATECTL_ON)
+ usb_callout_reset(&rvp->ratectl_ch, hz, run_ratectl_to, rvp);
}
@@ -2033,10 +2035,11 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
struct ifnet *ifp = ic->ic_ifp;
struct run_softc *sc = ifp->if_softc;
struct ieee80211_node_table *nt = &ic->ic_sta;
- struct ieee80211_amrr_node *amn = &rvp->amn[0]; /* make compiler happy */
uint32_t sta[3], stat;
int error;
uint8_t wcid, mcs, pid;
+ struct ieee80211vap *vap = ni->ni_vap;
+ int txcnt = 0, success = 0, retrycnt = 0;
if(ic->ic_opmode != IEEE80211_M_STA)
IEEE80211_NODE_ITERATE_UNLOCK(nt);
@@ -2056,10 +2059,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
continue;
/* update per-STA AMRR stats */
- amn = &rvp->amn[wcid];
- amn->amn_txcnt++;
if (stat & RT2860_TXQ_OK) {
- amn->amn_success++;
/*
* Check if there were retries, ie if the Tx
* success rate is different from the requested
@@ -2069,16 +2069,20 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f;
pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf;
if (mcs + 1 != pid)
- amn->amn_retrycnt++;
+ retrycnt = 1;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
} else {
- amn->amn_retrycnt++;
+ retrycnt = 1;
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
ifp->if_oerrors++;
}
run_read_region_1(sc, RT2860_TX_STAT_FIFO,
(uint8_t *)&stat, sizeof stat);
}
- DPRINTFN(3, "retrycnt=%d txcnt=%d success=%d\n",
- amn->amn_retrycnt, amn->amn_txcnt, amn->amn_success);
} else {
/* read statistic counters (clear on read) and update AMRR state */
error = run_read_region_1(sc, RT2860_TX_STA_CNT0, (uint8_t *)sta,
@@ -2090,26 +2094,30 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
le32toh(sta[1]) >> 16, le32toh(sta[1]) & 0xffff,
le32toh(sta[0]) & 0xffff);
+#if 0
wcid = RUN_AID2WCID(ni == NULL ? 0 : ni->ni_associd);
amn = &rvp->amn[wcid];
+#endif
/* count failed TX as errors */
ifp->if_oerrors += le32toh(sta[0]) & 0xffff;
- amn->amn_retrycnt =
+ retrycnt =
(le32toh(sta[0]) & 0xffff) + /* failed TX count */
(le32toh(sta[1]) >> 16); /* TX retransmission count */
- amn->amn_txcnt =
- amn->amn_retrycnt +
+ txcnt =
+ retrycnt +
(le32toh(sta[1]) & 0xffff); /* successful TX count */
- amn->amn_success =
+ success =
(le32toh(sta[1]) >> 16) +
(le32toh(sta[1]) & 0xffff);
+ ieee80211_ratectl_tx_update(vap, ni, &txcnt, &success,
+ &retrycnt);
}
- ieee80211_amrr_choose(ni, amn);
+ ieee80211_ratectl_rate(ni, NULL, 0);
skip:;
RUN_UNLOCK(sc);
@@ -4447,7 +4455,7 @@ run_stop(void *arg)
RUN_LOCK_ASSERT(sc, MA_OWNED);
if(sc->sc_rvp != NULL){
- sc->sc_rvp->amrr_run = RUN_AMRR_OFF;
+ sc->sc_rvp->ratectl_run = RUN_RATECTL_OFF;
if (ic->ic_flags & IEEE80211_F_SCAN)
ieee80211_cancel_scan(&sc->sc_rvp->vap);
}
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index 87b15bc..a7f8f1f 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -107,13 +107,11 @@ struct run_node {
struct run_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct ieee80211_amrr_node amn[RT2870_WCID_MAX + 1];
- struct usb_callout amrr_ch;
- struct task amrr_task;
- uint8_t amrr_run;
-#define RUN_AMRR_ON 1
-#define RUN_AMRR_OFF 0
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
+ uint8_t ratectl_run;
+#define RUN_RATECTL_ON 1
+#define RUN_RATECTL_OFF 0
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 25fb86f..fc907bc 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -162,9 +162,6 @@ static void ural_write_multi(struct ural_softc *, uint16_t, void *,
static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
static uint8_t ural_bbp_read(struct ural_softc *, uint8_t);
static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
-static struct ieee80211_node *ural_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_newassoc(struct ieee80211_node *, int);
static void ural_scan_start(struct ieee80211com *);
static void ural_scan_end(struct ieee80211com *);
static void ural_set_channel(struct ieee80211com *);
@@ -191,10 +188,10 @@ static void ural_init(void *);
static void ural_stop(struct ural_softc *);
static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void ural_amrr_start(struct ural_softc *,
+static void ural_ratectl_start(struct ural_softc *,
struct ieee80211_node *);
-static void ural_amrr_timeout(void *);
-static void ural_amrr_task(void *, int);
+static void ural_ratectl_timeout(void *);
+static void ural_ratectl_task(void *, int);
static int ural_pause(struct ural_softc *sc, int timeout);
/*
@@ -403,7 +400,6 @@ static devclass_t ural_devclass;
DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, NULL, 0);
MODULE_DEPEND(ural, usb, 1, 1, 1);
MODULE_DEPEND(ural, wlan, 1, 1, 1);
-MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1);
static int
ural_match(device_t self)
@@ -500,9 +496,7 @@ ural_attach(device_t self)
ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_update_promisc = ural_update_promisc;
- ic->ic_newassoc = ural_newassoc;
ic->ic_raw_xmit = ural_raw_xmit;
- ic->ic_node_alloc = ural_node_alloc;
ic->ic_scan_start = ural_scan_start;
ic->ic_scan_end = ural_scan_end;
ic->ic_set_channel = ural_set_channel;
@@ -597,12 +591,10 @@ ural_vap_create(struct ieee80211com *ic,
uvp->newstate = vap->iv_newstate;
vap->iv_newstate = ural_newstate;
- usb_callout_init_mtx(&uvp->amrr_ch, &sc->sc_mtx, 0);
- TASK_INIT(&uvp->amrr_task, 0, ural_amrr_task, uvp);
- ieee80211_amrr_init(&uvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ usb_callout_init_mtx(&uvp->ratectl_ch, &sc->sc_mtx, 0);
+ TASK_INIT(&uvp->ratectl_task, 0, ural_ratectl_task, uvp);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
@@ -616,9 +608,9 @@ ural_vap_delete(struct ieee80211vap *vap)
struct ural_vap *uvp = URAL_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- usb_callout_drain(&uvp->amrr_ch);
- ieee80211_draintask(ic, &uvp->amrr_task);
- ieee80211_amrr_cleanup(&uvp->amrr);
+ usb_callout_drain(&uvp->ratectl_ch);
+ ieee80211_draintask(ic, &uvp->ratectl_task);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(uvp, M_80211_VAP);
}
@@ -703,7 +695,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_UNLOCK(ic);
RAL_LOCK(sc);
- usb_callout_stop(&uvp->amrr_ch);
+ usb_callout_stop(&uvp->ratectl_ch);
switch (nstate) {
case IEEE80211_S_INIT:
@@ -759,7 +751,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* XXX should use ic_bsschan but not valid until after newstate call below */
tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- ural_amrr_start(sc, ni);
+ ural_ratectl_start(sc, ni);
break;
@@ -1584,25 +1576,6 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff);
}
-/* ARGUSED */
-static struct ieee80211_node *
-ural_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct ural_node *un;
-
- un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return un != NULL ? &un->ni : NULL;
-}
-
-static void
-ural_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni);
-}
-
static void
ural_scan_start(struct ieee80211com *ic)
{
@@ -2231,7 +2204,7 @@ bad:
}
static void
-ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
+ural_ratectl_start(struct ural_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ural_vap *uvp = URAL_VAP(vap);
@@ -2239,23 +2212,23 @@ ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
- ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni);
+ ieee80211_ratectl_node_init(ni);
- usb_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
+ usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
}
static void
-ural_amrr_timeout(void *arg)
+ural_ratectl_timeout(void *arg)
{
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- ieee80211_runtask(ic, &uvp->amrr_task);
+ ieee80211_runtask(ic, &uvp->ratectl_task);
}
static void
-ural_amrr_task(void *arg, int pending)
+ural_ratectl_task(void *arg, int pending)
{
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
@@ -2264,6 +2237,7 @@ ural_amrr_task(void *arg, int pending)
struct ural_softc *sc = ifp->if_softc;
struct ieee80211_node *ni = vap->iv_bss;
int ok, fail;
+ int sum, retrycnt;
RAL_LOCK(sc);
/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
@@ -2272,14 +2246,15 @@ ural_amrr_task(void *arg, int pending)
ok = sc->sta[7] + /* TX ok w/o retry */
sc->sta[8]; /* TX ok w/ retry */
fail = sc->sta[9]; /* TX retry-fail count */
+ sum = ok+fail;
+ retrycnt = sc->sta[8] + fail;
- ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn,
- ok+fail, ok, sc->sta[8] + fail);
- (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn);
+ ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
- usb_callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, uvp);
+ usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
RAL_UNLOCK(sc);
}
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index 5d9c582..46dbfbd 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -71,18 +71,11 @@ struct ural_tx_data {
};
typedef STAILQ_HEAD(, ural_tx_data) ural_txdhead;
-struct ural_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define URAL_NODE(ni) ((struct ural_node *)(ni))
-
struct ural_vap {
struct ieee80211vap vap;
struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct usb_callout amrr_ch;
- struct task amrr_task;
+ struct usb_callout ratectl_ch;
+ struct task ratectl_task;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index 6604268..2b20a62 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/wlan/if_urtwvar.h>
SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
+#define URTW_DEBUG
#ifdef URTW_DEBUG
int urtw_debug = 0;
SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 724bfaa..ee143d6 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -125,8 +125,6 @@ static void zyd_vap_delete(struct ieee80211vap *);
static void zyd_tx_free(struct zyd_tx_data *, int);
static void zyd_setup_tx_list(struct zyd_softc *);
static void zyd_unsetup_tx_list(struct zyd_softc *);
-static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
void *, int, int);
@@ -163,7 +161,6 @@ static void zyd_init_locked(struct zyd_softc *);
static void zyd_init(void *);
static void zyd_stop(struct zyd_softc *);
static int zyd_loadfirmware(struct zyd_softc *);
-static void zyd_newassoc(struct ieee80211_node *, int);
static void zyd_scan_start(struct ieee80211com *);
static void zyd_scan_end(struct ieee80211com *);
static void zyd_set_channel(struct ieee80211com *);
@@ -408,9 +405,7 @@ zyd_attach(device_t dev)
ieee80211_init_channels(ic, NULL, &bands);
ieee80211_ifattach(ic, sc->sc_bssid);
- ic->ic_newassoc = zyd_newassoc;
ic->ic_raw_xmit = zyd_raw_xmit;
- ic->ic_node_alloc = zyd_node_alloc;
ic->ic_scan_start = zyd_scan_start;
ic->ic_scan_end = zyd_scan_end;
ic->ic_set_channel = zyd_set_channel;
@@ -483,10 +478,8 @@ zyd_vap_create(struct ieee80211com *ic,
zvp->newstate = vap->iv_newstate;
vap->iv_newstate = zyd_newstate;
- ieee80211_amrr_init(&zvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
+ ieee80211_ratectl_init(vap);
+ ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@@ -500,7 +493,7 @@ zyd_vap_delete(struct ieee80211vap *vap)
{
struct zyd_vap *zvp = ZYD_VAP(vap);
- ieee80211_amrr_cleanup(&zvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(zvp, M_80211_VAP);
}
@@ -518,8 +511,8 @@ zyd_tx_free(struct zyd_tx_data *data, int txerr)
data->m = NULL;
if (txerr == 0)
- ieee80211_amrr_tx_complete(&ZYD_NODE(data->ni)->amn,
- IEEE80211_AMRR_SUCCESS, 0);
+ ieee80211_ratectl_tx_complete(data->ni->ni_vap,
+ data->ni, IEEE80211_RATECTL_TX_SUCCESS, NULL, NULL);
ieee80211_free_node(data->ni);
data->ni = NULL;
}
@@ -572,17 +565,6 @@ zyd_unsetup_tx_list(struct zyd_softc *sc)
}
}
-/* ARGUSED */
-static struct ieee80211_node *
-zyd_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct zyd_node *zn;
-
- zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return (zn != NULL) ? (&zn->ni) : (NULL);
-}
-
static int
zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
@@ -669,9 +651,12 @@ zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
*/
ni = ieee80211_find_txnode(vap, retry->macaddr);
if (ni != NULL) {
- ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn,
- IEEE80211_AMRR_FAILURE,
- (int)(le16toh(retry->count) & 0xff));
+ int retrycnt =
+ (int)(le16toh(retry->count) & 0xff);
+
+ ieee80211_ratectl_tx_complete(vap, ni,
+ IEEE80211_RATECTL_TX_FAILURE,
+ &retrycnt, NULL);
ieee80211_free_node(ni);
}
if (le16toh(retry->count) & 0x100)
@@ -2498,7 +2483,7 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else {
- (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
}
@@ -2910,14 +2895,6 @@ zyd_loadfirmware(struct zyd_softc *sc)
}
static void
-zyd_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
-}
-
-static void
zyd_scan_start(struct ieee80211com *ic)
{
struct ifnet *ifp = ic->ic_ifp;
@@ -2970,4 +2947,3 @@ static devclass_t zyd_devclass;
DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, NULL, 0);
MODULE_DEPEND(zyd, usb, 1, 1, 1);
MODULE_DEPEND(zyd, wlan, 1, 1, 1);
-MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h
index 57a5e87..dd11632 100644
--- a/sys/dev/usb/wlan/if_zydreg.h
+++ b/sys/dev/usb/wlan/if_zydreg.h
@@ -1177,12 +1177,6 @@ struct zyd_rx_data {
int rssi;
};
-struct zyd_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define ZYD_NODE(ni) ((struct zyd_node *)(ni))
-
struct zyd_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint8_t wr_flags;
@@ -1243,7 +1237,6 @@ struct zyd_vap {
struct ieee80211vap vap;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
- struct ieee80211_amrr amrr;
};
#define ZYD_VAP(vap) ((struct zyd_vap *)(vap))
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 1797c2d..33c801b 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_ratectl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -173,8 +174,6 @@ static int wpi_alloc_tx_ring(struct wpi_softc *, struct wpi_tx_ring *,
int, int);
static void wpi_reset_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
static void wpi_free_tx_ring(struct wpi_softc *, struct wpi_tx_ring *);
-static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void wpi_mem_lock(struct wpi_softc *);
static void wpi_mem_unlock(struct wpi_softc *);
@@ -235,7 +234,6 @@ static void wpi_init_locked(struct wpi_softc *, int);
static void wpi_stop(struct wpi_softc *);
static void wpi_stop_locked(struct wpi_softc *);
-static void wpi_newassoc(struct ieee80211_node *, int);
static int wpi_set_txpower(struct wpi_softc *, struct ieee80211_channel *,
int);
static void wpi_calib_timeout(void *);
@@ -668,8 +666,6 @@ wpi_attach(device_t dev)
ieee80211_ifattach(ic, macaddr);
/* override default methods */
- ic->ic_node_alloc = wpi_node_alloc;
- ic->ic_newassoc = wpi_newassoc;
ic->ic_raw_xmit = wpi_raw_xmit;
ic->ic_wme.wme_update = wpi_wme_update;
ic->ic_scan_start = wpi_scan_start;
@@ -782,11 +778,7 @@ wpi_vap_create(struct ieee80211com *ic,
wvp->newstate = vap->iv_newstate;
vap->iv_newstate = wpi_newstate;
- ieee80211_amrr_init(&wvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 500 /*ms*/);
-
+ ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
@@ -798,7 +790,7 @@ wpi_vap_delete(struct ieee80211vap *vap)
{
struct wpi_vap *wvp = WPI_VAP(vap);
- ieee80211_amrr_cleanup(&wvp->amrr);
+ ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(wvp, M_80211_VAP);
}
@@ -1236,18 +1228,6 @@ wpi_resume(device_t dev)
return 0;
}
-/* ARGSUSED */
-static struct ieee80211_node *
-wpi_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct wpi_node *wn;
-
- wn = malloc(sizeof (struct wpi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
-
- return &wn->ni;
-}
-
/**
* Called by net80211 when ever there is a change to 80211 state machine
*/
@@ -1567,7 +1547,9 @@ wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc)
struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3];
struct wpi_tx_data *txdata = &ring->data[desc->idx];
struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1);
- struct wpi_node *wn = (struct wpi_node *)txdata->ni;
+ struct ieee80211_node *ni = txdata->ni;
+ struct ieee80211vap *vap = ni->ni_vap;
+ int retrycnt = 0;
DPRINTFN(WPI_DEBUG_TX, ("tx done: qid=%d idx=%d retries=%d nkill=%d "
"rate=%x duration=%d status=%x\n", desc->qid, desc->idx,
@@ -1580,11 +1562,12 @@ wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc)
* the lowest available bit-rate.
* XXX frames w/o ACK shouldn't be used either
*/
- wn->amn.amn_txcnt++;
if (stat->ntries > 0) {
DPRINTFN(WPI_DEBUG_TX, ("%d retries\n", stat->ntries));
- wn->amn.amn_retrycnt++;
+ retrycnt = 1;
}
+ ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS,
+ &retrycnt, NULL);
/* XXX oerrors should only count errors !maxtries */
if ((le32toh(stat->status) & 0xff) != 1)
@@ -1919,7 +1902,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = tp->ucastrate;
} else {
- (void) ieee80211_amrr_choose(ni, &WPI_NODE(ni)->amn);
+ (void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
}
tx->rate = wpi_plcp_signal(rate);
@@ -3212,15 +3195,6 @@ wpi_stop(struct wpi_softc *sc)
}
static void
-wpi_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct wpi_vap *wvp = WPI_VAP(vap);
-
- ieee80211_amrr_node_init(&wvp->amrr, &WPI_NODE(ni)->amn, ni);
-}
-
-static void
wpi_calib_timeout(void *arg)
{
struct wpi_softc *sc = arg;
@@ -3706,4 +3680,3 @@ static const char *wpi_cmd_str(int cmd)
MODULE_DEPEND(wpi, pci, 1, 1, 1);
MODULE_DEPEND(wpi, wlan, 1, 1, 1);
MODULE_DEPEND(wpi, firmware, 1, 1, 1);
-MODULE_DEPEND(wpi, wlan_amrr, 1, 1, 1);
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index 811624b..00579b3e 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -106,12 +106,6 @@ struct wpi_amrr {
int recovery;
};
-struct wpi_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define WPI_NODE(ni) ((struct wpi_node *)(ni))
-
struct wpi_power_sample {
uint8_t index;
int8_t power;
@@ -127,7 +121,6 @@ struct wpi_power_group {
struct wpi_vap {
struct ieee80211vap vap;
- struct ieee80211_amrr amrr;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
diff --git a/sys/modules/wlan/Makefile b/sys/modules/wlan/Makefile
index 07233c6..34a4f0d 100644
--- a/sys/modules/wlan/Makefile
+++ b/sys/modules/wlan/Makefile
@@ -8,7 +8,8 @@ SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c \
ieee80211_freebsd.c ieee80211_input.c ieee80211_ioctl.c \
ieee80211_mesh.c ieee80211_node.c ieee80211_output.c ieee80211_phy.c \
ieee80211_power.c ieee80211_proto.c ieee80211_scan.c \
- ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_regdomain.c \
+ ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_ratectl.c \
+ ieee80211_regdomain.c \
ieee80211_ht.c ieee80211_hwmp.c ieee80211_adhoc.c ieee80211_hostap.c \
ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h opt_ipx.h opt_wlan.h \
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 8a50bc0..3d5669c 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#ifdef IEEE80211_SUPPORT_SUPERG
#include <net80211/ieee80211_superg.h>
#endif
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -486,6 +487,8 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ieee80211_regdomain_vattach(vap);
ieee80211_radiotap_vattach(vap);
+ ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR);
+
return 0;
}
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
index a759e64..e8eed09 100644
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -1,6 +1,7 @@
/* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */
/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* Copyright (c) 2006
* Damien Bergamini <damien.bergamini@free.fr>
*
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_amrr.h>
+#include <net80211/ieee80211_ratectl.h>
#define is_success(amn) \
((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
@@ -54,15 +56,45 @@ __FBSDID("$FreeBSD$");
#define is_enough(amn) \
((amn)->amn_txcnt > 10)
-static void amrr_sysctlattach(struct ieee80211_amrr *amrr,
- struct sysctl_ctx_list *ctx, struct sysctl_oid *tree);
+static void amrr_setinterval(const struct ieee80211vap *, int);
+static void amrr_init(struct ieee80211vap *);
+static void amrr_deinit(struct ieee80211vap *);
+static void amrr_node_init(struct ieee80211_node *);
+static void amrr_node_deinit(struct ieee80211_node *);
+static int amrr_update(struct ieee80211_amrr *,
+ struct ieee80211_amrr_node *, struct ieee80211_node *);
+static int amrr_rate(struct ieee80211_node *, void *, uint32_t);
+static void amrr_tx_complete(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+static void amrr_tx_update(const struct ieee80211vap *vap,
+ const struct ieee80211_node *, void *, void *, void *);
+static void amrr_sysctlattach(struct ieee80211vap *,
+ struct sysctl_ctx_list *, struct sysctl_oid *);
/* number of references from net80211 layer */
static int nrefs = 0;
-void
-ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs)
+static const struct ieee80211_ratectl amrr = {
+ .ir_name = "amrr",
+ .ir_attach = NULL,
+ .ir_detach = NULL,
+ .ir_init = amrr_init,
+ .ir_deinit = amrr_deinit,
+ .ir_node_init = amrr_node_init,
+ .ir_node_deinit = amrr_node_deinit,
+ .ir_rate = amrr_rate,
+ .ir_tx_complete = amrr_tx_complete,
+ .ir_tx_update = amrr_tx_update,
+ .ir_setinterval = amrr_setinterval,
+};
+IEEE80211_RATECTL_MODULE(amrr, 1);
+IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr);
+
+static void
+amrr_setinterval(const struct ieee80211vap *vap, int msecs)
{
+ struct ieee80211_amrr *amrr = vap->iv_rs;
int t;
if (msecs < 100)
@@ -71,29 +103,42 @@ ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs)
amrr->amrr_interval = (t < 1) ? 1 : t;
}
-void
-ieee80211_amrr_init(struct ieee80211_amrr *amrr,
- struct ieee80211vap *vap, int amin, int amax, int interval)
+static void
+amrr_init(struct ieee80211vap *vap)
{
- /* XXX bounds check? */
- amrr->amrr_min_success_threshold = amin;
- amrr->amrr_max_success_threshold = amax;
- ieee80211_amrr_setinterval(amrr, interval);
+ struct ieee80211_amrr *amrr;
+
+ KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
- amrr_sysctlattach(amrr, vap->iv_sysctl, vap->iv_oid);
+ vap->iv_rs = malloc(sizeof(struct ieee80211_amrr), M_80211_RATECTL,
+ M_WAITOK|M_ZERO);
+ amrr = vap->iv_rs;
+ amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD;
+ amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD;
+ amrr_setinterval(vap, 500 /* ms */);
+ amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid);
}
-void
-ieee80211_amrr_cleanup(struct ieee80211_amrr *amrr)
+static void
+amrr_deinit(struct ieee80211vap *vap)
{
+ free(vap->iv_rs, M_80211_RATECTL);
}
-void
-ieee80211_amrr_node_init(struct ieee80211_amrr *amrr,
- struct ieee80211_amrr_node *amn, struct ieee80211_node *ni)
+static void
+amrr_node_init(struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs = &ni->ni_rates;
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_amrr *amrr = vap->iv_rs;
+ struct ieee80211_amrr_node *amn;
+ KASSERT(ni->ni_rctls == NULL, ("%s: ni_rctls already initialized",
+ __func__));
+
+ ni->ni_rctls = malloc(sizeof(struct ieee80211_amrr_node),
+ M_80211_RATECTL, M_WAITOK|M_ZERO);
+ amn = ni->ni_rctls;
amn->amn_amrr = amrr;
amn->amn_success = 0;
amn->amn_recovery = 0;
@@ -112,6 +157,12 @@ ieee80211_amrr_node_init(struct ieee80211_amrr *amrr,
"AMRR initial rate %d", ni->ni_txrate);
}
+static void
+amrr_node_deinit(struct ieee80211_node *ni)
+{
+ free(ni->ni_rctls, M_80211_RATECTL);
+}
+
static int
amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
struct ieee80211_node *ni)
@@ -168,10 +219,10 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
* Update our internal state if it's been long enough.
* If the rate changes we also update ni_txrate to match.
*/
-int
-ieee80211_amrr_choose(struct ieee80211_node *ni,
- struct ieee80211_amrr_node *amn)
+static int
+amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused)
{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
struct ieee80211_amrr *amrr = amn->amn_amrr;
int rix;
@@ -189,27 +240,65 @@ ieee80211_amrr_choose(struct ieee80211_node *ni,
return rix;
}
+/*
+ * Update statistics with tx complete status. Ok is non-zero
+ * if the packet is known to be ACK'd. Retries has the number
+ * retransmissions (i.e. xmit attempts - 1).
+ */
+static void
+amrr_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int ok,
+ void *arg1, void *arg2 __unused)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ int retries = *(int *)arg1;
+
+ amn->amn_txcnt++;
+ if (ok)
+ amn->amn_success++;
+ amn->amn_retrycnt += retries;
+}
+
+/*
+ * Set tx count/retry statistics explicitly. Intended for
+ * drivers that poll the device for statistics maintained
+ * in the device.
+ */
+static void
+amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni,
+ void *arg1, void *arg2, void *arg3)
+{
+ struct ieee80211_amrr_node *amn = ni->ni_rctls;
+ int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3;
+
+ amn->amn_txcnt = txcnt;
+ amn->amn_success = success;
+ amn->amn_retrycnt = retrycnt;
+}
+
static int
amrr_sysctl_interval(SYSCTL_HANDLER_ARGS)
{
- struct ieee80211_amrr *amrr = arg1;
+ struct ieee80211vap *vap = arg1;
+ struct ieee80211_amrr *amrr = vap->iv_rs;
int msecs = ticks_to_msecs(amrr->amrr_interval);
int error;
error = sysctl_handle_int(oidp, &msecs, 0, req);
if (error || !req->newptr)
return error;
- ieee80211_amrr_setinterval(amrr, msecs);
+ amrr_setinterval(vap, msecs);
return 0;
}
static void
-amrr_sysctlattach(struct ieee80211_amrr *amrr,
+amrr_sysctlattach(struct ieee80211vap *vap,
struct sysctl_ctx_list *ctx, struct sysctl_oid *tree)
{
+ struct ieee80211_amrr *amrr = vap->iv_rs;
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, amrr,
+ "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap,
0, amrr_sysctl_interval, "I", "amrr operation interval (ms)");
/* XXX bounds check values */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
@@ -219,8 +308,3 @@ amrr_sysctlattach(struct ieee80211_amrr *amrr,
"amrr_min_sucess_threshold", CTLFLAG_RW,
&amrr->amrr_min_success_threshold, 0, "");
}
-
-/*
- * Module glue.
- */
-IEEE80211_RATE_MODULE(amrr, 1);
diff --git a/sys/net80211/ieee80211_amrr.h b/sys/net80211/ieee80211_amrr.h
index c03f699..ec67bdf 100644
--- a/sys/net80211/ieee80211_amrr.h
+++ b/sys/net80211/ieee80211_amrr.h
@@ -58,44 +58,4 @@ struct ieee80211_amrr_node {
u_int amn_retrycnt;
};
-void ieee80211_amrr_init(struct ieee80211_amrr *, struct ieee80211vap *,
- int, int, int);
-void ieee80211_amrr_cleanup(struct ieee80211_amrr *);
-void ieee80211_amrr_setinterval(struct ieee80211_amrr *, int);
-void ieee80211_amrr_node_init(struct ieee80211_amrr *,
- struct ieee80211_amrr_node *, struct ieee80211_node *);
-int ieee80211_amrr_choose(struct ieee80211_node *,
- struct ieee80211_amrr_node *);
-
-#define IEEE80211_AMRR_SUCCESS 1
-#define IEEE80211_AMRR_FAILURE 0
-
-/*
- * Update statistics with tx complete status. Ok is non-zero
- * if the packet is known to be ACK'd. Retries has the number
- * retransmissions (i.e. xmit attempts - 1).
- */
-static __inline void
-ieee80211_amrr_tx_complete(struct ieee80211_amrr_node *amn,
- int ok, int retries)
-{
- amn->amn_txcnt++;
- if (ok)
- amn->amn_success++;
- amn->amn_retrycnt += retries;
-}
-
-/*
- * Set tx count/retry statistics explicitly. Intended for
- * drivers that poll the device for statistics maintained
- * in the device.
- */
-static __inline void
-ieee80211_amrr_tx_update(struct ieee80211_amrr_node *amn,
- int txcnt, int success, int retrycnt)
-{
- amn->amn_txcnt = txcnt;
- amn->amn_success = success;
- amn->amn_retrycnt = retrycnt;
-}
#endif /* _NET80211_IEEE80211_AMRR_H_ */
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 6a8875a..861ac51 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -386,14 +386,19 @@ TEXT_SET(auth_set, name##_modevent)
/*
* Rate control modules provide tx rate control support.
*/
-#define IEEE80211_RATE_MODULE(alg, version) \
-_IEEE80211_POLICY_MODULE(rate, alg, version); \
+#define IEEE80211_RATECTL_MODULE(alg, version) \
+ _IEEE80211_POLICY_MODULE(ratectl, alg, version); \
+
+#define IEEE80211_RATECTL_ALG(name, alg, v) \
static void \
alg##_modevent(int type) \
{ \
- /* XXX nothing to do until the rate control framework arrives */\
+ if (type == MOD_LOAD) \
+ ieee80211_ratectl_register(alg, &v); \
+ else \
+ ieee80211_ratectl_unregister(alg); \
} \
-TEXT_SET(rate##_set, alg##_modevent)
+TEXT_SET(ratectl##_set, alg##_modevent)
struct ieee80211req;
typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index bccb6d5..b17f42f 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <net80211/ieee80211_wds.h>
#include <net80211/ieee80211_mesh.h>
+#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@@ -1035,6 +1036,7 @@ node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
+ ieee80211_ratectl_node_deinit(ni);
ic->ic_node_cleanup(ni);
ieee80211_ies_cleanup(&ni->ni_ies);
ieee80211_psq_cleanup(&ni->ni_psq);
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 63b2355..01bb2cf 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -218,7 +218,8 @@ struct ieee80211_node {
struct ieee80211_nodestats ni_stats; /* per-node statistics */
struct ieee80211vap *ni_wdsvap; /* associated WDS vap */
- uint64_t ni_spare[4];
+ void *ni_rctls; /* private ratectl state */
+ uint64_t ni_spare[3];
};
MALLOC_DECLARE(M_80211_NODE);
MALLOC_DECLARE(M_80211_NODE_IE);
diff --git a/sys/net80211/ieee80211_ratectl.c b/sys/net80211/ieee80211_ratectl.c
new file mode 100644
index 0000000..2e8eb7e
--- /dev/null
+++ b/sys/net80211/ieee80211_ratectl.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_ratectl.h>
+
+static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX];
+
+MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control");
+
+void
+ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ ratectls[type] = ratectl;
+}
+
+void
+ieee80211_ratectl_unregister(int type)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ ratectls[type] = NULL;
+}
+
+void
+ieee80211_ratectl_set(struct ieee80211vap *vap, int type)
+{
+ if (type >= IEEE80211_RATECTL_MAX)
+ return;
+ vap->iv_rate = ratectls[type];
+}
diff --git a/sys/net80211/ieee80211_ratectl.h b/sys/net80211/ieee80211_ratectl.h
new file mode 100644
index 0000000..1093df4
--- /dev/null
+++ b/sys/net80211/ieee80211_ratectl.h
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+enum ieee80211_ratealgs {
+ IEEE80211_RATECTL_AMRR = 0,
+ IEEE80211_RATECTL_RSSADAPT = 1,
+ IEEE80211_RATECTL_ONOE = 2,
+ IEEE80211_RATECTL_SAMPLE = 3,
+ IEEE80211_RATECTL_MAX
+};
+
+#define IEEE80211_RATECTL_TX_SUCCESS 0
+#define IEEE80211_RATECTL_TX_FAILURE 1
+
+struct ieee80211_ratectl {
+ const char *ir_name;
+ int (*ir_attach)(const struct ieee80211vap *);
+ void (*ir_detach)(const struct ieee80211vap *);
+ void (*ir_init)(struct ieee80211vap *);
+ void (*ir_deinit)(struct ieee80211vap *);
+ void (*ir_node_init)(struct ieee80211_node *);
+ void (*ir_node_deinit)(struct ieee80211_node *);
+ int (*ir_rate)(struct ieee80211_node *, void *, uint32_t);
+ void (*ir_tx_complete)(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+ void (*ir_tx_update)(const struct ieee80211vap *,
+ const struct ieee80211_node *,
+ void *, void *, void *);
+ void (*ir_setinterval)(const struct ieee80211vap *, int);
+};
+
+void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *);
+void ieee80211_ratectl_unregister(int);
+void ieee80211_ratectl_set(struct ieee80211vap *, int);
+
+MALLOC_DECLARE(M_80211_RATECTL);
+
+static void __inline
+ieee80211_ratectl_init(struct ieee80211vap *vap)
+{
+ vap->iv_rate->ir_init(vap);
+}
+
+static void __inline
+ieee80211_ratectl_deinit(struct ieee80211vap *vap)
+{
+ vap->iv_rate->ir_deinit(vap);
+}
+
+static void __inline
+ieee80211_ratectl_node_init(struct ieee80211_node *ni)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ vap->iv_rate->ir_node_init(ni);
+}
+
+static void __inline
+ieee80211_ratectl_node_deinit(struct ieee80211_node *ni)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ vap->iv_rate->ir_node_deinit(ni);
+}
+
+static int __inline
+ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ return vap->iv_rate->ir_rate(ni, arg, iarg);
+}
+
+static void __inline
+ieee80211_ratectl_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int status, void *arg1, void *arg2)
+{
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ vap->iv_rate->ir_tx_complete(vap, ni, status, arg1, arg2);
+}
+
+static void __inline
+ieee80211_ratectl_tx_update(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, void *arg1, void *arg2, void *arg3)
+{
+ if (vap->iv_rate->ir_tx_update == NULL)
+ return;
+ if (ni->ni_rctls == NULL) /* ratectl not setup */
+ return;
+ vap->iv_rate->ir_tx_update(vap, ni, arg1, arg2, arg3);
+}
+
+static void __inline
+ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs)
+{
+ if (vap->iv_rate->ir_setinterval == NULL)
+ return;
+ vap->iv_rate->ir_setinterval(vap, msecs);
+}
diff --git a/sys/net80211/ieee80211_rssadapt.c b/sys/net80211/ieee80211_rssadapt.c
index f1fc409..e90ad57 100644
--- a/sys/net80211/ieee80211_rssadapt.c
+++ b/sys/net80211/ieee80211_rssadapt.c
@@ -1,6 +1,7 @@
/* $FreeBSD$ */
/* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */
/*-
+ * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
@@ -42,6 +43,7 @@
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_rssadapt.h>
+#include <net80211/ieee80211_ratectl.h>
struct rssadapt_expavgctl {
/* RSS threshold decay. */
@@ -71,15 +73,45 @@ static struct rssadapt_expavgctl master_expavgctl = {
(parm##_denom - parm##_old) * (new)) / \
parm##_denom)
-static void rssadapt_sysctlattach(struct ieee80211_rssadapt *rs,
- struct sysctl_ctx_list *ctx, struct sysctl_oid *tree);
+static void rssadapt_setinterval(const struct ieee80211vap *, int);
+static void rssadapt_init(struct ieee80211vap *);
+static void rssadapt_deinit(struct ieee80211vap *);
+static void rssadapt_updatestats(struct ieee80211_rssadapt_node *);
+static void rssadapt_node_init(struct ieee80211_node *);
+static void rssadapt_node_deinit(struct ieee80211_node *);
+static int rssadapt_rate(struct ieee80211_node *, void *, uint32_t);
+static void rssadapt_lower_rate(struct ieee80211_rssadapt_node *, int, int);
+static void rssadapt_raise_rate(struct ieee80211_rssadapt_node *,
+ int, int);
+static void rssadapt_tx_complete(const struct ieee80211vap *,
+ const struct ieee80211_node *, int,
+ void *, void *);
+static void rssadapt_sysctlattach(struct ieee80211vap *,
+ struct sysctl_ctx_list *, struct sysctl_oid *);
/* number of references from net80211 layer */
static int nrefs = 0;
-void
-ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs)
+static const struct ieee80211_ratectl rssadapt = {
+ .ir_name = "rssadapt",
+ .ir_attach = NULL,
+ .ir_detach = NULL,
+ .ir_init = rssadapt_init,
+ .ir_deinit = rssadapt_deinit,
+ .ir_node_init = rssadapt_node_init,
+ .ir_node_deinit = rssadapt_node_deinit,
+ .ir_rate = rssadapt_rate,
+ .ir_tx_complete = rssadapt_tx_complete,
+ .ir_tx_update = NULL,
+ .ir_setinterval = rssadapt_setinterval,
+};
+IEEE80211_RATECTL_MODULE(rssadapt, 1);
+IEEE80211_RATECTL_ALG(rssadapt, IEEE80211_RATECTL_RSSADAPT, rssadapt);
+
+static void
+rssadapt_setinterval(const struct ieee80211vap *vap, int msecs)
{
+ struct ieee80211_rssadapt *rs = vap->iv_rs;
int t;
if (msecs < 100)
@@ -88,18 +120,26 @@ ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs)
rs->interval = (t < 1) ? 1 : t;
}
-void
-ieee80211_rssadapt_init(struct ieee80211_rssadapt *rs, struct ieee80211vap *vap, int interval)
+static void
+rssadapt_init(struct ieee80211vap *vap)
{
+ struct ieee80211_rssadapt *rs;
+
+ KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized",
+ __func__));
+
+ rs = malloc(sizeof(struct ieee80211_rssadapt), M_80211_RATECTL,
+ M_WAITOK|M_ZERO);
+ vap->iv_rs = rs;
rs->vap = vap;
- ieee80211_rssadapt_setinterval(rs, interval);
-
- rssadapt_sysctlattach(rs, vap->iv_sysctl, vap->iv_oid);
+ rssadapt_setinterval(vap, 500 /* msecs */);
+ rssadapt_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid);
}
-void
-ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *rs)
+static void
+rssadapt_deinit(struct ieee80211vap *vap)
{
+ free(vap->iv_rs, M_80211_RATECTL);
}
static void
@@ -118,12 +158,16 @@ rssadapt_updatestats(struct ieee80211_rssadapt_node *ra)
ra->ra_raise_interval = msecs_to_ticks(interval);
}
-void
-ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa,
- struct ieee80211_rssadapt_node *ra, struct ieee80211_node *ni)
+static void
+rssadapt_node_init(struct ieee80211_node *ni)
{
+ struct ieee80211_rssadapt_node *ra;
+ struct ieee80211_rssadapt *rsa = ni->ni_vap->iv_rs;
const struct ieee80211_rateset *rs = &ni->ni_rates;
+ ra = malloc(sizeof(struct ieee80211_rssadapt_node), M_80211_RATECTL,
+ M_WAITOK|M_ZERO);
+ ni->ni_rctls = ra;
ra->ra_rs = rsa;
ra->ra_rates = *rs;
rssadapt_updatestats(ra);
@@ -140,6 +184,13 @@ ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa,
"RSSADAPT initial rate %d", ni->ni_txrate);
}
+static void
+rssadapt_node_deinit(struct ieee80211_node *ni)
+{
+
+ free(ni->ni_rctls, M_80211_RATECTL);
+}
+
static __inline int
bucket(int pktlen)
{
@@ -155,10 +206,11 @@ bucket(int pktlen)
return thridx;
}
-int
-ieee80211_rssadapt_choose(struct ieee80211_node *ni,
- struct ieee80211_rssadapt_node *ra, u_int pktlen)
+static int
+rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg)
{
+ struct ieee80211_rssadapt_node *ra = ni->ni_rctls;
+ u_int pktlen = iarg;
const struct ieee80211_rateset *rs = &ra->ra_rates;
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
int rix, rssi;
@@ -193,9 +245,8 @@ ieee80211_rssadapt_choose(struct ieee80211_node *ni,
* raise the RSS threshold for transmitting packets of similar length at
* the same data rate.
*/
-void
-ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra,
- int pktlen, int rssi)
+static void
+rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi)
{
uint16_t last_thr;
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
@@ -214,9 +265,8 @@ ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra,
last_thr, (*thrs)[rix], rssi);
}
-void
-ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra,
- int pktlen, int rssi)
+static void
+rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi)
{
uint16_t (*thrs)[IEEE80211_RATE_SIZE];
uint16_t newthr, oldthr;
@@ -243,31 +293,45 @@ ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra,
}
}
+static void
+rssadapt_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int success, void *arg1, void *arg2)
+{
+ struct ieee80211_rssadapt_node *ra = ni->ni_rctls;
+ int pktlen = *(int *)arg1, rssi = *(int *)arg2;
+
+ if (success) {
+ ra->ra_nok++;
+ if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates &&
+ (ticks - ra->ra_last_raise) >= ra->ra_raise_interval)
+ rssadapt_raise_rate(ra, pktlen, rssi);
+ } else {
+ ra->ra_nfail++;
+ rssadapt_lower_rate(ra, pktlen, rssi);
+ }
+}
+
static int
rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS)
{
- struct ieee80211_rssadapt *rs = arg1;
+ struct ieee80211vap *vap = arg1;
+ struct ieee80211_rssadapt *rs = vap->iv_rs;
int msecs = ticks_to_msecs(rs->interval);
int error;
error = sysctl_handle_int(oidp, &msecs, 0, req);
if (error || !req->newptr)
return error;
- ieee80211_rssadapt_setinterval(rs, msecs);
+ rssadapt_setinterval(vap, msecs);
return 0;
}
static void
-rssadapt_sysctlattach(struct ieee80211_rssadapt *rs,
+rssadapt_sysctlattach(struct ieee80211vap *vap,
struct sysctl_ctx_list *ctx, struct sysctl_oid *tree)
{
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
- "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, rs,
+ "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap,
0, rssadapt_sysctl_interval, "I", "rssadapt operation interval (ms)");
}
-
-/*
- * Module glue.
- */
-IEEE80211_RATE_MODULE(rssadapt, 1);
diff --git a/sys/net80211/ieee80211_rssadapt.h b/sys/net80211/ieee80211_rssadapt.h
index b454f43..ee1d2d9 100644
--- a/sys/net80211/ieee80211_rssadapt.h
+++ b/sys/net80211/ieee80211_rssadapt.h
@@ -43,7 +43,7 @@
#define IEEE80211_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */
struct ieee80211_rssadapt {
- struct ieee80211vap *vap;
+ const struct ieee80211vap *vap;
int interval; /* update interval (ticks) */
};
@@ -66,36 +66,6 @@ struct ieee80211_rssadapt_node {
[IEEE80211_RATE_SIZE];
};
-void ieee80211_rssadapt_init(struct ieee80211_rssadapt *,
- struct ieee80211vap *, int);
-void ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *);
-void ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *, int);
-void ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *,
- struct ieee80211_rssadapt_node *, struct ieee80211_node *);
-int ieee80211_rssadapt_choose(struct ieee80211_node *,
- struct ieee80211_rssadapt_node *, u_int);
-
-/* NB: these are public only for the inline below */
-void ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *,
- int pktlen, int rssi);
-void ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *,
- int pktlen, int rssi);
-
#define IEEE80211_RSSADAPT_SUCCESS 1
#define IEEE80211_RSSADAPT_FAILURE 0
-
-static __inline void
-ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *ra,
- int success, int pktlen, int rssi)
-{
- if (success) {
- ra->ra_nok++;
- if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates &&
- (ticks - ra->ra_last_raise) >= ra->ra_raise_interval)
- ieee80211_rssadapt_raise_rate(ra, pktlen, rssi);
- } else {
- ra->ra_nfail++;
- ieee80211_rssadapt_lower_rate(ra, pktlen, rssi);
- }
-}
#endif /* _NET80211_IEEE80211_RSSADAPT_H_ */
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 3fa0aec..ff3694f 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -436,6 +436,9 @@ struct ieee80211vap {
const struct ieee80211_aclator *iv_acl; /* acl glue */
void *iv_as; /* private aclator state */
+ const struct ieee80211_ratectl *iv_rate;
+ void *iv_rs; /* private ratectl state */
+
struct ieee80211_tdma_state *iv_tdma; /* tdma state */
struct ieee80211_mesh_state *iv_mesh; /* MBSS state */
struct ieee80211_hwmp_state *iv_hwmp; /* HWMP state */
@@ -471,7 +474,7 @@ struct ieee80211vap {
/* 802.3 output method for raw frame xmit */
int (*iv_output)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct route *);
- uint64_t iv_spare[8];
+ uint64_t iv_spare[6];
};
MALLOC_DECLARE(M_80211_VAP);
OpenPOWER on IntegriCloud