From 07f3e2174606202f7954e3a0454dd59064148610 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Apr 2026 11:25:40 +0200 Subject: wifi: cfg80211: separate NPCA validity from chandef validity When considering both NPCA and DBE, it can appear that the NPCA configuration is invalid, e.g. for an 80 MHz BSS channel with DBE to 160 MHz: | primary channel | NPCA primary channel | | V V | p | | n | | | | | | | BSS channel | | DBE channel | Now the NPCA primary channel is in the same half as the primary channel, and the NPCA puncturing bitmap could be completely invalid as a puncturing bitmap when considering the overall channel. Split out the validity checks from cfg80211_chandef_valid() to a new cfg80211_chandef_npca_valid() function that just checks the NPCA configuration against the BSS chandef. Link: https://patch.msgid.link/20260428112708.1225df131557.If3a6afadcce05d215b72fd82175f72373a0f6d24@changeid Signed-off-by: Johannes Berg --- net/wireless/chan.c | 59 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 21 deletions(-) (limited to 'net/wireless') diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 5289a4ddacd6..ed35b55b1b67 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -460,9 +460,6 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) return false; if (chandef->npca_chan) { - bool pri_upper, npca_upper; - u32 cf1; - switch (chandef->width) { case NL80211_CHAN_WIDTH_80: case NL80211_CHAN_WIDTH_160: @@ -471,24 +468,6 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) default: return false; } - - if (!cfg80211_chandef_valid_control_freq(chandef, - chandef->npca_chan->center_freq)) - return false; - - cf1 = chandef->center_freq1; - pri_upper = chandef->chan->center_freq > cf1; - npca_upper = chandef->npca_chan->center_freq > cf1; - - if (pri_upper == npca_upper) - return false; - - if (!valid_puncturing_bitmap(chandef, - chandef->npca_chan->center_freq, - chandef->npca_punctured) || - (chandef->punctured & chandef->npca_punctured) != - chandef->punctured) - return false; } else if (chandef->npca_punctured) { return false; } @@ -556,6 +535,44 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *c, } EXPORT_SYMBOL(cfg80211_chandef_primary); +bool cfg80211_chandef_npca_valid(struct wiphy *wiphy, + const struct cfg80211_chan_def *chandef, + const struct ieee80211_uhr_npca_info *npca) +{ + struct cfg80211_chan_def tmp = *chandef; + bool pri_upper, npca_upper; + u32 cf1; + + if (chandef->npca_chan || chandef->npca_punctured) + return false; + + if (!npca) + return true; + + if (cfg80211_chandef_add_npca(wiphy, &tmp, npca)) + return false; + + if (!cfg80211_chandef_valid_control_freq(&tmp, + tmp.npca_chan->center_freq)) + return false; + + cf1 = tmp.center_freq1; + pri_upper = tmp.chan->center_freq > cf1; + npca_upper = tmp.npca_chan->center_freq > cf1; + + if (pri_upper == npca_upper) + return false; + + if (!valid_puncturing_bitmap(&tmp, + tmp.npca_chan->center_freq, + tmp.npca_punctured) || + (tmp.punctured & tmp.npca_punctured) != tmp.punctured) + return false; + + return true; +} +EXPORT_SYMBOL(cfg80211_chandef_npca_valid); + int cfg80211_chandef_add_npca(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, const struct ieee80211_uhr_npca_info *npca) -- cgit v1.2.3