svn commit: r266577 - stable/10/sys/dev/usb/wlan

Hans Petter Selasky hselasky at FreeBSD.org
Fri May 23 06:35:46 UTC 2014


Author: hselasky
Date: Fri May 23 06:35:45 2014
New Revision: 266577
URL: http://svnweb.freebsd.org/changeset/base/266577

Log:
  MFC r266466, r266471, r266484, r266505, r266535 and r266542:
  Fix multiple issues in the RSU driver.

Modified:
  stable/10/sys/dev/usb/wlan/if_rsu.c
  stable/10/sys/dev/usb/wlan/if_rsureg.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/usb/wlan/if_rsu.c
==============================================================================
--- stable/10/sys/dev/usb/wlan/if_rsu.c	Fri May 23 06:28:31 2014	(r266576)
+++ stable/10/sys/dev/usb/wlan/if_rsu.c	Fri May 23 06:35:45 2014	(r266577)
@@ -127,7 +127,10 @@ static const STRUCT_USB_HOST_ID rsu_devs
 static device_probe_t   rsu_match;
 static device_attach_t  rsu_attach;
 static device_detach_t  rsu_detach;
-static usb_callback_t   rsu_bulk_tx_callback;
+static usb_callback_t   rsu_bulk_tx_callback_0;
+static usb_callback_t   rsu_bulk_tx_callback_1;
+static usb_callback_t   rsu_bulk_tx_callback_2;
+static usb_callback_t   rsu_bulk_tx_callback_3;
 static usb_callback_t   rsu_bulk_rx_callback;
 static usb_error_t	rsu_do_request(struct rsu_softc *,
 			    struct usb_device_request *, void *);
@@ -186,7 +189,6 @@ static int	rsu_raw_xmit(struct ieee80211
 		    const struct ieee80211_bpf_params *);
 static void	rsu_init(void *);
 static void	rsu_init_locked(struct rsu_softc *);
-static void	rsu_watchdog(void *);
 static int	rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, 
 		    struct mbuf *, struct rsu_data *);
 static void	rsu_start(struct ifnet *);
@@ -194,6 +196,7 @@ static void	rsu_start_locked(struct ifne
 static int	rsu_ioctl(struct ifnet *, u_long, caddr_t);
 static void	rsu_stop(struct ifnet *, int);
 static void	rsu_stop_locked(struct ifnet *, int);
+static void	rsu_ms_delay(struct rsu_softc *);
 
 static device_method_t rsu_methods[] = {
 	DEVMETHOD(device_probe,		rsu_match),
@@ -239,7 +242,7 @@ static const struct usb_config rsu_confi
 			.pipe_bof = 1,
 			.force_short_xfer = 1
 		},
-		.callback = rsu_bulk_tx_callback,
+		.callback = rsu_bulk_tx_callback_0,
 		.timeout = RSU_TX_TIMEOUT
 	},
 	[RSU_BULK_TX_BK] = {
@@ -252,7 +255,7 @@ static const struct usb_config rsu_confi
 			.pipe_bof = 1,
 			.force_short_xfer = 1
 		},
-		.callback = rsu_bulk_tx_callback,
+		.callback = rsu_bulk_tx_callback_1,
 		.timeout = RSU_TX_TIMEOUT
 	},
 	[RSU_BULK_TX_VI] = {
@@ -265,7 +268,7 @@ static const struct usb_config rsu_confi
 			.pipe_bof = 1,
 			.force_short_xfer = 1
 		},
-		.callback = rsu_bulk_tx_callback,
+		.callback = rsu_bulk_tx_callback_2,
 		.timeout = RSU_TX_TIMEOUT
 	},
 	[RSU_BULK_TX_VO] = {
@@ -278,7 +281,7 @@ static const struct usb_config rsu_confi
 			.pipe_bof = 1,
 			.force_short_xfer = 1
 		},
-		.callback = rsu_bulk_tx_callback,
+		.callback = rsu_bulk_tx_callback_3,
 		.timeout = RSU_TX_TIMEOUT
 	},
 };
@@ -314,7 +317,20 @@ rsu_attach(device_t self)
 	    MTX_DEF);
 	TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, 
 	    rsu_calib_task, sc);
