PERFORCE change 163611 for review

Andrew Thompson thompsa at FreeBSD.org
Fri Jun 5 21:25:55 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=163611

Change 163611 by thompsa at thompsa_burger on 2009/06/05 21:24:55

	First crack at a driver with the urb api, not complete.

Affected files ...

.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#8 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rumvar.h#4 edit

Differences ...

==== //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#8 (text+ko) ====

@@ -69,19 +69,15 @@
 #define	USB_DEBUG_VAR rum_debug
 
 #include <dev/usb/usb.h>
-#include <dev/usb/usb_core.h>
-#include <dev/usb/usb_lookup.h>
+#include <dev/usb/usbdi.h>
 #include <dev/usb/usb_debug.h>
-#include <dev/usb/usb_request.h>
-#include <dev/usb/usb_busdma.h>
-#include <dev/usb/usb_util.h>
 #include "usbdevs.h"
 
 #include <dev/usb/wlan/if_rumreg.h>
 #include <dev/usb/wlan/if_rumvar.h>
 #include <dev/usb/wlan/if_rumfw.h>
 
-#if USB_DEBUG
+#ifdef USB_DEBUG
 static int rum_debug = 0;
 
 SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
@@ -417,7 +413,7 @@
 	if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
 		return (ENXIO);
 
-	return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
+	return (usb_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
 }
 
 static int
@@ -431,7 +427,7 @@
 	uint32_t tmp;
 	int error, ntries;
 
-	device_set_usb2_desc(self);
+	device_set_usb_desc(self);
 	sc->sc_udev = uaa->device;
 	sc->sc_dev = self;
 
@@ -439,11 +435,11 @@
 	    MTX_NETWORK_LOCK, MTX_DEF);
 
 	iface_index = RT2573_IFACE_INDEX;
-	error = usb2_transfer_setup(uaa->device, &iface_index,
-	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
+	error = usb_pipe_open(uaa->device, &iface_index,
+	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc);
 	if (error) {
 		device_printf(self, "could not allocate USB transfers, "
-		    "err=%s\n", usb2_errstr(error));
+		    "err=%s\n", usb_errstr(error));
 		goto detach;
 	}
 
@@ -546,7 +542,7 @@
 	struct ieee80211com *ic;
 
 	/* stop all USB transfers */
-	usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
+	usb_pipe_close(sc->sc_xfer, RUM_N_TRANSFER);
 
 	/* free TX list, if any */
 	RUM_LOCK(sc);
@@ -571,13 +567,13 @@
 	int ntries = 10;
 
 	while (ntries--) {
-		err = usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx,
+		err = usb_do_request_flags(sc->sc_udev, &sc->sc_mtx,
 		    req, data, 0, NULL, 250 /* ms */);
 		if (err == 0)
 			break;
 
 		DPRINTFN(1, "Control request failed, %s (retrying)\n",
-		    usb2_errstr(err));
+		    usb_errstr(err));
 		if (rum_pause(sc, hz / 100))
 			break;
 	}
@@ -609,7 +605,7 @@
 	rvp->newstate = vap->iv_newstate;
 	vap->iv_newstate = rum_newstate;
 
-	usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
+	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,
@@ -628,7 +624,7 @@
 	struct rum_vap *rvp = RUM_VAP(vap);
 	struct ieee80211com *ic = vap->iv_ic;
 
-	usb2_callout_drain(&rvp->amrr_ch);
+	usb_callout_drain(&rvp->amrr_ch);
 	ieee80211_draintask(ic, &rvp->amrr_task);
 	ieee80211_amrr_cleanup(&rvp->amrr);
 	ieee80211_vap_detach(vap);
@@ -650,6 +646,7 @@
 		ieee80211_free_node(data->ni);
 		data->ni = NULL;
 	}
+	usb_init_urb(data->urb);	/* reset state */
 	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
 	sc->tx_nfree++;
 }
@@ -661,13 +658,15 @@
 	int i;
 
 	sc->tx_nfree = 0;
-	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
 	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
 		data = &sc->tx_data[i];
 
 		data->sc = sc;
