From aea184b2710e16e8ee36412feae7cacac1499f4a Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Sat, 8 Jul 2017 14:26:24 +0000 Subject: - For RTL8188CUS/RTL8192CU, we have to force 8051 reset/enable before waiting for firmware to get ready. It fixes "urtwn0: could not load firmware page" while running stsp@'s script: dhclient urtwn0; ifconfig urtwn0 down; ifconfig urtwn0 scan in a loop. - Minor cleanup for rtwn_read_rom()/rtwn_get_txpower(); no need to use callbacks. Tested by stsp@ and me. ok stsp@ --- sys/dev/ic/r92creg.h | 13 ++++++++- sys/dev/ic/rtwn.c | 76 +++++++++++++++++++++++++++++++--------------------- sys/dev/ic/rtwnvar.h | 6 +---- 3 files changed, 58 insertions(+), 37 deletions(-) (limited to 'sys') diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h index 89a1ff4721b..e0bc3d9bddd 100644 --- a/sys/dev/ic/r92creg.h +++ b/sys/dev/ic/r92creg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: r92creg.h,v 1.11 2017/07/01 15:56:11 kevlo Exp $ */ +/* $OpenBSD: r92creg.h,v 1.12 2017/07/08 14:26:23 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -304,6 +304,16 @@ #define R92C_SYS_CLKR_SYS_EN 0x00001000 #define R92C_SYS_CLKR_RING_EN 0x00002000 +/* Bits for R92C_RSV_CTRL. */ +#define R92C_RSV_CTRL_WLOCK_ALL 0x01 +#define R92C_RSV_CTRL_WLOCK_00 0x02 +#define R92C_RSV_CTRL_WLOCK_04 0x04 +#define R92C_RSV_CTRL_WLOCK_08 0x08 +#define R92C_RSV_CTRL_WLOCK_40 0x10 +#define R92C_RSV_CTRL_R_DIS_PRST_0 0x20 +#define R92C_RSV_CTRL_R_DIS_PRST_1 0x40 +#define R92C_RSV_CTRL_LOCK_ALL_EN 0x80 + /* Bits for R92C_RF_CTRL. */ #define R92C_RF_CTRL_EN 0x01 #define R92C_RF_CTRL_RSTB 0x02 @@ -348,6 +358,7 @@ #define R92C_MCUFWDL_RAM_DL_SEL 0x00000080 /* 1: RAM, 0: ROM */ #define R92C_MCUFWDL_PAGE_M 0x00070000 #define R92C_MCUFWDL_PAGE_S 16 +#define R92C_MCUFWDL_ROM_DLEN 0x00080000 #define R92C_MCUFWDL_CPRST 0x00800000 /* Bits for R88E_HIMR. */ diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c index 1481da209e0..524f97c7670 100644 --- a/sys/dev/ic/rtwn.c +++ b/sys/dev/ic/rtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwn.c,v 1.25 2017/07/02 14:48:19 kevlo Exp $ */ +/* $OpenBSD: rtwn.c,v 1.26 2017/07/08 14:26:23 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -103,7 +103,7 @@ uint8_t rtwn_efuse_read_1(struct rtwn_softc *, uint16_t); void rtwn_efuse_read(struct rtwn_softc *, uint8_t *, size_t); void rtwn_efuse_switch_power(struct rtwn_softc *); int rtwn_read_chipid(struct rtwn_softc *); -void rtwn_read_rom(void *); +void rtwn_read_rom(struct rtwn_softc *); void rtwn_r92c_read_rom(struct rtwn_softc *); void rtwn_r88e_read_rom(struct rtwn_softc *); int rtwn_media_change(struct ifnet *); @@ -118,6 +118,8 @@ void rtwn_update_short_preamble(struct ieee80211com *); void rtwn_update_avgrssi(struct rtwn_softc *, int, int8_t); int8_t rtwn_r88e_get_rssi(struct rtwn_softc *, int, void *); void rtwn_watchdog(struct ifnet *); +void rtwn_fw_reset(struct rtwn_softc *); +void rtwn_r92c_fw_reset(struct rtwn_softc *); void rtwn_r88e_fw_reset(struct rtwn_softc *); int rtwn_load_firmware(struct rtwn_softc *); void rtwn_rf_init(struct rtwn_softc *); @@ -128,8 +130,9 @@ void rtwn_edca_init(struct rtwn_softc *); void rtwn_rate_fallback_init(struct rtwn_softc *); void rtwn_usb_aggr_init(struct rtwn_softc *); void rtwn_write_txpower(struct rtwn_softc *, int, uint16_t[]); -void rtwn_get_txpower(void *, int, struct ieee80211_channel *, - struct ieee80211_channel *, uint16_t[]); +void rtwn_get_txpower(struct rtwn_softc *sc, int, + struct ieee80211_channel *, struct ieee80211_channel *, + uint16_t[]); void rtwn_r92c_get_txpower(struct rtwn_softc *, int, struct ieee80211_channel *, struct ieee80211_channel *, uint16_t[]); @@ -183,9 +186,6 @@ rtwn_attach(struct device *pdev, struct rtwn_softc *sc) return (ENXIO); } - sc->sc_ops.get_txpower = rtwn_get_txpower; - sc->sc_ops.read_rom = rtwn_read_rom; - /* Determine number of Tx/Rx chains. */ if (sc->chip & RTWN_CHIP_92C) { sc->ntxchains = (sc->chip & RTWN_CHIP_92C_1T2R) ? 1 : 2; @@ -585,10 +585,8 @@ rtwn_read_chipid(struct rtwn_softc *sc) } void -rtwn_read_rom(void *cookie) +rtwn_read_rom(struct rtwn_softc *sc) { - struct rtwn_softc *sc = cookie; - if (sc->chip & RTWN_CHIP_88E) rtwn_r88e_read_rom(sc); else @@ -1474,6 +1472,15 @@ rtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) void rtwn_fw_reset(struct rtwn_softc *sc) +{ + if (sc->chip & RTWN_CHIP_88E) + rtwn_r88e_fw_reset(sc); + else + rtwn_r92c_fw_reset(sc); +} + +void +rtwn_r92c_fw_reset(struct rtwn_softc *sc) { uint16_t reg; int ntries; @@ -1505,8 +1512,14 @@ rtwn_r88e_fw_reset(struct rtwn_softc *sc) { uint16_t reg; + /* Reset MCU IO wrapper. */ + rtwn_write_1(sc, R92C_RSV_CTRL + 1, + rtwn_read_1(sc, R92C_RSV_CTRL + 1) & ~R92C_RSV_CTRL_WLOCK_08); reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN); rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN); + /* Enable MCU IO wrapper. */ + rtwn_write_1(sc, R92C_RSV_CTRL + 1, + rtwn_read_1(sc, R92C_RSV_CTRL) | R92C_RSV_CTRL_WLOCK_08); rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN); } @@ -1543,23 +1556,20 @@ rtwn_load_firmware(struct rtwn_softc *sc) } if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) { - if (sc->chip & RTWN_CHIP_88E) - rtwn_r88e_fw_reset(sc); - else - rtwn_fw_reset(sc); rtwn_write_1(sc, R92C_MCUFWDL, 0); + rtwn_fw_reset(sc); } - /* Enable FW download. */ - if (!(sc->chip & RTWN_CHIP_88E)) + if (sc->chip & RTWN_CHIP_PCI) { rtwn_write_2(sc, R92C_SYS_FUNC_EN, - rtwn_read_2(sc, R92C_SYS_FUNC_EN) | - R92C_SYS_FUNC_EN_CPUEN); + rtwn_read_2(sc, R92C_SYS_FUNC_EN) | R92C_SYS_FUNC_EN_CPUEN); + } + /* Enable FW download. */ rtwn_write_1(sc, R92C_MCUFWDL, rtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN); - rtwn_write_1(sc, R92C_MCUFWDL + 2, - rtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08); + rtwn_write_4(sc, R92C_MCUFWDL, + rtwn_read_4(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_ROM_DLEN); /* Reset the FWDL checksum. */ rtwn_write_1(sc, R92C_MCUFWDL, @@ -1578,11 +1588,6 @@ rtwn_load_firmware(struct rtwn_softc *sc) len -= mlen; } - /* Disable FW download. */ - rtwn_write_1(sc, R92C_MCUFWDL, - rtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN); - rtwn_write_1(sc, R92C_MCUFWDL + 1, 0); - /* Wait for checksum report. */ for (ntries = 0; ntries < 1000; ntries++) { if (rtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT) @@ -1596,11 +1601,22 @@ rtwn_load_firmware(struct rtwn_softc *sc) goto fail; } + /* Disable FW download. */ + rtwn_write_1(sc, R92C_MCUFWDL, + rtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN); + rtwn_write_1(sc, R92C_MCUFWDL + 1, 0); + reg = rtwn_read_4(sc, R92C_MCUFWDL); reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY; rtwn_write_4(sc, R92C_MCUFWDL, reg); - if (sc->chip & RTWN_CHIP_88E) - rtwn_r88e_fw_reset(sc); + if (sc->chip & (RTWN_CHIP_92C | RTWN_CHIP_88C)) { + reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN); + rtwn_write_2(sc, R92C_SYS_FUNC_EN, + reg & ~R92C_SYS_FUNC_EN_CPUEN); + rtwn_write_2(sc, R92C_SYS_FUNC_EN, + reg | R92C_SYS_FUNC_EN_CPUEN); + } else + rtwn_fw_reset(sc); /* Wait for firmware readiness. */ for (ntries = 0; ntries < 1000; ntries++) { if (rtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY) @@ -1613,7 +1629,7 @@ rtwn_load_firmware(struct rtwn_softc *sc) error = ETIMEDOUT; goto fail; } - fail: +fail: free(fw, M_DEVBUF, len0); return (error); } @@ -1884,11 +1900,9 @@ rtwn_write_txpower(struct rtwn_softc *sc, int chain, } void -rtwn_get_txpower(void *cookie, int chain, struct ieee80211_channel *c, +rtwn_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, uint16_t power[RTWN_POWER_COUNT]) { - struct rtwn_softc *sc = cookie; - if (sc->chip & RTWN_CHIP_88E) rtwn_r88e_get_txpower(sc, chain, c, extc, power); else diff --git a/sys/dev/ic/rtwnvar.h b/sys/dev/ic/rtwnvar.h index 6165b043811..a5a3c674c6e 100644 --- a/sys/dev/ic/rtwnvar.h +++ b/sys/dev/ic/rtwnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwnvar.h,v 1.9 2017/06/16 14:57:51 kevlo Exp $ */ +/* $OpenBSD: rtwnvar.h,v 1.10 2017/07/08 14:26:23 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -43,10 +43,6 @@ struct rtwn_ops { void (*next_scan)(void *); void (*cancel_scan)(void *); void (*wait_async)(void *); - - void (*get_txpower)(void *, int, struct ieee80211_channel *, - struct ieee80211_channel *, uint16_t[]); - void (*read_rom)(void *); }; #define RTWN_LED_LINK 0 -- cgit v1.2.3