#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"
#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 */
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) {
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 &&
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 */
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");
} \
} 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;
}
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));
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);
* @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;
u16 counter_offset_beacon[2];
u16 counter_offset_presp[2];
+
+ u16 punct_bitmap;
};
/**