+		data->urb = usb_get_urb(sc->sc_xfer[RUM_BULK_WR], 0);
+		KASSERT(data->urb != NULL, ("usb_get_urb failed"));
+		urb_set_priv(data->urb, &data);
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
 		sc->tx_nfree++;
 	}
@@ -681,7 +680,6 @@
 
 	/* make sure any subsequent use of the queues will fail */
 	sc->tx_nfree = 0;
-	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
 
 	/* free up all node references and mbufs */
@@ -696,6 +694,10 @@
 			ieee80211_free_node(data->ni);
 			data->ni = NULL;
 		}
+		if (data->urb != NULL) {
+			usb_free_urb(data->urb);
+			data->urb = NULL;
+		}
 	}
 }
 
@@ -717,7 +719,7 @@
 
 	IEEE80211_UNLOCK(ic);
 	RUM_LOCK(sc);
-	usb2_callout_stop(&rvp->amrr_ch);
+	usb_callout_stop(&rvp->amrr_ch);
 
 	switch (nstate) {
 	case IEEE80211_S_INIT:
@@ -763,194 +765,113 @@
 }
 
 static void
-rum_bulk_write_callback(struct usb_xfer *xfer)
+rum_bulk_write_callback(struct usb_urb *urb, usb_error_t error)
 {
-	struct rum_softc *sc = xfer->priv_sc;
+	struct rum_softc *sc = urb_get_softc(urb);
 	struct ifnet *ifp = sc->sc_ifp;
-	struct ieee80211vap *vap;
 	struct rum_tx_data *data;
-	struct mbuf *m;
-	unsigned int len;
+	int len;
 
-	switch (USB_GET_STATE(xfer)) {
-	case USB_ST_TRANSFERRED:
-		DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
+	printf("rum_bulk_write_callback(%p, %d)\n", urb, error);
 
-		/* free resources */
-		data = xfer->priv_fifo;
-		rum_tx_free(data, 0);
-		xfer->priv_fifo = NULL;
+	urb_get_status(urb, NULL, NULL, &len, NULL);
+	DPRINTFN(11, "transfer complete, %d bytes\n", len);
 
-		ifp->if_opackets++;
-		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	/* free resources */
+	data = urb_get_priv(urb);
+	rum_tx_free(data, 0);
+	usb_free_urb(urb);
 
-		/* FALLTHROUGH */
-	case USB_ST_SETUP:
-tr_setup:
-		data = STAILQ_FIRST(&sc->tx_q);
-		if (data) {
-			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
-			m = data->m;
-
-			if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
-				DPRINTFN(0, "data overflow, %u bytes\n",
-				    m->m_pkthdr.len);
-				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
-			}
-			usb2_copy_in(xfer->frbuffers, 0, &data->desc,
-			    RT2573_TX_DESC_SIZE);
-			usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
-			    0, m->m_pkthdr.len);
-
-			vap = data->ni->ni_vap;
-			if (ieee80211_radiotap_active_vap(vap)) {
-				struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
-				tap->wt_flags = 0;
-				tap->wt_rate = data->rate;
-				tap->wt_antenna = sc->tx_ant;
-
-				ieee80211_radiotap_tx(vap, m);
-			}
-
-			/* align end on a 4-bytes boundary */
-			len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
-			if ((len % 64) == 0)
-				len += 4;
-
-			DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
-			    m->m_pkthdr.len, len);
-
-			xfer->frlengths[0] = len;
-			xfer->priv_fifo = data;
-
-			usb_submit_urb(xfer);
-		}
-		break;
-
-	default:			/* Error */
-		DPRINTFN(11, "transfer error, %s\n",
-		    usb2_errstr(xfer->error));
-
+	if (error) {
+		if (error == USB_ERR_CANCELLED)
+			return;
 		ifp->if_oerrors++;
-		data = xfer->priv_fifo;
-		if (data != NULL) {
-			rum_tx_free(data, xfer->error);
-			xfer->priv_fifo = NULL;
-		}
+	} else
+		ifp->if_opackets++;
 
