diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 9aa55a846..d479006c7 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2571,7 +2571,7 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, for (i = 0; i < iface->num_bss; i++) { - /* Save CHAN_SWITCH VHT and HE config */ + /* Save CHAN_SWITCH VHT, HE, and EHT config */ hostapd_chan_switch_config(iface->bss[i], &settings.freq_params); diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c index 260912111..60396f3da 100644 --- a/hostapd/hostapd_cli.c +++ b/hostapd/hostapd_cli.c @@ -1169,7 +1169,7 @@ static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl, "arguments (count and freq)\n" "usage: [sec_channel_offset=] " "[center_freq1=] [center_freq2=] [bandwidth=] " - "[blocktx] [ht|vht]\n"); + "[blocktx] [ht|vht|he|eht]\n"); return -1; } diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 0739bc61c..5b7e574a5 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -1131,6 +1131,11 @@ struct hostapd_config { u8 eht_oper_centr_freq_seg0_idx; struct eht_phy_capabilities_info eht_phy_capab; #endif /* CONFIG_IEEE80211BE */ + + /* EHT enable/disable config from CHAN_SWITCH */ +#define CH_SWITCH_EHT_ENABLED BIT(0) +#define CH_SWITCH_EHT_DISABLED BIT(1) + unsigned int ch_switch_eht_config; }; diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index 00639ae2e..cd36420a4 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -932,6 +932,7 @@ int hostapd_parse_csa_settings(const char *pos, 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 diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index beba2fd06..6c1e61137 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -865,10 +865,11 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, - "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", + "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", finished ? "had" : "starting", freq, ht, hapd->iconf->ch_switch_vht_config, - hapd->iconf->ch_switch_he_config, offset, + hapd->iconf->ch_switch_he_config, + hapd->iconf->ch_switch_eht_config, offset, width, channel_width_to_string(width), cf1, cf2); if (!hapd->iface->current_mode) { @@ -948,9 +949,23 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, else if (hapd->iconf->ch_switch_he_config & CH_SWITCH_HE_DISABLED) hapd->iconf->ieee80211ax = 0; +#ifdef CONFIG_IEEE80211BE + } else if (hapd->iconf->ch_switch_eht_config) { + /* CHAN_SWITCH EHT config */ + if (hapd->iconf->ch_switch_eht_config & + CH_SWITCH_EHT_ENABLED) { + hapd->iconf->ieee80211be = 1; + hapd->iconf->ieee80211ax = 1; + if (!is_6ghz_freq(hapd->iface->freq)) + hapd->iconf->ieee80211ac = 1; + } else if (hapd->iconf->ch_switch_eht_config & + CH_SWITCH_EHT_DISABLED) + hapd->iconf->ieee80211be = 0; +#endif /* CONFIG_IEEE80211BE */ } hapd->iconf->ch_switch_vht_config = 0; hapd->iconf->ch_switch_he_config = 0; + hapd->iconf->ch_switch_eht_config = 0; if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 || width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160) diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 6b46e798e..ef53c41df 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -3557,11 +3557,12 @@ static int hostapd_fill_csa_settings(struct hostapd_data *hapd, &hapd->iface->cs_oper_class, &chan) == NUM_HOSTAPD_MODES) { wpa_printf(MSG_DEBUG, - "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d)", + "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d)", settings->freq_params.freq, settings->freq_params.sec_channel_offset, settings->freq_params.vht_enabled, - settings->freq_params.he_enabled); + settings->freq_params.he_enabled, + settings->freq_params.eht_enabled); return -1; } @@ -3618,6 +3619,11 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd) void hostapd_chan_switch_config(struct hostapd_data *hapd, struct hostapd_freq_params *freq_params) { + if (freq_params->eht_enabled) + hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_ENABLED; + else + hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_DISABLED; + if (freq_params->he_enabled) hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED; else @@ -3630,7 +3636,8 @@ void hostapd_chan_switch_config(struct hostapd_data *hapd, hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, - "CHAN_SWITCH HE config 0x%x VHT config 0x%x", + "CHAN_SWITCH EHT config 0x%x HE config 0x%x VHT config 0x%x", + hapd->iconf->ch_switch_eht_config, hapd->iconf->ch_switch_he_config, hapd->iconf->ch_switch_vht_config); } @@ -3708,6 +3715,7 @@ hostapd_switch_channel_fallback(struct hostapd_iface *iface, iface->conf->ieee80211n = freq_params->ht_enabled; iface->conf->ieee80211ac = freq_params->vht_enabled; iface->conf->ieee80211ax = freq_params->he_enabled; + iface->conf->ieee80211be = freq_params->eht_enabled; /* * cs_params must not be cleared earlier because the freq_params diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index ddc4d8574..394e292bd 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -7116,7 +7116,8 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) if (!hapd->cs_freq_params.channel || (!hapd->cs_freq_params.vht_enabled && - !hapd->cs_freq_params.he_enabled)) + !hapd->cs_freq_params.he_enabled && + !hapd->cs_freq_params.eht_enabled)) return eid; /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */