git: fb97712a7f13 - main - LinuxKPI: 802.11: implement ieee80211_start_tx_ba_session()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 05 Jun 2026 12:10:06 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=fb97712a7f13b85ca707f52f206a2944ee66cf2c
commit fb97712a7f13b85ca707f52f206a2944ee66cf2c
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-04-26 19:58:08 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-06-05 12:09:22 +0000
LinuxKPI: 802.11: implement ieee80211_start_tx_ba_session()
Implement ieee80211_start_tx_ba_session() as a start for rtw8x (and
select mt76 chipsets) to support more throughput.
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
---
sys/compat/linuxkpi/common/include/net/mac80211.h | 6 +-
sys/compat/linuxkpi/common/src/linux_80211.c | 102 ++++++++++++++++++++++
2 files changed, 105 insertions(+), 3 deletions(-)
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 3c783d1f3c8a..c77d37e72fd1 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -1197,6 +1197,7 @@ void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *,
struct ieee80211_txq *, bool);
void linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *,
struct ieee80211_txq *);
+int linuxkpi_ieee80211_start_tx_ba_session(struct ieee80211_sta *, uint8_t, int);
/* -------------------------------------------------------------------------- */
@@ -2118,10 +2119,9 @@ ieee80211_sta_eosp(struct ieee80211_sta *sta)
}
static __inline int
-ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid, int x)
+ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid, int timeout)
{
- TODO("rtw8x");
- return (-EINVAL);
+ return (linuxkpi_ieee80211_start_tx_ba_session(sta, tid, timeout));
}
static __inline int
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 901c59702840..7e55e0912bb1 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -6441,6 +6441,108 @@ net80211_only:
}
#endif
+int
+linuxkpi_ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid,
+ int timeout)
+{
+ struct lkpi_sta *lsta;
+ struct ieee80211_hw *hw;
+ struct lkpi_hw *lhw;
+ struct ieee80211_tx_ampdu *tap;
+ int worked;
+
+ lsta = STA_TO_LSTA(sta);
+
+ /* If tid is out of range, fail gracefully. */
+ /* XXX-BZ are we limited to 8? */
+ if (tid >= IEEE80211_NUM_TIDS) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: tid %u out of range "
+ ">= %u\n", __func__, tid, IEEE80211_NUM_TIDS);
+ return (-EINVAL);
+ }
+
+ hw = lsta->hw;
+ lhw = HW_TO_LHW(hw);
+
+ /* No ampdu_action support, just error. */
+ if (lhw->ops->ampdu_action == NULL) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: (*ampdu_action) "
+ "not supported\n", __func__);
+ return (-ENOTSUPP);
+ }
+
+ /* Does HW allow us to set this up? */
+ if (!ieee80211_hw_check(hw, AMPDU_AGGREGATION)) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: !AMPDU_AGGREGATION\n",
+ __func__);
+ return (-ENOTSUPP);
+ }
+ if (ieee80211_hw_check(hw, TX_AMPDU_SETUP_IN_HW)) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: TX_AMPDU_SETUP_IN_HW\n",
+ __func__);
+ return (-EPERM);
+ }
+
+ /* We need at least HT or higher support enabled. */
+ if (!sta->deflink.ht_cap.ht_supported &&
+ !sta->deflink.vht_cap.vht_supported &&
+ !sta->deflink.he_cap.has_he &&
+ !sta->deflink.eht_cap.has_eht) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: HT or later not "
+ "supported\n", __func__);
+ return (-ENOTSUPP);
+ }
+
+#ifdef __notyet__
+ /*
+ * We need some rate limiting/disabling in case we try too hard and
+ * get NACKed over and over.
+ * XXX-BZ This check should likely go to addba_req along with a counter.
+ */
+ if (lsta->block_ba)
+ return (-EACCESS);
+#endif
+
+ /* XXX-BZ locking? */
+
+ /* Do we have a running session already? */
+ tap = &lsta->ni->ni_tx_ampdu[tid];
+ if (IEEE80211_AMPDU_REQUESTED(tap)) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: "
+ "AMPDU requested/running\n", __func__);
+ return (-EINPROGRESS);
+ }
+
+ /* Tell net80211 to setup an aggr sessions. */
+ /* XXX-BZ we have no way to carry the timeout forward easily. */
+ worked = ieee80211_ampdu_tx_request_ext(lsta->ni, tid);
+ TRACEOK("ieee80211_ampdu_tx_request_ext %d", worked);
+
+ if (worked != 1) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: "
+ "ieee80211_ampdu_tx_request_ext returned %d != 1\n",
+ __func__, worked);
+ return (-EINVAL);
+ }
+
+ /*
+ * How do we make sure the EAPOL handshake has completed?
+ * Let ieee80211_output do it.
+ */
+ if (1) {
+ /* Immediately trigger the setup and output of the action frame. */
+ worked = ieee80211_ampdu_request(lsta->ni, tap);
+ if (worked != 1) {
+ net80211_vap_printf(lsta->ni->ni_vap, "%s: "
+ "ieee80211_ampdu_request returned %d != 1\n",
+ __func__, worked);
+ return (-EAGAIN);
+ }
+ }
+
+ return (0);
+}
+
static void
lkpi_ic_getradiocaps_ht(struct ieee80211com *ic, struct ieee80211_hw *hw,
uint8_t *bands, int *chan_flags, enum nl80211_band band)