-	callout_init(&sc->sc_watchdog_ch, 0);
+
+	/* Allocate Tx/Rx buffers. */
+	error = rsu_alloc_rx_list(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Rx buffers\n");
+		goto fail_usb;
+	}
+
+	error = rsu_alloc_tx_list(sc);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Tx buffers\n");
+		rsu_free_rx_list(sc);
+		goto fail_usb;
+	}
 
 	iface_index = 0;
 	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
@@ -422,13 +438,10 @@ rsu_detach(device_t self)
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 
-	if (!device_is_attached(self))
-		return (0);
 	rsu_stop(ifp, 1);
 	usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
 	ieee80211_ifdetach(ic);
 
-	callout_drain(&sc->sc_watchdog_ch);
 	taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task);
 
 	/* Free Tx/Rx buffers. */
@@ -453,7 +466,7 @@ rsu_do_request(struct rsu_softc *sc, str
 	while (ntries--) {
 		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
 		    req, data, 0, NULL, 250 /* ms */);
-		if (err == 0 || !device_is_attached(sc->sc_dev))
+		if (err == 0 || err == USB_ERR_NOT_CONFIGURED)
 			break;
 		DPRINTFN(1, "Control request failed, %s (retrying)\n",
 		    usbd_errstr(err));
@@ -598,9 +611,12 @@ rsu_alloc_tx_list(struct rsu_softc *sc)
 	if (error != 0)
 		return (error);
 
-	STAILQ_INIT(&sc->sc_tx_active);
 	STAILQ_INIT(&sc->sc_tx_inactive);
-	STAILQ_INIT(&sc->sc_tx_pending);
+
+	for (i = 0; i != RSU_MAX_TX_EP; i++) {
+		STAILQ_INIT(&sc->sc_tx_active[i]);
+		STAILQ_INIT(&sc->sc_tx_pending[i]);
+	}
 
 	for (i = 0; i < RSU_TX_LIST_COUNT; i++) {
 		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
@@ -612,12 +628,26 @@ rsu_alloc_tx_list(struct rsu_softc *sc)
 static void
 rsu_free_tx_list(struct rsu_softc *sc)
 {
+	int i;
+
+	/* prevent further allocations from TX list(s) */
+	STAILQ_INIT(&sc->sc_tx_inactive);
+
+	for (i = 0; i != RSU_MAX_TX_EP; i++) {
+		STAILQ_INIT(&sc->sc_tx_active[i]);
+		STAILQ_INIT(&sc->sc_tx_pending[i]);
+	}
+
 	rsu_free_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT);
 }
 
 static void
 rsu_free_rx_list(struct rsu_softc *sc)
 {
+	/* prevent further allocations from RX list(s) */
+	STAILQ_INIT(&sc->sc_rx_inactive);
+	STAILQ_INIT(&sc->sc_rx_active);
+
 	rsu_free_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT);
 }
 
@@ -757,11 +787,11 @@ rsu_fw_iocmd(struct rsu_softc *sc, uint3
 	int ntries;
 
 	rsu_write_4(sc, R92S_IOCMD_CTRL, iocmd);
-	DELAY(100);
+	rsu_ms_delay(sc);
 	for (ntries = 0; ntries < 50; ntries++) {
 		if (rsu_read_4(sc, R92S_IOCMD_CTRL) == 0)
 			return (0);
-		DELAY(10);
+		rsu_ms_delay(sc);
 	}
 	return (ETIMEDOUT);
 }
@@ -781,7 +811,7 @@ rsu_efuse_read_1(struct rsu_softc *sc, u
 		reg = rsu_read_4(sc, R92S_EFUSE_CTRL);
 		if (reg & R92S_EFUSE_CTRL_VALID)
 			return (MS(reg, R92S_EFUSE_CTRL_DATA));
-		DELAY(5);
+		rsu_ms_delay(sc);
 	}
 	device_printf(sc->sc_dev,
 	    "could not read efuse byte at address 0x%x\n", addr);
@@ -805,7 +835,7 @@ rsu_read_rom(struct rsu_softc *sc)
 	/* Turn on 2.5V to prevent eFuse leakage. */
 	reg = rsu_read_1(sc, R92S_EFUSE_TEST + 3);
 	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg | 0x80);
-	DELAY(1000);
+	rsu_ms_delay(sc);
 	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg & ~0x80);
 
 	/* Read full ROM image. */
