[RFC] hostapd: ACS VHT get best control channel from segment
Janusz Dziedzic
janusz.dziedzic
Tue Mar 11 03:24:29 PDT 2014
In case of VHT40/VHT80 get best control channel
from the segment instead of first one.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic at tieto.com>
---
src/ap/acs.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 3e0155c..0c4a40c 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -508,8 +508,8 @@ static struct hostapd_channel_data *
acs_find_ideal_chan(struct hostapd_iface *iface)
{
struct hostapd_channel_data *chan, *adj_chan, *ideal_chan = NULL,
- *rand_chan = NULL;
- long double factor, ideal_factor = 0;
+ *rand_chan = NULL, *control_chan = NULL;
+ long double factor, ideal_factor = 0, control_factor = 0;
int i, j;
int n_chans = 1;
@@ -550,7 +550,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
iface->conf->ieee80211n &&
iface->conf->secondary_channel &&
!acs_usable_ht40_chan(chan)) {
- wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for HT40",
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for HT40 segment",
chan->chan);
continue;
}
@@ -559,7 +559,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
iface->conf->ieee80211ac &&
iface->conf->vht_oper_chwidth == 1 &&
!acs_usable_vht80_chan(chan)) {
- wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for VHT80",
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for VHT80 segment",
chan->chan);
continue;
}
@@ -568,6 +568,9 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
if (acs_usable_chan(chan))
factor = chan->interference_factor;
+ control_chan = chan;
+ control_factor = factor;
+
for (j = 1; j < n_chans; j++) {
adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
if (!adj_chan)
@@ -575,6 +578,13 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
if (acs_usable_chan(adj_chan))
factor += adj_chan->interference_factor;
+
+ /* TODO handle control_chan also for 2.4 */
+ if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+ control_factor > adj_chan->interference_factor) {
+ control_factor = adj_chan->interference_factor;
+ control_chan = adj_chan;
+ }
}
if (j != n_chans) {
@@ -616,10 +626,13 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
wpa_printf(MSG_DEBUG, "ACS: * channel %d: total interference = %Lg",
chan->chan, factor);
+ wpa_printf(MSG_DEBUG, "ACS: * control_channel %d: control interference = %Lg",
+ control_chan->chan, control_factor);
+
if (acs_usable_chan(chan) &&
(!ideal_chan || factor < ideal_factor)) {
ideal_factor = factor;
- ideal_chan = chan;
+ ideal_chan = control_chan;
}
/* This channel would at least be usable */
@@ -636,19 +649,55 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
return rand_chan;
}
+static void acs_adjust_vht40(struct hostapd_iface *iface)
+{
+ const int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149,
+ 157, 184, 192 };
+ unsigned int i;
+
+ if (!iface->conf->secondary_channel) {
+ /* HT20 only */
+ iface->conf->vht_oper_centr_freq_seg0_idx = iface->conf->channel;
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(allowed); i++)
+ if (iface->conf->channel >= allowed[i] &&
+ iface->conf->channel < allowed[i] + 8) {
+ if (iface->conf->channel == allowed[i])
+ iface->conf->secondary_channel = 1;
+ else
+ iface->conf->secondary_channel = -1;
+ iface->conf->vht_oper_centr_freq_seg0_idx = allowed[i] + 2;
+ }
+}
+
+static void acs_adjust_vht80(struct hostapd_iface *iface)
+{
+ const int allowed[] = { 36, 52, 100, 116, 132, 149 };
+ unsigned int i;
+
+ acs_adjust_vht40(iface);
+
+ for (i = 0; i < ARRAY_SIZE(allowed); i++)
+ if (iface->conf->channel >= allowed[i] &&
+ iface->conf->channel < allowed[i] + 16)
+ iface->conf->vht_oper_centr_freq_seg0_idx = allowed[i] + 6;
+}
static void acs_adjust_vht_center_freq(struct hostapd_iface *iface)
{
+ if (!iface->conf->ieee80211ac)
+ return;
+
wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
switch (iface->conf->vht_oper_chwidth) {
case VHT_CHANWIDTH_USE_HT:
- iface->conf->vht_oper_centr_freq_seg0_idx =
- iface->conf->channel + 2;
+ acs_adjust_vht40(iface);
break;
case VHT_CHANWIDTH_80MHZ:
- iface->conf->vht_oper_centr_freq_seg0_idx =
- iface->conf->channel + 6;
+ acs_adjust_vht80(iface);
break;
default:
/* TODO: How can this be calculated? Adjust
--
1.7.9.5
More information about the Hostap
mailing list