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
This commit is contained in:
Adrian Chadd 2024-12-03 21:21:44 -08:00
parent 468cd60623
commit b4980d8a48

View file

@ -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
}