xref: /freebsd/sys/dev/rtwn/rtl8188e/usb/r88eu_init.c (revision af2e102c40652156c89029177da7961165ffe4cc)
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 #include "opt_wlan.h"
237453645fSAndriy Voskoboinyk 
247453645fSAndriy Voskoboinyk #include <sys/param.h>
257453645fSAndriy Voskoboinyk #include <sys/lock.h>
267453645fSAndriy Voskoboinyk #include <sys/mutex.h>
277453645fSAndriy Voskoboinyk #include <sys/mbuf.h>
287453645fSAndriy Voskoboinyk #include <sys/kernel.h>
297453645fSAndriy Voskoboinyk #include <sys/socket.h>
307453645fSAndriy Voskoboinyk #include <sys/systm.h>
317453645fSAndriy Voskoboinyk #include <sys/malloc.h>
327453645fSAndriy Voskoboinyk #include <sys/queue.h>
337453645fSAndriy Voskoboinyk #include <sys/taskqueue.h>
347453645fSAndriy Voskoboinyk #include <sys/bus.h>
357453645fSAndriy Voskoboinyk #include <sys/endian.h>
367453645fSAndriy Voskoboinyk #include <sys/linker.h>
377453645fSAndriy Voskoboinyk 
387453645fSAndriy Voskoboinyk #include <net/if.h>
397453645fSAndriy Voskoboinyk #include <net/ethernet.h>
407453645fSAndriy Voskoboinyk #include <net/if_media.h>
417453645fSAndriy Voskoboinyk 
427453645fSAndriy Voskoboinyk #include <net80211/ieee80211_var.h>
437453645fSAndriy Voskoboinyk #include <net80211/ieee80211_radiotap.h>
447453645fSAndriy Voskoboinyk 
457453645fSAndriy Voskoboinyk #include <dev/rtwn/if_rtwnreg.h>
467453645fSAndriy Voskoboinyk #include <dev/rtwn/if_rtwnvar.h>
477453645fSAndriy Voskoboinyk 
487453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8192c/r92c.h>
497453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8192c/r92c_var.h>
507453645fSAndriy Voskoboinyk 
517453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8188e/usb/r88eu.h>
527453645fSAndriy Voskoboinyk #include <dev/rtwn/rtl8188e/usb/r88eu_reg.h>
537453645fSAndriy Voskoboinyk 
547453645fSAndriy Voskoboinyk void
r88eu_init_bb(struct rtwn_softc * sc)554e4bcfcfSAndriy Voskoboinyk r88eu_init_bb(struct rtwn_softc *sc)
564e4bcfcfSAndriy Voskoboinyk {
574e4bcfcfSAndriy Voskoboinyk 
584e4bcfcfSAndriy Voskoboinyk 	/* Enable BB and RF. */
594e4bcfcfSAndriy Voskoboinyk 	rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
604e4bcfcfSAndriy Voskoboinyk 	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
614e4bcfcfSAndriy Voskoboinyk 	    R92C_SYS_FUNC_EN_DIO_RF);
624e4bcfcfSAndriy Voskoboinyk 
634e4bcfcfSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RF_CTRL,
644e4bcfcfSAndriy Voskoboinyk 	    R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
654e4bcfcfSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_SYS_FUNC_EN,
664e4bcfcfSAndriy Voskoboinyk 	    R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
674e4bcfcfSAndriy Voskoboinyk 	    R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
684e4bcfcfSAndriy Voskoboinyk 
694e4bcfcfSAndriy Voskoboinyk 	r88e_init_bb_common(sc);
704e4bcfcfSAndriy Voskoboinyk }
714e4bcfcfSAndriy Voskoboinyk 
724e4bcfcfSAndriy Voskoboinyk int
r88eu_power_on(struct rtwn_softc * sc)734e4bcfcfSAndriy Voskoboinyk r88eu_power_on(struct rtwn_softc *sc)
744e4bcfcfSAndriy Voskoboinyk {
754e4bcfcfSAndriy Voskoboinyk #define RTWN_CHK(res) do {	\
764e4bcfcfSAndriy Voskoboinyk 	if (res != 0)		\
774e4bcfcfSAndriy Voskoboinyk 		return (EIO);	\
784e4bcfcfSAndriy Voskoboinyk } while(0)
794e4bcfcfSAndriy Voskoboinyk 	int ntries;
804e4bcfcfSAndriy Voskoboinyk 
814e4bcfcfSAndriy Voskoboinyk 	/* Wait for power ready bit. */
824e4bcfcfSAndriy Voskoboinyk 	for (ntries = 0; ntries < 5000; ntries++) {
834e4bcfcfSAndriy Voskoboinyk 		if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
844e4bcfcfSAndriy Voskoboinyk 			break;
854e4bcfcfSAndriy Voskoboinyk 		rtwn_delay(sc, 10);
864e4bcfcfSAndriy Voskoboinyk 	}
874e4bcfcfSAndriy Voskoboinyk 	if (ntries == 5000) {
884e4bcfcfSAndriy Voskoboinyk 		device_printf(sc->sc_dev,
894e4bcfcfSAndriy Voskoboinyk 		    "timeout waiting for chip power up\n");
904e4bcfcfSAndriy Voskoboinyk 		return (ETIMEDOUT);
914e4bcfcfSAndriy Voskoboinyk 	}
924e4bcfcfSAndriy Voskoboinyk 
934e4bcfcfSAndriy Voskoboinyk 	/* Reset BB. */
944e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_FUNC_EN,
954e4bcfcfSAndriy Voskoboinyk 	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST, 0));
964e4bcfcfSAndriy Voskoboinyk 
974e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80));
984e4bcfcfSAndriy Voskoboinyk 
994e4bcfcfSAndriy Voskoboinyk 	/* Disable HWPDN. */
1004e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
1014e4bcfcfSAndriy Voskoboinyk 	    R92C_APS_FSMCO_APDM_HPDN, 0, 1));
1024e4bcfcfSAndriy Voskoboinyk 
1034e4bcfcfSAndriy Voskoboinyk 	/* Disable WL suspend. */
1044e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
1054e4bcfcfSAndriy Voskoboinyk 	    R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
1064e4bcfcfSAndriy Voskoboinyk 
1074e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
1084e4bcfcfSAndriy Voskoboinyk 	    0, R92C_APS_FSMCO_APFM_ONMAC, 1));
1094e4bcfcfSAndriy Voskoboinyk 	for (ntries = 0; ntries < 5000; ntries++) {
1104e4bcfcfSAndriy Voskoboinyk 		if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
1114e4bcfcfSAndriy Voskoboinyk 		    R92C_APS_FSMCO_APFM_ONMAC))
1124e4bcfcfSAndriy Voskoboinyk 			break;
1134e4bcfcfSAndriy Voskoboinyk 		rtwn_delay(sc, 10);
1144e4bcfcfSAndriy Voskoboinyk 	}
1154e4bcfcfSAndriy Voskoboinyk 	if (ntries == 5000)
1164e4bcfcfSAndriy Voskoboinyk 		return (ETIMEDOUT);
1174e4bcfcfSAndriy Voskoboinyk 
1184e4bcfcfSAndriy Voskoboinyk 	/* Enable LDO normal mode. */
1194e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_1(sc, R92C_LPLDO_CTRL,
1204e4bcfcfSAndriy Voskoboinyk 	    R92C_LPLDO_CTRL_SLEEP, 0));
1214e4bcfcfSAndriy Voskoboinyk 
1224e4bcfcfSAndriy Voskoboinyk 	/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
1234e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0));
1244e4bcfcfSAndriy Voskoboinyk 	RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0,
1254e4bcfcfSAndriy Voskoboinyk 	    R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN |
1264e4bcfcfSAndriy Voskoboinyk 	    R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN |
1274e4bcfcfSAndriy Voskoboinyk 	    R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN |
1284e4bcfcfSAndriy Voskoboinyk 	    ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) |
1294e4bcfcfSAndriy Voskoboinyk 	    R92C_CR_CALTMR_EN));
1304e4bcfcfSAndriy Voskoboinyk 
1314e4bcfcfSAndriy Voskoboinyk 	return (0);
1324e4bcfcfSAndriy Voskoboinyk #undef RTWN_CHK
1334e4bcfcfSAndriy Voskoboinyk }
1344e4bcfcfSAndriy Voskoboinyk 
1354e4bcfcfSAndriy Voskoboinyk void
r88eu_power_off(struct rtwn_softc * sc)1367453645fSAndriy Voskoboinyk r88eu_power_off(struct rtwn_softc *sc)
1377453645fSAndriy Voskoboinyk {
1387453645fSAndriy Voskoboinyk 	uint8_t reg;
1397453645fSAndriy Voskoboinyk 	int error, ntries;
1407453645fSAndriy Voskoboinyk 
1417453645fSAndriy Voskoboinyk 	/* Disable any kind of TX reports. */
1427453645fSAndriy Voskoboinyk 	error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL,
1437453645fSAndriy Voskoboinyk 	    R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA, 0);
1447453645fSAndriy Voskoboinyk 	if (error == ENXIO)	/* hardware gone */
1457453645fSAndriy Voskoboinyk 		return;
1467453645fSAndriy Voskoboinyk 
1477453645fSAndriy Voskoboinyk 	/* Stop Rx. */
1487453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_CR, 0);
1497453645fSAndriy Voskoboinyk 
1507453645fSAndriy Voskoboinyk 	/* Move card to Low Power State. */
1517453645fSAndriy Voskoboinyk 	/* Block all Tx queues. */
1527453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
1537453645fSAndriy Voskoboinyk 
1547453645fSAndriy Voskoboinyk 	for (ntries = 0; ntries < 10; ntries++) {
1557453645fSAndriy Voskoboinyk 		/* Should be zero if no packet is transmitting. */
1567453645fSAndriy Voskoboinyk 		if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
1577453645fSAndriy Voskoboinyk 			break;
1587453645fSAndriy Voskoboinyk 
1597453645fSAndriy Voskoboinyk 		rtwn_delay(sc, 5000);
1607453645fSAndriy Voskoboinyk 	}
1617453645fSAndriy Voskoboinyk 	if (ntries == 10) {
1627453645fSAndriy Voskoboinyk 		device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
1637453645fSAndriy Voskoboinyk 		    __func__);
1647453645fSAndriy Voskoboinyk 		return;
1657453645fSAndriy Voskoboinyk 	}
1667453645fSAndriy Voskoboinyk 
1677453645fSAndriy Voskoboinyk 	/* CCK and OFDM are disabled, and clock are gated. */
1687453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0);
1697453645fSAndriy Voskoboinyk 
1707453645fSAndriy Voskoboinyk 	rtwn_delay(sc, 1);
1717453645fSAndriy Voskoboinyk 
1727453645fSAndriy Voskoboinyk 	/* Reset MAC TRX */
1737453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_CR,
1747453645fSAndriy Voskoboinyk 	    R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
1757453645fSAndriy Voskoboinyk 	    R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN |
1767453645fSAndriy Voskoboinyk 	    R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN);
1777453645fSAndriy Voskoboinyk 
1787453645fSAndriy Voskoboinyk 	/* check if removed later */
1797453645fSAndriy Voskoboinyk 	rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1);
1807453645fSAndriy Voskoboinyk 
1817453645fSAndriy Voskoboinyk 	/* Respond TxOK to scheduler */
1827453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, 0x20);
1837453645fSAndriy Voskoboinyk 
1847453645fSAndriy Voskoboinyk 	/* If firmware in ram code, do reset. */
1857453645fSAndriy Voskoboinyk #ifndef RTWN_WITHOUT_UCODE
1867453645fSAndriy Voskoboinyk 	if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY)
1877453645fSAndriy Voskoboinyk 		r88e_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
1887453645fSAndriy Voskoboinyk #endif
1897453645fSAndriy Voskoboinyk 
1907453645fSAndriy Voskoboinyk 	/* Reset MCU ready status. */
1917453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_MCUFWDL, 0);
1927453645fSAndriy Voskoboinyk 
1937453645fSAndriy Voskoboinyk 	/* Disable 32k. */
1947453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R88E_32K_CTRL, 0x01, 0);
1957453645fSAndriy Voskoboinyk 
1967453645fSAndriy Voskoboinyk 	/* Move card to Disabled state. */
1977453645fSAndriy Voskoboinyk 	/* Turn off RF. */
1987453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RF_CTRL, 0);
1997453645fSAndriy Voskoboinyk 
2007453645fSAndriy Voskoboinyk 	/* LDO Sleep mode. */
2017453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 0, R92C_LPLDO_CTRL_SLEEP);
2027453645fSAndriy Voskoboinyk 
2037453645fSAndriy Voskoboinyk 	/* Turn off MAC by HW state machine */
2047453645fSAndriy Voskoboinyk 	rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
2057453645fSAndriy Voskoboinyk 	    R92C_APS_FSMCO_APFM_OFF, 1);
2067453645fSAndriy Voskoboinyk 
2077453645fSAndriy Voskoboinyk 	for (ntries = 0; ntries < 10; ntries++) {
2087453645fSAndriy Voskoboinyk 		/* Wait until it will be disabled. */
2097453645fSAndriy Voskoboinyk 		if ((rtwn_read_2(sc, R92C_APS_FSMCO) &
2107453645fSAndriy Voskoboinyk 		    R92C_APS_FSMCO_APFM_OFF) == 0)
2117453645fSAndriy Voskoboinyk 			break;
2127453645fSAndriy Voskoboinyk 
2137453645fSAndriy Voskoboinyk 		rtwn_delay(sc, 5000);
2147453645fSAndriy Voskoboinyk 	}
2157453645fSAndriy Voskoboinyk 	if (ntries == 10) {
2167453645fSAndriy Voskoboinyk 		device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
2177453645fSAndriy Voskoboinyk 		    __func__);
2187453645fSAndriy Voskoboinyk 		return;
2197453645fSAndriy Voskoboinyk 	}
2207453645fSAndriy Voskoboinyk 
2217453645fSAndriy Voskoboinyk 	/* schmit trigger */
2227453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80);
2237453645fSAndriy Voskoboinyk 
2247453645fSAndriy Voskoboinyk 	/* Enable WL suspend. */
2257453645fSAndriy Voskoboinyk 	rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
2267453645fSAndriy Voskoboinyk 	    R92C_APS_FSMCO_AFSM_PCIE, R92C_APS_FSMCO_AFSM_HSUS, 1);
2277453645fSAndriy Voskoboinyk 
2287453645fSAndriy Voskoboinyk 	/* Enable bandgap mbias in suspend. */
2297453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_APS_FSMCO + 3, 0);
2307453645fSAndriy Voskoboinyk 
2317453645fSAndriy Voskoboinyk 	/* Clear SIC_EN register. */
2327453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_GPIO_MUXCFG + 1, 0x10, 0);
2337453645fSAndriy Voskoboinyk 
2347453645fSAndriy Voskoboinyk 	/* Set USB suspend enable local register */
2357453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_USB_SUSPEND, 0, 0x10);
2367453645fSAndriy Voskoboinyk 
2377453645fSAndriy Voskoboinyk 	/* Reset MCU IO Wrapper. */
2387453645fSAndriy Voskoboinyk 	reg = rtwn_read_1(sc, R92C_RSV_CTRL + 1);
2397453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08);
2407453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08);
2417453645fSAndriy Voskoboinyk 
2427453645fSAndriy Voskoboinyk 	/* marked as 'For Power Consumption' code. */
2437453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_GPIO_OUT, rtwn_read_1(sc, R92C_GPIO_IN));
2447453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff);
2457453645fSAndriy Voskoboinyk 
2467453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_GPIO_IO_SEL,
2477453645fSAndriy Voskoboinyk 	    rtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4);
2487453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_GPIO_MOD, 0, 0x0f);
2497453645fSAndriy Voskoboinyk 
2507453645fSAndriy Voskoboinyk 	/* Set LNA, TRSW, EX_PA Pin to output mode. */
2517453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808);
2527453645fSAndriy Voskoboinyk }
2537453645fSAndriy Voskoboinyk 
2547453645fSAndriy Voskoboinyk void
r88eu_init_intr(struct rtwn_softc * sc)2557453645fSAndriy Voskoboinyk r88eu_init_intr(struct rtwn_softc *sc)
2567453645fSAndriy Voskoboinyk {
2577453645fSAndriy Voskoboinyk 	/* TODO: adjust */
2587453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_HISR, 0xffffffff);
2597453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
2607453645fSAndriy Voskoboinyk 	    R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT);
2617453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
2627453645fSAndriy Voskoboinyk 	    R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR);
2637453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
2647453645fSAndriy Voskoboinyk 	    R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
2657453645fSAndriy Voskoboinyk }
2667453645fSAndriy Voskoboinyk 
2677453645fSAndriy Voskoboinyk void
r88eu_init_rx_agg(struct rtwn_softc * sc)2687453645fSAndriy Voskoboinyk r88eu_init_rx_agg(struct rtwn_softc *sc)
2697453645fSAndriy Voskoboinyk {
2707453645fSAndriy Voskoboinyk 	/* XXX merge? */
2717453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
2727453645fSAndriy Voskoboinyk 	    R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
2737453645fSAndriy Voskoboinyk 	/* XXX dehardcode */
2747453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
2757453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
2767453645fSAndriy Voskoboinyk }
2777453645fSAndriy Voskoboinyk 
2787453645fSAndriy Voskoboinyk void
r88eu_post_init(struct rtwn_softc * sc)2797453645fSAndriy Voskoboinyk r88eu_post_init(struct rtwn_softc *sc)
2807453645fSAndriy Voskoboinyk {
2817453645fSAndriy Voskoboinyk 
282*af2e102cSAdrian Chadd 	/* Enable per-packet TX report (RPT1) */
2837453645fSAndriy Voskoboinyk 	rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA);
2847453645fSAndriy Voskoboinyk 
285*af2e102cSAdrian Chadd #ifndef RTWN_WITHOUT_UCODE
286*af2e102cSAdrian Chadd 	/* Enable timer report (RPT2) if requested */
287*af2e102cSAdrian Chadd 	if (sc->macid_rpt2_max_num > 0) {
288*af2e102cSAdrian Chadd 		rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0,
289*af2e102cSAdrian Chadd 		    R88E_TX_RPT2_ENA);
290*af2e102cSAdrian Chadd 
291*af2e102cSAdrian Chadd 		/* Configure how many TX RPT2 entries to populate */
292*af2e102cSAdrian Chadd 		rtwn_write_1(sc, R88E_TX_RPT_MACID_MAX,
293*af2e102cSAdrian Chadd 		    sc->macid_rpt2_max_num);
294*af2e102cSAdrian Chadd 		/* Enable periodic TX report; 32uS units */
295*af2e102cSAdrian Chadd 		rtwn_write_2(sc, R88E_TX_RPT_TIME, 0xcdf0);
296*af2e102cSAdrian Chadd 	}
297*af2e102cSAdrian Chadd #endif
2987453645fSAndriy Voskoboinyk 	/* Disable Tx if MACID is not associated. */
2997453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff);
3007453645fSAndriy Voskoboinyk 	rtwn_write_4(sc, R88E_MACID_NO_LINK + 4, 0xffffffff);
3017453645fSAndriy Voskoboinyk 	r88e_macid_enable_link(sc, RTWN_MACID_BC, 1);
3027453645fSAndriy Voskoboinyk 
3037453645fSAndriy Voskoboinyk 	/* Perform LO and IQ calibrations. */
3047453645fSAndriy Voskoboinyk 	r88e_iq_calib(sc);
3057453645fSAndriy Voskoboinyk 	/* Perform LC calibration. */
3067453645fSAndriy Voskoboinyk 	r92c_lc_calib(sc);
3077453645fSAndriy Voskoboinyk 
3087453645fSAndriy Voskoboinyk 	rtwn_write_1(sc, R92C_USB_HRPWM, 0);
3097453645fSAndriy Voskoboinyk 
3107453645fSAndriy Voskoboinyk 	if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
3117453645fSAndriy Voskoboinyk 		/* No support (yet?) for f/w rate adaptation. */
3127453645fSAndriy Voskoboinyk 		sc->sc_ratectl = RTWN_RATECTL_NET80211;
3137453645fSAndriy Voskoboinyk 	} else
3147453645fSAndriy Voskoboinyk 		sc->sc_ratectl = sc->sc_ratectl_sysctl;
3157453645fSAndriy Voskoboinyk }
316