The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=fc9369abef6b6993e79b08de832e1d49f81a17b9
commit fc9369abef6b6993e79b08de832e1d49f81a17b9 Author: Bjoern A. Zeeb <[email protected]> AuthorDate: 2026-02-24 12:55:48 +0000 Commit: Bjoern A. Zeeb <[email protected]> CommitDate: 2026-02-24 22:06:18 +0000 LinuxKPI: 802.11: do not leak BA sessions when tearing down state In certain cases we may tear down state of a node with 'ongoing' BA sessions. This can trigger a firmware crash with iwlwifi as reported in [1] when trying to remove the sta from the firmware. 0x2010303A | ADVANCED_SYSASSERT .. 0x00000000 | umac data1 (sta id=0) .. 0x0088030C | last host cmd (STA_RM) [1] https://lists.freebsd.org/archives/freebsd-wireless/2025-November/003901.html I hit the same problem while running regression tests after reworking some LinuxKPI 802.11 sta state machine bits. Add the missing calls to lkpi_sta_run_to_assoc() and lkpi_sta_run_to_init() to make sure (through net80211) we call (*ampdu_action) with IEEE80211_AMPDU_RX_STOP to avoid the firmware crash. Note: this specific patch was not excessively tested. The upcoming change to the state machine including this fix has seen more testing but also only needed the change in one place. The reason for putting this in upfront is to document the case well. Reported by: Mohammad Amin (the.madamin20 gmail.com) [1] Sponsored by: The FreeBSSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/src/linux_80211.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 0b732cb691c6..e80cf9436b3a 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -3256,6 +3256,7 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int #if 0 enum ieee80211_bss_changed bss_changed; #endif + struct ieee80211_rx_ampdu *rap; int error; lhw = vap->iv_ic->ic_softc; @@ -3311,6 +3312,16 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int goto outni; } + /* Stop any BA sessions if still active. */ + for (int rapn = 0; rapn < WME_NUM_TID; rapn++) { + rap = &ni->ni_rx_ampdu[rapn]; + + if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0) + continue; + + vap->iv_ic->ic_ampdu_rx_stop(ni, rap); + } + IEEE80211_UNLOCK(vap->iv_ic); /* Ensure the packets get out. */ @@ -3412,6 +3423,7 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int struct ieee80211_sta *sta; struct ieee80211_prep_tx_info prep_tx_info; enum ieee80211_bss_changed bss_changed; + struct ieee80211_rx_ampdu *rap; int error; lhw = vap->iv_ic->ic_softc; @@ -3467,6 +3479,16 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int goto outni; } + /* Stop any BA sessions if still active. */ + for (int rapn = 0; rapn < WME_NUM_TID; rapn++) { + rap = &ni->ni_rx_ampdu[rapn]; + + if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0) + continue; + + vap->iv_ic->ic_ampdu_rx_stop(ni, rap); + } + IEEE80211_UNLOCK(vap->iv_ic); /* Ensure the packets get out. */
