1ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt/*
2ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt * hostapd / IEEE 802.11ax HE
3ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt * Copyright (c) 2016-2017, Qualcomm Atheros, Inc.
4ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt *
5ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt * This software may be distributed under the terms of the BSD license.
6ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt * See README for more details.
7ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt */
8ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
9ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "utils/includes.h"
10ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
11ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "utils/common.h"
12ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "common/ieee802_11_defs.h"
13ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "common/qca-vendor.h"
14ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "hostapd.h"
15ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "ap_config.h"
16ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "beacon.h"
17ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "ieee802_11.h"
18ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "dfs.h"
19ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
20ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidtu8 * hostapd_eid_vendor_he_capab(struct hostapd_data *hapd, u8 *eid)
21ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt{
22ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	struct ieee80211_he_capabilities *cap;
23ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	u8 *pos = eid;
24ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
25ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (!hapd->iface->current_mode)
26ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		return eid;
27ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
28ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	/* For now, use a vendor specific element since the P802.11ax draft is
29ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * still subject to changes and the contents of this element may change.
30ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * This can be replaced with the actual element once P802.11ax is
31ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * finalized. */
32ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	/* Vendor HE Capabilities element */
33ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
34ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	*pos++ = 4 /* The Vendor OUI, subtype */ +
35ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		sizeof(struct ieee80211_he_capabilities);
36ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
37ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	WPA_PUT_BE32(pos, (OUI_QCA << 8) | QCA_VENDOR_ELEM_HE_CAPAB);
38ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	pos += 4;
39ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	cap = (struct ieee80211_he_capabilities *) pos;
40ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	os_memset(cap, 0, sizeof(*cap));
41ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
42ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_phy_capab.he_su_beamformer)
43ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |=
44ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			HE_PHYCAP_SU_BEAMFORMER_CAPAB;
45ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
46ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_phy_capab.he_su_beamformee)
47ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX] |=
48ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			HE_PHYCAP_SU_BEAMFORMEE_CAPAB;
49ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
50ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_phy_capab.he_mu_beamformer)
51ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] |=
52ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			HE_PHYCAP_MU_BEAMFORMER_CAPAB;
53ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
54ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	pos += sizeof(*cap);
55ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
56ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	return pos;
57ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt}
58ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
59ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
60ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidtu8 * hostapd_eid_vendor_he_operation(struct hostapd_data *hapd, u8 *eid)
61ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt{
62ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	struct ieee80211_he_operation *oper;
63ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	u8 *pos = eid;
64ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
65ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (!hapd->iface->current_mode)
66ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		return eid;
67ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
68ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	/* For now, use a vendor specific element since the P802.11ax draft is
69ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * still subject to changes and the contents of this element may change.
70ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * This can be replaced with the actual element once P802.11ax is
71ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	 * finalized. */
72ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	/* Vendor HE Operation element */
73ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
74ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	*pos++ = 4 /* The Vendor OUI, subtype */ +
75ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		sizeof(struct ieee80211_he_operation);
76ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
77ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	WPA_PUT_BE32(pos, (OUI_QCA << 8) | QCA_VENDOR_ELEM_HE_OPER);
78ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	pos += 4;
79ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	oper = (struct ieee80211_he_operation *) pos;
80ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	os_memset(oper, 0, sizeof(*oper));
81ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
82ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_op.he_bss_color)
83ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		oper->he_oper_params |= hapd->iface->conf->he_op.he_bss_color;
84ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
85ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_op.he_default_pe_duration)
86ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		oper->he_oper_params |=
87ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			(hapd->iface->conf->he_op.he_default_pe_duration <<
88ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			 HE_OPERATION_DFLT_PE_DURATION_OFFSET);
89ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
90ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_op.he_twt_required)
91ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		oper->he_oper_params |= HE_OPERATION_TWT_REQUIRED;
92ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
93ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	if (hapd->iface->conf->he_op.he_rts_threshold)
94ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt		oper->he_oper_params |=
95ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			(hapd->iface->conf->he_op.he_rts_threshold <<
96ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt			 HE_OPERATION_RTS_THRESHOLD_OFFSET);
97ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
98ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	pos += sizeof(*oper);
99ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt
100ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt	return pos;
101ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt}
102