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(-) Index: hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/hostapd/ctrl_iface.c +++ hostapd-2021-12-13-b26f5c0f/hostapd/ctrl_iface.c @@ -33,6 +33,7 @@ #include "common/version.h" #include "common/ieee802_11_defs.h" #include "common/ctrl_iface_common.h" +#include "common/hw_features_common.h" #ifdef CONFIG_DPP #include "common/dpp.h" #endif /* CONFIG_DPP */ @@ -2637,6 +2638,7 @@ static int hostapd_ctrl_register_frame(s static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) { int idx, bw, bw_idx[] = { 20, 40, 80, 160 }; + u32 start_freq; if (is_6ghz_freq(params->freq)) { /* Verify if HE was enabled by user or not. 6 GHz does not @@ -2669,11 +2671,17 @@ static int hostapd_ctrl_check_freq_param if (params->center_freq2 || params->sec_channel_offset) return -1; + + if (params->ru_punct_bitmap) + return -1; break; case 40: if (params->center_freq2 || !params->sec_channel_offset) return -1; + if (params->ru_punct_bitmap) + return -1; + if (!params->center_freq1) break; switch (params->sec_channel_offset) { @@ -2708,6 +2716,9 @@ static int hostapd_ctrl_check_freq_param 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 && @@ -2742,6 +2753,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 */ Index: hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/ap/ctrl_iface_ap.c +++ hostapd-2021-12-13-b26f5c0f/src/ap/ctrl_iface_ap.c @@ -1266,10 +1266,13 @@ 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); 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 Index: hostapd-2021-12-13-b26f5c0f/src/ap/drv_callbacks.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/ap/drv_callbacks.c +++ hostapd-2021-12-13-b26f5c0f/src/ap/drv_callbacks.c @@ -872,6 +872,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 ru_punct_bitmap, u8 ru_punct_ofdma, int finished) { #ifdef NEED_AP_MLME @@ -881,12 +882,13 @@ void hostapd_event_ch_switch(struct host 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, eht_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, ru_punct_bitmap=0x%x, ru_punct_ofdma=%u", finished ? "had" : "starting", 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); + width, channel_width_to_string(width), cf1, cf2, + ru_punct_bitmap, ru_punct_ofdma); if (!hapd->iface->current_mode) { hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, @@ -985,6 +987,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; if (hapd->iconf->ieee80211ac) { hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK; if (chwidth == CHANWIDTH_160MHZ) @@ -999,11 +1003,11 @@ 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 dfs=%d", + "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d 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_dfs); + cf1, cf2, is_dfs, ru_punct_bitmap, ru_punct_ofdma); if (!finished) return; @@ -2090,6 +2094,8 @@ void hostapd_wpa_event(void *ctx, enum w data->ch_switch.ch_width, data->ch_switch.cf1, data->ch_switch.cf2, + data->ch_switch.ru_punct_bitmap, + data->ch_switch.ru_punct_ofdma, event == EVENT_CH_SWITCH); break; case EVENT_CONNECT_FAILED_REASON: Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.c +++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.c @@ -3624,6 +3624,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, @@ -3837,6 +3839,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 Index: hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/ap/hostapd.h +++ hostapd-2021-12-13-b26f5c0f/src/ap/hostapd.h @@ -730,6 +730,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, int finished); struct survey_results; void hostapd_event_get_survey(struct hostapd_iface *iface, Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver.h +++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver.h @@ -6111,6 +6111,8 @@ union wpa_event_data { enum chan_width ch_width; int cf1; int cf2; + u16 ru_punct_bitmap; + u8 ru_punct_ofdma; } ch_switch; /** Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211.c +++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211.c @@ -10064,7 +10064,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%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%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, @@ -10074,7 +10074,9 @@ static int nl80211_switch_channel(void * settings->freq_params.center_freq2, 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"); Index: hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/src/drivers/driver_nl80211_event.c +++ hostapd-2021-12-13-b26f5c0f/src/drivers/driver_nl80211_event.c @@ -692,6 +692,8 @@ static void mlme_event_ch_switch(struct struct nlattr *ifindex, struct nlattr *freq, struct nlattr *type, struct nlattr *bw, struct nlattr *cf1, struct nlattr *cf2, + struct nlattr *ru_punct_bitmap, + struct nlattr *ru_punct_ofdma, struct nlattr *count, int finished) { @@ -754,6 +756,11 @@ static void mlme_event_ch_switch(struct data.ch_switch.cf1 = nla_get_u32(cf1); if (cf2) data.ch_switch.cf2 = nla_get_u32(cf2); + 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 (count) data.ch_switch.count = nla_get_u32(count); @@ -3113,6 +3120,8 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], tb[NL80211_ATTR_CH_SWITCH_COUNT], 0); break; @@ -3124,6 +3133,8 @@ static void do_process_drv_event(struct tb[NL80211_ATTR_CHANNEL_WIDTH], tb[NL80211_ATTR_CENTER_FREQ1], tb[NL80211_ATTR_CENTER_FREQ2], + tb[NL80211_ATTR_RU_PUNCT_BITMAP], + tb[NL80211_ATTR_RU_PUNCT_SUPP_HE], NULL, 1); break; Index: hostapd-2021-12-13-b26f5c0f/wpa_supplicant/ap.c =================================================================== --- hostapd-2021-12-13-b26f5c0f.orig/wpa_supplicant/ap.c +++ hostapd-2021-12-13-b26f5c0f/wpa_supplicant/ap.c @@ -1663,7 +1663,7 @@ void wpas_ap_ch_switch(struct wpa_suppli if (wpa_s->current_ssid) wpa_s->current_ssid->frequency = freq; hostapd_event_ch_switch(iface->bss[0], freq, ht, - offset, width, cf1, cf2, finished); + offset, width, cf1, cf2, 0, 0, finished); }