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
This commit is contained in:
Bjoern A. Zeeb
2026-04-26 19:58:08 +00:00
parent ba796102fe
commit fb97712a7f
2 changed files with 105 additions and 3 deletions
@@ -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
@@ -6441,6 +6441,108 @@ lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
}
#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)