1 /*
2 * Copyright (c) 2026 Ahmad Khalifa <vexeduxr@FreeBSD.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7 #include <sys/param.h>
8 #include <sys/lock.h>
9 #include <sys/mutex.h>
10 #include <sys/mbuf.h>
11 #include <sys/kernel.h>
12 #include <sys/socket.h>
13 #include <sys/systm.h>
14 #include <sys/malloc.h>
15 #include <sys/queue.h>
16 #include <sys/taskqueue.h>
17 #include <sys/bus.h>
18 #include <sys/endian.h>
19 #include <sys/linker.h>
20
21 #include <net/if.h>
22 #include <net/ethernet.h>
23 #include <net/if_media.h>
24
25 #include <net80211/ieee80211_var.h>
26 #include <net80211/ieee80211_radiotap.h>
27
28 #include <dev/rtwn/if_rtwnreg.h>
29 #include <dev/rtwn/if_rtwnvar.h>
30
31 #include <dev/rtwn/rtl8192c/r92c_reg.h>
32 #include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
33
34 #include <dev/rtwn/rtl8192e/r92e_var.h>
35
36 #include <dev/rtwn/rtl8723b/r23b.h>
37 #include <dev/rtwn/rtl8723b/r23b_reg.h>
38 #include <dev/rtwn/rtl8723b/r23b_var.h>
39 #include <dev/rtwn/rtl8723b/r23b_rom_image.h>
40
41 #include <dev/rtwn/rtl8812a/r12a_rom_image.h>
42
43 int
r23b_efuse_preread(struct rtwn_softc * sc)44 r23b_efuse_preread(struct rtwn_softc *sc)
45 {
46 int error;
47
48 /* Switch to the WIFI bank. */
49 error = rtwn_setbits_4(sc, R92C_EFUSE_TEST, R23B_EFUSE_TEST_SEL_M,
50 SM(R23B_EFUSE_TEST_SEL, R23B_EFUSE_TEST_SEL_WIFI));
51 if (error != 0)
52 return (error);
53
54 /* NB: Vendor driver does this on every read. */
55 error = rtwn_setbits_2(sc, R92C_EFUSE_TEST, R23B_EFUSE_TEST_PGMEN, 0);
56 return (error);
57 }
58
59 void
r23b_parse_rom(struct rtwn_softc * sc,uint8_t * buf)60 r23b_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
61 {
62 struct r23b_rom *rom = (struct r23b_rom *)buf;
63 struct r23b_softc *rs = sc->sc_priv;
64
65 for (int i = 0; i < sc->ntxchains; i++) {
66 struct r23b_tx_pwr_2g *pwr_2g = &rom->tx_pwr[i].pwr_2g;
67 struct r23b_tx_pwr_diff_2g *pwr_diff_2g =
68 &rom->tx_pwr[i].pwr_diff_2g;
69 int j;
70
71 for (j = 0; j < R23B_GROUP_2G - 1; j++) {
72 rs->super.cck_tx_pwr[i][j] = RTWN_GET_ROM_VAR(
73 pwr_2g->cck[j], R23B_DEF_TX_PWR_2G);
74 rs->super.ht40_tx_pwr_2g[i][j] =
75 RTWN_GET_ROM_VAR(pwr_2g->ht40[j],
76 R23B_DEF_TX_PWR_2G);
77 }
78 rs->super.cck_tx_pwr[i][j] = RTWN_GET_ROM_VAR(pwr_2g->cck[j],
79 R23B_DEF_TX_PWR_2G);
80
81 rs->super.cck_tx_pwr_diff_2g[i][0] = 0;
82 rs->super.bw40_tx_pwr_diff_2g[i][0] = 0;
83 if (pwr_diff_2g->ht20_ofdm == 0xff) {
84 rs->super.ofdm_tx_pwr_diff_2g[i][0] =
85 R23B_DEF_TX_OFDM_DIFF;
86 rs->super.bw20_tx_pwr_diff_2g[i][0] =
87 R23B_DEF_TX_HT20_DIFF;
88 } else {
89 rs->super.ofdm_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
90 MS(pwr_diff_2g->ht20_ofdm, LOW_PART));
91 rs->super.bw20_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
92 MS(pwr_diff_2g->ht20_ofdm, HIGH_PART));
93 }
94
95 for (j = 1; j < R23B_MAX_TX_COUNT; j++) {
96 struct r23b_tx_pwr_diff123_2g *diff =
97 &pwr_diff_2g->diff123[j - 1];
98
99 if (diff->ofdm_cck == 0xff) {
100 rs->super.ofdm_tx_pwr_diff_2g[i][j] =
101 rs->super.cck_tx_pwr_diff_2g[i][j] =
102 R23B_DEF_TX_DIFF;
103 } else {
104 rs->super.cck_tx_pwr_diff_2g[i][j] =
105 RTWN_SIGN4TO8(MS(diff->ofdm_cck, LOW_PART));
106 rs->super.ofdm_tx_pwr_diff_2g[i][j] =
107 RTWN_SIGN4TO8(
108 MS(diff->ofdm_cck, HIGH_PART));
109 }
110
111 if (diff->ht40_ht20 == 0xff) {
112 rs->super.bw40_tx_pwr_diff_2g[i][j] =
113 rs->super.bw20_tx_pwr_diff_2g[i][j] =
114 R23B_DEF_TX_DIFF;
115 } else {
116 rs->super.bw40_tx_pwr_diff_2g[i][j] =
117 RTWN_SIGN4TO8(
118 MS(diff->ht40_ht20, HIGH_PART));
119 rs->super.bw20_tx_pwr_diff_2g[i][j] =
120 RTWN_SIGN4TO8(
121 MS(diff->ht40_ht20, LOW_PART));
122 }
123 }
124
125 rs->bt_antnum = rom->rf_bt_opt & R12A_RF_BT_OPT_ANT_NUM;
126 }
127
128 rs->super.crystalcap = RTWN_GET_ROM_VAR(rom->crystal_cap,
129 R23B_ROM_CRYSTALCAP_DEF);
130
131 sc->thermal_meter = RTWN_GET_ROM_VAR(rom->thermal_meter,
132 R23B_ROM_THERMALMETER_DEF);
133 }
134