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/rtl8192c/r92c_reg.h>
32*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
33*551b7c5eSAhmad Khalifa
34*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8192e/r92e_var.h>
35*551b7c5eSAhmad Khalifa
36*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b.h>
37*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_reg.h>
38*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_var.h>
39*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8723b/r23b_rom_image.h>
40*551b7c5eSAhmad Khalifa
41*551b7c5eSAhmad Khalifa #include <dev/rtwn/rtl8812a/r12a_rom_image.h>
42*551b7c5eSAhmad Khalifa
43*551b7c5eSAhmad Khalifa int
r23b_efuse_preread(struct rtwn_softc * sc)44*551b7c5eSAhmad Khalifa r23b_efuse_preread(struct rtwn_softc *sc)
45*551b7c5eSAhmad Khalifa {
46*551b7c5eSAhmad Khalifa int error;
47*551b7c5eSAhmad Khalifa
48*551b7c5eSAhmad Khalifa /* Switch to the WIFI bank. */
49*551b7c5eSAhmad Khalifa error = rtwn_setbits_4(sc, R92C_EFUSE_TEST, R23B_EFUSE_TEST_SEL_M,
50*551b7c5eSAhmad Khalifa SM(R23B_EFUSE_TEST_SEL, R23B_EFUSE_TEST_SEL_WIFI));
51*551b7c5eSAhmad Khalifa if (error != 0)
52*551b7c5eSAhmad Khalifa return (error);
53*551b7c5eSAhmad Khalifa
54*551b7c5eSAhmad Khalifa /* NB: Vendor driver does this on every read. */
55*551b7c5eSAhmad Khalifa error = rtwn_setbits_2(sc, R92C_EFUSE_TEST, R23B_EFUSE_TEST_PGMEN, 0);
56*551b7c5eSAhmad Khalifa return (error);
57*551b7c5eSAhmad Khalifa }
58*551b7c5eSAhmad Khalifa
59*551b7c5eSAhmad Khalifa void
r23b_parse_rom(struct rtwn_softc * sc,uint8_t * buf)60*551b7c5eSAhmad Khalifa r23b_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
61*551b7c5eSAhmad Khalifa {
62*551b7c5eSAhmad Khalifa struct r23b_rom *rom = (struct r23b_rom *)buf;
63*551b7c5eSAhmad Khalifa struct r23b_softc *rs = sc->sc_priv;
64*551b7c5eSAhmad Khalifa
65*551b7c5eSAhmad Khalifa for (int i = 0; i < sc->ntxchains; i++) {
66*551b7c5eSAhmad Khalifa struct r23b_tx_pwr_2g *pwr_2g = &rom->tx_pwr[i].pwr_2g;
67*551b7c5eSAhmad Khalifa struct r23b_tx_pwr_diff_2g *pwr_diff_2g =
68*551b7c5eSAhmad Khalifa &rom->tx_pwr[i].pwr_diff_2g;
69*551b7c5eSAhmad Khalifa int j;
70*551b7c5eSAhmad Khalifa
71*551b7c5eSAhmad Khalifa for (j = 0; j < R23B_GROUP_2G - 1; j++) {
72*551b7c5eSAhmad Khalifa rs->super.cck_tx_pwr[i][j] = RTWN_GET_ROM_VAR(
73*551b7c5eSAhmad Khalifa pwr_2g->cck[j], R23B_DEF_TX_PWR_2G);
74*551b7c5eSAhmad Khalifa rs->super.ht40_tx_pwr_2g[i][j] =
75*551b7c5eSAhmad Khalifa RTWN_GET_ROM_VAR(pwr_2g->ht40[j],
76*551b7c5eSAhmad Khalifa R23B_DEF_TX_PWR_2G);
77*551b7c5eSAhmad Khalifa }
78*551b7c5eSAhmad Khalifa rs->super.cck_tx_pwr[i][j] = RTWN_GET_ROM_VAR(pwr_2g->cck[j],
79*551b7c5eSAhmad Khalifa R23B_DEF_TX_PWR_2G);
80*551b7c5eSAhmad Khalifa
81*551b7c5eSAhmad Khalifa rs->super.cck_tx_pwr_diff_2g[i][0] = 0;
82*551b7c5eSAhmad Khalifa rs->super.bw40_tx_pwr_diff_2g[i][0] = 0;
83*551b7c5eSAhmad Khalifa if (pwr_diff_2g->ht20_ofdm == 0xff) {
84*551b7c5eSAhmad Khalifa rs->super.ofdm_tx_pwr_diff_2g[i][0] =
85*551b7c5eSAhmad Khalifa R23B_DEF_TX_OFDM_DIFF;
86*551b7c5eSAhmad Khalifa rs->super.bw20_tx_pwr_diff_2g[i][0] =
87*551b7c5eSAhmad Khalifa R23B_DEF_TX_HT20_DIFF;
88*551b7c5eSAhmad Khalifa } else {
89*551b7c5eSAhmad Khalifa rs->super.ofdm_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
90*551b7c5eSAhmad Khalifa MS(pwr_diff_2g->ht20_ofdm, LOW_PART));
91*551b7c5eSAhmad Khalifa rs->super.bw20_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
92*551b7c5eSAhmad Khalifa MS(pwr_diff_2g->ht20_ofdm, HIGH_PART));
93*551b7c5eSAhmad Khalifa }
94*551b7c5eSAhmad Khalifa
95*551b7c5eSAhmad Khalifa for (j = 1; j < R23B_MAX_TX_COUNT; j++) {
96*551b7c5eSAhmad Khalifa struct r23b_tx_pwr_diff123_2g *diff =
97*551b7c5eSAhmad Khalifa &pwr_diff_2g->diff123[j - 1];
98*551b7c5eSAhmad Khalifa
99*551b7c5eSAhmad Khalifa if (diff->ofdm_cck == 0xff) {
100*551b7c5eSAhmad Khalifa rs->super.ofdm_tx_pwr_diff_2g[i][j] =
101*551b7c5eSAhmad Khalifa rs->super.cck_tx_pwr_diff_2g[i][j] =
102*551b7c5eSAhmad Khalifa R23B_DEF_TX_DIFF;
103*551b7c5eSAhmad Khalifa } else {
104*551b7c5eSAhmad Khalifa rs->super.cck_tx_pwr_diff_2g[i][j] =
105*551b7c5eSAhmad Khalifa RTWN_SIGN4TO8(MS(diff->ofdm_cck, LOW_PART));
106*551b7c5eSAhmad Khalifa rs->super.ofdm_tx_pwr_diff_2g[i][j] =
107*551b7c5eSAhmad Khalifa RTWN_SIGN4TO8(
108*551b7c5eSAhmad Khalifa MS(diff->ofdm_cck, HIGH_PART));
109*551b7c5eSAhmad Khalifa }
110*551b7c5eSAhmad Khalifa
111*551b7c5eSAhmad Khalifa if (diff->ht40_ht20 == 0xff) {
112*551b7c5eSAhmad Khalifa rs->super.bw40_tx_pwr_diff_2g[i][j] =
113*551b7c5eSAhmad Khalifa rs->super.bw20_tx_pwr_diff_2g[i][j] =
114*551b7c5eSAhmad Khalifa R23B_DEF_TX_DIFF;
115*551b7c5eSAhmad Khalifa } else {
116*551b7c5eSAhmad Khalifa rs->super.bw40_tx_pwr_diff_2g[i][j] =
117*551b7c5eSAhmad Khalifa RTWN_SIGN4TO8(
118*551b7c5eSAhmad Khalifa MS(diff->ht40_ht20, HIGH_PART));
119*551b7c5eSAhmad Khalifa rs->super.bw20_tx_pwr_diff_2g[i][j] =
120*551b7c5eSAhmad Khalifa RTWN_SIGN4TO8(
121*551b7c5eSAhmad Khalifa MS(diff->ht40_ht20, LOW_PART));
122*551b7c5eSAhmad Khalifa }
123*551b7c5eSAhmad Khalifa }
124*551b7c5eSAhmad Khalifa
125*551b7c5eSAhmad Khalifa rs->bt_antnum = rom->rf_bt_opt & R12A_RF_BT_OPT_ANT_NUM;
126*551b7c5eSAhmad Khalifa }
127*551b7c5eSAhmad Khalifa
128*551b7c5eSAhmad Khalifa rs->super.crystalcap = RTWN_GET_ROM_VAR(rom->crystal_cap,
129*551b7c5eSAhmad Khalifa R23B_ROM_CRYSTALCAP_DEF);
130*551b7c5eSAhmad Khalifa
131*551b7c5eSAhmad Khalifa sc->thermal_meter = RTWN_GET_ROM_VAR(rom->thermal_meter,
132*551b7c5eSAhmad Khalifa R23B_ROM_THERMALMETER_DEF);
133*551b7c5eSAhmad Khalifa }
134