From owner-svn-src-all@FreeBSD.ORG Fri May 23 06:35:46 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 66B9D507; Fri, 23 May 2014 06:35:46 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5240627D6; Fri, 23 May 2014 06:35:46 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4N6Zk6p055008; Fri, 23 May 2014 06:35:46 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4N6ZjEO055006; Fri, 23 May 2014 06:35:45 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201405230635.s4N6ZjEO055006@svn.freebsd.org> From: Hans Petter Selasky Date: Fri, 23 May 2014 06:35:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r266577 - stable/10/sys/dev/usb/wlan X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 May 2014 06:35:46 -0000 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 * @@ -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;