17453645fSAndriy Voskoboinyk /* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ 27453645fSAndriy Voskoboinyk 37453645fSAndriy Voskoboinyk /*- 47453645fSAndriy Voskoboinyk * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> 57453645fSAndriy Voskoboinyk * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org> 67453645fSAndriy Voskoboinyk * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org> 77453645fSAndriy Voskoboinyk * 87453645fSAndriy Voskoboinyk * Permission to use, copy, modify, and distribute this software for any 97453645fSAndriy Voskoboinyk * purpose with or without fee is hereby granted, provided that the above 107453645fSAndriy Voskoboinyk * copyright notice and this permission notice appear in all copies. 117453645fSAndriy Voskoboinyk * 127453645fSAndriy Voskoboinyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 137453645fSAndriy Voskoboinyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 147453645fSAndriy Voskoboinyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 157453645fSAndriy Voskoboinyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 167453645fSAndriy Voskoboinyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 177453645fSAndriy Voskoboinyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 187453645fSAndriy Voskoboinyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 197453645fSAndriy Voskoboinyk */ 207453645fSAndriy Voskoboinyk 217453645fSAndriy Voskoboinyk #include <sys/cdefs.h> 227453645fSAndriy Voskoboinyk __FBSDID("$FreeBSD$"); 237453645fSAndriy Voskoboinyk 247453645fSAndriy Voskoboinyk #include "opt_wlan.h" 257453645fSAndriy Voskoboinyk 267453645fSAndriy Voskoboinyk #include <sys/param.h> 277453645fSAndriy Voskoboinyk #include <sys/lock.h> 287453645fSAndriy Voskoboinyk #include <sys/mutex.h> 297453645fSAndriy Voskoboinyk #include <sys/mbuf.h> 307453645fSAndriy Voskoboinyk #include <sys/kernel.h> 317453645fSAndriy Voskoboinyk #include <sys/socket.h> 327453645fSAndriy Voskoboinyk #include <sys/systm.h> 337453645fSAndriy Voskoboinyk #include <sys/malloc.h> 347453645fSAndriy Voskoboinyk #include <sys/queue.h> 357453645fSAndriy Voskoboinyk #include <sys/taskqueue.h> 367453645fSAndriy Voskoboinyk #include <sys/bus.h> 377453645fSAndriy Voskoboinyk #include <sys/endian.h> 387453645fSAndriy Voskoboinyk #include <sys/linker.h> 397453645fSAndriy Voskoboinyk 407453645fSAndriy Voskoboinyk #include <net/if.h> 417453645fSAndriy Voskoboinyk #include <net/ethernet.h> 427453645fSAndriy Voskoboinyk #include <net/if_media.h> 437453645fSAndriy Voskoboinyk 447453645fSAndriy Voskoboinyk #include <net80211/ieee80211_var.h> 457453645fSAndriy Voskoboinyk #include <net80211/ieee80211_radiotap.h> 467453645fSAndriy Voskoboinyk 477453645fSAndriy Voskoboinyk #include <dev/rtwn/if_rtwnreg.h> 487453645fSAndriy Voskoboinyk #include <dev/rtwn/if_rtwnvar.h> 497453645fSAndriy Voskoboinyk 507453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8192c/r92c.h> 517453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8192c/r92c_var.h> 527453645fSAndriy Voskoboinyk 537453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8188e/usb/r88eu.h> 547453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8188e/usb/r88eu_reg.h> 557453645fSAndriy Voskoboinyk 567453645fSAndriy Voskoboinyk 577453645fSAndriy Voskoboinyk void 58*4e4bcfcfSAndriy Voskoboinyk r88eu_init_bb(struct rtwn_softc *sc) 59*4e4bcfcfSAndriy Voskoboinyk { 60*4e4bcfcfSAndriy Voskoboinyk 61*4e4bcfcfSAndriy Voskoboinyk /* Enable BB and RF. */ 62*4e4bcfcfSAndriy Voskoboinyk rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0, 63*4e4bcfcfSAndriy Voskoboinyk R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST | 64*4e4bcfcfSAndriy Voskoboinyk R92C_SYS_FUNC_EN_DIO_RF); 65*4e4bcfcfSAndriy Voskoboinyk 66*4e4bcfcfSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RF_CTRL, 67*4e4bcfcfSAndriy Voskoboinyk R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB); 68*4e4bcfcfSAndriy Voskoboinyk rtwn_write_1(sc, R92C_SYS_FUNC_EN, 69*4e4bcfcfSAndriy Voskoboinyk R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD | 70*4e4bcfcfSAndriy Voskoboinyk R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB); 71*4e4bcfcfSAndriy Voskoboinyk 72*4e4bcfcfSAndriy Voskoboinyk r88e_init_bb_common(sc); 73*4e4bcfcfSAndriy Voskoboinyk } 74*4e4bcfcfSAndriy Voskoboinyk 75*4e4bcfcfSAndriy Voskoboinyk int 76*4e4bcfcfSAndriy Voskoboinyk r88eu_power_on(struct rtwn_softc *sc) 77*4e4bcfcfSAndriy Voskoboinyk { 78*4e4bcfcfSAndriy Voskoboinyk #define RTWN_CHK(res) do { \ 79*4e4bcfcfSAndriy Voskoboinyk if (res != 0) \ 80*4e4bcfcfSAndriy Voskoboinyk return (EIO); \ 81*4e4bcfcfSAndriy Voskoboinyk } while(0) 82*4e4bcfcfSAndriy Voskoboinyk int ntries; 83*4e4bcfcfSAndriy Voskoboinyk 84*4e4bcfcfSAndriy Voskoboinyk /* Wait for power ready bit. */ 85*4e4bcfcfSAndriy Voskoboinyk for (ntries = 0; ntries < 5000; ntries++) { 86*4e4bcfcfSAndriy Voskoboinyk if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST) 87*4e4bcfcfSAndriy Voskoboinyk break; 88*4e4bcfcfSAndriy Voskoboinyk rtwn_delay(sc, 10); 89*4e4bcfcfSAndriy Voskoboinyk } 90*4e4bcfcfSAndriy Voskoboinyk if (ntries == 5000) { 91*4e4bcfcfSAndriy Voskoboinyk device_printf(sc->sc_dev, 92*4e4bcfcfSAndriy Voskoboinyk "timeout waiting for chip power up\n"); 93*4e4bcfcfSAndriy Voskoboinyk return (ETIMEDOUT); 94*4e4bcfcfSAndriy Voskoboinyk } 95*4e4bcfcfSAndriy Voskoboinyk 96*4e4bcfcfSAndriy Voskoboinyk /* Reset BB. */ 97*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, 98*4e4bcfcfSAndriy Voskoboinyk R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST, 0)); 99*4e4bcfcfSAndriy Voskoboinyk 100*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80)); 101*4e4bcfcfSAndriy Voskoboinyk 102*4e4bcfcfSAndriy Voskoboinyk /* Disable HWPDN. */ 103*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 104*4e4bcfcfSAndriy Voskoboinyk R92C_APS_FSMCO_APDM_HPDN, 0, 1)); 105*4e4bcfcfSAndriy Voskoboinyk 106*4e4bcfcfSAndriy Voskoboinyk /* Disable WL suspend. */ 107*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 108*4e4bcfcfSAndriy Voskoboinyk R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1)); 109*4e4bcfcfSAndriy Voskoboinyk 110*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 111*4e4bcfcfSAndriy Voskoboinyk 0, R92C_APS_FSMCO_APFM_ONMAC, 1)); 112*4e4bcfcfSAndriy Voskoboinyk for (ntries = 0; ntries < 5000; ntries++) { 113*4e4bcfcfSAndriy Voskoboinyk if (!(rtwn_read_2(sc, R92C_APS_FSMCO) & 114*4e4bcfcfSAndriy Voskoboinyk R92C_APS_FSMCO_APFM_ONMAC)) 115*4e4bcfcfSAndriy Voskoboinyk break; 116*4e4bcfcfSAndriy Voskoboinyk rtwn_delay(sc, 10); 117*4e4bcfcfSAndriy Voskoboinyk } 118*4e4bcfcfSAndriy Voskoboinyk if (ntries == 5000) 119*4e4bcfcfSAndriy Voskoboinyk return (ETIMEDOUT); 120*4e4bcfcfSAndriy Voskoboinyk 121*4e4bcfcfSAndriy Voskoboinyk /* Enable LDO normal mode. */ 122*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 123*4e4bcfcfSAndriy Voskoboinyk R92C_LPLDO_CTRL_SLEEP, 0)); 124*4e4bcfcfSAndriy Voskoboinyk 125*4e4bcfcfSAndriy Voskoboinyk /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ 126*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0)); 127*4e4bcfcfSAndriy Voskoboinyk RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0, 128*4e4bcfcfSAndriy Voskoboinyk R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN | 129*4e4bcfcfSAndriy Voskoboinyk R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN | 130*4e4bcfcfSAndriy Voskoboinyk R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN | 131*4e4bcfcfSAndriy Voskoboinyk ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) | 132*4e4bcfcfSAndriy Voskoboinyk R92C_CR_CALTMR_EN)); 133*4e4bcfcfSAndriy Voskoboinyk 134*4e4bcfcfSAndriy Voskoboinyk return (0); 135*4e4bcfcfSAndriy Voskoboinyk #undef RTWN_CHK 136*4e4bcfcfSAndriy Voskoboinyk } 137*4e4bcfcfSAndriy Voskoboinyk 138*4e4bcfcfSAndriy Voskoboinyk void 1397453645fSAndriy Voskoboinyk r88eu_power_off(struct rtwn_softc *sc) 1407453645fSAndriy Voskoboinyk { 1417453645fSAndriy Voskoboinyk uint8_t reg; 1427453645fSAndriy Voskoboinyk int error, ntries; 1437453645fSAndriy Voskoboinyk 1447453645fSAndriy Voskoboinyk /* Disable any kind of TX reports. */ 1457453645fSAndriy Voskoboinyk error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 1467453645fSAndriy Voskoboinyk R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA, 0); 1477453645fSAndriy Voskoboinyk if (error == ENXIO) /* hardware gone */ 1487453645fSAndriy Voskoboinyk return; 1497453645fSAndriy Voskoboinyk 1507453645fSAndriy Voskoboinyk /* Stop Rx. */ 1517453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_CR, 0); 1527453645fSAndriy Voskoboinyk 1537453645fSAndriy Voskoboinyk /* Move card to Low Power State. */ 1547453645fSAndriy Voskoboinyk /* Block all Tx queues. */ 1557453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL); 1567453645fSAndriy Voskoboinyk 1577453645fSAndriy Voskoboinyk for (ntries = 0; ntries < 10; ntries++) { 1587453645fSAndriy Voskoboinyk /* Should be zero if no packet is transmitting. */ 1597453645fSAndriy Voskoboinyk if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0) 1607453645fSAndriy Voskoboinyk break; 1617453645fSAndriy Voskoboinyk 1627453645fSAndriy Voskoboinyk rtwn_delay(sc, 5000); 1637453645fSAndriy Voskoboinyk } 1647453645fSAndriy Voskoboinyk if (ntries == 10) { 1657453645fSAndriy Voskoboinyk device_printf(sc->sc_dev, "%s: failed to block Tx queues\n", 1667453645fSAndriy Voskoboinyk __func__); 1677453645fSAndriy Voskoboinyk return; 1687453645fSAndriy Voskoboinyk } 1697453645fSAndriy Voskoboinyk 1707453645fSAndriy Voskoboinyk /* CCK and OFDM are disabled, and clock are gated. */ 1717453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0); 1727453645fSAndriy Voskoboinyk 1737453645fSAndriy Voskoboinyk rtwn_delay(sc, 1); 1747453645fSAndriy Voskoboinyk 1757453645fSAndriy Voskoboinyk /* Reset MAC TRX */ 1767453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_CR, 1777453645fSAndriy Voskoboinyk R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | 1787453645fSAndriy Voskoboinyk R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | 1797453645fSAndriy Voskoboinyk R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN); 1807453645fSAndriy Voskoboinyk 1817453645fSAndriy Voskoboinyk /* check if removed later */ 1827453645fSAndriy Voskoboinyk rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1); 1837453645fSAndriy Voskoboinyk 1847453645fSAndriy Voskoboinyk /* Respond TxOK to scheduler */ 1857453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, 0x20); 1867453645fSAndriy Voskoboinyk 1877453645fSAndriy Voskoboinyk /* If firmware in ram code, do reset. */ 1887453645fSAndriy Voskoboinyk #ifndef RTWN_WITHOUT_UCODE 1897453645fSAndriy Voskoboinyk if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) 1907453645fSAndriy Voskoboinyk r88e_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN); 1917453645fSAndriy Voskoboinyk #endif 1927453645fSAndriy Voskoboinyk 1937453645fSAndriy Voskoboinyk /* Reset MCU ready status. */ 1947453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_MCUFWDL, 0); 1957453645fSAndriy Voskoboinyk 1967453645fSAndriy Voskoboinyk /* Disable 32k. */ 1977453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R88E_32K_CTRL, 0x01, 0); 1987453645fSAndriy Voskoboinyk 1997453645fSAndriy Voskoboinyk /* Move card to Disabled state. */ 2007453645fSAndriy Voskoboinyk /* Turn off RF. */ 2017453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RF_CTRL, 0); 2027453645fSAndriy Voskoboinyk 2037453645fSAndriy Voskoboinyk /* LDO Sleep mode. */ 2047453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 0, R92C_LPLDO_CTRL_SLEEP); 2057453645fSAndriy Voskoboinyk 2067453645fSAndriy Voskoboinyk /* Turn off MAC by HW state machine */ 2077453645fSAndriy Voskoboinyk rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, 2087453645fSAndriy Voskoboinyk R92C_APS_FSMCO_APFM_OFF, 1); 2097453645fSAndriy Voskoboinyk 2107453645fSAndriy Voskoboinyk for (ntries = 0; ntries < 10; ntries++) { 2117453645fSAndriy Voskoboinyk /* Wait until it will be disabled. */ 2127453645fSAndriy Voskoboinyk if ((rtwn_read_2(sc, R92C_APS_FSMCO) & 2137453645fSAndriy Voskoboinyk R92C_APS_FSMCO_APFM_OFF) == 0) 2147453645fSAndriy Voskoboinyk break; 2157453645fSAndriy Voskoboinyk 2167453645fSAndriy Voskoboinyk rtwn_delay(sc, 5000); 2177453645fSAndriy Voskoboinyk } 2187453645fSAndriy Voskoboinyk if (ntries == 10) { 2197453645fSAndriy Voskoboinyk device_printf(sc->sc_dev, "%s: could not turn off MAC\n", 2207453645fSAndriy Voskoboinyk __func__); 2217453645fSAndriy Voskoboinyk return; 2227453645fSAndriy Voskoboinyk } 2237453645fSAndriy Voskoboinyk 2247453645fSAndriy Voskoboinyk /* schmit trigger */ 2257453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80); 2267453645fSAndriy Voskoboinyk 2277453645fSAndriy Voskoboinyk /* Enable WL suspend. */ 2287453645fSAndriy Voskoboinyk rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 2297453645fSAndriy Voskoboinyk R92C_APS_FSMCO_AFSM_PCIE, R92C_APS_FSMCO_AFSM_HSUS, 1); 2307453645fSAndriy Voskoboinyk 2317453645fSAndriy Voskoboinyk /* Enable bandgap mbias in suspend. */ 2327453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_APS_FSMCO + 3, 0); 2337453645fSAndriy Voskoboinyk 2347453645fSAndriy Voskoboinyk /* Clear SIC_EN register. */ 2357453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_GPIO_MUXCFG + 1, 0x10, 0); 2367453645fSAndriy Voskoboinyk 2377453645fSAndriy Voskoboinyk /* Set USB suspend enable local register */ 2387453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_USB_SUSPEND, 0, 0x10); 2397453645fSAndriy Voskoboinyk 2407453645fSAndriy Voskoboinyk /* Reset MCU IO Wrapper. */ 2417453645fSAndriy Voskoboinyk reg = rtwn_read_1(sc, R92C_RSV_CTRL + 1); 2427453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08); 2437453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08); 2447453645fSAndriy Voskoboinyk 2457453645fSAndriy Voskoboinyk /* marked as 'For Power Consumption' code. */ 2467453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_GPIO_OUT, rtwn_read_1(sc, R92C_GPIO_IN)); 2477453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff); 2487453645fSAndriy Voskoboinyk 2497453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_GPIO_IO_SEL, 2507453645fSAndriy Voskoboinyk rtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4); 2517453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_GPIO_MOD, 0, 0x0f); 2527453645fSAndriy Voskoboinyk 2537453645fSAndriy Voskoboinyk /* Set LNA, TRSW, EX_PA Pin to output mode. */ 2547453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808); 2557453645fSAndriy Voskoboinyk } 2567453645fSAndriy Voskoboinyk 2577453645fSAndriy Voskoboinyk void 2587453645fSAndriy Voskoboinyk r88eu_init_intr(struct rtwn_softc *sc) 2597453645fSAndriy Voskoboinyk { 2607453645fSAndriy Voskoboinyk /* TODO: adjust */ 2617453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_HISR, 0xffffffff); 2627453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 | 2637453645fSAndriy Voskoboinyk R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT); 2647453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW | 2657453645fSAndriy Voskoboinyk R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR); 2667453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0, 2677453645fSAndriy Voskoboinyk R92C_USB_SPECIAL_OPTION_INT_BULK_SEL); 2687453645fSAndriy Voskoboinyk } 2697453645fSAndriy Voskoboinyk 2707453645fSAndriy Voskoboinyk void 2717453645fSAndriy Voskoboinyk r88eu_init_rx_agg(struct rtwn_softc *sc) 2727453645fSAndriy Voskoboinyk { 2737453645fSAndriy Voskoboinyk /* XXX merge? */ 2747453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0, 2757453645fSAndriy Voskoboinyk R92C_TRXDMA_CTRL_RXDMA_AGG_EN); 2767453645fSAndriy Voskoboinyk /* XXX dehardcode */ 2777453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48); 2787453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4); 2797453645fSAndriy Voskoboinyk } 2807453645fSAndriy Voskoboinyk 2817453645fSAndriy Voskoboinyk void 2827453645fSAndriy Voskoboinyk r88eu_post_init(struct rtwn_softc *sc) 2837453645fSAndriy Voskoboinyk { 2847453645fSAndriy Voskoboinyk 2857453645fSAndriy Voskoboinyk /* Enable per-packet TX report. */ 2867453645fSAndriy Voskoboinyk rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA); 2877453645fSAndriy Voskoboinyk 2887453645fSAndriy Voskoboinyk /* Disable Tx if MACID is not associated. */ 2897453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff); 2907453645fSAndriy Voskoboinyk rtwn_write_4(sc, R88E_MACID_NO_LINK + 4, 0xffffffff); 2917453645fSAndriy Voskoboinyk r88e_macid_enable_link(sc, RTWN_MACID_BC, 1); 2927453645fSAndriy Voskoboinyk 2937453645fSAndriy Voskoboinyk /* Perform LO and IQ calibrations. */ 2947453645fSAndriy Voskoboinyk r88e_iq_calib(sc); 2957453645fSAndriy Voskoboinyk /* Perform LC calibration. */ 2967453645fSAndriy Voskoboinyk r92c_lc_calib(sc); 2977453645fSAndriy Voskoboinyk 2987453645fSAndriy Voskoboinyk rtwn_write_1(sc, R92C_USB_HRPWM, 0); 2997453645fSAndriy Voskoboinyk 3007453645fSAndriy Voskoboinyk if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) { 3017453645fSAndriy Voskoboinyk /* No support (yet?) for f/w rate adaptation. */ 3027453645fSAndriy Voskoboinyk sc->sc_ratectl = RTWN_RATECTL_NET80211; 3037453645fSAndriy Voskoboinyk } else 3047453645fSAndriy Voskoboinyk sc->sc_ratectl = sc->sc_ratectl_sysctl; 3057453645fSAndriy Voskoboinyk } 306