Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Feb 2026 22:09:10 +0000
From:      Bjoern A. Zeeb <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: fc9369abef6b - main - LinuxKPI: 802.11: do not leak BA sessions when tearing down state
Message-ID:  <699e2186.3483e.4e53180e@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by bz:

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

commit fc9369abef6b6993e79b08de832e1d49f81a17b9
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-02-24 12:55:48 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
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. */


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?699e2186.3483e.4e53180e>