git: 77e64f45c478 - main - rtwn: use ieee80211_ht_get_node_ampdu_density(), fix programming MAX_AGG

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Thu, 05 Dec 2024 07:30:12 UTC
The branch main has been updated by adrian:

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

commit 77e64f45c47827987b84a2e5bf3e9f6a2a52bda8
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2024-11-26 16:59:11 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2024-12-05 07:26:35 +0000

    rtwn: use ieee80211_ht_get_node_ampdu_density(), fix programming MAX_AGG
    
    * use ieee80211_ht_get_node_ampdu_density() now instead of the
      vap->iv_ampdu_density, so the correct density is used in AP/IBSS/mesh
      modes.
    
    * MAX_AGG controls how many frames are to be sent in an A-MPDU.
      It maps to ((MAX_AGG * 2) + 1) == npackets.  0x1f (31) means
      64 packets.  So, instead of hard-coding 0x1f, use the negotiated
      block-ack window size.
    
    Differential Revision: https://reviews.freebsd.org/D47766
---
 sys/dev/rtwn/rtl8192c/r92c_tx.c | 26 ++++++++++++++++++++++++--
 sys/dev/rtwn/rtl8812a/r12a_tx.c | 26 ++++++++++++++++++++++++--
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/sys/dev/rtwn/rtl8192c/r92c_tx.c b/sys/dev/rtwn/rtl8192c/r92c_tx.c
index b8c26d861a14..a3e92e1b7ebb 100644
--- a/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -221,6 +221,28 @@ r92c_tx_setup_macid(void *buf, int id)
 	txd->txdw4 &= ~htole32(R92C_TXDW4_RTS_SHORT);
 }
 
+static int
+r92c_calculate_tx_agg_window(struct rtwn_softc *sc,
+    const struct ieee80211_node *ni, int tid)
+{
+	const struct ieee80211_tx_ampdu *tap;
+	int wnd;
+
+	tap = &ni->ni_tx_ampdu[tid];
+
+	/*
+	 * BAW is (MAX_AGG * 2) + 1, hence the /2 here.
+	 * Ensure we don't send 0 or more than 64.
+	 */
+	wnd = tap->txa_wnd / 2;
+	if (wnd == 0)
+		wnd = 1;
+	else if (wnd > 0x1f)
+		wnd = 0x1f;
+
+	return (wnd);
+}
+
 void
 r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
     struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
@@ -276,9 +298,9 @@ r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
 			    (m->m_flags & M_AMPDU_MPDU) != 0);
 			if (m->m_flags & M_AMPDU_MPDU) {
 				txd->txdw2 |= htole32(SM(R92C_TXDW2_AMPDU_DEN,
-				    vap->iv_ampdu_density));
+				    ieee80211_ht_get_node_ampdu_density(ni)));
 				txd->txdw6 |= htole32(SM(R92C_TXDW6_MAX_AGG,
-				    0x1f));	/* XXX */
+				    r92c_calculate_tx_agg_window(sc, ni, tid)));
 			}
 			if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
 				txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT);
diff --git a/sys/dev/rtwn/rtl8812a/r12a_tx.c b/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 8cee2a16fbd5..6102a0567e74 100644
--- a/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -229,6 +229,28 @@ r12a_tx_set_ldpc(struct rtwn_softc *sc, struct r12a_tx_desc *txd,
 		txd->txdw5 |= htole32(R12A_TXDW5_DATA_LDPC);
 }
 
+static int
+r12a_calculate_tx_agg_window(struct rtwn_softc *sc,
+    const struct ieee80211_node *ni, int tid)
+{
+	const struct ieee80211_tx_ampdu *tap;
+	int wnd;
+
+	tap = &ni->ni_tx_ampdu[tid];
+
+	/*
+	 * BAW is (MAX_AGG * 2) + 1, hence the /2 here.
+	 * Ensure we don't send 0 or more than 64.
+	 */
+	wnd = tap->txa_wnd / 2;
+	if (wnd == 0)
+		wnd = 1;
+	else if (wnd > 0x1f)
+		wnd = 0x1f;
+
+	return (wnd);
+}
+
 void
 r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
     struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
@@ -280,9 +302,9 @@ r12a_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
 			if (m->m_flags & M_AMPDU_MPDU) {
 				txd->txdw2 |= htole32(R12A_TXDW2_AGGEN);
 				txd->txdw2 |= htole32(SM(R12A_TXDW2_AMPDU_DEN,
-				    vap->iv_ampdu_density));
+				    ieee80211_ht_get_node_ampdu_density(ni)));
 				txd->txdw3 |= htole32(SM(R12A_TXDW3_MAX_AGG,
-				    0x1f));	/* XXX */
+				    r12a_calculate_tx_agg_window(sc, ni, tid)));
 			} else
 				txd->txdw2 |= htole32(R12A_TXDW2_AGGBK);