diff --git a/sys/dev/rtwn/if_rtwnvar.h b/sys/dev/rtwn/if_rtwnvar.h --- a/sys/dev/rtwn/if_rtwnvar.h +++ b/sys/dev/rtwn/if_rtwnvar.h @@ -408,6 +408,7 @@ uint16_t bcn_status_reg[RTWN_PORT_COUNT]; uint32_t rcr; /* Rx filter */ + uint8_t chan_flag; }; MALLOC_DECLARE(M_RTWN_PRIV); diff --git a/sys/dev/rtwn/rtl8188e/r88e_reg.h b/sys/dev/rtwn/rtl8188e/r88e_reg.h --- a/sys/dev/rtwn/rtl8188e/r88e_reg.h +++ b/sys/dev/rtwn/rtl8188e/r88e_reg.h @@ -121,5 +121,6 @@ /* Bits for R88E_XCK_OUT_CTRL. */ #define R88E_XCK_OUT_CTRL_EN 1 +#define R88E_USB_DELAY_US_DEF 1000 #endif /* R88E_REG_H */ diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_attach.c @@ -58,6 +58,7 @@ #include /* for 'macaddr' field */ #include +#include static struct rtwn_r88e_txpwr r88e_txpwr; @@ -122,6 +123,7 @@ /* USB part. */ uc->uc_align_rx = r92cu_align_rx; uc->tx_agg_desc_num = 6; + uc->uc_delay_us = R88E_USB_DELAY_US_DEF; /* Common part. */ sc->sc_flags = RTWN_FLAG_EXT_HDR; diff --git a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c --- a/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c +++ b/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c @@ -48,6 +48,8 @@ #include #include +#include + #include #include @@ -76,8 +78,12 @@ if (res != 0) \ return (EIO); \ } while(0) + struct rtwn_usb_softc *uc; int ntries; + if ((uc = RTWN_USB_SOFTC(sc)) != NULL) + uc->uc_write_delay = 1; + /* Wait for power ready bit. */ for (ntries = 0; ntries < 5000; ntries++) { if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST) @@ -85,6 +91,8 @@ rtwn_delay(sc, 10); } if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; device_printf(sc->sc_dev, "timeout waiting for chip power up\n"); return (ETIMEDOUT); @@ -112,8 +120,11 @@ break; rtwn_delay(sc, 10); } - if (ntries == 5000) + if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; return (ETIMEDOUT); + } /* Enable LDO normal mode. */ RTWN_CHK(rtwn_setbits_1(sc, R92C_LPLDO_CTRL, @@ -128,6 +139,8 @@ ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) | R92C_CR_CALTMR_EN)); + if (uc != NULL) + uc->uc_write_delay = 0; return (0); #undef RTWN_CHK } diff --git a/sys/dev/rtwn/rtl8192c/r92c_chan.c b/sys/dev/rtwn/rtl8192c/r92c_chan.c --- a/sys/dev/rtwn/rtl8192c/r92c_chan.c +++ b/sys/dev/rtwn/rtl8192c/r92c_chan.c @@ -364,6 +364,7 @@ u_int chan; int i; + sc->chan_flag = 1; chan = rtwn_chan2centieee(c); /* Set Tx power for this new channel. */ @@ -377,6 +378,8 @@ r92c_set_bw40(sc, chan, IEEE80211_IS_CHAN_HT40U(c)); else rtwn_r92c_set_bw20(sc, chan); + + sc->chan_flag = 0; } void diff --git a/sys/dev/rtwn/rtl8192c/r92c_reg.h b/sys/dev/rtwn/rtl8192c/r92c_reg.h --- a/sys/dev/rtwn/rtl8192c/r92c_reg.h +++ b/sys/dev/rtwn/rtl8192c/r92c_reg.h @@ -926,4 +926,6 @@ #define R92C_RF_T_METER_VAL_M 0x1f #define R92C_RF_T_METER_VAL_S 0 +#define R92C_USB_DELAY_US_DEF 1000 + #endif /* R92C_REG_H */ diff --git a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c --- a/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c +++ b/sys/dev/rtwn/rtl8192c/usb/r92cu_attach.c @@ -151,6 +151,7 @@ /* USB part. */ uc->uc_align_rx = r92cu_align_rx; uc->tx_agg_desc_num = 6; + uc->uc_delay_us = R92C_USB_DELAY_US_DEF; /* Common part. */ sc->sc_flags = RTWN_FLAG_CAM_FIXED; diff --git a/sys/dev/rtwn/rtl8192e/r92e_chan.c b/sys/dev/rtwn/rtl8192e/r92e_chan.c --- a/sys/dev/rtwn/rtl8192e/r92e_chan.c +++ b/sys/dev/rtwn/rtl8192e/r92e_chan.c @@ -238,6 +238,7 @@ u_int chan; int i; + sc->chan_flag = 1; chan = rtwn_chan2centieee(c); for (i = 0; i < sc->nrxchains; i++) { @@ -252,4 +253,5 @@ /* Set Tx power for this new channel. */ r92e_set_txpower(sc, c); + sc->chan_flag = 0; } diff --git a/sys/dev/rtwn/rtl8192e/r92e_init.c b/sys/dev/rtwn/rtl8192e/r92e_init.c --- a/sys/dev/rtwn/rtl8192e/r92e_init.c +++ b/sys/dev/rtwn/rtl8192e/r92e_init.c @@ -53,6 +53,8 @@ #include +#include + #include #include @@ -224,8 +226,12 @@ if (res != 0) \ return (EIO); \ } while(0) + struct rtwn_usb_softc *uc; int ntries; + if ((uc = RTWN_USB_SOFTC(sc)) != NULL) + uc->uc_write_delay = 1; + if (rtwn_read_4(sc, R92C_SYS_CFG) & R92C_SYS_CFG_TRP_BT_EN) RTWN_CHK(rtwn_write_1(sc, R92C_LDO_SWR_CTRL, 0xc3)); else { @@ -252,6 +258,8 @@ rtwn_delay(sc, 10); } if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; device_printf(sc->sc_dev, "timeout waiting for chip power up\n"); return (ETIMEDOUT); @@ -269,8 +277,11 @@ break; rtwn_delay(sc, 10); } - if (ntries == 5000) + if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; return (ETIMEDOUT); + } /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0)); @@ -281,18 +292,27 @@ ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) | R92C_CR_CALTMR_EN)); + if (uc != NULL) + uc->uc_write_delay = 0; return (0); } void r92e_power_off(struct rtwn_softc *sc) { + struct rtwn_usb_softc *uc; int error, ntries; + if ((uc = RTWN_USB_SOFTC(sc)) != NULL) + uc->uc_write_delay = 1; + /* Stop Rx. */ error = rtwn_write_1(sc, R92C_CR, 0); - if (error == ENXIO) /* hardware gone */ + if (error == ENXIO) { /* hardware gone */ + if (uc != NULL) + uc->uc_write_delay = 0; return; + } /* Move card to Low Power state. */ /* Block all Tx queues. */ @@ -306,6 +326,8 @@ rtwn_delay(sc, 10); } if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; device_printf(sc->sc_dev, "%s: failed to block Tx queues\n", __func__); return; @@ -363,6 +385,8 @@ rtwn_delay(sc, 10); } if (ntries == 5000) { + if (uc != NULL) + uc->uc_write_delay = 0; device_printf(sc->sc_dev, "%s: could not turn off MAC\n", __func__); return; @@ -385,4 +409,7 @@ /* Enable SW LPS. */ rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_RSM, 1); + + if (uc != NULL) + uc->uc_write_delay = 0; } diff --git a/sys/dev/rtwn/rtl8192e/r92e_reg.h b/sys/dev/rtwn/rtl8192e/r92e_reg.h --- a/sys/dev/rtwn/rtl8192e/r92e_reg.h +++ b/sys/dev/rtwn/rtl8192e/r92e_reg.h @@ -41,5 +41,6 @@ /* Bits for R92E_AFE_XTAL_CTRL. */ #define R92E_AFE_XTAL_CTRL_ADDR_M 0x00fff000 #define R92E_AFE_XTAL_CTRL_ADDR_S 12 +#define R92E_USB_DELAY_US_DEF 1000 #endif /* R92E_REG_H */ diff --git a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c --- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -100,6 +100,7 @@ /* USB part. */ uc->uc_align_rx = r12au_align_rx; uc->tx_agg_desc_num = 3; + uc->uc_delay_us = R92E_USB_DELAY_US_DEF; /* Common part. */ sc->sc_flags = RTWN_FLAG_EXT_HDR; diff --git a/sys/dev/rtwn/usb/rtwn_usb_attach.c b/sys/dev/rtwn/usb/rtwn_usb_attach.c --- a/sys/dev/rtwn/usb/rtwn_usb_attach.c +++ b/sys/dev/rtwn/usb/rtwn_usb_attach.c @@ -377,6 +377,11 @@ uc->uc_rx_buf_size = RTWN_USB_RXBUFSZ_MIN; if (uc->uc_rx_buf_size > RTWN_USB_RXBUFSZ_MAX) uc->uc_rx_buf_size = RTWN_USB_RXBUFSZ_MAX; + + uc->uc_delay_us = RTWN_USB_DELAY_US_DEF; + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "delay_us", CTLFLAG_RWTUN, &uc->uc_delay_us, + uc->uc_delay_us, "RTWN USB set channel delay microseconds"); } static int @@ -419,6 +424,7 @@ if (error != 0) goto detach; + sc->chan_flag = 0; return (0); detach: diff --git a/sys/dev/rtwn/usb/rtwn_usb_reg.c b/sys/dev/rtwn/usb/rtwn_usb_reg.c --- a/sys/dev/rtwn/usb/rtwn_usb_reg.c +++ b/sys/dev/rtwn/usb/rtwn_usb_reg.c @@ -88,12 +88,16 @@ int len) { usb_device_request_t req; + struct rtwn_usb_softc *uc; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = R92C_REQ_REGS; USETW(req.wValue, addr); USETW(req.wIndex, 0); USETW(req.wLength, len); + uc = RTWN_USB_SOFTC(sc); + if (uc->uc_write_delay == 1 || sc->chan_flag == 1) + rtwn_delay(sc,uc->uc_delay_us); return (rtwn_do_request(sc, &req, buf)); } diff --git a/sys/dev/rtwn/usb/rtwn_usb_var.h b/sys/dev/rtwn/usb/rtwn_usb_var.h --- a/sys/dev/rtwn/usb/rtwn_usb_var.h +++ b/sys/dev/rtwn/usb/rtwn_usb_var.h @@ -27,6 +27,7 @@ #define RTWN_USB_RXBUFSZ_DEF (24) #define RTWN_USB_RXBUFSZ_MAX (64) #define RTWN_USB_TXBUFSZ (16 * 1024) +#define RTWN_USB_DELAY_US_DEF 0 #define RTWN_IFACE_INDEX 0 @@ -82,6 +83,9 @@ int tx_agg_desc_num; uint8_t wme2qid[4]; + + int uc_delay_us; + int uc_write_delay; }; #define RTWN_USB_SOFTC(sc) ((struct rtwn_usb_softc *)(sc))