git: a27b3695d123 - stable/14 - LinuxKPI: 802.11: improvements to (*ampdu_action)() callers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 14 Nov 2024 01:53:57 UTC
The branch stable/14 has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=a27b3695d12300bd458e0d9efc0780f095691204
commit a27b3695d12300bd458e0d9efc0780f095691204
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2024-01-27 13:24:27 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2024-11-14 01:53:12 +0000
LinuxKPI: 802.11: improvements to (*ampdu_action)() callers
Annotate lkpi_ic_recv_action(), lkpi_ic_send_action(), and
lkpi_ic_ampdu_enable() with HT specifc debug logging as we only hook
them up currently for debug tracing but later should not need them
anymore.
Start the implementation for lkpi_ic_addba_request(),
lkpi_ic_addba_response(), and lkpi_ic_addba_stop().
Improve the implementation of lkpi_ic_ampdu_rx_start() and
lkpi_ic_ampdu_rx_stop().
Sponsored by: The FreeBSD Foundation (commit)
(cherry picked from commit 310743c4ccc545d58401cb9fb7761432e12a9fb5)
---
sys/compat/linuxkpi/common/src/linux_80211.c | 206 +++++++++++++++++++++++++--
1 file changed, 192 insertions(+), 14 deletions(-)
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 1a07ef0a82fe..2bb0c2ab113c 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -3992,7 +3992,7 @@ lkpi_ic_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
ic = ni->ni_ic;
lhw = ic->ic_softc;
- IMPROVE_HT();
+ IMPROVE_HT("recv_action called; nothing to do in lkpi; make debugging");
return (lhw->ic_recv_action(ni, wh, frm, efrm));
}
@@ -4006,7 +4006,7 @@ lkpi_ic_send_action(struct ieee80211_node *ni, int category, int action, void *s
ic = ni->ni_ic;
lhw = ic->ic_softc;
- IMPROVE_HT();
+ IMPROVE_HT("send_action called; nothing to do in lkpi; make debugging");
return (lhw->ic_send_action(ni, category, action, sa));
}
@@ -4021,52 +4021,207 @@ lkpi_ic_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
ic = ni->ni_ic;
lhw = ic->ic_softc;
- IMPROVE_HT();
+ IMPROVE_HT("ieee80211_ampdu_enable called; nothing to do in lkpi for now; make debugging");
return (lhw->ic_ampdu_enable(ni, tap));
}
+/*
+ * (*ic_addba_request)() is called by ieee80211_ampdu_request() before
+ * calling send_action(CAT_BA, BA_ADDBA_REQUEST).
+ *
+ * NB: returns 0 on ERROR!
+ */
static int
lkpi_ic_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int dialogtoken, int baparamset, int batimeout)
{
struct ieee80211com *ic;
struct lkpi_hw *lhw;
+ struct ieee80211_hw *hw;
+ struct ieee80211vap *vap;
+ struct lkpi_vif *lvif;
+ struct ieee80211_vif *vif;
+ struct lkpi_sta *lsta;
+ struct ieee80211_sta *sta;
+ struct ieee80211_ampdu_params params = { };
+ int error;
ic = ni->ni_ic;
lhw = ic->ic_softc;
+ hw = LHW_TO_HW(lhw);
+ vap = ni->ni_vap;
+ lvif = VAP_TO_LVIF(vap);
+ vif = LVIF_TO_VIF(lvif);
+ lsta = ni->ni_drv_data;
+ sta = LSTA_TO_STA(lsta);
- IMPROVE_HT();
+ if (!lsta->added_to_drv) {
+ ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
+ __func__, lsta, ni, sta);
+ return (0);
+ }
+
+ params.sta = sta;
+ params.action = IEEE80211_AMPDU_TX_START;
+ /* Keep 0 here! */
+ params.buf_size = 0;
+ params.timeout = 0;
+ params.ssn = tap->txa_start & (IEEE80211_SEQ_RANGE-1);
+ params.tid = tap->txa_tid;
+ params.amsdu = false;
+
+ IEEE80211_UNLOCK(ic);
+ LKPI_80211_LHW_LOCK(lhw);
+ error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
+ LKPI_80211_LHW_UNLOCK(lhw);
+ IEEE80211_LOCK(ic);
+ if (error != 0) {
+ ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
+ __func__, error, ni, tap);
+ return (0);
+ }
return (lhw->ic_addba_request(ni, tap, dialogtoken, baparamset, batimeout));
}
+/*
+ * (*ic_addba_response)() is called from ht_recv_action_ba_addba_response()
+ * and calls the default ieee80211_addba_response() which always returns 1.
+ *
+ * NB: No error checking in net80211!
+ * Staying with 0 is an error.
+ */
static int
lkpi_ic_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int status, int baparamset, int batimeout)
{
struct ieee80211com *ic;
struct lkpi_hw *lhw;
+ struct ieee80211_hw *hw;
+ struct ieee80211vap *vap;
+ struct lkpi_vif *lvif;
+ struct ieee80211_vif *vif;
+ struct lkpi_sta *lsta;
+ struct ieee80211_sta *sta;
+ struct ieee80211_ampdu_params params = { };
+ int error;
ic = ni->ni_ic;
lhw = ic->ic_softc;
+ hw = LHW_TO_HW(lhw);
+ vap = ni->ni_vap;
+ lvif = VAP_TO_LVIF(vap);
+ vif = LVIF_TO_VIF(lvif);
+ lsta = ni->ni_drv_data;
+ sta = LSTA_TO_STA(lsta);
- IMPROVE_HT();
+ if (!lsta->added_to_drv) {
+ ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
+ __func__, lsta, ni, sta);
+ return (0);
+ }
+
+ if (status == IEEE80211_STATUS_SUCCESS) {
+ params.sta = sta;
+ params.action = IEEE80211_AMPDU_TX_OPERATIONAL;
+ params.buf_size = tap->txa_wnd;
+ params.timeout = 0;
+ params.ssn = 0;
+ params.tid = tap->txa_tid;
+ if ((tap->txa_flags & IEEE80211_AGGR_AMSDU) != 0)
+ params.amsdu = true;
+ else
+ params.amsdu = false;
+ } else {
+ /* We need to free the allocated resources. */
+ params.sta = sta;
+ switch (status) {
+ /* params.action = FLUSH, FLUSH_CONT */
+ default:
+ params.action = IEEE80211_AMPDU_TX_STOP_CONT;
+ break;
+ }
+ params.buf_size = 0;
+ params.timeout = 0;
+ params.ssn = 0;
+ params.tid = tap->txa_tid;
+ params.amsdu = false;
+ }
+
+ IEEE80211_UNLOCK(ic);
+ LKPI_80211_LHW_LOCK(lhw);
+ error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
+ LKPI_80211_LHW_UNLOCK(lhw);
+ IEEE80211_LOCK(ic);
+ if (error != 0) {
+ ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
+ __func__, error, ni, tap);
+ return (0);
+ }
+
+ IMPROVE_HT("who unleashes the TXQ? and when?, do we need to ni->ni_txseqs[tid] = tap->txa_start & 0xfff;");
return (lhw->ic_addba_response(ni, tap, status, baparamset, batimeout));
}
+/*
+ * (*ic_addba_stop)() is called from ampdu_tx_stop(), ht_recv_action_ba_delba(),
+ * and ieee80211_ampdu_stop() and calls the default ieee80211_addba_stop().
+ */
static void
lkpi_ic_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
struct ieee80211com *ic;
struct lkpi_hw *lhw;
+ struct ieee80211_hw *hw;
+ struct ieee80211vap *vap;
+ struct lkpi_vif *lvif;
+ struct ieee80211_vif *vif;
+ struct lkpi_sta *lsta;
+ struct ieee80211_sta *sta;
+ struct ieee80211_ampdu_params params = { };
+ int error;
ic = ni->ni_ic;
lhw = ic->ic_softc;
+ hw = LHW_TO_HW(lhw);
+ vap = ni->ni_vap;
+ lvif = VAP_TO_LVIF(vap);
+ vif = LVIF_TO_VIF(lvif);
+ lsta = ni->ni_drv_data;
+ sta = LSTA_TO_STA(lsta);
- IMPROVE_HT();
+ if (!lsta->added_to_drv) {
+ ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
+ __func__, lsta, ni, sta);
+ goto n80211;
+ }
+ /* We need to free the allocated resources. */
+ params.sta = sta;
+ IMPROVE("net80211 does not provide a reason to us");
+ params.action = IEEE80211_AMPDU_TX_STOP_CONT; /* params.action = FLUSH, FLUSH_CONT */
+ params.buf_size = 0;
+ params.timeout = 0;
+ params.ssn = 0;
+ params.tid = tap->txa_tid;
+ params.amsdu = false;
+
+ IEEE80211_UNLOCK(ic);
+ LKPI_80211_LHW_LOCK(lhw);
+ error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
+ LKPI_80211_LHW_UNLOCK(lhw);
+ IEEE80211_LOCK(ic);
+ if (error != 0) {
+ ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
+ __func__, error, ni, tap);
+ goto n80211;
+ }
+
+ IMPROVE_HT("anyting else?");
+
+n80211:
lhw->ic_addba_stop(ni, tap);
}
@@ -4110,8 +4265,8 @@ lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap
struct lkpi_vif *lvif;
struct ieee80211_vif *vif;
struct lkpi_sta *lsta;
- struct ieee80211_sta *sta;
- struct ieee80211_ampdu_params params;
+ struct ieee80211_sta *sta;
+ struct ieee80211_ampdu_params params = { };
int error;
ic = ni->ni_ic;
@@ -4123,6 +4278,14 @@ lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap
lsta = ni->ni_drv_data;
sta = LSTA_TO_STA(lsta);
+ IEEE80211_UNLOCK_ASSERT(ic);
+
+ if (!lsta->added_to_drv) {
+ ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p not added to firmware\n",
+ __func__, lsta, ni, vap, sta);
+ return (-ENXIO);
+ }
+
params.sta = sta;
params.action = IEEE80211_AMPDU_RX_START;
params.buf_size = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
@@ -4130,22 +4293,33 @@ lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap
params.buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
else
params.buf_size = min(params.buf_size, IEEE80211_MAX_AMPDU_BUF_HT);
- if (params.buf_size > hw->max_rx_aggregation_subframes)
+ if (hw->max_rx_aggregation_subframes > 0 &&
+ params.buf_size > hw->max_rx_aggregation_subframes)
params.buf_size = hw->max_rx_aggregation_subframes;
params.timeout = le16toh(batimeout);
params.ssn = _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
params.tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
- params.amsdu = false;
- IMPROVE_HT("Do we need to distinguish based on SUPPORTS_REORDERING_BUFFER?");
+ /* Based on net80211::ampdu_rx_start(). */
+ if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) &&
+ (_IEEE80211_MASKSHIFT(baparamset, IEEE80211_BAPS_AMSDU)))
+ params.amsdu = true;
+ else
+ params.amsdu = false;
- /* This may call kalloc. Make sure we can sleep. */
+ LKPI_80211_LHW_LOCK(lhw);
error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
+ LKPI_80211_LHW_UNLOCK(lhw);
if (error != 0) {
ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
__func__, error, ni, rap);
return (error);
}
+
+ if (!ieee80211_hw_check(hw, SUPPORTS_REORDERING_BUFFER)) {
+ IMPROVE("%s: TODO: SUPPORTS_REORDERING_BUFFER not set; check net80211\n", __func__);
+ }
+
IMPROVE_HT("net80211 is missing the error check on return and assumes success");
error = lhw->ic_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
@@ -4162,8 +4336,8 @@ lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
struct lkpi_vif *lvif;
struct ieee80211_vif *vif;
struct lkpi_sta *lsta;
- struct ieee80211_sta *sta;
- struct ieee80211_ampdu_params params;
+ struct ieee80211_sta *sta;
+ struct ieee80211_ampdu_params params = { };
int error;
uint8_t tid;
@@ -4203,7 +4377,11 @@ lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
params.tid = tid;
params.amsdu = false;
+ // IEEE80211_UNLOCK(ic);
+ LKPI_80211_LHW_LOCK(lhw);
error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
+ LKPI_80211_LHW_UNLOCK(lhw);
+ // IEEE80211_LOCK(ic);
if (error != 0)
ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
__func__, error, ni, rap);