blob: 77677d04564575c735b06f2dee40f97183d64683 [file] [log] [blame]
From cb9841c4361d5c1d236b7d257e2d513ecc1c7c91 Mon Sep 17 00:00:00 2001
From: Michael-CY Lee <michael-cy.lee@mediatek.com>
Date: Tue, 17 Oct 2023 11:11:40 +0800
Subject: [PATCH 53/54] mtk: hostapd: add eht_bw320_offset configuration option
This patch introduces a new configuration option, "eht_bw320_offset",
which enables devices to specify a preferred channelization for 320 MHz
BSSs when using automatic channel selection (ACS).
This option is only applicable when the channel is not already decided
and the bandwidth is set to 320 MHz.
The value and meaning of the option:
0: auto-detected by hostapd
1: 320 MHz-1
2: 320 MHz-2
Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
---
hostapd/config_file.c | 3 +++
hostapd/hostapd.conf | 8 ++++++++
src/ap/ap_config.c | 6 ++++++
src/ap/ap_config.h | 37 +++++++++++++++++++++++++++++++++++++
src/ap/ctrl_iface_ap.c | 11 +++++++++++
src/ap/drv_callbacks.c | 2 ++
6 files changed, 67 insertions(+)
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 278f6b347..721685baf 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -4822,6 +4822,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line);
return 1;
}
+ } else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
+ u8 val = atoi(pos);
+ conf->eht_bw320_offset = val;
#endif /* CONFIG_IEEE80211BE */
} else if (os_strcmp(buf, "edcca_threshold") == 0) {
if (hostapd_parse_intlist(&conf->edcca_threshold, pos) ||
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index f16e3b08d..290504317 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -1032,6 +1032,14 @@ wmm_ac_vo_acm=0
#eht_oper_chwidth (see vht_oper_chwidth)
#eht_oper_centr_freq_seg0_idx
+#eht_bw320_offset: For automatic channel selection (ACS) to indicate a prefered
+# 320 MHz channelization in EHT mode.
+# If the channel is decided or the bandwidth is not 320 MHz, this option is meaningless.
+# 0 = auto-detect by hostapd
+# 1 = 320 MHz-1
+# 2 = 320 MHz-2
+#eht_bw320_offset=0
+
# Disabled subchannel bitmap (16 bits) as per IEEE P802.11be/3.0,
# Figure 9-1002c (EHT Operation Information field format). Each bit corresponds
# to a 20 MHz channel, the lowest bit corresponds to the lowest frequency. A
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index d8dd5495a..3fb98d08f 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -304,6 +304,7 @@ struct hostapd_config * hostapd_config_defaults(void)
conf->amsdu = 1;
conf->pp_mode = PP_DISABLE;
+ hostapd_set_and_check_bw320_offset(conf, 0);
return conf;
}
@@ -1515,6 +1516,7 @@ static int hostapd_config_check_cw(struct hostapd_config *conf, int queue)
int hostapd_config_check(struct hostapd_config *conf, int full_config)
{
size_t i;
+ u8 bw320_offset = 0;
if (full_config && is_6ghz_op_class(conf->op_class) &&
!conf->hw_mode_set) {
@@ -1566,6 +1568,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
"Cannot set ieee80211be without ieee80211ax");
return -1;
}
+
+ bw320_offset = conf->eht_bw320_offset;
#endif /* CONFIG_IEEE80211BE */
if (full_config && conf->mbssid && !conf->ieee80211ax) {
@@ -1574,6 +1578,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config)
return -1;
}
+ hostapd_set_and_check_bw320_offset(conf, bw320_offset);
+
for (i = 0; i < conf->num_bss; i++) {
if (hostapd_config_check_bss(conf->bss[i], conf, full_config))
return -1;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 9e39e8285..3e0505594 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1184,6 +1184,7 @@ struct hostapd_config {
struct eht_phy_capabilities_info eht_phy_capab;
u16 punct_bitmap; /* a bitmap of disabled 20 MHz channels */
u8 punct_acs_threshold;
+ u8 eht_bw320_offset;
#endif /* CONFIG_IEEE80211BE */
/* EHT enable/disable config from CHAN_SWITCH */
@@ -1355,6 +1356,42 @@ hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
conf->vht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
}
+static inline u8
+hostapd_get_bw320_offset(struct hostapd_config *conf)
+{
+#ifdef CONFIG_IEEE80211BE
+ if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
+ hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ)
+ return conf->eht_bw320_offset;
+#endif /* CONFIG_IEEE80211BE */
+ return 0;
+}
+
+static inline void
+hostapd_set_and_check_bw320_offset(struct hostapd_config *conf,
+ u8 bw320_offset)
+{
+#ifdef CONFIG_IEEE80211BE
+ if (conf->ieee80211be && is_6ghz_op_class(conf->op_class) &&
+ hostapd_get_oper_chwidth(conf) == CONF_OPER_CHWIDTH_320MHZ) {
+ if (conf->channel) {
+ /* If the channel is set, then calculate bw320_offset
+ * by center frequency segment 0.
+ */
+ u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf);
+ conf->eht_bw320_offset = (seg0 - 31) % 64 ? 2 : 1;
+ } else {
+ /* If the channel is not set, bw320_offset indicates
+ * prefered offset of 320 MHz.
+ */
+ conf->eht_bw320_offset = bw320_offset;
+ }
+ } else {
+ conf->eht_bw320_offset = 0;
+ }
+#endif /* CONFIG_IEEE80211BE */
+}
+
#define IBF_DEFAULT_ENABLE 0
int hostapd_mac_comp(const void *a, const void *b);
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index 7bdefb4cf..e686fb8b7 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -831,6 +831,17 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
+
+ if (is_6ghz_op_class(iface->conf->op_class) &&
+ hostapd_get_oper_chwidth(iface->conf) ==
+ CONF_OPER_CHWIDTH_320MHZ) {
+ ret = os_snprintf(buf + len, buflen - len,
+ "eht_bw320_offset=%d\n",
+ iface->conf->eht_bw320_offset);
+ if (os_snprintf_error(buflen - len, ret))
+ return len;
+ len += ret;
+ }
}
#endif /* CONFIG_IEEE80211BE */
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 12419c6d4..b0d9420e8 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -1175,6 +1175,8 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
hostapd_set_oper_chwidth(hapd->iconf, chwidth);
hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
+ /* Auto-detect new bw320_offset */
+ hostapd_set_and_check_bw320_offset(hapd->iconf, 0);
#ifdef CONFIG_IEEE80211BE
hapd->iconf->punct_bitmap = punct_bitmap;
#endif /* CONFIG_IEEE80211BE */
--
2.18.0