jerpelea commented on code in PR #5755:
URL: https://github.com/apache/incubator-nuttx/pull/5755#discussion_r849472503


##########
include/nuttx/wireless/ieee80211/ieee80211.h:
##########
@@ -42,849 +42,4070 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define IEEE80211_ADDR_LEN          6  /* size of 802.11 address */
-
-/* is 802.11 address multicast/broadcast? */
-
-#define IEEE80211_IS_MULTICAST(_a)  (*(_a) & 0x01)
-
-/* htframe */
-
-#define IEEE80211_FC0_VERSION_MASK          0x03
-#define IEEE80211_FC0_VERSION_SHIFT         0
-#define IEEE80211_FC0_VERSION_0             0x00
-#define IEEE80211_FC0_TYPE_MASK             0x0c
-#define IEEE80211_FC0_TYPE_SHIFT            2
-#define IEEE80211_FC0_TYPE_MGT              0x00
-#define IEEE80211_FC0_TYPE_CTL              0x04
-#define IEEE80211_FC0_TYPE_DATA             0x08
-
-#define IEEE80211_FC0_SUBTYPE_MASK          0xf0
-#define IEEE80211_FC0_SUBTYPE_SHIFT         4
-
-/* for TYPE_MGT */
-
-#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ     0x00
-#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP    0x10
-#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ   0x20
-#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP  0x30
-#define IEEE80211_FC0_SUBTYPE_PROBE_REQ     0x40
-#define IEEE80211_FC0_SUBTYPE_PROBE_RESP    0x50
-#define IEEE80211_FC0_SUBTYPE_BEACON        0x80
-#define IEEE80211_FC0_SUBTYPE_ATIM          0x90
-#define IEEE80211_FC0_SUBTYPE_DISASSOC      0xa0
-#define IEEE80211_FC0_SUBTYPE_AUTH          0xb0
-#define IEEE80211_FC0_SUBTYPE_DEAUTH        0xc0
-#define IEEE80211_FC0_SUBTYPE_ACTION        0xd0
-#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK  0xe0  /* 11n */
-
-/* for TYPE_CTL */
-
-#define IEEE80211_FC0_SUBTYPE_WRAPPER       0x70  /* 11n */
-#define IEEE80211_FC0_SUBTYPE_BAR           0x80
-#define IEEE80211_FC0_SUBTYPE_BA            0x90
-#define IEEE80211_FC0_SUBTYPE_PS_POLL       0xa0
-#define IEEE80211_FC0_SUBTYPE_RTS           0xb0
-#define IEEE80211_FC0_SUBTYPE_CTS           0xc0
-#define IEEE80211_FC0_SUBTYPE_ACK           0xd0
-#define IEEE80211_FC0_SUBTYPE_CF_END        0xe0
-#define IEEE80211_FC0_SUBTYPE_CF_END_ACK    0xf0
-
-/* for TYPE_DATA (bit combination) */
-
-#define IEEE80211_FC0_SUBTYPE_DATA          0x00
-#define IEEE80211_FC0_SUBTYPE_CF_ACK        0x10
-#define IEEE80211_FC0_SUBTYPE_CF_POLL       0x20
-#define IEEE80211_FC0_SUBTYPE_CF_ACPL       0x30
-#define IEEE80211_FC0_SUBTYPE_NODATA        0x40
-#define IEEE80211_FC0_SUBTYPE_CFACK         0x50
-#define IEEE80211_FC0_SUBTYPE_CFPOLL        0x60
-#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
-#define IEEE80211_FC0_SUBTYPE_QOS           0x80
-
-#define IEEE80211_FC1_DIR_MASK              0x03
-#define IEEE80211_FC1_DIR_NODS              0x00  /* STA->STA */
-#define IEEE80211_FC1_DIR_TODS              0x01  /* STA->AP */
-#define IEEE80211_FC1_DIR_FROMDS            0x02
-                                                  /* AP ->STA */
-#define IEEE80211_FC1_DIR_DSTODS            0x03
-                                                  /* AP ->AP */
-
-#define IEEE80211_FC1_MORE_FRAG             0x04
-#define IEEE80211_FC1_RETRY                 0x08
-#define IEEE80211_FC1_PWR_MGT               0x10
-#define IEEE80211_FC1_MORE_DATA             0x20
-#define IEEE80211_FC1_PROTECTED             0x40
-#define IEEE80211_FC1_WEP                   0x40  /* pre-RSNA compat */
-#define IEEE80211_FC1_ORDER                 0x80
-#define IEEE80211_FC1_BITS \
-    "\20\03MORE_FRAG\04RETRY\05PWR_MGT\06MORE_DATA" \
-    "\07PROTECTED\08ORDER"
-
-/* Sequence Control field (see 7.1.3.4). */
-
-#define IEEE80211_SEQ_FRAG_MASK            0x000f
-#define IEEE80211_SEQ_FRAG_SHIFT           0
-#define IEEE80211_SEQ_SEQ_MASK             0xfff0
-#define IEEE80211_SEQ_SEQ_SHIFT            4
-
-#define IEEE80211_NWID_LEN                 32
-#define IEEE80211_MMIE_LEN                 18  /* 11w */
-
-/* QoS Control field (see 7.1.3.5). */
-
-#define IEEE80211_QOS_TXOP                 0xff00
-#define IEEE80211_QOS_AMSDU                0x0080  /* 11n */
-#define IEEE80211_QOS_ACK_POLICY_NORMAL    0x0000
-#define IEEE80211_QOS_ACK_POLICY_NOACK     0x0020
-#define IEEE80211_QOS_ACK_POLICY_NOEXPLACK 0x0040
-#define IEEE80211_QOS_ACK_POLICY_BA        0x0060
-#define IEEE80211_QOS_ACK_POLICY_MASK      0x0060
-#define IEEE80211_QOS_ACK_POLICY_SHIFT     5
-#define IEEE80211_QOS_EOSP                 0x0010
-#define IEEE80211_QOS_TID                  0x000f
-
-/* Capability Information field (see 7.3.1.4) */
-
-#define IEEE80211_CAPINFO_ESS              0x0001
-#define IEEE80211_CAPINFO_IBSS             0x0002
-#define IEEE80211_CAPINFO_CF_POLLABLE      0x0004
-#define IEEE80211_CAPINFO_CF_POLLREQ       0x0008
-#define IEEE80211_CAPINFO_PRIVACY          0x0010
-#define IEEE80211_CAPINFO_SHORT_PREAMBLE   0x0020
-#define IEEE80211_CAPINFO_PBCC             0x0040
-#define IEEE80211_CAPINFO_CHNL_AGILITY     0x0080
-#define IEEE80211_CAPINFO_SPECTRUM_MGMT    0x0100
-#define IEEE80211_CAPINFO_QOS              0x0200
-#define IEEE80211_CAPINFO_SHORT_SLOTTIME   0x0400
-#define IEEE80211_CAPINFO_APSD             0x0800
-
-/* bit 12 is reserved */
-
-#define IEEE80211_CAPINFO_DSSSOFDM         0x2000
-#define IEEE80211_CAPINFO_DELAYED_B_ACK    0x4000
-#define IEEE80211_CAPINFO_IMMEDIATE_B_ACK  0x8000
-#define IEEE80211_CAPINFO_BITS \
-    "\10\01ESS\02IBSS\03CF_POLLABLE\04CF_POLLREQ" \
-    "\05PRIVACY\06SHORT_PREAMBLE\07PBCC\10CHNL_AGILITY" \
-    "\11SPECTRUM_MGMT\12QOS\13SHORT_SLOTTIME\14APSD" \
-    "\16DSSSOFDM\17DELAYED_B_ACK\20IMMEDIATE_B_ACK"
-
-/* Block Ack Action field values (see Table 7-54). */
-
-#define IEEE80211_ACTION_ADDBA_REQ         0
-#define IEEE80211_ACTION_ADDBA_RESP        1
-#define IEEE80211_ACTION_DELBA             2
-
-/* SA Query Action field values (see Table 7-57l). */
-
-#define IEEE80211_ACTION_SA_QUERY_REQ      0
-#define IEEE80211_ACTION_SA_QUERY_RESP     1
-
-/* HT Action field values (see Table 7-57m). */
-
-#define IEEE80211_ACTION_NOTIFYCW          0
-
-#define IEEE80211_RATE_BASIC               0x80
-#define IEEE80211_RATE_VAL                 0x7f
-#define IEEE80211_RATE_SIZE                8    /* 802.11 standard */
-#define IEEE80211_RATE_MAXSIZE             15   /* max rates we'll handle */
-
-/* BlockAck/BlockAckReq Control field (see Figure 7-13). */
-
-#define IEEE80211_BA_ACK_POLICY            0x0001
-#define IEEE80211_BA_MULTI_TID             0x0002
-#define IEEE80211_BA_COMPRESSED            0x0004
-#define IEEE80211_BA_TID_INFO_MASK         0xf000
-#define IEEE80211_BA_TID_INFO_SHIFT        12
-
-/* DELBA Parameter Set field (see Figure 7-34). */
-
-#define IEEE80211_DELBA_INITIATOR          0x0800
-
-/* ERP information element (see 7.3.2.13). */
-
-#define IEEE80211_ERP_NON_ERP_PRESENT      0x01
-#define IEEE80211_ERP_USE_PROTECTION       0x02
-#define IEEE80211_ERP_BARKER_MODE          0x04
-
-/* RSN capabilities (see 7.3.2.25.3). */
-
-#define IEEE80211_RSNCAP_PREAUTH           0x0001
-#define IEEE80211_RSNCAP_NOPAIRWISE        0x0002
-#define IEEE80211_RSNCAP_PTKSA_RCNT_MASK   0x000c
-#define IEEE80211_RSNCAP_PTKSA_RCNT_SHIFT  2
-#define IEEE80211_RSNCAP_GTKSA_RCNT_MASK   0x0030
-#define IEEE80211_RSNCAP_GTKSA_RCNT_SHIFT  4
-#define IEEE80211_RSNCAP_RCNT1             0
-#define IEEE80211_RSNCAP_RCNT2             1
-#define IEEE80211_RSNCAP_RCNT4             2
-#define IEEE80211_RSNCAP_RCNT16            3
-#define IEEE80211_RSNCAP_MFPR              0x0040  /* 11w */
-#define IEEE80211_RSNCAP_MFPC              0x0080  /* 11w */
-#define IEEE80211_RSNCAP_PEERKEYENA        0x0200
-#define IEEE80211_RSNCAP_SPPAMSDUC         0x0400  /* 11n */
-#define IEEE80211_RSNCAP_SPPAMSDUR         0x0800  /* 11n */
-#define IEEE80211_RSNCAP_PBAC              0x1000  /* 11n */
-
-/* HT Capabilities Info (see 7.3.2.57.2). */
-
-#define IEEE80211_HTCAP_LDPC               0x00000001
-#define IEEE80211_HTCAP_CBW20_40           0x00000002
-#define IEEE80211_HTCAP_SMPS_MASK          0x0000000c
-#define IEEE80211_HTCAP_SMPS_SHIFT         2
-#define IEEE80211_HTCAP_SMPS_STA           0
-#define IEEE80211_HTCAP_SMPS_DYN           1
-#define IEEE80211_HTCAP_SMPS_DIS           3
-#define IEEE80211_HTCAP_GF                 0x00000010
-#define IEEE80211_HTCAP_SGI20              0x00000020
-#define IEEE80211_HTCAP_SGI40              0x00000040
-#define IEEE80211_HTCAP_TXSTBC             0x00000080
-#define IEEE80211_HTCAP_RXSTBC_MASK        0x00000300
-#define IEEE80211_HTCAP_RXSTBC_SHIFT       8
-#define IEEE80211_HTCAP_DELAYEDBA          0x00000400
-#define IEEE80211_HTCAP_AMSDU7935          0x00000800
-#define IEEE80211_HTCAP_DSSSCCK40          0x00001000
-#define IEEE80211_HTCAP_PSMP               0x00002000
-#define IEEE80211_HTCAP_40INTOLERANT       0x00004000
-#define IEEE80211_HTCAP_LSIGTXOPPROT       0x00008000
+/*  IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
+ *  and FCS/CRC (frame check sequence).
+ */
+
+#define ETH_ALEN      6       /* Octets in one ethernet addr   */
+#define ETH_TLEN      2       /* Octets in ethernet type field */
+#define ETH_HLEN      14      /* Total octets in header.   */
+#define ETH_ZLEN      60      /* Min. octets in frame sans FCS */
+#define ETH_DATA_LEN  1500    /* Max. octets in payload  */
+#define ETH_FRAME_LEN 1514    /* Max. octets in frame sans FCS */
+#define ETH_FCS_LEN   4       /* Octets in the FCS     */
+
+#define ETH_MIN_MTU   68      /* Min IPv4 MTU per RFC791  */
+#define ETH_MAX_MTU   0xFFFFU /* 65535, same as IP_MAX_MTU  */
+
+/* DS bit usage
+ *
+ * TA = transmitter address
+ * RA = receiver address
+ * DA = destination address
+ * SA = source address
+ *
+ * ToDS    FromDS  A1(RA)  A2(TA)  A3      A4      Use
+ * -----------------------------------------------------------------
+ *  0       0       DA      SA      BSSID   -       IBSS/DLS
+ *  0       1       DA      BSSID   SA      -       AP -> STA
+ *  1       0       BSSID   SA      DA      -       AP <- STA
+ *  1       1       RA      TA      DA      SA      unspecified (WDS)
+ */
+
+#define FCS_LEN  4
+
+#define IEEE80211_FCTL_VERS                 0x0003
+#define IEEE80211_FCTL_FTYPE                0x000c
+#define IEEE80211_FCTL_STYPE                0x00f0
+#define IEEE80211_FCTL_TODS                 0x0100
+#define IEEE80211_FCTL_FROMDS               0x0200
+#define IEEE80211_FCTL_MOREFRAGS            0x0400
+#define IEEE80211_FCTL_RETRY                0x0800
+#define IEEE80211_FCTL_PM                   0x1000
+#define IEEE80211_FCTL_MOREDATA             0x2000
+#define IEEE80211_FCTL_PROTECTED            0x4000
+#define IEEE80211_FCTL_ORDER                0x8000
+#define IEEE80211_FCTL_CTL_EXT              0x0f00
+
+#define IEEE80211_SCTL_FRAG                 0x000F
+#define IEEE80211_SCTL_SEQ                  0xFFF0
+
+#define IEEE80211_FTYPE_MGMT                0x0000
+#define IEEE80211_FTYPE_CTL                 0x0004
+#define IEEE80211_FTYPE_DATA                0x0008
+#define IEEE80211_FTYPE_EXT                 0x000c
+
+/* management */
+
+#define IEEE80211_STYPE_ASSOC_REQ           0x0000
+#define IEEE80211_STYPE_ASSOC_RESP          0x0010
+#define IEEE80211_STYPE_REASSOC_REQ         0x0020
+#define IEEE80211_STYPE_REASSOC_RESP        0x0030
+#define IEEE80211_STYPE_PROBE_REQ           0x0040
+#define IEEE80211_STYPE_PROBE_RESP          0x0050
+#define IEEE80211_STYPE_BEACON              0x0080
+#define IEEE80211_STYPE_ATIM                0x0090
+#define IEEE80211_STYPE_DISASSOC            0x00A0
+#define IEEE80211_STYPE_AUTH                0x00B0
+#define IEEE80211_STYPE_DEAUTH              0x00C0
+#define IEEE80211_STYPE_ACTION              0x00D0
+
+/* control */
+
+#define IEEE80211_STYPE_CTL_EXT             0x0060
+#define IEEE80211_STYPE_BACK_REQ            0x0080
+#define IEEE80211_STYPE_BACK                0x0090
+#define IEEE80211_STYPE_PSPOLL              0x00A0
+#define IEEE80211_STYPE_RTS                 0x00B0
+#define IEEE80211_STYPE_CTS                 0x00C0
+#define IEEE80211_STYPE_ACK                 0x00D0
+#define IEEE80211_STYPE_CFEND               0x00E0
+#define IEEE80211_STYPE_CFENDACK            0x00F0
+
+/* data */
+
+#define IEEE80211_STYPE_DATA                0x0000
+#define IEEE80211_STYPE_DATA_CFACK          0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL         0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL      0x0030
+#define IEEE80211_STYPE_NULLFUNC            0x0040
+#define IEEE80211_STYPE_CFACK               0x0050
+#define IEEE80211_STYPE_CFPOLL              0x0060
+#define IEEE80211_STYPE_CFACKPOLL           0x0070
+#define IEEE80211_STYPE_QOS_DATA            0x0080
+#define IEEE80211_STYPE_QOS_DATA_CFACK      0x0090
+#define IEEE80211_STYPE_QOS_DATA_CFPOLL     0x00A0
+#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL  0x00B0
+#define IEEE80211_STYPE_QOS_NULLFUNC        0x00C0
+#define IEEE80211_STYPE_QOS_CFACK           0x00D0
+#define IEEE80211_STYPE_QOS_CFPOLL          0x00E0
+#define IEEE80211_STYPE_QOS_CFACKPOLL       0x00F0
+
+/* extension, added by 802.11ad */
+
+#define IEEE80211_STYPE_DMG_BEACON          0x0000
+#define IEEE80211_STYPE_S1G_BEACON          0x0010
+
+/* bits unique to S1G beacon */
+
+#define IEEE80211_S1G_BCN_NEXT_TBTT         0x100
+
+/* see 802.11ah-2016 9.9 NDP CMAC frames */
+
+#define IEEE80211_S1G_1MHZ_NDP_BITS         25
+#define IEEE80211_S1G_1MHZ_NDP_BYTES        4
+#define IEEE80211_S1G_2MHZ_NDP_BITS         37
+#define IEEE80211_S1G_2MHZ_NDP_BYTES        5
+
+#define IEEE80211_NDP_FTYPE_CTS             0
+#define IEEE80211_NDP_FTYPE_CF_END          0
+#define IEEE80211_NDP_FTYPE_PS_POLL         1
+#define IEEE80211_NDP_FTYPE_ACK             2
+#define IEEE80211_NDP_FTYPE_PS_POLL_ACK     3
+#define IEEE80211_NDP_FTYPE_BA              4
+#define IEEE80211_NDP_FTYPE_BF_REPORT_POLL  5
+#define IEEE80211_NDP_FTYPE_PAGING          6
+#define IEEE80211_NDP_FTYPE_PREQ            7
+
+#define SM64(f,v) ((((uint64_t)v) << f##_S) & f)
+
+/* NDP CMAC frame fields */
+
+#define IEEE80211_NDP_FTYPE                 0x0000000000000007
+#define IEEE80211_NDP_FTYPE_S               0x0000000000000000
+
+/* 1M Probe Request 11ah 9.9.3.1.1 */
+
+#define IEEE80211_NDP_1M_PREQ_ANO           0x0000000000000008
+#define IEEE80211_NDP_1M_PREQ_ANO_S         3
+#define IEEE80211_NDP_1M_PREQ_CSSID         0x00000000000FFFF0
+#define IEEE80211_NDP_1M_PREQ_CSSID_S       4
+#define IEEE80211_NDP_1M_PREQ_RTYPE         0x0000000000100000
+#define IEEE80211_NDP_1M_PREQ_RTYPE_S       20
+#define IEEE80211_NDP_1M_PREQ_RSV           0x0000000001E00000
+#define IEEE80211_NDP_1M_PREQ_RSV           0x0000000001E00000
+
+/* 2M Probe Request 11ah 9.9.3.1.2 */
+
+#define IEEE80211_NDP_2M_PREQ_ANO           0x0000000000000008
+#define IEEE80211_NDP_2M_PREQ_ANO_S         3
+#define IEEE80211_NDP_2M_PREQ_CSSID         0x0000000FFFFFFFF0
+#define IEEE80211_NDP_2M_PREQ_CSSID_S       4
+#define IEEE80211_NDP_2M_PREQ_RTYPE         0x0000001000000000
+#define IEEE80211_NDP_2M_PREQ_RTYPE_S       36
+
+#define IEEE80211_ANO_NETTYPE_WILD          15
+
+/* bits unique to S1G beacon */
+
+#define IEEE80211_S1G_BCN_NEXT_TBTT         0x100
+
+/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */
+
+#define IEEE80211_CTL_EXT_POLL              0x2000
+#define IEEE80211_CTL_EXT_SPR               0x3000
+#define IEEE80211_CTL_EXT_GRANT             0x4000
+#define IEEE80211_CTL_EXT_DMG_CTS           0x5000
+#define IEEE80211_CTL_EXT_DMG_DTS           0x6000
+#define IEEE80211_CTL_EXT_SSW               0x8000
+#define IEEE80211_CTL_EXT_SSW_FBACK         0x9000
+#define IEEE80211_CTL_EXT_SSW_ACK           0xa000
+
+#define IEEE80211_SN_MASK   ((IEEE80211_SCTL_SEQ) >> 4)
+#define IEEE80211_MAX_SN    IEEE80211_SN_MASK
+#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1)
+
+/* PV1 Layout 11ah 9.8.3.1 */
+#define IEEE80211_PV1_FCTL_VERS             0x0003
+#define IEEE80211_PV1_FCTL_FTYPE            0x001c
+#define IEEE80211_PV1_FCTL_STYPE            0x00e0
+#define IEEE80211_PV1_FCTL_TODS             0x0100
+#define IEEE80211_PV1_FCTL_MOREFRAGS        0x0200
+#define IEEE80211_PV1_FCTL_PM               0x0400
+#define IEEE80211_PV1_FCTL_MOREDATA         0x0800
+#define IEEE80211_PV1_FCTL_PROTECTED        0x1000
+#define IEEE80211_PV1_FCTL_END_SP           0x2000
+#define IEEE80211_PV1_FCTL_RELAYED          0x4000
+#define IEEE80211_PV1_FCTL_ACK_POLICY       0x8000
+#define IEEE80211_PV1_FCTL_CTL_EXT          0x0f00
+
+static inline bool ieee80211_sn_less(uint16_t sn1, uint16_t sn2)
+{
+  return ((sn1 - sn2) & IEEE80211_SN_MASK) > (IEEE80211_SN_MODULO >> 1);
+}
+
+static inline uint16_t ieee80211_sn_add(uint16_t sn1, uint16_t sn2)
+{
+  return (sn1 + sn2) & IEEE80211_SN_MASK;
+}
+
+static inline uint16_t ieee80211_sn_inc(uint16_t sn)
+{
+  return ieee80211_sn_add(sn, 1);
+}
+
+static inline uint16_t ieee80211_sn_sub(uint16_t sn1, uint16_t sn2)
+{
+  return (sn1 - sn2) & IEEE80211_SN_MASK;
+}
+
+#define IEEE80211_SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+#define IEEE80211_SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
+
+/* miscellaneous IEEE 802.11 constants */
+
+#define IEEE80211_MAX_FRAG_THRESHOLD        2352
+#define IEEE80211_MAX_RTS_THRESHOLD         2353
+#define IEEE80211_MAX_AID                   2007
+#define IEEE80211_MAX_AID_S1G               8191
+#define IEEE80211_MAX_TIM_LEN               251
+#define IEEE80211_MAX_MESH_PEERINGS         63
+
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+ * 6.2.1.1.2.
+ * 802.11e clarifies the figure in section 7.1.2. The frame body is
+ * up to 2304 octets long (maximum MSDU size) plus any crypt overhead.
+ */
+
+#define IEEE80211_MAX_DATA_LEN              2304
+
+/* 802.11ad extends maximum MSDU size for DMG (freq > 40Ghz) networks
+ * to 7920 bytes, see 8.2.3 General frame format
+ */
+
+#define IEEE80211_MAX_DATA_LEN_DMG          7920
+
+/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU,
+ * 12 byte crypt, 4 byte FCS
+ */
+
+#define IEEE80211_MAX_FRAME_LEN             2352
+
+/* Maximal size of an A-MSDU that can be transported in a HT BA session */
+
+#define IEEE80211_MAX_MPDU_LEN_HT_BA        4095
+
+/* Maximal size of an A-MSDU */
+
+#define IEEE80211_MAX_MPDU_LEN_HT_3839      3839
+#define IEEE80211_MAX_MPDU_LEN_HT_7935      7935
+
+#define IEEE80211_MAX_MPDU_LEN_VHT_3895     3895
+#define IEEE80211_MAX_MPDU_LEN_VHT_7991     7991
+#define IEEE80211_MAX_MPDU_LEN_VHT_11454    11454
+
+#define IEEE80211_MAX_SSID_LEN              32
+
+#define IEEE80211_MAX_MESH_ID_LEN           32
+
+#define IEEE80211_FIRST_TSPEC_TSID          8
+#define IEEE80211_NUM_TIDS                  16
+
+/* number of user priorities 802.11 uses */
+
+#define IEEE80211_NUM_UPS                   8
+
+/* number of ACs */
+
+#define IEEE80211_NUM_ACS                   4
+
+#define IEEE80211_QOS_CTL_LEN               2
+
+/* 1d tag mask */
+
+#define IEEE80211_QOS_CTL_TAG1D_MASK        0x0007
+
+/* TID mask */
+
+#define IEEE80211_QOS_CTL_TID_MASK          0x000f
+
+/* EOSP */
+
+#define IEEE80211_QOS_CTL_EOSP              0x0010
+
+/* ACK policy */
+
+#define IEEE80211_QOS_CTL_ACK_POLICY_NORMAL   0x0000
+#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK    0x0020
+#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL  0x0040
+#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060
+#define IEEE80211_QOS_CTL_ACK_POLICY_MASK     0x0060
+
+/* A-MSDU 802.11n */
+
+#define IEEE80211_QOS_CTL_A_MSDU_PRESENT    0x0080
+
+/* Mesh Control 802.11s */
+
+#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
+
+/* Mesh Power Save Level */
+
+#define IEEE80211_QOS_CTL_MESH_PS_LEVEL     0x0200
+
+/* Mesh Receiver Service Period Initiated */
+
+#define IEEE80211_QOS_CTL_RSPI              0x0400
+
+/* U-APSD queue for WMM IEs sent by AP */
+
+#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD              (1<<7)
+#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
+
+/* U-APSD queues for WMM IEs sent by STA */
+
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO   (1<<0)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI   (1<<1)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK   (1<<2)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE   (1<<3)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK 0x0f
+
+/* U-APSD max SP length for WMM IEs sent by STA */
+
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL   0x00
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_2     0x01
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_4     0x02
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_6     0x03
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK  0x03
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT 5
+
+#define IEEE80211_HT_CTL_LEN  4
+
+struct ieee80211_hdr
+{
+  uint16_t frame_control;
+  uint16_t duration_id;
+  uint8_t addr1[ETH_ALEN];
+  uint8_t addr2[ETH_ALEN];
+  uint8_t addr3[ETH_ALEN];
+  uint16_t seq_ctrl;
+  uint8_t addr4[ETH_ALEN];
+};
+
+struct ieee80211_hdr_3addr
+{
+  uint16_t frame_control;
+  uint16_t duration_id;
+  uint8_t addr1[ETH_ALEN];
+  uint8_t addr2[ETH_ALEN];
+  uint8_t addr3[ETH_ALEN];
+  uint16_t seq_ctrl;
+};
+
+struct ieee80211_qos_hdr
+{
+  uint16_t frame_control;
+  uint16_t duration_id;
+  uint8_t addr1[ETH_ALEN];
+  uint8_t addr2[ETH_ALEN];
+  uint8_t addr3[ETH_ALEN];
+  uint16_t seq_ctrl;
+  uint16_t qos_ctrl;
+};
+
+/* ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_tods(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0;
+}
+
+/* ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_fromds(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0;
+}
+
+/* ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and
+ *                    IEEE80211_FCTL_FROMDS are set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_a4(uint16_t fc)
+{
+  uint16_t tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
+  return (fc & tmp) == tmp;
+}
+
+/* ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_morefrags(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0;
+}
+
+/* ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_retry(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0;
+}
+
+/* ieee80211_has_pm - check if IEEE80211_FCTL_PM is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_pm(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0;
+}
+
+/* ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_moredata(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0;
+}
+
+/* ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_protected(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0;
+}
+
+/* ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_has_order(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0;
+}
+
+/* ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_mgmt(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT);
+}
+
+/* ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_ctl(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL);
+}
+
+/* ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_data(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_DATA);
+}
+
+/* ieee80211_is_ext - check if type is IEEE80211_FTYPE_EXT
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_ext(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_EXT);
+}
+
+/* ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA
+ *                         and IEEE80211_STYPE_QOS_DATA is set
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_data_qos(uint16_t fc)
+{
+  /* mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need
+   * to check the one bit
+   */
+
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE |
+                           IEEE80211_STYPE_QOS_DATA)) ==
+    cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA);
+}
+
+/* ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA
+ *                             and has data
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_data_present(uint16_t fc)
+{
+  /* mask with 0x40 and test that that bit is clear to only return true
+   * for the data-containing substypes.
+   */
+
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) ==
+    cpu_to_le16(IEEE80211_FTYPE_DATA);
+}
+
+/* ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT &&
+ *                                   IEEE80211_STYPE_ASSOC_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_assoc_req(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
+}
+
+/* ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT &&
+ *                                    IEEE80211_STYPE_ASSOC_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_assoc_resp(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP);
+}
+
+/* ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT &&
+ *                                     IEEE80211_STYPE_REASSOC_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_reassoc_req(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ);
+}
+
+/* ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT &&
+ *                                      IEEE80211_STYPE_REASSOC_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_reassoc_resp(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP);
+}
+
+/* ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT &&
+ *                                   IEEE80211_STYPE_PROBE_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_probe_req(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ);
+}
+
+/* ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT &&
+ *                                    IEEE80211_STYPE_PROBE_RESP
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_probe_resp(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
+}
+
+/* ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT &&
+ *                                IEEE80211_STYPE_BEACON
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_beacon(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+}
+
+/* ieee80211_is_s1g_beacon - check if IEEE80211_FTYPE_EXT &&
+ * IEEE80211_STYPE_S1G_BEACON
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_s1g_beacon(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE |
+        IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON);
+}
+
+/* ieee80211_next_tbtt_present - check if IEEE80211_FTYPE_EXT &&
+ * IEEE80211_STYPE_S1G_BEACON && IEEE80211_S1G_BCN_NEXT_TBTT
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_next_tbtt_present(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON) &&
+    fc & cpu_to_le16(IEEE80211_S1G_BCN_NEXT_TBTT);
+}
+
+/* ieee80211_is_s1g_short_beacon - check if next tbtt present bit is set.
+ * Only true for S1G beacons when they're short.
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_s1g_short_beacon(uint16_t fc)
+{
+  return ieee80211_is_s1g_beacon(fc) && ieee80211_next_tbtt_present(fc);
+}
+
+/* ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_atim(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM);
+}
+
+/* ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT &&
+ *                                  IEEE80211_STYPE_DISASSOC
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_disassoc(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC);
+}
+
+/* ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_auth(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+}
+
+/* ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT &&
+ *                                IEEE80211_STYPE_DEAUTH
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_deauth(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
+}
+
+/* ieee80211_is_action - check if IEEE80211_FTYPE_MGMT &&
+ *                                IEEE80211_STYPE_ACTION
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_action(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
+}
+
+/* ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL &&
+ *                                  IEEE80211_STYPE_BACK_REQ
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_back_req(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ);
+}
+
+/* ieee80211_is_back - check if IEEE80211_FTYPE_CTL &&
+ *                              IEEE80211_STYPE_BACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_back(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);
+}
+
+/* ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL &&
+ *                                IEEE80211_STYPE_PSPOLL
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_pspoll(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+}
+
+/* ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_rts(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+}
+
+/* ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_cts(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+}
+
+/* ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_ack(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK);
+}
+
+/* ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_cfend(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND);
+}
+
+/* ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL &&
+ *                                  IEEE80211_STYPE_CFENDACK
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_cfendack(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK);
+}
+
+/* ieee80211_is_nullfunc - check if frame is a regular
+ *                         (non-QoS) nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_nullfunc(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC);
+}
+
+/* ieee80211_is_qos_nullfunc - check if frame is a QoS nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_qos_nullfunc(uint16_t fc)
+{
+  return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==
+    cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
+}
+
+/* ieee80211_is_any_nullfunc - check if frame is regular or QoS
+ *                             nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_any_nullfunc(uint16_t fc)
+{
+  return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
+}
+
+/* ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
+ * @fc: frame control field in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_bufferable_mmpdu(uint16_t fc)
+{
+  /* IEEE 802.11-2012, definition of "bufferable management frame";
+   * note that this ignores the IBSS special case.
+   */
+
+  return ieee80211_is_mgmt(fc) &&
+    (ieee80211_is_action(fc) ||
+     ieee80211_is_disassoc(fc) ||
+     ieee80211_is_deauth(fc));
+}
+
+/* ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
+ * @seq_ctrl: frame sequence control bytes in little-endian byteorder
+ */
+
+static inline bool ieee80211_is_first_frag(uint16_t seq_ctrl)
+{
+  return (seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0;
+}
+
+/* ieee80211_is_frag - check if a frame is a fragment
+ * @hdr: 802.11 header of the frame
+ */
+
+static inline bool ieee80211_is_frag(struct ieee80211_hdr *hdr)
+{
+  return ieee80211_has_morefrags(hdr->frame_control) ||
+    hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG);
+}
+
+struct ieee80211s_hdr
+{
+  uint8_t flags;
+  uint8_t ttl;
+  uint32_t seqnum;
+  uint8_t eaddr1[ETH_ALEN];
+  uint8_t eaddr2[ETH_ALEN];
+};
+
+/* Mesh flags */
+
+#define MESH_FLAGS_AE_A4    0x1
+#define MESH_FLAGS_AE_A5_A6 0x2
+#define MESH_FLAGS_AE       0x3
+#define MESH_FLAGS_PS_DEEP  0x4
+
+/* enum ieee80211_preq_flags - mesh PREQ element flags
+ *
+ * @IEEE80211_PREQ_PROACTIVE_PREP_FLAG: proactive PREP subfield
+ */
+
+enum ieee80211_preq_flags
+{
+  IEEE80211_PREQ_PROACTIVE_PREP_FLAG = 1 << 2,
+};
+
+/* enum ieee80211_preq_target_flags - mesh PREQ element per target flags
+ *
+ * @IEEE80211_PREQ_TO_FLAG: target only subfield
+ * @IEEE80211_PREQ_USN_FLAG: unknown target HWMP sequence number subfield
+ */
+
+enum ieee80211_preq_target_flags
+{
+  IEEE80211_PREQ_TO_FLAG  = 1 << 0,
+  IEEE80211_PREQ_USN_FLAG = 1 << 2,
+};
+
+/* struct ieee80211_quiet_ie
+ *
+ * This structure refers to "Quiet information element"
+ */
+
+struct ieee80211_quiet_ie
+{
+  uint8_t count;
+  uint8_t period;
+  uint16_t duration;
+  uint16_t offset;
+};
+
+/* struct ieee80211_msrment_ie
+ *
+ * This structure refers to "Measurement Request/Report information element"
+ */
+
+struct ieee80211_msrment_ie
+{
+  uint8_t token;
+  uint8_t mode;
+  uint8_t type;
+  uint8_t request[];
+};
+
+/* struct ieee80211_channel_sw_ie
+ *
+ * This structure refers to "Channel Switch Announcement information element"
+ */
+
+struct ieee80211_channel_sw_ie
+{
+  uint8_t mode;
+  uint8_t new_ch_num;
+  uint8_t count;
+};
+
+/* struct ieee80211_ext_chansw_ie
+ *
+ * This structure represents the
+ * "Extended Channel Switch Announcement element"
+ */
+
+struct ieee80211_ext_chansw_ie
+{
+  uint8_t mode;
+  uint8_t new_operating_class;
+  uint8_t new_ch_num;
+  uint8_t count;
+};
+
+/* struct ieee80211_sec_chan_offs_ie - secondary channel offset IE
+ * @sec_chan_offs: secondary channel offset,
+ *                 uses IEEE80211_HT_PARAM_CHA_SEC_* values here
+ * This structure represents the "Secondary Channel Offset element"
+ */
+
+struct ieee80211_sec_chan_offs_ie
+{
+  uint8_t sec_chan_offs;
+};
+
+/* struct ieee80211_mesh_chansw_params_ie - mesh channel switch parameters IE
+ *
+ * This structure represents the "Mesh Channel Switch Paramters element"
+ */
+
+struct ieee80211_mesh_chansw_params_ie
+{
+  uint8_t mesh_ttl;
+  uint8_t mesh_flags;
+  uint16_t mesh_reason;
+  uint16_t mesh_pre_value;
+};
+
+/* struct ieee80211_wide_bw_chansw_ie - wide bandwidth channel switch IE
+ */
+
+struct ieee80211_wide_bw_chansw_ie
+{
+  uint8_t new_channel_width;
+  uint8_t new_center_freq_seg0;
+  uint8_t new_center_freq_seg1;
+};
+
+/* struct ieee80211_tim
+ *
+ * This structure refers to "Traffic Indication Map information element"
+ */
+
+struct ieee80211_tim_ie
+{
+  uint8_t dtim_count;
+  uint8_t dtim_period;
+  uint8_t bitmap_ctrl;
+
+  /* variable size: 1 - 251 bytes */
+
+  uint8_t virtual_map[1];
+};
+
+/* struct ieee80211_meshconf_ie
+ *
+ * This structure refers to "Mesh Configuration information element"
+ */
+
+struct ieee80211_meshconf_ie
+{
+  uint8_t meshconf_psel;
+  uint8_t meshconf_pmetric;
+  uint8_t meshconf_congest;
+  uint8_t meshconf_synch;
+  uint8_t meshconf_auth;
+  uint8_t meshconf_form;
+  uint8_t meshconf_cap;
+};
+
+/* enum mesh_config_capab_flags
+ * Mesh Configuration IE capability field flags
+ *
+ * @IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS: STA is willing to establish
+ * additional mesh peerings with other mesh STAs
+ * @IEEE80211_MESHCONF_CAPAB_FORWARDING: the STA forwards MSDUs
+ * @IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING: TBTT adjustment procedure
+ * is ongoing
+ * @IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL:
+ *                        STA is in deep sleep mode or has
+ * neighbors in deep sleep mode
+ */
+
+enum mesh_config_capab_flags
+{
+  IEEE80211_MESHCONF_CAPAB_ACCEPT_PLINKS    = 0x01,
+  IEEE80211_MESHCONF_CAPAB_FORWARDING       = 0x08,
+  IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING   = 0x20,
+  IEEE80211_MESHCONF_CAPAB_POWER_SAVE_LEVEL = 0x40,
+};
+
+#define IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE 0x1
+
+/* mesh channel switch parameters element's flag indicator */
+
+#define WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT  BIT(0)
+#define WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR    BIT(1)
+#define WLAN_EID_CHAN_SWITCH_PARAM_REASON       BIT(2)
+
+/* struct ieee80211_rann_ie
+ *
+ * This structure refers to "Root Announcement information element"
+ */
+
+struct ieee80211_rann_ie
+{
+  uint8_t rann_flags;
+  uint8_t rann_hopcount;
+  uint8_t rann_ttl;
+  uint8_t rann_addr[ETH_ALEN];
+  uint32_t rann_seq;
+  uint32_t rann_interval;
+  uint32_t rann_metric;
+};
+
+enum ieee80211_rann_flags
+{
+  RANN_FLAG_IS_GATE = 1 << 0,
+};
+
+enum ieee80211_ht_chanwidth_values
+{
+  IEEE80211_HT_CHANWIDTH_20MHZ  = 0,
+  IEEE80211_HT_CHANWIDTH_ANY    = 1,
+};
+
+/* enum ieee80211_opmode_bits - VHT operating mode field bits
+ * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK: channel width mask
+ * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: 20 MHz channel width
+ * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ: 40 MHz channel width
+ * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ: 80 MHz channel width
+ * @IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ: 160 MHz or 80+80 MHz channel
+ *                                           width
+ * @IEEE80211_OPMODE_NOTIF_BW_160_80P80: 160 / 80+80 MHz indicator flag
+ * @IEEE80211_OPMODE_NOTIF_RX_NSS_MASK: number of spatial streams mask
+ * (the NSS value is the value of this field + 1)
+ * @IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT: number of spatial streams shift
+ * @IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF: indicates streams in SU-MIMO PPDU
+ * using a beamforming steering matrix
+ */
+
+enum ieee80211_vht_opmode_bits
+{
+  IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK   = 0x03,
+  IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ  = 0,
+  IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ  = 1,
+  IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ  = 2,
+  IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ = 3,
+  IEEE80211_OPMODE_NOTIF_BW_160_80P80     = 0x04,
+  IEEE80211_OPMODE_NOTIF_RX_NSS_MASK      = 0x70,
+  IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT     = 4,
+  IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF   = 0x80,
+};
+
+/* enum ieee80211_s1g_chanwidth
+ * These are defined in IEEE802.11-2016ah Table 10-20
+ * as BSS Channel Width
+ *
+ * @IEEE80211_S1G_CHANWIDTH_1MHZ: 1MHz operating channel
+ * @IEEE80211_S1G_CHANWIDTH_2MHZ: 2MHz operating channel
+ * @IEEE80211_S1G_CHANWIDTH_4MHZ: 4MHz operating channel
+ * @IEEE80211_S1G_CHANWIDTH_8MHZ: 8MHz operating channel
+ * @IEEE80211_S1G_CHANWIDTH_16MHZ: 16MHz operating channel
+ */
+
+enum ieee80211_s1g_chanwidth
+{
+  IEEE80211_S1G_CHANWIDTH_1MHZ  = 0,
+  IEEE80211_S1G_CHANWIDTH_2MHZ  = 1,
+  IEEE80211_S1G_CHANWIDTH_4MHZ  = 3,
+  IEEE80211_S1G_CHANWIDTH_8MHZ  = 7,
+  IEEE80211_S1G_CHANWIDTH_16MHZ = 15,
+};
+
+#define WLAN_SA_QUERY_TR_ID_LEN 2
+#define WLAN_MEMBERSHIP_LEN     8
+#define WLAN_USER_POSITION_LEN 16
+
+/* struct ieee80211_tpc_report_ie
+ *
+ * This structure refers to "TPC Report element"
+ */
+
+struct ieee80211_tpc_report_ie
+{
+  uint8_t tx_power;
+  uint8_t link_margin;
+};
+
+#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK   GENMASK(2, 1)
+#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_SHIFT  1
+#define IEEE80211_ADDBA_EXT_NO_FRAG           BIT(0)
+
+struct ieee80211_addba_ext_ie
+{
+  uint8_t data;
+};
+
+/* struct ieee80211_s1g_bcn_compat_ie
+ *
+ * S1G Beacon Compatibility element
+ */
+
+struct ieee80211_s1g_bcn_compat_ie
+{
+  uint16_t compat_info;
+  uint16_t beacon_int;
+  uint32_t tsf_completion;
+};
+
+/* struct ieee80211_s1g_oper_ie
+ *
+ * S1G Operation element
+ */
+
+struct ieee80211_s1g_oper_ie
+{
+  uint8_t ch_width;
+  uint8_t oper_class;
+  uint8_t primary_ch;
+  uint8_t oper_ch;
+  uint16_t basic_mcs_nss;
+};
+
+/* struct ieee80211_aid_response_ie
+ *
+ * AID Response element
+ */
+
+struct ieee80211_aid_response_ie
+{
+  uint16_t aid;
+  uint8_t switch_count;
+  uint16_t response_int;
+};
+
+struct ieee80211_s1g_cap
+{
+  uint8_t capab_info[10];
+  uint8_t supp_mcs_nss[5];
+};
+
+struct ieee80211_ext
+{
+  uint16_t frame_control;
+  uint16_t duration;
+  union
+    {
+      struct
+        {
+          uint8_t sa[ETH_ALEN];
+          uint32_t timestamp;
+          uint8_t change_seq;
+          uint8_t variable[0];
+        } s1g_beacon;
+      struct
+        {
+          uint8_t sa[ETH_ALEN];
+          uint32_t timestamp;
+          uint8_t change_seq;
+          uint8_t next_tbtt[3];
+          uint8_t variable[0];
+        } s1g_short_beacon;
+    } u;
+};
+
+struct ieee80211_mgmt
+{
+  uint16_t frame_control;
+  uint16_t duration;
+  uint8_t da[ETH_ALEN];
+  uint8_t sa[ETH_ALEN];
+  uint8_t bssid[ETH_ALEN];
+  uint16_t seq_ctrl;
+  union
+    {
+      struct
+        {
+          uint16_t auth_alg;
+          uint16_t auth_transaction;
+          uint16_t status_code;
+
+          /* possibly followed by Challenge text */
+
+          uint8_t variable[0];
+        } auth;
+      struct
+        {
+          uint16_t reason_code;
+        } deauth;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t listen_interval;
+
+          /* followed by SSID and Supported rates */
+
+          uint8_t variable[0];
+        } assoc_req;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t status_code;
+          uint16_t aid;
+
+          /* followed by Supported rates */
+
+          uint8_t variable[0];
+        } assoc_resp;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t status_code;
+          uint16_t aid;
+
+          /* followed by Supported rates */
+
+          uint8_t variable[0];
+        } reassoc_resp;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t status_code;
+          uint8_t variable[0];
+        } s1g_assoc_resp;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t status_code;
+          uint8_t variable[0];
+        } s1g_reassoc_resp;
+      struct
+        {
+          uint16_t capab_info;
+          uint16_t listen_interval;
+          uint8_t current_ap[ETH_ALEN];
+
+          /* followed by SSID and Supported rates */
+
+          uint8_t variable[0];
+        } reassoc_req;
+      struct
+        {
+          uint16_t reason_code;
+        } disassoc;
+      struct
+        {
+          uint64_t timestamp;
+          uint16_t beacon_int;
+          uint16_t capab_info;
+
+          /* followed by some of SSID, Supported rates,
+           * FH Params, DS Params, CF Params, IBSS Params, TIM
+           */
+
+          uint8_t variable[0];
+        } beacon;
+      struct
+        {
+          /* only variable items: SSID, Supported rates */
+
+          uint8_t variable[0];
+        } probe_req;
+      struct
+        {
+          uint64_t timestamp;
+          uint16_t beacon_int;
+          uint16_t capab_info;
+
+          /* followed by some of SSID, Supported rates,
+           * FH Params, DS Params, CF Params, IBSS Params
+           */
+
+          uint8_t variable[0];
+        } probe_resp;
+
+      struct
+        {
+          uint8_t category;
+          union
+            {
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint8_t status_code;
+                  uint8_t variable[0];
+                } wme_action;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t variable[0];
+                } chan_switch;
+              struct
+                {
+                  uint8_t action_code;
+                  struct ieee80211_ext_chansw_ie data;
+                  uint8_t variable[0];
+                } ext_chan_switch;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint8_t element_id;
+                  uint8_t length;
+                  struct ieee80211_msrment_ie msr_elem;
+                } measurement;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint16_t capab;
+                  uint16_t timeout;
+                  uint16_t start_seq_num;
+
+                  /* followed by BA Extension */
+
+                  uint8_t variable[0];
+                } addba_req;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint16_t status;
+                  uint16_t capab;
+                  uint16_t timeout;
+                } addba_resp;
+              struct
+                {
+                  uint8_t action_code;
+                  uint16_t params;
+                  uint16_t reason_code;
+                } delba;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t variable[0];
+                } self_prot;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t variable[0];
+                } mesh_action;
+              struct
+                {
+                  uint8_t action;
+                  uint8_t trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+                } sa_query;
+              struct
+                {
+                  uint8_t action;
+                  uint8_t smps_control;
+                } ht_smps;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t chanwidth;
+                } ht_notify_cw;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint16_t capability;
+                  uint8_t variable[0];
+                } tdls_discover_resp;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t operating_mode;
+                } vht_opmode_notif;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t membership[WLAN_MEMBERSHIP_LEN];
+                  uint8_t position[WLAN_USER_POSITION_LEN];
+                } vht_group_notif;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint8_t tpc_elem_id;
+                  uint8_t tpc_elem_length;
+                  struct ieee80211_tpc_report_ie tpc;
+                } tpc_report;
+              struct
+                {
+                  uint8_t action_code;
+                  uint8_t dialog_token;
+                  uint8_t follow_up;
+                  uint8_t tod[6];
+                  uint8_t toa[6];
+                  uint16_t tod_error;
+                  uint16_t toa_error;
+                  uint8_t variable[0];
+                } ftm;
+            } u;
+        } action;
+    } u;
+};
+
+/* Supported rates membership selectors */
+
+#define BSS_MEMBERSHIP_SELECTOR_HT_PHY  127
+#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
+#define BSS_MEMBERSHIP_SELECTOR_HE_PHY  122
+#define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123
+
+/* mgmt header + 1 byte category code */
+
+#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
+
+/* Management MIC information element (IEEE 802.11w) */
+
+struct ieee80211_mmie
+{
+  uint8_t element_id;
+  uint8_t length;
+  uint16_t key_id;
+  uint8_t sequence_number[6];
+  uint8_t mic[8];
+};
+
+/* Management MIC information element (IEEE 802.11w) for GMAC and CMAC-256 */
+
+struct ieee80211_mmie_16
+{
+  uint8_t element_id;
+  uint8_t length;
+  uint16_t key_id;
+  uint8_t sequence_number[6];
+  uint8_t mic[16];
+};
+
+struct ieee80211_vendor_ie
+{
+  uint8_t element_id;
+  uint8_t len;
+  uint8_t oui[3];
+  uint8_t oui_type;
+};
+
+struct ieee80211_wmm_ac_param
+{
+  uint8_t aci_aifsn;  /* AIFSN, ACM, ACI */
+  uint8_t cw;         /* ECWmin, ECWmax (CW = 2^ECW - 1) */
+  uint16_t txop_limit;
+};
+
+struct ieee80211_wmm_param_ie
+{
+  uint8_t element_id;   /* Element ID: 221 (0xdd); */
+  uint8_t len;          /* Length: 24 */
+
+  /* required fields for WMM version 1 */
+
+  uint8_t oui[3];       /* 00:50:f2 */
+  uint8_t oui_type;     /* 2 */
+  uint8_t oui_subtype;  /* 1 */
+  uint8_t version;      /* 1 for WMM version 1.0 */
+  uint8_t qos_info;     /* AP/STA specific QoS info */
+  uint8_t reserved;     /* 0 */
+
+  /* AC_BE, AC_BK, AC_VI, AC_VO */
+
+  struct ieee80211_wmm_ac_param ac[4];
+};
+
+/* Control frames */
+
+struct ieee80211_rts
+{
+  uint16_t frame_control;
+  uint16_t duration;
+  uint8_t ra[ETH_ALEN];
+  uint8_t ta[ETH_ALEN];
+};
+
+struct ieee80211_cts
+{
+  uint16_t frame_control;
+  uint16_t duration;
+  uint8_t ra[ETH_ALEN];
+};
+
+struct ieee80211_pspoll
+{
+  uint16_t frame_control;
+  uint16_t aid;
+  uint8_t bssid[ETH_ALEN];
+  uint8_t ta[ETH_ALEN];
+};
+
+/* TDLS */
+
+/* Channel switch timing */
+
+struct ieee80211_ch_switch_timing
+{
+  uint16_t switch_time;
+  uint16_t switch_timeout;
+};
+
+/* Link-id information element */
+
+struct ieee80211_tdls_lnkie
+{
+  uint8_t ie_type; /* Link Identifier IE */
+  uint8_t ie_len;
+  uint8_t bssid[ETH_ALEN];
+  uint8_t init_sta[ETH_ALEN];
+  uint8_t resp_sta[ETH_ALEN];
+};
+
+struct ieee80211_tdls_data
+{
+  uint8_t da[ETH_ALEN];
+  uint8_t sa[ETH_ALEN];
+  uint16_t ether_type;
+  uint8_t payload_type;
+  uint8_t category;
+  uint8_t action_code;
+  union
+    {
+      struct
+        {
+          uint8_t dialog_token;
+          uint16_t capability;
+          uint8_t variable[0];
+        } setup_req;
+      struct
+        {
+          uint16_t status_code;
+          uint8_t dialog_token;
+          uint16_t capability;
+          uint8_t variable[0];
+        } setup_resp;
+      struct
+        {
+          uint16_t status_code;
+          uint8_t dialog_token;
+          uint8_t variable[0];
+        } setup_cfm;
+      struct
+        {
+          uint16_t reason_code;
+          uint8_t variable[0];
+        } teardown;
+      struct
+        {
+          uint8_t dialog_token;
+          uint8_t variable[0];
+        } discover_req;
+      struct
+        {
+          uint8_t target_channel;
+          uint8_t oper_class;
+          uint8_t variable[0];
+        } chan_switch_req;
+      struct
+        {
+          uint16_t status_code;
+          uint8_t variable[0];
+        } chan_switch_resp;
+    } u;
+};
+
+/* Peer-to-Peer IE attribute related definitions.
+ */
+
+/* enum ieee80211_p2p_attr_id - identifies type of peer-to-peer attribute.
+ */
+
+enum ieee80211_p2p_attr_id
+{
+  IEEE80211_P2P_ATTR_STATUS = 0,
+  IEEE80211_P2P_ATTR_MINOR_REASON,
+  IEEE80211_P2P_ATTR_CAPABILITY,
+  IEEE80211_P2P_ATTR_DEVICE_ID,
+  IEEE80211_P2P_ATTR_GO_INTENT,
+  IEEE80211_P2P_ATTR_GO_CONFIG_TIMEOUT,
+  IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
+  IEEE80211_P2P_ATTR_GROUP_BSSID,
+  IEEE80211_P2P_ATTR_EXT_LISTEN_TIMING,
+  IEEE80211_P2P_ATTR_INTENDED_IFACE_ADDR,
+  IEEE80211_P2P_ATTR_MANAGABILITY,
+  IEEE80211_P2P_ATTR_CHANNEL_LIST,
+  IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+  IEEE80211_P2P_ATTR_DEVICE_INFO,
+  IEEE80211_P2P_ATTR_GROUP_INFO,
+  IEEE80211_P2P_ATTR_GROUP_ID,
+  IEEE80211_P2P_ATTR_INTERFACE,
+  IEEE80211_P2P_ATTR_OPER_CHANNEL,
+  IEEE80211_P2P_ATTR_INVITE_FLAGS,
+
+  /* 19 - 220: Reserved */
+
+  IEEE80211_P2P_ATTR_VENDOR_SPECIFIC = 221,
+
+  IEEE80211_P2P_ATTR_MAX
+};
+
+/* Notice of Absence attribute - described in P2P spec 4.1.14 */
+
+/* Typical max value used here */
+
+#define IEEE80211_P2P_NOA_DESC_MAX 4
+
+struct ieee80211_p2p_noa_desc
+{
+  uint8_t count;
+  uint32_t duration;
+  uint32_t interval;
+  uint32_t start_time;
+};
+
+struct ieee80211_p2p_noa_attr
+{
+  uint8_t index;
+  uint8_t oppps_ctwindow;
+  struct ieee80211_p2p_noa_desc desc[IEEE80211_P2P_NOA_DESC_MAX];
+};
+
+#define IEEE80211_P2P_OPPPS_ENABLE_BIT  BIT(7)
+#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F
+
+/* struct ieee80211_bar - HT Block Ack Request
+ *
+ * This structure refers to "HT BlockAckReq" as
+ * described in 802.11n draft section 7.2.1.7.1
+ */
+
+struct ieee80211_bar
+{
+  uint16_t frame_control;
+  uint16_t duration;
+  uint8_t ra[ETH_ALEN];
+  uint8_t ta[ETH_ALEN];
+  uint16_t control;
+  uint16_t start_seq_num;
+};
+
+/* 802.11 BAR control masks */
+
+#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL    0x0000
+#define IEEE80211_BAR_CTRL_MULTI_TID            0x0002
+#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
+#define IEEE80211_BAR_CTRL_TID_INFO_MASK        0xf000
+#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT       12
+
+#define IEEE80211_HT_MCS_MASK_LEN  10
+
+/* struct ieee80211_mcs_info - MCS information
+ * @rx_mask: RX mask
+ * @rx_highest: highest supported RX rate. If set represents
+ * the highest supported RX data rate in units of 1 Mbps.
+ * If this field is 0 this value should not be used to
+ * consider the highest RX data rate supported.
+ * @tx_params: TX parameters
+ */
+
+struct ieee80211_mcs_info
+{
+  uint8_t rx_mask[IEEE80211_HT_MCS_MASK_LEN];
+  uint16_t rx_highest;
+  uint8_t tx_params;
+  uint8_t reserved[3];
+};
+
+/* 802.11n HT capability MSC set */
+
+#define IEEE80211_HT_MCS_RX_HIGHEST_MASK  0x3ff
+#define IEEE80211_HT_MCS_TX_DEFINED       0x01
+#define IEEE80211_HT_MCS_TX_RX_DIFF       0x02
+
+/* value 0 == 1 stream etc */
+
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK    0x0C
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT   2
+#define  IEEE80211_HT_MCS_TX_MAX_STREAMS        4
+#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION  0x10
+
+/* 802.11n D5.0 20.3.5 / 20.6 says:
+ * - indices 0 to 7 and 32 are single spatial stream
+ * - 8 to 31 are multiple spatial streams using equal modulation
+ *   [8..15 for two streams, 16..23 for three and 24..31 for four]
+ * - remainder are multiple spatial streams using unequal modulation
+ */
+
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \
+  (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8)
+
+/* struct ieee80211_ht_cap - HT capabilities
+ *
+ * This structure is the "HT capabilities element" as
+ * described in 802.11n D5.0 7.3.2.57
+ */
+
+struct ieee80211_ht_cap
+{
+  uint16_t cap_info;
+  uint8_t ampdu_params_info;
+
+  /* 16 bytes MCS information */
+
+  struct ieee80211_mcs_info mcs;
+
+  uint16_t extended_ht_cap_info;
+  uint32_t tx_bf_cap_info;
+  uint8_t antenna_selection_info;
+};
+
+/* 802.11n HT capabilities masks (for cap_info) */
+
+#define IEEE80211_HT_CAP_LDPC_CODING      0x0001
+#define IEEE80211_HT_CAP_SUP_WIDTH_20_40  0x0002
+#define IEEE80211_HT_CAP_SM_PS            0x000C
+#define  IEEE80211_HT_CAP_SM_PS_SHIFT     2
+#define IEEE80211_HT_CAP_GRN_FLD          0x0010
+#define IEEE80211_HT_CAP_SGI_20           0x0020
+#define IEEE80211_HT_CAP_SGI_40           0x0040
+#define IEEE80211_HT_CAP_TX_STBC          0x0080
+#define IEEE80211_HT_CAP_RX_STBC          0x0300
+#define  IEEE80211_HT_CAP_RX_STBC_SHIFT   8
+#define IEEE80211_HT_CAP_DELAY_BA         0x0400
+#define IEEE80211_HT_CAP_MAX_AMSDU        0x0800
+#define IEEE80211_HT_CAP_DSSSCCK40        0x1000
+#define IEEE80211_HT_CAP_RESERVED         0x2000
+#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000
+#define IEEE80211_HT_CAP_LSIG_TXOP_PROT   0x8000
+
+/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */
+
+#define IEEE80211_HT_EXT_CAP_PCO          0x0001
+#define IEEE80211_HT_EXT_CAP_PCO_TIME     0x0006
+#define  IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1
+#define IEEE80211_HT_EXT_CAP_MCS_FB       0x0300
+#define  IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8
+#define IEEE80211_HT_EXT_CAP_HTC_SUP      0x0400
+#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800
+
+/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+
+#define IEEE80211_HT_AMPDU_PARM_FACTOR    0x03
+#define IEEE80211_HT_AMPDU_PARM_DENSITY   0x1C
+#define  IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2
+
+/* Maximum length of AMPDU that the STA can receive in high-throughput (HT).
+ * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+
+enum ieee80211_max_ampdu_length_exp
+{
+  IEEE80211_HT_MAX_AMPDU_8K   = 0,
+  IEEE80211_HT_MAX_AMPDU_16K  = 1,
+  IEEE80211_HT_MAX_AMPDU_32K  = 2,
+  IEEE80211_HT_MAX_AMPDU_64K  = 3
+};
+
+/* Maximum length of AMPDU that the STA can receive in VHT.
+ * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+
+enum ieee80211_vht_max_ampdu_length_exp
+{
+  IEEE80211_VHT_MAX_AMPDU_8K    = 0,
+  IEEE80211_VHT_MAX_AMPDU_16K   = 1,
+  IEEE80211_VHT_MAX_AMPDU_32K   = 2,
+  IEEE80211_VHT_MAX_AMPDU_64K   = 3,
+  IEEE80211_VHT_MAX_AMPDU_128K  = 4,
+  IEEE80211_VHT_MAX_AMPDU_256K  = 5,
+  IEEE80211_VHT_MAX_AMPDU_512K  = 6,
+  IEEE80211_VHT_MAX_AMPDU_1024K = 7
+};
+
+#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
+
+/* Minimum MPDU start spacing */
+
+enum ieee80211_min_mpdu_spacing
+{
+  IEEE80211_HT_MPDU_DENSITY_NONE  = 0, /* No restriction */
+  IEEE80211_HT_MPDU_DENSITY_0_25  = 1, /* 1/4 usec */
+  IEEE80211_HT_MPDU_DENSITY_0_5   = 2, /* 1/2 usec */
+  IEEE80211_HT_MPDU_DENSITY_1     = 3, /* 1 usec */
+  IEEE80211_HT_MPDU_DENSITY_2     = 4, /* 2 usec */
+  IEEE80211_HT_MPDU_DENSITY_4     = 5, /* 4 usec */
+  IEEE80211_HT_MPDU_DENSITY_8     = 6, /* 8 usec */
+  IEEE80211_HT_MPDU_DENSITY_16    = 7  /* 16 usec */
+};
+
+/* struct ieee80211_ht_operation - HT operation IE
+ *
+ * This structure is the "HT operation element" as
+ * described in 802.11n-2009 7.3.2.57
+ */
+
+struct ieee80211_ht_operation
+{
+  uint8_t primary_chan;
+  uint8_t ht_param;
+  uint16_t operation_mode;
+  uint16_t stbc_param;
+  uint8_t basic_set[16];
+};
+
+/* for ht_param */
+
+#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET   0x03
+#define  IEEE80211_HT_PARAM_CHA_SEC_NONE    0x00
+#define  IEEE80211_HT_PARAM_CHA_SEC_ABOVE   0x01
+#define  IEEE80211_HT_PARAM_CHA_SEC_BELOW   0x03
+#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY   0x04
+#define IEEE80211_HT_PARAM_RIFS_MODE        0x08
+
+/* for operation_mode */
+
+#define IEEE80211_HT_OP_MODE_PROTECTION               0x0003
+#define  IEEE80211_HT_OP_MODE_PROTECTION_NONE         0
+#define  IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER    1
+#define  IEEE80211_HT_OP_MODE_PROTECTION_20MHZ        2
+#define  IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED  3
+#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT         0x0004
+#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT         0x0010
+#define IEEE80211_HT_OP_MODE_CCFS2_SHIFT              5
+#define IEEE80211_HT_OP_MODE_CCFS2_MASK               0x1fe0
+
+/* for stbc_param */
+
+#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON         0x0040
+#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT       0x0080
+#define IEEE80211_HT_STBC_PARAM_STBC_BEACON         0x0100
+#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT  0x0200
+#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE          0x0400
+#define IEEE80211_HT_STBC_PARAM_PCO_PHASE           0x0800
+
+/* block-ack parameters */
+
+#define IEEE80211_ADDBA_PARAM_AMSDU_MASK      0x0001
+#define IEEE80211_ADDBA_PARAM_POLICY_MASK     0x0002
+#define IEEE80211_ADDBA_PARAM_TID_MASK        0x003C
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK   0xFFC0
+#define IEEE80211_DELBA_PARAM_TID_MASK        0xF000
+#define IEEE80211_DELBA_PARAM_INITIATOR_MASK  0x0800
+
+/* A-MPDU buffer sizes
+ * According to HT size varies from 8 to 64 frames
+ * HE adds the ability to have up to 256 frames.
+ */
+
+#define IEEE80211_MIN_AMPDU_BUF     0x8
+#define IEEE80211_MAX_AMPDU_BUF_HT  0x40
+#define IEEE80211_MAX_AMPDU_BUF     0x100
+
+/* Spatial Multiplexing Power Save Modes (for capability) */
+
+#define WLAN_HT_CAP_SM_PS_STATIC    0
+#define WLAN_HT_CAP_SM_PS_DYNAMIC   1
+#define WLAN_HT_CAP_SM_PS_INVALID   2
+#define WLAN_HT_CAP_SM_PS_DISABLED  3
+
+/* for SM power control field lower two bits */
+
+#define WLAN_HT_SMPS_CONTROL_DISABLED 0
+#define WLAN_HT_SMPS_CONTROL_STATIC   1
+#define WLAN_HT_SMPS_CONTROL_DYNAMIC  3
+
+/* struct ieee80211_vht_mcs_info - VHT MCS information
+ * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
+ * @rx_highest: Indicates highest long GI VHT PPDU data rate
+ * STA can receive. Rate expressed in units of 1 Mbps.
+ * If this field is 0 this value should not be used to
+ * consider the highest RX data rate supported.
+ * The top 3 bits of this field indicate the Maximum NSTS,total
+ * (a beamformee capability.)
+ * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
+ * @tx_highest: Indicates highest long GI VHT PPDU data rate
+ * STA can transmit. Rate expressed in units of 1 Mbps.
+ * If this field is 0 this value should not be used to
+ * consider the highest TX data rate supported.
+ * The top 2 bits of this field are reserved, the
+ * 3rd bit from the top indiciates VHT Extended NSS BW
+ * Capability.
+ */
+
+struct ieee80211_vht_mcs_info
+{
+  uint16_t rx_mcs_map;
+  uint16_t rx_highest;
+  uint16_t tx_mcs_map;
+  uint16_t tx_highest;
+};
+
+/* for rx_highest */
+
+#define IEEE80211_VHT_MAX_NSTS_TOTAL_SHIFT 13
+#define IEEE80211_VHT_MAX_NSTS_TOTAL_MASK (7 << 
IEEE80211_VHT_MAX_NSTS_TOTAL_SHIFT)
+
+/* for tx_highest */
+
+#define IEEE80211_VHT_EXT_NSS_BW_CAPABLE (1 << 13)
+
+/* enum ieee80211_vht_mcs_support - VHT MCS support definitions
+ * @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the
+ * number of streams
+ * @IEEE80211_VHT_MCS_SUPPORT_0_8: MCSes 0-8 are supported
+ * @IEEE80211_VHT_MCS_SUPPORT_0_9: MCSes 0-9 are supported
+ * @IEEE80211_VHT_MCS_NOT_SUPPORTED: This number of streams isn't supported
+ *
+ * These definitions are used in each 2-bit subfield of the @rx_mcs_map
+ * and @tx_mcs_map fields of &struct ieee80211_vht_mcs_info, 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_vht_mcs_support
+{
+  IEEE80211_VHT_MCS_SUPPORT_0_7   = 0,
+  IEEE80211_VHT_MCS_SUPPORT_0_8   = 1,
+  IEEE80211_VHT_MCS_SUPPORT_0_9   = 2,
+  IEEE80211_VHT_MCS_NOT_SUPPORTED = 3,
+};
+
+/* struct ieee80211_vht_cap - VHT capabilities
+ *
+ * This structure is the "VHT capabilities element" as
+ * described in 802.11ac D3.0 8.4.2.160
+ * @vht_cap_info: VHT capability info
+ * @supp_mcs: VHT MCS supported rates
+ */
+
+struct ieee80211_vht_cap
+{
+  uint32_t vht_cap_info;
+  struct ieee80211_vht_mcs_info supp_mcs;
+};
+
+/**
+ * enum ieee80211_vht_chanwidth - VHT channel width
+ * @IEEE80211_VHT_CHANWIDTH_USE_HT: use the HT operation IE to
+ * determine the channel width (20 or 40 MHz)
+ * @IEEE80211_VHT_CHANWIDTH_80MHZ: 80 MHz bandwidth
+ * @IEEE80211_VHT_CHANWIDTH_160MHZ: 160 MHz bandwidth
+ * @IEEE80211_VHT_CHANWIDTH_80P80MHZ: 80+80 MHz bandwidth
+ */
+
+enum ieee80211_vht_chanwidth
+{
+  IEEE80211_VHT_CHANWIDTH_USE_HT    = 0,
+  IEEE80211_VHT_CHANWIDTH_80MHZ     = 1,
+  IEEE80211_VHT_CHANWIDTH_160MHZ    = 2,
+  IEEE80211_VHT_CHANWIDTH_80P80MHZ  = 3,
+};
+
+/* struct ieee80211_vht_operation - VHT operation IE
+ *
+ * This structure is the "VHT operation element" as
+ * described in 802.11ac D3.0 8.4.2.161
+ * @chan_width: Operating channel width
+ * @center_freq_seg0_idx: center freq segment 0 index
+ * @center_freq_seg1_idx: center freq segment 1 index
+ * @basic_mcs_set: VHT Basic MCS rate set
+ */
+
+struct ieee80211_vht_operation
+{
+  uint8_t chan_width;
+  uint8_t center_freq_seg0_idx;
+  uint8_t center_freq_seg1_idx;
+  uint16_t basic_mcs_set;
+};
+
+/* struct ieee80211_he_cap_elem - HE capabilities element
+ *
+ * This structure is the "HE capabilities element" fixed fields as
+ * described in P802.11ax_D4.0 section 9.4.2.242.2 and 9.4.2.242.3
+ */
+
+struct ieee80211_he_cap_elem
+{
+  uint8_t mac_cap_info[6];
+  uint8_t phy_cap_info[11];
+};
+
+#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
+{
+  uint16_t rx_mcs_80;
+  uint16_t tx_mcs_80;
+  uint16_t rx_mcs_160;
+  uint16_t tx_mcs_160;
+  uint16_t rx_mcs_80p80;
+  uint16_t tx_mcs_80p80;
+};
+
+/* struct ieee80211_he_operation - HE capabilities element
+ *
+ * This structure is the "HE operation element" fields as
+ * described in P802.11ax_D4.0 section 9.4.2.243
+ */
+
+struct ieee80211_he_operation
+{
+  uint32_t he_oper_params;
+  uint16_t he_mcs_nss_set;
+
+  /* Optional 0,1,3,4,5,7 or 8 bytes: depends on @he_oper_params */
 
-/* HT Extended Capabilities (see 7.3.2.57.5).*/
+  uint8_t optional[];
+};
+
+/* struct ieee80211_he_spr - HE spatial reuse element
+ *
+ * This structure is the "HE spatial reuse element" element as
+ * described in P802.11ax_D4.0 section 9.4.2.241
+ */
 
