xref: /freebsd/contrib/wpa/src/ap/ieee802_11_he.c (revision 85732ac8bccbc0adcf5a261ea1ffec8ca7b3a92d)
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