From 6017023786ba26149c18d3f73b3f0b829bab4a61 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Mon, 20 Sep 2021 18:49:42 +0530 Subject: [PATCH] ACS: Add ACS support for 11be mode Add ACS support for channels in 11be mode including 320MHz bw support for 6GHz. Signed-off-by: Sriram R Signed-off-by: Ramya Gnanasekar --- src/ap/acs.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/ap/acs.c b/src/ap/acs.c index 3e0726d..a53aab6 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -422,6 +422,18 @@ acs_survey_chan_interference_factor(struct hostapd_iface *iface, chan->interference_factor /= count; } +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 }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(allowed); i++) + if (chan->freq == allowed[i]) + return 1; + + return 0; +} static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan, enum bw_type bw) @@ -991,7 +1003,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, } if (mode->mode == HOSTAPD_MODE_IEEE80211A && - (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) { + (iface->conf->ieee80211ac || iface->conf->ieee80211ax || + iface->conf->ieee80211be)) { if (hostapd_get_oper_chwidth(iface->conf) == CONF_OPER_CHWIDTH_80MHZ && !acs_usable_bw_chan(chan, ACS_BW80)) { @@ -1009,6 +1022,16 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, chan->chan); continue; } + + if (iface->conf->ieee80211be && + hostapd_get_oper_chwidth(iface->conf) == + CONF_OPER_CHWIDTH_320MHZ && + !acs_usable_bw320_chan(chan)) { + wpa_printf(MSG_DEBUG, + "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth", + chan->chan); + continue; + } } factor = 0; @@ -1196,7 +1219,8 @@ acs_find_ideal_chan(struct hostapd_iface *iface) 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_80MHZ: n_chans = 4; @@ -1206,6 +1230,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface) break; default: break; + /* 320 is supported only in 6GHz 11be mode */ } } @@ -1285,12 +1310,30 @@ static void acs_adjust_secondary(struct hostapd_iface *iface) } } +static int acs_get_center_freq_320mhz(int channel) +{ + if (channel >= 1 && channel <= 45) + return 31; + else if (channel >= 49 && channel <= 77) + return 63; + else if (channel >= 81 && channel <= 109) + return 95; + else if (channel >= 113 && channel <= 141) + return 127; + else if (channel >= 145 && channel <= 173) + return 159; + else + return 191; +} static void acs_adjust_center_freq(struct hostapd_iface *iface) { int psc_chan[] = {37, 53, 69, 85, 101, 117, 133, 149, 165, 181, 197, 213} ; - int offset, i; + + int psc_chan_320_1[] = {69, 85, 133, 149, 197, 213}; + int psc_chan_320_2[] = {37, 53, 101, 117, 165, 181, 219}; + int offset = 0, i, seg0 = 0; u8 bw = hostapd_get_oper_chwidth(iface->conf); bool acs_exclude_6ghz_non_psc = iface->conf->acs_exclude_6ghz_non_psc; bool is_sec_psc_chan = false; @@ -1316,6 +1359,26 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface) else offset = 6; break; + case CONF_OPER_CHWIDTH_320MHZ: + if (acs_exclude_6ghz_non_psc) { + for (i = 0; i < ARRAY_SIZE(psc_chan_320_1); i++) { + if (psc_chan_320_1[i] == iface->conf->channel) { + is_sec_psc_chan = (i%2) ? true : false; + offset = is_sec_psc_chan ? 10 : 26; + break; + } + } + for (i = 0; i < ARRAY_SIZE(psc_chan_320_2); i++) { + if (psc_chan_320_2[i] == iface->conf->channel) { + is_sec_psc_chan = (i%2) ? true : false; + offset = is_sec_psc_chan ? -22 : -6; + break; + } + } + seg0 = iface->conf->channel + offset; + } else + seg0 = acs_get_center_freq_320mhz(iface->conf->channel); + /* fallthrough */ case CONF_OPER_CHWIDTH_160MHZ: /* In 160MHz, if primary 20MHz present in secondary 80MHz, then * subtract with -6 to find the center frequency of the 160MHz @@ -1329,12 +1392,17 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface) /* TODO: How can this be calculated? Adjust * acs_find_ideal_chan() */ wpa_printf(MSG_INFO, - "ACS: Only VHT20/40/80/160 is supported now"); + "ACS: Only VHT20/40/80/160 EHT320 is supported now"); return; } hostapd_set_oper_centr_freq_seg0_idx(iface->conf, iface->conf->channel + offset); + +#ifdef CONFIG_IEEE80211BE + if (bw == CONF_OPER_CHWIDTH_320MHZ) + iface->conf->eht_oper_centr_freq_seg0_idx = seg0; +#endif } @@ -1394,7 +1462,8 @@ static void acs_study(struct hostapd_iface *iface) iface->conf->punct_bitmap = ideal_chan->punct_bitmap; #endif /* CONFIG_IEEE80211BE */ - if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { + if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || + iface->conf->ieee80211be) { acs_adjust_secondary(iface); acs_adjust_center_freq(iface); }