From 19cb10a62d2cd4507cbe28bf36a1522fd8d5870a Mon Sep 17 00:00:00 2001 From: Karthik M Date: Fri, 24 Jun 2022 10:28:31 +0530 Subject: [PATCH] hostapd: Add ACS and DFS support for 5GHz BW240MHZ ACS dynamically punctures the channels based on the noise levels. Incase of 5G 240MHZ bandwidth, we need to use static punturing bitmap. In case of radar, We have only one channel in 240MHz. The bandwidth should downgrade to 160MHz and choose a channel. Signed-off-by: Karthik M --- src/ap/acs.c | 19 +++++++++++++++---- src/ap/dfs.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 8 deletions(-) --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -424,7 +424,7 @@ acs_survey_chan_interference_factor(stru static int acs_usable_bw320_chan(const struct hostapd_channel_data *chan) { /* Allow start of overlapping 320MHz channels */ - const int allowed[] = { 5955, 6115, 6275, 6435, 6595, 6755 }; + const int allowed[] = { 5500, 5955, 6115, 6275, 6435, 6595, 6755 }; unsigned int i; for (i = 0; i < ARRAY_SIZE(allowed); i++) @@ -707,6 +707,7 @@ static int is_common_24ghz_chan(int chan #define ACS_24GHZ_PREFER_1_6_11 0.8 #endif /* ACS_24GHZ_PREFER_1_6_11 */ +#define PUNCTURING_PATTERN_5G_320MHZ 0XF000 #ifdef CONFIG_IEEE80211BE static void acs_update_puncturing_bitmap(struct hostapd_iface *iface, @@ -730,6 +731,22 @@ static void acs_update_puncturing_bitmap if (is_24ghz_mode(mode->mode) || bw < 80) return; + + /* + * 5GHz 320Mhz operates with static punturing bitmap. Overiding the dynammic + * bitmap calculation. + */ + if (!is_6ghz_op_class(iface->conf->op_class) && bw == 320) { + if ((conf->punct_bitmap & PUNCTURING_PATTERN_5G_320MHZ) == + PUNCTURING_PATTERN_5G_320MHZ) { + chan->punct_bitmap = conf->punct_bitmap; + goto bitmap_selected; + } else { + wpa_printf(MSG_DEBUG, "ACS : Invalid ru_punct_bitmap for 5G %X", + conf->punct_bitmap); + return; + } + } threshold = factor * conf->punct_acs_threshold / 100; for (i = 0; i < n_chans; i++) { @@ -755,7 +772,10 @@ static void acs_update_puncturing_bitmap if (adj_chan->interference_factor > threshold) chan->punct_bitmap |= BIT(i); } - +bitmap_selected: + wpa_printf(MSG_DEBUG, + "ACS: Calculated ru_punct_bitmap is %X and ru_punct_ofdma is %X", + chan->punct_bitmap,conf->ru_punct_ofdma); if (!is_punct_bitmap_valid(bw, (chan->freq - first_chan->freq) / 20, chan->punct_bitmap)) chan->punct_bitmap = 0; @@ -985,6 +1005,11 @@ acs_find_ideal_chan_mode(struct hostapd_ factor = chan->interference_factor; total_weight = 1; + /* 5GHz is supported for 240Mhz and so reducing number of channels*/ + if(!is_6ghz_op_class(iface->conf->op_class) && + hostapd_get_oper_chwidth(iface->conf) == CONF_OPER_CHWIDTH_320MHZ) + n_chans = n_chans - 4; + for (j = 1; j < n_chans; j++) { adj_chan = acs_find_chan(iface, chan->freq + (j * 20)); if (!adj_chan) @@ -1166,7 +1191,9 @@ acs_find_ideal_chan(struct hostapd_iface break; default: break; - /* 320 is supported only in 6GHz 11be mode */ + case CONF_OPER_CHWIDTH_320MHZ: + n_chans = 16; + break; } } --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -50,7 +50,8 @@ static int dfs_get_used_n_chans(struct h if (iface->conf->ieee80211n && iface->conf->secondary_channel) n_chans = 2; - if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { + if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || + iface->conf->ieee80211be) { switch (hostapd_get_oper_chwidth(iface->conf)) { case CONF_OPER_CHWIDTH_USE_HT: break; @@ -64,6 +65,9 @@ static int dfs_get_used_n_chans(struct h n_chans = 4; *seg1 = 4; break; + case CONF_OPER_CHWIDTH_320MHZ: + n_chans = 12; + break; default: break; } @@ -126,6 +130,12 @@ static int dfs_is_chan_allowed(struct ho * 50, 114, 163 */ int allowed_160[] = { 36, 100, 149 }; + /* + * EHT320 valid channels based on center frequency: + * 100 + */ + int allowed_320[] = {100}; + int *allowed = allowed_40; unsigned int i, allowed_no = 0; @@ -142,6 +152,10 @@ static int dfs_is_chan_allowed(struct ho allowed = allowed_160; allowed_no = ARRAY_SIZE(allowed_160); break; + case 16: + allowed = allowed_320; + allowed_no = ARRAY_SIZE(allowed_320); + break; default: wpa_printf(MSG_DEBUG, "Unknown width for %d channels", n_chans); break; @@ -373,7 +387,8 @@ static void dfs_adjust_center_freq(struc u8 *oper_centr_freq_seg0_idx, u8 *oper_centr_freq_seg1_idx) { - if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax) + if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax && + !iface->conf->ieee80211be) return; if (!chan) @@ -400,7 +415,9 @@ static void dfs_adjust_center_freq(struc *oper_centr_freq_seg0_idx = chan->chan + 6; *oper_centr_freq_seg1_idx = sec_chan_idx_80p80 + 6; break; - + case CONF_OPER_CHWIDTH_320MHZ: + *oper_centr_freq_seg0_idx = chan->chan + 30; + break; default: wpa_printf(MSG_INFO, "DFS: Unsupported channel width configuration"); @@ -790,7 +807,7 @@ static int set_dfs_state(struct hostapd_ frequency = cf1 - 70; break; case CHAN_WIDTH_320: - n_chans = 16; + n_chans = 12; frequency = cf1 - 150; break; default: @@ -854,6 +871,10 @@ static int dfs_are_channels_overlapped(s radar_n_chans = 8; frequency = cf1 - 70; break; + case CHAN_WIDTH_320: + radar_n_chans = 12; + frequency = cf1 - 150; + break; default: wpa_printf(MSG_INFO, "DFS chan_width %d not supported", chan_width); @@ -1387,6 +1408,7 @@ dfs_downgrade_bandwidth(struct hostapd_i enum dfs_channel_type *channel_type) { struct hostapd_channel_data *channel; + int oper_chwidth; for (;;) { channel = dfs_get_valid_channel(iface, secondary_channel,