xref: /linux/include/linux/ieee80211-he.h (revision 8f7aa3d3c7323f4ca2768a9e74ebbe359c4f8f88)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * IEEE 802.11 HE definitions
4  *
5  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6  * <jkmaline@cc.hut.fi>
7  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8  * Copyright (c) 2005, Devicescape Software, Inc.
9  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
10  * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
11  * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
12  * Copyright (c) 2018 - 2025 Intel Corporation
13  */
14 
15 #ifndef LINUX_IEEE80211_HE_H
16 #define LINUX_IEEE80211_HE_H
17 
18 #include <linux/types.h>
19 #include <linux/if_ether.h>
20 
21 #define IEEE80211_TWT_CONTROL_NDP			BIT(0)
22 #define IEEE80211_TWT_CONTROL_RESP_MODE			BIT(1)
23 #define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST	BIT(3)
24 #define IEEE80211_TWT_CONTROL_RX_DISABLED		BIT(4)
25 #define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT		BIT(5)
26 
27 #define IEEE80211_TWT_REQTYPE_REQUEST			BIT(0)
28 #define IEEE80211_TWT_REQTYPE_SETUP_CMD			GENMASK(3, 1)
29 #define IEEE80211_TWT_REQTYPE_TRIGGER			BIT(4)
30 #define IEEE80211_TWT_REQTYPE_IMPLICIT			BIT(5)
31 #define IEEE80211_TWT_REQTYPE_FLOWTYPE			BIT(6)
32 #define IEEE80211_TWT_REQTYPE_FLOWID			GENMASK(9, 7)
33 #define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP		GENMASK(14, 10)
34 #define IEEE80211_TWT_REQTYPE_PROTECTION		BIT(15)
35 
36 enum ieee80211_twt_setup_cmd {
37 	TWT_SETUP_CMD_REQUEST,
38 	TWT_SETUP_CMD_SUGGEST,
39 	TWT_SETUP_CMD_DEMAND,
40 	TWT_SETUP_CMD_GROUPING,
41 	TWT_SETUP_CMD_ACCEPT,
42 	TWT_SETUP_CMD_ALTERNATE,
43 	TWT_SETUP_CMD_DICTATE,
44 	TWT_SETUP_CMD_REJECT,
45 };
46 
47 struct ieee80211_twt_params {
48 	__le16 req_type;
49 	__le64 twt;
50 	u8 min_twt_dur;
51 	__le16 mantissa;
52 	u8 channel;
53 } __packed;
54 
55 struct ieee80211_twt_setup {
56 	u8 dialog_token;
57 	u8 element_id;
58 	u8 length;
59 	u8 control;
60 	u8 params[];
61 } __packed;
62 
63 /**
64  * struct ieee80211_he_cap_elem - HE capabilities element
65  * @mac_cap_info: HE MAC Capabilities Information
66  * @phy_cap_info: HE PHY Capabilities Information
67  *
68  * This structure represents the fixed fields of the payload of the
69  * "HE capabilities element" as described in IEEE Std 802.11ax-2021
70  * sections 9.4.2.248.2 and 9.4.2.248.3.
71  */
72 struct ieee80211_he_cap_elem {
73 	u8 mac_cap_info[6];
74 	u8 phy_cap_info[11];
75 } __packed;
76 
77 #define IEEE80211_TX_RX_MCS_NSS_DESC_MAX_LEN	5
78 
79 /**
80  * enum ieee80211_he_mcs_support - HE MCS support definitions
81  * @IEEE80211_HE_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
82  *	number of streams
83  * @IEEE80211_HE_MCS_SUPPORT_0_9: MCSes 0-9 are supported
84  * @IEEE80211_HE_MCS_SUPPORT_0_11: MCSes 0-11 are supported
85  * @IEEE80211_HE_MCS_NOT_SUPPORTED: This number of streams isn't supported
86  *
87  * These definitions are used in each 2-bit subfield of the rx_mcs_*
88  * and tx_mcs_* fields of &struct ieee80211_he_mcs_nss_supp, which are
89  * both split into 8 subfields by number of streams. These values indicate
90  * which MCSes are supported for the number of streams the value appears
91  * for.
92  */
93 enum ieee80211_he_mcs_support {
94 	IEEE80211_HE_MCS_SUPPORT_0_7	= 0,
95 	IEEE80211_HE_MCS_SUPPORT_0_9	= 1,
96 	IEEE80211_HE_MCS_SUPPORT_0_11	= 2,
97 	IEEE80211_HE_MCS_NOT_SUPPORTED	= 3,
98 };
99 
100 /**
101  * struct ieee80211_he_mcs_nss_supp - HE Tx/Rx HE MCS NSS Support Field
102  *
103  * This structure holds the data required for the Tx/Rx HE MCS NSS Support Field
104  * described in P802.11ax_D2.0 section 9.4.2.237.4
105  *
106  * @rx_mcs_80: Rx MCS map 2 bits for each stream, total 8 streams, for channel
107  *     widths less than 80MHz.
108  * @tx_mcs_80: Tx MCS map 2 bits for each stream, total 8 streams, for channel
109  *     widths less than 80MHz.
110  * @rx_mcs_160: Rx MCS map 2 bits for each stream, total 8 streams, for channel
111  *     width 160MHz.
112  * @tx_mcs_160: Tx MCS map 2 bits for each stream, total 8 streams, for channel
113  *     width 160MHz.
114  * @rx_mcs_80p80: Rx MCS map 2 bits for each stream, total 8 streams, for
115  *     channel width 80p80MHz.
116  * @tx_mcs_80p80: Tx MCS map 2 bits for each stream, total 8 streams, for
117  *     channel width 80p80MHz.
118  */
119 struct ieee80211_he_mcs_nss_supp {
120 	__le16 rx_mcs_80;
121 	__le16 tx_mcs_80;
122 	__le16 rx_mcs_160;
123 	__le16 tx_mcs_160;
124 	__le16 rx_mcs_80p80;
125 	__le16 tx_mcs_80p80;
126 } __packed;
127 
128 /**
129  * struct ieee80211_he_operation - HE Operation element
130  * @he_oper_params: HE Operation Parameters + BSS Color Information
131  * @he_mcs_nss_set: Basic HE-MCS And NSS Set
132  * @optional: Optional fields VHT Operation Information, Max Co-Hosted
133  *            BSSID Indicator, and 6 GHz Operation Information
134  *
135  * This structure represents the payload of the "HE Operation
136  * element" as described in IEEE Std 802.11ax-2021 section 9.4.2.249.
137  */
138 struct ieee80211_he_operation {
139 	__le32 he_oper_params;
140 	__le16 he_mcs_nss_set;
141 	u8 optional[];
142 } __packed;
143 
144 /**
145  * struct ieee80211_he_spr - Spatial Reuse Parameter Set element
146  * @he_sr_control: SR Control
147  * @optional: Optional fields Non-SRG OBSS PD Max Offset, SRG OBSS PD
148  *            Min Offset, SRG OBSS PD Max Offset, SRG BSS Color
149  *            Bitmap, and SRG Partial BSSID Bitmap
150  *
151  * This structure represents the payload of the "Spatial Reuse
152  * Parameter Set element" as described in IEEE Std 802.11ax-2021
153  * section 9.4.2.252.
154  */
155 struct ieee80211_he_spr {
156 	u8 he_sr_control;
157 	u8 optional[];
158 } __packed;
159 
160 /**
161  * struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
162  * @aifsn: ACI/AIFSN
163  * @ecw_min_max: ECWmin/ECWmax
164  * @mu_edca_timer: MU EDCA Timer
165  *
166  * This structure represents the "MU AC Parameter Record" as described
167  * in IEEE Std 802.11ax-2021 section 9.4.2.251, Figure 9-788p.
168  */
169 struct ieee80211_he_mu_edca_param_ac_rec {
170 	u8 aifsn;
171 	u8 ecw_min_max;
172 	u8 mu_edca_timer;
173 } __packed;
174 
175 /**
176  * struct ieee80211_mu_edca_param_set - MU EDCA Parameter Set element
177  * @mu_qos_info: QoS Info
178  * @ac_be: MU AC_BE Parameter Record
179  * @ac_bk: MU AC_BK Parameter Record
180  * @ac_vi: MU AC_VI Parameter Record
181  * @ac_vo: MU AC_VO Parameter Record
182  *
183  * This structure represents the payload of the "MU EDCA Parameter Set
184  * element" as described in IEEE Std 802.11ax-2021 section 9.4.2.251.
185  */
186 struct ieee80211_mu_edca_param_set {
187 	u8 mu_qos_info;
188 	struct ieee80211_he_mu_edca_param_ac_rec ac_be;
189 	struct ieee80211_he_mu_edca_param_ac_rec ac_bk;
190 	struct ieee80211_he_mu_edca_param_ac_rec ac_vi;
191 	struct ieee80211_he_mu_edca_param_ac_rec ac_vo;
192 } __packed;
193 
194 /* 802.11ax HE MAC capabilities */
195 #define IEEE80211_HE_MAC_CAP0_HTC_HE				0x01
196 #define IEEE80211_HE_MAC_CAP0_TWT_REQ				0x02
197 #define IEEE80211_HE_MAC_CAP0_TWT_RES				0x04
198 #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_NOT_SUPP		0x00
199 #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_1		0x08
200 #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_2		0x10
201 #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_LEVEL_3		0x18
202 #define IEEE80211_HE_MAC_CAP0_DYNAMIC_FRAG_MASK			0x18
203 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_1		0x00
204 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_2		0x20
205 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_4		0x40
206 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_8		0x60
207 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_16		0x80
208 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_32		0xa0
209 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_64		0xc0
210 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_UNLIMITED	0xe0
211 #define IEEE80211_HE_MAC_CAP0_MAX_NUM_FRAG_MSDU_MASK		0xe0
212 
213 #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_UNLIMITED		0x00
214 #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_128			0x01
215 #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_256			0x02
216 #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_512			0x03
217 #define IEEE80211_HE_MAC_CAP1_MIN_FRAG_SIZE_MASK		0x03
218 #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_0US		0x00
219 #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US		0x04
220 #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US		0x08
221 #define IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_MASK		0x0c
222 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_1		0x00
223 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_2		0x10
224 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_3		0x20
225 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_4		0x30
226 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_5		0x40
227 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_6		0x50
228 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_7		0x60
229 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8		0x70
230 #define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_MASK		0x70
231 
232 /* Link adaptation is split between byte HE_MAC_CAP1 and
233  * HE_MAC_CAP2. It should be set only if IEEE80211_HE_MAC_CAP0_HTC_HE
234  * in which case the following values apply:
235  * 0 = No feedback.
236  * 1 = reserved.
237  * 2 = Unsolicited feedback.
238  * 3 = both
239  */
240 #define IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION			0x80
241 
242 #define IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION			0x01
243 #define IEEE80211_HE_MAC_CAP2_ALL_ACK				0x02
244 #define IEEE80211_HE_MAC_CAP2_TRS				0x04
245 #define IEEE80211_HE_MAC_CAP2_BSR				0x08
246 #define IEEE80211_HE_MAC_CAP2_BCAST_TWT				0x10
247 #define IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP			0x20
248 #define IEEE80211_HE_MAC_CAP2_MU_CASCADING			0x40
249 #define IEEE80211_HE_MAC_CAP2_ACK_EN				0x80
250 
251 #define IEEE80211_HE_MAC_CAP3_OMI_CONTROL			0x02
252 #define IEEE80211_HE_MAC_CAP3_OFDMA_RA				0x04
253 
254 /* The maximum length of an A-MDPU is defined by the combination of the Maximum
255  * A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the
256  * same field in the HE capabilities.
257  */
258 #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0		0x00
259 #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1		0x08
260 #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2		0x10
261 #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3		0x18
262 #define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK		0x18
263 #define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG			0x20
264 #define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED			0x40
265 #define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS		0x80
266 
267 #define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG		0x01
268 #define IEEE80211_HE_MAC_CAP4_QTP				0x02
269 #define IEEE80211_HE_MAC_CAP4_BQR				0x04
270 #define IEEE80211_HE_MAC_CAP4_PSR_RESP				0x08
271 #define IEEE80211_HE_MAC_CAP4_NDP_FB_REP			0x10
272 #define IEEE80211_HE_MAC_CAP4_OPS				0x20
273 #define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU			0x40
274 /* Multi TID agg TX is split between byte #4 and #5
275  * The value is a combination of B39,B40,B41
276  */
277 #define IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39		0x80
278 
279 #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40		0x01
280 #define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41		0x02
281 #define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION	0x04
282 #define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU			0x08
283 #define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX		0x10
284 #define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS			0x20
285 #define IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING		0x40
286 #define IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX		0x80
287 
288 #define IEEE80211_HE_VHT_MAX_AMPDU_FACTOR	20
289 #define IEEE80211_HE_HT_MAX_AMPDU_FACTOR	16
290 #define IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR	13
291 
292 /* 802.11ax HE PHY capabilities */
293 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G		0x02
294 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G	0x04
295 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G		0x08
296 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G	0x10
297 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL		0x1e
298 
299 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G	0x20
300 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G	0x40
301 #define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK			0xfe
302 
303 #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_80MHZ_ONLY_SECOND_20MHZ	0x01
304 #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_80MHZ_ONLY_SECOND_40MHZ	0x02
305 #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_160MHZ_ONLY_SECOND_20MHZ	0x04
306 #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_160MHZ_ONLY_SECOND_40MHZ	0x08
307 #define IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK			0x0f
308 #define IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A				0x10
309 #define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD			0x20
310 #define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US		0x40
311 /* Midamble RX/TX Max NSTS is split between byte #2 and byte #3 */
312 #define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS			0x80
313 
314 #define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS			0x01
315 #define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US			0x02
316 #define IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ			0x04
317 #define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ			0x08
318 #define IEEE80211_HE_PHY_CAP2_DOPPLER_TX				0x10
319 #define IEEE80211_HE_PHY_CAP2_DOPPLER_RX				0x20
320 
321 /* Note that the meaning of UL MU below is different between an AP and a non-AP
322  * sta, where in the AP case it indicates support for Rx and in the non-AP sta
323  * case it indicates support for Tx.
324  */
325 #define IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO			0x40
326 #define IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO			0x80
327 
328 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_NO_DCM			0x00
329 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK			0x01
330 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK			0x02
331 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_16_QAM			0x03
332 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK			0x03
333 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1				0x00
334 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2				0x04
335 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_NO_DCM			0x00
336 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK			0x08
337 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK			0x10
338 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM			0x18
339 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK			0x18
340 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1				0x00
341 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2				0x20
342 #define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU		0x40
343 #define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER				0x80
344 
345 #define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE				0x01
346 #define IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER				0x02
347 
348 /* Minimal allowed value of Max STS under 80MHz is 3 */
349 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4		0x0c
350 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_5		0x10
351 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_6		0x14
352 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_7		0x18
353 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8		0x1c
354 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK	0x1c
355 
356 /* Minimal allowed value of Max STS above 80MHz is 3 */
357 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4		0x60
358 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_5		0x80
359 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_6		0xa0
360 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_7		0xc0
361 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8		0xe0
362 #define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK	0xe0
363 
364 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_1	0x00
365 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2	0x01
366 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_3	0x02
367 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_4	0x03
368 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_5	0x04
369 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_6	0x05
370 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_7	0x06
371 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_8	0x07
372 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK	0x07
373 
374 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_1	0x00
375 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2	0x08
376 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_3	0x10
377 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_4	0x18
378 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_5	0x20
379 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_6	0x28
380 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_7	0x30
381 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_8	0x38
382 #define IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK	0x38
383 
384 #define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK				0x40
385 #define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK				0x80
386 
387 #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU			0x01
388 #define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU			0x02
389 #define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB			0x04
390 #define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB		0x08
391 #define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB				0x10
392 #define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE			0x20
393 #define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO		0x40
394 #define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT			0x80
395 
396 #define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR				0x01
397 #define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP			0x02
398 #define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI		0x04
399 #define IEEE80211_HE_PHY_CAP7_MAX_NC_1					0x08
400 #define IEEE80211_HE_PHY_CAP7_MAX_NC_2					0x10
401 #define IEEE80211_HE_PHY_CAP7_MAX_NC_3					0x18
402 #define IEEE80211_HE_PHY_CAP7_MAX_NC_4					0x20
403 #define IEEE80211_HE_PHY_CAP7_MAX_NC_5					0x28
404 #define IEEE80211_HE_PHY_CAP7_MAX_NC_6					0x30
405 #define IEEE80211_HE_PHY_CAP7_MAX_NC_7					0x38
406 #define IEEE80211_HE_PHY_CAP7_MAX_NC_MASK				0x38
407 #define IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ			0x40
408 #define IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ			0x80
409 
410 #define IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI		0x01
411 #define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G		0x02
412 #define IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU			0x04
413 #define IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU			0x08
414 #define IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI		0x10
415 #define IEEE80211_HE_PHY_CAP8_MIDAMBLE_RX_TX_2X_AND_1XLTF		0x20
416 #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_242				0x00
417 #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484				0x40
418 #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_996				0x80
419 #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_2x996				0xc0
420 #define IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_MASK				0xc0
421 
422 #define IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM		0x01
423 #define IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK		0x02
424 #define IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU		0x04
425 #define IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU		0x08
426 #define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB	0x10
427 #define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB	0x20
428 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_0US			0x0
429 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_8US			0x1
430 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US			0x2
431 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_RESERVED		0x3
432 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_POS			6
433 #define IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_MASK			0xc0
434 
435 #define IEEE80211_HE_PHY_CAP10_HE_MU_M1RU_MAX_LTF			0x01
436 
437 /* 802.11ax HE TX/RX MCS NSS Support  */
438 #define IEEE80211_TX_RX_MCS_NSS_SUPP_HIGHEST_MCS_POS			(3)
439 #define IEEE80211_TX_RX_MCS_NSS_SUPP_TX_BITMAP_POS			(6)
440 #define IEEE80211_TX_RX_MCS_NSS_SUPP_RX_BITMAP_POS			(11)
441 #define IEEE80211_TX_RX_MCS_NSS_SUPP_TX_BITMAP_MASK			0x07c0
442 #define IEEE80211_TX_RX_MCS_NSS_SUPP_RX_BITMAP_MASK			0xf800
443 
444 /* TX/RX HE MCS Support field Highest MCS subfield encoding */
445 enum ieee80211_he_highest_mcs_supported_subfield_enc {
446 	HIGHEST_MCS_SUPPORTED_MCS7 = 0,
447 	HIGHEST_MCS_SUPPORTED_MCS8,
448 	HIGHEST_MCS_SUPPORTED_MCS9,
449 	HIGHEST_MCS_SUPPORTED_MCS10,
450 	HIGHEST_MCS_SUPPORTED_MCS11,
451 };
452 
453 /* Calculate 802.11ax HE capabilities IE Tx/Rx HE MCS NSS Support Field size */
454 static inline u8
ieee80211_he_mcs_nss_size(const struct ieee80211_he_cap_elem * he_cap)455 ieee80211_he_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap)
456 {
457 	u8 count = 4;
458 
459 	if (he_cap->phy_cap_info[0] &
460 	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
461 		count += 4;
462 
463 	if (he_cap->phy_cap_info[0] &
464 	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
465 		count += 4;
466 
467 	return count;
468 }
469 
470 /* 802.11ax HE PPE Thresholds */
471 #define IEEE80211_PPE_THRES_NSS_SUPPORT_2NSS			(1)
472 #define IEEE80211_PPE_THRES_NSS_POS				(0)
473 #define IEEE80211_PPE_THRES_NSS_MASK				(7)
474 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_2x966_AND_966_RU	\
475 	(BIT(5) | BIT(6))
476 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK		0x78
477 #define IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS		(3)
478 #define IEEE80211_PPE_THRES_INFO_PPET_SIZE			(3)
479 #define IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE			(7)
480 
481 /*
482  * Calculate 802.11ax HE capabilities IE PPE field size
483  * Input: Header byte of ppe_thres (first byte), and HE capa IE's PHY cap u8*
484  */
485 static inline u8
ieee80211_he_ppe_size(u8 ppe_thres_hdr,const u8 * phy_cap_info)486 ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
487 {
488 	u8 n;
489 
490 	if ((phy_cap_info[6] &
491 	     IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0)
492 		return 0;
493 
494 	n = hweight8(ppe_thres_hdr &
495 		     IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK);
496 	n *= (1 + ((ppe_thres_hdr & IEEE80211_PPE_THRES_NSS_MASK) >>
497 		   IEEE80211_PPE_THRES_NSS_POS));
498 
499 	/*
500 	 * Each pair is 6 bits, and we need to add the 7 "header" bits to the
501 	 * total size.
502 	 */
503 	n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7;
504 	n = DIV_ROUND_UP(n, 8);
505 
506 	return n;
507 }
508 
ieee80211_he_capa_size_ok(const u8 * data,u8 len)509 static inline bool ieee80211_he_capa_size_ok(const u8 *data, u8 len)
510 {
511 	const struct ieee80211_he_cap_elem *he_cap_ie_elem = (const void *)data;
512 	u8 needed = sizeof(*he_cap_ie_elem);
513 
514 	if (len < needed)
515 		return false;
516 
517 	needed += ieee80211_he_mcs_nss_size(he_cap_ie_elem);
518 	if (len < needed)
519 		return false;
520 
521 	if (he_cap_ie_elem->phy_cap_info[6] &
522 			IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
523 		if (len < needed + 1)
524 			return false;
525 		needed += ieee80211_he_ppe_size(data[needed],
526 						he_cap_ie_elem->phy_cap_info);
527 	}
528 
529 	return len >= needed;
530 }
531 
532 /* HE Operation defines */
533 #define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK		0x00000007
534 #define IEEE80211_HE_OPERATION_TWT_REQUIRED			0x00000008
535 #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK		0x00003ff0
536 #define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET		4
537 #define IEEE80211_HE_OPERATION_VHT_OPER_INFO			0x00004000
538 #define IEEE80211_HE_OPERATION_CO_HOSTED_BSS			0x00008000
539 #define IEEE80211_HE_OPERATION_ER_SU_DISABLE			0x00010000
540 #define IEEE80211_HE_OPERATION_6GHZ_OP_INFO			0x00020000
541 #define IEEE80211_HE_OPERATION_BSS_COLOR_MASK			0x3f000000
542 #define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET			24
543 #define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR		0x40000000
544 #define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED		0x80000000
545 
546 #define IEEE80211_6GHZ_CTRL_REG_LPI_AP			0
547 #define IEEE80211_6GHZ_CTRL_REG_SP_AP			1
548 #define IEEE80211_6GHZ_CTRL_REG_VLP_AP			2
549 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP		3
550 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP_OLD	4
551 #define IEEE80211_6GHZ_CTRL_REG_AP_ROLE_NOT_RELEVANT	7
552 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP		8
553 
554 /**
555  * struct ieee80211_he_6ghz_oper - HE 6 GHz operation Information field
556  * @primary: primary channel
557  * @control: control flags
558  * @ccfs0: channel center frequency segment 0
559  * @ccfs1: channel center frequency segment 1
560  * @minrate: minimum rate (in 1 Mbps units)
561  */
562 struct ieee80211_he_6ghz_oper {
563 	u8 primary;
564 #define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH	0x3
565 #define		IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ	0
566 #define		IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ	1
567 #define		IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ	2
568 #define		IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ	3
569 #define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON	0x4
570 #define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO	0x78
571 	u8 control;
572 	u8 ccfs0;
573 	u8 ccfs1;
574 	u8 minrate;
575 } __packed;
576 
577 /**
578  * enum ieee80211_reg_conn_bits - represents Regulatory connectivity field bits.
579  *
580  * This enumeration defines bit flags used to represent regulatory connectivity
581  * field bits.
582  *
583  * @IEEE80211_REG_CONN_LPI_VALID: Indicates whether the LPI bit is valid.
584  * @IEEE80211_REG_CONN_LPI_VALUE: Represents the value of the LPI bit.
585  * @IEEE80211_REG_CONN_SP_VALID: Indicates whether the SP bit is valid.
586  * @IEEE80211_REG_CONN_SP_VALUE: Represents the value of the SP bit.
587  */
588 enum ieee80211_reg_conn_bits {
589 	IEEE80211_REG_CONN_LPI_VALID = BIT(0),
590 	IEEE80211_REG_CONN_LPI_VALUE = BIT(1),
591 	IEEE80211_REG_CONN_SP_VALID = BIT(2),
592 	IEEE80211_REG_CONN_SP_VALUE = BIT(3),
593 };
594 
595 /* transmit power interpretation type of transmit power envelope element */
596 enum ieee80211_tx_power_intrpt_type {
597 	IEEE80211_TPE_LOCAL_EIRP,
598 	IEEE80211_TPE_LOCAL_EIRP_PSD,
599 	IEEE80211_TPE_REG_CLIENT_EIRP,
600 	IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
601 };
602 
603 /* category type of transmit power envelope element */
604 enum ieee80211_tx_power_category_6ghz {
605 	IEEE80211_TPE_CAT_6GHZ_DEFAULT = 0,
606 	IEEE80211_TPE_CAT_6GHZ_SUBORDINATE = 1,
607 };
608 
609 /*
610  * For IEEE80211_TPE_LOCAL_EIRP / IEEE80211_TPE_REG_CLIENT_EIRP,
611  * setting to 63.5 dBm means no constraint.
612  */
613 #define IEEE80211_TPE_MAX_TX_PWR_NO_CONSTRAINT	127
614 
615 /*
616  * For IEEE80211_TPE_LOCAL_EIRP_PSD / IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
617  * setting to 127 indicates no PSD limit for the 20 MHz channel.
618  */
619 #define IEEE80211_TPE_PSD_NO_LIMIT		127
620 
621 /**
622  * struct ieee80211_tx_pwr_env - Transmit Power Envelope
623  * @info: Transmit Power Information field
624  * @variable: Maximum Transmit Power field
625  *
626  * This structure represents the payload of the "Transmit Power
627  * Envelope element" as described in IEEE Std 802.11ax-2021 section
628  * 9.4.2.161
629  */
630 struct ieee80211_tx_pwr_env {
631 	u8 info;
632 	u8 variable[];
633 } __packed;
634 
635 #define IEEE80211_TX_PWR_ENV_INFO_COUNT 0x7
636 #define IEEE80211_TX_PWR_ENV_INFO_INTERPRET 0x38
637 #define IEEE80211_TX_PWR_ENV_INFO_CATEGORY 0xC0
638 
639 #define IEEE80211_TX_PWR_ENV_EXT_COUNT	0xF
640 
ieee80211_valid_tpe_element(const u8 * data,u8 len)641 static inline bool ieee80211_valid_tpe_element(const u8 *data, u8 len)
642 {
643 	const struct ieee80211_tx_pwr_env *env = (const void *)data;
644 	u8 count, interpret, category;
645 	u8 needed = sizeof(*env);
646 	u8 N; /* also called N in the spec */
647 
648 	if (len < needed)
649 		return false;
650 
651 	count = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_COUNT);
652 	interpret = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_INTERPRET);
653 	category = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_CATEGORY);
654 
655 	switch (category) {
656 	case IEEE80211_TPE_CAT_6GHZ_DEFAULT:
657 	case IEEE80211_TPE_CAT_6GHZ_SUBORDINATE:
658 		break;
659 	default:
660 		return false;
661 	}
662 
663 	switch (interpret) {
664 	case IEEE80211_TPE_LOCAL_EIRP:
665 	case IEEE80211_TPE_REG_CLIENT_EIRP:
666 		if (count > 3)
667 			return false;
668 
669 		/* count == 0 encodes 1 value for 20 MHz, etc. */
670 		needed += count + 1;
671 
672 		if (len < needed)
673 			return false;
674 
675 		/* there can be extension fields not accounted for in 'count' */
676 
677 		return true;
678 	case IEEE80211_TPE_LOCAL_EIRP_PSD:
679 	case IEEE80211_TPE_REG_CLIENT_EIRP_PSD:
680 		if (count > 4)
681 			return false;
682 
683 		N = count ? 1 << (count - 1) : 1;
684 		needed += N;
685 
686 		if (len < needed)
687 			return false;
688 
689 		if (len > needed) {
690 			u8 K = u8_get_bits(env->variable[N],
691 					   IEEE80211_TX_PWR_ENV_EXT_COUNT);
692 
693 			needed += 1 + K;
694 			if (len < needed)
695 				return false;
696 		}
697 
698 		return true;
699 	}
700 
701 	return false;
702 }
703 
704 /*
705  * ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size
706  * @he_oper_ie: byte data of the He Operations IE, stating from the byte
707  *	after the ext ID byte. It is assumed that he_oper_ie has at least
708  *	sizeof(struct ieee80211_he_operation) bytes, the caller must have
709  *	validated this.
710  * @return the actual size of the IE data (not including header), or 0 on error
711  */
712 static inline u8
ieee80211_he_oper_size(const u8 * he_oper_ie)713 ieee80211_he_oper_size(const u8 *he_oper_ie)
714 {
715 	const struct ieee80211_he_operation *he_oper = (const void *)he_oper_ie;
716 	u8 oper_len = sizeof(struct ieee80211_he_operation);
717 	u32 he_oper_params;
718 
719 	/* Make sure the input is not NULL */
720 	if (!he_oper_ie)
721 		return 0;
722 
723 	/* Calc required length */
724 	he_oper_params = le32_to_cpu(he_oper->he_oper_params);
725 	if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)
726 		oper_len += 3;
727 	if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
728 		oper_len++;
729 	if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)
730 		oper_len += sizeof(struct ieee80211_he_6ghz_oper);
731 
732 	/* Add the first byte (extension ID) to the total length */
733 	oper_len++;
734 
735 	return oper_len;
736 }
737 
738 /**
739  * ieee80211_he_6ghz_oper - obtain 6 GHz operation field
740  * @he_oper: HE operation element (must be pre-validated for size)
741  *	but may be %NULL
742  *
743  * Return: a pointer to the 6 GHz operation field, or %NULL
744  */
745 static inline const struct ieee80211_he_6ghz_oper *
ieee80211_he_6ghz_oper(const struct ieee80211_he_operation * he_oper)746 ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper)
747 {
748 	const u8 *ret;
749 	u32 he_oper_params;
750 
751 	if (!he_oper)
752 		return NULL;
753 
754 	ret = (const void *)&he_oper->optional;
755 
756 	he_oper_params = le32_to_cpu(he_oper->he_oper_params);
757 
758 	if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO))
759 		return NULL;
760 	if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)
761 		ret += 3;
762 	if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
763 		ret++;
764 
765 	return (const void *)ret;
766 }
767 
768 /* HE Spatial Reuse defines */
769 #define IEEE80211_HE_SPR_PSR_DISALLOWED				BIT(0)
770 #define IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED		BIT(1)
771 #define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT			BIT(2)
772 #define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT		BIT(3)
773 #define IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED		BIT(4)
774 
775 /*
776  * ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size
777  * @he_spr_ie: byte data of the He Spatial Reuse IE, stating from the byte
778  *	after the ext ID byte. It is assumed that he_spr_ie has at least
779  *	sizeof(struct ieee80211_he_spr) bytes, the caller must have validated
780  *	this
781  * @return the actual size of the IE data (not including header), or 0 on error
782  */
783 static inline u8
ieee80211_he_spr_size(const u8 * he_spr_ie)784 ieee80211_he_spr_size(const u8 *he_spr_ie)
785 {
786 	const struct ieee80211_he_spr *he_spr = (const void *)he_spr_ie;
787 	u8 spr_len = sizeof(struct ieee80211_he_spr);
788 	u8 he_spr_params;
789 
790 	/* Make sure the input is not NULL */
791 	if (!he_spr_ie)
792 		return 0;
793 
794 	/* Calc required length */
795 	he_spr_params = he_spr->he_sr_control;
796 	if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
797 		spr_len++;
798 	if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)
799 		spr_len += 18;
800 
801 	/* Add the first byte (extension ID) to the total length */
802 	spr_len++;
803 
804 	return spr_len;
805 }
806 
807 struct ieee80211_he_6ghz_capa {
808 	/* uses IEEE80211_HE_6GHZ_CAP_* below */
809 	__le16 capa;
810 } __packed;
811 
812 /* HE 6 GHz band capabilities */
813 /* uses enum ieee80211_min_mpdu_spacing values */
814 #define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START	0x0007
815 /* uses enum ieee80211_vht_max_ampdu_length_exp values */
816 #define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP	0x0038
817 /* uses IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_* values */
818 #define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN	0x00c0
819 /* WLAN_HT_CAP_SM_PS_* values */
820 #define IEEE80211_HE_6GHZ_CAP_SM_PS		0x0600
821 #define IEEE80211_HE_6GHZ_CAP_RD_RESPONDER	0x0800
822 #define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS	0x1000
823 #define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS	0x2000
824 
825 #endif /* LINUX_IEEE80211_HE_H */
826