xref: /freebsd/sys/dev/rtwn/rtl8723b/r23b_rf.c (revision 9aff62dee28239f84b4aa4a3429cf26dbbf770cc)
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/rtl8188e/r88e_reg.h>
32 
33 #include <dev/rtwn/rtl8192c/r92c_reg.h>
34 
35 #include <dev/rtwn/rtl8723b/r23b.h>
36 
37 void
38 r23b_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
39 {
40 	uint32_t reg;
41 
42 	rtwn_write_4(sc, R92C_LSSI_PARAM(chain),
43 	    SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val));
44 
45 	/*
46 	 * The vendor driver claims that writing to 0xb6 may fail under high
47 	 * temperature conditions, but only attempts to retry during RF init.
48 	 *
49 	 * It is not mentioned why 0xb2 is also special.
50 	 */
51 	switch (addr) {
52 	case 0xb6:
53 		rtwn_delay(sc, 1);
54 
55 		reg = rtwn_rf_read(sc, chain, addr);
56 		rtwn_delay(sc, 1);
57 
58 		for (int retry = 0; (reg & ~0xff) != (val & ~0xff) &&
59 		    retry < 6; retry++) {
60 			rtwn_write_4(sc, R92C_LSSI_PARAM(chain),
61 			    SM(R88E_LSSI_PARAM_ADDR, addr) |
62 			    SM(R92C_LSSI_PARAM_DATA, val));
63 			rtwn_delay(sc, 1);
64 
65 			reg = rtwn_rf_read(sc, chain, addr);
66 		}
67 		break;
68 	case 0xb2:
69 		rtwn_delay(sc, 1);
70 
71 		reg = rtwn_rf_read(sc, chain, addr);
72 		rtwn_delay(sc, 1);
73 
74 		for (int retry = 0; reg != val && retry < 6; retry++) {
75 			rtwn_write_4(sc, R92C_LSSI_PARAM(chain),
76 			    SM(R88E_LSSI_PARAM_ADDR, addr) |
77 			    SM(R92C_LSSI_PARAM_DATA, val));
78 			rtwn_delay(sc, 1);
79 
80 			rtwn_rf_write(sc, chain, R92C_RF_CHNLBW, 0x0fc07);
81 			rtwn_delay(sc, 1);
82 
83 			reg = rtwn_rf_read(sc, chain, addr);
84 		}
85 		break;
86 	}
87 }
88