From c920b7fe2e5076a8af543ccefdbccadb8bb152a0 Mon Sep 17 00:00:00 2001 From: Markov Mikhail <markov.mikhail@xxxxxxx> Date: Mon, 5 Oct 2020 22:31:00 +0500 Subject: [PATCH] AP: ACS: Primary channel for 5 GHz band is now selected based on interference factor. This commit replaces former logic where primary channel was always the first one within bandwidth. Signed-off-by: Markov Mikhail <markov.mikhail@xxxxxxx> --- src/ap/acs.c | 33 ++++++++++++++++++++++++++------- src/ap/ap_config.h | 1 + 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/ap/acs.c b/src/ap/acs.c index aa2ceb0d1..924678a64 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -642,6 +642,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, int n_chans, u32 bw, struct hostapd_channel_data **rand_chan, struct hostapd_channel_data **ideal_chan, + struct hostapd_channel_data **first_chan, long double *ideal_factor) { struct hostapd_channel_data *chan, *adj_chan = NULL; @@ -652,8 +653,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, for (i = 0; i < mode->num_channels; i++) { double total_weight; struct acs_bias *bias, tmp_bias; + struct hostapd_channel_data *pri_chan; - chan = &mode->channels[i]; + pri_chan = chan = &mode->channels[i]; /* Since in the current ACS implementation the first channel is * always a primary channel, skip channels not available as @@ -727,6 +729,10 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, if (acs_usable_chan(adj_chan)) { factor += adj_chan->interference_factor; total_weight += 1; + + if (adj_chan->interference_factor < pri_chan->interference_factor) { + pri_chan = adj_chan; + } } } @@ -805,7 +811,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, if (acs_usable_chan(chan) && (!*ideal_chan || factor < *ideal_factor)) { *ideal_factor = factor; - *ideal_chan = chan; + *ideal_chan = pri_chan; + *first_chan = chan; } /* This channel would at least be usable */ @@ -825,7 +832,7 @@ static struct hostapd_channel_data * acs_find_ideal_chan(struct hostapd_iface *iface) { struct hostapd_channel_data *ideal_chan = NULL, - *rand_chan = NULL; + *rand_chan = NULL, *first_chan = NULL; long double ideal_factor = 0; int i; int n_chans = 1; @@ -866,14 +873,15 @@ acs_find_ideal_chan(struct hostapd_iface *iface) mode = &iface->hw_features[i]; if (!hostapd_hw_skip_mode(iface, mode)) acs_find_ideal_chan_mode(iface, mode, n_chans, bw, - &rand_chan, &ideal_chan, + &rand_chan, &ideal_chan, &first_chan, &ideal_factor); } 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); - return ideal_chan; + iface->conf->bw_first_chan = first_chan->chan; + return is_24ghz_mode(iface->current_mode->mode)? first_chan : ideal_chan; } return rand_chan; @@ -905,7 +913,16 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface) } hostapd_set_oper_centr_freq_seg0_idx(iface->conf, - iface->conf->channel + offset); + iface->conf->bw_first_chan + offset); +} + + +static void acs_adjust_sec_chan(struct hostapd_config *conf) +{ + const short center = hostapd_get_oper_centr_freq_seg0_idx(conf); + + conf->secondary_channel = + (center > conf->channel)? 1 : -1; } @@ -961,8 +978,10 @@ static void acs_study(struct hostapd_iface *iface) iface->conf->channel = ideal_chan->chan; iface->freq = ideal_chan->freq; - if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) + if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { acs_adjust_center_freq(iface); + acs_adjust_sec_chan(iface->conf); + } err = 0; fail: diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index bada04c3e..18d662c6e 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -909,6 +909,7 @@ struct hostapd_config { int fragm_threshold; u8 op_class; u8 channel; + u8 bw_first_chan; int enable_edmg; u8 edmg_channel; u8 acs; -- 2.28.0
_______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap