xref: /freebsd/sys/dev/rtwn/rtl8723b/r23b_rom.c (revision 551b7c5e12bfea623a47edf97ad5689732a1233f)
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