diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index e8b1810e1..cef2976bd 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2222,6 +2222,11 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, return ret; for (i = 0; i < iface->num_bss; i++) { + + /* Save CHAN_SWITCH VHT config */ + hostapd_chan_switch_vht_config( + iface->bss[i], settings.freq_params.vht_enabled); + ret = hostapd_switch_channel(iface->bss[i], &settings); if (ret) { /* FIX: What do we do if CSA fails in the middle of diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 35ccd21e6..bc6489a84 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -818,6 +818,11 @@ struct hostapd_config { struct he_phy_capabilities_info he_phy_capab; struct he_operation he_op; #endif /* CONFIG_IEEE80211AX */ + + /* VHT enable/disable config from CHAN_SWITCH */ +#define CH_SWITCH_VHT_ENABLED BIT(0) +#define CH_SWITCH_VHT_DISABLED BIT(1) + unsigned int ch_switch_vht_config; }; diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index c5fd15e06..79fcd9ca1 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -737,9 +737,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, - "driver had channel switch: freq=%d, ht=%d, offset=%d, width=%d (%s), cf1=%d, cf2=%d", - freq, ht, offset, width, channel_width_to_string(width), - cf1, cf2); + "driver had channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d", + freq, ht, hapd->iconf->ch_switch_vht_config, offset, + width, channel_width_to_string(width), cf1, cf2); hapd->iface->freq = freq; @@ -784,8 +784,19 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, hapd->iconf->channel = channel; hapd->iconf->ieee80211n = ht; - if (!ht) + if (!ht) { hapd->iconf->ieee80211ac = 0; + } else if (hapd->iconf->ch_switch_vht_config) { + /* CHAN_SWITCH VHT config */ + if (hapd->iconf->ch_switch_vht_config & + CH_SWITCH_VHT_ENABLED) + hapd->iconf->ieee80211ac = 1; + else if (hapd->iconf->ch_switch_vht_config & + CH_SWITCH_VHT_DISABLED) + hapd->iconf->ieee80211ac = 0; + } + hapd->iconf->ch_switch_vht_config = 0; + hapd->iconf->secondary_channel = offset; hapd->iconf->vht_oper_chwidth = chwidth; hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 49cceb88b..42e82cdec 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -3370,6 +3370,19 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd) } +void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled) +{ + if (vht_enabled) + hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED; + else + hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED; + + hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, + HOSTAPD_LEVEL_INFO, "CHAN_SWITCH VHT CONFIG 0x%x", + hapd->iconf->ch_switch_vht_config); +} + + int hostapd_switch_channel(struct hostapd_data *hapd, struct csa_settings *settings) { diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 7743acf25..4129120f3 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -564,6 +564,7 @@ void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator); void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s); const char * hostapd_state_text(enum hostapd_iface_state s); int hostapd_csa_in_progress(struct hostapd_iface *iface); +void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled); int hostapd_switch_channel(struct hostapd_data *hapd, struct csa_settings *settings); void