@@ -843,10 +873,12 @@ rsu_read_rom(struct rsu_softc *sc)
 static int
 rsu_fw_cmd(struct rsu_softc *sc, uint8_t code, void *buf, int len)
 {
+	const uint8_t which = RSU_BULK_TX_VO - RSU_BULK_TX_BE;
 	struct rsu_data *data;
 	struct r92s_tx_desc *txd;
 	struct r92s_fw_cmd_hdr *cmd;
-	int cmdsz, xferlen;
+	int cmdsz;
+	int xferlen;
 
 	data = rsu_getbuf(sc);
 	if (data == NULL)
@@ -879,8 +911,8 @@ rsu_fw_cmd(struct rsu_softc *sc, uint8_t
 
 	DPRINTFN(2, "Tx cmd code=0x%x len=0x%x\n", code, cmdsz);
 	data->buflen = xferlen;
-	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
-	usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_VO]);
+	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
+	usbd_transfer_start(sc->sc_xfer[which + RSU_BULK_TX_BE]);
 
 	return (0);
 }
@@ -1589,13 +1621,13 @@ rsu_txeof(struct usb_xfer *xfer, struct 
 		ieee80211_free_node(data->ni);
 		data->ni = NULL;
 	}
-	sc->sc_tx_timer = 0;
 	ifp->if_opackets++;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
 
 static void
-rsu_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
+rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
+    uint8_t which)
 {
 	struct rsu_softc *sc = usbd_xfer_softc(xfer);
 	struct ifnet *ifp = sc->sc_ifp;
@@ -1605,37 +1637,36 @@ rsu_bulk_tx_callback(struct usb_xfer *xf
 
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
-		data = STAILQ_FIRST(&sc->sc_tx_active);
+		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
 		if (data == NULL)
 			goto tr_setup;
 		DPRINTF("transfer done %p\n", data);
-		STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
+		STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
 		rsu_txeof(xfer, data);
 		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
 tr_setup:
-		data = STAILQ_FIRST(&sc->sc_tx_pending);
+		data = STAILQ_FIRST(&sc->sc_tx_pending[which]);
 		if (data == NULL) {
 			DPRINTF("empty pending queue sc %p\n", sc);
 			return;
 		}
-		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next);
-		STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
+		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next);
+		STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next);
 		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
 		DPRINTF("submitting transfer %p\n", data);
 		usbd_transfer_submit(xfer);
-		rsu_start_locked(ifp);
 		break;
 	default:
-		data = STAILQ_FIRST(&sc->sc_tx_active);
-		if (data == NULL)
-			goto tr_setup;
-		if (data->ni != NULL) {
-			ieee80211_free_node(data->ni);
-			data->ni = NULL;
-			ifp->if_oerrors++;
+		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
+		if (data != NULL) {
+			STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
+			rsu_txeof(xfer, data);
+			STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
 		}
+		ifp->if_oerrors++;
+
 		if (error != USB_ERR_CANCELLED) {
 			usbd_xfer_set_stall(xfer);
 			goto tr_setup;
@@ -1644,6 +1675,30 @@ tr_setup:
 	}
 }
 
+static void
+rsu_bulk_tx_callback_0(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, 0);
+}
+
+static void
+rsu_bulk_tx_callback_1(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, 1);
+}
+
+static void
+rsu_bulk_tx_callback_2(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, 2);
+}
+
+static void
+rsu_bulk_tx_callback_3(struct usb_xfer *xfer, usb_error_t error)
+{
+	rsu_bulk_tx_callback_sub(xfer, error, 3);
+}
+
 static int
 rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 
     struct mbuf *m0, struct rsu_data *data)
