]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - src/ap/beacon.c
HT: Remove SMPS in AP mode
[thirdparty/hostap.git] / src / ap / beacon.c
index 0570ab721fc6cb1af695f46ebdd571742e18c98d..0bab464c2dc3b6778f8d30ac9815d9a58de46b37 100644 (file)
@@ -16,6 +16,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/hw_features_common.h"
+#include "common/wpa_ctrl.h"
 #include "wps/wps_defs.h"
 #include "p2p/p2p.h"
 #include "hostapd.h"
 #include "beacon.h"
 #include "hs20.h"
 #include "dfs.h"
+#include "taxonomy.h"
+#include "ieee802_11_auth.h"
 
 
 #ifdef NEED_AP_MLME
 
-static u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
-                                        size_t len)
-{
-       size_t i;
-
-       for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
-               if (hapd->conf->radio_measurements[i])
-                       break;
-       }
-
-       if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
-               return eid;
-
-       *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
-       *eid++ = RRM_CAPABILITIES_IE_LEN;
-       os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
-
-       return eid + RRM_CAPABILITIES_IE_LEN;
-}
-
-
 static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
 {
        if (len < 2 + 5)
@@ -344,7 +326,7 @@ static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
 
        if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
                                          hapd->iconf->secondary_channel,
-                                         hapd->iconf->vht_oper_chwidth,
+                                         hostapd_get_oper_chwidth(hapd->iconf),
                                          &op_class, &channel) ==
            NUM_HOSTAPD_MODES)
                return eid;
@@ -391,7 +373,17 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
                        2 + sizeof(struct ieee80211_vht_operation);
        }
 
+#ifdef CONFIG_IEEE80211AX
+       if (hapd->iconf->ieee80211ax) {
+               buflen += 3 + sizeof(struct ieee80211_he_capabilities) +
+                       3 + sizeof(struct ieee80211_he_operation) +
+                       3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
+                       3 + sizeof(struct ieee80211_spatial_reuse);
+       }
+#endif /* CONFIG_IEEE80211AX */
+
        buflen += hostapd_mbo_ie_len(hapd);
+       buflen += hostapd_eid_owe_trans_len(hapd);
 
        resp = os_zalloc(buflen);
        if (resp == NULL)
@@ -442,8 +434,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        /* Extended supported rates */
        pos = hostapd_eid_ext_supp_rates(hapd, pos);
 
-       /* RSN, MDIE, WPA */
-       pos = hostapd_eid_wpa(hapd, pos, epos - pos);
+       /* RSN, MDIE */
+       if (!(hapd->conf->wpa == WPA_PROTO_WPA ||
+             (hapd->conf->osen && !hapd->conf->wpa)))
+               pos = hostapd_eid_wpa(hapd, pos, epos - pos);
 
        pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
 
@@ -484,16 +478,36 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 #endif /* CONFIG_FST */
 
 #ifdef CONFIG_IEEE80211AC
-       if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-               pos = hostapd_eid_vht_capabilities(hapd, pos);
+       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);
                pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
        }
+#endif /* CONFIG_IEEE80211AC */
+
+       pos = hostapd_eid_fils_indic(hapd, pos, 0);
+
+#ifdef CONFIG_IEEE80211AX
+       if (hapd->iconf->ieee80211ax) {
+               pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
+               pos = hostapd_eid_he_operation(hapd, pos);
+               pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos);
+               pos = hostapd_eid_spatial_reuse(hapd, pos);
+       }
+#endif /* CONFIG_IEEE80211AX */
+
+#ifdef CONFIG_IEEE80211AC
        if (hapd->conf->vendor_vht)
                pos = hostapd_eid_vendor_vht(hapd, pos);
 #endif /* CONFIG_IEEE80211AC */
 
+       /* WPA */
+       if (hapd->conf->wpa == WPA_PROTO_WPA ||
+           (hapd->conf->osen && !hapd->conf->wpa))
+               pos = hostapd_eid_wpa(hapd, pos, epos - pos);
+
        /* Wi-Fi Alliance WMM */
        pos = hostapd_eid_wmm(hapd, pos);
 
@@ -521,10 +535,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 
 #ifdef CONFIG_HS20
        pos = hostapd_eid_hs20_indication(hapd, pos);
-       pos = hostapd_eid_osen(hapd, pos);
 #endif /* CONFIG_HS20 */
 
        pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
