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