-#define IEEE80211_HTXCAP_PCO               0x0001
-#define IEEE80211_HTXCAP_PCOTT_MASK        0x0006
-#define IEEE80211_HTXCAP_PCOTT_SHIFT       1
-#define IEEE80211_HTXCAP_PCOTT_400         1
-#define IEEE80211_HTXCAP_PCOTT_1500        2
-#define IEEE80211_HTXCAP_PCOTT_5000        3
+struct ieee80211_he_spr
+{
+  uint8_t he_sr_control;
+
+  /* Optional 0 to 19 bytes: depends on @he_sr_control */
+
+  uint8_t optional[];
+};
 
-/* Bits 3-7 are reserved. */
+/* struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
+ *
+ * This structure is the "MU AC Parameter Record" fields as
+ * described in P802.11ax_D4.0 section 9.4.2.245
+ */
 
-#define IEEE80211_HTXCAP_MFB_MASK          0x0300
-#define IEEE80211_HTXCAP_MFB_SHIFT         8
-#define IEEE80211_HTXCAP_MFB_NONE          0
-#define IEEE80211_HTXCAP_MFB_UNSOL         2
-#define IEEE80211_HTXCAP_MFB_BOTH          3
-#define IEEE80211_HTXCAP_HTC               0x0400
-#define IEEE80211_HTXCAP_RDRESP            0x0800
+struct ieee80211_he_mu_edca_param_ac_rec
+{
+  uint8_t aifsn;
+  uint8_t ecw_min_max;
+  uint8_t mu_edca_timer;
+};
 
