Make ACS algorithm select the best channel within a bandwidth as primary channel instead of just picking the first one. The reason i had to add acs_adjust_sec_chan is because even if i use VHT80 ieee80211n_allowed_ht40_channel_pair -> allowed_ht40_channel_pair check fails and i get fallback to 20 MHz. Signed-off-by: Markov Mikhail <markov.mikhail@xxxxxxx> --- src/ap/acs.c | 42 ++++++++++++++++++++++++++++++++++-------- src/ap/ap_config.h | 1 + 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/ap/acs.c b/src/ap/acs.c index aa2ceb0d1..1ac37271d 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -642,9 +642,10 @@ 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; + struct hostapd_channel_data *chan, *adj_chan = NULL, *pri_chan; long double factor; int i, j; unsigned int k; @@ -653,7 +654,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface, double total_weight; struct acs_bias *bias, tmp_bias; - 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 +728,9 @@ 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 +809,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 +830,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 +871,16 @@ 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; + /* Primary channel selection belongs only to 5G band. */ + return is_24ghz_mode(iface->current_mode->mode)? first_chan : ideal_chan; } return rand_chan; @@ -905,7 +912,24 @@ 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 int ht40_plus_channels[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140, + 149, 157, 165, 184, 192 }; + int i, sec_chan = -1; + + for (i = 0; i < ARRAY_SIZE(ht40_plus_channels); i++) { + if (conf->channel == ht40_plus_channels[i]) { + sec_chan = 1; + break; + } + } + + conf->secondary_channel = sec_chan; } @@ -961,8 +985,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