wifi: cfg80211: move puncturing bitmap validation from mac80211
authorAloka Dixit <quic_alokad@quicinc.com>
Tue, 31 Jan 2023 00:12:24 +0000 (16:12 -0800)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 14 Feb 2023 11:09:18 +0000 (12:09 +0100)
- Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to
  chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap()
  and export it.
- Modify the prototype to include struct cfg80211_chan_def instead
  of only bandwidth to support a check which returns false if the
  primary channel is punctured.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/mac80211/mlme.c
net/wireless/chan.c

index 70f01ea..191603f 100644 (file)
@@ -8952,4 +8952,16 @@ static inline int cfg80211_color_change_notify(struct net_device *dev)
                                         0, 0);
 }
 
+/**
+ * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap
+ * @bitmap: bitmap to be validated
+ * @chandef: channel definition
+ *
+ * Validate the puncturing bitmap.
+ *
+ * Return: %true if the bitmap is valid. %false otherwise.
+ */
+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
+                                             const struct cfg80211_chan_def *chandef);
+
 #endif /* __NET_CFG80211_H */
index a14a5ea..09703ca 100644 (file)
@@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms,
  */
 #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
 
-struct ieee80211_per_bw_puncturing_values {
-       u8 len;
-       const u16 *valid_values;
-};
-
-static const u16 puncturing_values_80mhz[] = {
-       0x8, 0x4, 0x2, 0x1
-};
-
-static const u16 puncturing_values_160mhz[] = {
-        0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
-};
-
-static const u16 puncturing_values_320mhz[] = {
-       0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
-       0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
-       0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
-};
-
-#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
-       { \
-               .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
-               .valid_values = puncturing_values_ ## _bw ## mhz \
-       }
-
-static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
-       IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
-       IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
-       IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
-};
-
-static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
-                                                     enum nl80211_chan_width bw)
-{
-       u32 idx, i;
-
-       switch (bw) {
-       case NL80211_CHAN_WIDTH_80:
-               idx = 0;
-               break;
-       case NL80211_CHAN_WIDTH_160:
-               idx = 1;
-               break;
-       case NL80211_CHAN_WIDTH_320:
-               idx = 2;
-               break;
-       default:
-               *bitmap = 0;
-               break;
-       }
-
-       if (!*bitmap)
-               return true;
-
-       for (i = 0; i < per_bw_puncturing[idx].len; i++)
-               if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
-                       return true;
-
-       return false;
-}
-
 /*
  * Extract from the given disabled subchannel bitmap (raw format
  * from the EHT Operation Element) the bits for the subchannel
@@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link,
                        ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
                                                         bitmap);
 
-               if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-                                                             chandef->width))
+               if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
+                                                            chandef))
                        break;
                link->u.mgd.conn_flags |=
                        ieee80211_chandef_downgrade(chandef);
@@ -5638,8 +5577,8 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link,
            extracted == link->conf->eht_puncturing)
                return true;
 
-       if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-                                                      link->conf->chandef.width)) {
+       if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap,
+                                                     &link->conf->chandef)) {
                link_info(link,
                          "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
                          link->u.mgd.bssid,
@@ -7132,8 +7071,8 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
                        u16 bitmap;
 
                        bitmap = get_unaligned_le16(disable_subchannel_bitmap);
-                       if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
-                                                                     link->conf->chandef.width))
+                       if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
+                                                                    &link->conf->chandef))
                                ieee80211_handle_puncturing_bitmap(link,
                                                                   eht_oper,
                                                                   bitmap,
index 0e5835c..0b7e81d 100644 (file)
@@ -1460,3 +1460,72 @@ struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
        }
 }
 EXPORT_SYMBOL(wdev_chandef);
+
+struct cfg80211_per_bw_puncturing_values {
+       u8 len;
+       const u16 *valid_values;
+};
+
+static const u16 puncturing_values_80mhz[] = {
+       0x8, 0x4, 0x2, 0x1
+};
+
+static const u16 puncturing_values_160mhz[] = {
+        0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
+};
+
+static const u16 puncturing_values_320mhz[] = {
+       0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
+       0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
+       0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
+};
+
+#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
+       { \
+               .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
+               .valid_values = puncturing_values_ ## _bw ## mhz \
+       }
+
+static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
+       CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
+       CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
+       CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
+};
+
+bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
+                                             const struct cfg80211_chan_def *chandef)
+{
+       u32 idx, i, start_freq;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_80:
+               idx = 0;
+               start_freq = chandef->center_freq1 - 40;
+               break;
+       case NL80211_CHAN_WIDTH_160:
+               idx = 1;
+               start_freq = chandef->center_freq1 - 80;
+               break;
+       case NL80211_CHAN_WIDTH_320:
+               idx = 2;
+               start_freq = chandef->center_freq1 - 160;
+               break;
+       default:
+               *bitmap = 0;
+               break;
+       }
+
+       if (!*bitmap)
+               return true;
+
+       /* check if primary channel is punctured */
+       if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20))
+               return false;
+
+       for (i = 0; i < per_bw_puncturing[idx].len; i++)
+               if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
+                       return true;
+
+       return false;
+}
+EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap);