git: 82182587bcc3 - main - rtwn: add VHT20/VHT40/VHT80 bandwidth configuration for transmit.

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Thu, 09 Jan 2025 00:59:12 UTC
The branch main has been updated by adrian:

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

commit 82182587bcc3adf39d6b3b6347f052865c3a34e2
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-12-16 02:35:28 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-01-09 00:52:00 +0000

    rtwn: add VHT20/VHT40/VHT80 bandwidth configuration for transmit.
    
    Add a separate function and path for VHT 20/40/80MHz bandwidth
    transmission.
    
    Differential Revision:  https://reviews.freebsd.org/D48102
---
 sys/dev/rtwn/rtl8812a/r12a_tx.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/sys/dev/rtwn/rtl8812a/r12a_tx.c b/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 336ad75a0b1f..acb238316559 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -47,6 +47,7 @@
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_vht.h>
 
 #include <dev/rtwn/if_rtwnreg.h>
 #include <dev/rtwn/if_rtwnvar.h>
@@ -87,12 +88,42 @@ r12a_get_primary_channel(struct rtwn_softc *sc, struct ieee80211_channel *c)
 	return (0);
 }
 
+/*
+ * Configure VHT20/VHT40/VHT80 as appropriate.
+ *
+ * This is only called for VHT, not for HT.
+ */
+static void
+r12a_tx_set_vht_bw(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
+{
+	struct r12a_tx_desc *txd = (struct r12a_tx_desc *)buf;
+	int prim_chan;
+
+	prim_chan = r12a_get_primary_channel(sc, ni->ni_chan);
+
+	if (ieee80211_vht_check_tx_bw(ni, IEEE80211_STA_RX_BW_80)) {
+		txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_BW,
+		    R12A_TXDW5_DATA_BW80));
+		txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_PRIM_CHAN,
+		    prim_chan));
+	} else if (ieee80211_vht_check_tx_bw(ni, IEEE80211_STA_RX_BW_40)) {
+		txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_BW,
+		    R12A_TXDW5_DATA_BW40));
+		txd->txdw5 |= htole32(SM(R12A_TXDW5_DATA_PRIM_CHAN,
+		    prim_chan));
+	}
+}
+
+/*
+ * Configure HT20/HT40 as appropriate.
+ *
+ * This is only called for HT, not for VHT.
+ */
 static void
 r12a_tx_set_ht40(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
 {
 	struct r12a_tx_desc *txd = (struct r12a_tx_desc *)buf;
 
-	/* XXX VHT80; VHT40; VHT20 */
 	if (ieee80211_ht_check_tx_ht40(ni)) {
 		int prim_chan;
 
@@ -353,8 +384,12 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
 				txd->txdw5 |= htole32(R12A_TXDW5_DATA_SHORT);
 
 			prot = IEEE80211_PROT_NONE;
-			/* TODO: VHT */
-			if (RTWN_RATE_IS_HT(ridx)) {
+			if (RTWN_RATE_IS_VHT(ridx)) {
+				r12a_tx_set_vht_bw(sc, txd, ni);
+				/* XXX TODO: sgi */
+				/* XXX TODO: ldpc */
+				prot = ic->ic_htprotmode;
+			} else if (RTWN_RATE_IS_HT(ridx)) {
 				r12a_tx_set_ht40(sc, txd, ni);
 				r12a_tx_set_sgi(sc, txd, ni);
 				r12a_tx_set_ldpc(sc, txd, ni);