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