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 <damien.bergam...@free.fr>
@@ -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 <damien.bergam...@free.fr>
@@ -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;
 

Reply via email to