@@ -1654,15 +1709,11 @@ rsu_tx_start(struct rsu_softc *sc, struc
 	struct ieee80211_frame *wh;
 	struct ieee80211_key *k = NULL;
 	struct r92s_tx_desc *txd;
-	struct usb_xfer *xfer;
-	uint8_t type, tid = 0;
-	int hasqos, xferlen;
-	struct usb_xfer *rsu_pipes[4] = {
-		sc->sc_xfer[RSU_BULK_TX_BE],
-		sc->sc_xfer[RSU_BULK_TX_BK],
-		sc->sc_xfer[RSU_BULK_TX_VI],
-		sc->sc_xfer[RSU_BULK_TX_VO]
-	};
+	uint8_t type;
+	uint8_t tid = 0;
+	uint8_t which;
+	int hasqos;
+	int xferlen;
 
 	RSU_ASSERT_LOCKED(sc);
 
@@ -1683,12 +1734,12 @@ rsu_tx_start(struct rsu_softc *sc, struc
 	switch (type) {
 	case IEEE80211_FC0_TYPE_CTL:
 	case IEEE80211_FC0_TYPE_MGT:
-		xfer = sc->sc_xfer[RSU_BULK_TX_VO];
+		which = RSU_BULK_TX_VO - RSU_BULK_TX_BE;
 		break;
 	default:
-		KASSERT(M_WME_GETAC(m0) < 4,
-		    ("unsupported WME pipe %d", M_WME_GETAC(m0)));
-		xfer = rsu_pipes[M_WME_GETAC(m0)];
+		which = M_WME_GETAC(m0);
+		KASSERT(which < RSU_MAX_TX_EP,
+		    ("unsupported WME pipe %d", which));
 		break;
 	}
 	hasqos = 0;
@@ -1750,9 +1801,10 @@ rsu_tx_start(struct rsu_softc *sc, struc
 	data->buflen = xferlen;
 	data->ni = ni;
 	data->m = m0;
-	STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
-	usbd_transfer_start(xfer);
+	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
 
+	/* start transfer, if any */
+	usbd_transfer_start(sc->sc_xfer[which + RSU_BULK_TX_BE]);
 	return (0);
 }
 
@@ -1774,8 +1826,8 @@ rsu_start_locked(struct ifnet *ifp)
 {
 	struct rsu_softc *sc = ifp->if_softc;
 	struct ieee80211_node *ni;
-	struct mbuf *m;
 	struct rsu_data *bf;
+	struct mbuf *m;
 
 	RSU_ASSERT_LOCKED(sc);
 
@@ -1783,39 +1835,19 @@ rsu_start_locked(struct ifnet *ifp)
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL)
 			break;
-		bf = rsu_getbuf(sc);
-		if (bf == NULL) {
-			IFQ_DRV_PREPEND(&ifp->if_snd, m);
-			break;
-		}
 		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 		m->m_pkthdr.rcvif = NULL;
 
-		if (rsu_tx_start(sc, ni, m, bf) != 0) {
+		bf = rsu_getbuf(sc);
+		if (bf == NULL) {
+			ifp->if_iqdrops++;
+			m_freem(m);
+			ieee80211_free_node(ni);
+		} else if (rsu_tx_start(sc, ni, m, bf) != 0) {
 			ifp->if_oerrors++;
 			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
 			ieee80211_free_node(ni);
-			break;
-		}
-		sc->sc_tx_timer = 5;
-		callout_reset(&sc->sc_watchdog_ch, hz, rsu_watchdog, sc);
-	}
-}
-
-static void
-rsu_watchdog(void *arg)
-{
-	struct rsu_softc *sc = arg;
-	struct ifnet *ifp = sc->sc_ifp;
-
-	if (sc->sc_tx_timer > 0) {
-		if (--sc->sc_tx_timer == 0) {
-			device_printf(sc->sc_dev, "device timeout\n");
-			/* rsu_init(ifp); XXX needs a process context! */
-			ifp->if_oerrors++;
-			return;
 		}
-		callout_reset(&sc->sc_watchdog_ch, hz, rsu_watchdog, sc);
 	}
 }
 
@@ -1947,7 +1979,7 @@ rsu_power_on_bcut(struct rsu_softc *sc)
 
 	/* Prevent eFuse leakage. */
 	rsu_write_1(sc, 0x37, 0xb0);
-	usb_pause_mtx(&sc->sc_mtx, 10);
+	usb_pause_mtx(&sc->sc_mtx, hz / 100);
 	rsu_write_1(sc, 0x37, 0x30);
 
 	/* Switch the control path to hardware. */
@@ -1958,7 +1990,7 @@ rsu_power_on_bcut(struct rsu_softc *sc)
 	}
 	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
 	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) & ~0x8c);
-	DELAY(1000);
+	rsu_ms_delay(sc);
 
 	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53);
 	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57);
@@ -1991,11 +2023,11 @@ rsu_power_on_bcut(struct rsu_softc *sc)
 	/* Enable AFE PLL macro block. */
 	reg = rsu_read_1(sc, R92S_AFE_PLL_CTRL);
 	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
