summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-10-22 11:53:22 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-10-22 11:53:22 +0000
commit2a92d599291d5de3fa88b9ed157b5c16f14cde61 (patch)
tree8972db5641b0902ae04eecbc16f25f431afe5b14 /sys/dev/usb
parentfbdc97ffa6fcba099e2b07123c1948d93e441d98 (diff)
do per-node rate control.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/if_zyd.c85
-rw-r--r--sys/dev/usb/if_zydreg.h9
2 files changed, 67 insertions, 27 deletions
diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c
index 0f4c1f94d4b..cda864ad987 100644
--- a/sys/dev/usb/if_zyd.c
+++ b/sys/dev/usb/if_zyd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_zyd.c,v 1.29 2006/10/21 18:32:20 deraadt Exp $ */
+/* $OpenBSD: if_zyd.c,v 1.30 2006/10/22 11:53:21 damien Exp $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
@@ -123,6 +123,7 @@ int zyd_alloc_tx_list(struct zyd_softc *);
void zyd_free_tx_list(struct zyd_softc *);
int zyd_alloc_rx_list(struct zyd_softc *);
void zyd_free_rx_list(struct zyd_softc *);
+struct ieee80211_node *zyd_node_alloc(struct ieee80211com *);
int zyd_media_change(struct ifnet *);
void zyd_next_scan(void *);
void zyd_task(void *);
@@ -150,8 +151,7 @@ int zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
int zyd_set_bssid(struct zyd_softc *, const uint8_t *);
int zyd_switch_radio(struct zyd_softc *, int);
int zyd_set_rxfilter(struct zyd_softc *);
-void zyd_set_chan(struct zyd_softc *,
- struct ieee80211_channel *);
+void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
int zyd_set_beacon_interval(struct zyd_softc *, int);
uint8_t zyd_plcp_signal(int);
void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
@@ -166,8 +166,10 @@ int zyd_ioctl(struct ifnet *, u_long, caddr_t);
int zyd_init(struct ifnet *);
void zyd_stop(struct ifnet *, int);
int zyd_loadfirmware(struct zyd_softc *, u_char *, size_t);
-void zyd_amrr_start(struct zyd_softc *, struct ieee80211_node *);
+void zyd_iter_func(void *, struct ieee80211_node *);
void zyd_amrr_timeout(void *);
+void zyd_newassoc(struct ieee80211com *, struct ieee80211_node *,
+ int);
/*
* Supported rates for 802.11b/g modes (in 500Kbps unit).
@@ -342,6 +344,8 @@ zyd_complete_attach(struct zyd_softc *sc)
if_attach(ifp);
ieee80211_ifattach(ifp);
+ ic->ic_node_alloc = zyd_node_alloc;
+ ic->ic_newassoc = zyd_newassoc;
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
@@ -584,6 +588,17 @@ zyd_free_rx_list(struct zyd_softc *sc)
}
}
+struct ieee80211_node *
+zyd_node_alloc(struct ieee80211com *ic)
+{
+ struct zyd_node *zn;
+
+ zn = malloc(sizeof (struct zyd_node), M_DEVBUF, M_NOWAIT);
+ if (zn != NULL)
+ bzero(zn, sizeof (struct zyd_node));
+ return (struct ieee80211_node *)zn;
+}
+
int
zyd_media_change(struct ifnet *ifp)
{
@@ -648,10 +663,14 @@ zyd_task(void *arg)
if (ic->ic_opmode != IEEE80211_M_MONITOR)
zyd_set_bssid(sc, ni->ni_bssid);
- /* enable automatic rate control in STA mode */
- if (ic->ic_opmode == IEEE80211_M_STA &&
- ic->ic_fixed_rate == -1)
- zyd_amrr_start(sc, ni);
+ if (ic->ic_opmode == IEEE80211_M_STA) {
+ /* fake a join to init the tx rate */
+ zyd_newassoc(ic, ni, 1);
+ }
+
+ /* start automatic rate control timer */
+ if (ic->ic_fixed_rate == -1)
+ timeout_add(&sc->amrr_to, hz);
break;
}
@@ -1237,8 +1256,7 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
struct ieee80211_node *ni;
DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
- letoh16(retry->rate),
- ether_sprintf((u_char *)retry->macaddr),
+ letoh16(retry->rate), ether_sprintf(retry->macaddr),
letoh16(retry->count) & 0xff, letoh16(retry->count)));
/*
@@ -1253,7 +1271,8 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
} else
ni = ic->ic_bss;
- sc->amn.amn_retrycnt++;
+ ((struct zyd_node *)ni)->amn.amn_retrycnt++;
+
if (letoh16(retry->count) & 0x100)
ifp->if_oerrors++; /* too many retries */
@@ -1454,12 +1473,14 @@ zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
s = splnet();
+ /* update rate control statistics */
+ ((struct zyd_node *)data->ni)->amn.amn_txcnt++;
+
ieee80211_release_node(ic, data->ni);
data->ni = NULL;
sc->tx_queued--;
ifp->if_opackets++;
- sc->amn.amn_txcnt++;
sc->tx_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1898,30 +1919,46 @@ zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size)
}
void
-zyd_amrr_start(struct zyd_softc *sc, struct ieee80211_node *ni)
+zyd_iter_func(void *arg, struct ieee80211_node *ni)
{
- int i;
-
- ieee80211_amrr_node_init(&sc->amrr, &sc->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;
+ struct zyd_softc *sc = arg;
+ struct zyd_node *zn = (struct zyd_node *)ni;
- timeout_add(&sc->amrr_to, hz);
+ ieee80211_amrr_choose(&sc->amrr, ni, &zn->amn);
}
void
zyd_amrr_timeout(void *arg)
{
struct zyd_softc *sc = arg;
+ struct ieee80211com *ic = &sc->sc_ic;
+ int s;
+
+ s = splnet();
+ if (ic->ic_opmode == IEEE80211_M_STA)
+ zyd_iter_func(sc, ic->ic_bss);
+ else
+ ieee80211_iterate_nodes(ic, zyd_iter_func, sc);
+ splx(s);
- ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn);
timeout_add(&sc->amrr_to, hz);
}
+void
+zyd_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
+{
+ struct zyd_softc *sc = ic->ic_softc;
+ int i;
+
+ ieee80211_amrr_node_init(&sc->amrr, &((struct zyd_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
zyd_activate(device_ptr_t self, enum devact act)
{
diff --git a/sys/dev/usb/if_zydreg.h b/sys/dev/usb/if_zydreg.h
index dc0b40181bc..e84e2cfab47 100644
--- a/sys/dev/usb/if_zydreg.h
+++ b/sys/dev/usb/if_zydreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_zydreg.h,v 1.11 2006/10/21 18:18:50 damien Exp $ */
+/* $OpenBSD: if_zydreg.h,v 1.12 2006/10/22 11:53:21 damien Exp $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
@@ -797,6 +797,11 @@ struct zyd_rx_data {
const uint8_t *buf;
};
+struct zyd_node {
+ struct ieee80211_node ni; /* must be the first */
+ struct ieee80211_amrr_node amn;
+};
+
struct zyd_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint8_t wr_flags;
@@ -857,8 +862,6 @@ struct zyd_softc {
struct timeout amrr_to;
struct ieee80211_amrr amrr;
- struct ieee80211_amrr_node amn;
-
void *odata;
int olen;