diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 0754ada73..331c09bc2 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -499,7 +499,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, #endif /* CONFIG_FST */ #ifdef CONFIG_IEEE80211AC - if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { + if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac && + !is_6ghz_op_class(hapd->iconf->op_class)) { pos = hostapd_eid_vht_capabilities(hapd, pos, 0); pos = hostapd_eid_vht_operation(hapd, pos); pos = hostapd_eid_txpower_envelope(hapd, pos); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 2c6004021..401f907f4 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3657,7 +3657,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_IEEE80211AC - if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { + if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac && + !is_6ghz_op_class(hapd->iconf->op_class)) { u32 nsts = 0, sta_nsts; if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) { diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index 42b05d7ee..abd39409e 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -11,6 +11,7 @@ #include "utils/common.h" #include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" #include "hostapd.h" #include "ap_config.h" #include "beacon.h" @@ -170,6 +171,9 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) if (!hapd->iface->current_mode) return eid; + if (is_6ghz_op_class(hapd->iconf->op_class)) + oper_size += 5; + *pos++ = WLAN_EID_EXTENSION; *pos++ = 1 + oper_size; *pos++ = WLAN_EID_EXT_HE_OPERATION; @@ -198,9 +202,26 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) /* TODO: conditional MaxBSSID Indicator subfield */ - oper->he_oper_params = host_to_le32(params); + pos += 6; /* skip the fixed part */ + + if (is_6ghz_op_class(hapd->iconf->op_class)) { + u8 seg0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf); + + if (!seg0) + seg0 = hapd->iconf->channel; - pos += oper_size; + params |= HE_OPERATION_6GHZ_OPER_INFO; + *pos++ = hapd->iconf->channel; /* Primary Channel */ + *pos++ = center_idx_to_bw_6ghz(seg0); /* Control: Channel Width + */ + /* Channel Center Freq Seg0/Seg0 */ + *pos++ = seg0; + *pos++ = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); + /* Minimum Rate */ + *pos++ = 6; /* TODO: what should be set here? */ + } + + oper->he_oper_params = host_to_le32(params); return pos; } diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c index 214855dcc..6db93658c 100644 --- a/src/ap/ieee802_11_ht.c +++ b/src/ap/ieee802_11_ht.c @@ -27,7 +27,7 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) u8 *pos = eid; if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode || - hapd->conf->disable_11n) + hapd->conf->disable_11n || is_6ghz_op_class(hapd->iconf->op_class)) return eid; *pos++ = WLAN_EID_HT_CAP; @@ -84,7 +84,8 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) struct ieee80211_ht_operation *oper; u8 *pos = eid; - if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n) + if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n || + is_6ghz_op_class(hapd->iconf->op_class)) return eid; *pos++ = WLAN_EID_HT_OPERATION; @@ -113,7 +114,8 @@ u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid) u8 sec_ch; if (!hapd->cs_freq_params.channel || - !hapd->cs_freq_params.sec_channel_offset) + !hapd->cs_freq_params.sec_channel_offset || + is_6ghz_op_class(hapd->iconf->op_class)) return eid; if (hapd->cs_freq_params.sec_channel_offset == -1) diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c index 269345fbf..f50f142dc 100644 --- a/src/ap/ieee802_11_vht.c +++ b/src/ap/ieee802_11_vht.c @@ -26,7 +26,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts) struct hostapd_hw_modes *mode = hapd->iface->current_mode; u8 *pos = eid; - if (!mode) + if (!mode || is_6ghz_op_class(hapd->iconf->op_class)) return eid; if (mode->mode == HOSTAPD_MODE_IEEE80211G && hapd->conf->vendor_vht && @@ -76,6 +76,9 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) struct ieee80211_vht_operation *oper; u8 *pos = eid; + if (is_6ghz_op_class(hapd->iconf->op_class)) + return eid; + *pos++ = WLAN_EID_VHT_OPERATION; *pos++ = sizeof(*oper); diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index f75ce1e30..adfdaa797 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -1958,6 +1958,12 @@ int is_6ghz_freq(int freq) } +int is_6ghz_op_class(u8 op_class) +{ + return op_class >= 131 && op_class <= 135; +} + + int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len) { diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index d8b6fa216..3a54aa087 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -222,6 +222,7 @@ const struct oper_class_map * get_oper_class(const char *country, u8 op_class); int oper_class_bw_to_int(const struct oper_class_map *map); int center_idx_to_bw_6ghz(u8 idx); int is_6ghz_freq(int freq); +int is_6ghz_op_class(u8 op_class); int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, size_t nei_rep_len); diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 02cf0ee9b..fbed05119 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2185,6 +2185,10 @@ struct ieee80211_spatial_reuse { BIT(10) | BIT(11) | \ BIT(12) | BIT(13))) #define HE_OPERATION_RTS_THRESHOLD_OFFSET 4 +#define HE_OPERATION_VHT_OPER_INFO ((u32) BIT(14)) +#define HE_OPERATION_COHOSTED_BSS ((u32) BIT(15)) +#define HE_OPERATION_ER_SU_DISABLE ((u32) BIT(16)) +#define HE_OPERATION_6GHZ_OPER_INFO ((u32) BIT(17)) #define HE_OPERATION_BSS_COLOR_MASK ((u32) (BIT(24) | BIT(25) | \ BIT(26) | BIT(27) | \ BIT(28) | BIT(29)))