- For RTL8188CUS/RTL8192CU, we have to force 8051 reset/enable before waiting
authorkevlo <kevlo@openbsd.org>
Sat, 8 Jul 2017 14:26:23 +0000 (14:26 +0000)
committerkevlo <kevlo@openbsd.org>
Sat, 8 Jul 2017 14:26:23 +0000 (14:26 +0000)
  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
sys/dev/ic/rtwn.c
sys/dev/ic/rtwnvar.h

index 89a1ff4..e0bc3d9 100644 (file)
@@ -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 <damien.bergamini@free.fr>
 #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
 #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. */
index 1481da2..524f97c 100644 (file)
@@ -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 <damien.bergamini@free.fr>
@@ -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
index 6165b04..a5a3c67 100644 (file)
@@ -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 <damien.bergamini@free.fr>
@@ -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