[RFC AP: ACS: select primary channel for 5G-band based on interference factor
Марков Михаил Александрович
markov.mikhail at itmh.ru
Mon Oct 26 08:31:59 EDT 2020
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 at itmh.ru>
---
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
More information about the Hostap
mailing list