-	DELAY(500);
+	rsu_ms_delay(sc);
 	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x51);
-	DELAY(500);
+	rsu_ms_delay(sc);
 	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
-	DELAY(500);
+	rsu_ms_delay(sc);
 
 	/* Attach AFE PLL to MACTOP/BB. */
 	rsu_write_1(sc, R92S_SYS_ISO_CTRL,
@@ -2042,14 +2074,14 @@ rsu_power_on_bcut(struct rsu_softc *sc)
 		if ((reg & (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT)) ==
 		    (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT))
 			break;
-		DELAY(5);
+		rsu_ms_delay(sc);
 	}
 	if (ntries == 20) {
 		DPRINTF("TxDMA is not ready\n");
 		/* Reset TxDMA. */
 		reg = rsu_read_1(sc, R92S_CR);
 		rsu_write_1(sc, R92S_CR, reg & ~R92S_CR_TXDMA_EN);
-		DELAY(2);
+		rsu_ms_delay(sc);
 		rsu_write_1(sc, R92S_CR, reg | R92S_CR_TXDMA_EN);
 	}
 }
@@ -2059,7 +2091,7 @@ rsu_power_off(struct rsu_softc *sc)
 {
 	/* Turn RF off. */
 	rsu_write_1(sc, R92S_RF_CTRL, 0x00);
-	usb_pause_mtx(&sc->sc_mtx, 5);
+	usb_pause_mtx(&sc->sc_mtx, hz / 200);
 
 	/* Turn MAC off. */
 	/* Switch control path. */
@@ -2087,6 +2119,7 @@ rsu_power_off(struct rsu_softc *sc)
 static int
 rsu_fw_loadsection(struct rsu_softc *sc, const uint8_t *buf, int len)
 {
+	const uint8_t which = RSU_BULK_TX_VO - RSU_BULK_TX_BE;
 	struct rsu_data *data;
 	struct r92s_tx_desc *txd;
 	int mlen;
@@ -2107,12 +2140,11 @@ rsu_fw_loadsection(struct rsu_softc *sc,
 		memcpy(&txd[1], buf, mlen);
 		data->buflen = sizeof(*txd) + mlen;
 		DPRINTF("starting transfer %p\n", data);
-		STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next);
+		STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
 		buf += mlen;
 		len -= mlen;
 	}
-	usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_VO]);
-
+	usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_BE + which]);
 	return (0);
 }
 
@@ -2182,15 +2214,14 @@ rsu_load_firmware(struct rsu_softc *sc)
 		goto fail;
 	}
 	/* Wait for load to complete. */
