1*85732ac8SCy Schubert /* 2*85732ac8SCy Schubert * hostapd / IEEE 802.11ax HE 3*85732ac8SCy Schubert * Copyright (c) 2016-2017, Qualcomm Atheros, Inc. 4*85732ac8SCy Schubert * 5*85732ac8SCy Schubert * This software may be distributed under the terms of the BSD license. 6*85732ac8SCy Schubert * See README for more details. 7*85732ac8SCy Schubert */ 8*85732ac8SCy Schubert 9*85732ac8SCy Schubert #include "utils/includes.h" 10*85732ac8SCy Schubert 11*85732ac8SCy Schubert #include "utils/common.h" 12*85732ac8SCy Schubert #include "common/ieee802_11_defs.h" 13*85732ac8SCy Schubert #include "hostapd.h" 14*85732ac8SCy Schubert #include "ap_config.h" 15*85732ac8SCy Schubert #include "beacon.h" 16*85732ac8SCy Schubert #include "ieee802_11.h" 17*85732ac8SCy Schubert #include "dfs.h" 18*85732ac8SCy Schubert 19*85732ac8SCy Schubert u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid) 20*85732ac8SCy Schubert { 21*85732ac8SCy Schubert struct ieee80211_he_capabilities *cap; 22*85732ac8SCy Schubert u8 *pos = eid; 23*85732ac8SCy Schubert 24*85732ac8SCy Schubert if (!hapd->iface->current_mode) 25*85732ac8SCy Schubert return eid; 26*85732ac8SCy Schubert 27*85732ac8SCy Schubert *pos++ = WLAN_EID_EXTENSION; 28*85732ac8SCy Schubert *pos++ = 1 + sizeof(struct ieee80211_he_capabilities); 29*85732ac8SCy Schubert *pos++ = WLAN_EID_EXT_HE_CAPABILITIES; 30*85732ac8SCy Schubert 31*85732ac8SCy Schubert cap = (struct ieee80211_he_capabilities *) pos; 32*85732ac8SCy Schubert os_memset(cap, 0, sizeof(*cap)); 33*85732ac8SCy Schubert 34*85732ac8SCy Schubert if (hapd->iface->conf->he_phy_capab.he_su_beamformer) 35*85732ac8SCy Schubert cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |= 36*85732ac8SCy Schubert HE_PHYCAP_SU_BEAMFORMER_CAPAB; 37*85732ac8SCy Schubert 38*85732ac8SCy Schubert if (hapd->iface->conf->he_phy_capab.he_su_beamformee) 39*85732ac8SCy Schubert cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX] |= 40*85732ac8SCy Schubert HE_PHYCAP_SU_BEAMFORMEE_CAPAB; 41*85732ac8SCy Schubert 42*85732ac8SCy Schubert if (hapd->iface->conf->he_phy_capab.he_mu_beamformer) 43*85732ac8SCy Schubert cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] |= 44*85732ac8SCy Schubert HE_PHYCAP_MU_BEAMFORMER_CAPAB; 45*85732ac8SCy Schubert 46*85732ac8SCy Schubert pos += sizeof(*cap); 47*85732ac8SCy Schubert 48*85732ac8SCy Schubert return pos; 49*85732ac8SCy Schubert } 50*85732ac8SCy Schubert 51*85732ac8SCy Schubert 52*85732ac8SCy Schubert u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) 53*85732ac8SCy Schubert { 54*85732ac8SCy Schubert struct ieee80211_he_operation *oper; 55*85732ac8SCy Schubert u8 *pos = eid; 56*85732ac8SCy Schubert 57*85732ac8SCy Schubert if (!hapd->iface->current_mode) 58*85732ac8SCy Schubert return eid; 59*85732ac8SCy Schubert 60*85732ac8SCy Schubert *pos++ = WLAN_EID_EXTENSION; 61*85732ac8SCy Schubert *pos++ = 1 + sizeof(struct ieee80211_he_operation); 62*85732ac8SCy Schubert *pos++ = WLAN_EID_EXT_HE_OPERATION; 63*85732ac8SCy Schubert 64*85732ac8SCy Schubert oper = (struct ieee80211_he_operation *) pos; 65*85732ac8SCy Schubert os_memset(oper, 0, sizeof(*oper)); 66*85732ac8SCy Schubert 67*85732ac8SCy Schubert if (hapd->iface->conf->he_op.he_bss_color) 68*85732ac8SCy Schubert oper->he_oper_params |= hapd->iface->conf->he_op.he_bss_color; 69*85732ac8SCy Schubert 70*85732ac8SCy Schubert if (hapd->iface->conf->he_op.he_default_pe_duration) 71*85732ac8SCy Schubert oper->he_oper_params |= 72*85732ac8SCy Schubert (hapd->iface->conf->he_op.he_default_pe_duration << 73*85732ac8SCy Schubert HE_OPERATION_DFLT_PE_DURATION_OFFSET); 74*85732ac8SCy Schubert 75*85732ac8SCy Schubert if (hapd->iface->conf->he_op.he_twt_required) 76*85732ac8SCy Schubert oper->he_oper_params |= HE_OPERATION_TWT_REQUIRED; 77*85732ac8SCy Schubert 78*85732ac8SCy Schubert if (hapd->iface->conf->he_op.he_rts_threshold) 79*85732ac8SCy Schubert oper->he_oper_params |= 80*85732ac8SCy Schubert (hapd->iface->conf->he_op.he_rts_threshold << 81*85732ac8SCy Schubert HE_OPERATION_RTS_THRESHOLD_OFFSET); 82*85732ac8SCy Schubert 83*85732ac8SCy Schubert /* TODO: conditional MaxBSSID Indicator subfield */ 84*85732ac8SCy Schubert 85*85732ac8SCy Schubert pos += sizeof(*oper); 86*85732ac8SCy Schubert 87*85732ac8SCy Schubert return pos; 88*85732ac8SCy Schubert } 89