Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Apr 2026 21:08:49 +0000
From:      Bjoern A. Zeeb <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 83648b5d42e6 - stable/15 - LinuxKPI: 802.11: make sure dtim_period is set
Message-ID:  <69e938e1.30511.500975d2@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/15 has been updated by bz:

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

commit 83648b5d42e67e2be2c084028d684009a84da5a7
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-04-17 02:34:51 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-04-22 20:57:06 +0000

    LinuxKPI: 802.11: make sure dtim_period is set
    
    When going from ASSOC to RUN LinuxKPI based wireless drivers have
    certian expectations written in various ways.  I believe mac80211
    waits to see a beacon before setting the vif to assoc (or the sta
    to AUTHORIZED).  We have some comments in lkpi_update_dtim_tsf()
    for that.
    In practice we can filter out the beacons already and know when
    they came in as we count them but it is hard to split up the
    state machine and defer the work.
    
    So we make sure that dtim_period is set to at least 1 before
    calling the (*vif_cfg_change) after setting assoc to true;
    0 is a reserved value according to the standards.
    
    We will update it once we see a beacon and in case the value
    differs from 1 shortly afterwards from the recv_mgmt callback.
    
    While iwlwifi seems to have coped with our initial implementation,
    rtw89 may hit a DIV 0 if dtim_period is 0 depending on how well
    the rx path races with our unlocking in assoc_to_run.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 9f20a4ebf044eb0cab83397c83f13bb3958abf6a)
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 89395f2f98b8..b9528295ad8e 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -2013,12 +2013,23 @@ lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni,
 	 * make sure we do not do it on every beacon we still may
 	 * get so only do if something changed.  vif->bss_conf.dtim_period
 	 * should be 0 as we start up (we also reset it on teardown).
+	 *
+	 * If we are assoc we need to make sure dtim_period is non-0.
+	 * 0 is a reserved value and drivers assume they can DIV by it.
+	 * In theory this means we need to wait for the first beacon
+	 * before we finalize the vif being assoc.  In practise that
+	 * is harder until net80211 learns how to.  Work around like
+	 * this for the moment.
 	 */
-	if (vif->cfg.assoc &&
-	    vif->bss_conf.dtim_period != ni->ni_dtim_period &&
-	    ni->ni_dtim_period > 0) {
-		vif->bss_conf.dtim_period = ni->ni_dtim_period;
-		bss_changed |= BSS_CHANGED_BEACON_INFO;
+	if (vif->cfg.assoc) {
+		if (vif->bss_conf.dtim_period != ni->ni_dtim_period &&
+	            ni->ni_dtim_period > 0) {
+			vif->bss_conf.dtim_period = ni->ni_dtim_period;
+			bss_changed |= BSS_CHANGED_BEACON_INFO;
+		} else if (vif->bss_conf.dtim_period == 0) {
+			vif->bss_conf.dtim_period = 1;
+			bss_changed |= BSS_CHANGED_BEACON_INFO;
+		}
 	}
 
 	vif->bss_conf.sync_dtim_count = ni->ni_dtim_count;


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69e938e1.30511.500975d2>