-		if (xfer->error == USB_ERR_STALLED) {
-			/* try to clear stall first */
-			xfer->flags.stall_pipe = 1;
-			goto tr_setup;
-		}
-		if (xfer->error == USB_ERR_TIMEOUT)
-			device_printf(sc->sc_dev, "device timeout\n");
-		break;
-	}
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	rum_start(ifp);
 }
 
 static void
-rum_bulk_read_callback(struct usb_xfer *xfer)
+rum_bulk_read_callback(struct usb_urb *urb, usb_error_t error)
 {
-	struct rum_softc *sc = xfer->priv_sc;
+	struct rum_softc *sc = urb_get_softc(urb);
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ieee80211_node *ni;
 	struct mbuf *m = NULL;
+	struct rum_rx_desc *desc;
 	uint32_t flags;
 	uint8_t rssi = 0;
-	unsigned int len;
+	int actlen;
 
-	switch (USB_GET_STATE(xfer)) {
-	case USB_ST_TRANSFERRED:
-
-		DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
-
-		len = xfer->actlen;
-		if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
-			DPRINTF("%s: xfer too short %d\n",
-			    device_get_nameunit(sc->sc_dev), len);
-			ifp->if_ierrors++;
-			goto tr_setup;
+	if (error) {
+		if (error == USB_ERR_CANCELLED) {
+			usb_free_urb(urb);
+			return;
 		}
+		goto skip;
+	}
 
-		len -= RT2573_RX_DESC_SIZE;
-		usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc,
-		    RT2573_RX_DESC_SIZE);
+	urb_get_status(urb, (void **)&desc, NULL, &actlen, NULL);
+	DPRINTFN(0, "rx done, actlen=%d\n", actlen);
 
-		rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
-		flags = le32toh(sc->sc_rx_desc.flags);
-		if (flags & RT2573_RX_CRC_ERROR) {
-			/*
-		         * This should not happen since we did not
-		         * request to receive those frames when we
-		         * filled RUM_TXRX_CSR2:
-		         */
-			DPRINTFN(5, "PHY or CRC error\n");
-			ifp->if_ierrors++;
-			goto tr_setup;
-		}
+	if (actlen < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
+		DPRINTF("%s: xfer too short %d\n",
+		    device_get_nameunit(sc->sc_dev), actlen);
+		ifp->if_ierrors++;
+		goto skip;
+	}
 
-		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
-		if (m == NULL) {
-			DPRINTF("could not allocate mbuf\n");
-			ifp->if_ierrors++;
-			goto tr_setup;
-		}
-		usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
-		    mtod(m, uint8_t *), len);
+	actlen -= RT2573_RX_DESC_SIZE;
 
-		/* finalize mbuf */
-		m->m_pkthdr.rcvif = ifp;
-		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
+	rssi = rum_get_rssi(sc, desc->rssi);
+	flags = le32toh(desc->flags);
+	if (flags & RT2573_RX_CRC_ERROR) {
+		/*
+		 * This should not happen since we did not
+		 * request to receive those frames when we
+		 * filled RUM_TXRX_CSR2:
+		 */
+		DPRINTFN(5, "PHY or CRC error\n");
+		ifp->if_ierrors++;
+		goto skip;
+	}
 
-		if (ieee80211_radiotap_active(ic)) {
-			struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
+	m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL) {
+		DPRINTF("could not allocate mbuf\n");
+		ifp->if_ierrors++;
+		goto skip;
+	}
 
-			/* XXX read tsf */
-			tap->wr_flags = 0;
-			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
-			    (flags & RT2573_RX_OFDM) ?
-			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
-			tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi;
-			tap->wr_antnoise = RT2573_NOISE_FLOOR;
-			tap->wr_antenna = sc->rx_ant;
-		}
-		/* FALLTHROUGH */
-	case USB_ST_SETUP:
-tr_setup:
-		xfer->frlengths[0] = xfer->max_data_length;
-		usb_submit_urb(xfer);
+	/* finalize mbuf */
+	m->m_pkthdr.rcvif = ifp;
+	bcopy((caddr_t)(desc + 1), mtod(m, uint8_t *), actlen);
+	m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
 