-	for (ntries = 0; ntries < 10; ntries++) {
-		usb_pause_mtx(&sc->sc_mtx, 10);
+	for (ntries = 0; ntries != 50; ntries++) {
+		usb_pause_mtx(&sc->sc_mtx, hz / 100);
 		reg = rsu_read_2(sc, R92S_TCR);
 		if (reg & R92S_TCR_IMEM_CODE_DONE)
 			break;
 	}
-	if (ntries == 10 || !(reg & R92S_TCR_IMEM_CHK_RPT)) {
-		device_printf(sc->sc_dev, "timeout waiting for %s transfer\n",
-		    "IMEM");
+	if (ntries == 50) {
+		device_printf(sc->sc_dev, "timeout waiting for IMEM transfer\n");
 		error = ETIMEDOUT;
 		goto fail;
 	}
@@ -2203,15 +2234,14 @@ rsu_load_firmware(struct rsu_softc *sc)
 		goto fail;
 	}
 	/* Wait for load to complete. */
-	for (ntries = 0; ntries < 10; ntries++) {
-		usb_pause_mtx(&sc->sc_mtx, 10);
+	for (ntries = 0; ntries != 50; ntries++) {
+		usb_pause_mtx(&sc->sc_mtx, hz / 100);
 		reg = rsu_read_2(sc, R92S_TCR);
 		if (reg & R92S_TCR_EMEM_CODE_DONE)
 			break;
 	}
-	if (ntries == 10 || !(reg & R92S_TCR_EMEM_CHK_RPT)) {
-		device_printf(sc->sc_dev, "timeout waiting for %s transfer\n",
-		    "EMEM");
+	if (ntries == 50) {
+		device_printf(sc->sc_dev, "timeout waiting for EMEM transfer\n");
 		error = ETIMEDOUT;
 		goto fail;
 	}
@@ -2236,7 +2266,7 @@ rsu_load_firmware(struct rsu_softc *sc)
 	for (ntries = 0; ntries < 100; ntries++) {
 		if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_IMEM_RDY)
 			break;
-		DELAY(1000);
+		rsu_ms_delay(sc);
 	}
 	if (ntries == 100) {
 		device_printf(sc->sc_dev,
@@ -2249,7 +2279,7 @@ rsu_load_firmware(struct rsu_softc *sc)
 	dmem = __DECONST(struct r92s_fw_priv *, &hdr->priv);
 	memset(dmem, 0, sizeof(*dmem));
 	dmem->hci_sel = R92S_HCI_SEL_USB | R92S_HCI_SEL_8172;
-	dmem->nendpoints = sc->npipes;
+	dmem->nendpoints = 0;
 	dmem->rf_config = 0x12;	/* 1T2R */
 	dmem->vcs_type = R92S_VCS_TYPE_AUTO;
 	dmem->vcs_mode = R92S_VCS_MODE_RTS_CTS;
@@ -2268,7 +2298,7 @@ rsu_load_firmware(struct rsu_softc *sc)
 	for (ntries = 0; ntries < 100; ntries++) {
 		if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE)
 			break;
-		DELAY(1000);
+		rsu_ms_delay(sc);
 	}
 	if (ntries == 100) {
 		device_printf(sc->sc_dev, "timeout waiting for %s transfer\n",
@@ -2280,7 +2310,7 @@ rsu_load_firmware(struct rsu_softc *sc)
 	for (ntries = 0; ntries < 60; ntries++) {
 		if (!(rsu_read_2(sc, R92S_TCR) & R92S_TCR_FWRDY))
 			break;
-		DELAY(1000);
+		rsu_ms_delay(sc);
 	}
 	if (ntries == 60) {
 		device_printf(sc->sc_dev, 
@@ -2326,7 +2356,6 @@ rsu_raw_xmit(struct ieee80211_node *ni, 
 		return (EIO);
 	}
 	RSU_UNLOCK(sc);
-	sc->sc_tx_timer = 5;
 
 	return (0);
 }
@@ -2347,22 +2376,11 @@ rsu_init_locked(struct rsu_softc *sc)
 	struct ifnet *ifp = sc->sc_ifp;
 	struct r92s_set_pwr_mode cmd;
 	int error;
+	int i;
 
 	/* Init host async commands ring. */
 	sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
 
-	/* Allocate Tx/Rx buffers. */
-	error = rsu_alloc_rx_list(sc);
-	if (error != 0) {
-		device_printf(sc->sc_dev, "could not allocate Rx buffers\n");
-		return;
-	}
-	error = rsu_alloc_tx_list(sc);
-	if (error != 0) {
-		device_printf(sc->sc_dev, "could not allocate Tx buffers\n");
-		rsu_free_rx_list(sc);
-		return;
-	}
 	/* Power on adapter. */
 	if (sc->cut == 1)
 		rsu_power_on_acut(sc);
@@ -2401,8 +2419,8 @@ rsu_init_locked(struct rsu_softc *sc)
 	rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), 
 	    IEEE80211_ADDR_LEN);
 
-	/* NB: it really takes that long for firmware to boot. */
-	usb_pause_mtx(&sc->sc_mtx, 1500);
+	/* It really takes 1.5 seconds for the firmware to boot: */
+	usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2);
 
 	DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp)));
 	error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
@@ -2447,14 +2465,11 @@ rsu_init_locked(struct rsu_softc *sc)
 	/* We're ready to go. */
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
-	callout_reset(&sc->sc_watchdog_ch, hz, rsu_watchdog, sc);
-
 	return;
 fail:
-	rsu_free_rx_list(sc);
-	rsu_free_tx_list(sc);
-	return;
+	/* Need to stop all failed transfers, if any */
+	for (i = 0; i != RSU_N_TRANSFER; i++)
+		usbd_transfer_stop(sc->sc_xfer[i]);
 }
 
 static void
@@ -2474,7 +2489,6 @@ rsu_stop_locked(struct ifnet *ifp, int d
 	int i;
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-	callout_stop(&sc->sc_watchdog_ch);
 	sc->sc_calibrating = 0;
 	taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL);
 
