Message ID | 20220324141920.317515-4-nico.escande@gmail.com |
---|---|
State | RFC |
Headers | show |
Series | ACS: better channel selection for 40/80/160 MHz | expand |
On Thu Mar 24, 2022 at 3:19 PM CET, Nicolas Escande wrote: > When using 40/80/160MHz over 5G/6G, enforce the secondary channel to be > the other channel of the corresponding 40MHz segment. > > Even if this is useless for now, this is preparatory work to allow > ACS to select a primary channel which is not the first of it's segment. > > Signed-off-by: Nicolas Escande <nico.escande@gmail.com> > --- > src/ap/acs.c | 43 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 42 insertions(+), 1 deletion(-) > > diff --git a/src/ap/acs.c b/src/ap/acs.c > index 30f2e8d08..9e1810901 100644 > --- a/src/ap/acs.c > +++ b/src/ap/acs.c > @@ -670,6 +670,24 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq) > return NULL; > } > > +static enum hostapd_hw_mode > +acs_find_mode(struct hostapd_iface *iface, int freq) > +{ > + int i; > + struct hostapd_hw_modes *mode; > + struct hostapd_channel_data *chan; > + > + for (i = 0; i < iface->num_hw_features; i++) { > + mode = &iface->hw_features[i]; > + if (!hostapd_hw_skip_mode(iface, mode)) { > + chan = acs_find_chan_mode(mode, freq); > + if (chan) > + return mode->mode; > + } > + } > + > + return HOSTAPD_MODE_IEEE80211ANY; > +} > > static struct hostapd_channel_data * > acs_find_chan(struct hostapd_iface *iface, int freq) > @@ -981,6 +999,27 @@ bw_selected: > } > > > +static void acs_adjust_secondary(struct hostapd_iface *iface) > +{ > + unsigned int i; > + > + /* When working with bw > 20 on 5G/6G, ACS can return a secondary wich > + * is not channel the first of the segment & wee need to abjust */ > + if (!iface->conf->secondary_channel || > + acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A) > + return; > + > + wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency"); > + > + for (i = 0; i < ARRAY_SIZE(bw40_seg); i++) { > + if (iface->freq == bw40_seg[i].first) > + iface->conf->secondary_channel = 1; > + else /* (iface->freq == bw40_seg[i].last) */ This one should read else if (iface->freq == bw40_seg[i].last) I'll send and updated V2 later on with other remarks if any > + iface->conf->secondary_channel = -1; > + } > +} > + > + > static void acs_adjust_center_freq(struct hostapd_iface *iface) > { > int center; > @@ -1063,8 +1102,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_secondary(iface); > acs_adjust_center_freq(iface); > + } > > err = 0; > fail: > -- > 2.35.1
diff --git a/src/ap/acs.c b/src/ap/acs.c index 30f2e8d08..9e1810901 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -670,6 +670,24 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq) return NULL; } +static enum hostapd_hw_mode +acs_find_mode(struct hostapd_iface *iface, int freq) +{ + int i; + struct hostapd_hw_modes *mode; + struct hostapd_channel_data *chan; + + for (i = 0; i < iface->num_hw_features; i++) { + mode = &iface->hw_features[i]; + if (!hostapd_hw_skip_mode(iface, mode)) { + chan = acs_find_chan_mode(mode, freq); + if (chan) + return mode->mode; + } + } + + return HOSTAPD_MODE_IEEE80211ANY; +} static struct hostapd_channel_data * acs_find_chan(struct hostapd_iface *iface, int freq) @@ -981,6 +999,27 @@ bw_selected: } +static void acs_adjust_secondary(struct hostapd_iface *iface) +{ + unsigned int i; + + /* When working with bw > 20 on 5G/6G, ACS can return a secondary wich + * is not channel the first of the segment & wee need to abjust */ + if (!iface->conf->secondary_channel || + acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A) + return; + + wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency"); + + for (i = 0; i < ARRAY_SIZE(bw40_seg); i++) { + if (iface->freq == bw40_seg[i].first) + iface->conf->secondary_channel = 1; + else /* (iface->freq == bw40_seg[i].last) */ + iface->conf->secondary_channel = -1; + } +} + + static void acs_adjust_center_freq(struct hostapd_iface *iface) { int center; @@ -1063,8 +1102,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_secondary(iface); acs_adjust_center_freq(iface); + } err = 0; fail:
When using 40/80/160MHz over 5G/6G, enforce the secondary channel to be the other channel of the corresponding 40MHz segment. Even if this is useless for now, this is preparatory work to allow ACS to select a primary channel which is not the first of it's segment. Signed-off-by: Nicolas Escande <nico.escande@gmail.com> --- src/ap/acs.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-)