diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 47ced9a16..22e672c8d 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -463,6 +463,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, 3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_spatial_reuse); + if (is_6ghz_op_class(hapd->iconf->op_class)) + buflen += sizeof(struct ieee80211_he_6ghz_oper_info) + + 3 + sizeof(struct ieee80211_he_6ghz_band_cap); } #endif /* CONFIG_IEEE80211AX */ @@ -570,6 +573,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_he_operation(hapd, pos); pos = hostapd_eid_spatial_reuse(hapd, pos); pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos); + pos = hostapd_eid_he_6ghz_band_cap(hapd, pos); } #endif /* CONFIG_IEEE80211AX */ @@ -1161,6 +1165,9 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, 3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_spatial_reuse); + if (is_6ghz_op_class(hapd->iconf->op_class)) + tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) + + 3 + sizeof(struct ieee80211_he_6ghz_band_cap); } #endif /* CONFIG_IEEE80211AX */ @@ -1288,6 +1295,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_he_operation(hapd, tailpos); tailpos = hostapd_eid_spatial_reuse(hapd, tailpos); tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos); + tailpos = hostapd_eid_he_6ghz_band_cap(hapd, tailpos); } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 3e1896cf1..3a7c9a2b9 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3786,6 +3786,7 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, p = hostapd_eid_he_operation(hapd, p); p = hostapd_eid_spatial_reuse(hapd, p); p = hostapd_eid_he_mu_edca_parameter_set(hapd, p); + p = hostapd_eid_he_6ghz_band_cap(hapd, p); } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index c7bdb4b2b..ba5056289 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -63,6 +63,7 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_spatial_reuse(struct hostapd_data *hapd, u8 *eid); +u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid); int hostapd_ht_operation_update(struct hostapd_iface *iface); void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index 57c6b18f4..3267a9d67 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -311,6 +311,54 @@ u8 * hostapd_eid_spatial_reuse(struct hostapd_data *hapd, u8 *eid) } +u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid) +{ + struct hostapd_hw_modes *mode = hapd->iface->current_mode; + struct ieee80211_he_6ghz_band_cap *cap; + u32 vht_cap; + u8 ht_info; + u8 params; + u8 *pos; + + if (!mode || !is_6ghz_op_class(hapd->iconf->op_class)) + return eid; + + vht_cap = hapd->iface->conf->vht_capab; + ht_info = mode->a_mpdu_params; + + pos = eid; + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 1 + sizeof(*cap); + *pos++ = WLAN_EID_EXT_HE_6GHZ_BAND_CAP; + + /* Minimum MPDU Start Spacing B0..B2 */ + params = (ht_info >> 2) & HE_6GHZ_BAND_CAP_MIN_MPDU_START_SPACE_MASK; + + /* Maximum A-MPDU Length Exponent B3..B5 */ + params |= ((((vht_cap & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >> + VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT) & + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) << + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); + + /* Maximum MPDU Length B6..B7 */ + params |= ((((vht_cap & VHT_CAP_MAX_MPDU_LENGTH_MASK) >> + VHT_CAP_MAX_MPDU_LENGTH_MASK_SHIFT) & + HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_MASK) << + HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_SHIFT); + + cap = (struct ieee80211_he_6ghz_band_cap *) pos; + cap->a_mpdu_params = params; + cap->info = HE_6GHZ_BAND_CAP_SMPS_DISABLED; + if (vht_cap & VHT_CAP_RX_ANTENNA_PATTERN) + cap->info |= HE_6GHZ_BAND_CAP_RX_ANTENNA_PATTERN; + if (vht_cap & VHT_CAP_TX_ANTENNA_PATTERN) + cap->info |= HE_6GHZ_BAND_CAP_TX_ANTENNA_PATTERN; + pos += sizeof(*cap); + + return pos; +} + + void hostapd_get_he_capab(struct hostapd_data *hapd, const struct ieee80211_he_capabilities *he_cap, struct ieee80211_he_capabilities *neg_he_cap,