Date: Fri, 5 Jun 2009 21:25:54 GMT From: Andrew Thompson <thompsa@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 163611 for review Message-ID: <200906052125.n55LPsof070789@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163611 Change 163611 by thompsa@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906052125.n55LPsof070789>