-		/*
-		 * At the end of a USB callback it is always safe to unlock
-		 * the private mutex of a device! That is why we do the
-		 * "ieee80211_input" here, and not some lines up!
-		 */
-		if (m) {
-			RUM_UNLOCK(sc);
-			ni = ieee80211_find_rxnode(ic,
-			    mtod(m, struct ieee80211_frame_min *));
-			if (ni != NULL) {
-				(void) ieee80211_input(ni, m, rssi,
-				    RT2573_NOISE_FLOOR);
-				ieee80211_free_node(ni);
-			} else
-				(void) ieee80211_input_all(ic, m, rssi,
-				    RT2573_NOISE_FLOOR);
-			RUM_LOCK(sc);
-		}
-		return;
+	if (ieee80211_radiotap_active(ic)) {
+		struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
 
-	default:			/* Error */
-		if (xfer->error != USB_ERR_CANCELLED) {
-			/* try to clear stall first */
-			xfer->flags.stall_pipe = 1;
-			goto tr_setup;
-		}
-		return;
+		/* XXX read tsf */
+		tap->wr_flags = 0;
+		tap->wr_rate = ieee80211_plcp2rate(desc->rate,
+		    (flags & RT2573_RX_OFDM) ?
+		    IEEE80211_T_OFDM : IEEE80211_T_CCK);
+		tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi;
+		tap->wr_antnoise = RT2573_NOISE_FLOOR;
+		tap->wr_antenna = sc->rx_ant;
 	}
+	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
+	if (ni != NULL) {
+		(void) ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR);
+		ieee80211_free_node(ni);
+	} else
+		(void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR);
+skip:
+	usb_init_urb(urb);
+	usb_submit_urb(urb);
 }
 
 static uint8_t
@@ -1025,10 +946,12 @@
     const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
 {
 	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211vap *vap;
 	const struct ieee80211_frame *wh;
 	struct rum_tx_data *data;
+	struct rum_tx_desc *desc;
 	struct mbuf *mprot;
-	int protrate, ackrate, pktlen, flags, isshort;
+	int protrate, ackrate, pktlen, flags, isshort, xferlen;
 	uint16_t dur;
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
@@ -1061,13 +984,37 @@
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
 	sc->tx_nfree--;
 
+	urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+	if (xferlen < m->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
+		//m_freem(m);	/* XXX data leak */
+		return EINVAL;
+	}
+
+	desc = (struct rum_tx_desc *)data->buf;
 	data->m = mprot;
 	data->ni = ieee80211_ref_node(ni);
-	data->rate = protrate;
-	rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate);
+
+	vap = data->ni->ni_vap;
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = protrate;
+		tap->wt_antenna = sc->tx_ant;
+
+		ieee80211_radiotap_tx(vap, mprot);
+	}
+
+	m_copydata(mprot, 0, mprot->m_pkthdr.len,
+	    data->buf + RT2573_TX_DESC_SIZE);
+	rum_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, protrate);
+
+	DPRINTFN(10, "sending prot frame len=%d rate=%d\n",
+	    m->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
 
-	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
-	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
+	/* NB: no roundup necessary */
+	urb_set_framelen(data->urb, 0, RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len);
+	usb_submit_urb(data->urb);
 
 	return 0;
 }
@@ -1079,11 +1026,13 @@
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct rum_tx_data *data;
+	struct rum_tx_desc *desc;
 	struct ieee80211_frame *wh;
 	const struct ieee80211_txparam *tp;
 	struct ieee80211_key *k;
 	uint32_t flags = 0;
 	uint16_t dur;
+	int xferlen;
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
 
@@ -1117,17 +1066,45 @@
 			flags |= RT2573_TX_TIMESTAMP;
 	}
 
+	urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+	if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
+		m_freem(m0);	/* XXX data leak */
+		return EINVAL;
+	}
+
+	desc = (struct rum_tx_desc *)data->buf;
 	data->m = m0;
 	data->ni = ni;
-	data->rate = tp->mgmtrate;
+
+	vap = data->ni->ni_vap;
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = tp->mgmtrate;
+		tap->wt_antenna = sc->tx_ant;
+
+		ieee80211_radiotap_tx(vap, m0);
+	}
+
+	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, tp->mgmtrate);
+
+	/* align end on a 4-bytes boundary */
+	xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
 
