From nobody Wed Mar 4 11:13:26 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4fQqm70vWrz6TMWp for ; Wed, 04 Mar 2026 11:13:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fQqm66dwwz4KsW for ; Wed, 04 Mar 2026 11:13:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1772622806; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=d02krJi0lje0dMRl50gl0aiPM2IegGlax+75pNvmS5U=; b=Hpz1/cjS7KK1edlgsV/TZqOA6wa6bwAWFI+XraRQvk6SsN98AbdzZ/yOEqQ5oPAf8N4Y1P Po6QdUGDuBlIqNozJT8tesXAyfdQ0UP62V9IgpiRxAYpcuJSNelbD8SRrPThLXvHOdF7mr T/ob1yzy2TCPZ3xD9z2B0lQz1+5mXi6aALN0VpWdNA8l7rOt5AYuHOqgL8Gbb/hsZOkvuR laf+ZCS+A/NHaUzF6PuUEgI83pM/Jrg/W9/0eh20N1Lkp/UZsanTEGJDred93dpvQigR17 3VdGMqKqcgCO37r6TNsGfRHOYusWlrXNxxIGmd7i68+x856vD7CF3lbrxyEcTQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1772622806; a=rsa-sha256; cv=none; b=Q2HsL8WOKAWdxSVznus5am7K02+a1DiISYI9nr6LodCEuU65wKLMOTUs1cUhvcp5lfV7nM Hxit7AXaaTkTJ5tlVlSrY7uSFW/9e1k1UK6eu9WVqBto2KAY8X9oP9EmDaqVxsnVOpp8za vj60chnne8SPbKkXgNh7jxr+srXZjdQc1MlK8Dup3yXJn73TzQynGKmDuNWJftQ5+s6T0N RirnaA/vC72+2VTZ0d8/OcjkCIEYjdVS08KDXB9uOgWwyd2hzsMZaA7ReJoej9b36y55rw Ljek0lLDgIe69OTBfPcLvyct1EGE02DLCmdNJMsBDySI+CZj7G3XJB81BoY7Rw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1772622806; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=d02krJi0lje0dMRl50gl0aiPM2IegGlax+75pNvmS5U=; b=eKa/aHJToaseYD6Q9Z0zpm+SakXCcoocYHN45y7A9s2NIm2f2HMAtIuFyFIrP+vrRvJoUU CCck5Xen6Cyp+SnL8s++m010iGZumqArvxYtA/LXwTaFofK4KUUeSrVyNTOdLoD2v/Qc+F D2/oL3bIsh5YkT0tHWWrnxquR3W8Vv5D+UItMG8+YqcWEfSPd3PWEwLgWSI8skl86A7AzS AnibJ4rGBuiGCLaPXzIkuP9TstIm+/fK5F3HHnLUIUM6Jb+txNM3a8PVOsz0e170XHmvbH a3CgtpvhvhqTwoARwnqxqnuOblKb22CGXCPbgVdzIIXCXL+qwV0bh02Fo+ZT0w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fQqm65sGHzpBb for ; Wed, 04 Mar 2026 11:13:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 409c5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 04 Mar 2026 11:13:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bjoern A. Zeeb Subject: git: 8f532c7b25d5 - main - LinuxKPI: 802.11: improve prep_tx_info List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8f532c7b25d54906c307bfda6cb679632cc26313 Auto-Submitted: auto-generated Date: Wed, 04 Mar 2026 11:13:26 +0000 Message-Id: <69a813d6.409c5.2bf61770@gitrepo.freebsd.org> The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=8f532c7b25d54906c307bfda6cb679632cc26313 commit 8f532c7b25d54906c307bfda6cb679632cc26313 Author: Bjoern A. Zeeb AuthorDate: 2026-03-02 12:51:55 +0000 Commit: Bjoern A. Zeeb CommitDate: 2026-03-04 08:21:41 +0000 LinuxKPI: 802.11: improve prep_tx_info Over time struct ieee80211_prep_tx_info has grown further fields. One which is becoming mandatory is the subtype (of the mgmt frame). iwlwifi(mld) has a WARN for it if it does not match, so we now have to set this for proper operation. In addition we are tyring to improve the situation of setting/unsetting (prepare_tx/complete_tx) in various states and cleanup the use of other fields but link_id which we now leave as a marker for the future everywhere. The general problem we are facing is that our hook surface in this case is the state machine but likely would have to be tx/rx mgmt frames but we would alos have to driver the TX queues from there which is tricky. The long-term answer is to change net80211. Further the hardware flag DEAUTH_NEED_MGD_TX_PREP is dead and was removed again in favour of leting drivers deal with it. iwlwifi(mvm) likely being the only driver which ever used this. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/include/net/mac80211.h | 1 - sys/compat/linuxkpi/common/src/linux_80211.c | 93 ++++++++++++++++++----- 2 files changed, 72 insertions(+), 22 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h index 18891d035094..4f3aad532810 100644 --- a/sys/compat/linuxkpi/common/include/net/mac80211.h +++ b/sys/compat/linuxkpi/common/include/net/mac80211.h @@ -431,7 +431,6 @@ enum ieee80211_hw_flags { IEEE80211_HW_BUFF_MMPDU_TXQ, IEEE80211_HW_CHANCTX_STA_CSA, IEEE80211_HW_CONNECTION_MONITOR, - IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, IEEE80211_HW_HAS_RATE_CONTROL, IEEE80211_HW_MFP_CAPABLE, IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR, diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index 7b61ff6603b7..bbda35cb2e38 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -2502,7 +2502,9 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* Start mgd_prepare_tx. */ memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.duration = PREP_TX_INFO_DURATION; + prep_tx_info.duration = PREP_TX_INFO_DURATION; /* SAE */ + prep_tx_info.subtype = IEEE80211_STYPE_AUTH; + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); lsta->in_mgd = true; @@ -2638,6 +2640,7 @@ lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, in /* End mgd_complete_tx. */ if (lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); + prep_tx_info.subtype = IEEE80211_STYPE_AUTH; prep_tx_info.success = true; lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); lsta->in_mgd = false; @@ -2648,7 +2651,8 @@ lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, in /* Start mgd_prepare_tx. */ if (nstate == IEEE80211_S_ASSOC && !lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.duration = PREP_TX_INFO_DURATION; + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); lsta->in_mgd = true; } @@ -2796,7 +2800,9 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* End mgd_complete_tx. (we do not have to check ostate == IEEE80211_S_ASSOC). */ if (lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.success = true; + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + prep_tx_info.success = true; /* Needs vif->cfg.assoc set! */ + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); lsta->in_mgd = false; } @@ -2860,6 +2866,9 @@ out: * DOWN1 * "to assoc" means we are going back to State 2 from State 4[/3]. * This means ni still is authenticated, so we keep sta, chanctx, .. + * We will send a (Re)Assoc Request in case net80211 handles roadming. + * Note: this can be called as part of a DEAUTH going to State 1 as well, + * so for RoC prep_tx_info we need to check nstate (see run_to_{auth,scan,init}). */ static int lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) @@ -2910,15 +2919,33 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* flush, drop. */ lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true); - IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?"); - if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) && - !lsta->in_mgd) { - memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.duration = PREP_TX_INFO_DURATION; - prep_tx_info.was_assoc = true; - lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); - lsta->in_mgd = true; + /* We should make this a KASSERT. */ + if (lsta->in_mgd) { + ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p lsta %p in_mgd\n", + __func__, __LINE__, lvif, vap, lsta); } + /* + * Problem is that we should hook into the tx/rx flow and not + * try to re-model the state machine parts. We may miss a SME + * triggered frame this way. + */ + memset(&prep_tx_info, 0, sizeof(prep_tx_info)); + if (nstate == IEEE80211_S_ASSOC) { + if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) { + if (arg) + prep_tx_info.subtype = IEEE80211_STYPE_REASSOC_REQ; + else + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + } else { + /* wpa_supplicant upon RTM_IEEE80211_LEAVE. */ + prep_tx_info.subtype = IEEE80211_STYPE_DISASSOC; + } + } else + prep_tx_info.subtype = IEEE80211_STYPE_DEAUTH; + prep_tx_info.was_assoc = true; + prep_tx_info.link_id = 0; + lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); + lsta->in_mgd = true; wiphy_unlock(hw->wiphy); IEEE80211_LOCK(vap->iv_ic); @@ -2957,13 +2984,13 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false); /* End mgd_complete_tx. */ - if (lsta->in_mgd) { - memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.success = false; - prep_tx_info.was_assoc = true; - lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); - lsta->in_mgd = false; + /* We should make this a KASSERT. */ + if (!lsta->in_mgd) { + ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p lsta %p !in_mgd\n", + __func__, __LINE__, lvif, vap, lsta); } + lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); + lsta->in_mgd = false; #if 0 /* sync_rx_queues */ @@ -3047,6 +3074,7 @@ lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, in struct ieee80211_vif *vif; struct ieee80211_node *ni; struct lkpi_sta *lsta; + struct ieee80211_prep_tx_info prep_tx_info; int error; lhw = vap->iv_ic->ic_softc; @@ -3077,6 +3105,20 @@ lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, in lkpi_lsta_dump(lsta, ni, __func__, __LINE__); + /* End mgd_complete_tx. */ + if (lsta->in_mgd && vap->iv_state == IEEE80211_S_ASSOC) { + memset(&prep_tx_info, 0, sizeof(prep_tx_info)); + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + prep_tx_info.link_id = 0; + lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); + lsta->in_mgd = false; + } else if (lsta->in_mgd) { + ic_printf(vap->iv_ic, "%s:%d: in_mgd %d (%s) -> %d (%s) %d\n", + __func__, __LINE__, + vap->iv_state, ieee80211_state_name[vap->iv_state], + nstate, ieee80211_state_name[nstate], arg); + } + /* Take the station down. */ /* Update sta_state (AUTH to NONE). */ KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni)); @@ -3158,7 +3200,8 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int /* End mgd_complete_tx. */ if (lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.success = false; + prep_tx_info.subtype = IEEE80211_STYPE_AUTH; + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); lsta->in_mgd = false; } @@ -3342,17 +3385,25 @@ lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) /* End mgd_complete_tx. */ if (lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.success = false; + if (vap->iv_state == IEEE80211_S_AUTH) + prep_tx_info.subtype = IEEE80211_STYPE_AUTH; + else + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info); lsta->in_mgd = false; } - /* Now start assoc. */ + /* Now start auth/assoc. */ /* Start mgd_prepare_tx. */ if (!lsta->in_mgd) { memset(&prep_tx_info, 0, sizeof(prep_tx_info)); - prep_tx_info.duration = PREP_TX_INFO_DURATION; + if (nstate == IEEE80211_S_AUTH) + prep_tx_info.subtype = IEEE80211_STYPE_AUTH; + else + prep_tx_info.subtype = IEEE80211_STYPE_ASSOC_REQ; + prep_tx_info.link_id = 0; lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info); lsta->in_mgd = true; }