@@ -403,6 +403,19 @@ static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
}
+static int acs_get_bw40_center_chan(int freq)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bw40_seg); i++)
+ if (freq >= bw40_seg[i].first &&
+ freq < bw40_seg[i].last + 1)
+ return bw40_seg[i].center_chan;
+
+ return 0;
+}
+
+
const struct {
int first;
int last;
@@ -429,6 +442,19 @@ static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
}
+static int acs_get_bw80_center_chan(int freq)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bw80_seg); i++)
+ if (freq >= bw80_seg[i].first &&
+ freq < bw80_seg[i].last + 1)
+ return bw80_seg[i].center_chan;
+
+ return 0;
+}
+
+
const struct {
int first;
int last;
@@ -451,6 +477,19 @@ static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
}
+static int acs_get_bw160_center_chan(int freq)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bw160_seg); i++)
+ if (freq >= bw160_seg[i].first &&
+ freq < bw160_seg[i].last + 1)
+ return bw160_seg[i].center_chan;
+
+ return 0;
+}
+
+
static int acs_survey_is_sufficient(struct freq_survey *survey)
{
if (!(survey->filled & SURVEY_HAS_NF)) {
@@ -944,19 +983,21 @@ bw_selected:
static void acs_adjust_center_freq(struct hostapd_iface *iface)
{
- int offset;
+ int center;
wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
switch (hostapd_get_oper_chwidth(iface->conf)) {
case CHANWIDTH_USE_HT:
- offset = 2 * iface->conf->secondary_channel;
+ center = (iface->conf->secondary_channel) ?
+ acs_get_bw40_center_chan(iface->freq):
+ iface->conf->channel;
break;
case CHANWIDTH_80MHZ:
- offset = 6;
+ center = acs_get_bw80_center_chan(iface->freq);
break;
case CHANWIDTH_160MHZ:
- offset = 14;
+ center = acs_get_bw160_center_chan(iface->freq);
break;
default:
/* TODO: How can this be calculated? Adjust
@@ -966,8 +1007,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
return;
}
- hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
- iface->conf->channel + offset);
+ hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
}
When using 40/80/160MHz, instead of computing the segment center freq based on the selected channel, lets look it up in the bwXXX_seg table. This is preparative work to allow selecting a primary channel which is not the first of the segment. Signed-off-by: Nicolas Escande <nico.escande@gmail.com> --- src/ap/acs.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-)