From: Johannes Berg Date: Tue, 28 Apr 2026 09:25:33 +0000 (+0200) Subject: wifi: cfg80211: add helper for parsing NPCA to chandef X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=3ca884399be1bcb04baec264a75133cf7a422b52;p=thirdparty%2Flinux.git wifi: cfg80211: add helper for parsing NPCA to chandef Add a cfg80211_chandef_add_npca() helper function that takes an existing chandef without NPCA and sets the NPCA information from the format used in UHR operation and UHR Parameters Update. Link: https://patch.msgid.link/20260428112708.5cdc4e69a306.I95d396ac671da438f340b1afb735ebfe33164894@changeid Signed-off-by: Johannes Berg --- diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 16e11c5718b5..e807999fc8e8 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1154,6 +1154,19 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *chandef, enum nl80211_chan_width primary_chan_width, u16 *punctured); +/** + * cfg80211_chandef_add_npca - parse and add NPCA information to chandef + * @wiphy: the wiphy this will be used for, for channel pointer lookup + * @chandef: the chandef to modify, must be a valid chandef without NPCA + * @npca: the NPCA information, can be %NULL + * + * Returns: 0 if the NPCA information was added and the resulting + * chandef is valid, a negative error code on errors + */ +int cfg80211_chandef_add_npca(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef, + const struct ieee80211_uhr_npca_info *npca); + /** * nl80211_send_chandef - sends the channel definition. * @msg: the msg to send channel definition diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 38b83b44b5dc..5289a4ddacd6 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -556,6 +556,52 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *c, } EXPORT_SYMBOL(cfg80211_chandef_primary); +int cfg80211_chandef_add_npca(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef, + const struct ieee80211_uhr_npca_info *npca) +{ + struct cfg80211_chan_def new_chandef = *chandef; + u32 width, npca_freq; + u8 offs; + + if (chandef->npca_chan || chandef->npca_punctured) + return -EINVAL; + + if (WARN_ON(!cfg80211_chandef_valid(chandef))) + return -EINVAL; + + if (!npca) + return 0; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_160: + case NL80211_CHAN_WIDTH_320: + break; + default: + return -EINVAL; + } + + offs = le32_get_bits(npca->params, + IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS); + + width = cfg80211_chandef_get_width(chandef); + npca_freq = chandef->center_freq1 - width / 2 + 10 + 20 * offs; + new_chandef.npca_chan = ieee80211_get_channel(wiphy, npca_freq); + if (!new_chandef.npca_chan) + return -EINVAL; + + if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES)) + new_chandef.npca_punctured = le16_to_cpu(npca->dis_subch_bmap[0]); + + if (!cfg80211_chandef_valid(&new_chandef)) + return -EINVAL; + + *chandef = new_chandef; + return 0; +} +EXPORT_SYMBOL(cfg80211_chandef_add_npca); + static const struct cfg80211_chan_def * check_chandef_primary_compat(const struct cfg80211_chan_def *c1, const struct cfg80211_chan_def *c2,