From owner-svn-src-stable@FreeBSD.ORG Wed Jun 11 05:50:05 2014 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 330EC541; Wed, 11 Jun 2014 05:50:05 +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 149542B3B; Wed, 11 Jun 2014 05:50:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s5B5o4EV058527; Wed, 11 Jun 2014 05:50:04 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s5B5o4p5058524; Wed, 11 Jun 2014 05:50:04 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201406110550.s5B5o4p5058524@svn.freebsd.org> From: Hans Petter Selasky Date: Wed, 11 Jun 2014 05:50:04 +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: r267349 - 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-stable@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Jun 2014 05:50:05 -0000 Author: hselasky Date: Wed Jun 11 05:50:04 2014 New Revision: 267349 URL: http://svnweb.freebsd.org/changeset/base/267349 Log: MFC r267066 and r267041: Fixes for the RSU driver: - The R92S_TCR register is an 8-bit register. Don't access it like a 16-bit register. - Disable parsing the delete station event, due to many false events. - Ensure that there is only one transfer queue for each endpoint, so to hal packets transmitted don't get out of order. - Properly align temporary buffer to 32-bit. - Add an extra parenthesis to make expression clear. - Range check the association ID received from hardware. 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 Wed Jun 11 05:45:48 2014 (r267348) +++ stable/10/sys/dev/usb/wlan/if_rsu.c Wed Jun 11 05:50:04 2014 (r267349) @@ -127,10 +127,8 @@ 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_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_tx_callback_be_bk; +static usb_callback_t rsu_bulk_tx_callback_vi_vo; static usb_callback_t rsu_bulk_rx_callback; static usb_error_t rsu_do_request(struct rsu_softc *, struct usb_device_request *, void *); @@ -220,6 +218,13 @@ MODULE_DEPEND(rsu, usb, 1, 1, 1); MODULE_DEPEND(rsu, firmware, 1, 1, 1); MODULE_VERSION(rsu, 1); +static uint8_t rsu_wme_ac_xfer_map[4] = { + [WME_AC_BE] = RSU_BULK_TX_BE_BK, + [WME_AC_BK] = RSU_BULK_TX_BE_BK, + [WME_AC_VI] = RSU_BULK_TX_VI_VO, + [WME_AC_VO] = RSU_BULK_TX_VI_VO, +}; + static const struct usb_config rsu_config[RSU_N_TRANSFER] = { [RSU_BULK_RX] = { .type = UE_BULK, @@ -232,20 +237,7 @@ static const struct usb_config rsu_confi }, .callback = rsu_bulk_rx_callback }, - [RSU_BULK_TX_BE] = { - .type = UE_BULK, - .endpoint = 0x06, - .direction = UE_DIR_OUT, - .bufsize = RSU_TXBUFSZ, - .flags = { - .ext_buffer = 1, - .pipe_bof = 1, - .force_short_xfer = 1 - }, - .callback = rsu_bulk_tx_callback_0, - .timeout = RSU_TX_TIMEOUT - }, - [RSU_BULK_TX_BK] = { + [RSU_BULK_TX_BE_BK] = { .type = UE_BULK, .endpoint = 0x06, .direction = UE_DIR_OUT, @@ -255,10 +247,10 @@ static const struct usb_config rsu_confi .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback_1, + .callback = rsu_bulk_tx_callback_be_bk, .timeout = RSU_TX_TIMEOUT }, - [RSU_BULK_TX_VI] = { + [RSU_BULK_TX_VI_VO] = { .type = UE_BULK, .endpoint = 0x04, .direction = UE_DIR_OUT, @@ -268,20 +260,7 @@ static const struct usb_config rsu_confi .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback_2, - .timeout = RSU_TX_TIMEOUT - }, - [RSU_BULK_TX_VO] = { - .type = UE_BULK, - .endpoint = 0x04, - .direction = UE_DIR_OUT, - .bufsize = RSU_TXBUFSZ, - .flags = { - .ext_buffer = 1, - .pipe_bof = 1, - .force_short_xfer = 1 - }, - .callback = rsu_bulk_tx_callback_3, + .callback = rsu_bulk_tx_callback_vi_vo, .timeout = RSU_TX_TIMEOUT }, }; @@ -613,7 +592,7 @@ rsu_alloc_tx_list(struct rsu_softc *sc) STAILQ_INIT(&sc->sc_tx_inactive); - for (i = 0; i != RSU_MAX_TX_EP; i++) { + for (i = 0; i != RSU_N_TRANSFER; i++) { STAILQ_INIT(&sc->sc_tx_active[i]); STAILQ_INIT(&sc->sc_tx_pending[i]); } @@ -633,7 +612,7 @@ rsu_free_tx_list(struct rsu_softc *sc) /* prevent further allocations from TX list(s) */ STAILQ_INIT(&sc->sc_tx_inactive); - for (i = 0; i != RSU_MAX_TX_EP; i++) { + for (i = 0; i != RSU_N_TRANSFER; i++) { STAILQ_INIT(&sc->sc_tx_active[i]); STAILQ_INIT(&sc->sc_tx_pending[i]); } @@ -873,7 +852,7 @@ 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; + const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO]; struct rsu_data *data; struct r92s_tx_desc *txd; struct r92s_fw_cmd_hdr *cmd; @@ -912,7 +891,7 @@ 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[which], data, next); - usbd_transfer_start(sc->sc_xfer[which + RSU_BULK_TX_BE]); + usbd_transfer_start(sc->sc_xfer[which]); return (0); } @@ -925,6 +904,7 @@ rsu_calib_task(void *arg, int pending __ uint32_t reg; DPRINTFN(6, "running calibration task\n"); + RSU_LOCK(sc); #ifdef notyet /* Read WPS PBC status. */ @@ -941,12 +921,9 @@ rsu_calib_task(void *arg, int pending __ reg = rsu_read_4(sc, R92S_IOCMD_DATA); DPRINTFN(8, "RSSI=%d%%\n", reg >> 4); } - if (sc->sc_calibrating) { - RSU_UNLOCK(sc); - taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, - hz * 2); - } else - RSU_UNLOCK(sc); + if (sc->sc_calibrating) + taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz); + RSU_UNLOCK(sc); } static int @@ -1000,11 +977,10 @@ rsu_newstate(struct ieee80211vap *vap, e break; } sc->sc_calibrating = 1; + /* Start periodic calibration. */ + taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz); RSU_UNLOCK(sc); IEEE80211_LOCK(ic); - /* Start periodic calibration. */ - taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz * 2); - return (uvp->newstate(vap, nstate, arg)); } @@ -1080,7 +1056,8 @@ rsu_join_bss(struct rsu_softc *sc, struc struct ndis_wlan_bssid_ex *bss; struct ndis_802_11_fixed_ies *fixed; struct r92s_fw_cmd_auth auth; - uint8_t buf[sizeof(*bss) + 128], *frm; + uint8_t buf[sizeof(*bss) + 128] __aligned(4); + uint8_t *frm; uint8_t opmode; int error; @@ -1094,7 +1071,7 @@ rsu_join_bss(struct rsu_softc *sc, struc memset(&auth, 0, sizeof(auth)); if (vap->iv_flags & IEEE80211_F_WPA) { auth.mode = R92S_AUTHMODE_WPA; - auth.dot1x = ni->ni_authmode == IEEE80211_AUTH_8021X; + auth.dot1x = (ni->ni_authmode == IEEE80211_AUTH_8021X); } else auth.mode = R92S_AUTHMODE_OPEN; DPRINTF("setting auth mode to %d\n", auth.mode); @@ -1222,6 +1199,7 @@ rsu_event_join_bss(struct rsu_softc *sc, struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; struct r92s_event_join_bss *rsp; + uint32_t tmp; int res; if (__predict_false(len < sizeof(*rsp))) @@ -1236,9 +1214,14 @@ rsu_event_join_bss(struct rsu_softc *sc, RSU_LOCK(sc); return; } + tmp = le32toh(rsp->associd); + if (tmp >= vap->iv_max_aid) { + DPRINTF("Assoc ID overflow\n"); + tmp = 1; + } DPRINTF("associated with %s associd=%d\n", - ether_sprintf(rsp->bss.macaddr), le32toh(rsp->associd)); - ni->ni_associd = le32toh(rsp->associd) | 0xc000; + ether_sprintf(rsp->bss.macaddr), tmp); + ni->ni_associd = tmp | 0xc000; RSU_UNLOCK(sc); ieee80211_new_state(vap, IEEE80211_S_RUN, IEEE80211_FC0_SUBTYPE_ASSOC_RESP); @@ -1277,6 +1260,9 @@ rsu_rx_event(struct rsu_softc *sc, uint8 if (vap->iv_state == IEEE80211_S_AUTH) rsu_event_join_bss(sc, buf, len); break; +#if 0 +XXX This event is occurring regularly, possibly due to some power saving event +XXX and disrupts the WLAN traffic. Disable for now. case R92S_EVT_DEL_STA: DPRINTF("disassociated from %s\n", ether_sprintf(buf)); if (vap->iv_state == IEEE80211_S_RUN && @@ -1286,6 +1272,7 @@ rsu_rx_event(struct rsu_softc *sc, uint8 RSU_LOCK(sc); } break; +#endif case R92S_EVT_WPS_PBC: DPRINTF("WPS PBC pushed.\n"); break; @@ -1295,6 +1282,8 @@ rsu_rx_event(struct rsu_softc *sc, uint8 printf("FWDBG: %s\n", (char *)buf); } break; + default: + break; } } @@ -1676,27 +1665,15 @@ 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_be_bk(struct usb_xfer *xfer, usb_error_t error) { - rsu_bulk_tx_callback_sub(xfer, error, 1); + rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_BE_BK); } static void -rsu_bulk_tx_callback_2(struct usb_xfer *xfer, usb_error_t error) +rsu_bulk_tx_callback_vi_vo(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); + rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO); } static int @@ -1734,12 +1711,10 @@ rsu_tx_start(struct rsu_softc *sc, struc switch (type) { case IEEE80211_FC0_TYPE_CTL: case IEEE80211_FC0_TYPE_MGT: - which = RSU_BULK_TX_VO - RSU_BULK_TX_BE; + which = rsu_wme_ac_xfer_map[WME_AC_VO]; break; default: - which = M_WME_GETAC(m0); - KASSERT(which < RSU_MAX_TX_EP, - ("unsupported WME pipe %d", which)); + which = rsu_wme_ac_xfer_map[M_WME_GETAC(m0)]; break; } hasqos = 0; @@ -1804,7 +1779,7 @@ rsu_tx_start(struct rsu_softc *sc, struc 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]); + usbd_transfer_start(sc->sc_xfer[which]); return (0); } @@ -2119,7 +2094,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; + const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO]; struct rsu_data *data; struct r92s_tx_desc *txd; int mlen; @@ -2144,7 +2119,7 @@ rsu_fw_loadsection(struct rsu_softc *sc, buf += mlen; len -= mlen; } - usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_BE + which]); + usbd_transfer_start(sc->sc_xfer[which]); return (0); } @@ -2160,6 +2135,11 @@ rsu_load_firmware(struct rsu_softc *sc) uint32_t reg; int ntries, error; + if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY) { + DPRINTF("Firmware already loaded\n"); + return (0); + } + RSU_UNLOCK(sc); /* Read firmware image from the filesystem. */ if ((fw = firmware_get("rsu-rtl8712fw")) == NULL) { @@ -2216,7 +2196,7 @@ rsu_load_firmware(struct rsu_softc *sc) /* Wait for load to complete. */ for (ntries = 0; ntries != 50; ntries++) { usb_pause_mtx(&sc->sc_mtx, hz / 100); - reg = rsu_read_2(sc, R92S_TCR); + reg = rsu_read_1(sc, R92S_TCR); if (reg & R92S_TCR_IMEM_CODE_DONE) break; } @@ -2225,7 +2205,6 @@ rsu_load_firmware(struct rsu_softc *sc) error = ETIMEDOUT; goto fail; } - /* Load EMEM section. */ error = rsu_fw_loadsection(sc, emem, ememsz); if (error != 0) { @@ -2245,7 +2224,6 @@ rsu_load_firmware(struct rsu_softc *sc) error = ETIMEDOUT; goto fail; } - /* Enable CPU. */ rsu_write_1(sc, R92S_SYS_CLKR, rsu_read_1(sc, R92S_SYS_CLKR) | R92S_SYS_CPU_CLKSEL); @@ -2264,7 +2242,7 @@ rsu_load_firmware(struct rsu_softc *sc) } /* Wait for CPU to initialize. */ for (ntries = 0; ntries < 100; ntries++) { - if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_IMEM_RDY) + if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_IMEM_RDY) break; rsu_ms_delay(sc); } @@ -2296,7 +2274,7 @@ rsu_load_firmware(struct rsu_softc *sc) } /* Wait for load to complete. */ for (ntries = 0; ntries < 100; ntries++) { - if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE) + if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE) break; rsu_ms_delay(sc); } @@ -2308,7 +2286,7 @@ rsu_load_firmware(struct rsu_softc *sc) } /* Wait for firmware readiness. */ for (ntries = 0; ntries < 60; ntries++) { - if (!(rsu_read_2(sc, R92S_TCR) & R92S_TCR_FWRDY)) + if (!(rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY)) break; rsu_ms_delay(sc); } @@ -2386,6 +2364,7 @@ rsu_init_locked(struct rsu_softc *sc) rsu_power_on_acut(sc); else rsu_power_on_bcut(sc); + /* Load firmware. */ error = rsu_load_firmware(sc); if (error != 0) Modified: stable/10/sys/dev/usb/wlan/if_rsureg.h ============================================================================== --- stable/10/sys/dev/usb/wlan/if_rsureg.h Wed Jun 11 05:45:48 2014 (r267348) +++ stable/10/sys/dev/usb/wlan/if_rsureg.h Wed Jun 11 05:50:04 2014 (r267349) @@ -698,11 +698,9 @@ struct rsu_host_cmd_ring { enum { RSU_BULK_RX, - RSU_BULK_TX_BE, /* = WME_AC_BE */ - RSU_BULK_TX_BK, /* = WME_AC_BK */ - RSU_BULK_TX_VI, /* = WME_AC_VI */ - RSU_BULK_TX_VO, /* = WME_AC_VI */ - RSU_N_TRANSFER = 5, + RSU_BULK_TX_BE_BK, /* = WME_AC_BE/BK */ + RSU_BULK_TX_VI_VO, /* = WME_AC_VI/VO */ + RSU_N_TRANSFER, }; struct rsu_data { @@ -727,8 +725,6 @@ 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; @@ -754,9 +750,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[RSU_MAX_TX_EP]; + STAILQ_HEAD(, rsu_data) sc_tx_active[RSU_N_TRANSFER]; STAILQ_HEAD(, rsu_data) sc_tx_inactive; - STAILQ_HEAD(, rsu_data) sc_tx_pending[RSU_MAX_TX_EP]; + STAILQ_HEAD(, rsu_data) sc_tx_pending[RSU_N_TRANSFER]; union { struct rsu_rx_radiotap_header th;