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(-) Index: b/src/ap/acs.c =================================================================== --- a/src/ap/acs.c 2022-10-18 16:25:59.609149848 +0530 +++ b/src/ap/acs.c 2022-10-18 16:26:17.653035183 +0530 @@ -417,6 +417,18 @@ static int acs_usable_bw160_chan(const s return 0; } +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 int acs_survey_is_sufficient(struct freq_survey *survey) { @@ -871,7 +883,8 @@ acs_find_ideal_chan_mode(struct hostapd_ } 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) == CHANWIDTH_80MHZ && !acs_usable_bw80_chan(chan)) { @@ -889,6 +902,16 @@ acs_find_ideal_chan_mode(struct hostapd_ chan->chan); continue; } + + if (iface->conf->ieee80211be && + hostapd_get_oper_chwidth(iface->conf) == + CHANWIDTH_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; @@ -1043,7 +1066,8 @@ acs_find_ideal_chan(struct hostapd_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 CHANWIDTH_80MHZ: n_chans = 4; @@ -1051,6 +1075,7 @@ acs_find_ideal_chan(struct hostapd_iface case CHANWIDTH_160MHZ: n_chans = 8; break; + /* 320 is supported only in 6GHz 11be mode */ } } @@ -1095,12 +1120,29 @@ bw_selected: return rand_chan; } +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; @@ -1126,6 +1168,27 @@ static void acs_adjust_center_freq(struc else offset = 6; break; + case CHANWIDTH_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 CHANWIDTH_160MHZ: /* In 160MHz, if primary 20MHz present in secondary 80MHz, then * subtract with -6 to find the center frequency of the 160MHz @@ -1139,12 +1202,16 @@ static void acs_adjust_center_freq(struc /* 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 == CHANWIDTH_320MHZ) + iface->conf->eht_oper_centr_freq_seg0_idx = seg0; +#endif } @@ -1201,7 +1268,8 @@ static void acs_study(struct hostapd_ifa iface->freq = ideal_chan->freq; iface->conf->ru_punct_bitmap = ideal_chan->ru_punct_bitmap; - if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) + if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || + iface->conf->ieee80211be) acs_adjust_center_freq(iface); err = 0;