-	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
+	/*
+	 * 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 mgt frame len=%d rate=%d\n",
-	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
+	DPRINTFN(10, "sending mgt frame len=%d rate=%d xfer len=%d\n",
+	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate, xferlen);
 
-	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
-	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
+	urb_set_framelen(data->urb, 0, xferlen);
+	usb_submit_urb(data->urb);
 
 	return (0);
 }
@@ -1137,9 +1114,11 @@
     const struct ieee80211_bpf_params *params)
 {
 	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211vap *vap;
 	struct rum_tx_data *data;
+	struct rum_tx_desc *desc;
 	uint32_t flags;
-	int rate, error;
+	int rate, error, xferlen;
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
 	KASSERT(params != NULL, ("no raw xmit params"));
@@ -1168,18 +1147,46 @@
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
 	sc->tx_nfree--;
 
+	urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+	if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
+		m_freem(m0);	/* XXX data leak */
+		return EINVAL;
+	}
+
+	vap = data->ni->ni_vap;
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_antenna = sc->tx_ant;
+
+		ieee80211_radiotap_tx(vap, m0);
+	}
+
+	desc = (struct rum_tx_desc *)data->buf;
 	data->m = m0;
 	data->ni = ni;
-	data->rate = rate;
 
+	m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
 	/* XXX need to setup descriptor ourself */
-	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
+	rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
+
+	/* 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 raw frame len=%u rate=%u\n",
-	    m0->m_pkthdr.len, rate);
+	DPRINTFN(10, "sending raw frame len=%u rate=%u xfer len=%u\n",
+	    m0->m_pkthdr.len, rate, xferlen);
 
-	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
-	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
+	urb_set_framelen(data->urb, 0, xferlen);
+	usb_submit_urb(data->urb);
 
 	return 0;
 }
@@ -1191,12 +1198,13 @@
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct rum_tx_data *data;
+	struct rum_tx_desc *desc;
 	struct ieee80211_frame *wh;
 	const struct ieee80211_txparam *tp;
 	struct ieee80211_key *k;
 	uint32_t flags = 0;
 	uint16_t dur;
-	int error, rate;
+	int error, rate, xferlen;
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
 
@@ -1242,9 +1250,15 @@
 	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
 	sc->tx_nfree--;
 
+	urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+	if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
+		m_freem(m0);	/* XXX data leak */
+		return EINVAL;
+	}
+
+	desc = (struct rum_tx_desc *)data->buf;
 	data->m = m0;
 	data->ni = ni;
-	data->rate = rate;
 
 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 		flags |= RT2573_TX_NEED_ACK;
@@ -1255,13 +1269,29 @@
 		*(uint16_t *)wh->i_dur = htole16(dur);
 	}
 
-	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
+	vap = data->ni->ni_vap;
+	if (ieee80211_radiotap_active_vap(vap)) {
+		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_antenna = sc->tx_ant;
+
+		ieee80211_radiotap_tx(vap, m0);
+	}
+
+	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);
 
-	DPRINTFN(10, "sending frame len=%d rate=%d\n",
-	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
+	/* align end on a 4-bytes boundary */
+	xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
+	if ((xferlen % 64) == 0)
+		xferlen += 4;
+	DPRINTFN(10, "sending frame len=%d rate=%d xfer len=%d\n",
+	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate, xferlen);
 
-	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
-	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
+	urb_set_framelen(data->urb, 0, xferlen);
+	usb_submit_urb(data->urb);
 
 	return 0;
 }
@@ -1350,7 +1380,7 @@
 	error = rum_do_request(sc, &req, buf);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
-		    usb2_errstr(error));
+		    usb_errstr(error));
 	}
 }
 
@@ -1380,7 +1410,7 @@
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "could not multi read MAC register: %s\n",
-		    usb2_errstr(error));
+		    usb_errstr(error));
 	}
 }
 
@@ -1408,7 +1438,7 @@
 	if (error != 0) {
 		device_printf(sc->sc_dev,
 		    "could not multi write MAC register: %s\n",
-		    usb2_errstr(error));
+		    usb_errstr(error));
 	}
 	return (error);
 }
