ieee80211: fix for_each_element_extid()
[carl9170fw.git] / include / linux / ieee80211.h
index 6c75148d4c9bd2349038630464d3dcf137e9e1e0..4e47319fd9d3b4942b47ba08e1e7fca431264312 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
  * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (c) 2018        Intel Corporation
+ * Copyright (c) 2018 - 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -814,6 +814,8 @@ enum mesh_config_capab_flags {
        IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING         = 0x20,
 };
 
+#define IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE 0x1
+
 /**
  * mesh channel switch parameters element's flag indicator
  *
@@ -1479,13 +1481,16 @@ struct ieee80211_ht_operation {
  *     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 are reserved.
+ *     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 3 bits of this field are reserved.
+ *     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 {
        __le16 rx_mcs_map;
@@ -1494,6 +1499,13 @@ struct ieee80211_vht_mcs_info {
        __le16 tx_highest;
 } __packed;
 
+/* 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
@@ -1564,11 +1576,11 @@ struct ieee80211_vht_operation {
  * struct ieee80211_he_cap_elem - HE capabilities element
  *
  * This structure is the "HE capabilities element" fixed fields as
- * described in P802.11ax_D2.0 section 9.4.2.237.2 and 9.4.2.237.3
+ * described in P802.11ax_D3.0 section 9.4.2.237.2 and 9.4.2.237.3
  */
 struct ieee80211_he_cap_elem {
-       u8 mac_cap_info[5];
-       u8 phy_cap_info[9];
+       u8 mac_cap_info[6];
+       u8 phy_cap_info[11];
 } __packed;
 
 #define IEEE80211_TX_RX_MCS_NSS_DESC_MAX_LEN   5
