Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Sep 2025 01:52:39 GMT
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b73f52a0344d - main - rsu: implement A-MPDU TX; add TODO items for further work
Message-ID:  <202509090152.5891qdG5058727@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by adrian:

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

commit b73f52a0344d0f18207ef51397ceded3ffe58cd0
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2025-06-09 02:09:37 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-09-09 01:46:42 +0000

    rsu: implement A-MPDU TX; add TODO items for further work
    
    * Enable A-MPDU TX by fixing the A-MPDU TX establish routine;
      always assign sequence numbers from net80211 (for now); and
      fix the descriptor programming.
    
    * Add TODO items around CAM allocation for keys, MAC ID stuff which
      we likely need to fix for working IBSS/AP behaviour, and whatever
      other bits and pieces I noticed.
    
    * Disable amsdu2ampdu, we can decap A-MSDU just fine in net80211,
      doubly so if we somehow get A-MSDU inside an A-MPDU.
    
    I've tested / verified that A-MPDU TX and A-MPDU RX is correctly
    established and functioning by using rtwn in monitor mode.
    
    I used an old r92su linux out of tree driver for comparison.
    
    Differential Revision:  https://reviews.freebsd.org/D50748
    Okayed by: bz
---
 sys/dev/usb/wlan/if_rsu.c    | 62 ++++++++++++++++++++++++++++++--------------
 sys/dev/usb/wlan/if_rsureg.h |  9 ++++++-
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index ce2b98a1ba55..e976948f6849 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -371,18 +371,16 @@ rsu_update_chw(struct ieee80211com *ic)
 
 /*
  * notification from net80211 that it'd like to do A-MPDU on the given TID.
- *
- * Note: this actually hangs traffic at the present moment, so don't use it.
- * The firmware debug does indiciate it's sending and establishing a TX AMPDU
- * session, but then no traffic flows.
  */
 static int
 rsu_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 {
-#if 0
 	struct rsu_softc *sc = ni->ni_ic->ic_softc;
 	struct r92s_add_ba_req req;
 
+	RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: called, tid=%d\n",
+	    __func__, tap->txa_tid);
+
 	/* Don't enable if it's requested or running */
 	if (IEEE80211_AMPDU_REQUESTED(tap))
 		return (0);
@@ -397,23 +395,30 @@ rsu_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
 		return (0);
 
 	/* Send the firmware command */
-	RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: establishing AMPDU TX for TID %d\n",
+	RSU_DPRINTF(sc, RSU_DEBUG_AMPDU,
+	    "%s: establishing AMPDU TX for TID %d\n",
 	    __func__,
 	    tap->txa_tid);
 
 	RSU_LOCK(sc);
-	if (rsu_fw_cmd(sc, R92S_CMD_ADDBA_REQ, &req, sizeof(req)) != 1) {
+	if (rsu_fw_cmd(sc, R92S_CMD_ADDBA_REQ, &req, sizeof(req)) != 0) {
 		RSU_UNLOCK(sc);
+		RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: AMPDU TX cmd failure\n",
+		    __func__);
 		/* Mark failure */
-		(void) ieee80211_ampdu_tx_request_active_ext(ni, tap->txa_tid, 0);
+		ieee80211_ampdu_tx_request_active_ext(ni, tap->txa_tid, 0);
+		/* Return 0, we've been driving this ourselves */
 		return (0);
 	}
 	RSU_UNLOCK(sc);
 
+	RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: AMPDU TX cmd success\n",
+	    __func__);
+
 	/* Mark success; we don't get any further notifications */
-	(void) ieee80211_ampdu_tx_request_active_ext(ni, tap->txa_tid, 1);
-#endif
-	/* Return 0, we're driving this ourselves */
+	ieee80211_ampdu_tx_request_active_ext(ni, tap->txa_tid, 1);
+
+	/* Return 0, we've been driving this ourselves */
 	return (0);
 }
 
@@ -563,9 +568,7 @@ rsu_attach(device_t self)
 
 		/* Enable basic HT */
 		ic->ic_htcaps = IEEE80211_HTC_HT |
-#if 0
 		    IEEE80211_HTC_AMPDU |
-#endif
 		    IEEE80211_HTC_AMSDU |
 		    IEEE80211_HTCAP_MAXAMSDU_3839 |
 		    IEEE80211_HTCAP_SMPS_OFF;
@@ -1538,6 +1541,10 @@ rsu_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
 			is_checked = 1;
 			k->wk_flags |= IEEE80211_KEY_SWCRYPT;
 		} else
+			/*
+			 * TODO: should allocate these from the CAM space;
+			 * skipping over the fixed slots and _BC / _BSS.
+			 */
 			*keyix = R92S_MACID_BSS;
 	}
 