+       pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
 
        if (hapd->conf->vendor_elements) {
                os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
@@ -546,7 +560,9 @@ enum ssid_match_result {
 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
                                         const u8 *ssid, size_t ssid_len,
                                         const u8 *ssid_list,
-                                        size_t ssid_list_len)
+                                        size_t ssid_list_len,
+                                        const u8 *short_ssid_list,
+                                        size_t short_ssid_list_len)
 {
        const u8 *pos, *end;
        int wildcard = 0;
@@ -557,20 +573,30 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
            os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
                return EXACT_SSID_MATCH;
 
-       if (ssid_list == NULL)
-               return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
+       if (ssid_list) {
+               pos = ssid_list;
+               end = ssid_list + ssid_list_len;
+               while (end - pos >= 2) {
+                       if (2 + pos[1] > end - pos)
+                               break;
+                       if (pos[1] == 0)
+                               wildcard = 1;
+                       if (pos[1] == hapd->conf->ssid.ssid_len &&
+                           os_memcmp(pos + 2, hapd->conf->ssid.ssid,
+                                     pos[1]) == 0)
+                               return EXACT_SSID_MATCH;
+                       pos += 2 + pos[1];
+               }
+       }
 
-       pos = ssid_list;
-       end = ssid_list + ssid_list_len;
-       while (end - pos >= 1) {
-               if (2 + pos[1] > end - pos)
-                       break;
-               if (pos[1] == 0)
-                       wildcard = 1;
-               if (pos[1] == hapd->conf->ssid.ssid_len &&
-                   os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
-                       return EXACT_SSID_MATCH;
-               pos += 2 + pos[1];
+       if (short_ssid_list) {
+               pos = short_ssid_list;
+               end = short_ssid_list + short_ssid_list_len;
+               while (end - pos >= 4) {
+                       if (hapd->conf->ssid.short_ssid == WPA_GET_LE32(pos))
+                               return EXACT_SSID_MATCH;
+                       pos += 4;
+               }
        }
 
        return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
@@ -599,7 +625,7 @@ void sta_track_expire(struct hostapd_iface *iface, int force)
                           MAC2STR(info->addr));
                dl_list_del(&info->list);
                iface->num_sta_seen--;
-               os_free(info);
+               sta_track_del(info);
        }
 }
 
@@ -617,7 +643,7 @@ static struct hostapd_sta_info * sta_track_get(struct hostapd_iface *iface,
 }
 
 
-void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
+void sta_track_add(struct hostapd_iface *iface, const u8 *addr, int ssi_signal)
 {
        struct hostapd_sta_info *info;
 
@@ -627,13 +653,17 @@ void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
                dl_list_del(&info->list);
                dl_list_add_tail(&iface->sta_seen, &info->list);
                os_get_reltime(&info->last_seen);
+               info->ssi_signal = ssi_signal;
                return;
        }
 
        /* Add a new entry */
        info = os_zalloc(sizeof(*info));
+       if (info == NULL)
+               return;
        os_memcpy(info->addr, addr, ETH_ALEN);
        os_get_reltime(&info->last_seen);
+       info->ssi_signal = ssi_signal;
 
        if (iface->num_sta_seen >= iface->conf->track_sta_max_num) {
                /* Expire oldest entry to make room for a new one */
@@ -673,6 +703,23 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
 }
 
 
+#ifdef CONFIG_TAXONOMY
+void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
+                                  struct wpabuf **probe_ie_taxonomy)
+{
+       struct hostapd_sta_info *info;
+
+       info = sta_track_get(iface, addr);
+       if (!info)
+               return;
+
+       wpabuf_free(*probe_ie_taxonomy);
+       *probe_ie_taxonomy = info->probe_ie_taxonomy;
+       info->probe_ie_taxonomy = NULL;
+}
+#endif /* CONFIG_TAXONOMY */
+
+
 void handle_probe_req(struct hostapd_data *hapd,
                      const struct ieee80211_mgmt *mgmt, size_t len,
                      int ssi_signal)
@@ -687,21 +734,31 @@ void handle_probe_req(struct hostapd_data *hapd,
        int ret;
        u16 csa_offs[2];
        size_t csa_offs_len;
+       struct radius_sta rad_info;
 
        if (len < IEEE80211_HDRLEN)
                return;
        ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
        if (hapd->iconf->track_sta_max_num)
-               sta_track_add(hapd->iface, mgmt->sa);
+               sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
        ie_len = len - IEEE80211_HDRLEN;
 
+       ret = hostapd_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
+                                     &rad_info, 1);
+       if (ret == HOSTAPD_ACL_REJECT) {
+               wpa_msg(hapd->msg_ctx, MSG_DEBUG,
+                       "Ignore Probe Request frame from " MACSTR
+                       " due to ACL reject ", MAC2STR(mgmt->sa));
+               return;
+       }
+
        for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
                if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
                                            mgmt->sa, mgmt->da, mgmt->bssid,
                                            ie, ie_len, ssi_signal) > 0)
                        return;
 
-       if (!hapd->iconf->send_probe_response)
+       if (!hapd->conf->send_probe_response)
                return;
 
        if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
