svn commit: r291902 - head/sys/dev/usb/wlan
Kevin Lo
kevlo at FreeBSD.org
Sun Dec 6 14:07:59 UTC 2015
Author: kevlo
Date: Sun Dec 6 14:07:57 2015
New Revision: 291902
URL: https://svnweb.freebsd.org/changeset/base/291902
Log:
- Fix Tx queues to USB endpoints mapping
- Merge urtwn_r92c_dma_init() and urtwn_r88e_dma_init() into one
Reviewed by: adrian, avos
Differential Revision: https://reviews.freebsd.org/D4381
Modified:
head/sys/dev/usb/wlan/if_urtwn.c
head/sys/dev/usb/wlan/if_urtwnvar.h
Modified: head/sys/dev/usb/wlan/if_urtwn.c
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c Sun Dec 6 08:20:07 2015 (r291901)
+++ head/sys/dev/usb/wlan/if_urtwn.c Sun Dec 6 14:07:57 2015 (r291902)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/condvar.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
@@ -70,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_device.h>
#include "usbdevs.h"
#define USB_DEBUG_VAR urtwn_debug
@@ -265,8 +267,7 @@ static void urtwn_r88e_fw_reset(struct
static int urtwn_fw_loadpage(struct urtwn_softc *, int,
const uint8_t *, int);
static int urtwn_load_firmware(struct urtwn_softc *);
-static int urtwn_r92c_dma_init(struct urtwn_softc *);
-static int urtwn_r88e_dma_init(struct urtwn_softc *);
+static int urtwn_dma_init(struct urtwn_softc *);
static int urtwn_mac_init(struct urtwn_softc *);
static void urtwn_bb_init(struct urtwn_softc *);
static void urtwn_rf_init(struct urtwn_softc *);
@@ -396,7 +397,7 @@ urtwn_attach(device_t self)
struct usb_attach_arg *uaa = device_get_ivars(self);
struct urtwn_softc *sc = device_get_softc(self);
struct ieee80211com *ic = &sc->sc_ic;
- uint8_t iface_index, bands;
+ uint8_t bands;
int error;
device_set_usb_desc(self);
@@ -410,9 +411,9 @@ urtwn_attach(device_t self)
callout_init(&sc->sc_watchdog_ch, 0);
mbufq_init(&sc->sc_snd, ifqmaxlen);
- iface_index = URTWN_IFACE_INDEX;
- error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
- urtwn_config, URTWN_N_TRANSFER, sc, &sc->sc_mtx);
+ sc->sc_iface_index = URTWN_IFACE_INDEX;
+ error = usbd_transfer_setup(uaa->device, &sc->sc_iface_index,
+ sc->sc_xfer, urtwn_config, URTWN_N_TRANSFER, sc, &sc->sc_mtx);
if (error) {
device_printf(self, "could not allocate USB transfers, "
"err=%s\n", usbd_errstr(error));
@@ -1471,7 +1472,6 @@ urtwn_read_rom(struct urtwn_softc *sc)
sc->sc_rf_write = urtwn_r92c_rf_write;
sc->sc_power_on = urtwn_r92c_power_on;
- sc->sc_dma_init = urtwn_r92c_dma_init;
return (0);
}
@@ -1503,7 +1503,6 @@ urtwn_r88e_read_rom(struct urtwn_softc *
sc->sc_rf_write = urtwn_r88e_rf_write;
sc->sc_power_on = urtwn_r88e_power_on;
- sc->sc_dma_init = urtwn_r88e_dma_init;
return (0);
}
@@ -2811,86 +2810,103 @@ fail:
return (error);
}
-static __inline int
+static int
urtwn_dma_init(struct urtwn_softc *sc)
{
+ struct usb_endpoint *ep, *ep_end;
usb_error_t usb_err;
- int error;
+ uint32_t reg;
+ int hashq, hasnq, haslq, nqueues, ntx;
+ int error, pagecount, npubqpages, nqpages, nrempages, tx_boundary;
/* Initialize LLT table. */
error = urtwn_llt_init(sc);
if (error != 0)
return (error);
- error = sc->sc_dma_init(sc);
- if (error != 0)
- return (error);
-
- /* Set Tx/Rx transfer page size. */
- usb_err = urtwn_write_1(sc, R92C_PBP,
- SM(R92C_PBP_PSRX, R92C_PBP_128) |
- SM(R92C_PBP_PSTX, R92C_PBP_128));
- if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ /* Determine the number of bulk-out pipes. */
+ ntx = 0;
+ ep = sc->sc_udev->endpoints;
+ ep_end = sc->sc_udev->endpoints + sc->sc_udev->endpoints_max;
+ for (; ep != ep_end; ep++) {
+ if ((ep->edesc == NULL) ||
+ (ep->iface_index != sc->sc_iface_index))
+ continue;
+ if (UE_GET_DIR(ep->edesc->bEndpointAddress) == UE_DIR_OUT)
+ ntx++;
+ }
+ if (ntx == 0) {
+ device_printf(sc->sc_dev,
+ "%d: invalid number of Tx bulk pipes\n", ntx);
return (EIO);
-
- return (0);
-}
-
-static int
-urtwn_r92c_dma_init(struct urtwn_softc *sc)
-{
- int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
- usb_error_t error;
- uint32_t reg;
+ }
/* Get Tx queues to USB endpoints mapping. */
- hashq = hasnq = haslq = 0;
- reg = urtwn_read_2(sc, R92C_USB_EP + 1);
- DPRINTFN(2, "USB endpoints mapping 0x%x\n", reg);
- if (MS(reg, R92C_USB_EP_HQ) != 0)
- hashq = 1;
- if (MS(reg, R92C_USB_EP_NQ) != 0)
- hasnq = 1;
- if (MS(reg, R92C_USB_EP_LQ) != 0)
- haslq = 1;
+ hashq = hasnq = haslq = nqueues = 0;
+ switch (ntx) {
+ case 1: hashq = 1; break;
+ case 2: hashq = hasnq = 1; break;
+ case 3: case 4: hashq = hasnq = haslq = 1; break;
+ }
nqueues = hashq + hasnq + haslq;
if (nqueues == 0)
return (EIO);
- /* Get the number of pages for each queue. */
- nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
- /* The remaining pages are assigned to the high priority queue. */
- nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
+
+ npubqpages = nqpages = nrempages = pagecount = 0;
+ if (sc->chip & URTWN_CHIP_88E)
+ tx_boundary = R88E_TX_PAGE_BOUNDARY;
+ else {
+ pagecount = R92C_TX_PAGE_COUNT;
+ npubqpages = R92C_PUBQ_NPAGES;
+ tx_boundary = R92C_TX_PAGE_BOUNDARY;
+ }
/* Set number of pages for normal priority queue. */
- error = urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_4(sc, R92C_RQPN,
- /* Set number of pages for public queue. */
- SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
- /* Set number of pages for high priority queue. */
- SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
- /* Set number of pages for low priority queue. */
- SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
- /* Load values. */
- R92C_RQPN_LD);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
+ if (sc->chip & URTWN_CHIP_88E) {
+ usb_err = urtwn_write_2(sc, R92C_RQPN_NPQ, 0xd);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ usb_err = urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ } else {
+ /* Get the number of pages for each queue. */
+ nqpages = (pagecount - npubqpages) / nqueues;
+ /*
+ * The remaining pages are assigned to the high priority
+ * queue.
+ */
+ nrempages = (pagecount - npubqpages) % nqueues;
+ usb_err = urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ usb_err = urtwn_write_4(sc, R92C_RQPN,
+ /* Set number of pages for public queue. */
+ SM(R92C_RQPN_PUBQ, npubqpages) |
+ /* Set number of pages for high priority queue. */
+ SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
+ /* Set number of pages for low priority queue. */
+ SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
+ /* Load values. */
+ R92C_RQPN_LD);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ }
- error = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, tx_boundary);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
- error = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, tx_boundary);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
- error = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, tx_boundary);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
- error = urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_1(sc, R92C_TRXFF_BNDY, tx_boundary);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
- error = urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_1(sc, R92C_TDECTRL + 1, tx_boundary);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
/* Set queue to USB pipe mapping. */
@@ -2913,72 +2929,21 @@ urtwn_r92c_dma_init(struct urtwn_softc *
reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
} else
reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
- error = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
/* Set Tx/Rx transfer page boundary. */
- error = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
-
- return (0);
-}
-
-static int
-urtwn_r88e_dma_init(struct urtwn_softc *sc)
-{
- struct usb_interface *iface;
- uint32_t reg;
- usb_error_t error;
- int nqueues;
-
- /* Get Tx queues to USB endpoints mapping. */
- iface = usbd_get_iface(sc->sc_udev, 0);
- nqueues = iface->idesc->bNumEndpoints - 1;
- if (nqueues == 0)
- return (EIO);
-
- /* Set number of pages for normal priority queue. */
- error = urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
-
- error = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R88E_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R88E_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R88E_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_1(sc, R92C_TRXFF_BNDY, R88E_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
- error = urtwn_write_1(sc, R92C_TDECTRL + 1, R88E_TX_PAGE_BOUNDARY);
- if (error != USB_ERR_NORMAL_COMPLETION)
- return (EIO);
-
- /* Set queue to USB pipe mapping. */
- reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
- reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
- if (nqueues == 1)
- reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
- else if (nqueues == 2)
- reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
- else
- reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
- error = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ usb_err = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2,
+ (sc->chip & URTWN_CHIP_88E) ? 0x23ff : 0x27ff);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
- /* Set Tx/Rx transfer page boundary. */
- error = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x23ff);
- if (error != USB_ERR_NORMAL_COMPLETION)
+ /* Set Tx/Rx transfer page size. */
+ usb_err = urtwn_write_1(sc, R92C_PBP,
+ SM(R92C_PBP_PSRX, R92C_PBP_128) |
+ SM(R92C_PBP_PSTX, R92C_PBP_128));
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
return (EIO);
return (0);
Modified: head/sys/dev/usb/wlan/if_urtwnvar.h
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 6 08:20:07 2015 (r291901)
+++ head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 6 14:07:57 2015 (r291902)
@@ -139,6 +139,7 @@ struct urtwn_softc {
device_t sc_dev;
struct usb_device *sc_udev;
+ uint8_t sc_iface_index;
int ac2idx[WME_NUM_AC];
u_int sc_flags;
#define URTWN_FLAG_CCK_HIPWR 0x01
@@ -155,7 +156,6 @@ struct urtwn_softc {
void (*sc_rf_write)(struct urtwn_softc *,
int, uint8_t, uint32_t);
int (*sc_power_on)(struct urtwn_softc *);
- int (*sc_dma_init)(struct urtwn_softc *);
uint8_t board_type;
uint8_t regulatory;
More information about the svn-src-head
mailing list