@@ -2167,7 +2174,7 @@ rsu_event_addba_req_report(struct rsu_softc *sc, uint8_t *buf, int len)
 	    __func__,
 	    ether_sprintf(ba->mac_addr),
 	    (int) ba->tid,
-	    (int) le16toh(ba->ssn));
+	    (int) le16toh(ba->ssn) >> 4);
 
 	/* XXX do node lookup; this is STA specific */
 
@@ -2213,6 +2220,11 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
 		if (vap->iv_state == IEEE80211_S_AUTH)
 			rsu_event_join_bss(sc, buf, len);
 		break;
+
+	/* TODO: what about R92S_EVT_ADD_STA? and decoding macid? */
+	/* It likely is required for IBSS/AP mode */
+
+	/* TODO: should I be doing this transition in AP mode? */
 	case R92S_EVT_DEL_STA:
 		RSU_DPRINTF(sc, RSU_DEBUG_FWCMD | RSU_DEBUG_STATE,
 		    "%s: disassociated from %s\n", __func__,
@@ -2230,6 +2242,7 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
 		break;
 	case R92S_EVT_FWDBG:
 		buf[60] = '\0';
+		/* TODO: some are \n terminated, some aren't, sigh */
 		RSU_DPRINTF(sc, RSU_DEBUG_FWDBG, "FWDBG: %s\n", (char *)buf);
 		break;
 	case R92S_EVT_ADDBA_REQ_REPORT:
@@ -2842,8 +2855,10 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
 	    SM(R92S_TXDW0_OFFSET, sizeof(*txd)) |
 	    R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG);
 
+	/* TODO: correct macid here? It should be in the node */
 	txd->txdw1 |= htole32(
 	    SM(R92S_TXDW1_MACID, R92S_MACID_BSS) | SM(R92S_TXDW1_QSEL, qid));
+
 	if (!hasqos)
 		txd->txdw1 |= htole32(R92S_TXDW1_NONQOS);
 	if (k != NULL && !(k->wk_flags & IEEE80211_KEY_SWENCRYPT)) {
@@ -2864,8 +2879,13 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
 		    SM(R92S_TXDW1_CIPHER, cipher) |
 		    SM(R92S_TXDW1_KEYIDX, k->wk_keyix));
 	}
-	/* XXX todo: set AGGEN bit if appropriate? */
-	txd->txdw2 |= htole32(R92S_TXDW2_BK);
+
+	/*
+	 * Note: no need to set TXDW2_AGGEN/TXDW2_BK to mark
+	 * A-MPDU and non-AMPDU candidates; the firmware will
+	 * handle this for us.
+	 */
+
 	if (ismcast)
 		txd->txdw2 |= htole32(R92S_TXDW2_BMCAST);
 
@@ -2884,8 +2904,11 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
 	}
 
 	/*
-	 * Firmware will use and increment the sequence number for the
-	 * specified priority.
+	 * Pass in prio here, NOT the sequence number.
+	 *
+	 * The hardware is in theory incrementing sequence numbers
+	 * for us, but I haven't yet figured out exactly when/how
+	 * it's supposed to work.
 	 */
 	txd->txdw3 |= htole32(SM(R92S_TXDW3_SEQ, prio));
 
@@ -3485,7 +3508,8 @@ rsu_load_firmware(struct rsu_softc *sc)
 	dmem.vcs_mode = R92S_VCS_MODE_RTS_CTS;
 	dmem.turbo_mode = 0;
 	dmem.bw40_en = !! (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40);
-	dmem.amsdu2ampdu_en = !! (sc->sc_ht);
+	/* net80211 handles AMSDUs just fine */
+	dmem.amsdu2ampdu_en = 0;
 	dmem.ampdu_en = !! (sc->sc_ht);
 	dmem.agg_offload = !! (sc->sc_ht);
 	dmem.qos_en = 1;
diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h
index fb706a4d9b1a..e2074e1dd2ad 100644
--- a/sys/dev/usb/wlan/if_rsureg.h
+++ b/sys/dev/usb/wlan/if_rsureg.h
@@ -593,7 +593,14 @@ struct r92s_event_join_bss {
 	struct		ndis_wlan_bssid_ex bss;
 } __packed;
 
-#define R92S_MACID_BSS	5	/* XXX hardcoded somewhere */
+/*
+ * This is hard-coded in the firmware for a STA mode
+ * BSS join.  If you turn on FWDEBUG, you'll see this
+ * in the logs:
+ *
+ * rsu0: FWDBG: mac id #5: 0000005b, 000fffff, 00000000
+ */
+#define R92S_MACID_BSS	5
 
 /* Rx MAC descriptor. */
 struct r92s_rx_stat {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509090152.5891qdG5058727>