The branch main has been updated by bz:

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

commit f68ebebd8ae469e344f10ed2f3c4d9d983a29f41
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2026-03-05 09:58:28 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
CommitDate: 2026-03-05 13:44:02 +0000

    LinuxKPI: 802.11: change teardown order of disassoc and sta rm
    
    In lkpi_sta_auth_to_scan() we remove the sta from the firmware
    for everything supporting (*sta_state).
    
    We used to run into issues here with iwlwifi in that we had to
    use a specific order: set vif->cfg.assoc = false, .aid = 0,
    then remove the sta, and then send the mac update as otherwise
    we would either have the sta silently removed (if we run
    (*bss_info_change) first and fail then or silently not have the
    sta removed and upon sta add we would trigger the fw crash.
    
    The order of events seem to have changed now and especially BE200
    (iwlwifi/mld) is picky about this and would crash the firmware with
    something like:
    
            iwlwifi0: 0x20103311 | ADVANCED_SYSASSERT
            iwlwifi0: 0x00000000 | umac branchlink1
            iwlwifi0: 0xC00808AA | umac branchlink2
            iwlwifi0: 0xD00D6E90 | umac interruptlink1
            iwlwifi0: 0x0108C504 | umac interruptlink2
            iwlwifi0: 0x00000000 | umac data1 (link_id? seen weird values there 
though)
            iwlwifi0: 0x00000006 | umac data2 (fw_sta_id)
            iwlwifi0: 0x00000001 | umac data3
    
    if it would still think we were assoc.
    
    So the new order is as one would have expected initially:
    set assoc = false, aid = 0;  do the remaining bss_conf (vif/link) changes
    and issue the (*vif_cfg_changed) / (*link_info_changed) or for older
    drivers (*bss_info_changed).  That will tell the mac we are no longer
    associated.  And only then remove the sta from the firmware.
    
    Update the comment there along so we do have the paper trail as to when
    and why this changed.
    
    Tested on:      BE200, AX210 (11ac)
    Tested on:      AX200. 9260, 8265, 3165 (11a)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 57 +++++++++++++++-------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c 
b/sys/compat/linuxkpi/common/src/linux_80211.c
index c003075ae601..63f92b8afb2b 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -3281,24 +3281,27 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
 
        bss_changed = 0;
        /*
-        * Start updating bss info (bss_info_changed) (assoc, aid, ..).
+        * Start updating bss info (*bss_info_changed) (assoc, aid, ..).
         *
-        * One would expect this to happen when going off AUTHORIZED.
-        * See comment there; removes the sta from fw if not careful
-        * (bss_info_changed() change is executed right away).
+        * One would expect this to happen when going off AUTHORIZED but
+        * not so.
         *
-        * We need to do this now, before sta changes to IEEE80211_STA_NOTEXIST
-        * as otherwise drivers (iwlwifi at least) will silently not remove
-        * the sta from the firmware and when we will add a new one trigger
-        * a fw assert.
+        * Immediately issuing the (*bss_info_changed) used to also remove the
+        * sta from firmware for iwlwifi; or we have problems with the sta
+        * silently not being removed and then crash upon the next sta add.
+        * Neither seems to be the case or a problem still.
         *
-        * The order which works best so far avoiding early removal or silent
-        * non-removal seems to be (for iwlwifi::mld-mac80211.c cases;
-        * the iwlwifi:mac80211.c case still to be tested):
-        * 1) lkpi_disassoc(): set vif->cfg.assoc = false (aid=0 side effect 
here)
-        * 2) call the last sta_state update -> IEEE80211_STA_NOTEXIST
-        *    (removes the sta given assoc is false)
-        * 3) add the remaining BSS_CHANGED changes and call bss_info_changed()
+        * Contrary for BE200 (iwlwifi/mld) if we do not issue the
+        * (*vif_cfg_change) to tell FW that we are no longer assoc
+        * it will crash now upon sta rm.  So the order now is as we once
+        * expected it:
+        *
+        * 1) lkpi_disassoc(): set vif->cfg.assoc = false and .aid=0
+        * 2) add the remaining BSS_CHANGED changes and call (*bss_info_changed)
+        *    (which may be split up into (*vif_cfg_change) and
+        *    (*link_info_changed) for more modern drivers).
+        * 3) call the last sta_state update -> IEEE80211_STA_NOTEXIST
+        *    (removes the sta given assoc is false) and tidy up our lists.
         * 4) call unassign_vif_chanctx
         * 5) call lkpi_hw_conf_idle
         * 6) call remove_chanctx
@@ -3310,6 +3313,18 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
 
        lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
 
+       IMPROVE("Any bss_info changes to announce?");
+       vif->bss_conf.qos = false;
+       bss_changed |= BSS_CHANGED_QOS;
+       vif->cfg.ssid_len = 0;
+       memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
+       bss_changed |= BSS_CHANGED_BSSID;
+       vif->bss_conf.use_short_preamble = false;
+       /* XXX BSS_CHANGED_???? */
+       vif->bss_conf.dtim_period = 0; /* go back to 0. */
+       bss_changed |= BSS_CHANGED_BEACON_INFO;
+       lkpi_bss_info_change(hw, vif, bss_changed);
+
        /* Adjust sta and change state (from NONE) to NOTEXIST. */
        KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
        KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
@@ -3326,18 +3341,6 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
 
        lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
 
-       IMPROVE("Any bss_info changes to announce?");
-       vif->bss_conf.qos = false;
-       bss_changed |= BSS_CHANGED_QOS;
-       vif->cfg.ssid_len = 0;
-       memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
-       bss_changed |= BSS_CHANGED_BSSID;
-       vif->bss_conf.use_short_preamble = false;
-       /* XXX BSS_CHANGED_???? */
-       vif->bss_conf.dtim_period = 0; /* go back to 0. */
-       bss_changed |= BSS_CHANGED_BEACON_INFO;
-       lkpi_bss_info_change(hw, vif, bss_changed);
-
        LKPI_80211_LVIF_LOCK(lvif);
        /* Remove ni reference for this cache of lsta. */
        lvif->lvif_bss = NULL;

Reply via email to