aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2024-12-07 15:47:45 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2024-12-18 19:31:18 +0000
commitcf6b389f7c485f735c3d84a7e3fe6833e91321e4 (patch)
tree14f8bdfca6b313cb425c1a6a891454fc26b02592
parentff7e00eb4dd6bbe5f7621e77f887766b162929fc (diff)
rtwn: add tx power training for RTL8812/RTL8821
This apparently kicks off TX power level self-calibration, which can't hurt. Locally tested: * RTL8812AU, STA * RTL8821AU, STA Obtained from: Linux rtw88 Differential Revision: https://reviews.freebsd.org/D47978 Reviewed by: bz, imp
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_chan.c32
-rw-r--r--sys/dev/rtwn/rtl8812a/r12a_reg.h1
2 files changed, 33 insertions, 0 deletions
diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c b/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 749f0e09e831..d71e0a8177fd 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -181,6 +181,36 @@ r12a_write_txpower_ofdm(struct rtwn_softc *sc, int chain,
}
static void
+r12a_tx_power_training(struct rtwn_softc *sc, int chain,
+ const struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
+{
+ uint32_t write_data;
+ int32_t power_level;
+ int i;
+
+ write_data = 0;
+
+ power_level = (int32_t) power[RTWN_RIDX_HT_MCS(7)];
+ for (i = 0; i < 3; i++) {
+ if (i == 0)
+ power_level -= 10;
+ else if (i == 1)
+ power_level -= 8;
+ else
+ power_level -= 6;
+
+ /* Handle underflow and the minimum value (2) */
+ if (power_level < 2)
+ power_level = 2;
+
+ write_data |= ((power_level & 0xff) << (i * 8));
+ }
+
+ rtwn_bb_setbits(sc, R12A_TX_PWR_TRAINING(chain),
+ 0x00ffffff, write_data);
+}
+
+static void
r12a_write_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
{
@@ -189,6 +219,8 @@ r12a_write_txpower(struct rtwn_softc *sc, int chain,
r12a_write_txpower_ofdm(sc, chain, c, power);
r12a_write_txpower_ht(sc, chain, c, power);
r12a_write_txpower_vht(sc, chain, c, power);
+
+ r12a_tx_power_training(sc, chain, c, power);
}
static int
diff --git a/sys/dev/rtwn/rtl8812a/r12a_reg.h b/sys/dev/rtwn/rtl8812a/r12a_reg.h
index 13867fb76973..f1fc4ee2f302 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_reg.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_reg.h
@@ -124,6 +124,7 @@
#define R12A_TXAGC_NSS2IX5_2IX2(chain) (0xc48 + (chain) * 0x200)
#define R12A_TXAGC_NSS2IX9_2IX6(chain) (0xc4c + (chain) * 0x200)
#define R12A_INITIAL_GAIN(chain) (0xc50 + (chain) * 0x200)
+#define R12A_TX_PWR_TRAINING(chain) (0xc54 + (chain) * 0x200)
#define R12A_AFE_POWER_1(chain) (0xc60 + (chain) * 0x200)
#define R12A_AFE_POWER_2(chain) (0xc64 + (chain) * 0x200)
#define R12A_SLEEP_NAV(chain) (0xc80 + (chain) * 0x200)