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