@@ -766,7 +823,7 @@ void handle_probe_req(struct hostapd_data *hapd,
 #endif /* CONFIG_P2P */
 
        if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
-           elems.ssid_list_len == 0) {
+           elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
                wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
                           "broadcast SSID ignored", MAC2STR(mgmt->sa));
                return;
@@ -782,8 +839,24 @@ void handle_probe_req(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_TAXONOMY
+       {
+               struct sta_info *sta;
+               struct hostapd_sta_info *info;
+
+               if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
+                       taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
+               } else if ((info = sta_track_get(hapd->iface,
+                                                mgmt->sa)) != NULL) {
+                       taxonomy_hostapd_sta_info_probe_req(hapd, info,
+                                                           ie, ie_len);
+               }
+       }
+#endif /* CONFIG_TAXONOMY */
+
        res = ssid_match(hapd, elems.ssid, elems.ssid_len,
-                        elems.ssid_list, elems.ssid_list_len);
+                        elems.ssid_list, elems.ssid_list_len,
+                        elems.short_ssid_list, elems.short_ssid_list_len);
        if (res == NO_SSID_MATCH) {
                if (!(mgmt->da[0] & 0x01)) {
                        wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
@@ -796,6 +869,12 @@ void handle_probe_req(struct hostapd_data *hapd,
                return;
        }
 
+       if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
+               wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
+                          "broadcast SSID ignored", MAC2STR(mgmt->sa));
+               return;
+       }
+
 #ifdef CONFIG_INTERWORKING
        if (hapd->conf->interworking &&
            elems.interworking && elems.interworking_len >= 1) {
@@ -874,6 +953,9 @@ void handle_probe_req(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_TESTING_OPTIONS */
 
+       wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
+                    " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
+
        resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
                                      &resp_len);
        if (resp == NULL)
@@ -897,9 +979,9 @@ void handle_probe_req(struct hostapd_data *hapd,
                                hapd->cs_c_off_ecsa_proberesp;
        }
 
-       ret = hostapd_drv_send_mlme_csa(hapd, resp, resp_len, noack,
-                                       csa_offs_len ? csa_offs : NULL,
-                                       csa_offs_len);
+       ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack,
+                                   csa_offs_len ? csa_offs : NULL,
+                                   csa_offs_len, 0);
 
        if (ret < 0)
                wpa_printf(MSG_INFO, "handle_probe_req: send failed");
@@ -950,6 +1032,16 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
 #endif /* NEED_AP_MLME */
 
 
+void sta_track_del(struct hostapd_sta_info *info)
+{
+#ifdef CONFIG_TAXONOMY
+       wpabuf_free(info->probe_ie_taxonomy);
+       info->probe_ie_taxonomy = NULL;
+#endif /* CONFIG_TAXONOMY */
+       os_free(info);
+}
+
+
 int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                               struct wpa_driver_ap_params *params)
 {
@@ -988,7 +1080,17 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_IEEE80211AC */
 
+#ifdef CONFIG_IEEE80211AX
+       if (hapd->iconf->ieee80211ax) {
+               tail_len += 3 + sizeof(struct ieee80211_he_capabilities) +
+                       3 + sizeof(struct ieee80211_he_operation) +
+                       3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
+                       3 + sizeof(struct ieee80211_spatial_reuse);
+       }
+#endif /* CONFIG_IEEE80211AX */
+
        tail_len += hostapd_mbo_ie_len(hapd);
+       tail_len += hostapd_eid_owe_trans_len(hapd);
 
        tailpos = tail = os_malloc(tail_len);
        if (head == NULL || tail == NULL) {
@@ -1055,9 +1157,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        /* Extended supported rates */
        tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
 
-       /* RSN, MDIE, WPA */
-       tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
-                                 tailpos);
+       /* RSN, MDIE */
+       if (!(hapd->conf->wpa == WPA_PROTO_WPA ||
+             (hapd->conf->osen && !hapd->conf->wpa)))
+               tailpos = hostapd_eid_wpa(hapd, tailpos,
+                                         tail + BEACON_TAIL_BUF_SIZE -
+                                         tailpos);
 
        tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
                                               tail + BEACON_TAIL_BUF_SIZE -
@@ -1105,15 +1210,37 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211AC
        if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-               tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
+               tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
                tailpos = hostapd_eid_vht_operation(hapd, tailpos);
                tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
                tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
        }
+#endif /* CONFIG_IEEE80211AC */
+
+       tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
+
+#ifdef CONFIG_IEEE80211AX
+       if (hapd->iconf->ieee80211ax) {
+               tailpos = hostapd_eid_he_capab(hapd, tailpos,
+                                              IEEE80211_MODE_AP);
+               tailpos = hostapd_eid_he_operation(hapd, tailpos);
+               tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos);
+               tailpos = hostapd_eid_spatial_reuse(hapd, tailpos);
+       }
+#endif /* CONFIG_IEEE80211AX */
+
+#ifdef CONFIG_IEEE80211AC
        if (hapd->conf->vendor_vht)
                tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
 #endif /* CONFIG_IEEE80211AC */
 