@@ -2485,3 +2499,8 @@ rsu_stop_locked(struct ifnet *ifp, int d
 		usbd_transfer_stop(sc->sc_xfer[i]);
 }
 
+static void
+rsu_ms_delay(struct rsu_softc *sc)
+{
+	usb_pause_mtx(&sc->sc_mtx, hz / 1000);
+}

Modified: stable/10/sys/dev/usb/wlan/if_rsureg.h
==============================================================================
--- stable/10/sys/dev/usb/wlan/if_rsureg.h	Fri May 23 06:28:31 2014	(r266576)
+++ stable/10/sys/dev/usb/wlan/if_rsureg.h	Fri May 23 06:35:45 2014	(r266577)
@@ -1,4 +1,3 @@
-
 /*-
  * Copyright (c) 2010 Damien Bergamini <damien.bergamini at free.fr>
  *
@@ -18,9 +17,6 @@
  * $FreeBSD$
  */
 
-/* Maximum number of pipes is 11. */
-#define R92S_MAX_EP	11
-
 /* USB Requests. */
 #define R92S_REQ_REGS	0x05
 
@@ -519,7 +515,7 @@ struct r92s_rx_stat {
 
 	uint32_t	rxdw4;
 	uint32_t	rxdw5;
-} __packed __attribute__((aligned(4)));
+} __packed __aligned(4);
 
 /* Rx PHY descriptor. */
 struct r92s_rx_phystat {
@@ -531,7 +527,7 @@ struct r92s_rx_phystat {
 	uint32_t	phydw5;
 	uint32_t	phydw6;
 	uint32_t	phydw7;
-} __packed __attribute__((aligned(4)));
+} __packed __aligned(4);
 
 /* Rx PHY CCK descriptor. */
 struct r92s_rx_cck {
@@ -595,18 +591,14 @@ struct r92s_tx_desc {
 
 	uint16_t	txbufsize;
 	uint16_t	reserved1;
-} __packed __attribute__((aligned(4)));
+} __packed __aligned(4);
 
 
 /*
  * Driver definitions.
  */
 #define RSU_RX_LIST_COUNT	1
-#ifdef __OpenBSD__
-#define RSU_TX_LIST_COUNT	(8 + 1)	/* NB: +1 for FW commands. */
-#else
 #define RSU_TX_LIST_COUNT	32
-#endif
 
 #define RSU_HOST_CMD_RING_COUNT	32
 
@@ -735,6 +727,8 @@ struct rsu_vap {
 #define	RSU_UNLOCK(sc)			mtx_unlock(&(sc)->sc_mtx)
 #define	RSU_ASSERT_LOCKED(sc)		mtx_assert(&(sc)->sc_mtx, MA_OWNED)
 
+#define	RSU_MAX_TX_EP			4
+
 struct rsu_softc {
 	struct ifnet			*sc_ifp;
 	device_t			sc_dev;
@@ -743,15 +737,11 @@ struct rsu_softc {
 					    enum ieee80211_state, int);
 	struct usbd_interface		*sc_iface;
 	struct timeout_task		calib_task;
-	struct callout			sc_watchdog_ch;
-	struct usbd_pipe		*pipe[R92S_MAX_EP];
-	int				npipes;
 	const uint8_t			*qid2idx;
 	struct mtx			sc_mtx;
 
 	u_int				cut;
 	int				scan_pass;
-	int				sc_tx_timer;
 	struct rsu_host_cmd_ring	cmdq;
 	struct rsu_data			sc_rx[RSU_RX_LIST_COUNT];
 	struct rsu_data			sc_tx[RSU_TX_LIST_COUNT];
@@ -764,9 +754,9 @@ struct rsu_softc {
 
 	STAILQ_HEAD(, rsu_data)		sc_rx_active;
 	STAILQ_HEAD(, rsu_data)		sc_rx_inactive;
-	STAILQ_HEAD(, rsu_data)		sc_tx_active;
+	STAILQ_HEAD(, rsu_data)		sc_tx_active[RSU_MAX_TX_EP];
 	STAILQ_HEAD(, rsu_data)		sc_tx_inactive;
-	STAILQ_HEAD(, rsu_data)		sc_tx_pending;
+	STAILQ_HEAD(, rsu_data)		sc_tx_pending[RSU_MAX_TX_EP];
 
 	union {
 		struct rsu_rx_radiotap_header th;


More information about the svn-src-all mailing list