1*551b7c5eSAhmad Khalifa /*
2*551b7c5eSAhmad Khalifa * Copyright (c) 2026 Ahmad Khalifa <vexeduxr@FreeBSD.org>
3*551b7c5eSAhmad Khalifa *
4*551b7c5eSAhmad Khalifa * SPDX-License-Identifier: BSD-2-Clause
5*551b7c5eSAhmad Khalifa */
6*551b7c5eSAhmad Khalifa
7*551b7c5eSAhmad Khalifa #include <sys/param.h>
8*551b7c5eSAhmad Khalifa #include <sys/lock.h>
9*551b7c5eSAhmad Khalifa #include <sys/mutex.h>
10*551b7c5eSAhmad Khalifa #include <sys/mbuf.h>
11*551b7c5eSAhmad Khalifa #include <sys/kernel.h>
12*551b7c5eSAhmad Khalifa #include <sys/socket.h>
13*551b7c5eSAhmad Khalifa #include <sys/systm.h>
14*551b7c5eSAhmad Khalifa #include <sys/malloc.h>
15*551b7c5eSAhmad Khalifa #include <sys/queue.h>
16*551b7c5eSAhmad Khalifa #include <sys/taskqueue.h>
17*551b7c5eSAhmad Khalifa #include <sys/bus.h>
18*551b7c5eSAhmad Khalifa #include <sys/endian.h>
19*551b7c5eSAhmad Khalifa #include <sys/linker.h>
20*551b7c5eSAhmad Khalifa
21*551b7c5eSAhmad Khalifa #include <net/if.h>
22*551b7c5eSAhmad Khalifa #include <net/ethernet.h>
23*551b7c5eSAhmad Khalifa #include <net/if_media.h>
24*551b7c5eSAhmad Khalifa
25*551b7c5eSAhmad Khalifa #include <net80211/ieee80211_var.h>
26*551b7c5eSAhmad Khalifa #include <net80211/ieee80211_radiotap.h>
27*551b7c5eSAhmad Khalifa
28*551b7c5eSAhmad Khalifa #include <dev/rtwn/if_rtwnreg.h>
29*551b7c5eSAhmad Khalifa #include <dev/rtwn/if_rtwnvar.h>
30*551b7c5eSAhmad Khalifa
31*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8188e/r88e.h>
32*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8188e/r88e_reg.h>
33*551b7c5eSAhmad Khalifa
34*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192c/r92c_reg.h>
35*551b7c5eSAhmad Khalifa
36*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192e/r92e.h>
37*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192e/r92e_var.h>
38*551b7c5eSAhmad Khalifa
39*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b.h>
40*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_reg.h>
41*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_var.h>
42*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_fw_cmd.h>
43*551b7c5eSAhmad Khalifa
44*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8821a/r21a_reg.h>
45*551b7c5eSAhmad Khalifa
46*551b7c5eSAhmad Khalifa int
r23b_set_page_size(struct rtwn_softc * sc)47*551b7c5eSAhmad Khalifa r23b_set_page_size(struct rtwn_softc *sc)
48*551b7c5eSAhmad Khalifa {
49*551b7c5eSAhmad Khalifa return (rtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_256) |
50*551b7c5eSAhmad Khalifa SM(R92C_PBP_PSTX, R92C_PBP_256)));
51*551b7c5eSAhmad Khalifa }
52*551b7c5eSAhmad Khalifa
53*551b7c5eSAhmad Khalifa void
r23b_init_antsel(struct rtwn_softc * sc)54*551b7c5eSAhmad Khalifa r23b_init_antsel(struct rtwn_softc *sc)
55*551b7c5eSAhmad Khalifa {
56*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R88E_BB_PAD_CTRL, 0x1100000, 0);
57*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_GPIO_MUXCFG, 0x10, 0x8);
58*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_LEDCFG0, 0x400000, 0x800000);
59*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, 0x944, 0, 0x3);
60*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, 0x930, 0xff, 0x77);
61*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_PWR_DATA, 0, 0x800);
62*551b7c5eSAhmad Khalifa }
63*551b7c5eSAhmad Khalifa
64*551b7c5eSAhmad Khalifa void
r23b_init_bb_common(struct rtwn_softc * sc)65*551b7c5eSAhmad Khalifa r23b_init_bb_common(struct rtwn_softc *sc)
66*551b7c5eSAhmad Khalifa {
67*551b7c5eSAhmad Khalifa struct r23b_softc *rs = sc->sc_priv;
68*551b7c5eSAhmad Khalifa uint8_t val;
69*551b7c5eSAhmad Khalifa
70*551b7c5eSAhmad Khalifa /* PathA RF Power On. */
71*551b7c5eSAhmad Khalifa rtwn_write_1(sc, R92C_RF_CTRL,
72*551b7c5eSAhmad Khalifa R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
73*551b7c5eSAhmad Khalifa
74*551b7c5eSAhmad Khalifa rtwn_delay(sc, 10);
75*551b7c5eSAhmad Khalifa
76*551b7c5eSAhmad Khalifa rtwn_rf_write(sc, 0, R92C_RF_IQADJ_G(0), 0x780);
77*551b7c5eSAhmad Khalifa
78*551b7c5eSAhmad Khalifa rtwn_write_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB |
79*551b7c5eSAhmad Khalifa R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_DIO_PCIE |
80*551b7c5eSAhmad Khalifa R92C_SYS_FUNC_EN_PCIEA | R92C_SYS_FUNC_EN_PPLL);
81*551b7c5eSAhmad Khalifa
82*551b7c5eSAhmad Khalifa rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
83*551b7c5eSAhmad Khalifa
84*551b7c5eSAhmad Khalifa for (int i = 0; i < sc->bb_size; i++) {
85*551b7c5eSAhmad Khalifa const struct rtwn_bb_prog *bb_prog = &sc->bb_prog[i];
86*551b7c5eSAhmad Khalifa
87*551b7c5eSAhmad Khalifa for (int j = 0; j < bb_prog->count; j++) {
88*551b7c5eSAhmad Khalifa rtwn_write_4(sc, bb_prog->reg[j], bb_prog->val[j]);
89*551b7c5eSAhmad Khalifa rtwn_delay(sc, 1);
90*551b7c5eSAhmad Khalifa }
91*551b7c5eSAhmad Khalifa }
92*551b7c5eSAhmad Khalifa
93*551b7c5eSAhmad Khalifa for (int i = 0; i < sc->agc_size; i++) {
94*551b7c5eSAhmad Khalifa const struct rtwn_agc_prog *agc_prog = &sc->agc_prog[i];
95*551b7c5eSAhmad Khalifa
96*551b7c5eSAhmad Khalifa for (int j = 0; j < agc_prog->count; j++) {
97*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R92C_OFDM0_AGCRSSITABLE,
98*551b7c5eSAhmad Khalifa agc_prog->val[j]);
99*551b7c5eSAhmad Khalifa rtwn_delay(sc, 1);
100*551b7c5eSAhmad Khalifa }
101*551b7c5eSAhmad Khalifa }
102*551b7c5eSAhmad Khalifa
103*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
104*551b7c5eSAhmad Khalifa rtwn_delay(sc, 1);
105*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
106*551b7c5eSAhmad Khalifa rtwn_delay(sc, 1);
107*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R92C_HSSI_PARAM2(0), 0x00390204);
108*551b7c5eSAhmad Khalifa rtwn_delay(sc, 1);
109*551b7c5eSAhmad Khalifa
110*551b7c5eSAhmad Khalifa val = rs->super.crystalcap & 0x3f;
111*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_MAC_PHY_CTRL, R21A_MAC_PHY_CRYSTALCAP_M,
112*551b7c5eSAhmad Khalifa SM(R21A_MAC_PHY_CRYSTALCAP, val | (val << 6)));
113*551b7c5eSAhmad Khalifa }
114*551b7c5eSAhmad Khalifa
115*551b7c5eSAhmad Khalifa void
r23b_init_rf(struct rtwn_softc * sc)116*551b7c5eSAhmad Khalifa r23b_init_rf(struct rtwn_softc *sc)
117*551b7c5eSAhmad Khalifa {
118*551b7c5eSAhmad Khalifa r92e_init_rf(sc);
119*551b7c5eSAhmad Khalifa
120*551b7c5eSAhmad Khalifa /* Init LCK. */
121*551b7c5eSAhmad Khalifa rtwn_rf_write(sc, 0, R23B_RF_S0S1, 0xdfbe0);
122*551b7c5eSAhmad Khalifa rtwn_rf_write(sc, 0, R92C_RF_CHNLBW, 0x8c01);
123*551b7c5eSAhmad Khalifa rtwn_delay(sc, 200000);
124*551b7c5eSAhmad Khalifa rtwn_rf_write(sc, 0, R23B_RF_S0S1, 0xdffe0);
125*551b7c5eSAhmad Khalifa }
126*551b7c5eSAhmad Khalifa
127*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
128*551b7c5eSAhmad Khalifa static void
r23b_write_btreg(struct rtwn_softc * sc,uint8_t addr,uint8_t data)129*551b7c5eSAhmad Khalifa r23b_write_btreg(struct rtwn_softc *sc, uint8_t addr, uint8_t data)
130*551b7c5eSAhmad Khalifa {
131*551b7c5eSAhmad Khalifa struct r23b_fw_cmd_btoper cmd;
132*551b7c5eSAhmad Khalifa
133*551b7c5eSAhmad Khalifa cmd.req_num = 0;
134*551b7c5eSAhmad Khalifa cmd.opcode = R23B_BT_MP_OPER_WRITE_VAL;
135*551b7c5eSAhmad Khalifa cmd.value = data;
136*551b7c5eSAhmad Khalifa cmd.addr = 0;
137*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_BT_MP_OPER, &cmd, sizeof(cmd));
138*551b7c5eSAhmad Khalifa
139*551b7c5eSAhmad Khalifa rtwn_delay(sc, 200000); /* 200ms */
140*551b7c5eSAhmad Khalifa
141*551b7c5eSAhmad Khalifa cmd.req_num = 1;
142*551b7c5eSAhmad Khalifa cmd.opcode = R23B_BT_MP_OPER_WRITE_ADDR;
143*551b7c5eSAhmad Khalifa cmd.value = 0;
144*551b7c5eSAhmad Khalifa cmd.addr = addr;
145*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_BT_MP_OPER, &cmd, sizeof(cmd));
146*551b7c5eSAhmad Khalifa }
147*551b7c5eSAhmad Khalifa #endif
148*551b7c5eSAhmad Khalifa
149*551b7c5eSAhmad Khalifa void
r23b_post_init(struct rtwn_softc * sc)150*551b7c5eSAhmad Khalifa r23b_post_init(struct rtwn_softc *sc)
151*551b7c5eSAhmad Khalifa {
152*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
153*551b7c5eSAhmad Khalifa struct r23b_fw_cmd_antinv cmd;
154*551b7c5eSAhmad Khalifa const uint8_t ps_tdma[5] = { 0x8, 0x0, 0x0, 0x0, 0x0 };
155*551b7c5eSAhmad Khalifa #endif
156*551b7c5eSAhmad Khalifa
157*551b7c5eSAhmad Khalifa if (sc->macid_rpt2_max_num > 0) {
158*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT2_ENA);
159*551b7c5eSAhmad Khalifa rtwn_write_1(sc, R88E_TX_RPT_MACID_MAX, sc->macid_rpt2_max_num);
160*551b7c5eSAhmad Khalifa /* Enable periodic TX report; 32uS units */
161*551b7c5eSAhmad Khalifa rtwn_write_2(sc, R88E_TX_RPT_TIME, 0xcdf0);
162*551b7c5eSAhmad Khalifa }
163*551b7c5eSAhmad Khalifa
164*551b7c5eSAhmad Khalifa rtwn_lc_calib(sc);
165*551b7c5eSAhmad Khalifa rtwn_iq_calib(sc);
166*551b7c5eSAhmad Khalifa
167*551b7c5eSAhmad Khalifa /* Enable RF */
168*551b7c5eSAhmad Khalifa
169*551b7c5eSAhmad Khalifa /* XXX lots of magic numbers here. */
170*551b7c5eSAhmad Khalifa
171*551b7c5eSAhmad Khalifa rtwn_write_1(sc, 0x790, 0x5);
172*551b7c5eSAhmad Khalifa rtwn_write_1(sc, 0x778, 0x1);
173*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, R92C_GPIO_MUXCFG, 0, R92C_GPIO_MUXCFG_ENBT);
174*551b7c5eSAhmad Khalifa
175*551b7c5eSAhmad Khalifa /* WiFi TRx Mask on */
176*551b7c5eSAhmad Khalifa rtwn_rf_write(sc, 0, R92C_RF_IQADJ_G(0), 0x780);
177*551b7c5eSAhmad Khalifa
178*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
179*551b7c5eSAhmad Khalifa /* BT TRx Mask on */
180*551b7c5eSAhmad Khalifa r23b_write_btreg(sc, 0x3c, 0x15);
181*551b7c5eSAhmad Khalifa
182*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_BT_GRANT, R23B_CMD_BT_GRANT_LOW,
183*551b7c5eSAhmad Khalifa sizeof(R23B_CMD_BT_GRANT_LOW));
184*551b7c5eSAhmad Khalifa #endif
185*551b7c5eSAhmad Khalifa
186*551b7c5eSAhmad Khalifa rtwn_write_1(sc, 0x76e, 0x4);
187*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, R88E_BB_PAD_CTRL + 3, 0, 0x20);
188*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, R92C_PWR_DATA + 1, 0, 0x8);
189*551b7c5eSAhmad Khalifa rtwn_write_1(sc, 0x974, 0xff);
190*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, 0x944, 0, 0x3);
191*551b7c5eSAhmad Khalifa rtwn_write_1(sc, 0x930, 0x77);
192*551b7c5eSAhmad Khalifa
193*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_LEDCFG0, 0x1000000, 0x800000);
194*551b7c5eSAhmad Khalifa rtwn_setbits_1(sc, R88E_BB_PAD_CTRL, 0x1, 0);
195*551b7c5eSAhmad Khalifa
196*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
197*551b7c5eSAhmad Khalifa /* Inform firmware of the antenna inversion. */
198*551b7c5eSAhmad Khalifa cmd.internal_switch = 0;
199*551b7c5eSAhmad Khalifa cmd.invert = 1;
200*551b7c5eSAhmad Khalifa
201*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_ANT_INV, &cmd, sizeof(cmd));
202*551b7c5eSAhmad Khalifa #endif
203*551b7c5eSAhmad Khalifa
204*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R23B_ANT_SEL, 0x80);
205*551b7c5eSAhmad Khalifa
206*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
207*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_PS_TDMA, ps_tdma, sizeof(ps_tdma));
208*551b7c5eSAhmad Khalifa #endif
209*551b7c5eSAhmad Khalifa
210*551b7c5eSAhmad Khalifa /* btcoex table */
211*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R23B_BTCOEX_TABLE(0), 0x55555555);
212*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R23B_BTCOEX_TABLE(1), 0x55555555);
213*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R23B_BTCOEX_TABLE(2), 0x00ffffff);
214*551b7c5eSAhmad Khalifa rtwn_write_4(sc, R23B_BTCOEX_TABLE(3), 0x00000003);
215*551b7c5eSAhmad Khalifa
216*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
217*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_BT_INFO, &(uint8_t){ 1 }, sizeof(uint8_t));
218*551b7c5eSAhmad Khalifa r88e_fw_cmd(sc, R23B_CMD_BT_WLANACT, R23B_CMD_BT_WLANACT_IGNORE,
219*551b7c5eSAhmad Khalifa sizeof(R23B_CMD_BT_WLANACT_IGNORE));
220*551b7c5eSAhmad Khalifa #endif
221*551b7c5eSAhmad Khalifa
222*551b7c5eSAhmad Khalifa /* ACK for xmit mgmt frames. */
223*551b7c5eSAhmad Khalifa rtwn_setbits_4(sc, R92C_FWHW_TXQ_CTRL, 0, R23B_FWHW_TXQ_CTRL_ACK_MGNT);
224*551b7c5eSAhmad Khalifa
225*551b7c5eSAhmad Khalifa #ifndef RTWN_WITHOUT_UCODE
226*551b7c5eSAhmad Khalifa if (sc->sc_flags & RTWN_FW_LOADED) {
227*551b7c5eSAhmad Khalifa if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
228*551b7c5eSAhmad Khalifa /* TODO: implement */
229*551b7c5eSAhmad Khalifa sc->sc_ratectl = RTWN_RATECTL_NET80211;
230*551b7c5eSAhmad Khalifa } else
231*551b7c5eSAhmad Khalifa sc->sc_ratectl = sc->sc_ratectl_sysctl;
232*551b7c5eSAhmad Khalifa } else
233*551b7c5eSAhmad Khalifa #endif
234*551b7c5eSAhmad Khalifa sc->sc_ratectl = RTWN_RATECTL_NONE;
235*551b7c5eSAhmad Khalifa }
236