@@ -1943,6 +1973,7 @@
 #define N(a)	(sizeof (a) / sizeof ((a)[0]))
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
+	struct usb_urb *urb;
 	uint32_t tmp;
 	usb_error_t error;
 	int i, ntries;
@@ -2008,10 +2039,16 @@
 	}
 	rum_write(sc, RT2573_TXRX_CSR0, tmp);
 
+	/*
+	 * Start up the receive pipe.
+	 */
+	urb = usb_get_urb(sc->sc_xfer[RUM_BULK_RD], 0);
+	usb_submit_urb(urb);
+
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
-	usb2_transfer_set_stall(sc->sc_xfer[RUM_BULK_WR]);
-	usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
+	usb_pipe_ready(sc->sc_xfer[RUM_BULK_WR]);
+	usb_pipe_ready(sc->sc_xfer[RUM_BULK_RD]);
 	return;
 
 fail:	rum_stop(sc);
@@ -2043,16 +2080,12 @@
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
-	RUM_UNLOCK(sc);
-
 	/*
 	 * Drain the USB transfers, if not already drained:
 	 */
-	usb_pipe_drain(sc->sc_xfer[RUM_BULK_WR]);
-	usb_pipe_drain(sc->sc_xfer[RUM_BULK_RD]);
+	usb_pipe_halt(sc->sc_xfer[RUM_BULK_WR]);
+	usb_pipe_halt(sc->sc_xfer[RUM_BULK_RD]);
 
-	RUM_LOCK(sc);
-
 	rum_unsetup_tx_list(sc);
 
 	/* disable Rx */
@@ -2091,7 +2124,7 @@
 	err = rum_do_request(sc, &req, NULL);
 	if (err != 0) {
 		device_printf(sc->sc_dev, "could not run firmware: %s\n",
-		    usb2_errstr(err));
+		    usb_errstr(err));
 	}
 
 	/* give the chip some time to boot */
@@ -2188,7 +2221,7 @@
 
 	ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
 
-	usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+	usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
 }
 
 static void
@@ -2226,7 +2259,7 @@
 
 	ifp->if_oerrors += fail;	/* count TX retry-fail as Tx errors */
 
-	usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
+	usb_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
 	RUM_UNLOCK(sc);
 }
 
@@ -2338,7 +2371,7 @@
 rum_pause(struct rum_softc *sc, int timeout)
 {
 
-	usb2_pause_mtx(&sc->sc_mtx, timeout);
+	usb_pause_mtx(&sc->sc_mtx, timeout);
 	return (0);
 }
 

==== //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rumvar.h#4 (text+ko) ====

@@ -17,8 +17,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RUM_TX_LIST_COUNT	8
-#define RUM_TX_MINFREE		2
+#define RUM_TX_LIST_COUNT	1
+#define RUM_TX_MINFREE		0
 
 struct rum_rx_radiotap_header {
 	struct ieee80211_radiotap_header wr_ihdr;
@@ -60,10 +60,11 @@
 struct rum_tx_data {
 	STAILQ_ENTRY(rum_tx_data)	next;
 	struct rum_softc		*sc;
-	struct rum_tx_desc		desc;
+	struct usb_urb			*urb;
 	struct mbuf			*m;
 	struct ieee80211_node		*ni;
-	int				rate;
+	uint8_t				*buf;
+	//int				rate;
 };
 typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead;
 
@@ -96,13 +97,12 @@
 	device_t			sc_dev;
 	struct usb_device		*sc_udev;
 
-	struct usb_xfer		*sc_xfer[RUM_N_TRANSFER];
+	struct usb_pipe		*sc_xfer[RUM_N_TRANSFER];
 
 	uint8_t				rf_rev;
 	uint8_t				rffreq;
 
 	struct rum_tx_data		tx_data[RUM_TX_LIST_COUNT];
-	rum_txdhead			tx_q;
 	rum_txdhead			tx_free;
 	int				tx_nfree;
 	struct rum_rx_desc		sc_rx_desc;


More information about the p4-projects mailing list