xref: /freebsd/sys/dev/rtwn/rtl8723b/usb/r23bu_init.c (revision 551b7c5e12bfea623a47edf97ad5689732a1233f)
1*551b7c5eSAhmad Khalifa /*
2*551b7c5eSAhmad Khalifa  * SPDX-License-Identifier: BSD-2-Clause
3*551b7c5eSAhmad Khalifa  *
4*551b7c5eSAhmad Khalifa  * Copyright (c) 2016 Andriy Voskoboinyk <avos@FreeBSD.org>
5*551b7c5eSAhmad Khalifa  * Copyright (c) 2026 Ahmad Khalifa <vexeduxr@FreeBSD.org>
6*551b7c5eSAhmad Khalifa  * All rights reserved.
7*551b7c5eSAhmad Khalifa  *
8*551b7c5eSAhmad Khalifa  * Redistribution and use in source and binary forms, with or without
9*551b7c5eSAhmad Khalifa  * modification, are permitted provided that the following conditions
10*551b7c5eSAhmad Khalifa  * are met:
11*551b7c5eSAhmad Khalifa  * 1. Redistributions of source code must retain the above copyright
12*551b7c5eSAhmad Khalifa  *    notice, this list of conditions and the following disclaimer.
13*551b7c5eSAhmad Khalifa  * 2. Redistributions in binary form must reproduce the above copyright
14*551b7c5eSAhmad Khalifa  *    notice, this list of conditions and the following disclaimer in the
15*551b7c5eSAhmad Khalifa  *    documentation and/or other materials provided with the distribution.
16*551b7c5eSAhmad Khalifa  *
17*551b7c5eSAhmad Khalifa  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*551b7c5eSAhmad Khalifa  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*551b7c5eSAhmad Khalifa  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*551b7c5eSAhmad Khalifa  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*551b7c5eSAhmad Khalifa  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*551b7c5eSAhmad Khalifa  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*551b7c5eSAhmad Khalifa  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*551b7c5eSAhmad Khalifa  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*551b7c5eSAhmad Khalifa  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*551b7c5eSAhmad Khalifa  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*551b7c5eSAhmad Khalifa  * SUCH DAMAGE.
28*551b7c5eSAhmad Khalifa  */
29*551b7c5eSAhmad Khalifa 
30*551b7c5eSAhmad Khalifa #include <sys/param.h>
31*551b7c5eSAhmad Khalifa #include <sys/lock.h>
32*551b7c5eSAhmad Khalifa #include <sys/mutex.h>
33*551b7c5eSAhmad Khalifa #include <sys/mbuf.h>
34*551b7c5eSAhmad Khalifa #include <sys/kernel.h>
35*551b7c5eSAhmad Khalifa #include <sys/socket.h>
36*551b7c5eSAhmad Khalifa #include <sys/systm.h>
37*551b7c5eSAhmad Khalifa #include <sys/malloc.h>
38*551b7c5eSAhmad Khalifa #include <sys/queue.h>
39*551b7c5eSAhmad Khalifa #include <sys/taskqueue.h>
40*551b7c5eSAhmad Khalifa #include <sys/bus.h>
41*551b7c5eSAhmad Khalifa #include <sys/endian.h>
42*551b7c5eSAhmad Khalifa #include <sys/linker.h>
43*551b7c5eSAhmad Khalifa 
44*551b7c5eSAhmad Khalifa #include <net/if.h>
45*551b7c5eSAhmad Khalifa #include <net/ethernet.h>
46*551b7c5eSAhmad Khalifa #include <net/if_media.h>
47*551b7c5eSAhmad Khalifa 
48*551b7c5eSAhmad Khalifa #include <net80211/ieee80211_var.h>
49*551b7c5eSAhmad Khalifa #include <net80211/ieee80211_radiotap.h>
50*551b7c5eSAhmad Khalifa 
51*551b7c5eSAhmad Khalifa #include <dev/usb/usb.h>
52*551b7c5eSAhmad Khalifa #include <dev/usb/usbdi.h>
53*551b7c5eSAhmad Khalifa 
54*551b7c5eSAhmad Khalifa #include <dev/rtwn/if_rtwnreg.h>
55*551b7c5eSAhmad Khalifa #include <dev/rtwn/if_rtwnvar.h>
56*551b7c5eSAhmad Khalifa 
57*551b7c5eSAhmad Khalifa #include <dev/rtwn/usb/rtwn_usb_var.h>
58*551b7c5eSAhmad Khalifa 
59*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8188e/r88e_reg.h>
60*551b7c5eSAhmad Khalifa 
61*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192c/r92c_reg.h>
62*551b7c5eSAhmad Khalifa 
63*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192e/r92e_var.h>
64*551b7c5eSAhmad Khalifa 
65*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_reg.h>
66*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_var.h>
67*551b7c5eSAhmad Khalifa 
68*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/usb/r23bu.h>
69*551b7c5eSAhmad Khalifa 
70*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8812a/r12a_reg.h>
71*551b7c5eSAhmad Khalifa 
72*551b7c5eSAhmad Khalifa int
r23bu_power_on(struct rtwn_softc * sc)73*551b7c5eSAhmad Khalifa r23bu_power_on(struct rtwn_softc *sc)
74*551b7c5eSAhmad Khalifa {
75*551b7c5eSAhmad Khalifa #define RTWN_CHK(res) do {	\
76*551b7c5eSAhmad Khalifa 	if (res != 0)		\
77*551b7c5eSAhmad Khalifa 		return (EIO);	\
78*551b7c5eSAhmad Khalifa } while(0)
79*551b7c5eSAhmad Khalifa 	int ntries;
80*551b7c5eSAhmad Khalifa 
81*551b7c5eSAhmad Khalifa 	/* Clear suspend and power down bits.*/
82*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
83*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_APDM_HPDN, 0, 1));
84*551b7c5eSAhmad Khalifa 
85*551b7c5eSAhmad Khalifa 	/* Disable GPIO9 as EXT WAKEUP. */
86*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_GPIO_INTM + 2, 0x01, 0));
87*551b7c5eSAhmad Khalifa 
88*551b7c5eSAhmad Khalifa 	/* Enable WL suspend. */
89*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
90*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
91*551b7c5eSAhmad Khalifa 
92*551b7c5eSAhmad Khalifa 	/* Enable LDOA12 MACRO block for all interfaces. */
93*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_LDOA15_CTRL, 0, R92C_LDOA15_CTRL_EN));
94*551b7c5eSAhmad Khalifa 
95*551b7c5eSAhmad Khalifa 	/* Disable BT_GPS_SEL pins. */
96*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, 0x067, 0x10, 0));
97*551b7c5eSAhmad Khalifa 
98*551b7c5eSAhmad Khalifa 	/* 1 ms delay. */
99*551b7c5eSAhmad Khalifa 	rtwn_delay(sc, 1000);
100*551b7c5eSAhmad Khalifa 
101*551b7c5eSAhmad Khalifa 	/* Release analog Ips to digital isolation. */
102*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL,
103*551b7c5eSAhmad Khalifa 	    R92C_SYS_ISO_CTRL_IP2MAC, 0));
104*551b7c5eSAhmad Khalifa 
105*551b7c5eSAhmad Khalifa 	/* Disable SW LPS and WL suspend. */
106*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
107*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_APFM_RSM |
108*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_HSUS |
109*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
110*551b7c5eSAhmad Khalifa 
111*551b7c5eSAhmad Khalifa 	/* Wait for power ready bit. */
112*551b7c5eSAhmad Khalifa 	for (ntries = 0; ntries < 5000; ntries++) {
113*551b7c5eSAhmad Khalifa 		if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
114*551b7c5eSAhmad Khalifa 			break;
115*551b7c5eSAhmad Khalifa 		rtwn_delay(sc, 10);
116*551b7c5eSAhmad Khalifa 	}
117*551b7c5eSAhmad Khalifa 	if (ntries == 5000) {
118*551b7c5eSAhmad Khalifa 		device_printf(sc->sc_dev,
119*551b7c5eSAhmad Khalifa 		    "timeout waiting for chip power up\n");
120*551b7c5eSAhmad Khalifa 		return (ETIMEDOUT);
121*551b7c5eSAhmad Khalifa 	}
122*551b7c5eSAhmad Khalifa 
123*551b7c5eSAhmad Khalifa 	/* Release WLON reset. */
124*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
125*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_RDY_MACON, 2));
126*551b7c5eSAhmad Khalifa 
127*551b7c5eSAhmad Khalifa 	/* Disable HWPDN. */
128*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
129*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_APDM_HPDN, 0, 1));
130*551b7c5eSAhmad Khalifa 
131*551b7c5eSAhmad Khalifa 	/* Disable WL suspend. */
132*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
133*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
134*551b7c5eSAhmad Khalifa 
135*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
136*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_APFM_ONMAC, 1));
137*551b7c5eSAhmad Khalifa 	for (ntries = 0; ntries < 5000; ntries++) {
138*551b7c5eSAhmad Khalifa 		if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
139*551b7c5eSAhmad Khalifa 		    R92C_APS_FSMCO_APFM_ONMAC))
140*551b7c5eSAhmad Khalifa 			break;
141*551b7c5eSAhmad Khalifa 		rtwn_delay(sc, 10);
142*551b7c5eSAhmad Khalifa 	}
143*551b7c5eSAhmad Khalifa 	if (ntries == 5000)
144*551b7c5eSAhmad Khalifa 		return (ETIMEDOUT);
145*551b7c5eSAhmad Khalifa 
146*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_AFE_MISC, 0, 0x40));
147*551b7c5eSAhmad Khalifa 
148*551b7c5eSAhmad Khalifa 	/* Enable falling edge triggering interrupt. */
149*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_GPIO_INTM + 1, 0, 0x02));
150*551b7c5eSAhmad Khalifa 
151*551b7c5eSAhmad Khalifa 	/* Enable GPIO9 interrupt mode. */
152*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, 0x063, 0, 0x02));
153*551b7c5eSAhmad Khalifa 
154*551b7c5eSAhmad Khalifa 	/* Enable GPIO9 input mode. */
155*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, 0x062, 0x02, 0));
156*551b7c5eSAhmad Khalifa 
157*551b7c5eSAhmad Khalifa 	/* Enable HSISR GPIO interrupt. */
158*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_HSIMR, 0, 0x01));
159*551b7c5eSAhmad Khalifa 
160*551b7c5eSAhmad Khalifa 	/* Enable HSISR GPIO9 interrupt. */
161*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_HSIMR + 2, 0, 0x02));
162*551b7c5eSAhmad Khalifa 
163*551b7c5eSAhmad Khalifa 	/* GPIO9 internal pull up. */
164*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R92C_MULTI_FUNC_CTRL, 0, 0x08));
165*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_MULTI_FUNC_CTRL, 0, 0x4000, 1));
166*551b7c5eSAhmad Khalifa 
167*551b7c5eSAhmad Khalifa 	/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
168*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_1(sc, R92C_CR, 0x00));
169*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0,
170*551b7c5eSAhmad Khalifa 	    R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN |
171*551b7c5eSAhmad Khalifa 	    R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN |
172*551b7c5eSAhmad Khalifa 	    R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN |
173*551b7c5eSAhmad Khalifa 	    ((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) |
174*551b7c5eSAhmad Khalifa 	    R92C_CR_CALTMR_EN));
175*551b7c5eSAhmad Khalifa 
176*551b7c5eSAhmad Khalifa 	/* btcoex power on. */
177*551b7c5eSAhmad Khalifa 
178*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_1(sc, R88E_BB_PAD_CTRL + 3, 0x20));
179*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
180*551b7c5eSAhmad Khalifa 	    R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST));
181*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_1(sc, R23B_GNT_BT + 1, 0x18));
182*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_1(sc, 0x76e, 0x4));
183*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_4(sc, R23B_ANT_SEL, R23B_ANT_SEL_S0));
184*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_write_1(sc, 0xfe08, 0x1));
185*551b7c5eSAhmad Khalifa 
186*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_2(sc, R92C_PWR_DATA, 0,
187*551b7c5eSAhmad Khalifa 	    R23B_PWR_DATA_RFE_CTRL_EN));
188*551b7c5eSAhmad Khalifa 
189*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_4(sc, R92C_LEDCFG0, 0, R23B_LEDCFG0_DPDT_SEL_EN));
190*551b7c5eSAhmad Khalifa 
191*551b7c5eSAhmad Khalifa 	RTWN_CHK(rtwn_setbits_1(sc, R88E_BB_PAD_CTRL,
192*551b7c5eSAhmad Khalifa 	    R23B_BB_PAD_CTRL_DPDT_SEL_DATA, 0));
193*551b7c5eSAhmad Khalifa 
194*551b7c5eSAhmad Khalifa 	return (0);
195*551b7c5eSAhmad Khalifa #undef RTWN_CHK
196*551b7c5eSAhmad Khalifa }
197*551b7c5eSAhmad Khalifa 
198*551b7c5eSAhmad Khalifa void
r23bu_power_off(struct rtwn_softc * sc)199*551b7c5eSAhmad Khalifa r23bu_power_off(struct rtwn_softc *sc)
200*551b7c5eSAhmad Khalifa {
201*551b7c5eSAhmad Khalifa 	int error, ntries;
202*551b7c5eSAhmad Khalifa 
203*551b7c5eSAhmad Khalifa 	/* Stop Tx report timer. */
204*551b7c5eSAhmad Khalifa 	error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, R88E_TX_RPT2_ENA, 0);
205*551b7c5eSAhmad Khalifa 	if (error == ENXIO) /* hardware gone */
206*551b7c5eSAhmad Khalifa 		return;
207*551b7c5eSAhmad Khalifa 
208*551b7c5eSAhmad Khalifa 	/* Stop Rx. */
209*551b7c5eSAhmad Khalifa 	rtwn_write_4(sc, R92C_CR, 0x0000);
210*551b7c5eSAhmad Khalifa 
211*551b7c5eSAhmad Khalifa 	/* Move card to Low Power state. */
212*551b7c5eSAhmad Khalifa 	/* Block all Tx queues. */
213*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
214*551b7c5eSAhmad Khalifa 
215*551b7c5eSAhmad Khalifa 	for (ntries = 0; ntries < 10; ntries++) {
216*551b7c5eSAhmad Khalifa 		/* Should be zero if no packet is transmitting. */
217*551b7c5eSAhmad Khalifa 		if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
218*551b7c5eSAhmad Khalifa 			break;
219*551b7c5eSAhmad Khalifa 
220*551b7c5eSAhmad Khalifa 		rtwn_delay(sc, 5000);
221*551b7c5eSAhmad Khalifa 	}
222*551b7c5eSAhmad Khalifa 	if (ntries == 10) {
223*551b7c5eSAhmad Khalifa 		device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
224*551b7c5eSAhmad Khalifa 		    __func__);
225*551b7c5eSAhmad Khalifa 		return;
226*551b7c5eSAhmad Khalifa 	}
227*551b7c5eSAhmad Khalifa 
228*551b7c5eSAhmad Khalifa 	/* CCK and OFDM are disabled, and clock are gated. */
229*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0);
230*551b7c5eSAhmad Khalifa 
231*551b7c5eSAhmad Khalifa 	rtwn_delay(sc, 1);
232*551b7c5eSAhmad Khalifa 
233*551b7c5eSAhmad Khalifa 	/* Reset whole BB. */
234*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BB_GLB_RST, 0);
235*551b7c5eSAhmad Khalifa 
236*551b7c5eSAhmad Khalifa 	/* Reset MAC TRX. */
237*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_CR, R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN);
238*551b7c5eSAhmad Khalifa 
239*551b7c5eSAhmad Khalifa 	/* check if removed later. (?) */
240*551b7c5eSAhmad Khalifa 	rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1);
241*551b7c5eSAhmad Khalifa 
242*551b7c5eSAhmad Khalifa 	/* Respond TxOK to scheduler */
243*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, R92C_DUAL_TSF_RST_TXOK);
244*551b7c5eSAhmad Khalifa 
245*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
246*551b7c5eSAhmad Khalifa 	if ((sc->sc_flags & RTWN_FW_LOADED) &&
247*551b7c5eSAhmad Khalifa 	    (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL))
248*551b7c5eSAhmad Khalifa 		rtwn_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
249*551b7c5eSAhmad Khalifa #endif
250*551b7c5eSAhmad Khalifa 
251*551b7c5eSAhmad Khalifa 	/* Reset MCU. */
252*551b7c5eSAhmad Khalifa 	rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_CPUEN,
253*551b7c5eSAhmad Khalifa 	    0, 1);
254*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_MCUFWDL, 0);
255*551b7c5eSAhmad Khalifa 
256*551b7c5eSAhmad Khalifa 	/* Move card to Disabled state. */
257*551b7c5eSAhmad Khalifa 	/* Turn off RF. */
258*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_RF_CTRL, 0);
259*551b7c5eSAhmad Khalifa 
260*551b7c5eSAhmad Khalifa 	/* Enable rising edge triggering interrupt. */
261*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_GPIO_INTM + 1, 0x02, 0);
262*551b7c5eSAhmad Khalifa 
263*551b7c5eSAhmad Khalifa 	/* Release WLON reset. */
264*551b7c5eSAhmad Khalifa 	rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
265*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_RDY_MACON, 2);
266*551b7c5eSAhmad Khalifa 
267*551b7c5eSAhmad Khalifa 	/* Turn off MAC by HW state machine */
268*551b7c5eSAhmad Khalifa 	rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_OFF, 1);
269*551b7c5eSAhmad Khalifa 	for (ntries = 0; ntries < 10; ntries++) {
270*551b7c5eSAhmad Khalifa 		/* Wait until it will be disabled. */
271*551b7c5eSAhmad Khalifa 		if ((rtwn_read_2(sc, R92C_APS_FSMCO) &
272*551b7c5eSAhmad Khalifa 		    R92C_APS_FSMCO_APFM_OFF) == 0)
273*551b7c5eSAhmad Khalifa 			break;
274*551b7c5eSAhmad Khalifa 
275*551b7c5eSAhmad Khalifa 		rtwn_delay(sc, 5000);
276*551b7c5eSAhmad Khalifa 	}
277*551b7c5eSAhmad Khalifa 	if (ntries == 10) {
278*551b7c5eSAhmad Khalifa 		device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
279*551b7c5eSAhmad Khalifa 		    __func__);
280*551b7c5eSAhmad Khalifa 		return;
281*551b7c5eSAhmad Khalifa 	}
282*551b7c5eSAhmad Khalifa 
283*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_AFE_MISC, 0x40, 0);
284*551b7c5eSAhmad Khalifa 
285*551b7c5eSAhmad Khalifa 	/* Analog Ips to digital isolation. */
286*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL, 0, R92C_SYS_ISO_CTRL_IP2MAC);
287*551b7c5eSAhmad Khalifa 
288*551b7c5eSAhmad Khalifa 	/* Disable LDOA12 MACRO block. */
289*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_EN, 0);
290*551b7c5eSAhmad Khalifa 
291*551b7c5eSAhmad Khalifa 	/* Enable WL suspend. */
292*551b7c5eSAhmad Khalifa 	rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, R92C_APS_FSMCO_AFSM_PCIE,
293*551b7c5eSAhmad Khalifa 	    R92C_APS_FSMCO_AFSM_HSUS, 1);
294*551b7c5eSAhmad Khalifa 
295*551b7c5eSAhmad Khalifa 	/* Enable GPIO9 as EXT WAKEUP. */
296*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_GPIO_INTM + 2, 0, 0x01);
297*551b7c5eSAhmad Khalifa }
298*551b7c5eSAhmad Khalifa 
299*551b7c5eSAhmad Khalifa void
r23bu_init_bb(struct rtwn_softc * sc)300*551b7c5eSAhmad Khalifa r23bu_init_bb(struct rtwn_softc *sc)
301*551b7c5eSAhmad Khalifa {
302*551b7c5eSAhmad Khalifa 	/* Enable BB and RF. */
303*551b7c5eSAhmad Khalifa 	rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0, R92C_SYS_FUNC_EN_BBRSTB |
304*551b7c5eSAhmad Khalifa 	    R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_DIO_RF);
305*551b7c5eSAhmad Khalifa 
306*551b7c5eSAhmad Khalifa 	/* Select antenna S0. */
307*551b7c5eSAhmad Khalifa 	rtwn_write_4(sc, R23B_ANT_SEL, R23B_ANT_SEL_S0);
308*551b7c5eSAhmad Khalifa 
309*551b7c5eSAhmad Khalifa 	return (r23b_init_bb_common(sc));
310*551b7c5eSAhmad Khalifa }
311*551b7c5eSAhmad Khalifa 
312*551b7c5eSAhmad Khalifa void
r23bu_init_rx_agg(struct rtwn_softc * sc)313*551b7c5eSAhmad Khalifa r23bu_init_rx_agg(struct rtwn_softc *sc)
314*551b7c5eSAhmad Khalifa {
315*551b7c5eSAhmad Khalifa 	struct r23b_softc *rs = sc->sc_priv;
316*551b7c5eSAhmad Khalifa 	uint32_t val;
317*551b7c5eSAhmad Khalifa 
318*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0, R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
319*551b7c5eSAhmad Khalifa 
320*551b7c5eSAhmad Khalifa 	val = rtwn_read_4(sc, R92C_RXDMA_AGG_PG_TH);
321*551b7c5eSAhmad Khalifa 	val = RW(val, R23B_RXDMA_AGG_PG_TH_SIZE, rs->super.ac_usb_dma_size);
322*551b7c5eSAhmad Khalifa 	val = RW(val, R23B_RXDMA_AGG_PG_TH_TIME, rs->super.ac_usb_dma_time);
323*551b7c5eSAhmad Khalifa 	val |= R23B_RXDMA_AGG_PG_TH_EN;
324*551b7c5eSAhmad Khalifa 	rtwn_write_4(sc, R92C_RXDMA_AGG_PG_TH, val);
325*551b7c5eSAhmad Khalifa }
326*551b7c5eSAhmad Khalifa 
327*551b7c5eSAhmad Khalifa void
r23bu_init_ampdu(struct rtwn_softc * sc)328*551b7c5eSAhmad Khalifa r23bu_init_ampdu(struct rtwn_softc *sc)
329*551b7c5eSAhmad Khalifa {
330*551b7c5eSAhmad Khalifa 	struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
331*551b7c5eSAhmad Khalifa 	uint8_t val;
332*551b7c5eSAhmad Khalifa 
333*551b7c5eSAhmad Khalifa 	val = rtwn_read_1(sc, R12A_RXDMA_PRO);
334*551b7c5eSAhmad Khalifa 	val = RW(val, R12A_BURST_SZ,
335*551b7c5eSAhmad Khalifa 	    usbd_get_speed(uc->uc_udev) == USB_SPEED_HIGH ?
336*551b7c5eSAhmad Khalifa 	    R12A_BURST_SZ_USB2 : R12A_BURST_SZ_USB1);
337*551b7c5eSAhmad Khalifa 	val |= R12A_DMA_MODE | SM(R12A_BURST_CNT, 3);
338*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R12A_RXDMA_PRO, val);
339*551b7c5eSAhmad Khalifa 
340*551b7c5eSAhmad Khalifa 	/* Enable single packet AMPDU. */
341*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R12A_HT_SINGLE_AMPDU, 0,
342*551b7c5eSAhmad Khalifa 	    R12A_HT_SINGLE_AMPDU_PKT_ENA);
343*551b7c5eSAhmad Khalifa 
344*551b7c5eSAhmad Khalifa 	rtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0c14);
345*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R12A_AMPDU_MAX_TIME, 0x5e);
346*551b7c5eSAhmad Khalifa 	rtwn_write_4(sc, R12A_AMPDU_MAX_LENGTH, UINT32_MAX);
347*551b7c5eSAhmad Khalifa 
348*551b7c5eSAhmad Khalifa 	/*
349*551b7c5eSAhmad Khalifa 	 * The vendor driver says this is for
350*551b7c5eSAhmad Khalifa 	 * "VHT packet length 11K", but this chip
351*551b7c5eSAhmad Khalifa 	 * doesn't support VHT rates...
352*551b7c5eSAhmad Khalifa 	 */
353*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_RX_PKT_LIMIT, 0x18);
354*551b7c5eSAhmad Khalifa 
355*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_PIFS, 0);
356*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_FWHW_TXQ_CTRL, R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
357*551b7c5eSAhmad Khalifa 	rtwn_write_4(sc, R92C_FAST_EDCA_CTRL, 0x03086666);
358*551b7c5eSAhmad Khalifa 
359*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_USTIME_TSF, 0x50);
360*551b7c5eSAhmad Khalifa 	rtwn_write_1(sc, R92C_USTIME_EDCA, 0x50);
361*551b7c5eSAhmad Khalifa 
362*551b7c5eSAhmad Khalifa 	/* Do not reset MAC. */
363*551b7c5eSAhmad Khalifa 	rtwn_setbits_1(sc, R92C_RSV_CTRL, 0, 0x60);
364*551b7c5eSAhmad Khalifa }
365