git: b4980d8a48e5 - main - rtwn: calculate the transmit power for VHT rates

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

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

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

    rtwn: calculate the transmit power for VHT rates
    
    The VHT rate power array wasn't populated, and it needs to be in order
    to use VHT rates.
    
    The vendor driver reuses the HT40 values for VHT rates.
    
    Differential Revision:  https://reviews.freebsd.org/D47898
---
 sys/dev/rtwn/rtl8812a/r12a_chan.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/sys/dev/rtwn/rtl8812a/r12a_chan.c b/sys/dev/rtwn/rtl8812a/r12a_chan.c
index 517d96bb06cf..518b02d765cf 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_chan.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_chan.c
@@ -187,7 +187,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
     struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
 {
 	struct r12a_softc *rs = sc->sc_priv;
-	int i, ridx, group, max_mcs;
+	int i, ridx, group, max_mcs, max_vht_mcs;
 
 	/* Determine channel group. */
 	group = r12a_get_power_group(sc, c);
@@ -196,8 +196,8 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 		return;
 	}
 
-	/* TODO: VHT rates. */
 	max_mcs = RTWN_RIDX_HT_MCS(sc->ntxchains * 8 - 1);
+	max_vht_mcs = RTWN_RIDX_VHT_MCS(sc->ntxchains, 9) - 1;
 
 	/* XXX regulatory */
 	/* XXX net80211 regulatory */
@@ -215,13 +215,11 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 			uint8_t min_mcs;
 			uint8_t pwr_diff;
 
-#ifdef notyet
-			if (IEEE80211_IS_CHAN_HT80(c)) {
+			if (IEEE80211_IS_CHAN_VHT80(c)) {
 				/* Vendor driver uses HT40 values here. */
 				pwr_diff = rs->bw40_tx_pwr_diff_2g[chain][i];
 			} else
-#endif
-			if (IEEE80211_IS_CHAN_HT40(c))
+			if (IEEE80211_IS_CHAN_HT40(c) || IEEE80211_IS_CHAN_VHT40(c))
 				pwr_diff = rs->bw40_tx_pwr_diff_2g[chain][i];
 			else
 				pwr_diff = rs->bw20_tx_pwr_diff_2g[chain][i];
@@ -231,9 +229,14 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 				power[ridx] += pwr_diff;
 		}
 	} else {	/* 5GHz */
+		/* OFDM + HT */
 		for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++)
 			power[ridx] = rs->ht40_tx_pwr_5g[chain][group];
+		/* VHT */
+		for (ridx = RTWN_RIDX_VHT_MCS_SHIFT; ridx <= max_vht_mcs; ridx++)
+			power[ridx] = rs->ht40_tx_pwr_5g[chain][group];
 
+		/* Add power for OFDM rates */
 		for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
 			power[ridx] += rs->ofdm_tx_pwr_diff_5g[chain][0];
 
@@ -241,20 +244,26 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 			uint8_t min_mcs;
 			uint8_t pwr_diff;
 
-#ifdef notyet
-			if (IEEE80211_IS_CHAN_HT80(c)) {
+			if (IEEE80211_IS_CHAN_VHT80(c)) {
 				/* TODO: calculate base value. */
 				pwr_diff = rs->bw80_tx_pwr_diff_5g[chain][i];
 			} else
-#endif
-			if (IEEE80211_IS_CHAN_HT40(c))
+			if (IEEE80211_IS_CHAN_HT40(c) || IEEE80211_IS_CHAN_VHT40(c))
 				pwr_diff = rs->bw40_tx_pwr_diff_5g[chain][i];
 			else
 				pwr_diff = rs->bw20_tx_pwr_diff_5g[chain][i];
 
+			/* Adjust HT rates */
 			min_mcs = RTWN_RIDX_HT_MCS(i * 8);
 			for (ridx = min_mcs; ridx <= max_mcs; ridx++)
 				power[ridx] += pwr_diff;
+
+			/* Adjust VHT rates */
+			for (ridx = RTWN_RIDX_VHT_MCS(i, 0);
+			    ridx <= RTWN_RIDX_VHT_MCS(i, 9);
+			    ridx++)
+				power[ridx] += pwr_diff;
+
 		}
 	}
 
@@ -263,6 +272,12 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 		if (power[ridx] > R92C_MAX_TX_PWR)
 			power[ridx] = R92C_MAX_TX_PWR;
 	}
+	for (ridx = RTWN_RIDX_VHT_MCS(0, 0);
+	    ridx <= RTWN_RIDX_VHT_MCS(3, 9);
+	    ridx++) {
+		if (power[ridx] > R92C_MAX_TX_PWR)
+			power[ridx] = R92C_MAX_TX_PWR;
+	}
 
 #ifdef RTWN_DEBUG
 	if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
@@ -270,6 +285,7 @@ r12a_get_txpower(struct rtwn_softc *sc, int chain,
 		printf("Tx power for chain %d:\n", chain);
 		for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++)
 			printf("Rate %d = %u\n", ridx, power[ridx]);
+		/* TODO: dump VHT 0..9 for each spatial stream */
 	}
 #endif
 }