]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EHT: Configure puncturing bitmap during channel switch
authorAloka Dixit <quic_alokad@quicinc.com>
Tue, 14 Mar 2023 04:59:20 +0000 (21:59 -0700)
committerJouni Malinen <j@w1.fi>
Fri, 17 Mar 2023 17:49:54 +0000 (19:49 +0200)
Parse, validate, and configure puncturing bitmap if provided in the
channel switch command.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
hostapd/ctrl_iface.c
src/ap/ctrl_iface_ap.c
src/ap/hostapd.c
src/drivers/driver.h

index 656aacc7db096d19318dcacd8d1b1cc3d9710b61..ca8c705ea15cd4f06ed15312b727b57b8cd39b1b 100644 (file)
@@ -38,6 +38,7 @@
 #endif /* CONFIG_DPP */
 #include "common/wpa_ctrl.h"
 #include "common/ptksa_cache.h"
+#include "common/hw_features_common.h"
 #include "crypto/tls.h"
 #include "drivers/driver.h"
 #include "eapol_auth/eapol_auth_sm.h"
@@ -2431,8 +2432,11 @@ static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
 
 
 #ifdef NEED_AP_MLME
-static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
+static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
+                                         u16 punct_bitmap)
 {
+       u32 start_freq;
+
        switch (params->bandwidth) {
        case 0:
                /* bandwidth not specified: use 20 MHz by default */
@@ -2444,11 +2448,17 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
 
                if (params->center_freq2 || params->sec_channel_offset)
                        return -1;
+
+               if (punct_bitmap)
+                       return -1;
                break;
        case 40:
                if (params->center_freq2 || !params->sec_channel_offset)
                        return -1;
 
+               if (punct_bitmap)
+                       return -1;
+
                if (!params->center_freq1)
                        break;
                switch (params->sec_channel_offset) {
@@ -2483,6 +2493,9 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
                        return -1;
                }
 
+               if (params->center_freq2 && punct_bitmap)
+                       return -1;
+
                /* Adjacent and overlapped are not allowed for 80+80 */
                if (params->center_freq2 &&
                    params->center_freq1 - params->center_freq2 <= 80 &&
@@ -2517,6 +2530,29 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
                return -1;
        }
 
+       if (!punct_bitmap)
+               return 0;
+
+       if (!params->eht_enabled) {
+               wpa_printf(MSG_ERROR,
+                          "Preamble puncturing supported only in EHT");
+               return -1;
+       }
+
+       if (params->freq >= 2412 && params->freq <= 2484) {
+               wpa_printf(MSG_ERROR,
+                          "Preamble puncturing is not supported in 2.4 GHz");
+               return -1;
+       }
+
+       start_freq = params->center_freq1 - (params->bandwidth / 2);
+       if (!is_punct_bitmap_valid(params->bandwidth,
+                                  (params->freq - start_freq) / 20,
+                                  punct_bitmap)) {
+               wpa_printf(MSG_ERROR, "Invalid preamble puncturing bitmap");
+               return -1;
+       }
+
        return 0;
 }
 #endif /* NEED_AP_MLME */
@@ -2537,7 +2573,8 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
        if (ret)
                return ret;
 
-       ret = hostapd_ctrl_check_freq_params(&settings.freq_params);
+       ret = hostapd_ctrl_check_freq_params(&settings.freq_params,
+                                            settings.punct_bitmap);
        if (ret) {
                wpa_printf(MSG_INFO,
                           "chanswitch: invalid frequency settings provided");
index 45f31d9a04af831d0bb9616a3c5210cf8acd30d2..6934a732a5d6d0ada2ba081b63c6f8a82a94725f 100644 (file)
@@ -980,16 +980,27 @@ int hostapd_parse_csa_settings(const char *pos,
                } \
        } while (0)
 
+#define SET_CSA_SETTING_EXT(str) \
+       do { \
+               const char *pos2 = os_strstr(pos, " " #str "="); \
+               if (pos2) { \
+                       pos2 += sizeof(" " #str "=") - 1; \
+                       settings->str = atoi(pos2); \
+               } \
+       } while (0)
+
        SET_CSA_SETTING(center_freq1);
        SET_CSA_SETTING(center_freq2);
        SET_CSA_SETTING(bandwidth);
        SET_CSA_SETTING(sec_channel_offset);
+       SET_CSA_SETTING_EXT(punct_bitmap);
        settings->freq_params.ht_enabled = !!os_strstr(pos, " ht");
        settings->freq_params.vht_enabled = !!os_strstr(pos, " vht");
        settings->freq_params.he_enabled = !!os_strstr(pos, " he");
        settings->freq_params.eht_enabled = !!os_strstr(pos, " eht");
        settings->block_tx = !!os_strstr(pos, " blocktx");
 #undef SET_CSA_SETTING
+#undef SET_CSA_SETTING_EXT
 
        return 0;
 }
index 366b5a195a4024434aba5fe27d667f2a856ff317..141c77f4bd183b9ac3410bf69fb3402f17766e7e 100644 (file)
@@ -3655,6 +3655,9 @@ static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
        struct hostapd_iface *iface = hapd->iface;
        struct hostapd_freq_params old_freq;
        int ret;
+#ifdef CONFIG_IEEE80211BE
+       u16 old_punct_bitmap;
+#endif /* CONFIG_IEEE80211BE */
        u8 chan, bandwidth;
 
        os_memset(&old_freq, 0, sizeof(old_freq));
@@ -3700,9 +3703,16 @@ static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
        if (ret)
                return ret;
 
+#ifdef CONFIG_IEEE80211BE
+       old_punct_bitmap = iface->conf->punct_bitmap;
+       iface->conf->punct_bitmap = settings->punct_bitmap;
+#endif /* CONFIG_IEEE80211BE */
        ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
 
        /* change back the configuration */
+#ifdef CONFIG_IEEE80211BE
+       iface->conf->punct_bitmap = old_punct_bitmap;
+#endif /* CONFIG_IEEE80211BE */
        hostapd_change_config_freq(iface->bss[0], iface->conf,
                                   &old_freq, NULL);
 
index a3ce31f606468ecfe7d59783c34a434ea26cc0aa..a79e0fb89049931123015915b6da7ce65cbb218b 100644 (file)
@@ -2589,6 +2589,7 @@ struct beacon_data {
  * @beacon_after: Next beacon/probe resp/asooc resp info
  * @counter_offset_beacon: Offset to the count field in beacon's tail
  * @counter_offset_presp: Offset to the count field in probe resp.
+ * @punct_bitmap - Preamble puncturing bitmap
  */
 struct csa_settings {
        u8 cs_count;
@@ -2600,6 +2601,8 @@ struct csa_settings {
 
        u16 counter_offset_beacon[2];
        u16 counter_offset_presp[2];
+
+       u16 punct_bitmap;
 };
 
 /**