From nobody Sat Apr 18 01:12:45 2026 X-Original-To: dev-commits-src-all@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 4fyDJG1f1Zz6ZTKk for ; Sat, 18 Apr 2026 01:12:46 +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 "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fyDJF5TPRz3nCL for ; Sat, 18 Apr 2026 01:12:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1776474765; 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=zYd+wJ+dpuHBTeME9dDfEvvgjt4pXK0QB1DF33D1570=; b=FD+Ea/DcvkwtYqn6T6V1NcnWCNKoewp9J3ybKXkAM682Zom9B+Ap8MrsG+gx1WDCdHaD2R av+6WshK6PzZm1uu17zchHMLy+ypTyrRtfFCviIppxa7mJHQWAw2aIfeATIjHBD1cxQftz RrRh18XeOBeFF2AulqyJ3whdgRG1RKLnYGS85m2ekfRuN52hbdWp333mdcxVaM/g+aHahI MwThAGDGNVjs372b7+0bJQmb49x1Dudzdld+biV1dYoz5UY6kyCeBfuxPfmNC4UhsJh3b3 c7vF2bzkfumWRakQrZhMwstLdf43CdxMwSfhXAHpcESr1d7SXeabn5DzWcjovg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1776474765; a=rsa-sha256; cv=none; b=DiNicyw45T5VuCn6s1/Jur+PR7thKZRy3WzKhjkkCav7cn4JnmzFwPxhwEVFSPYXJzxf8V E0jzJs/OCRmXPAYH+XP5KbDyVkiiK2vRHWK23ZpjnsTdbWd4K5Z+MXUp/38I2gNRNGtANl w2o2cLJgMZCSaTYX83/qyBXjGcvF3iCN/X2VhMrQz/nZtr/8aEEL701Pe6BXcsFmvZ6370 KxwDggYcfV6QUcdkIZ4pYfH4bPVpctSGaK2IVLNe24lx15NHeIixiSfJTapZrlMW+nipLF 9MWmkA3Ysrb8e+N3nvh18drhojyswEvLxXm2LzbbRj/t7Dt0S3jLijNWMmPcGA== 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=1776474765; 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=zYd+wJ+dpuHBTeME9dDfEvvgjt4pXK0QB1DF33D1570=; b=ZjG85/YJ79ft4LdBnO+ddE90vl2FbWMXK9nCo6NZ5Mpx+HgP1DmagJrqh/LpQ9HeuOrzAA 4R44kfZNdAq7vaHPnY6Fz4sZFJSMo4zZvbYjFJHAUjOFOBRnBND289HjwaDNbqicEfeN8O CDMao1qdXVIQZb08GXg6/G2hZi5Q+3BaujOC0k4L0OucU2+syB1vsD4qvLLFtWvqDXBmdy 7acyi6u1AeW90Wk+gNbkTSeUrkwHTvuE1H36+wIMmnBUiLobfU31Dodx0rgJ829ih9Berr ahjX4W8I/vAwLveo+SO/HNmedS0O3BLTVIuth5Bux5MVB7q/tu1GINnsy8z3Zw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fyDJF52VNz3Kj for ; Sat, 18 Apr 2026 01:12:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 46709 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 18 Apr 2026 01:12:45 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bjoern A. Zeeb Subject: git: 491f5876bfb4 - main - LinuxKPI: 802.11: rework lkpi_ic_set_channel() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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: 491f5876bfb40a4f70f523b5d14bccf6b53d2b0c Auto-Submitted: auto-generated Date: Sat, 18 Apr 2026 01:12:45 +0000 Message-Id: <69e2da8d.46709.17e5559f@gitrepo.freebsd.org> The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=491f5876bfb40a4f70f523b5d14bccf6b53d2b0c commit 491f5876bfb40a4f70f523b5d14bccf6b53d2b0c Author: Bjoern A. Zeeb AuthorDate: 2026-03-10 19:14:43 +0000 Commit: Bjoern A. Zeeb CommitDate: 2026-04-18 01:12:09 +0000 LinuxKPI: 802.11: rework lkpi_ic_set_channel() We are called by net80211 when channel changes are happening and we have to map this to LinuxKPI 802.11. There are multiple cases: (1) it is a hardware scan and net80211 still changes the channel; we do not need to; (2) it is a software scan (the magic fallback case) in which case we let net80211 drive the scan channel and we need to keep a copy of the scan_chandef (see follow-up commit); (3) no scanning but a normal channel change triggerd by net80211; in that case we could (should?) setup the full flags right away but deferred LinuxKPI logic currently handle this for us as not in all cases the information was fully available from net80211 in times we would have needed it. We only do this in order to handle the emulate chanctx cases but do not change the channel otherwise; scan_to_auth will set the correct chanctx. (3a) we have no (active) chanctx for that, create/set one, (3b) we do have an (active) chanctx for this, use it but reset to defaults. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/src/linux_80211.c | 170 +++++++++++++++++++++------ sys/compat/linuxkpi/common/src/linux_80211.h | 1 + 2 files changed, 132 insertions(+), 39 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index d7648f31d70d..e839867bea58 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -4191,7 +4191,6 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], if (hw->max_listen_interval == 0) hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval); hw->conf.listen_interval = hw->max_listen_interval; - ic->ic_set_channel(ic); /* XXX-BZ do we need to be able to update these? */ hw->wiphy->frag_threshold = vap->iv_fragthreshold; @@ -5073,6 +5072,9 @@ lkpi_ic_scan_end(struct ieee80211com *ic) */ lkpi_enable_hw_scan(lhw); + /* Clear the scanning chandef. */ + memset(&lhw->scan_chandef, 0, sizeof(lhw->scan_chandef)); + LKPI_80211_LHW_SCAN_LOCK(lhw); wakeup(lhw); LKPI_80211_LHW_SCAN_UNLOCK(lhw); @@ -5115,6 +5117,25 @@ lkpi_ic_scan_mindwell(struct ieee80211_scan_state *ss) lhw->ic_scan_mindwell(ss); } +struct lkpi_ic_set_channel_iter_arg { + struct linuxkpi_ieee80211_channel *chan; + struct ieee80211_chanctx_conf *chanctx_conf; +}; + +static void +lkpi_ic_set_channel_chanctx_iterf(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *chanctx_conf, void *arg) +{ + struct lkpi_ic_set_channel_iter_arg *chanctx_iter_arg; + + chanctx_iter_arg = arg; + if (chanctx_iter_arg->chanctx_conf != NULL) + return; + + if (chanctx_iter_arg->chan == chanctx_conf->def.chan) + chanctx_iter_arg->chanctx_conf = chanctx_conf; +} + static void lkpi_ic_set_channel(struct ieee80211com *ic) { @@ -5122,64 +5143,133 @@ lkpi_ic_set_channel(struct ieee80211com *ic) struct ieee80211_hw *hw; struct ieee80211_channel *c; struct linuxkpi_ieee80211_channel *chan; + struct ieee80211_chanctx_conf *chanctx_conf; + uint32_t changed; int error; - bool hw_scan_running; + bool hw_scan, scan_running; - lhw = ic->ic_softc; - - /* If we do not support (*config)() save us the work. */ - if (lhw->ops->config == NULL) - return; + IEEE80211_UNLOCK_ASSERT(ic); - /* If we have a hw_scan running do not switch channels. */ - LKPI_80211_LHW_SCAN_LOCK(lhw); - hw_scan_running = - (lhw->scan_flags & (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW)) == - (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW); - LKPI_80211_LHW_SCAN_UNLOCK(lhw); - if (hw_scan_running) - return; + lhw = ic->ic_softc; c = ic->ic_curchan; if (c == NULL || c == IEEE80211_CHAN_ANYC) { - ic_printf(ic, "%s: c %p ops->config %p\n", __func__, - c, lhw->ops->config); + ic_printf(ic, "%s: Unset channel: c %p, ignoring update\n", + __func__, c); return; } chan = lkpi_find_lkpi80211_chan(lhw, c); if (chan == NULL) { - ic_printf(ic, "%s: c %p chan %p\n", __func__, - c, chan); + ic_printf(ic, "%s: No channel found for c %p(%d) chan %p\n", + __func__, c, c->ic_ieee, chan); return; } - /* XXX max power for scanning? */ - IMPROVE(); + /* + * All net80211 callers call ieee80211_radiotap_chan_change(). + * That means we have nothing to do ourselves. + */ + + /* If we have a hw_scan running do not switch channels. */ + LKPI_80211_LHW_SCAN_LOCK(lhw); + scan_running = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0; + hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0; + LKPI_80211_LHW_SCAN_UNLOCK(lhw); + if (scan_running && hw_scan) { + TRACE_SCAN(ic, "scan_flags %b chan %d nothing to do.", + lhw->scan_flags, LKPI_LHW_SCAN_BITS, + c->ic_ieee); + /* Let us hope we set tx power levels elsewhere. */ + return; + } hw = LHW_TO_HW(lhw); - cfg80211_chandef_create(&hw->conf.chandef, chan, -#ifdef LKPI_80211_HT - (ic->ic_flags_ht & IEEE80211_FHT_HT) ? NL80211_CHAN_HT20 : -#endif - NL80211_CHAN_NO_HT); + wiphy_lock(hw->wiphy); + if (scan_running) { + struct ieee80211vap *vap; + struct lkpi_vif *lvif; + struct ieee80211_vif *vif; - error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_CHANNEL); - if (error != 0 && error != EOPNOTSUPP) { - ic_printf(ic, "ERROR: %s: config %#0x returned %d\n", - __func__, IEEE80211_CONF_CHANGE_CHANNEL, error); - /* XXX should we unroll to the previous chandef? */ - IMPROVE(); - } else { - /* Update radiotap channels as well. */ - lhw->rtap_tx.wt_chan_freq = htole16(c->ic_freq); - lhw->rtap_tx.wt_chan_flags = htole16(c->ic_flags); - lhw->rtap_rx.wr_chan_freq = htole16(c->ic_freq); - lhw->rtap_rx.wr_chan_flags = htole16(c->ic_flags); + /* + * For now and for scanning just pick the first VIF. + * net80211 will need to grow DBDC/link_id support + * for us to find the vif/chanctx otherwise. + */ + vap = TAILQ_FIRST(&ic->ic_vaps); + lvif = VAP_TO_LVIF(vap); + vif = LVIF_TO_VIF(lvif); + + /* We always set the chandef to no-HT for scanning. */ + cfg80211_chandef_create(&lhw->scan_chandef, chan, + NL80211_CHAN_NO_HT); + + /* + * This works for as long as we do not do BGSCANs; otherwise + * it'll have to be offchan work. + */ + chanctx_conf = lkpi_get_chanctx_conf(hw, vif); + changed = lkpi_init_chanctx_conf(hw, &lhw->scan_chandef, chanctx_conf); + error = lkpi_set_chanctx_conf(hw, vif, chanctx_conf, changed, true); + + TRACE_SCAN(ic, "scan_flags %b chan %d ???, error %d", + lhw->scan_flags, LKPI_LHW_SCAN_BITS, + c->ic_ieee, error); + + IMPROVE("max power for scanning; TODO in lkpi_80211_update_chandef"); + + } else if (lhw->ops->change_chanctx == ieee80211_emulate_change_chanctx) { + /* + * We do not set the channel here for normal chanctx operation. + * That's just a setup to fail. scan_to_auth will setup all the + * other neccessary options for this to work. + */ + struct lkpi_ic_set_channel_iter_arg chanctx_iter_arg = { + .chan = chan, + .chanctx_conf = NULL, + }; + struct cfg80211_chan_def chandef; + + lkpi_init_chandef(&chandef, chan, c, false); + + ieee80211_iter_chan_contexts_mtx(hw, + lkpi_ic_set_channel_chanctx_iterf, &chanctx_iter_arg); + + if (chanctx_iter_arg.chanctx_conf == NULL) { + /* No chanctx found for this channel. */ + struct ieee80211vap *vap; + struct lkpi_vif *lvif; + struct ieee80211_vif *vif; + + /* + * For now just pick the first VIF. + * net80211 will need to grow DBDC/link_id support + * for us to find the vif/chanctx otherwise. + */ + vap = TAILQ_FIRST(&ic->ic_vaps); + lvif = VAP_TO_LVIF(vap); + vif = LVIF_TO_VIF(lvif); + + chanctx_conf = lkpi_get_chanctx_conf(hw, vif); + changed = lkpi_init_chanctx_conf(hw, &chandef, chanctx_conf); + IMPROVE("update HT, VHT, bw, ..."); + error = lkpi_set_chanctx_conf(hw, vif, chanctx_conf, changed, true); + + } else { + /* + * We know we are on the same channel. + * Do we really have to reset everything? + */ + IMPROVE("update HT, VHT, bw, ..."); + + chanctx_conf = chanctx_iter_arg.chanctx_conf; + changed = lkpi_init_chanctx_conf(hw, &chandef, chanctx_conf); + lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed); + } } /* Currently PS is hard coded off! Not sure it belongs here. */ - IMPROVE(); + IMPROVE("PS"); if (ieee80211_hw_check(hw, SUPPORTS_PS) && (hw->conf.flags & IEEE80211_CONF_PS) != 0) { hw->conf.flags &= ~IEEE80211_CONF_PS; @@ -5189,6 +5279,8 @@ lkpi_ic_set_channel(struct ieee80211com *ic) "%d\n", __func__, IEEE80211_CONF_CHANGE_PS, error); } + + wiphy_unlock(hw->wiphy); } static struct ieee80211_node * diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h index e453cefa20f7..07816cdfe166 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.h +++ b/sys/compat/linuxkpi/common/src/linux_80211.h @@ -256,6 +256,7 @@ struct lkpi_hw { /* name it mac80211_sc? */ struct sx mc_sx; struct cfg80211_chan_def dflt_chandef; + struct cfg80211_chan_def scan_chandef; struct mtx txq_mtx; uint32_t txq_generation[IEEE80211_NUM_ACS];