+       /* WPA */
+       if (hapd->conf->wpa == WPA_PROTO_WPA ||
+           (hapd->conf->osen && !hapd->conf->wpa))
+               tailpos = hostapd_eid_wpa(hapd, tailpos,
+                                         tail + BEACON_TAIL_BUF_SIZE -
+                                         tailpos);
+
        /* Wi-Fi Alliance WMM */
        tailpos = hostapd_eid_wmm(hapd, tailpos);
 
@@ -1140,10 +1267,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
 #ifdef CONFIG_HS20
        tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
-       tailpos = hostapd_eid_osen(hapd, tailpos);
 #endif /* CONFIG_HS20 */
 
        tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
+       tailpos = hostapd_eid_owe_trans(hapd, tailpos,
+                                       tail + tail_len - tailpos);
 
        if (hapd->conf->vendor_elements) {
                os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
@@ -1166,6 +1294,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        params->dtim_period = hapd->conf->dtim_period;
        params->beacon_int = hapd->iconf->beacon_int;
        params->basic_rates = hapd->iface->basic_rates;
+       params->beacon_rate = hapd->iconf->beacon_rate;
+       params->rate_type = hapd->iconf->rate_type;
        params->ssid = hapd->conf->ssid.ssid;
        params->ssid_len = hapd->conf->ssid.ssid_len;
        if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
@@ -1196,7 +1326,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                break;
        }
        params->isolate = hapd->conf->isolate;
-       params->smps_mode = hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_MASK;
 #ifdef NEED_AP_MLME
        params->cts_protect = !!(ieee802_11_erp_info(hapd) &
                                ERP_INFO_USE_PROTECTION);
@@ -1229,7 +1358,20 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                params->osen = 1;
        }
 #endif /* CONFIG_HS20 */
+       params->multicast_to_unicast = hapd->conf->multicast_to_unicast;
        params->pbss = hapd->conf->pbss;
+
+       if (hapd->conf->ftm_responder) {
+               if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_FTM_RESPONDER) {
+                       params->ftm_responder = 1;
+                       params->lci = hapd->iface->conf->lci;
+                       params->civic = hapd->iface->conf->civic;
+               } else {
+                       wpa_printf(MSG_WARNING,
+                                  "Not configuring FTM responder as the driver doesn't advertise support for it");
+               }
+       }
+
        return 0;
 }
 
@@ -1251,6 +1393,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
        struct hostapd_freq_params freq;
        struct hostapd_iface *iface = hapd->iface;
        struct hostapd_config *iconf = iface->conf;
+       struct hostapd_hw_modes *cmode = iface->current_mode;
        struct wpabuf *beacon, *proberesp, *assocresp;
        int res, ret = -1;
 
@@ -1272,17 +1415,28 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
        params.proberesp_ies = proberesp;
        params.assocresp_ies = assocresp;
        params.reenable = hapd->reenable_beacon;
+#ifdef CONFIG_IEEE80211AX
+       params.he_spr = !!hapd->iface->conf->spr.sr_control;
+       params.he_spr_srg_obss_pd_min_offset =
+               hapd->iface->conf->spr.srg_obss_pd_min_offset;
+       params.he_spr_srg_obss_pd_max_offset =
+               hapd->iface->conf->spr.srg_obss_pd_max_offset;
+       params.twt_responder = hostapd_get_he_twt_responder(hapd,
+                                                           IEEE80211_MODE_AP);
+#endif /* CONFIG_IEEE80211AX */
        hapd->reenable_beacon = 0;
 
-       if (iface->current_mode &&
+       if (cmode &&
            hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
-                                   iconf->channel, iconf->ieee80211n,
-                                   iconf->ieee80211ac,
+                                   iconf->channel, iconf->enable_edmg,
+                                   iconf->edmg_channel, iconf->ieee80211n,
+                                   iconf->ieee80211ac, iconf->ieee80211ax,
                                    iconf->secondary_channel,
-                                   iconf->vht_oper_chwidth,
-                                   iconf->vht_oper_centr_freq_seg0_idx,
-                                   iconf->vht_oper_centr_freq_seg1_idx,
-                                   iface->current_mode->vht_capab) == 0)
+                                   hostapd_get_oper_chwidth(iconf),
+                                   hostapd_get_oper_centr_freq_seg0_idx(iconf),
+                                   hostapd_get_oper_centr_freq_seg1_idx(iconf),
+                                   cmode->vht_capab,
+                                   &cmode->he_capab[IEEE80211_MODE_AP]) == 0)
                params.freq = &freq;
 
        res = hostapd_drv_set_ap(hapd, &params);