ACS_BW40,
ACS_BW80,
ACS_BW160,
- ACS_BW320,
+ ACS_BW320_1,
+ ACS_BW320_2,
};
struct bw_item {
{ 6435, 6575, 111 }, { 6595, 6735, 143 },
{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
};
-static const struct bw_item bw_320[] = {
- { 5955, 6255, 31 }, { 6115, 6415, 63 }, { 6275, 6575, 95 },
- { 6435, 6735, 127 }, { 6595, 6895, 159}, { 6755, 7055, 191 },
+static const struct bw_item bw_320_1[] = {
+ { 5955, 6255, 31 }, { 6275, 6575, 95 }, { 6595, 6895, 159 },
+ { -1, -1, -1 }
+};
+static const struct bw_item bw_320_2[] = {
+ { 6115, 6415, 63 }, { 6435, 6735, 127 }, { 6755, 7055, 191 },
{ -1, -1, -1 }
};
static const struct bw_item *bw_desc[] = {
[ACS_BW40] = bw_40,
[ACS_BW80] = bw_80,
[ACS_BW160] = bw_160,
- [ACS_BW320] = bw_320,
+ [ACS_BW320_1] = bw_320_1,
+ [ACS_BW320_2] = bw_320_2,
};
#endif /* CONFIG_IEEE80211BE */
+static bool
+acs_usable_bw320_chan(struct hostapd_iface *iface,
+ struct hostapd_channel_data *chan, int *bw320_offset)
+{
+ const char *bw320_str[] = { "320 MHz", "320 MHz-1", "320 MHz-2" };
+ int conf_bw320_offset = hostapd_get_bw320_offset(iface->conf);
+
+ *bw320_offset = 0;
+ switch (conf_bw320_offset) {
+ case 1:
+ if (acs_usable_bw_chan(chan, ACS_BW320_1))
+ *bw320_offset = 1;
+ break;
+ case 2:
+ if (acs_usable_bw_chan(chan, ACS_BW320_2))
+ *bw320_offset = 2;
+ break;
+ case 0:
+ default:
+ conf_bw320_offset = 0;
+ if (acs_usable_bw_chan(chan, ACS_BW320_1))
+ *bw320_offset = 1;
+ else if (acs_usable_bw_chan(chan, ACS_BW320_2))
+ *bw320_offset = 2;
+ break;
+ }
+
+ if (!*bw320_offset)
+ wpa_printf(MSG_DEBUG,
+ "ACS: Channel %d: not allowed as primary channel for %s bandwidth",
+ chan->chan, bw320_str[conf_bw320_offset]);
+
+ return *bw320_offset != 0;
+}
+
+
static void
acs_find_ideal_chan_mode(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode,
struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
long double factor;
int i, j;
+ int bw320_offset = 0, ideal_bw320_offset = 0;
unsigned int k;
int secondary_channel = 1, freq_offset;
}
if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
- (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
+ (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
+ iface->conf->ieee80211be)) {
if (hostapd_get_oper_chwidth(iface->conf) ==
CONF_OPER_CHWIDTH_80MHZ &&
!acs_usable_bw_chan(chan, ACS_BW80)) {
iface->conf->ieee80211be) {
if (hostapd_get_oper_chwidth(iface->conf) ==
CONF_OPER_CHWIDTH_320MHZ &&
- !acs_usable_bw_chan(chan, ACS_BW320)) {
- wpa_printf(MSG_DEBUG,
- "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth",
- chan->chan);
+ !acs_usable_bw320_chan(iface, chan, &bw320_offset))
continue;
- }
}
factor = 0;
*ideal_factor = factor;
*ideal_chan = chan;
+ ideal_bw320_offset = bw320_offset;
#ifdef CONFIG_IEEE80211BE
if (iface->conf->ieee80211be)
}
/* This channel would at least be usable */
- if (!(*rand_chan))
+ if (!(*rand_chan)) {
*rand_chan = chan;
+ ideal_bw320_offset = bw320_offset;
+ }
}
+
+ hostapd_set_and_check_bw320_offset(iface->conf, ideal_bw320_offset);
}
acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
return;
- wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
+ wpa_printf(MSG_DEBUG,
+ "ACS: Adjusting HT/VHT/HE/EHT secondary frequency");
for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
if (iface->freq == bw_desc[ACS_BW40][i].first)
{
int center;
- wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
+ wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
switch (hostapd_get_oper_chwidth(iface->conf)) {
case CONF_OPER_CHWIDTH_USE_HT:
center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
break;
case CONF_OPER_CHWIDTH_320MHZ:
- center = acs_get_bw_center_chan(iface->freq, ACS_BW320);
+ switch (hostapd_get_bw320_offset(iface->conf)) {
+ case 1:
+ center = acs_get_bw_center_chan(iface->freq,
+ ACS_BW320_1);
+ break;
+ case 2:
+ center = acs_get_bw_center_chan(iface->freq,
+ ACS_BW320_2);
+ break;
+ default:
+ wpa_printf(MSG_INFO,
+ "ACS: BW320 offset is not selected");
+ return;
+ }
+
break;
default:
/* TODO: How can this be calculated? Adjust