line);
return 1;
}
+ } else if (os_strcmp(buf, "eht_bw320_offset") == 0) {
+ conf->eht_bw320_offset = atoi(pos);
#ifdef CONFIG_TESTING_OPTIONS
} else if (os_strcmp(buf, "eht_oper_puncturing_override") == 0) {
if (get_u16(pos, line, &bss->eht_oper_puncturing_override))
# 1 = PE field duration is 20 us
#eht_default_pe_duration=0
+#eht_bw320_offset: For automatic channel selection (ACS) to indicate a preferred
+# 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 (channel center frequency 31, 95, 159)
+# 2 = 320 MHz-2 (channel center frequency 63, 127, 191)
+#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
conf->airtime_update_interval = AIRTIME_DEFAULT_UPDATE_INTERVAL;
#endif /* CONFIG_AIRTIME_POLICY */
+ hostapd_set_and_check_bw320_offset(conf, 0);
+
return conf;
}
"Cannot set ieee80211be without ieee80211ax");
return -1;
}
+
+ if (full_config)
+ hostapd_set_and_check_bw320_offset(conf,
+ conf->eht_bw320_offset);
#endif /* CONFIG_IEEE80211BE */
if (full_config && conf->mbssid && !conf->ieee80211ax) {
u16 punct_bitmap; /* a bitmap of disabled 20 MHz channels */
u8 punct_acs_threshold;
u8 eht_default_pe_duration;
+ u8 eht_bw320_offset;
#endif /* CONFIG_IEEE80211BE */
/* EHT enable/disable config from CHAN_SWITCH */
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) &&
+ op_class_to_ch_width(conf->op_class) == 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
+ * preferred offset of 320 MHz.
+ */
+ conf->eht_bw320_offset = bw320_offset;
+ }
+ } else {
+ conf->eht_bw320_offset = 0;
+ }
+#endif /* CONFIG_IEEE80211BE */
+}
+
int hostapd_mac_comp(const void *a, const void *b);
struct hostapd_config * hostapd_config_defaults(void);
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 */
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 */