1 /* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org> 6 * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/cdefs.h> 22 __FBSDID("$FreeBSD$"); 23 24 #include "opt_wlan.h" 25 26 #include <sys/param.h> 27 #include <sys/lock.h> 28 #include <sys/mutex.h> 29 #include <sys/mbuf.h> 30 #include <sys/kernel.h> 31 #include <sys/socket.h> 32 #include <sys/systm.h> 33 #include <sys/malloc.h> 34 #include <sys/queue.h> 35 #include <sys/taskqueue.h> 36 #include <sys/bus.h> 37 #include <sys/endian.h> 38 #include <sys/linker.h> 39 40 #include <net/if.h> 41 #include <net/ethernet.h> 42 #include <net/if_media.h> 43 44 #include <net80211/ieee80211_var.h> 45 #include <net80211/ieee80211_radiotap.h> 46 47 #include <dev/rtwn/if_rtwnreg.h> 48 #include <dev/rtwn/if_rtwnvar.h> 49 #include <dev/rtwn/if_rtwn_debug.h> 50 51 #include <dev/rtwn/usb/rtwn_usb_var.h> 52 53 #include <dev/rtwn/rtl8192c/r92c_var.h> 54 55 #include <dev/rtwn/rtl8192c/usb/r92cu.h> 56 #include <dev/rtwn/rtl8192c/usb/r92cu_reg.h> 57 58 59 void 60 r92cu_init_bb(struct rtwn_softc *sc) 61 { 62 63 /* Enable BB and RF. */ 64 rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0, 65 R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST | 66 R92C_SYS_FUNC_EN_DIO_RF); 67 68 rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83); 69 70 rtwn_write_1(sc, R92C_RF_CTRL, 71 R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB); 72 rtwn_write_1(sc, R92C_SYS_FUNC_EN, 73 R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD | 74 R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB); 75 76 rtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f); 77 rtwn_write_1(sc, 0x15, 0xe9); 78 rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80); 79 80 r92c_init_bb_common(sc); 81 82 if (rtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & 83 R92C_HSSI_PARAM2_CCK_HIPWR) 84 sc->sc_flags |= RTWN_FLAG_CCK_HIPWR; 85 } 86 87 int 88 r92cu_power_on(struct rtwn_softc *sc) 89 { 90 #define RTWN_CHK(res) do { \ 91 if (res != 0) \ 92 return (EIO); \ 93 } while(0) 94 uint32_t reg; 95 int ntries; 96 97 /* Wait for autoload done bit. */ 98 for (ntries = 0; ntries < 5000; ntries++) { 99 if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN) 100 break; 101 rtwn_delay(sc, 10); 102 } 103 if (ntries == 5000) { 104 device_printf(sc->sc_dev, 105 "timeout waiting for chip autoload\n"); 106 return (ETIMEDOUT); 107 } 108 109 /* Unlock ISO/CLK/Power control register. */ 110 RTWN_CHK(rtwn_write_1(sc, R92C_RSV_CTRL, 0)); 111 112 /* Move SPS into PWM mode. */ 113 RTWN_CHK(rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b)); 114 115 /* just in case if power_off() was not properly executed. */ 116 rtwn_delay(sc, 100); 117 118 reg = rtwn_read_1(sc, R92C_LDOV12D_CTRL); 119 if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) { 120 RTWN_CHK(rtwn_write_1(sc, R92C_LDOV12D_CTRL, 121 reg | R92C_LDOV12D_CTRL_LDV12_EN)); 122 123 rtwn_delay(sc, 100); 124 125 RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL, 126 R92C_SYS_ISO_CTRL_MD2PP, 0)); 127 } 128 129 /* Auto enable WLAN. */ 130 RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, 131 R92C_APS_FSMCO_APFM_ONMAC, 1)); 132 133 for (ntries = 0; ntries < 5000; ntries++) { 134 if (!(rtwn_read_2(sc, R92C_APS_FSMCO) & 135 R92C_APS_FSMCO_APFM_ONMAC)) 136 break; 137 rtwn_delay(sc, 10); 138 } 139 if (ntries == 5000) { 140 device_printf(sc->sc_dev, 141 "timeout waiting for MAC auto ON\n"); 142 return (ETIMEDOUT); 143 } 144 145 /* Enable radio, GPIO and LED functions. */ 146 RTWN_CHK(rtwn_write_2(sc, R92C_APS_FSMCO, 147 R92C_APS_FSMCO_AFSM_HSUS | 148 R92C_APS_FSMCO_PDN_EN | 149 R92C_APS_FSMCO_PFM_ALDN)); 150 151 /* Release RF digital isolation. */ 152 RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_SYS_ISO_CTRL, 153 R92C_SYS_ISO_CTRL_DIOR, 0, 1)); 154 155 /* Initialize MAC. */ 156 RTWN_CHK(rtwn_setbits_1(sc, R92C_APSD_CTRL, 157 R92C_APSD_CTRL_OFF, 0)); 158 for (ntries = 0; ntries < 1000; ntries++) { 159 if (!(rtwn_read_1(sc, R92C_APSD_CTRL) & 160 R92C_APSD_CTRL_OFF_STATUS)) 161 break; 162 rtwn_delay(sc, 50); 163 } 164 if (ntries == 1000) { 165 device_printf(sc->sc_dev, 166 "timeout waiting for MAC initialization\n"); 167 return (ETIMEDOUT); 168 } 169 170 /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ 171 RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0, 172 R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN | 173 R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN | 174 R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN | 175 ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) | 176 R92C_CR_CALTMR_EN)); 177 178 RTWN_CHK(rtwn_write_1(sc, 0xfe10, 0x19)); 179 180 return (0); 181 #undef RTWN_CHK 182 } 183 184 void 185 r92cu_power_off(struct rtwn_softc *sc) 186 { 187 #ifndef RTWN_WITHOUT_UCODE 188 struct r92c_softc *rs = sc->sc_priv; 189 #endif 190 uint32_t reg; 191 int error; 192 193 /* Deinit C2H event handler. */ 194 #ifndef RTWN_WITHOUT_UCODE 195 callout_stop(&rs->rs_c2h_report); 196 rs->rs_c2h_paused = 0; 197 rs->rs_c2h_pending = 0; 198 rs->rs_c2h_timeout = hz; 199 #endif 200 201 /* Block all Tx queues. */ 202 error = rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL); 203 if (error == ENXIO) /* hardware gone */ 204 return; 205 206 /* Disable RF */ 207 rtwn_rf_write(sc, 0, 0, 0); 208 209 rtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF); 210 211 /* Reset BB state machine */ 212 rtwn_write_1(sc, R92C_SYS_FUNC_EN, 213 R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA | 214 R92C_SYS_FUNC_EN_BB_GLB_RST); 215 rtwn_write_1(sc, R92C_SYS_FUNC_EN, 216 R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA); 217 218 /* 219 * Reset digital sequence 220 */ 221 #ifndef RTWN_WITHOUT_UCODE 222 if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) { 223 /* Reset MCU ready status */ 224 rtwn_write_1(sc, R92C_MCUFWDL, 0); 225 226 /* If firmware in ram code, do reset */ 227 r92c_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN); 228 } 229 #endif 230 231 /* Reset MAC and Enable 8051 */ 232 rtwn_write_1(sc, R92C_SYS_FUNC_EN + 1, 233 (R92C_SYS_FUNC_EN_CPUEN | 234 R92C_SYS_FUNC_EN_ELDR | 235 R92C_SYS_FUNC_EN_HWPDN) >> 8); 236 237 /* Reset MCU ready status */ 238 rtwn_write_1(sc, R92C_MCUFWDL, 0); 239 240 /* Disable MAC clock */ 241 rtwn_write_2(sc, R92C_SYS_CLKR, 242 R92C_SYS_CLKR_ANAD16V_EN | 243 R92C_SYS_CLKR_ANA8M | 244 R92C_SYS_CLKR_LOADER_EN | 245 R92C_SYS_CLKR_80M_SSC_DIS | 246 R92C_SYS_CLKR_SYS_EN | 247 R92C_SYS_CLKR_RING_EN | 248 0x4000); 249 250 /* Disable AFE PLL */ 251 rtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80); 252 253 /* Gated AFE DIG_CLOCK */ 254 rtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F); 255 256 /* Isolated digital to PON */ 257 rtwn_write_1(sc, R92C_SYS_ISO_CTRL, 258 R92C_SYS_ISO_CTRL_MD2PP | 259 R92C_SYS_ISO_CTRL_PA2PCIE | 260 R92C_SYS_ISO_CTRL_PD2CORE | 261 R92C_SYS_ISO_CTRL_IP2MAC | 262 R92C_SYS_ISO_CTRL_DIOP | 263 R92C_SYS_ISO_CTRL_DIOE); 264 265 /* 266 * Pull GPIO PIN to balance level and LED control 267 */ 268 /* 1. Disable GPIO[7:0] */ 269 rtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000); 270 271 reg = rtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00; 272 reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000; 273 rtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg); 274 275 /* Disable GPIO[10:8] */ 276 rtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00); 277 278 reg = rtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0; 279 reg |= (((reg & 0x000f) << 4) | 0x0780); 280 rtwn_write_2(sc, R92C_GPIO_IO_SEL, reg); 281 282 /* Disable LED0 & 1 */ 283 rtwn_write_2(sc, R92C_LEDCFG0, 0x8080); 284 285 /* 286 * Reset digital sequence 287 */ 288 /* Disable ELDR clock */ 289 rtwn_write_2(sc, R92C_SYS_CLKR, 290 R92C_SYS_CLKR_ANAD16V_EN | 291 R92C_SYS_CLKR_ANA8M | 292 R92C_SYS_CLKR_LOADER_EN | 293 R92C_SYS_CLKR_80M_SSC_DIS | 294 R92C_SYS_CLKR_SYS_EN | 295 R92C_SYS_CLKR_RING_EN | 296 0x4000); 297 298 /* Isolated ELDR to PON */ 299 rtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1, 300 (R92C_SYS_ISO_CTRL_DIOR | 301 R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8); 302 303 /* 304 * Disable analog sequence 305 */ 306 /* Disable A15 power */ 307 rtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF); 308 /* Disable digital core power */ 309 rtwn_setbits_1(sc, R92C_LDOV12D_CTRL, 310 R92C_LDOV12D_CTRL_LDV12_EN, 0); 311 312 /* Enter PFM mode */ 313 rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23); 314 315 /* Set USB suspend */ 316 rtwn_write_2(sc, R92C_APS_FSMCO, 317 R92C_APS_FSMCO_APDM_HOST | 318 R92C_APS_FSMCO_AFSM_HSUS | 319 R92C_APS_FSMCO_PFM_ALDN); 320 321 /* Lock ISO/CLK/Power control register. */ 322 rtwn_write_1(sc, R92C_RSV_CTRL, 0x0E); 323 } 324 325 void 326 r92cu_init_intr(struct rtwn_softc *sc) 327 { 328 rtwn_write_4(sc, R92C_HISR, 0xffffffff); 329 rtwn_write_4(sc, R92C_HIMR, 0xffffffff); 330 } 331 332 void 333 r92cu_init_tx_agg(struct rtwn_softc *sc) 334 { 335 struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc); 336 337 rtwn_setbits_4(sc, R92C_TDECTRL, 338 R92C_TDECTRL_BLK_DESC_NUM_M, uc->tx_agg_desc_num); 339 } 340 341 void 342 r92cu_init_rx_agg(struct rtwn_softc *sc) 343 { 344 345 /* Rx aggregation (DMA & USB). */ 346 rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0, 347 R92C_TRXDMA_CTRL_RXDMA_AGG_EN); 348 rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0, 349 R92C_USB_SPECIAL_OPTION_AGG_EN); 350 351 /* XXX dehardcode */ 352 rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48); 353 rtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4); 354 rtwn_write_1(sc, R92C_USB_AGG_TH, 8); 355 rtwn_write_1(sc, R92C_USB_AGG_TO, 6); 356 } 357 358 void 359 r92cu_post_init(struct rtwn_softc *sc) 360 { 361 362 /* Perform LO and IQ calibrations. */ 363 r92c_iq_calib(sc); 364 /* Perform LC calibration. */ 365 r92c_lc_calib(sc); 366 367 /* Fix USB interference issue. */ 368 rtwn_write_1(sc, 0xfe40, 0xe0); 369 rtwn_write_1(sc, 0xfe41, 0x8d); 370 rtwn_write_1(sc, 0xfe42, 0x80); 371 372 r92c_pa_bias_init(sc); 373 374 /* Fix for lower temperature. */ 375 rtwn_write_1(sc, 0x15, 0xe9); 376 377 #ifndef RTWN_WITHOUT_UCODE 378 if (sc->sc_flags & RTWN_FW_LOADED) { 379 struct r92c_softc *rs = sc->sc_priv; 380 381 if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) { 382 /* XXX firmware RA does not work yet */ 383 sc->sc_ratectl = RTWN_RATECTL_NET80211; 384 } else 385 sc->sc_ratectl = sc->sc_ratectl_sysctl; 386 387 /* Start C2H event handling. */ 388 callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout, 389 r92c_handle_c2h_report, sc); 390 } else 391 #endif 392 sc->sc_ratectl = RTWN_RATECTL_NONE; 393 } 394