From 3975ed290f4d1dd7340595296fc8d39be6a41486 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Thu, 31 Mar 2022 15:17:47 -0700 Subject: [PATCH 2/3] acs: generate puncturing bitmap Generate puncturing bitmap after the ideal channel selection using the threshold. Signed-off-by: Aloka Dixit --- src/ap/acs.c | 72 +++++++++++++++++++++++++++++++++++++++++--- src/drivers/driver.h | 5 +++ 2 files changed, 73 insertions(+), 4 deletions(-) --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -275,6 +275,7 @@ static void acs_cleanup_mode(struct host dl_list_init(&chan->survey_list); chan->flag |= HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED; chan->min_nf = 0; + chan->ru_punct_bitmap = 0; } } @@ -644,6 +645,49 @@ static int is_common_24ghz_chan(int chan #define ACS_24GHZ_PREFER_1_6_11 0.8 #endif /* ACS_24GHZ_PREFER_1_6_11 */ +static void acs_update_puncturing_bitmap(struct hostapd_iface *iface, + struct hostapd_hw_modes *mode, u32 bw, + int n_chans, + struct hostapd_channel_data *chan, + long double factor, + int index_primary) +{ + struct hostapd_channel_data *adj_chan = NULL; + int i; + struct hostapd_config *conf = iface->conf; + long double threshold = factor * conf->ru_punct_acs_threshold / 100; + + /* + * If threshold is 0 or user configured puncturing pattern is + * available then don't add additional puncturing. + */ + if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap) + return; + + if (is_24ghz_mode(mode->mode) || (bw < 80)) + return; + + for (i = 0; i < n_chans; i++) { + if (i == index_primary) + continue; /* cannot puncture primary channel */ + + if (i > index_primary) + adj_chan = acs_find_chan(iface, + chan->freq + + ((i - index_primary) * 20)); + else + adj_chan = acs_find_chan(iface, + chan->freq - + ((index_primary - i) * 20)); + + if (!adj_chan) + break; + + if (adj_chan->interference_factor > threshold) + chan->ru_punct_bitmap |= BIT(i); + } +} + static void acs_find_6g_psc_chan_mode(struct hostapd_iface *iface, struct hostapd_hw_modes *mode, @@ -740,8 +784,17 @@ acs_find_6g_psc_chan_mode(struct hostapd if (acs_usable_chan(chan) && (!*ideal_chan || factor < *ideal_factor)) { - *ideal_factor = factor; + /* reset puncturing bitmap for the previous ideal channel */ + if (*ideal_chan) + (*ideal_chan)->ru_punct_bitmap = 0; + + *ideal_factor = factor; *ideal_chan = chan; + + if (iface->conf->ieee80211ax) + acs_update_puncturing_bitmap(iface, mode, bw, + n_chans, chan, + factor, 0); } /* This channel would at least be usable */ @@ -772,7 +825,11 @@ acs_find_ideal_chan_mode(struct hostapd_ /* Since in the current ACS implementation the first channel is * always a primary channel, skip channels not available as * primary until more sophisticated channel selection is - * implemented. */ + * implemented. + * If this implementation is changed to allow any channel in + * the bandwidth to be the primary one, the last parameter to + * acs_update_puncturing_bitmap() should be changed to the index + * of the primary channel */ if (!chan_pri_allowed(chan)) continue; @@ -923,8 +980,17 @@ acs_find_ideal_chan_mode(struct hostapd_ if (acs_usable_chan(chan) && (!*ideal_chan || factor < *ideal_factor)) { + /* reset puncturing bitmap for the previous ideal channel */ + if (*ideal_chan) + (*ideal_chan)->ru_punct_bitmap = 0; + *ideal_factor = factor; *ideal_chan = chan; + + if (iface->conf->ieee80211ax) + acs_update_puncturing_bitmap(iface, mode, bw, + n_chans, chan, + factor, 0); } /* This channel would at least be usable */ @@ -1006,9 +1072,18 @@ bw_selected: if (ideal_chan) { wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg", ideal_chan->chan, ideal_chan->freq, ideal_factor); + + if (iface->conf->ru_punct_acs_threshold) + wpa_printf(MSG_DEBUG, "ACS: RU puncturing bitmap 0x%x", + ideal_chan->ru_punct_bitmap); + return ideal_chan; } + if (iface->conf->ru_punct_acs_threshold) + wpa_printf(MSG_DEBUG, "ACS: RU puncturing bitmap 0x%x", + ideal_chan->ru_punct_bitmap); + return rand_chan; } @@ -1116,6 +1191,7 @@ static void acs_study(struct hostapd_ifa iface->conf->channel = ideal_chan->chan; iface->freq = ideal_chan->freq; + iface->conf->ru_punct_bitmap = ideal_chan->ru_punct_bitmap; if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) acs_adjust_center_freq(iface); --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -181,6 +181,11 @@ struct hostapd_channel_data { * wmm_rules - WMM regulatory rules */ struct hostapd_wmm_rule wmm_rules[WMM_AC_NUM]; + + /** + * ru_punct_bitmap - RU puncturing bitmap + */ + u16 ru_punct_bitmap; }; #define HE_MAC_CAPAB_0 0