From 710e19ab3a32cb29f833de594b07c7a2639b88b9 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Wed, 22 Dec 2021 14:16:01 -0800 Subject: [PATCH] ru_puncturing: additions to channel switch command Parse the command to retrive the RU puncturing bitmap and if OFDMA patterns shouldbe considered. Signed-off-by: Aloka Dixit --- hostapd/ctrl_iface.c | 37 ++++++++++++++++++++++++++++++ src/ap/ctrl_iface_ap.c | 3 +++ src/ap/drv_callbacks.c | 14 +++++++---- src/ap/hostapd.c | 4 ++++ src/ap/hostapd.h | 1 + src/drivers/driver.h | 2 ++ src/drivers/driver_nl80211.c | 6 +++-- src/drivers/driver_nl80211_event.c | 11 +++++++++ wpa_supplicant/ap.c | 2 +- 9 files changed, 73 insertions(+), 7 deletions(-) --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2539,6 +2539,11 @@ static int hostapd_ctrl_check_freq_param if (punct_bitmap) return -1; break; + + if (params->ru_punct_bitmap) + return -1; + break; + case 40: if (params->center_freq2 || !params->sec_channel_offset) return -1; @@ -2546,6 +2551,9 @@ static int hostapd_ctrl_check_freq_param if (punct_bitmap) return -1; + if (params->ru_punct_bitmap) + return -1; + if (!params->center_freq1) break; switch (params->sec_channel_offset) { @@ -2583,6 +2591,9 @@ static int hostapd_ctrl_check_freq_param if (params->center_freq2 && punct_bitmap) return -1; + if (params->center_freq2 && params->ru_punct_bitmap) + return -1; + /* Adjacent and overlapped are not allowed for 80+80 */ if (params->center_freq2 && params->center_freq1 - params->center_freq2 <= 80 && @@ -2670,6 +2681,32 @@ static int hostapd_ctrl_check_freq_param return -1; } + if (!params->ru_punct_bitmap) { + params->ru_punct_ofdma = 0; + return 0; + } + + if (!params->eht_enabled) { + wpa_printf(MSG_ERROR, + "Currently RU puncturing is supported only if EHT is enabled"); + return -1; + } + + if (params->freq >= 2412 && params->freq <= 2484) { + wpa_printf(MSG_ERROR, + "RU puncturing not supported in 2.4 GHz"); + return -1; + } + + start_freq = params->center_freq1 - (params->bandwidth / 2); + if (is_ru_punct_bitmap_valid(params->bandwidth, + (params->freq - start_freq) / 20, + params->ru_punct_bitmap, + params->ru_punct_ofdma) == false) { + wpa_printf(MSG_ERROR, "Invalid RU puncturing bitmap"); + return -1; + } + return 0; } #endif /* NEED_AP_MLME */ --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -1182,11 +1182,14 @@ int hostapd_parse_csa_settings(const cha SET_CSA_SETTING(center_freq2); SET_CSA_SETTING(bandwidth); SET_CSA_SETTING(sec_channel_offset); + SET_CSA_SETTING(ru_punct_bitmap); 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->freq_params.ru_punct_ofdma = !!os_strstr(pos, + " ru_punct_ofdma"); settings->block_tx = !!os_strstr(pos, " blocktx"); #undef SET_CSA_SETTING #undef SET_CSA_SETTING_EXT --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -870,7 +870,7 @@ void hostapd_event_sta_opmode_changed(st void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2, - u16 punct_bitmap, int finished) + u16 punct_bitmap, u16 ru_punct_bitmap, u8 ru_punct_ofdma, int finished) { #ifdef NEED_AP_MLME int channel, chwidth, is_dfs0, is_dfs; @@ -879,14 +879,15 @@ void hostapd_event_ch_switch(struct host hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, - "driver %s channel switch: iface->freq=%d, 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, puncturing_bitmap=0x%x", + "driver %s channel switch: iface->freq=%d, 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, puncturing_bitmap=0x%x, ru_punct_bitmap=0x%x, ru_punct_ofdma=%u", finished ? "had" : "starting", hapd->iface->freq, freq, ht, hapd->iconf->ch_switch_vht_config, hapd->iconf->ch_switch_he_config, hapd->iconf->ch_switch_eht_config, offset, width, channel_width_to_string(width), cf1, cf2, - punct_bitmap); + punct_bitmap, + ru_punct_bitmap, ru_punct_ofdma); if (!hapd->iface->current_mode) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, @@ -990,6 +991,8 @@ void hostapd_event_ch_switch(struct host hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx); hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx); hapd->iconf->op_class = op_class; + hapd->iconf->ru_punct_bitmap = ru_punct_bitmap; + hapd->iconf->ru_punct_ofdma = ru_punct_ofdma; #ifdef CONFIG_IEEE80211BE hapd->iconf->punct_bitmap = punct_bitmap; #endif /* CONFIG_IEEE80211BE */ @@ -1007,11 +1010,13 @@ void hostapd_event_ch_switch(struct host hapd->iface->num_hw_features); wpa_msg(hapd->msg_ctx, MSG_INFO, - "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d is_dfs0=%d dfs=%d puncturing_bitmap=0x%04x", + "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d is_dfs0=%d dfs=%d puncturing_bitmap=0x%04x" + "ru_punct_bitmap=0x%x ru_punct_ofdma=%u", finished ? WPA_EVENT_CHANNEL_SWITCH : WPA_EVENT_CHANNEL_SWITCH_STARTED, freq, ht, offset, channel_width_to_string(width), - cf1, cf2, is_dfs0, is_dfs, punct_bitmap); + cf1, cf2, is_dfs0, is_dfs, punct_bitmap, + ru_punct_bitmap, ru_punct_ofdma); if (!finished) return; @@ -2183,6 +2188,8 @@ void hostapd_wpa_event(void *ctx, enum w data->ch_switch.cf1, data->ch_switch.cf2, data->ch_switch.punct_bitmap, + data->ch_switch.ru_punct_bitmap, + data->ch_switch.ru_punct_ofdma, event == EVENT_CH_SWITCH); break; case EVENT_CONNECT_FAILED_REASON: --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -3943,6 +3943,8 @@ static int hostapd_change_config_freq(st conf->ieee80211n = params->ht_enabled; conf->ieee80211ac = params->vht_enabled; conf->secondary_channel = params->sec_channel_offset; + conf->ru_punct_bitmap = params->ru_punct_bitmap; + conf->ru_punct_ofdma= params->ru_punct_ofdma; ieee80211_freq_to_chan(params->center_freq1, &seg0); ieee80211_freq_to_chan(params->center_freq2, @@ -4171,6 +4173,8 @@ hostapd_switch_channel_fallback(struct h hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx); hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx); hostapd_set_oper_chwidth(iface->conf, bw); + iface->conf->ru_punct_bitmap = freq_params->ru_punct_bitmap; + iface->conf->ru_punct_ofdma = freq_params->ru_punct_ofdma; /* * Resetting operating class to avoid referring previous values --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -771,6 +771,7 @@ int hostapd_probe_req_rx(struct hostapd_ int ssi_signal); void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht, int offset, int width, int cf1, int cf2, + u16 ru_punct_bitmap, u8 ru_punct_ofdma, u16 punct_bitmap, int finished); struct survey_results; void hostapd_event_get_survey(struct hostapd_iface *iface, --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -6550,6 +6550,8 @@ union wpa_event_data { int cf2; int link_id; u16 punct_bitmap; + u16 ru_punct_bitmap; + u8 ru_punct_ofdma; } ch_switch; /** --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -11013,7 +11013,7 @@ static int nl80211_switch_channel(void * int i; wpa_printf(MSG_DEBUG, - "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d puncturing_bitmap=0x%04x%s%s%s)", + "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d puncturing_bitmap=0x%04x%s%s%s puncturing bitmap=0x%04x, ru_punct_ofdma=%u)", settings->cs_count, settings->block_tx, settings->freq_params.freq, settings->freq_params.channel, @@ -11024,7 +11024,9 @@ static int nl80211_switch_channel(void * settings->punct_bitmap, settings->freq_params.ht_enabled ? " ht" : "", settings->freq_params.vht_enabled ? " vht" : "", - settings->freq_params.he_enabled ? " he" : ""); + settings->freq_params.he_enabled ? " he" : "", + settings->freq_params.ru_punct_bitmap, + settings->freq_params.ru_punct_ofdma); if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) { wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command"); --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -1205,6 +1205,8 @@ static void mlme_event_ch_switch(struct struct nlattr *cf2, struct nlattr *punct_bitmap, struct nlattr *count, + struct nlattr *ru_punct_bitmap, + struct nlattr *ru_punct_ofdma, int finished) { struct i802_bss *bss; @@ -1271,6 +1273,12 @@ static void mlme_event_ch_switch(struct if (count) data.ch_switch.count = nla_get_u32(count); + if (ru_punct_bitmap) { + data.ch_switch.ru_punct_bitmap = nla_get_u16(ru_punct_bitmap); + if (ru_punct_ofdma) + data.ch_switch.ru_punct_ofdma = nla_get_flag(ru_punct_ofdma); + } + if (finished) bss->flink->freq = data.ch_switch.freq; @@ -3909,6 +3917,8 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ2], tb[NL80211_ATTR_PUNCT_BITMAP], tb[NL80211_ATTR_CH_SWITCH_COUNT], + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], 0); break; case NL80211_CMD_CH_SWITCH_NOTIFY: @@ -3922,6 +3932,8 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CENTER_FREQ2], tb[NL80211_ATTR_PUNCT_BITMAP], NULL, + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], 1); break; case NL80211_CMD_DISCONNECT: --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -1878,7 +1878,7 @@ void wpas_ap_ch_switch(struct wpa_suppli wpa_s->current_ssid->frequency = freq; hostapd_event_ch_switch(iface->bss[0], freq, ht, offset, width, cf1, cf2, punct_bitmap, - finished); + 0, 0, finished); }