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