From eff07e944b46f0cf33b0c5fee0c9ebcd023cf9e4 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Mon, 9 Jan 2023 12:54:00 -0800 Subject: [PATCH] rtwn: Fix RTL8192EU cannot associate in STA mode On some systems RTL8192EU will fail to associate in STA mode while others it will work fine. On the systems RTL8192EU fails to associate in STA mode, it works perfectly fine in AP mode. This points to a USB timing issue when selecting a channel while in STA mode. While here fix RTL8192EU power off and power on hang for the same reason. PR: 247528 Reported by: Mc James , many Reviewed by: Tested by: titus@edc.ro Approved by: Concept by: titus@edc.ro MFC after: Relnotes: Differential Revision: --- sys/dev/rtwn/rtl8192e/r92e_chan.c | 12 +++++++++++ sys/dev/rtwn/rtl8192e/r92e_init.c | 27 +++++++++++++++++++++++- sys/dev/rtwn/rtl8192e/r92e_reg.h | 1 + sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c | 1 + sys/dev/rtwn/usb/rtwn_usb_attach.c | 5 +++++ sys/dev/rtwn/usb/rtwn_usb_reg.c | 4 ++++ sys/dev/rtwn/usb/rtwn_usb_var.h | 3 +++ 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/sys/dev/rtwn/rtl8192e/r92e_chan.c b/sys/dev/rtwn/rtl8192e/r92e_chan.c index 0211e2883888..d76a25023e08 100644 --- a/sys/dev/rtwn/rtl8192e/r92e_chan.c +++ b/sys/dev/rtwn/rtl8192e/r92e_chan.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include static int r92e_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c) @@ -212,9 +213,15 @@ void r92e_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c) { struct r92e_softc *rs = sc->sc_priv; + struct rtwn_usb_softc *uc; u_int chan; int i; + if ((uc = RTWN_USB_SOFTC(sc)) != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 1; + RTWN_UNLOCK(sc); + } chan = rtwn_chan2centieee(c); for (i = 0; i < sc->nrxchains; i++) { @@ -229,4 +236,9 @@ r92e_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c) /* Set Tx power for this new channel. */ r92e_set_txpower(sc, c); + if (uc != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 0; + RTWN_UNLOCK(sc); + } } diff --git a/sys/dev/rtwn/rtl8192e/r92e_init.c b/sys/dev/rtwn/rtl8192e/r92e_init.c index 48a87e6ae98c..b3a8b831ed5e 100644 --- a/sys/dev/rtwn/rtl8192e/r92e_init.c +++ b/sys/dev/rtwn/rtl8192e/r92e_init.c @@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$"); #include +#include + #include #include @@ -226,8 +228,15 @@ r92e_power_on(struct rtwn_softc *sc) if (res != 0) \ return (EIO); \ } while(0) + struct rtwn_usb_softc *uc; int ntries; + if ((uc = RTWN_USB_SOFTC(sc)) != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 1; + RTWN_UNLOCK(sc); + } + 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 { @@ -254,6 +263,11 @@ r92e_power_on(struct rtwn_softc *sc) rtwn_delay(sc, 10); } if (ntries == 5000) { + if (uc != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 0; + RTWN_UNLOCK(sc); + } device_printf(sc->sc_dev, "timeout waiting for chip power up\n"); return (ETIMEDOUT); @@ -271,8 +285,14 @@ r92e_power_on(struct rtwn_softc *sc) break; rtwn_delay(sc, 10); } - if (ntries == 5000) + if (ntries == 5000) { + if (uc != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 0; + RTWN_UNLOCK(sc); + } return (ETIMEDOUT); + } /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0)); @@ -283,6 +303,11 @@ r92e_power_on(struct rtwn_softc *sc) ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) | R92C_CR_CALTMR_EN)); + if (uc != NULL) { + RTWN_LOCK(sc); + uc->uc_write_delay = 0; + RTWN_UNLOCK(sc); + } return (0); } diff --git a/sys/dev/rtwn/rtl8192e/r92e_reg.h b/sys/dev/rtwn/rtl8192e/r92e_reg.h index eb2b1f2c7119..1a238cd58d33 100644 --- a/sys/dev/rtwn/rtl8192e/r92e_reg.h +++ b/sys/dev/rtwn/rtl8192e/r92e_reg.h @@ -43,5 +43,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 index 6f166d99e36e..305a9bd9e4fd 100644 --- a/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c +++ b/sys/dev/rtwn/rtl8192e/usb/r92eu_attach.c @@ -102,6 +102,7 @@ r92eu_attach(struct rtwn_usb_softc *uc) /* 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 index 4e881b2d0de5..3060eee7d3e1 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_attach.c +++ b/sys/dev/rtwn/usb/rtwn_usb_attach.c @@ -372,6 +372,11 @@ rtwn_usb_sysctlattach(struct rtwn_softc *sc) 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 diff --git a/sys/dev/rtwn/usb/rtwn_usb_reg.c b/sys/dev/rtwn/usb/rtwn_usb_reg.c index fad6d04ec5ff..adc9412e68ba 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_reg.c +++ b/sys/dev/rtwn/usb/rtwn_usb_reg.c @@ -91,12 +91,16 @@ rtwn_usb_write_region_1(struct rtwn_softc *sc, uint16_t addr, uint8_t *buf, 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->sc_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 index 7ef214632b12..6ef0f964104c 100644 --- a/sys/dev/rtwn/usb/rtwn_usb_var.h +++ b/sys/dev/rtwn/usb/rtwn_usb_var.h @@ -28,6 +28,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 @@ -79,6 +80,8 @@ struct rtwn_usb_softc { int ntx; int tx_agg_desc_num; + int uc_delay_us; + int uc_write_delay; }; #define RTWN_USB_SOFTC(sc) ((struct rtwn_usb_softc *)(sc)) -- 2.39.0