Author: hselasky
Date: Wed Jun  4 09:18:13 2014
New Revision: 267041
URL: http://svnweb.freebsd.org/changeset/base/267041

Log:
  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
  that packets transmitted don't get out of order.
  
  MFC after:    1 week

Modified:
  head/sys/dev/usb/wlan/if_rsu.c
  head/sys/dev/usb/wlan/if_rsureg.h

Modified: head/sys/dev/usb/wlan/if_rsu.c
==============================================================================
--- head/sys/dev/usb/wlan/if_rsu.c      Wed Jun  4 06:21:54 2014        
(r267040)
+++ head/sys/dev/usb/wlan/if_rsu.c      Wed Jun  4 09:18:13 2014        
(r267041)
@@ -128,10 +128,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 *);
@@ -221,6 +219,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,
@@ -233,20 +238,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,
@@ -256,10 +248,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,
@@ -269,20 +261,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
        },
 };
@@ -614,7 +593,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]);
        }
@@ -634,7 +613,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]);
        }
@@ -874,7 +853,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;
@@ -913,7 +892,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);
 }
@@ -926,6 +905,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. */
@@ -942,12 +922,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
@@ -1001,11 +978,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));
 }
 
@@ -1271,6 +1247,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 &&
@@ -1280,6 +1259,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;
@@ -1289,6 +1269,8 @@ rsu_rx_event(struct rsu_softc *sc, uint8
                        printf("FWDBG: %s\n", (char *)buf);
                }
                break;
+       default:
+               break;
        }
 }
 
@@ -1662,27 +1644,15 @@ tr_setup:
 }
 
 static void
-rsu_bulk_tx_callback_0(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, 0);
+       rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_BE_BK);
 }
 
 static void
-rsu_bulk_tx_callback_1(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, 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);
+       rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO);
 }
 
 static int
@@ -1720,12 +1690,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;
@@ -1790,7 +1758,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);
 }
 
@@ -2105,7 +2073,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;
@@ -2130,7 +2098,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);
 }
 
@@ -2146,6 +2114,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) {
@@ -2202,7 +2175,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;
        }
@@ -2211,7 +2184,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) {
@@ -2231,7 +2203,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);
@@ -2250,7 +2221,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);
        }
@@ -2282,7 +2253,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);
        }
@@ -2294,7 +2265,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);
        }
@@ -2372,6 +2343,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: head/sys/dev/usb/wlan/if_rsureg.h
==============================================================================
--- head/sys/dev/usb/wlan/if_rsureg.h   Wed Jun  4 06:21:54 2014        
(r267040)
+++ head/sys/dev/usb/wlan/if_rsureg.h   Wed Jun  4 09:18:13 2014        
(r267041)
@@ -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;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to