git: b811e5a5effe - main - rtwn: program the 1 and 2 stream VHT transmit power rates

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Sat, 07 Dec 2024 07:14:57 UTC
The branch main has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=b811e5a5effed0a3f8fa017606e2f37649047537

commit b811e5a5effed0a3f8fa017606e2f37649047537
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-12-04 05:31:35 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2024-12-07 07:14:14 +0000

    rtwn: program the 1 and 2 stream VHT transmit power rates
    
    This is needed to be able to successfully transmit VHT frames.
    
    Locally tested:
    
    * RTL8821AU, STA mode (with the rest of VHT work to actually test VHT)
    
    Differential Revision:  https://reviews.freebsd.org/D47899
---
 sys/dev/rtwn/rtl8812a/r12a_chan.c | 58 ++++++++++++++++++++++++++++++++++++++-
 sys/dev/rtwn/rtl8812a/r12a_reg.h  | 50 +++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c b/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 518b02d765cf..789a14b0e1d6 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -91,6 +91,62 @@ r12a_write_txpower_ht(struct rtwn_softc *sc, int chain,
 	/* TODO: HT MCS 16 -> 31 */
 }
 
+static void
+r12a_write_txpower_vht(struct rtwn_softc *sc, int chain,
+    struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
+{
+
+	/* 1SS, MCS 0..3 */
+	rtwn_bb_write(sc, R12A_TXAGC_NSS1IX3_1IX0(chain),
+	    SM(R12A_TXAGC_NSS1_MCS0, power[RTWN_RIDX_VHT_MCS(0, 0)]) |
+	    SM(R12A_TXAGC_NSS1_MCS1, power[RTWN_RIDX_VHT_MCS(0, 1)]) |
+	    SM(R12A_TXAGC_NSS1_MCS2, power[RTWN_RIDX_VHT_MCS(0, 2)]) |
+	    SM(R12A_TXAGC_NSS1_MCS3, power[RTWN_RIDX_VHT_MCS(0, 3)]));
+
+	/* 1SS, MCS 4..7 */
+	rtwn_bb_write(sc, R12A_TXAGC_NSS1IX7_1IX4(chain),
+	    SM(R12A_TXAGC_NSS1_MCS4, power[RTWN_RIDX_VHT_MCS(0, 4)]) |
+	    SM(R12A_TXAGC_NSS1_MCS5, power[RTWN_RIDX_VHT_MCS(0, 5)]) |
+	    SM(R12A_TXAGC_NSS1_MCS6, power[RTWN_RIDX_VHT_MCS(0, 6)]) |
+	    SM(R12A_TXAGC_NSS1_MCS7, power[RTWN_RIDX_VHT_MCS(0, 7)]));
+
+	/* 1SS, MCS 8,9 ; 2SS MCS0, 1 */
+	if (sc->ntxchains == 1) {
+		rtwn_bb_write(sc, R12A_TXAGC_NSS2IX1_1IX8(chain),
+		    SM(R12A_TXAGC_NSS1_MCS8, power[RTWN_RIDX_VHT_MCS(0, 8)]) |
+		    SM(R12A_TXAGC_NSS1_MCS9, power[RTWN_RIDX_VHT_MCS(0, 9)]) |
+		    SM(R12A_TXAGC_NSS2_MCS0, 0) |
+		    SM(R12A_TXAGC_NSS2_MCS1, 0));
+	} else {
+		rtwn_bb_write(sc, R12A_TXAGC_NSS2IX1_1IX8(chain),
+		    SM(R12A_TXAGC_NSS1_MCS8, power[RTWN_RIDX_VHT_MCS(0, 8)]) |
+		    SM(R12A_TXAGC_NSS1_MCS9, power[RTWN_RIDX_VHT_MCS(0, 9)]) |
+		    SM(R12A_TXAGC_NSS2_MCS0, power[RTWN_RIDX_VHT_MCS(1, 0)]) |
+		    SM(R12A_TXAGC_NSS2_MCS1, power[RTWN_RIDX_VHT_MCS(1, 1)]));
+	}
+
+	/* 2SS MCS 2..5 */
+	if (sc->ntxchains > 1) {
+		rtwn_bb_write(sc, R12A_TXAGC_NSS2IX5_2IX2(chain),
+		    SM(R12A_TXAGC_NSS2_MCS2, power[RTWN_RIDX_VHT_MCS(1, 2)]) |
+		    SM(R12A_TXAGC_NSS2_MCS3, power[RTWN_RIDX_VHT_MCS(1, 3)]) |
+		    SM(R12A_TXAGC_NSS2_MCS4, power[RTWN_RIDX_VHT_MCS(1, 4)]) |
+		    SM(R12A_TXAGC_NSS2_MCS5, power[RTWN_RIDX_VHT_MCS(1, 5)]));
+	}
+
+	/* 2SS MCS 6..9 */
+	if (sc->ntxchains > 1) {
+		rtwn_bb_write(sc, R12A_TXAGC_NSS2IX9_2IX6(chain),
+		    SM(R12A_TXAGC_NSS2_MCS2, power[RTWN_RIDX_VHT_MCS(1, 6)]) |
+		    SM(R12A_TXAGC_NSS2_MCS3, power[RTWN_RIDX_VHT_MCS(1, 7)]) |
+		    SM(R12A_TXAGC_NSS2_MCS4, power[RTWN_RIDX_VHT_MCS(1, 8)]) |
+		    SM(R12A_TXAGC_NSS2_MCS5, power[RTWN_RIDX_VHT_MCS(1, 9)]));
+	}
+
+	/* TODO: 3SS, 4SS VHT rates */
+}
+
+
 static void
 r12a_write_txpower_cck(struct rtwn_softc *sc, int chain,
     struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
@@ -132,7 +188,7 @@ r12a_write_txpower(struct rtwn_softc *sc, int chain,
 	r12a_write_txpower_cck(sc, chain, c, power);
 	r12a_write_txpower_ofdm(sc, chain, c, power);
 	r12a_write_txpower_ht(sc, chain, c, power);
-	/* TODO: VHT rates */
+	r12a_write_txpower_vht(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 4e9892ce2592..4f5f6f28c11a 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_reg.h
+++ b/sys/dev/rtwn/rtl8812a/r12a_reg.h
@@ -230,6 +230,56 @@
 #define R12A_TXAGC_MCS15_M		0xff000000
 #define R12A_TXAGC_MCS15_S		24
 
+/* Bits for R12A_TXAGC_NSS1IX3_1IX0(i) */
+#define R12A_TXAGC_NSS1_MCS0_M		0x000000ff
+#define R12A_TXAGC_NSS1_MCS0_S		0
+#define R12A_TXAGC_NSS1_MCS1_M		0x0000ff00
+#define R12A_TXAGC_NSS1_MCS1_S		8
+#define R12A_TXAGC_NSS1_MCS2_M		0x00ff0000
+#define R12A_TXAGC_NSS1_MCS2_S		16
+#define R12A_TXAGC_NSS1_MCS3_M		0xff000000
+#define R12A_TXAGC_NSS1_MCS3_S		24
+
+/* Bits for R12A_TXAGC_NSS1IX7_1IX4(i) */
+#define R12A_TXAGC_NSS1_MCS4_M		0x000000ff
+#define R12A_TXAGC_NSS1_MCS4_S		0
+#define R12A_TXAGC_NSS1_MCS5_M		0x0000ff00
+#define R12A_TXAGC_NSS1_MCS5_S		8
+#define R12A_TXAGC_NSS1_MCS6_M		0x00ff0000
+#define R12A_TXAGC_NSS1_MCS6_S		16
+#define R12A_TXAGC_NSS1_MCS7_M		0xff000000
+#define R12A_TXAGC_NSS1_MCS7_S		24
+
+/* Bits for R12A_TXAGC_NSS2IX1_1IX8(i) */
+#define R12A_TXAGC_NSS1_MCS8_M		0x000000ff
+#define R12A_TXAGC_NSS1_MCS8_S		0
+#define R12A_TXAGC_NSS1_MCS9_M		0x0000ff00
+#define R12A_TXAGC_NSS1_MCS9_S		8
+#define R12A_TXAGC_NSS2_MCS0_M		0x00ff0000
+#define R12A_TXAGC_NSS2_MCS0_S		16
+#define R12A_TXAGC_NSS2_MCS1_M		0xff000000
+#define R12A_TXAGC_NSS2_MCS1_S		24
+
+/* Bits for R12A_TXAGC_NSS2IX5_2IX2(i) */
+#define R12A_TXAGC_NSS2_MCS2_M		0x000000ff
+#define R12A_TXAGC_NSS2_MCS2_S		0
+#define R12A_TXAGC_NSS2_MCS3_M		0x0000ff00
+#define R12A_TXAGC_NSS2_MCS3_S		8
+#define R12A_TXAGC_NSS2_MCS4_M		0x00ff0000
+#define R12A_TXAGC_NSS2_MCS4_S		16
+#define R12A_TXAGC_NSS2_MCS5_M		0xff000000
+#define R12A_TXAGC_NSS2_MCS5_S		24
+
+/* Bits for R12A_TXAGC_NSS2IX9_2IX6(i) */
+#define R12A_TXAGC_NSS2_MCS6_M		0x000000ff
+#define R12A_TXAGC_NSS2_MCS6_S		0
+#define R12A_TXAGC_NSS2_MCS7_M		0x0000ff00
+#define R12A_TXAGC_NSS2_MCS7_S		8
+#define R12A_TXAGC_NSS2_MCS8_M		0x00ff0000
+#define R12A_TXAGC_NSS2_MCS8_S		16
+#define R12A_TXAGC_NSS2_MCS9_M		0xff000000
+#define R12A_TXAGC_NSS2_MCS9_S		24
+
 /*
  * RF (6052) registers.
  */