]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: cfg80211: add helper for parsing NPCA to chandef
authorJohannes Berg <johannes.berg@intel.com>
Tue, 28 Apr 2026 09:25:33 +0000 (11:25 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 5 May 2026 12:49:03 +0000 (14:49 +0200)
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 <johannes.berg@intel.com>
include/net/cfg80211.h
net/wireless/chan.c

index 16e11c5718b5384b04e891573819b251607eeeaa..e807999fc8e8a7bff3af8e5fbecac91650bb5172 100644 (file)
@@ -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
index 38b83b44b5dc23503cb6477d69b9b5d5647a1591..5289a4ddacd6c76f76c363052fffd2086d198ef8 100644 (file)
@@ -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,