[PATCH] wifi: cfg80211: allow IR on a channel the wiphy already operates on
flat view
COOLING8d
From: TangYi <hidden>
Date: 2026-10-12 13:00:00
Also in:
linux-wireless
Self-managed LAR devices (e.g. iwlwifi) that have not yet learned a
regulatory domain flag their channels as NO-IR, typically without
setting IEEE80211_CHAN_IR_CONCURRENT, even while the device is
associated and communicating on that very channel. cfg80211's existing
IR relaxation cannot kick in for such channels:
- cfg80211_ir_permissive_chan() gates on the driver opting in via
REGULATORY_ENABLE_RELAX_NO_IR (iwlwifi does not), and its iftype
whitelist covers P2P-GO/STATION/P2P-CLIENT but not AP;
- even when it runs, it requires the channel to carry
IEEE80211_CHAN_IR_CONCURRENT, which the LAR did not set.
Meanwhile starting an AP on the exact channel the wiphy is already
operating a station connection on adds nothing new from a regulatory
point of view: the device is already initiating radiation there.
Add a same-channel exemption ahead of the opt-in gate in
cfg80211_ir_permissive_chan(): if any wdev on this wiphy is currently
operating (station connected, or AP beaconing) on the requested
channel, allow IR for the new use regardless of interface type and
without requiring the driver opt-in. Also add NL80211_IFTYPE_AP to the
relaxation whitelist for the general IR_CONCURRENT case, since a plain
AP in the same spot is no more dangerous than a P2P GO, which is
already permitted.
This makes the common "share my Wi-Fi uplink over a hotspot on the
same card" scenario work on single-radio hardware that advertises
managed+AP concurrency in its interface combinations
(`#{ managed } <= 1, #{ AP, ... } <= 1, #channels <= 1`), including the
5 GHz bands that LAR-hobbled devices would otherwise refuse entirely.
Verified on iwlwifi (Meteor Lake PCH CNVi): with the patch, hostapd
brings up an AP on the station's channel (both 2.4 GHz and 5 GHz
UNII-3) while the station connection stays up; a client associates and
reaches the internet through the station uplink. Without the patch,
both wpa_supplicant's embedded channel check and the kernel's
SET_CHANNEL/start_ap path reject the channel with -EINVAL.
Signed-off-by: TangYi <redacted>
---
net/wireless/chan.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletions(-)
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c@@ -1701,6 +1701,30 @@ lockdep_assert_held(&rdev->wiphy.mtx); + /* + * A channel the wiphy is already operating on (e.g. a station + * connection) is already being radiated on by this device; starting + * an AP on the very same channel adds nothing new from a regulatory + * point of view. Allow it regardless of the driver's relax opt-in. + */ + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { + struct ieee80211_channel *other_chan = NULL; + unsigned int link_id; + + for_each_valid_link(wdev, link_id) { + if (wdev->iftype == NL80211_IFTYPE_STATION && + wdev->links[link_id].client.current_bss) + other_chan = wdev->links[link_id].client.current_bss->pub.channel; + else if (wdev->iftype == NL80211_IFTYPE_AP && + wdev->links[link_id].ap.beacon_interval) + other_chan = wdev->links[link_id].ap.chandef.chan; + + if (other_chan == chan) + return true; + other_chan = NULL; + } + } + if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) || !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR)) return false;
@@ -1708,7 +1732,8 @@ /* only valid for GO and TDLS off-channel (station/p2p-CL) */ if (iftype != NL80211_IFTYPE_P2P_GO && iftype != NL80211_IFTYPE_STATION && - iftype != NL80211_IFTYPE_P2P_CLIENT) + iftype != NL80211_IFTYPE_P2P_CLIENT && + iftype != NL80211_IFTYPE_AP) return false; if (regulatory_indoor_allowed() &&