Module Name: src
Committed By: jmcneill
Date: Mon Feb 21 23:50:42 UTC 2011
Modified Files:
src/sys/dev/usb: if_rum.c if_rumreg.h if_rumvar.h
Log Message:
sync driver with openbsd
To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/dev/usb/if_rum.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/usb/if_rumreg.h
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/usb/if_rumvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/if_rum.c
diff -u src/sys/dev/usb/if_rum.c:1.34 src/sys/dev/usb/if_rum.c:1.35
--- src/sys/dev/usb/if_rum.c:1.34 Sun Feb 13 05:51:24 2011
+++ src/sys/dev/usb/if_rum.c Mon Feb 21 23:50:42 2011
@@ -1,5 +1,5 @@
/* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */
-/* $NetBSD: if_rum.c,v 1.34 2011/02/13 05:51:24 dholland Exp $ */
+/* $NetBSD: if_rum.c,v 1.35 2011/02/21 23:50:42 jmcneill Exp $ */
/*-
* Copyright (c) 2005-2007 Damien Bergamini <[email protected]>
@@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.34 2011/02/13 05:51:24 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.35 2011/02/21 23:50:42 jmcneill Exp $");
#include <sys/param.h>
@@ -134,71 +134,69 @@
{ USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 }
};
-Static int rum_attachhook(void *);
-Static int rum_alloc_tx_list(struct rum_softc *);
-Static void rum_free_tx_list(struct rum_softc *);
-Static int rum_alloc_rx_list(struct rum_softc *);
-Static void rum_free_rx_list(struct rum_softc *);
-Static int rum_media_change(struct ifnet *);
-Static void rum_next_scan(void *);
-Static void rum_task(void *);
-Static int rum_newstate(struct ieee80211com *,
+static int rum_attachhook(void *);
+static int rum_alloc_tx_list(struct rum_softc *);
+static void rum_free_tx_list(struct rum_softc *);
+static int rum_alloc_rx_list(struct rum_softc *);
+static void rum_free_rx_list(struct rum_softc *);
+static int rum_media_change(struct ifnet *);
+static void rum_next_scan(void *);
+static void rum_task(void *);
+static int rum_newstate(struct ieee80211com *,
enum ieee80211_state, int);
-Static void rum_txeof(usbd_xfer_handle, usbd_private_handle,
+static void rum_txeof(usbd_xfer_handle, usbd_private_handle,
usbd_status);
-Static void rum_rxeof(usbd_xfer_handle, usbd_private_handle,
+static void rum_rxeof(usbd_xfer_handle, usbd_private_handle,
usbd_status);
-Static uint8_t rum_rxrate(const struct rum_rx_desc *);
-Static int rum_ack_rate(struct ieee80211com *, int);
-Static uint16_t rum_txtime(int, int, uint32_t);
-Static uint8_t rum_plcp_signal(int);
-Static void rum_setup_tx_desc(struct rum_softc *,
+static uint8_t rum_rxrate(const struct rum_rx_desc *);
+static int rum_ack_rate(struct ieee80211com *, int);
+static uint16_t rum_txtime(int, int, uint32_t);
+static uint8_t rum_plcp_signal(int);
+static void rum_setup_tx_desc(struct rum_softc *,
struct rum_tx_desc *, uint32_t, uint16_t, int,
int);
-Static int rum_tx_mgt(struct rum_softc *, struct mbuf *,
+static int rum_tx_data(struct rum_softc *, struct mbuf *,
struct ieee80211_node *);
-Static int rum_tx_data(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *);
-Static void rum_start(struct ifnet *);
-Static void rum_watchdog(struct ifnet *);
-Static int rum_ioctl(struct ifnet *, u_long, void *);
-Static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
+static void rum_start(struct ifnet *);
+static void rum_watchdog(struct ifnet *);
+static int rum_ioctl(struct ifnet *, u_long, void *);
+static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
int);
-Static uint32_t rum_read(struct rum_softc *, uint16_t);
-Static void rum_read_multi(struct rum_softc *, uint16_t, void *,
+static uint32_t rum_read(struct rum_softc *, uint16_t);
+static void rum_read_multi(struct rum_softc *, uint16_t, void *,
int);
-Static void rum_write(struct rum_softc *, uint16_t, uint32_t);
-Static void rum_write_multi(struct rum_softc *, uint16_t, void *,
+static void rum_write(struct rum_softc *, uint16_t, uint32_t);
+static void rum_write_multi(struct rum_softc *, uint16_t, void *,
size_t);
-Static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
-Static uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
-Static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
-Static void rum_select_antenna(struct rum_softc *);
-Static void rum_enable_mrr(struct rum_softc *);
-Static void rum_set_txpreamble(struct rum_softc *);
-Static void rum_set_basicrates(struct rum_softc *);
-Static void rum_select_band(struct rum_softc *,
+static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
+static uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
+static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
+static void rum_select_antenna(struct rum_softc *);
+static void rum_enable_mrr(struct rum_softc *);
+static void rum_set_txpreamble(struct rum_softc *);
+static void rum_set_basicrates(struct rum_softc *);
+static void rum_select_band(struct rum_softc *,
struct ieee80211_channel *);
-Static void rum_set_chan(struct rum_softc *,
+static void rum_set_chan(struct rum_softc *,
struct ieee80211_channel *);
-Static void rum_enable_tsf_sync(struct rum_softc *);
-Static void rum_update_slot(struct rum_softc *);
-Static void rum_set_bssid(struct rum_softc *, const uint8_t *);
-Static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
-Static void rum_update_promisc(struct rum_softc *);
-Static const char *rum_get_rf(int);
-Static void rum_read_eeprom(struct rum_softc *);
-Static int rum_bbp_init(struct rum_softc *);
-Static int rum_init(struct ifnet *);
-Static void rum_stop(struct ifnet *, int);
-Static int rum_load_microcode(struct rum_softc *, const u_char *,
+static void rum_enable_tsf_sync(struct rum_softc *);
+static void rum_update_slot(struct rum_softc *);
+static void rum_set_bssid(struct rum_softc *, const uint8_t *);
+static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
+static void rum_update_promisc(struct rum_softc *);
+static const char *rum_get_rf(int);
+static void rum_read_eeprom(struct rum_softc *);
+static int rum_bbp_init(struct rum_softc *);
+static int rum_init(struct ifnet *);
+static void rum_stop(struct ifnet *, int);
+static int rum_load_microcode(struct rum_softc *, const u_char *,
size_t);
-Static int rum_prepare_beacon(struct rum_softc *);
-Static void rum_newassoc(struct ieee80211_node *, int);
-Static void rum_amrr_start(struct rum_softc *,
+static int rum_prepare_beacon(struct rum_softc *);
+static void rum_newassoc(struct ieee80211_node *, int);
+static void rum_amrr_start(struct rum_softc *,
struct ieee80211_node *);
-Static void rum_amrr_timeout(void *);
-Static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
+static void rum_amrr_timeout(void *);
+static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
usbd_status status);
/*
@@ -236,15 +234,15 @@
RT2573_RF5225
};
-int rum_match(device_t, cfdata_t, void *);
-void rum_attach(device_t, device_t, void *);
-int rum_detach(device_t, int);
-int rum_activate(device_t, enum devact);
+static int rum_match(device_t, cfdata_t, void *);
+static void rum_attach(device_t, device_t, void *);
+static int rum_detach(device_t, int);
+static int rum_activate(device_t, enum devact);
extern struct cfdriver rum_cd;
CFATTACH_DECL_NEW(rum, sizeof(struct rum_softc), rum_match, rum_attach,
rum_detach, rum_activate);
-int
+static int
rum_match(device_t parent, cfdata_t match, void *aux)
{
struct usb_attach_arg *uaa = aux;
@@ -253,7 +251,7 @@
UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
}
-Static int
+static int
rum_attachhook(void *xsc)
{
struct rum_softc *sc = xsc;
@@ -298,7 +296,7 @@
return 0;
}
-void
+static void
rum_attach(device_t parent, device_t self, void *aux)
{
struct rum_softc *sc = device_private(self);
@@ -482,7 +480,7 @@
return;
}
-int
+static int
rum_detach(device_t self, int flags)
{
struct rum_softc *sc = device_private(self);
@@ -526,13 +524,13 @@
return 0;
}
-Static int
+static int
rum_alloc_tx_list(struct rum_softc *sc)
{
struct rum_tx_data *data;
int i, error;
- sc->tx_queued = 0;
+ sc->tx_cur = sc->tx_queued = 0;
for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
data = &sc->tx_data[i];
@@ -548,7 +546,7 @@
}
data->buf = usbd_alloc_buffer(data->xfer,
- RT2573_TX_DESC_SIZE + MCLBYTES);
+ RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN);
if (data->buf == NULL) {
printf("%s: could not allocate tx buffer\n",
device_xname(sc->sc_dev));
@@ -566,7 +564,7 @@
return error;
}
-Static void
+static void
rum_free_tx_list(struct rum_softc *sc)
{
struct rum_tx_data *data;
@@ -587,7 +585,7 @@
}
}
-Static int
+static int
rum_alloc_rx_list(struct rum_softc *sc)
{
struct rum_rx_data *data;
@@ -638,7 +636,7 @@
return error;
}
-Static void
+static void
rum_free_rx_list(struct rum_softc *sc)
{
struct rum_rx_data *data;
@@ -659,7 +657,7 @@
}
}
-Static int
+static int
rum_media_change(struct ifnet *ifp)
{
int error;
@@ -678,17 +676,20 @@
* This function is called periodically (every 200ms) during scanning to
* switch from one channel to another.
*/
-Static void
+static void
rum_next_scan(void *arg)
{
struct rum_softc *sc = arg;
struct ieee80211com *ic = &sc->sc_ic;
+ int s;
+ s = splnet();
if (ic->ic_state == IEEE80211_S_SCAN)
ieee80211_next_scan(ic);
+ splx(s);
}
-Static void
+static void
rum_task(void *arg)
{
struct rum_softc *sc = arg;
@@ -753,10 +754,10 @@
break;
}
- sc->sc_newstate(ic, sc->sc_state, -1);
+ sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
}
-Static int
+static int
rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
{
struct rum_softc *sc = ic->ic_ifp->if_softc;
@@ -767,6 +768,7 @@
/* do it in a process context */
sc->sc_state = nstate;
+ sc->sc_arg = arg;
usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
return 0;
@@ -778,7 +780,7 @@
#define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */
#define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */
-Static void
+static void
rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct rum_tx_data *data = priv;
@@ -817,7 +819,7 @@
splx(s);
}
-Static void
+static void
rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
struct rum_rx_data *data = priv;
@@ -924,7 +926,7 @@
* This function is only used by the Rx radiotap code. It returns the rate at
* which a given frame was received.
*/
-Static uint8_t
+static uint8_t
rum_rxrate(const struct rum_rx_desc *desc)
{
if (le32toh(desc->flags) & RT2573_RX_OFDM) {
@@ -956,7 +958,7 @@
* Return the expected ack rate for a frame transmitted at rate `rate'.
* XXX: this should depend on the destination node basic rate set.
*/
-Static int
+static int
rum_ack_rate(struct ieee80211com *ic, int rate)
{
switch (rate) {
@@ -991,7 +993,7 @@
* The function automatically determines the operating mode depending on the
* given rate. `flags' indicates whether short preamble is in use or not.
*/
-Static uint16_t
+static uint16_t
rum_txtime(int len, int rate, uint32_t flags)
{
uint16_t txtime;
@@ -1011,7 +1013,7 @@
return txtime;
}
-Static uint8_t
+static uint8_t
rum_plcp_signal(int rate)
{
switch (rate) {
@@ -1036,7 +1038,7 @@
}
}
-Static void
+static void
rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
uint32_t flags, uint16_t xflags, int len, int rate)
{
@@ -1084,8 +1086,8 @@
#define RUM_TX_TIMEOUT 5000
-Static int
-rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
+static int
+rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_desc *desc;
@@ -1095,15 +1097,7 @@
uint32_t flags = 0;
uint16_t dur;
usbd_status error;
- int xferlen, rate;
-
- data = &sc->tx_data[0];
- desc = (struct rum_tx_desc *)data->buf;
-
- rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
-
- data->m = m0;
- data->ni = ni;
+ int rate, xferlen, pktlen, needrts = 0, needcts = 0;
wh = mtod(m0, struct ieee80211_frame *);
@@ -1113,102 +1107,102 @@
m_freem(m0);
return ENOBUFS;
}
- }
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RT2573_TX_NEED_ACK;
-
- dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
- ic->ic_flags) + sc->sifs;
- *(uint16_t *)wh->i_dur = htole16(dur);
-
- /* tell hardware to set timestamp in probe responses */
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
- flags |= RT2573_TX_TIMESTAMP;
- }
-
- if (sc->sc_drvbpf != NULL) {
- struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
- bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+ /* packet header may have moved, reset our local pointer */
+ wh = mtod(m0, struct ieee80211_frame *);
}
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
- rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
+ /* compute actual packet length (including CRC and crypto overhead) */
+ pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
- /* align end on a 4-bytes boundary */
- xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
-
- /*
- * No space left in the last URB to store the extra 4 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 4;
-
- DPRINTFN(10, ("sending msg frame len=%zu rate=%u xfer len=%u\n",
- (size_t)m0->m_pkthdr.len + RT2573_TX_DESC_SIZE,
- rate, xferlen));
+ /* pickup a rate */
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
+ ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+ IEEE80211_FC0_TYPE_MGT)) {
+ /* mgmt/multicast frames are sent at the lowest avail. rate */
+ rate = ni->ni_rates.rs_rates[0];
+ } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
+ rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
+ } else
+ rate = ni->ni_rates.rs_rates[ni->ni_txrate];
+ if (rate == 0)
+ rate = 2; /* XXX should not happen */
+ rate &= IEEE80211_RATE_VAL;
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
+ /* check if RTS/CTS or CTS-to-self protection must be used */
+ if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ /* multicast frames are not sent at OFDM rates in 802.11b/g */
+ if (pktlen > ic->ic_rtsthreshold) {
+ needrts = 1; /* RTS/CTS based on frame length */
+ } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
+ RUM_RATE_IS_OFDM(rate)) {
+ if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
+ needcts = 1; /* CTS-to-self */
+ else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
+ needrts = 1; /* RTS/CTS */
+ }
+ }
+ if (needrts || needcts) {
+ struct mbuf *mprot;
+ int protrate, ackrate;
+
+ protrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
+ ackrate = rum_ack_rate(ic, rate);
+
+ dur = rum_txtime(pktlen, rate, ic->ic_flags) +
+ rum_txtime(RUM_ACK_SIZE, ackrate, ic->ic_flags) +
+ 2 * sc->sifs;
+ if (needrts) {
+ dur += rum_txtime(RUM_CTS_SIZE, rum_ack_rate(ic,
+ protrate), ic->ic_flags) + sc->sifs;
+ mprot = ieee80211_get_rts(ic, wh, dur);
+ } else {
+ mprot = ieee80211_get_cts_to_self(ic, dur);
+ }
+ if (mprot == NULL) {
+ aprint_error_dev(sc->sc_dev,
+ "couldn't allocate protection frame\n");
+ m_freem(m0);
+ return ENOBUFS;
+ }
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- return error;
- }
+ data = &sc->tx_data[sc->tx_cur];
+ desc = (struct rum_tx_desc *)data->buf;
- sc->tx_queued++;
+ /* avoid multiple free() of the same node for each fragment */
+ data->ni = ieee80211_ref_node(ni);
- return 0;
-}
+ m_copydata(mprot, 0, mprot->m_pkthdr.len,
+ data->buf + RT2573_TX_DESC_SIZE);
+ rum_setup_tx_desc(sc, desc,
+ (needrts ? RT2573_TX_NEED_ACK : 0) | RT2573_TX_MORE_FRAG,
+ 0, mprot->m_pkthdr.len, protrate);
-Static int
-rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211com *ic = &sc->sc_ic;
- struct rum_tx_desc *desc;
- struct rum_tx_data *data;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- usbd_status error;
- int xferlen, rate;
+ /* no roundup necessary here */
+ xferlen = RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len;
- wh = mtod(m0, struct ieee80211_frame *);
+ /* XXX may want to pass the protection frame to BPF */
- if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
- rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
- else
- rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- if (rate == 0)
- rate = 2; /* XXX should not happen */
- rate &= IEEE80211_RATE_VAL;
+ /* mbuf is no longer needed */
+ m_freem(mprot);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ic, ni, m0);
- if (k == NULL) {
+ usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
+ xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
+ RUM_TX_TIMEOUT, rum_txeof);
+ error = usbd_transfer(data->xfer);
+ if (error != USBD_NORMAL_COMPLETION &&
+ error != USBD_IN_PROGRESS) {
m_freem(m0);
- return ENOBUFS;
+ return error;
}
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
+ sc->tx_queued++;
+ sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
+
+ flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
}
- data = &sc->tx_data[0];
+ data = &sc->tx_data[sc->tx_cur];
desc = (struct rum_tx_desc *)data->buf;
data->ni = ni;
@@ -1219,6 +1213,12 @@
dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
ic->ic_flags) + sc->sifs;
*(uint16_t *)wh->i_dur = htole16(dur);
+
+ /* tell hardware to set timestamp in probe responses */
+ if ((wh->i_fc[0] &
+ (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
+ (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
+ flags |= RT2573_TX_TIMESTAMP;
}
if (sc->sc_drvbpf != NULL) {
@@ -1255,17 +1255,17 @@
usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
-
error = usbd_transfer(data->xfer);
if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
return error;
sc->tx_queued++;
+ sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
return 0;
}
-Static void
+static void
rum_start(struct ifnet *ifp)
{
struct rum_softc *sc = ifp->if_softc;
@@ -1274,10 +1274,13 @@
struct ieee80211_node *ni;
struct mbuf *m0;
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+ return;
+
for (;;) {
IF_POLL(&ic->ic_mgtq, m0);
if (m0 != NULL) {
- if (sc->tx_queued >= RUM_TX_LIST_COUNT) {
+ if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -1286,7 +1289,7 @@
ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
m0->m_pkthdr.rcvif = NULL;
bpf_mtap3(ic->ic_rawbpf, m0);
- if (rum_tx_mgt(sc, m0, ni) != 0)
+ if (rum_tx_data(sc, m0, ni) != 0)
break;
} else {
@@ -1295,7 +1298,7 @@
IFQ_POLL(&ifp->if_snd, m0);
if (m0 == NULL)
break;
- if (sc->tx_queued >= RUM_TX_LIST_COUNT) {
+ if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -1329,7 +1332,7 @@
}
}
-Static void
+static void
rum_watchdog(struct ifnet *ifp)
{
struct rum_softc *sc = ifp->if_softc;
@@ -1350,7 +1353,7 @@
ieee80211_watchdog(ic);
}
-Static int
+static int
rum_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct rum_softc *sc = ifp->if_softc;
@@ -1395,7 +1398,7 @@
return error;
}
-Static void
+static void
rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
{
usb_device_request_t req;
@@ -1414,7 +1417,7 @@
}
}
-Static uint32_t
+static uint32_t
rum_read(struct rum_softc *sc, uint16_t reg)
{
uint32_t val;
@@ -1424,7 +1427,7 @@
return le32toh(val);
}
-Static void
+static void
rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
{
usb_device_request_t req;
@@ -1443,7 +1446,7 @@
}
}
-Static void
+static void
rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
{
uint32_t tmp = htole32(val);
@@ -1451,7 +1454,7 @@
rum_write_multi(sc, reg, &tmp, sizeof tmp);
}
-Static void
+static void
rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
{
usb_device_request_t req;
@@ -1470,7 +1473,7 @@
}
}
-Static void
+static void
rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
{
uint32_t tmp;
@@ -1489,7 +1492,7 @@
rum_write(sc, RT2573_PHY_CSR3, tmp);
}
-Static uint8_t
+static uint8_t
rum_bbp_read(struct rum_softc *sc, uint8_t reg)
{
uint32_t val;
@@ -1518,7 +1521,7 @@
return 0;
}
-Static void
+static void
rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
{
uint32_t tmp;
@@ -1543,7 +1546,7 @@
DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff));
}
-Static void
+static void
rum_select_antenna(struct rum_softc *sc)
{
uint8_t bbp4, bbp77;
@@ -1568,7 +1571,7 @@
* Enable multi-rate retries for frames sent at OFDM rates.
* In 802.11b/g mode, allow fallback to CCK rates.
*/
-Static void
+static void
rum_enable_mrr(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1584,7 +1587,7 @@
rum_write(sc, RT2573_TXRX_CSR4, tmp);
}
-Static void
+static void
rum_set_txpreamble(struct rum_softc *sc)
{
uint32_t tmp;
@@ -1598,7 +1601,7 @@
rum_write(sc, RT2573_TXRX_CSR4, tmp);
}
-Static void
+static void
rum_set_basicrates(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1620,7 +1623,7 @@
* Reprogram MAC/BBP to switch to a new band. Values taken from the reference
* driver.
*/
-Static void
+static void
rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
{
uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
@@ -1666,7 +1669,7 @@
sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
}
-Static void
+static void
rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1739,7 +1742,7 @@
* Enable TSF synchronization and tell h/w to start sending beacons for IBSS
* and HostAP operating modes.
*/
-Static void
+static void
rum_enable_tsf_sync(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1767,7 +1770,7 @@
rum_write(sc, RT2573_TXRX_CSR9, tmp);
}
-Static void
+static void
rum_update_slot(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1783,7 +1786,7 @@
DPRINTF(("setting slot time to %uus\n", slottime));
}
-Static void
+static void
rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
{
uint32_t tmp;
@@ -1795,7 +1798,7 @@
rum_write(sc, RT2573_MAC_CSR5, tmp);
}
-Static void
+static void
rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
{
uint32_t tmp;
@@ -1807,7 +1810,7 @@
rum_write(sc, RT2573_MAC_CSR3, tmp);
}
-Static void
+static void
rum_update_promisc(struct rum_softc *sc)
{
struct ifnet *ifp = sc->sc_ic.ic_ifp;
@@ -1825,7 +1828,7 @@
"entering" : "leaving"));
}
-Static const char *
+static const char *
rum_get_rf(int rev)
{
switch (rev) {
@@ -1837,7 +1840,7 @@
}
}
-Static void
+static void
rum_read_eeprom(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -1912,7 +1915,7 @@
#endif
}
-Static int
+static int
rum_bbp_init(struct rum_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
@@ -1947,7 +1950,7 @@
#undef N
}
-Static int
+static int
rum_init(struct ifnet *ifp)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
@@ -2095,7 +2098,7 @@
#undef N
}
-Static void
+static void
rum_stop(struct ifnet *ifp, int disable)
{
struct rum_softc *sc = ifp->if_softc;
@@ -2116,6 +2119,11 @@
rum_write(sc, RT2573_MAC_CSR1, 3);
rum_write(sc, RT2573_MAC_CSR1, 0);
+ if (sc->amrr_xfer != NULL) {
+ usbd_free_xfer(sc->amrr_xfer);
+ sc->amrr_xfer = NULL;
+ }
+
if (sc->sc_rx_pipeh != NULL) {
usbd_abort_pipe(sc->sc_rx_pipeh);
usbd_close_pipe(sc->sc_rx_pipeh);
@@ -2132,7 +2140,7 @@
rum_free_tx_list(sc);
}
-Static int
+static int
rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
{
usb_device_request_t req;
@@ -2157,7 +2165,7 @@
return error;
}
-Static int
+static int
rum_prepare_beacon(struct rum_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -2190,14 +2198,14 @@
return 0;
}
-Static void
+static void
rum_newassoc(struct ieee80211_node *ni, int isnew)
{
/* start with lowest Tx rate */
ni->ni_txrate = 0;
}
-Static void
+static void
rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
{
int i;
@@ -2216,7 +2224,7 @@
callout_reset(&sc->sc_amrr_ch, hz, rum_amrr_timeout, sc);
}
-Static void
+static void
rum_amrr_timeout(void *arg)
{
struct rum_softc *sc = arg;
@@ -2237,7 +2245,7 @@
(void)usbd_transfer(sc->amrr_xfer);
}
-Static void
+static void
rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status status)
{
@@ -2267,7 +2275,7 @@
callout_reset(&sc->sc_amrr_ch, hz, rum_amrr_timeout, sc);
}
-int
+static int
rum_activate(device_t self, enum devact act)
{
switch (act) {
@@ -2275,6 +2283,6 @@
/*if_deactivate(&sc->sc_ic.ic_if);*/
return 0;
default:
- return EOPNOTSUPP;
+ return 0;
}
}
Index: src/sys/dev/usb/if_rumreg.h
diff -u src/sys/dev/usb/if_rumreg.h:1.3 src/sys/dev/usb/if_rumreg.h:1.4
--- src/sys/dev/usb/if_rumreg.h:1.3 Fri May 29 18:49:21 2009
+++ src/sys/dev/usb/if_rumreg.h Mon Feb 21 23:50:42 2011
@@ -1,5 +1,5 @@
-/* $NetBSD: if_rumreg.h,v 1.3 2009/05/29 18:49:21 plunky Exp $ */
-/* $OpenBSD: if_rumreg.h,v 1.13 2006/11/13 20:06:38 damien Exp $ */
+/* $NetBSD: if_rumreg.h,v 1.4 2011/02/21 23:50:42 jmcneill Exp $ */
+/* $OpenBSD: if_rumreg.h,v 1.14 2009/08/10 18:04:56 damien Exp $ */
/*-
* Copyright (c) 2005, 2006 Damien Bergamini <[email protected]>
@@ -40,6 +40,9 @@
#define RT2573_CWMAX_CSR 0x0408
#define RT2573_MCU_CODE_BASE 0x0800
#define RT2573_HW_BEACON_BASE0 0x2400
+#define RT2573_HW_BEACON_BASE1 0x2500
+#define RT2573_HW_BEACON_BASE2 0x2600
+#define RT2573_HW_BEACON_BASE3 0x2700
#define RT2573_MAC_CSR0 0x3000
#define RT2573_MAC_CSR1 0x3004
#define RT2573_MAC_CSR2 0x3008
@@ -237,28 +240,32 @@
* Default values for MAC registers; values taken from the reference driver.
*/
#define RT2573_DEF_MAC \
- { RT2573_TXRX_CSR0, 0x025fb032 }, \
- { RT2573_TXRX_CSR1, 0x9eaa9eaf }, \
- { RT2573_TXRX_CSR2, 0x8a8b8c8d }, \
- { RT2573_TXRX_CSR3, 0x00858687 }, \
- { RT2573_TXRX_CSR7, 0x2e31353b }, \
- { RT2573_TXRX_CSR8, 0x2a2a2a2c }, \
- { RT2573_TXRX_CSR15, 0x0000000f }, \
- { RT2573_MAC_CSR6, 0x00000fff }, \
- { RT2573_MAC_CSR8, 0x016c030a }, \
- { RT2573_MAC_CSR10, 0x00000718 }, \
- { RT2573_MAC_CSR12, 0x00000004 }, \
- { RT2573_MAC_CSR13, 0x00007f00 }, \
- { RT2573_SEC_CSR0, 0x00000000 }, \
- { RT2573_SEC_CSR1, 0x00000000 }, \
- { RT2573_SEC_CSR5, 0x00000000 }, \
- { RT2573_PHY_CSR1, 0x000023b0 }, \
- { RT2573_PHY_CSR5, 0x00040a06 }, \
- { RT2573_PHY_CSR6, 0x00080606 }, \
- { RT2573_PHY_CSR7, 0x00000408 }, \
- { RT2573_AIFSN_CSR, 0x00002273 }, \
- { RT2573_CWMIN_CSR, 0x00002344 }, \
- { RT2573_CWMAX_CSR, 0x000034aa }
+ { RT2573_TXRX_CSR0, 0x025fb032 }, \
+ { RT2573_TXRX_CSR1, 0x9eaa9eaf }, \
+ { RT2573_TXRX_CSR2, 0x8a8b8c8d }, \
+ { RT2573_TXRX_CSR3, 0x00858687 }, \
+ { RT2573_TXRX_CSR7, 0x2e31353b }, \
+ { RT2573_TXRX_CSR8, 0x2a2a2a2c }, \
+ { RT2573_TXRX_CSR15, 0x0000000f }, \
+ { RT2573_MAC_CSR6, 0x00000fff }, \
+ { RT2573_MAC_CSR8, 0x016c030a }, \
+ { RT2573_MAC_CSR10, 0x00000718 }, \
+ { RT2573_MAC_CSR12, 0x00000004 }, \
+ { RT2573_MAC_CSR13, 0x00007f00 }, \
+ { RT2573_SEC_CSR0, 0x00000000 }, \
+ { RT2573_SEC_CSR1, 0x00000000 }, \
+ { RT2573_SEC_CSR5, 0x00000000 }, \
+ { RT2573_PHY_CSR1, 0x000023b0 }, \
+ { RT2573_PHY_CSR5, 0x00040a06 }, \
+ { RT2573_PHY_CSR6, 0x00080606 }, \
+ { RT2573_PHY_CSR7, 0x00000408 }, \
+ { RT2573_AIFSN_CSR, 0x00002273 }, \
+ { RT2573_CWMIN_CSR, 0x00002344 }, \
+ { RT2573_CWMAX_CSR, 0x000034aa }, \
+ { RT2573_HW_BEACON_BASE0, 0x00000000 }, \
+ { RT2573_HW_BEACON_BASE1, 0x00000000 }, \
+ { RT2573_HW_BEACON_BASE2, 0x00000000 }, \
+ { RT2573_HW_BEACON_BASE3, 0x00000000 }
/*
* Default values for BBP registers; values taken from the reference driver.
Index: src/sys/dev/usb/if_rumvar.h
diff -u src/sys/dev/usb/if_rumvar.h:1.8 src/sys/dev/usb/if_rumvar.h:1.9
--- src/sys/dev/usb/if_rumvar.h:1.8 Wed Nov 3 22:30:50 2010
+++ src/sys/dev/usb/if_rumvar.h Mon Feb 21 23:50:42 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: if_rumvar.h,v 1.8 2010/11/03 22:30:50 dyoung Exp $ */
+/* $NetBSD: if_rumvar.h,v 1.9 2011/02/21 23:50:42 jmcneill Exp $ */
/* $OpenBSD: if_rumvar.h,v 1.7 2006/11/13 20:06:38 damien Exp $ */
/*-
@@ -19,7 +19,7 @@
*/
#define RUM_RX_LIST_COUNT 1
-#define RUM_TX_LIST_COUNT 1
+#define RUM_TX_LIST_COUNT 8
struct rum_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
@@ -98,6 +98,7 @@
usbd_pipe_handle sc_tx_pipeh;
enum ieee80211_state sc_state;
+ int sc_arg;
struct usb_task sc_task;
struct ieee80211_amrr amrr;
@@ -106,6 +107,7 @@
struct rum_rx_data rx_data[RUM_RX_LIST_COUNT];
struct rum_tx_data tx_data[RUM_TX_LIST_COUNT];
int tx_queued;
+ int tx_cur;
struct ieee80211_beacon_offsets sc_bo;