@@ -1626,7 +1638,7 @@ struct ieee80211_he_mcs_nss_supp {
  * struct ieee80211_he_operation - HE capabilities element
  *
  * This structure is the "HE operation element" fields as
- * described in P802.11ax_D2.0 section 9.4.2.238
+ * described in P802.11ax_D3.0 section 9.4.2.238
  */
 struct ieee80211_he_operation {
        __le32 he_oper_params;
@@ -1668,6 +1680,8 @@ struct ieee80211_mu_edca_param_set {
 #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
@@ -1677,6 +1691,7 @@ struct ieee80211_mu_edca_param_set {
 #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
@@ -1696,6 +1711,26 @@ struct ieee80211_mu_edca_param_set {
 #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)
+ *
+ * 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.
+ */
+int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
+                             enum ieee80211_vht_chanwidth bw,
+                             int mcs, bool ext_nss_bw_capable);
 
 /* 802.11ax HE MAC capabilities */
 #define IEEE80211_HE_MAC_CAP0_HTC_HE                           0x01
@@ -1725,15 +1760,15 @@ struct ieee80211_mu_edca_param_set {
 #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_QOS_1              0x00
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_2              0x10
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_3              0x20
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_4              0x30
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_5              0x40
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_6              0x50
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_7              0x60
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8              0x70
-#define IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_MASK           0x70
+#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
@@ -1747,14 +1782,13 @@ struct ieee80211_mu_edca_param_set {
 
 #define IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION                  0x01
 #define IEEE80211_HE_MAC_CAP2_ALL_ACK                          0x02
-#define IEEE80211_HE_MAC_CAP2_UL_MU_RESP_SCHED                 0x04
+#define IEEE80211_HE_MAC_CAP2_TRS                              0x04
 #define IEEE80211_HE_MAC_CAP2_BSR                              0x08
 #define IEEE80211_HE_MAC_CAP2_BCAST_TWT                                0x10
 #define IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP                  0x20
 #define IEEE80211_HE_MAC_CAP2_MU_CASCADING                     0x40
 #define IEEE80211_HE_MAC_CAP2_ACK_EN                           0x80
 
-#define IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU      0x01
 #define IEEE80211_HE_MAC_CAP3_OMI_CONTROL                      0x02
 #define IEEE80211_HE_MAC_CAP3_OFDMA_RA                         0x04
 
@@ -1762,25 +1796,34 @@ struct ieee80211_mu_edca_param_set {
  * A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the
  * same field in the HE capabilities.
  */
-#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_USE_VHT      0x00
-#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_1                0x08
-#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2                0x10
-#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_RESERVED     0x18
-#define IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_MASK         0x18
-#define IEEE80211_HE_MAC_CAP3_A_AMSDU_FRAG                     0x20
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT        0x00
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1          0x08
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2          0x10
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED       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_SR_RESP                          0x08
+#define IEEE80211_HE_MAC_CAP4_SRP_RESP                         0x08
 #define IEEE80211_HE_MAC_CAP4_NDP_FB_REP                       0x10
 #define IEEE80211_HE_MAC_CAP4_OPS                              0x20
 #define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU                   0x40
+/* Multi TID agg TX is split between byte #4 and #5
+ * The value is a combination of B39,B40,B41
+ */
+#define IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39         0x80
+
+#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40         0x01
+#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41         0x02
+#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_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
 
 /* 802.11ax HE PHY capabilities */
-#define IEEE80211_HE_PHY_CAP0_DUAL_BAND                                        0x01
 #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
@@ -1797,10 +1840,10 @@ struct ieee80211_mu_edca_param_set {
 #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 Max NSTS is split between byte #2 and byte #3 */
-#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS                     0x80
+/* 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_MAX_NSTS                     0x01
+#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
@@ -1901,7 +1944,19 @@ struct ieee80211_mu_edca_param_set {
 #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_2X_AND_1XLTF                 0x20
+#define IEEE80211_HE_PHY_CAP8_MIDAMBLE_RX_TX_2X_AND_1XLTF              0x20
+#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_20MHZ                         0x00
+#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_40MHZ                         0x40
+#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_80MHZ                         0x80
+#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_160_OR_80P80_MHZ              0xc0
+#define IEEE80211_HE_PHY_CAP8_DCM_MAX_BW_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
 
 /* 802.11ax HE TX/RX MCS NSS Support  */
 #define IEEE80211_TX_RX_MCS_NSS_SUPP_HIGHEST_MCS_POS                   (3)
@@ -1975,17 +2030,17 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
 }
 
 /* HE Operation defines */
-#define IEEE80211_HE_OPERATION_BSS_COLOR_MASK                  0x0000003f
-#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK           0x000001c0
-#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_OFFSET         6
-#define IEEE80211_HE_OPERATION_TWT_REQUIRED                    0x00000200
-#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK              0x000ffc00
-#define IEEE80211_HE_OPERATION_RTS_THRESHOLD_OFFSET            10
-#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR               0x00100000
-#define IEEE80211_HE_OPERATION_VHT_OPER_INFO                   0x00200000
-#define IEEE80211_HE_OPERATION_MULTI_BSSID_AP                  0x10000000
-#define IEEE80211_HE_OPERATION_TX_BSSID_INDICATOR              0x20000000
-#define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED              0x40000000
+#define IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK           0x00000003
+#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_LOCATED_BSS                  0x00008000
+#define IEEE80211_HE_OPERATION_ER_SU_DISABLE                   0x00010000
+#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_oper_size - calculate 802.11ax HE Operations IE size
@@ -2010,7 +2065,7 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
        he_oper_params = le32_to_cpu(he_oper->he_oper_params);
        if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO)
                oper_len += 3;
-       if (he_oper_params & IEEE80211_HE_OPERATION_MULTI_BSSID_AP)
+       if (he_oper_params & IEEE80211_HE_OPERATION_CO_LOCATED_BSS)
                oper_len++;
 
        /* Add the first byte (extension ID) to the total length */
@@ -2439,6 +2494,7 @@ enum ieee80211_eid_ext {
        WLAN_EID_EXT_HE_OPERATION = 36,
        WLAN_EID_EXT_UORA = 37,
        WLAN_EID_EXT_HE_MU_EDCA = 38,
+       WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
 };
 
 /* Action category code */
@@ -2620,6 +2676,11 @@ enum ieee80211_tdls_actioncode {
  */
 #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING   BIT(2)
 
+/* Multiple BSSID capability is set in the 6th bit of 3rd byte of the
+ * @WLAN_EID_EXT_CAPABILITY information element
+ */
+#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT     BIT(6)
+
 /* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */
 #define WLAN_EXT_CAPA4_TDLS_BUFFER_STA         BIT(4)
 #define WLAN_EXT_CAPA4_TDLS_PEER_PSM           BIT(5)
@@ -2651,6 +2712,13 @@ enum ieee80211_tdls_actioncode {
  */
 #define WLAN_EXT_CAPA9_FTM_INITIATOR   BIT(7)
 
+/* Defines support for TWT Requester and TWT Responder */
+#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT  BIT(5)
+#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT  BIT(6)
+
+/* Defines support for enhanced multi-bssid advertisement*/
+#define WLAN_EXT_CAPA11_EMA_SUPPORT    BIT(1)
+
 /* TDLS specific payload type in the LLC/SNAP header */
 #define WLAN_TDLS_SNAP_RFTYPE  0x2
 
@@ -2842,6 +2910,35 @@ enum ieee80211_sa_query_action {
        WLAN_ACTION_SA_QUERY_RESPONSE = 1,
 };
 
+/**
+ * struct ieee80211_bssid_index
+ *
+ * This structure refers to "Multiple BSSID-index element"
+ *
+ * @bssid_index: BSSID index
+ * @dtim_period: optional, overrides transmitted BSS dtim period
+ * @dtim_count: optional, overrides transmitted BSS dtim count
+ */
+struct ieee80211_bssid_index {
+       u8 bssid_index;
+       u8 dtim_period;
+       u8 dtim_count;
+};
+
+/**
+ * struct ieee80211_multiple_bssid_configuration
+ *
+ * This structure refers to "Multiple BSSID Configuration element"
+ *
+ * @bssid_count: total number of active BSSIDs in the set
+ * @profile_periodicity: the least number of beacon frames need to be received
+ *     in order to discover all the nontransmitted BSSIDs in the set.
+ */
+struct ieee80211_multiple_bssid_configuration {
+       u8 bssid_count;
+       u8 profile_periodicity;
+};
+
 #define SUITE(oui, id) (((oui) << 8) | (id))
 
 /* cipher suite selectors */
@@ -3113,4 +3210,57 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim,
 #define TU_TO_JIFFIES(x)       (usecs_to_jiffies((x) * 1024))
 #define TU_TO_EXP_TIME(x)      (jiffies + TU_TO_JIFFIES(x))
 
+struct element {
+       u8 id;
+       u8 datalen;
+       u8 data[];
+};
+
+/* element iteration helpers */
+#define for_each_element(element, _data, _datalen)                     \
+       for (element = (void *)(_data);                                 \
+            (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
+               sizeof(*element) &&                                     \
+            (u8 *)(_data) + (_datalen) - (u8 *)element >=              \
+               sizeof(*element) + element->datalen;                    \
+            element = (void *)(element->data + element->datalen))
+
+#define for_each_element_id(element, _id, data, datalen)               \
+       for_each_element(element, data, datalen)                        \
+               if (element->id == (_id))
+
+#define for_each_element_extid(element, extid, _data, _datalen)                \
+       for_each_element(element, _data, _datalen)                      \
+               if (element->id == WLAN_EID_EXTENSION &&                \
+                   element->datalen > 0 &&                             \
+                   element->data[0] == (extid))
+
+#define for_each_subelement(sub, element)                              \
+       for_each_element(sub, (element)->data, (element)->datalen)
+
+#define for_each_subelement_id(sub, id, element)                       \
+       for_each_element_id(sub, id, (element)->data, (element)->datalen)
+
+#define for_each_subelement_extid(sub, extid, element)                 \
+       for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
+
+/**
+ * for_each_element_completed - determine if element parsing consumed all data
+ * @element: element pointer after for_each_element() or friends
+ * @data: same data pointer as passed to for_each_element() or friends
+ * @datalen: same data length as passed to for_each_element() or friends
+ *
+ * This function returns %true if all the data was parsed or considered
+ * while walking the elements. Only use this if your for_each_element()
+ * loop cannot be broken out of, otherwise it always returns %false.
+ *
+ * If some data was malformed, this returns %false since the last parsed
+ * element will not fill the whole remaining data.
+ */
+static inline bool for_each_element_completed(const struct element *element,
+                                             const void *data, size_t datalen)
+{
+       return (u8 *)element == (u8 *)data + datalen;
+}
+
 #endif /* __LINUX_IEEE80211_H */