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 <1914018426@qq.com> --- 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() &&