-/* Bits 12-15 are reserved. */
+/* struct ieee80211_mu_edca_param_set - MU EDCA Parameter Set element
+ *
+ * This structure is the "MU EDCA Parameter Set element" fields as
+ * described in P802.11ax_D4.0 section 9.4.2.245
+ */
 
-/* Transmit Beamforming (TxBF) Capabilities (see 7.3.2.57.6). */
+struct ieee80211_mu_edca_param_set
+{
+  uint8_t 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;
+};
 
-#define IEEE80211_TXBFCAP_IMPLICIT_RX      0x00000001
-#define IEEE80211_TXBFCAP_RSSC             0x00000002
-#define IEEE80211_TXBFCAP_TSSC             0x00000004
-#define IEEE80211_TXBFCAP_RNDP             0x00000008
-#define IEEE80211_TXBFCAP_TNDP             0x00000010
-#define IEEE80211_TXBFCAP_IMPLICIT_TX      0x00000020
-#define IEEE80211_TXBFCAP_CALIB_MASK       0x000000c0
-#define IEEE80211_TXBFCAP_CALIB_SHIFT      6
-#define IEEE80211_TXBFCAP_TX_CSI           0x00000100
+/* 802.11ac VHT Capabilities */
+
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895    0x00000000
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991    0x00000001
+#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454   0x00000002
+#define IEEE80211_VHT_CAP_MAX_MPDU_MASK           0x00000003
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ  0x00000004
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK    0x0000000C
+#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT   2
+#define IEEE80211_VHT_CAP_RXLDPC                  0x00000010
+#define IEEE80211_VHT_CAP_SHORT_GI_80             0x00000020
+#define IEEE80211_VHT_CAP_SHORT_GI_160            0x00000040
+#define IEEE80211_VHT_CAP_TXSTBC                  0x00000080
+#define IEEE80211_VHT_CAP_RXSTBC_1                0x00000100
+#define IEEE80211_VHT_CAP_RXSTBC_2                0x00000200
+#define IEEE80211_VHT_CAP_RXSTBC_3                0x00000300
+#define IEEE80211_VHT_CAP_RXSTBC_4                0x00000400
+#define IEEE80211_VHT_CAP_RXSTBC_MASK             0x00000700
+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT            8
+#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE   0x00000800
+#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE   0x00001000
+#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT    13
+#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK   \
+  (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
+#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK  \
+  (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
+#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE   0x00080000
+#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE   0x00100000
+#define IEEE80211_VHT_CAP_VHT_TXOP_PS             0x00200000
+#define IEEE80211_VHT_CAP_HTC_VHT                 0x00400000
+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23
+#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
+  (7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
+#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
+#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN      0x10000000
+#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN      0x20000000
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT        30
+#define IEEE80211_VHT_CAP_EXT_NSS_BW_MASK         0xc0000000
+
+/* ieee80211_get_vht_max_nss - return max NSS for a given bandwidth/MCS
+ * @cap: VHT capabilities of the peer
+ * @bw: bandwidth to use
+ * @mcs: MCS index to use
+ * @ext_nss_bw_capable: indicates whether or not the local transmitter
+ * (rate scaling algorithm) can deal with the new logic
+ * (dot11VHTExtendedNSSBWCapable)
+ * @max_vht_nss: current maximum NSS as advertised by the STA in
+ * operating mode notification, can be 0 in which case the
+ * capability data will be used to derive this (from MCS support)
+ *
+ * Due to the VHT Extended NSS Bandwidth Support, the maximum NSS can
+ * vary for a given BW/MCS. This function parses the data.
+ *
+ * Note: This function is exported by cfg80211.
+ */
 
-/* Antenna Selection (ASEL) Capability (see 7.3.2.57.7). */
+int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
+    enum ieee80211_vht_chanwidth bw,
+    int mcs, bool ext_nss_bw_capable,
+    unsigned int max_vht_nss);
+
+/* 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_ASELCAP_ASEL             0x01
-#define IEEE80211_ASELCAP_CSIFB            0x02
+#define IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION   0x80
 
-/* Bit 7 is reserved. */
+#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
 
-/* HT Operation element (see 7.3.2.58). */
+#define IEEE80211_HE_MAC_CAP3_OMI_CONTROL       0x02
+#define IEEE80211_HE_MAC_CAP3_OFDMA_RA          0x04
 
-/* Byte 1. */
+/* 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_HTOP0_SCO_MASK           0x03
-#define IEEE80211_HTOP0_SCO_SHIFT          0
-#define IEEE80211_HTOP0_SCO_SCN            0
-#define IEEE80211_HTOP0_SCO_SCA            1
-#define IEEE80211_HTOP0_SCO_SCB            3
-#define IEEE80211_HTOP0_CHW                0x04
-#define IEEE80211_HTOP0_RIFS               0x08
-#define IEEE80211_HTOP0_SPSMP              0x10
-#define IEEE80211_HTOP0_SIG_MASK           0xe0
-#define IEEE80211_HTOP0_SIG_SHIFT          5
+#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
+ */
 
-/* Bytes 2-3. */
+#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
+
+/* 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_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_HTOP1_PROT_MASK          0x0003
-#define IEEE80211_HTOP1_PROT_SHIFT         0
-#define IEEE80211_HTOP1_NONGTSTA           0x0004
+#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_NOMIMAL_PKT_PADDING_0US   0x00
+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_8US   0x40
+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US   0x80
+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_RESERVED  0xc0
+#define IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_MASK   0xc0
+
+/* 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,
+};
 
-/* Bit 3 is reserved. */
-
-#define IEEE80211_HTOP1_OBSS_NONHTSTA      0x0010
+/* Calculate 802.11ax HE capabilities IE Tx/Rx HE MCS NSS
+ * Support Field size
+ */
 
-/* Bits 5-15 are reserved. */
+static inline uint8_t
+ieee80211_he_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap)
+{
+  uint8_t count = 4;
 
-/* Bytes 4-5. */
+  if (he_cap->phy_cap_info[0] &
+      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+    {
+      count += 4;
+    }
 
-/* Bits 0-5 are reserved. */
+  if (he_cap->phy_cap_info[0] &
+      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+    {
+      count += 4;
+    }
 
-#define IEEE80211_HTOP2_DUALBEACON         0x0040
-#define IEEE80211_HTOP2_DUALCTSPROT        0x0080
-#define IEEE80211_HTOP2_STBCBEACON         0x0100
-#define IEEE80211_HTOP2_LSIGTXOP           0x0200
-#define IEEE80211_HTOP2_PCOACTIVE          0x0400
-#define IEEE80211_HTOP2_PCOPHASE40         0x0800
+  return count;
+}
 
-/* Bits 12-15 are reserved. */
+/* 802.11ax HE PPE Thresholds */
 
-/* EDCA Access Categories. */
+#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 EDCA_NUM_AC                        4
+/* Calculate 802.11ax HE capabilities IE PPE field size
+ * Input: Header byte of ppe_thres (first byte),
+ *        and HE capa IE's PHY cap uint8_t*
+ */
 
-/* Number of TID values (traffic identifier) */
+static inline uint8_t
+ieee80211_he_ppe_size(uint8_t ppe_thres_hdr, const uint8_t *phy_cap_info)
+{
+  uint8_t n;
 
-#define IEEE80211_NUM_TID                  16
+  if ((phy_cap_info[6] &
+        IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) == 0)
+    {
+      return 0;
+    }
 
-/* Atheros private advanced capabilities info */
+  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));
 
-#define ATHEROS_CAP_TURBO_PRIME            0x01
-#define ATHEROS_CAP_COMPRESSION            0x02
-#define ATHEROS_CAP_FAST_FRAME             0x04
+  /* Each pair is 6 bits, and we need to add the 7 "header" bits to the
+   * total size.
+   */
 
-/* bits 3-6 reserved */
+  n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7;
+  n = DIV_ROUND_UP(n, 8);
 
-#define ATHEROS_CAP_BOOST                  0x80
+  return n;
+}
 
-/* Organizationally Unique Identifiers.
- * See http://standards.ieee.org/regauth/oui/oui.txt for a list.
+/* 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
+
+/* 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)
  */
 
-#define ATHEROS_OUI                        ((const uint8_t[]){ 0x00, 0x03, 
0x7f })
-#define BROADCOM_OUI                       ((const uint8_t[]){ 0x00, 0x90, 
0x4c })
-#define IEEE80211_OUI                      ((const uint8_t[]){ 0x00, 0x0f, 
0xac })
-#define MICROSOFT_OUI                     ((const uint8_t[]){ 0x00, 0x50, 0xf2 
})
+struct ieee80211_he_6ghz_oper
+{
+  uint8_t 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
+  uint8_t control;
+  uint8_t ccfs0;
+  uint8_t ccfs1;
+  uint8_t minrate;
+};
 
-#define IEEE80211_AUTH_ALGORITHM(auth) \
-    ((auth)[0] | ((auth)[1] << 8))
-#define IEEE80211_AUTH_TRANSACTION(auth) \
-    ((auth)[2] | ((auth)[3] << 8))
-#define IEEE80211_AUTH_STATUS(auth) \
-    ((auth)[4] | ((auth)[5] << 8))
+/* 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
+ */
 
-/* Authentication Algorithm Number field (see 7.3.1.1). */
+static inline uint8_t
+ieee80211_he_oper_size(const uint8_t *he_oper_ie)
+{
+  struct ieee80211_he_operation *he_oper = (void *)he_oper_ie;
+  uint8_t oper_len = sizeof(struct ieee80211_he_operation);
+  uint32_t he_oper_params;
 
-#define IEEE80211_AUTH_ALG_OPEN            0x0000
-#define IEEE80211_AUTH_ALG_SHARED          0x0001
-#define IEEE80211_AUTH_ALG_LEAP            0x0080
+  /* Make sure the input is not NULL */
 
-/* WEP */
+  if (!he_oper_ie)
+    {
+      return 0;
+    }
 
-#define IEEE80211_WEP_KEYLEN               5   /* 40bit */
-#define IEEE80211_WEP_NKID                 4   /* number of key ids */
-#define IEEE80211_CHALLENGE_LEN            128
+  /* Calc required length */
 
-/* WEP header constants */
+  he_oper_params = le32_to_cpu(he_oper->he_oper_params);
+  if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)

Review Comment:
   @pkarashchenko please start a mailing list thread. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to