Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wifi: ieee80211: split EHT definitions out

The ieee80211.h file has gotten very long, continue splitting
it by putting EHT definitions into a separate file.

Link: https://patch.msgid.link/20251105153843.bf77fe169140.I691267e0edd914c604a5bfd447d33be00044c9b4@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+1184 -1162
+1182
include/linux/ieee80211-eht.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * IEEE 802.11 EHT definitions 4 + * 5 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 6 + * <jkmaline@cc.hut.fi> 7 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 8 + * Copyright (c) 2005, Devicescape Software, Inc. 9 + * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 10 + * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH 11 + * Copyright (c) 2016 - 2017 Intel Deutschland GmbH 12 + * Copyright (c) 2018 - 2025 Intel Corporation 13 + */ 14 + 15 + #ifndef LINUX_IEEE80211_EHT_H 16 + #define LINUX_IEEE80211_EHT_H 17 + 18 + #include <linux/types.h> 19 + #include <linux/if_ether.h> 20 + /* need HE definitions for the inlines here */ 21 + #include <linux/ieee80211-he.h> 22 + 23 + #define IEEE80211_TTLM_MAX_CNT 2 24 + #define IEEE80211_TTLM_CONTROL_DIRECTION 0x03 25 + #define IEEE80211_TTLM_CONTROL_DEF_LINK_MAP 0x04 26 + #define IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT 0x08 27 + #define IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT 0x10 28 + #define IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE 0x20 29 + 30 + #define IEEE80211_TTLM_DIRECTION_DOWN 0 31 + #define IEEE80211_TTLM_DIRECTION_UP 1 32 + #define IEEE80211_TTLM_DIRECTION_BOTH 2 33 + 34 + /** 35 + * struct ieee80211_ttlm_elem - TID-To-Link Mapping element 36 + * 37 + * Defined in section 9.4.2.314 in P802.11be_D4 38 + * 39 + * @control: the first part of control field 40 + * @optional: the second part of control field 41 + */ 42 + struct ieee80211_ttlm_elem { 43 + u8 control; 44 + u8 optional[]; 45 + } __packed; 46 + 47 + #define IEEE80211_EHT_MCS_NSS_RX 0x0f 48 + #define IEEE80211_EHT_MCS_NSS_TX 0xf0 49 + 50 + /** 51 + * struct ieee80211_eht_mcs_nss_supp_20mhz_only - EHT 20MHz only station max 52 + * supported NSS for per MCS. 53 + * 54 + * For each field below, bits 0 - 3 indicate the maximal number of spatial 55 + * streams for Rx, and bits 4 - 7 indicate the maximal number of spatial streams 56 + * for Tx. 57 + * 58 + * @rx_tx_mcs7_max_nss: indicates the maximum number of spatial streams 59 + * supported for reception and the maximum number of spatial streams 60 + * supported for transmission for MCS 0 - 7. 61 + * @rx_tx_mcs9_max_nss: indicates the maximum number of spatial streams 62 + * supported for reception and the maximum number of spatial streams 63 + * supported for transmission for MCS 8 - 9. 64 + * @rx_tx_mcs11_max_nss: indicates the maximum number of spatial streams 65 + * supported for reception and the maximum number of spatial streams 66 + * supported for transmission for MCS 10 - 11. 67 + * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams 68 + * supported for reception and the maximum number of spatial streams 69 + * supported for transmission for MCS 12 - 13. 70 + * @rx_tx_max_nss: array of the previous fields for easier loop access 71 + */ 72 + struct ieee80211_eht_mcs_nss_supp_20mhz_only { 73 + union { 74 + struct { 75 + u8 rx_tx_mcs7_max_nss; 76 + u8 rx_tx_mcs9_max_nss; 77 + u8 rx_tx_mcs11_max_nss; 78 + u8 rx_tx_mcs13_max_nss; 79 + }; 80 + u8 rx_tx_max_nss[4]; 81 + }; 82 + }; 83 + 84 + /** 85 + * struct ieee80211_eht_mcs_nss_supp_bw - EHT max supported NSS per MCS (except 86 + * 20MHz only stations). 87 + * 88 + * For each field below, bits 0 - 3 indicate the maximal number of spatial 89 + * streams for Rx, and bits 4 - 7 indicate the maximal number of spatial streams 90 + * for Tx. 91 + * 92 + * @rx_tx_mcs9_max_nss: indicates the maximum number of spatial streams 93 + * supported for reception and the maximum number of spatial streams 94 + * supported for transmission for MCS 0 - 9. 95 + * @rx_tx_mcs11_max_nss: indicates the maximum number of spatial streams 96 + * supported for reception and the maximum number of spatial streams 97 + * supported for transmission for MCS 10 - 11. 98 + * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams 99 + * supported for reception and the maximum number of spatial streams 100 + * supported for transmission for MCS 12 - 13. 101 + * @rx_tx_max_nss: array of the previous fields for easier loop access 102 + */ 103 + struct ieee80211_eht_mcs_nss_supp_bw { 104 + union { 105 + struct { 106 + u8 rx_tx_mcs9_max_nss; 107 + u8 rx_tx_mcs11_max_nss; 108 + u8 rx_tx_mcs13_max_nss; 109 + }; 110 + u8 rx_tx_max_nss[3]; 111 + }; 112 + }; 113 + 114 + /** 115 + * struct ieee80211_eht_cap_elem_fixed - EHT capabilities fixed data 116 + * 117 + * This structure is the "EHT Capabilities element" fixed fields as 118 + * described in P802.11be_D2.0 section 9.4.2.313. 119 + * 120 + * @mac_cap_info: MAC capabilities, see IEEE80211_EHT_MAC_CAP* 121 + * @phy_cap_info: PHY capabilities, see IEEE80211_EHT_PHY_CAP* 122 + */ 123 + struct ieee80211_eht_cap_elem_fixed { 124 + u8 mac_cap_info[2]; 125 + u8 phy_cap_info[9]; 126 + } __packed; 127 + 128 + /** 129 + * struct ieee80211_eht_cap_elem - EHT capabilities element 130 + * @fixed: fixed parts, see &ieee80211_eht_cap_elem_fixed 131 + * @optional: optional parts 132 + */ 133 + struct ieee80211_eht_cap_elem { 134 + struct ieee80211_eht_cap_elem_fixed fixed; 135 + 136 + /* 137 + * Followed by: 138 + * Supported EHT-MCS And NSS Set field: 4, 3, 6 or 9 octets. 139 + * EHT PPE Thresholds field: variable length. 140 + */ 141 + u8 optional[]; 142 + } __packed; 143 + 144 + #define IEEE80211_EHT_OPER_INFO_PRESENT 0x01 145 + #define IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT 0x02 146 + #define IEEE80211_EHT_OPER_EHT_DEF_PE_DURATION 0x04 147 + #define IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_LIMIT 0x08 148 + #define IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_EXP_MASK 0x30 149 + #define IEEE80211_EHT_OPER_MCS15_DISABLE 0x40 150 + 151 + /** 152 + * struct ieee80211_eht_operation - eht operation element 153 + * 154 + * This structure is the "EHT Operation Element" fields as 155 + * described in P802.11be_D2.0 section 9.4.2.311 156 + * 157 + * @params: EHT operation element parameters. See &IEEE80211_EHT_OPER_* 158 + * @basic_mcs_nss: indicates the EHT-MCSs for each number of spatial streams in 159 + * EHT PPDUs that are supported by all EHT STAs in the BSS in transmit and 160 + * receive. 161 + * @optional: optional parts 162 + */ 163 + struct ieee80211_eht_operation { 164 + u8 params; 165 + struct ieee80211_eht_mcs_nss_supp_20mhz_only basic_mcs_nss; 166 + u8 optional[]; 167 + } __packed; 168 + 169 + /** 170 + * struct ieee80211_eht_operation_info - eht operation information 171 + * 172 + * @control: EHT operation information control. 173 + * @ccfs0: defines a channel center frequency for a 20, 40, 80, 160, or 320 MHz 174 + * EHT BSS. 175 + * @ccfs1: defines a channel center frequency for a 160 or 320 MHz EHT BSS. 176 + * @optional: optional parts 177 + */ 178 + struct ieee80211_eht_operation_info { 179 + u8 control; 180 + u8 ccfs0; 181 + u8 ccfs1; 182 + u8 optional[]; 183 + } __packed; 184 + 185 + /* EHT MAC capabilities as defined in P802.11be_D2.0 section 9.4.2.313.2 */ 186 + #define IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS 0x01 187 + #define IEEE80211_EHT_MAC_CAP0_OM_CONTROL 0x02 188 + #define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 0x04 189 + #define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 0x08 190 + #define IEEE80211_EHT_MAC_CAP0_RESTRICTED_TWT 0x10 191 + #define IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC 0x20 192 + #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK 0xc0 193 + #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895 0 194 + #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991 1 195 + #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454 2 196 + 197 + #define IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK 0x01 198 + #define IEEE80211_EHT_MAC_CAP1_EHT_TRS 0x02 199 + #define IEEE80211_EHT_MAC_CAP1_TXOP_RET 0x04 200 + #define IEEE80211_EHT_MAC_CAP1_TWO_BQRS 0x08 201 + #define IEEE80211_EHT_MAC_CAP1_EHT_LINK_ADAPT_MASK 0x30 202 + #define IEEE80211_EHT_MAC_CAP1_UNSOL_EPCS_PRIO_ACCESS 0x40 203 + 204 + /* EHT PHY capabilities as defined in P802.11be_D2.0 section 9.4.2.313.3 */ 205 + #define IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ 0x02 206 + #define IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ 0x04 207 + #define IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI 0x08 208 + #define IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO 0x10 209 + #define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER 0x20 210 + #define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE 0x40 211 + 212 + /* EHT beamformee number of spatial streams <= 80MHz is split */ 213 + #define IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK 0x80 214 + #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK 0x03 215 + 216 + #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK 0x1c 217 + #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK 0xe0 218 + 219 + #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK 0x07 220 + #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK 0x38 221 + 222 + /* EHT number of sounding dimensions for 320MHz is split */ 223 + #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK 0xc0 224 + #define IEEE80211_EHT_PHY_CAP3_SOUNDING_DIM_320MHZ_MASK 0x01 225 + #define IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK 0x02 226 + #define IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK 0x04 227 + #define IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK 0x08 228 + #define IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK 0x10 229 + #define IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK 0x20 230 + #define IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK 0x40 231 + #define IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK 0x80 232 + 233 + #define IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO 0x01 234 + #define IEEE80211_EHT_PHY_CAP4_PSR_SR_SUPP 0x02 235 + #define IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP 0x04 236 + #define IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI 0x08 237 + #define IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK 0xf0 238 + 239 + #define IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK 0x01 240 + #define IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP 0x02 241 + #define IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP 0x04 242 + #define IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT 0x08 243 + #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK 0x30 244 + #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_0US 0 245 + #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US 1 246 + #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US 2 247 + #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US 3 248 + 249 + /* Maximum number of supported EHT LTF is split */ 250 + #define IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK 0xc0 251 + #define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF 0x40 252 + #define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK 0x07 253 + 254 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_80MHZ 0x08 255 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_160MHZ 0x30 256 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ 0x40 257 + #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK 0x78 258 + #define IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP 0x80 259 + 260 + #define IEEE80211_EHT_PHY_CAP7_20MHZ_STA_RX_NDP_WIDER_BW 0x01 261 + #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ 0x02 262 + #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ 0x04 263 + #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ 0x08 264 + #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ 0x10 265 + #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ 0x20 266 + #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ 0x40 267 + #define IEEE80211_EHT_PHY_CAP7_TB_SOUNDING_FDBK_RATE_LIMIT 0x80 268 + 269 + #define IEEE80211_EHT_PHY_CAP8_RX_1024QAM_WIDER_BW_DL_OFDMA 0x01 270 + #define IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA 0x02 271 + 272 + /* 273 + * EHT operation channel width as defined in P802.11be_D2.0 section 9.4.2.311 274 + */ 275 + #define IEEE80211_EHT_OPER_CHAN_WIDTH 0x7 276 + #define IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ 0 277 + #define IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ 1 278 + #define IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ 2 279 + #define IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ 3 280 + #define IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ 4 281 + 282 + /* Calculate 802.11be EHT capabilities IE Tx/Rx EHT MCS NSS Support Field size */ 283 + static inline u8 284 + ieee80211_eht_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap, 285 + const struct ieee80211_eht_cap_elem_fixed *eht_cap, 286 + bool from_ap) 287 + { 288 + u8 count = 0; 289 + 290 + /* on 2.4 GHz, if it supports 40 MHz, the result is 3 */ 291 + if (he_cap->phy_cap_info[0] & 292 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G) 293 + return 3; 294 + 295 + /* on 2.4 GHz, these three bits are reserved, so should be 0 */ 296 + if (he_cap->phy_cap_info[0] & 297 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G) 298 + count += 3; 299 + 300 + if (he_cap->phy_cap_info[0] & 301 + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) 302 + count += 3; 303 + 304 + if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ) 305 + count += 3; 306 + 307 + if (count) 308 + return count; 309 + 310 + return from_ap ? 3 : 4; 311 + } 312 + 313 + /* 802.11be EHT PPE Thresholds */ 314 + #define IEEE80211_EHT_PPE_THRES_NSS_POS 0 315 + #define IEEE80211_EHT_PPE_THRES_NSS_MASK 0xf 316 + #define IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK 0x1f0 317 + #define IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE 3 318 + #define IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE 9 319 + 320 + /* 321 + * Calculate 802.11be EHT capabilities IE EHT field size 322 + */ 323 + static inline u8 324 + ieee80211_eht_ppe_size(u16 ppe_thres_hdr, const u8 *phy_cap_info) 325 + { 326 + u32 n; 327 + 328 + if (!(phy_cap_info[5] & 329 + IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT)) 330 + return 0; 331 + 332 + n = hweight16(ppe_thres_hdr & 333 + IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); 334 + n *= 1 + u16_get_bits(ppe_thres_hdr, IEEE80211_EHT_PPE_THRES_NSS_MASK); 335 + 336 + /* 337 + * Each pair is 6 bits, and we need to add the 9 "header" bits to the 338 + * total size. 339 + */ 340 + n = n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2 + 341 + IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE; 342 + return DIV_ROUND_UP(n, 8); 343 + } 344 + 345 + static inline bool 346 + ieee80211_eht_capa_size_ok(const u8 *he_capa, const u8 *data, u8 len, 347 + bool from_ap) 348 + { 349 + const struct ieee80211_eht_cap_elem_fixed *elem = (const void *)data; 350 + u8 needed = sizeof(struct ieee80211_eht_cap_elem_fixed); 351 + 352 + if (len < needed || !he_capa) 353 + return false; 354 + 355 + needed += ieee80211_eht_mcs_nss_size((const void *)he_capa, 356 + (const void *)data, 357 + from_ap); 358 + if (len < needed) 359 + return false; 360 + 361 + if (elem->phy_cap_info[5] & 362 + IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) { 363 + u16 ppe_thres_hdr; 364 + 365 + if (len < needed + sizeof(ppe_thres_hdr)) 366 + return false; 367 + 368 + ppe_thres_hdr = get_unaligned_le16(data + needed); 369 + needed += ieee80211_eht_ppe_size(ppe_thres_hdr, 370 + elem->phy_cap_info); 371 + } 372 + 373 + return len >= needed; 374 + } 375 + 376 + static inline bool 377 + ieee80211_eht_oper_size_ok(const u8 *data, u8 len) 378 + { 379 + const struct ieee80211_eht_operation *elem = (const void *)data; 380 + u8 needed = sizeof(*elem); 381 + 382 + if (len < needed) 383 + return false; 384 + 385 + if (elem->params & IEEE80211_EHT_OPER_INFO_PRESENT) { 386 + needed += 3; 387 + 388 + if (elem->params & 389 + IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT) 390 + needed += 2; 391 + } 392 + 393 + return len >= needed; 394 + } 395 + 396 + /* must validate ieee80211_eht_oper_size_ok() first */ 397 + static inline u16 398 + ieee80211_eht_oper_dis_subchan_bitmap(const struct ieee80211_eht_operation *eht_oper) 399 + { 400 + const struct ieee80211_eht_operation_info *info = 401 + (const void *)eht_oper->optional; 402 + 403 + if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) 404 + return 0; 405 + 406 + if (!(eht_oper->params & IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) 407 + return 0; 408 + 409 + return get_unaligned_le16(info->optional); 410 + } 411 + 412 + #define IEEE80211_BW_IND_DIS_SUBCH_PRESENT BIT(1) 413 + 414 + struct ieee80211_bandwidth_indication { 415 + u8 params; 416 + struct ieee80211_eht_operation_info info; 417 + } __packed; 418 + 419 + static inline bool 420 + ieee80211_bandwidth_indication_size_ok(const u8 *data, u8 len) 421 + { 422 + const struct ieee80211_bandwidth_indication *bwi = (const void *)data; 423 + 424 + if (len < sizeof(*bwi)) 425 + return false; 426 + 427 + if (bwi->params & IEEE80211_BW_IND_DIS_SUBCH_PRESENT && 428 + len < sizeof(*bwi) + 2) 429 + return false; 430 + 431 + return true; 432 + } 433 + 434 + /* Protected EHT action codes */ 435 + enum ieee80211_protected_eht_actioncode { 436 + WLAN_PROTECTED_EHT_ACTION_TTLM_REQ = 0, 437 + WLAN_PROTECTED_EHT_ACTION_TTLM_RES = 1, 438 + WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN = 2, 439 + WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_REQ = 3, 440 + WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_RESP = 4, 441 + WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN = 5, 442 + WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF = 6, 443 + WLAN_PROTECTED_EHT_ACTION_LINK_RECOMMEND = 7, 444 + WLAN_PROTECTED_EHT_ACTION_ML_OP_UPDATE_REQ = 8, 445 + WLAN_PROTECTED_EHT_ACTION_ML_OP_UPDATE_RESP = 9, 446 + WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_NOTIF = 10, 447 + WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ = 11, 448 + WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_RESP = 12, 449 + }; 450 + 451 + /* multi-link device */ 452 + #define IEEE80211_MLD_MAX_NUM_LINKS 15 453 + 454 + #define IEEE80211_ML_CONTROL_TYPE 0x0007 455 + #define IEEE80211_ML_CONTROL_TYPE_BASIC 0 456 + #define IEEE80211_ML_CONTROL_TYPE_PREQ 1 457 + #define IEEE80211_ML_CONTROL_TYPE_RECONF 2 458 + #define IEEE80211_ML_CONTROL_TYPE_TDLS 3 459 + #define IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS 4 460 + #define IEEE80211_ML_CONTROL_PRESENCE_MASK 0xfff0 461 + 462 + struct ieee80211_multi_link_elem { 463 + __le16 control; 464 + u8 variable[]; 465 + } __packed; 466 + 467 + #define IEEE80211_MLC_BASIC_PRES_LINK_ID 0x0010 468 + #define IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT 0x0020 469 + #define IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY 0x0040 470 + #define IEEE80211_MLC_BASIC_PRES_EML_CAPA 0x0080 471 + #define IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP 0x0100 472 + #define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200 473 + #define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400 474 + 475 + #define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff 476 + #define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00 477 + #define IEEE80211_MED_SYNC_DELAY_SYNC_MAX_NUM_TXOPS 0xf000 478 + 479 + /* 480 + * Described in P802.11be_D3.0 481 + * dot11MSDTimerDuration should default to 5484 (i.e. 171.375) 482 + * dot11MSDOFDMEDthreshold defaults to -72 (i.e. 0) 483 + * dot11MSDTXOPMAX defaults to 1 484 + */ 485 + #define IEEE80211_MED_SYNC_DELAY_DEFAULT 0x10ac 486 + 487 + #define IEEE80211_EML_CAP_EMLSR_SUPP 0x0001 488 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY 0x000e 489 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_0US 0 490 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US 1 491 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_64US 2 492 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_128US 3 493 + #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US 4 494 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY 0x0070 495 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_0US 0 496 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_16US 1 497 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_32US 2 498 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US 3 499 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_128US 4 500 + #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US 5 501 + #define IEEE80211_EML_CAP_EMLMR_SUPPORT 0x0080 502 + #define IEEE80211_EML_CAP_EMLMR_DELAY 0x0700 503 + #define IEEE80211_EML_CAP_EMLMR_DELAY_0US 0 504 + #define IEEE80211_EML_CAP_EMLMR_DELAY_32US 1 505 + #define IEEE80211_EML_CAP_EMLMR_DELAY_64US 2 506 + #define IEEE80211_EML_CAP_EMLMR_DELAY_128US 3 507 + #define IEEE80211_EML_CAP_EMLMR_DELAY_256US 4 508 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT 0x7800 509 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_0 0 510 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128US 1 511 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_256US 2 512 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_512US 3 513 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_1TU 4 514 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_2TU 5 515 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_4TU 6 516 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_8TU 7 517 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_16TU 8 518 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_32TU 9 519 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_64TU 10 520 + #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU 11 521 + 522 + #define IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS 0x000f 523 + #define IEEE80211_MLD_CAP_OP_SRS_SUPPORT 0x0010 524 + #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP 0x0060 525 + #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_NO_SUPP 0 526 + #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME 1 527 + #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_RESERVED 2 528 + #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_DIFF 3 529 + #define IEEE80211_MLD_CAP_OP_FREQ_SEP_TYPE_IND 0x0f80 530 + #define IEEE80211_MLD_CAP_OP_AAR_SUPPORT 0x1000 531 + #define IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT 0x2000 532 + #define IEEE80211_MLD_CAP_OP_ALIGNED_TWT_SUPPORT 0x4000 533 + 534 + struct ieee80211_mle_basic_common_info { 535 + u8 len; 536 + u8 mld_mac_addr[ETH_ALEN]; 537 + u8 variable[]; 538 + } __packed; 539 + 540 + #define IEEE80211_MLC_PREQ_PRES_MLD_ID 0x0010 541 + 542 + struct ieee80211_mle_preq_common_info { 543 + u8 len; 544 + u8 variable[]; 545 + } __packed; 546 + 547 + #define IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR 0x0010 548 + #define IEEE80211_MLC_RECONF_PRES_EML_CAPA 0x0020 549 + #define IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP 0x0040 550 + #define IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP 0x0080 551 + 552 + /* no fixed fields in RECONF */ 553 + 554 + struct ieee80211_mle_tdls_common_info { 555 + u8 len; 556 + u8 ap_mld_mac_addr[ETH_ALEN]; 557 + } __packed; 558 + 559 + #define IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR 0x0010 560 + 561 + /* no fixed fields in PRIO_ACCESS */ 562 + 563 + /** 564 + * ieee80211_mle_common_size - check multi-link element common size 565 + * @data: multi-link element, must already be checked for size using 566 + * ieee80211_mle_size_ok() 567 + * Return: the size of the multi-link element's "common" subfield 568 + */ 569 + static inline u8 ieee80211_mle_common_size(const u8 *data) 570 + { 571 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 572 + u16 control = le16_to_cpu(mle->control); 573 + 574 + switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 575 + case IEEE80211_ML_CONTROL_TYPE_BASIC: 576 + case IEEE80211_ML_CONTROL_TYPE_PREQ: 577 + case IEEE80211_ML_CONTROL_TYPE_TDLS: 578 + case IEEE80211_ML_CONTROL_TYPE_RECONF: 579 + case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 580 + /* 581 + * The length is the first octet pointed by mle->variable so no 582 + * need to add anything 583 + */ 584 + break; 585 + default: 586 + WARN_ON(1); 587 + return 0; 588 + } 589 + 590 + return sizeof(*mle) + mle->variable[0]; 591 + } 592 + 593 + /** 594 + * ieee80211_mle_get_link_id - returns the link ID 595 + * @data: the basic multi link element 596 + * Return: the link ID, or -1 if not present 597 + * 598 + * The element is assumed to be of the correct type (BASIC) and big enough, 599 + * this must be checked using ieee80211_mle_type_ok(). 600 + */ 601 + static inline int ieee80211_mle_get_link_id(const u8 *data) 602 + { 603 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 604 + u16 control = le16_to_cpu(mle->control); 605 + const u8 *common = mle->variable; 606 + 607 + /* common points now at the beginning of ieee80211_mle_basic_common_info */ 608 + common += sizeof(struct ieee80211_mle_basic_common_info); 609 + 610 + if (!(control & IEEE80211_MLC_BASIC_PRES_LINK_ID)) 611 + return -1; 612 + 613 + return *common; 614 + } 615 + 616 + /** 617 + * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count 618 + * @data: pointer to the basic multi link element 619 + * Return: the BSS Parameter Change Count field value, or -1 if not present 620 + * 621 + * The element is assumed to be of the correct type (BASIC) and big enough, 622 + * this must be checked using ieee80211_mle_type_ok(). 623 + */ 624 + static inline int 625 + ieee80211_mle_get_bss_param_ch_cnt(const u8 *data) 626 + { 627 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 628 + u16 control = le16_to_cpu(mle->control); 629 + const u8 *common = mle->variable; 630 + 631 + /* common points now at the beginning of ieee80211_mle_basic_common_info */ 632 + common += sizeof(struct ieee80211_mle_basic_common_info); 633 + 634 + if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) 635 + return -1; 636 + 637 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 638 + common += 1; 639 + 640 + return *common; 641 + } 642 + 643 + /** 644 + * ieee80211_mle_get_eml_med_sync_delay - returns the medium sync delay 645 + * @data: pointer to the multi-link element 646 + * Return: the medium synchronization delay field value from the multi-link 647 + * element, or the default value (%IEEE80211_MED_SYNC_DELAY_DEFAULT) 648 + * if not present 649 + * 650 + * The element is assumed to be of the correct type (BASIC) and big enough, 651 + * this must be checked using ieee80211_mle_type_ok(). 652 + */ 653 + static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data) 654 + { 655 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 656 + u16 control = le16_to_cpu(mle->control); 657 + const u8 *common = mle->variable; 658 + 659 + /* common points now at the beginning of ieee80211_mle_basic_common_info */ 660 + common += sizeof(struct ieee80211_mle_basic_common_info); 661 + 662 + if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) 663 + return IEEE80211_MED_SYNC_DELAY_DEFAULT; 664 + 665 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 666 + common += 1; 667 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 668 + common += 1; 669 + 670 + return get_unaligned_le16(common); 671 + } 672 + 673 + /** 674 + * ieee80211_mle_get_eml_cap - returns the EML capability 675 + * @data: pointer to the multi-link element 676 + * Return: the EML capability field value from the multi-link element, 677 + * or 0 if not present 678 + * 679 + * The element is assumed to be of the correct type (BASIC) and big enough, 680 + * this must be checked using ieee80211_mle_type_ok(). 681 + */ 682 + static inline u16 ieee80211_mle_get_eml_cap(const u8 *data) 683 + { 684 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 685 + u16 control = le16_to_cpu(mle->control); 686 + const u8 *common = mle->variable; 687 + 688 + /* common points now at the beginning of ieee80211_mle_basic_common_info */ 689 + common += sizeof(struct ieee80211_mle_basic_common_info); 690 + 691 + if (!(control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)) 692 + return 0; 693 + 694 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 695 + common += 1; 696 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 697 + common += 1; 698 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 699 + common += 2; 700 + 701 + return get_unaligned_le16(common); 702 + } 703 + 704 + /** 705 + * ieee80211_mle_get_mld_capa_op - returns the MLD capabilities and operations. 706 + * @data: pointer to the multi-link element 707 + * Return: the MLD capabilities and operations field value from the multi-link 708 + * element, or 0 if not present 709 + * 710 + * The element is assumed to be of the correct type (BASIC) and big enough, 711 + * this must be checked using ieee80211_mle_type_ok(). 712 + */ 713 + static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data) 714 + { 715 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 716 + u16 control = le16_to_cpu(mle->control); 717 + const u8 *common = mle->variable; 718 + 719 + /* 720 + * common points now at the beginning of 721 + * ieee80211_mle_basic_common_info 722 + */ 723 + common += sizeof(struct ieee80211_mle_basic_common_info); 724 + 725 + if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)) 726 + return 0; 727 + 728 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 729 + common += 1; 730 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 731 + common += 1; 732 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 733 + common += 2; 734 + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 735 + common += 2; 736 + 737 + return get_unaligned_le16(common); 738 + } 739 + 740 + /* Defined in Figure 9-1074t in P802.11be_D7.0 */ 741 + #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_PARAM_UPDATE 0x0001 742 + #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_RECO_MAX_LINKS_MASK 0x001e 743 + #define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020 744 + #define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040 745 + #define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080 746 + 747 + /** 748 + * ieee80211_mle_get_ext_mld_capa_op - returns the extended MLD capabilities 749 + * and operations. 750 + * @data: pointer to the multi-link element 751 + * Return: the extended MLD capabilities and operations field value from 752 + * the multi-link element, or 0 if not present 753 + * 754 + * The element is assumed to be of the correct type (BASIC) and big enough, 755 + * this must be checked using ieee80211_mle_type_ok(). 756 + */ 757 + static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data) 758 + { 759 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 760 + u16 control = le16_to_cpu(mle->control); 761 + const u8 *common = mle->variable; 762 + 763 + /* 764 + * common points now at the beginning of 765 + * ieee80211_mle_basic_common_info 766 + */ 767 + common += sizeof(struct ieee80211_mle_basic_common_info); 768 + 769 + if (!(control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)) 770 + return 0; 771 + 772 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 773 + common += 1; 774 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 775 + common += 1; 776 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 777 + common += 2; 778 + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 779 + common += 2; 780 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 781 + common += 2; 782 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 783 + common += 1; 784 + 785 + return get_unaligned_le16(common); 786 + } 787 + 788 + /** 789 + * ieee80211_mle_get_mld_id - returns the MLD ID 790 + * @data: pointer to the multi-link element 791 + * Return: The MLD ID in the given multi-link element, or 0 if not present 792 + * 793 + * The element is assumed to be of the correct type (BASIC) and big enough, 794 + * this must be checked using ieee80211_mle_type_ok(). 795 + */ 796 + static inline u8 ieee80211_mle_get_mld_id(const u8 *data) 797 + { 798 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 799 + u16 control = le16_to_cpu(mle->control); 800 + const u8 *common = mle->variable; 801 + 802 + /* 803 + * common points now at the beginning of 804 + * ieee80211_mle_basic_common_info 805 + */ 806 + common += sizeof(struct ieee80211_mle_basic_common_info); 807 + 808 + if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_ID)) 809 + return 0; 810 + 811 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 812 + common += 1; 813 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 814 + common += 1; 815 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 816 + common += 2; 817 + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 818 + common += 2; 819 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 820 + common += 2; 821 + 822 + return *common; 823 + } 824 + 825 + /** 826 + * ieee80211_mle_size_ok - validate multi-link element size 827 + * @data: pointer to the element data 828 + * @len: length of the containing element 829 + * Return: whether or not the multi-link element size is OK 830 + */ 831 + static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) 832 + { 833 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 834 + u8 fixed = sizeof(*mle); 835 + u8 common = 0; 836 + bool check_common_len = false; 837 + u16 control; 838 + 839 + if (!data || len < fixed) 840 + return false; 841 + 842 + control = le16_to_cpu(mle->control); 843 + 844 + switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 845 + case IEEE80211_ML_CONTROL_TYPE_BASIC: 846 + common += sizeof(struct ieee80211_mle_basic_common_info); 847 + check_common_len = true; 848 + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 849 + common += 1; 850 + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 851 + common += 1; 852 + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 853 + common += 2; 854 + if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 855 + common += 2; 856 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 857 + common += 2; 858 + if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 859 + common += 1; 860 + if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP) 861 + common += 2; 862 + break; 863 + case IEEE80211_ML_CONTROL_TYPE_PREQ: 864 + common += sizeof(struct ieee80211_mle_preq_common_info); 865 + if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID) 866 + common += 1; 867 + check_common_len = true; 868 + break; 869 + case IEEE80211_ML_CONTROL_TYPE_RECONF: 870 + if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) 871 + common += ETH_ALEN; 872 + if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA) 873 + common += 2; 874 + if (control & IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP) 875 + common += 2; 876 + if (control & IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP) 877 + common += 2; 878 + break; 879 + case IEEE80211_ML_CONTROL_TYPE_TDLS: 880 + common += sizeof(struct ieee80211_mle_tdls_common_info); 881 + check_common_len = true; 882 + break; 883 + case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 884 + common = ETH_ALEN + 1; 885 + break; 886 + default: 887 + /* we don't know this type */ 888 + return true; 889 + } 890 + 891 + if (len < fixed + common) 892 + return false; 893 + 894 + if (!check_common_len) 895 + return true; 896 + 897 + /* if present, common length is the first octet there */ 898 + return mle->variable[0] >= common; 899 + } 900 + 901 + /** 902 + * ieee80211_mle_type_ok - validate multi-link element type and size 903 + * @data: pointer to the element data 904 + * @type: expected type of the element 905 + * @len: length of the containing element 906 + * Return: whether or not the multi-link element type matches and size is OK 907 + */ 908 + static inline bool ieee80211_mle_type_ok(const u8 *data, u8 type, size_t len) 909 + { 910 + const struct ieee80211_multi_link_elem *mle = (const void *)data; 911 + u16 control; 912 + 913 + if (!ieee80211_mle_size_ok(data, len)) 914 + return false; 915 + 916 + control = le16_to_cpu(mle->control); 917 + 918 + if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) == type) 919 + return true; 920 + 921 + return false; 922 + } 923 + 924 + enum ieee80211_mle_subelems { 925 + IEEE80211_MLE_SUBELEM_PER_STA_PROFILE = 0, 926 + IEEE80211_MLE_SUBELEM_FRAGMENT = 254, 927 + }; 928 + 929 + #define IEEE80211_MLE_STA_CONTROL_LINK_ID 0x000f 930 + #define IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE 0x0010 931 + #define IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 932 + #define IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT 0x0040 933 + #define IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT 0x0080 934 + #define IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT 0x0100 935 + #define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200 936 + #define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400 937 + #define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800 938 + 939 + struct ieee80211_mle_per_sta_profile { 940 + __le16 control; 941 + u8 sta_info_len; 942 + u8 variable[]; 943 + } __packed; 944 + 945 + /** 946 + * ieee80211_mle_basic_sta_prof_size_ok - validate basic multi-link element sta 947 + * profile size 948 + * @data: pointer to the sub element data 949 + * @len: length of the containing sub element 950 + * Return: %true if the STA profile is large enough, %false otherwise 951 + */ 952 + static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data, 953 + size_t len) 954 + { 955 + const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 956 + u16 control; 957 + u8 fixed = sizeof(*prof); 958 + u8 info_len = 1; 959 + 960 + if (len < fixed) 961 + return false; 962 + 963 + control = le16_to_cpu(prof->control); 964 + 965 + if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 966 + info_len += 6; 967 + if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 968 + info_len += 2; 969 + if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 970 + info_len += 8; 971 + if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 972 + info_len += 2; 973 + if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 974 + control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 975 + if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 976 + info_len += 2; 977 + else 978 + info_len += 1; 979 + } 980 + if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) 981 + info_len += 1; 982 + 983 + return prof->sta_info_len >= info_len && 984 + fixed + prof->sta_info_len - 1 <= len; 985 + } 986 + 987 + /** 988 + * ieee80211_mle_basic_sta_prof_bss_param_ch_cnt - get per-STA profile BSS 989 + * parameter change count 990 + * @prof: the per-STA profile, having been checked with 991 + * ieee80211_mle_basic_sta_prof_size_ok() for the correct length 992 + * 993 + * Return: The BSS parameter change count value if present, 0 otherwise. 994 + */ 995 + static inline u8 996 + ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta_profile *prof) 997 + { 998 + u16 control = le16_to_cpu(prof->control); 999 + const u8 *pos = prof->variable; 1000 + 1001 + if (!(control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)) 1002 + return 0; 1003 + 1004 + if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 1005 + pos += 6; 1006 + if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 1007 + pos += 2; 1008 + if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 1009 + pos += 8; 1010 + if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 1011 + pos += 2; 1012 + if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 1013 + control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 1014 + if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 1015 + pos += 2; 1016 + else 1017 + pos += 1; 1018 + } 1019 + 1020 + return *pos; 1021 + } 1022 + 1023 + #define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f 1024 + #define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 1025 + #define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 1026 + #define IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT 0x0040 1027 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE 0x0780 1028 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_AP_REM 0 1029 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_OP_PARAM_UPDATE 1 1030 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_ADD_LINK 2 1031 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_DEL_LINK 3 1032 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_NSTR_STATUS 4 1033 + #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 1034 + 1035 + /** 1036 + * ieee80211_mle_reconf_sta_prof_size_ok - validate reconfiguration multi-link 1037 + * element sta profile size. 1038 + * @data: pointer to the sub element data 1039 + * @len: length of the containing sub element 1040 + * Return: %true if the STA profile is large enough, %false otherwise 1041 + */ 1042 + static inline bool ieee80211_mle_reconf_sta_prof_size_ok(const u8 *data, 1043 + size_t len) 1044 + { 1045 + const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 1046 + u16 control; 1047 + u8 fixed = sizeof(*prof); 1048 + u8 info_len = 1; 1049 + 1050 + if (len < fixed) 1051 + return false; 1052 + 1053 + control = le16_to_cpu(prof->control); 1054 + 1055 + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT) 1056 + info_len += ETH_ALEN; 1057 + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT) 1058 + info_len += 2; 1059 + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT) 1060 + info_len += 2; 1061 + 1062 + return prof->sta_info_len >= info_len && 1063 + fixed + prof->sta_info_len - 1 <= len; 1064 + } 1065 + 1066 + #define IEEE80211_MLE_STA_EPCS_CONTROL_LINK_ID 0x000f 1067 + #define IEEE80211_EPCS_ENA_RESP_BODY_LEN 3 1068 + 1069 + static inline bool ieee80211_tid_to_link_map_size_ok(const u8 *data, size_t len) 1070 + { 1071 + const struct ieee80211_ttlm_elem *t2l = (const void *)data; 1072 + u8 control, fixed = sizeof(*t2l), elem_len = 0; 1073 + 1074 + if (len < fixed) 1075 + return false; 1076 + 1077 + control = t2l->control; 1078 + 1079 + if (control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT) 1080 + elem_len += 2; 1081 + if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) 1082 + elem_len += 3; 1083 + 1084 + if (!(control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP)) { 1085 + u8 bm_size; 1086 + 1087 + elem_len += 1; 1088 + if (len < fixed + elem_len) 1089 + return false; 1090 + 1091 + if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE) 1092 + bm_size = 1; 1093 + else 1094 + bm_size = 2; 1095 + 1096 + elem_len += hweight8(t2l->optional[0]) * bm_size; 1097 + } 1098 + 1099 + return len >= fixed + elem_len; 1100 + } 1101 + 1102 + /** 1103 + * ieee80211_emlsr_pad_delay_in_us - Fetch the EMLSR Padding delay 1104 + * in microseconds 1105 + * @eml_cap: EML capabilities field value from common info field of 1106 + * the Multi-link element 1107 + * Return: the EMLSR Padding delay (in microseconds) encoded in the 1108 + * EML Capabilities field 1109 + */ 1110 + 1111 + static inline u32 ieee80211_emlsr_pad_delay_in_us(u16 eml_cap) 1112 + { 1113 + /* IEEE Std 802.11be-2024 Table 9-417i—Encoding of the EMLSR 1114 + * Padding Delay subfield. 1115 + */ 1116 + u32 pad_delay = u16_get_bits(eml_cap, 1117 + IEEE80211_EML_CAP_EMLSR_PADDING_DELAY); 1118 + 1119 + if (!pad_delay || 1120 + pad_delay > IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US) 1121 + return 0; 1122 + 1123 + return 32 * (1 << (pad_delay - 1)); 1124 + } 1125 + 1126 + /** 1127 + * ieee80211_emlsr_trans_delay_in_us - Fetch the EMLSR Transition 1128 + * delay in microseconds 1129 + * @eml_cap: EML capabilities field value from common info field of 1130 + * the Multi-link element 1131 + * Return: the EMLSR Transition delay (in microseconds) encoded in the 1132 + * EML Capabilities field 1133 + */ 1134 + 1135 + static inline u32 ieee80211_emlsr_trans_delay_in_us(u16 eml_cap) 1136 + { 1137 + /* IEEE Std 802.11be-2024 Table 9-417j—Encoding of the EMLSR 1138 + * Transition Delay subfield. 1139 + */ 1140 + u32 trans_delay = 1141 + u16_get_bits(eml_cap, 1142 + IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY); 1143 + 1144 + /* invalid values also just use 0 */ 1145 + if (!trans_delay || 1146 + trans_delay > IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US) 1147 + return 0; 1148 + 1149 + return 16 * (1 << (trans_delay - 1)); 1150 + } 1151 + 1152 + /** 1153 + * ieee80211_eml_trans_timeout_in_us - Fetch the EMLSR Transition 1154 + * timeout value in microseconds 1155 + * @eml_cap: EML capabilities field value from common info field of 1156 + * the Multi-link element 1157 + * Return: the EMLSR Transition timeout (in microseconds) encoded in 1158 + * the EML Capabilities field 1159 + */ 1160 + 1161 + static inline u32 ieee80211_eml_trans_timeout_in_us(u16 eml_cap) 1162 + { 1163 + /* IEEE Std 802.11be-2024 Table 9-417m—Encoding of the 1164 + * Transition Timeout subfield. 1165 + */ 1166 + u8 timeout = u16_get_bits(eml_cap, 1167 + IEEE80211_EML_CAP_TRANSITION_TIMEOUT); 1168 + 1169 + /* invalid values also just use 0 */ 1170 + if (!timeout || timeout > IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU) 1171 + return 0; 1172 + 1173 + return 128 * (1 << (timeout - 1)); 1174 + } 1175 + 1176 + #define for_each_mle_subelement(_elem, _data, _len) \ 1177 + if (ieee80211_mle_size_ok(_data, _len)) \ 1178 + for_each_element(_elem, \ 1179 + _data + ieee80211_mle_common_size(_data),\ 1180 + _len - ieee80211_mle_common_size(_data)) 1181 + 1182 + #endif /* LINUX_IEEE80211_H */
+2 -1162
include/linux/ieee80211.h
··· 1141 1141 return len; 1142 1142 } 1143 1143 1144 - #define IEEE80211_TTLM_MAX_CNT 2 1145 - #define IEEE80211_TTLM_CONTROL_DIRECTION 0x03 1146 - #define IEEE80211_TTLM_CONTROL_DEF_LINK_MAP 0x04 1147 - #define IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT 0x08 1148 - #define IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT 0x10 1149 - #define IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE 0x20 1150 - 1151 - #define IEEE80211_TTLM_DIRECTION_DOWN 0 1152 - #define IEEE80211_TTLM_DIRECTION_UP 1 1153 - #define IEEE80211_TTLM_DIRECTION_BOTH 2 1154 - 1155 - /** 1156 - * struct ieee80211_ttlm_elem - TID-To-Link Mapping element 1157 - * 1158 - * Defined in section 9.4.2.314 in P802.11be_D4 1159 - * 1160 - * @control: the first part of control field 1161 - * @optional: the second part of control field 1162 - */ 1163 - struct ieee80211_ttlm_elem { 1164 - u8 control; 1165 - u8 optional[]; 1166 - } __packed; 1167 - 1168 1144 /** 1169 1145 * struct ieee80211_bss_load_elem - BSS Load elemen 1170 1146 * ··· 1567 1591 #define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7) 1568 1592 #define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F 1569 1593 1570 - #define IEEE80211_EHT_MCS_NSS_RX 0x0f 1571 - #define IEEE80211_EHT_MCS_NSS_TX 0xf0 1572 - 1573 - /** 1574 - * struct ieee80211_eht_mcs_nss_supp_20mhz_only - EHT 20MHz only station max 1575 - * supported NSS for per MCS. 1576 - * 1577 - * For each field below, bits 0 - 3 indicate the maximal number of spatial 1578 - * streams for Rx, and bits 4 - 7 indicate the maximal number of spatial streams 1579 - * for Tx. 1580 - * 1581 - * @rx_tx_mcs7_max_nss: indicates the maximum number of spatial streams 1582 - * supported for reception and the maximum number of spatial streams 1583 - * supported for transmission for MCS 0 - 7. 1584 - * @rx_tx_mcs9_max_nss: indicates the maximum number of spatial streams 1585 - * supported for reception and the maximum number of spatial streams 1586 - * supported for transmission for MCS 8 - 9. 1587 - * @rx_tx_mcs11_max_nss: indicates the maximum number of spatial streams 1588 - * supported for reception and the maximum number of spatial streams 1589 - * supported for transmission for MCS 10 - 11. 1590 - * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams 1591 - * supported for reception and the maximum number of spatial streams 1592 - * supported for transmission for MCS 12 - 13. 1593 - * @rx_tx_max_nss: array of the previous fields for easier loop access 1594 - */ 1595 - struct ieee80211_eht_mcs_nss_supp_20mhz_only { 1596 - union { 1597 - struct { 1598 - u8 rx_tx_mcs7_max_nss; 1599 - u8 rx_tx_mcs9_max_nss; 1600 - u8 rx_tx_mcs11_max_nss; 1601 - u8 rx_tx_mcs13_max_nss; 1602 - }; 1603 - u8 rx_tx_max_nss[4]; 1604 - }; 1605 - }; 1606 - 1607 - /** 1608 - * struct ieee80211_eht_mcs_nss_supp_bw - EHT max supported NSS per MCS (except 1609 - * 20MHz only stations). 1610 - * 1611 - * For each field below, bits 0 - 3 indicate the maximal number of spatial 1612 - * streams for Rx, and bits 4 - 7 indicate the maximal number of spatial streams 1613 - * for Tx. 1614 - * 1615 - * @rx_tx_mcs9_max_nss: indicates the maximum number of spatial streams 1616 - * supported for reception and the maximum number of spatial streams 1617 - * supported for transmission for MCS 0 - 9. 1618 - * @rx_tx_mcs11_max_nss: indicates the maximum number of spatial streams 1619 - * supported for reception and the maximum number of spatial streams 1620 - * supported for transmission for MCS 10 - 11. 1621 - * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams 1622 - * supported for reception and the maximum number of spatial streams 1623 - * supported for transmission for MCS 12 - 13. 1624 - * @rx_tx_max_nss: array of the previous fields for easier loop access 1625 - */ 1626 - struct ieee80211_eht_mcs_nss_supp_bw { 1627 - union { 1628 - struct { 1629 - u8 rx_tx_mcs9_max_nss; 1630 - u8 rx_tx_mcs11_max_nss; 1631 - u8 rx_tx_mcs13_max_nss; 1632 - }; 1633 - u8 rx_tx_max_nss[3]; 1634 - }; 1635 - }; 1636 - 1637 - /** 1638 - * struct ieee80211_eht_cap_elem_fixed - EHT capabilities fixed data 1639 - * 1640 - * This structure is the "EHT Capabilities element" fixed fields as 1641 - * described in P802.11be_D2.0 section 9.4.2.313. 1642 - * 1643 - * @mac_cap_info: MAC capabilities, see IEEE80211_EHT_MAC_CAP* 1644 - * @phy_cap_info: PHY capabilities, see IEEE80211_EHT_PHY_CAP* 1645 - */ 1646 - struct ieee80211_eht_cap_elem_fixed { 1647 - u8 mac_cap_info[2]; 1648 - u8 phy_cap_info[9]; 1649 - } __packed; 1650 - 1651 - /** 1652 - * struct ieee80211_eht_cap_elem - EHT capabilities element 1653 - * @fixed: fixed parts, see &ieee80211_eht_cap_elem_fixed 1654 - * @optional: optional parts 1655 - */ 1656 - struct ieee80211_eht_cap_elem { 1657 - struct ieee80211_eht_cap_elem_fixed fixed; 1658 - 1659 - /* 1660 - * Followed by: 1661 - * Supported EHT-MCS And NSS Set field: 4, 3, 6 or 9 octets. 1662 - * EHT PPE Thresholds field: variable length. 1663 - */ 1664 - u8 optional[]; 1665 - } __packed; 1666 - 1667 - #define IEEE80211_EHT_OPER_INFO_PRESENT 0x01 1668 - #define IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT 0x02 1669 - #define IEEE80211_EHT_OPER_EHT_DEF_PE_DURATION 0x04 1670 - #define IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_LIMIT 0x08 1671 - #define IEEE80211_EHT_OPER_GROUP_ADDRESSED_BU_IND_EXP_MASK 0x30 1672 - #define IEEE80211_EHT_OPER_MCS15_DISABLE 0x40 1673 - 1674 - /** 1675 - * struct ieee80211_eht_operation - eht operation element 1676 - * 1677 - * This structure is the "EHT Operation Element" fields as 1678 - * described in P802.11be_D2.0 section 9.4.2.311 1679 - * 1680 - * @params: EHT operation element parameters. See &IEEE80211_EHT_OPER_* 1681 - * @basic_mcs_nss: indicates the EHT-MCSs for each number of spatial streams in 1682 - * EHT PPDUs that are supported by all EHT STAs in the BSS in transmit and 1683 - * receive. 1684 - * @optional: optional parts 1685 - */ 1686 - struct ieee80211_eht_operation { 1687 - u8 params; 1688 - struct ieee80211_eht_mcs_nss_supp_20mhz_only basic_mcs_nss; 1689 - u8 optional[]; 1690 - } __packed; 1691 - 1692 - /** 1693 - * struct ieee80211_eht_operation_info - eht operation information 1694 - * 1695 - * @control: EHT operation information control. 1696 - * @ccfs0: defines a channel center frequency for a 20, 40, 80, 160, or 320 MHz 1697 - * EHT BSS. 1698 - * @ccfs1: defines a channel center frequency for a 160 or 320 MHz EHT BSS. 1699 - * @optional: optional parts 1700 - */ 1701 - struct ieee80211_eht_operation_info { 1702 - u8 control; 1703 - u8 ccfs0; 1704 - u8 ccfs1; 1705 - u8 optional[]; 1706 - } __packed; 1707 - 1708 1594 /* S1G Capabilities Information field */ 1709 1595 #define IEEE80211_S1G_CAPABILITY_LEN 15 1710 1596 ··· 1652 1814 1653 1815 #define S1G_2M_PRIMARY_LOCATION_LOWER 0 1654 1816 #define S1G_2M_PRIMARY_LOCATION_UPPER 1 1655 - 1656 - /* EHT MAC capabilities as defined in P802.11be_D2.0 section 9.4.2.313.2 */ 1657 - #define IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS 0x01 1658 - #define IEEE80211_EHT_MAC_CAP0_OM_CONTROL 0x02 1659 - #define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 0x04 1660 - #define IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2 0x08 1661 - #define IEEE80211_EHT_MAC_CAP0_RESTRICTED_TWT 0x10 1662 - #define IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC 0x20 1663 - #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK 0xc0 1664 - #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_3895 0 1665 - #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991 1 1666 - #define IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_11454 2 1667 - 1668 - #define IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK 0x01 1669 - #define IEEE80211_EHT_MAC_CAP1_EHT_TRS 0x02 1670 - #define IEEE80211_EHT_MAC_CAP1_TXOP_RET 0x04 1671 - #define IEEE80211_EHT_MAC_CAP1_TWO_BQRS 0x08 1672 - #define IEEE80211_EHT_MAC_CAP1_EHT_LINK_ADAPT_MASK 0x30 1673 - #define IEEE80211_EHT_MAC_CAP1_UNSOL_EPCS_PRIO_ACCESS 0x40 1674 - 1675 - /* EHT PHY capabilities as defined in P802.11be_D2.0 section 9.4.2.313.3 */ 1676 - #define IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ 0x02 1677 - #define IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ 0x04 1678 - #define IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI 0x08 1679 - #define IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO 0x10 1680 - #define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER 0x20 1681 - #define IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE 0x40 1682 - 1683 - /* EHT beamformee number of spatial streams <= 80MHz is split */ 1684 - #define IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK 0x80 1685 - #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK 0x03 1686 - 1687 - #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK 0x1c 1688 - #define IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK 0xe0 1689 - 1690 - #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK 0x07 1691 - #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK 0x38 1692 - 1693 - /* EHT number of sounding dimensions for 320MHz is split */ 1694 - #define IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK 0xc0 1695 - #define IEEE80211_EHT_PHY_CAP3_SOUNDING_DIM_320MHZ_MASK 0x01 1696 - #define IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK 0x02 1697 - #define IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK 0x04 1698 - #define IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK 0x08 1699 - #define IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK 0x10 1700 - #define IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK 0x20 1701 - #define IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK 0x40 1702 - #define IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK 0x80 1703 - 1704 - #define IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO 0x01 1705 - #define IEEE80211_EHT_PHY_CAP4_PSR_SR_SUPP 0x02 1706 - #define IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP 0x04 1707 - #define IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI 0x08 1708 - #define IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK 0xf0 1709 - 1710 - #define IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK 0x01 1711 - #define IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP 0x02 1712 - #define IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP 0x04 1713 - #define IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT 0x08 1714 - #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK 0x30 1715 - #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_0US 0 1716 - #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_8US 1 1717 - #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_16US 2 1718 - #define IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_20US 3 1719 - 1720 - /* Maximum number of supported EHT LTF is split */ 1721 - #define IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK 0xc0 1722 - #define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF 0x40 1723 - #define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK 0x07 1724 - 1725 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_80MHZ 0x08 1726 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_160MHZ 0x30 1727 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ 0x40 1728 - #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK 0x78 1729 - #define IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP 0x80 1730 - 1731 - #define IEEE80211_EHT_PHY_CAP7_20MHZ_STA_RX_NDP_WIDER_BW 0x01 1732 - #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ 0x02 1733 - #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ 0x04 1734 - #define IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ 0x08 1735 - #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ 0x10 1736 - #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ 0x20 1737 - #define IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ 0x40 1738 - #define IEEE80211_EHT_PHY_CAP7_TB_SOUNDING_FDBK_RATE_LIMIT 0x80 1739 - 1740 - #define IEEE80211_EHT_PHY_CAP8_RX_1024QAM_WIDER_BW_DL_OFDMA 0x01 1741 - #define IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA 0x02 1742 - 1743 - /* 1744 - * EHT operation channel width as defined in P802.11be_D2.0 section 9.4.2.311 1745 - */ 1746 - #define IEEE80211_EHT_OPER_CHAN_WIDTH 0x7 1747 - #define IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ 0 1748 - #define IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ 1 1749 - #define IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ 2 1750 - #define IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ 3 1751 - #define IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ 4 1752 - 1753 - /* need HE definitions for EHT functions */ 1754 - #include "ieee80211-he.h" 1755 - 1756 - /* Calculate 802.11be EHT capabilities IE Tx/Rx EHT MCS NSS Support Field size */ 1757 - static inline u8 1758 - ieee80211_eht_mcs_nss_size(const struct ieee80211_he_cap_elem *he_cap, 1759 - const struct ieee80211_eht_cap_elem_fixed *eht_cap, 1760 - bool from_ap) 1761 - { 1762 - u8 count = 0; 1763 - 1764 - /* on 2.4 GHz, if it supports 40 MHz, the result is 3 */ 1765 - if (he_cap->phy_cap_info[0] & 1766 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G) 1767 - return 3; 1768 - 1769 - /* on 2.4 GHz, these three bits are reserved, so should be 0 */ 1770 - if (he_cap->phy_cap_info[0] & 1771 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G) 1772 - count += 3; 1773 - 1774 - if (he_cap->phy_cap_info[0] & 1775 - IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) 1776 - count += 3; 1777 - 1778 - if (eht_cap->phy_cap_info[0] & IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ) 1779 - count += 3; 1780 - 1781 - if (count) 1782 - return count; 1783 - 1784 - return from_ap ? 3 : 4; 1785 - } 1786 - 1787 - /* 802.11be EHT PPE Thresholds */ 1788 - #define IEEE80211_EHT_PPE_THRES_NSS_POS 0 1789 - #define IEEE80211_EHT_PPE_THRES_NSS_MASK 0xf 1790 - #define IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK 0x1f0 1791 - #define IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE 3 1792 - #define IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE 9 1793 - 1794 - /* 1795 - * Calculate 802.11be EHT capabilities IE EHT field size 1796 - */ 1797 - static inline u8 1798 - ieee80211_eht_ppe_size(u16 ppe_thres_hdr, const u8 *phy_cap_info) 1799 - { 1800 - u32 n; 1801 - 1802 - if (!(phy_cap_info[5] & 1803 - IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT)) 1804 - return 0; 1805 - 1806 - n = hweight16(ppe_thres_hdr & 1807 - IEEE80211_EHT_PPE_THRES_RU_INDEX_BITMASK_MASK); 1808 - n *= 1 + u16_get_bits(ppe_thres_hdr, IEEE80211_EHT_PPE_THRES_NSS_MASK); 1809 - 1810 - /* 1811 - * Each pair is 6 bits, and we need to add the 9 "header" bits to the 1812 - * total size. 1813 - */ 1814 - n = n * IEEE80211_EHT_PPE_THRES_INFO_PPET_SIZE * 2 + 1815 - IEEE80211_EHT_PPE_THRES_INFO_HEADER_SIZE; 1816 - return DIV_ROUND_UP(n, 8); 1817 - } 1818 - 1819 - static inline bool 1820 - ieee80211_eht_capa_size_ok(const u8 *he_capa, const u8 *data, u8 len, 1821 - bool from_ap) 1822 - { 1823 - const struct ieee80211_eht_cap_elem_fixed *elem = (const void *)data; 1824 - u8 needed = sizeof(struct ieee80211_eht_cap_elem_fixed); 1825 - 1826 - if (len < needed || !he_capa) 1827 - return false; 1828 - 1829 - needed += ieee80211_eht_mcs_nss_size((const void *)he_capa, 1830 - (const void *)data, 1831 - from_ap); 1832 - if (len < needed) 1833 - return false; 1834 - 1835 - if (elem->phy_cap_info[5] & 1836 - IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) { 1837 - u16 ppe_thres_hdr; 1838 - 1839 - if (len < needed + sizeof(ppe_thres_hdr)) 1840 - return false; 1841 - 1842 - ppe_thres_hdr = get_unaligned_le16(data + needed); 1843 - needed += ieee80211_eht_ppe_size(ppe_thres_hdr, 1844 - elem->phy_cap_info); 1845 - } 1846 - 1847 - return len >= needed; 1848 - } 1849 - 1850 - static inline bool 1851 - ieee80211_eht_oper_size_ok(const u8 *data, u8 len) 1852 - { 1853 - const struct ieee80211_eht_operation *elem = (const void *)data; 1854 - u8 needed = sizeof(*elem); 1855 - 1856 - if (len < needed) 1857 - return false; 1858 - 1859 - if (elem->params & IEEE80211_EHT_OPER_INFO_PRESENT) { 1860 - needed += 3; 1861 - 1862 - if (elem->params & 1863 - IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT) 1864 - needed += 2; 1865 - } 1866 - 1867 - return len >= needed; 1868 - } 1869 - 1870 - /* must validate ieee80211_eht_oper_size_ok() first */ 1871 - static inline u16 1872 - ieee80211_eht_oper_dis_subchan_bitmap(const struct ieee80211_eht_operation *eht_oper) 1873 - { 1874 - const struct ieee80211_eht_operation_info *info = 1875 - (const void *)eht_oper->optional; 1876 - 1877 - if (!(eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) 1878 - return 0; 1879 - 1880 - if (!(eht_oper->params & IEEE80211_EHT_OPER_DISABLED_SUBCHANNEL_BITMAP_PRESENT)) 1881 - return 0; 1882 - 1883 - return get_unaligned_le16(info->optional); 1884 - } 1885 - 1886 - #define IEEE80211_BW_IND_DIS_SUBCH_PRESENT BIT(1) 1887 - 1888 - struct ieee80211_bandwidth_indication { 1889 - u8 params; 1890 - struct ieee80211_eht_operation_info info; 1891 - } __packed; 1892 - 1893 - static inline bool 1894 - ieee80211_bandwidth_indication_size_ok(const u8 *data, u8 len) 1895 - { 1896 - const struct ieee80211_bandwidth_indication *bwi = (const void *)data; 1897 - 1898 - if (len < sizeof(*bwi)) 1899 - return false; 1900 - 1901 - if (bwi->params & IEEE80211_BW_IND_DIS_SUBCH_PRESENT && 1902 - len < sizeof(*bwi) + 2) 1903 - return false; 1904 - 1905 - return true; 1906 - } 1907 1817 1908 1818 #define LISTEN_INT_USF GENMASK(15, 14) 1909 1819 #define LISTEN_INT_UI GENMASK(13, 0) ··· 2171 2585 enum ieee80211_unprotected_wnm_actioncode { 2172 2586 WLAN_UNPROTECTED_WNM_ACTION_TIM = 0, 2173 2587 WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE = 1, 2174 - }; 2175 - 2176 - /* Protected EHT action codes */ 2177 - enum ieee80211_protected_eht_actioncode { 2178 - WLAN_PROTECTED_EHT_ACTION_TTLM_REQ = 0, 2179 - WLAN_PROTECTED_EHT_ACTION_TTLM_RES = 1, 2180 - WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN = 2, 2181 - WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_REQ = 3, 2182 - WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_RESP = 4, 2183 - WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN = 5, 2184 - WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF = 6, 2185 - WLAN_PROTECTED_EHT_ACTION_LINK_RECOMMEND = 7, 2186 - WLAN_PROTECTED_EHT_ACTION_ML_OP_UPDATE_REQ = 8, 2187 - WLAN_PROTECTED_EHT_ACTION_ML_OP_UPDATE_RESP = 9, 2188 - WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_NOTIF = 10, 2189 - WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ = 11, 2190 - WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_RESP = 12, 2191 2588 }; 2192 2589 2193 2590 /* Security key length */ ··· 3424 3855 struct ieee80211_rnr_mld_params mld_params; 3425 3856 } __packed; 3426 3857 3427 - /* multi-link device */ 3428 - #define IEEE80211_MLD_MAX_NUM_LINKS 15 3429 - 3430 - #define IEEE80211_ML_CONTROL_TYPE 0x0007 3431 - #define IEEE80211_ML_CONTROL_TYPE_BASIC 0 3432 - #define IEEE80211_ML_CONTROL_TYPE_PREQ 1 3433 - #define IEEE80211_ML_CONTROL_TYPE_RECONF 2 3434 - #define IEEE80211_ML_CONTROL_TYPE_TDLS 3 3435 - #define IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS 4 3436 - #define IEEE80211_ML_CONTROL_PRESENCE_MASK 0xfff0 3437 - 3438 - struct ieee80211_multi_link_elem { 3439 - __le16 control; 3440 - u8 variable[]; 3441 - } __packed; 3442 - 3443 - #define IEEE80211_MLC_BASIC_PRES_LINK_ID 0x0010 3444 - #define IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT 0x0020 3445 - #define IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY 0x0040 3446 - #define IEEE80211_MLC_BASIC_PRES_EML_CAPA 0x0080 3447 - #define IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP 0x0100 3448 - #define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200 3449 - #define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400 3450 - 3451 - #define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff 3452 - #define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00 3453 - #define IEEE80211_MED_SYNC_DELAY_SYNC_MAX_NUM_TXOPS 0xf000 3454 - 3455 - /* 3456 - * Described in P802.11be_D3.0 3457 - * dot11MSDTimerDuration should default to 5484 (i.e. 171.375) 3458 - * dot11MSDOFDMEDthreshold defaults to -72 (i.e. 0) 3459 - * dot11MSDTXOPMAX defaults to 1 3460 - */ 3461 - #define IEEE80211_MED_SYNC_DELAY_DEFAULT 0x10ac 3462 - 3463 - #define IEEE80211_EML_CAP_EMLSR_SUPP 0x0001 3464 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY 0x000e 3465 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_0US 0 3466 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_32US 1 3467 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_64US 2 3468 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_128US 3 3469 - #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US 4 3470 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY 0x0070 3471 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_0US 0 3472 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_16US 1 3473 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_32US 2 3474 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_64US 3 3475 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_128US 4 3476 - #define IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US 5 3477 - #define IEEE80211_EML_CAP_EMLMR_SUPPORT 0x0080 3478 - #define IEEE80211_EML_CAP_EMLMR_DELAY 0x0700 3479 - #define IEEE80211_EML_CAP_EMLMR_DELAY_0US 0 3480 - #define IEEE80211_EML_CAP_EMLMR_DELAY_32US 1 3481 - #define IEEE80211_EML_CAP_EMLMR_DELAY_64US 2 3482 - #define IEEE80211_EML_CAP_EMLMR_DELAY_128US 3 3483 - #define IEEE80211_EML_CAP_EMLMR_DELAY_256US 4 3484 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT 0x7800 3485 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_0 0 3486 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128US 1 3487 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_256US 2 3488 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_512US 3 3489 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_1TU 4 3490 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_2TU 5 3491 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_4TU 6 3492 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_8TU 7 3493 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_16TU 8 3494 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_32TU 9 3495 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_64TU 10 3496 - #define IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU 11 3497 - 3498 - #define IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS 0x000f 3499 - #define IEEE80211_MLD_CAP_OP_SRS_SUPPORT 0x0010 3500 - #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP 0x0060 3501 - #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_NO_SUPP 0 3502 - #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME 1 3503 - #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_RESERVED 2 3504 - #define IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_DIFF 3 3505 - #define IEEE80211_MLD_CAP_OP_FREQ_SEP_TYPE_IND 0x0f80 3506 - #define IEEE80211_MLD_CAP_OP_AAR_SUPPORT 0x1000 3507 - #define IEEE80211_MLD_CAP_OP_LINK_RECONF_SUPPORT 0x2000 3508 - #define IEEE80211_MLD_CAP_OP_ALIGNED_TWT_SUPPORT 0x4000 3509 - 3510 - struct ieee80211_mle_basic_common_info { 3511 - u8 len; 3512 - u8 mld_mac_addr[ETH_ALEN]; 3513 - u8 variable[]; 3514 - } __packed; 3515 - 3516 - #define IEEE80211_MLC_PREQ_PRES_MLD_ID 0x0010 3517 - 3518 - struct ieee80211_mle_preq_common_info { 3519 - u8 len; 3520 - u8 variable[]; 3521 - } __packed; 3522 - 3523 - #define IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR 0x0010 3524 - #define IEEE80211_MLC_RECONF_PRES_EML_CAPA 0x0020 3525 - #define IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP 0x0040 3526 - #define IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP 0x0080 3527 - 3528 - /* no fixed fields in RECONF */ 3529 - 3530 - struct ieee80211_mle_tdls_common_info { 3531 - u8 len; 3532 - u8 ap_mld_mac_addr[ETH_ALEN]; 3533 - } __packed; 3534 - 3535 - #define IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR 0x0010 3536 - 3537 - /* no fixed fields in PRIO_ACCESS */ 3538 - 3539 - /** 3540 - * ieee80211_mle_common_size - check multi-link element common size 3541 - * @data: multi-link element, must already be checked for size using 3542 - * ieee80211_mle_size_ok() 3543 - * Return: the size of the multi-link element's "common" subfield 3544 - */ 3545 - static inline u8 ieee80211_mle_common_size(const u8 *data) 3546 - { 3547 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3548 - u16 control = le16_to_cpu(mle->control); 3549 - 3550 - switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 3551 - case IEEE80211_ML_CONTROL_TYPE_BASIC: 3552 - case IEEE80211_ML_CONTROL_TYPE_PREQ: 3553 - case IEEE80211_ML_CONTROL_TYPE_TDLS: 3554 - case IEEE80211_ML_CONTROL_TYPE_RECONF: 3555 - case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 3556 - /* 3557 - * The length is the first octet pointed by mle->variable so no 3558 - * need to add anything 3559 - */ 3560 - break; 3561 - default: 3562 - WARN_ON(1); 3563 - return 0; 3564 - } 3565 - 3566 - return sizeof(*mle) + mle->variable[0]; 3567 - } 3568 - 3569 - /** 3570 - * ieee80211_mle_get_link_id - returns the link ID 3571 - * @data: the basic multi link element 3572 - * Return: the link ID, or -1 if not present 3573 - * 3574 - * The element is assumed to be of the correct type (BASIC) and big enough, 3575 - * this must be checked using ieee80211_mle_type_ok(). 3576 - */ 3577 - static inline int ieee80211_mle_get_link_id(const u8 *data) 3578 - { 3579 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3580 - u16 control = le16_to_cpu(mle->control); 3581 - const u8 *common = mle->variable; 3582 - 3583 - /* common points now at the beginning of ieee80211_mle_basic_common_info */ 3584 - common += sizeof(struct ieee80211_mle_basic_common_info); 3585 - 3586 - if (!(control & IEEE80211_MLC_BASIC_PRES_LINK_ID)) 3587 - return -1; 3588 - 3589 - return *common; 3590 - } 3591 - 3592 - /** 3593 - * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count 3594 - * @data: pointer to the basic multi link element 3595 - * Return: the BSS Parameter Change Count field value, or -1 if not present 3596 - * 3597 - * The element is assumed to be of the correct type (BASIC) and big enough, 3598 - * this must be checked using ieee80211_mle_type_ok(). 3599 - */ 3600 - static inline int 3601 - ieee80211_mle_get_bss_param_ch_cnt(const u8 *data) 3602 - { 3603 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3604 - u16 control = le16_to_cpu(mle->control); 3605 - const u8 *common = mle->variable; 3606 - 3607 - /* common points now at the beginning of ieee80211_mle_basic_common_info */ 3608 - common += sizeof(struct ieee80211_mle_basic_common_info); 3609 - 3610 - if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) 3611 - return -1; 3612 - 3613 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3614 - common += 1; 3615 - 3616 - return *common; 3617 - } 3618 - 3619 - /** 3620 - * ieee80211_mle_get_eml_med_sync_delay - returns the medium sync delay 3621 - * @data: pointer to the multi-link element 3622 - * Return: the medium synchronization delay field value from the multi-link 3623 - * element, or the default value (%IEEE80211_MED_SYNC_DELAY_DEFAULT) 3624 - * if not present 3625 - * 3626 - * The element is assumed to be of the correct type (BASIC) and big enough, 3627 - * this must be checked using ieee80211_mle_type_ok(). 3628 - */ 3629 - static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data) 3630 - { 3631 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3632 - u16 control = le16_to_cpu(mle->control); 3633 - const u8 *common = mle->variable; 3634 - 3635 - /* common points now at the beginning of ieee80211_mle_basic_common_info */ 3636 - common += sizeof(struct ieee80211_mle_basic_common_info); 3637 - 3638 - if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) 3639 - return IEEE80211_MED_SYNC_DELAY_DEFAULT; 3640 - 3641 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3642 - common += 1; 3643 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3644 - common += 1; 3645 - 3646 - return get_unaligned_le16(common); 3647 - } 3648 - 3649 - /** 3650 - * ieee80211_mle_get_eml_cap - returns the EML capability 3651 - * @data: pointer to the multi-link element 3652 - * Return: the EML capability field value from the multi-link element, 3653 - * or 0 if not present 3654 - * 3655 - * The element is assumed to be of the correct type (BASIC) and big enough, 3656 - * this must be checked using ieee80211_mle_type_ok(). 3657 - */ 3658 - static inline u16 ieee80211_mle_get_eml_cap(const u8 *data) 3659 - { 3660 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3661 - u16 control = le16_to_cpu(mle->control); 3662 - const u8 *common = mle->variable; 3663 - 3664 - /* common points now at the beginning of ieee80211_mle_basic_common_info */ 3665 - common += sizeof(struct ieee80211_mle_basic_common_info); 3666 - 3667 - if (!(control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)) 3668 - return 0; 3669 - 3670 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3671 - common += 1; 3672 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3673 - common += 1; 3674 - if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 3675 - common += 2; 3676 - 3677 - return get_unaligned_le16(common); 3678 - } 3679 - 3680 - /** 3681 - * ieee80211_mle_get_mld_capa_op - returns the MLD capabilities and operations. 3682 - * @data: pointer to the multi-link element 3683 - * Return: the MLD capabilities and operations field value from the multi-link 3684 - * element, or 0 if not present 3685 - * 3686 - * The element is assumed to be of the correct type (BASIC) and big enough, 3687 - * this must be checked using ieee80211_mle_type_ok(). 3688 - */ 3689 - static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data) 3690 - { 3691 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3692 - u16 control = le16_to_cpu(mle->control); 3693 - const u8 *common = mle->variable; 3694 - 3695 - /* 3696 - * common points now at the beginning of 3697 - * ieee80211_mle_basic_common_info 3698 - */ 3699 - common += sizeof(struct ieee80211_mle_basic_common_info); 3700 - 3701 - if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)) 3702 - return 0; 3703 - 3704 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3705 - common += 1; 3706 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3707 - common += 1; 3708 - if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 3709 - common += 2; 3710 - if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 3711 - common += 2; 3712 - 3713 - return get_unaligned_le16(common); 3714 - } 3715 - 3716 - /* Defined in Figure 9-1074t in P802.11be_D7.0 */ 3717 - #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_PARAM_UPDATE 0x0001 3718 - #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_RECO_MAX_LINKS_MASK 0x001e 3719 - #define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020 3720 - #define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040 3721 - #define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080 3722 - 3723 - /** 3724 - * ieee80211_mle_get_ext_mld_capa_op - returns the extended MLD capabilities 3725 - * and operations. 3726 - * @data: pointer to the multi-link element 3727 - * Return: the extended MLD capabilities and operations field value from 3728 - * the multi-link element, or 0 if not present 3729 - * 3730 - * The element is assumed to be of the correct type (BASIC) and big enough, 3731 - * this must be checked using ieee80211_mle_type_ok(). 3732 - */ 3733 - static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data) 3734 - { 3735 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3736 - u16 control = le16_to_cpu(mle->control); 3737 - const u8 *common = mle->variable; 3738 - 3739 - /* 3740 - * common points now at the beginning of 3741 - * ieee80211_mle_basic_common_info 3742 - */ 3743 - common += sizeof(struct ieee80211_mle_basic_common_info); 3744 - 3745 - if (!(control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)) 3746 - return 0; 3747 - 3748 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3749 - common += 1; 3750 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3751 - common += 1; 3752 - if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 3753 - common += 2; 3754 - if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 3755 - common += 2; 3756 - if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 3757 - common += 2; 3758 - if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 3759 - common += 1; 3760 - 3761 - return get_unaligned_le16(common); 3762 - } 3763 - 3764 - /** 3765 - * ieee80211_mle_get_mld_id - returns the MLD ID 3766 - * @data: pointer to the multi-link element 3767 - * Return: The MLD ID in the given multi-link element, or 0 if not present 3768 - * 3769 - * The element is assumed to be of the correct type (BASIC) and big enough, 3770 - * this must be checked using ieee80211_mle_type_ok(). 3771 - */ 3772 - static inline u8 ieee80211_mle_get_mld_id(const u8 *data) 3773 - { 3774 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3775 - u16 control = le16_to_cpu(mle->control); 3776 - const u8 *common = mle->variable; 3777 - 3778 - /* 3779 - * common points now at the beginning of 3780 - * ieee80211_mle_basic_common_info 3781 - */ 3782 - common += sizeof(struct ieee80211_mle_basic_common_info); 3783 - 3784 - if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_ID)) 3785 - return 0; 3786 - 3787 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3788 - common += 1; 3789 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3790 - common += 1; 3791 - if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 3792 - common += 2; 3793 - if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 3794 - common += 2; 3795 - if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 3796 - common += 2; 3797 - 3798 - return *common; 3799 - } 3800 - 3801 - /** 3802 - * ieee80211_mle_size_ok - validate multi-link element size 3803 - * @data: pointer to the element data 3804 - * @len: length of the containing element 3805 - * Return: whether or not the multi-link element size is OK 3806 - */ 3807 - static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) 3808 - { 3809 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3810 - u8 fixed = sizeof(*mle); 3811 - u8 common = 0; 3812 - bool check_common_len = false; 3813 - u16 control; 3814 - 3815 - if (!data || len < fixed) 3816 - return false; 3817 - 3818 - control = le16_to_cpu(mle->control); 3819 - 3820 - switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 3821 - case IEEE80211_ML_CONTROL_TYPE_BASIC: 3822 - common += sizeof(struct ieee80211_mle_basic_common_info); 3823 - check_common_len = true; 3824 - if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 3825 - common += 1; 3826 - if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 3827 - common += 1; 3828 - if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 3829 - common += 2; 3830 - if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 3831 - common += 2; 3832 - if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 3833 - common += 2; 3834 - if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 3835 - common += 1; 3836 - if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP) 3837 - common += 2; 3838 - break; 3839 - case IEEE80211_ML_CONTROL_TYPE_PREQ: 3840 - common += sizeof(struct ieee80211_mle_preq_common_info); 3841 - if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID) 3842 - common += 1; 3843 - check_common_len = true; 3844 - break; 3845 - case IEEE80211_ML_CONTROL_TYPE_RECONF: 3846 - if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) 3847 - common += ETH_ALEN; 3848 - if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA) 3849 - common += 2; 3850 - if (control & IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP) 3851 - common += 2; 3852 - if (control & IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP) 3853 - common += 2; 3854 - break; 3855 - case IEEE80211_ML_CONTROL_TYPE_TDLS: 3856 - common += sizeof(struct ieee80211_mle_tdls_common_info); 3857 - check_common_len = true; 3858 - break; 3859 - case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 3860 - common = ETH_ALEN + 1; 3861 - break; 3862 - default: 3863 - /* we don't know this type */ 3864 - return true; 3865 - } 3866 - 3867 - if (len < fixed + common) 3868 - return false; 3869 - 3870 - if (!check_common_len) 3871 - return true; 3872 - 3873 - /* if present, common length is the first octet there */ 3874 - return mle->variable[0] >= common; 3875 - } 3876 - 3877 - /** 3878 - * ieee80211_mle_type_ok - validate multi-link element type and size 3879 - * @data: pointer to the element data 3880 - * @type: expected type of the element 3881 - * @len: length of the containing element 3882 - * Return: whether or not the multi-link element type matches and size is OK 3883 - */ 3884 - static inline bool ieee80211_mle_type_ok(const u8 *data, u8 type, size_t len) 3885 - { 3886 - const struct ieee80211_multi_link_elem *mle = (const void *)data; 3887 - u16 control; 3888 - 3889 - if (!ieee80211_mle_size_ok(data, len)) 3890 - return false; 3891 - 3892 - control = le16_to_cpu(mle->control); 3893 - 3894 - if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) == type) 3895 - return true; 3896 - 3897 - return false; 3898 - } 3899 - 3900 - enum ieee80211_mle_subelems { 3901 - IEEE80211_MLE_SUBELEM_PER_STA_PROFILE = 0, 3902 - IEEE80211_MLE_SUBELEM_FRAGMENT = 254, 3903 - }; 3904 - 3905 - #define IEEE80211_MLE_STA_CONTROL_LINK_ID 0x000f 3906 - #define IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE 0x0010 3907 - #define IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 3908 - #define IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT 0x0040 3909 - #define IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT 0x0080 3910 - #define IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT 0x0100 3911 - #define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200 3912 - #define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400 3913 - #define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800 3914 - 3915 - struct ieee80211_mle_per_sta_profile { 3916 - __le16 control; 3917 - u8 sta_info_len; 3918 - u8 variable[]; 3919 - } __packed; 3920 - 3921 - /** 3922 - * ieee80211_mle_basic_sta_prof_size_ok - validate basic multi-link element sta 3923 - * profile size 3924 - * @data: pointer to the sub element data 3925 - * @len: length of the containing sub element 3926 - * Return: %true if the STA profile is large enough, %false otherwise 3927 - */ 3928 - static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data, 3929 - size_t len) 3930 - { 3931 - const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 3932 - u16 control; 3933 - u8 fixed = sizeof(*prof); 3934 - u8 info_len = 1; 3935 - 3936 - if (len < fixed) 3937 - return false; 3938 - 3939 - control = le16_to_cpu(prof->control); 3940 - 3941 - if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 3942 - info_len += 6; 3943 - if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 3944 - info_len += 2; 3945 - if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 3946 - info_len += 8; 3947 - if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 3948 - info_len += 2; 3949 - if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 3950 - control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 3951 - if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 3952 - info_len += 2; 3953 - else 3954 - info_len += 1; 3955 - } 3956 - if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) 3957 - info_len += 1; 3958 - 3959 - return prof->sta_info_len >= info_len && 3960 - fixed + prof->sta_info_len - 1 <= len; 3961 - } 3962 - 3963 - /** 3964 - * ieee80211_mle_basic_sta_prof_bss_param_ch_cnt - get per-STA profile BSS 3965 - * parameter change count 3966 - * @prof: the per-STA profile, having been checked with 3967 - * ieee80211_mle_basic_sta_prof_size_ok() for the correct length 3968 - * 3969 - * Return: The BSS parameter change count value if present, 0 otherwise. 3970 - */ 3971 - static inline u8 3972 - ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta_profile *prof) 3973 - { 3974 - u16 control = le16_to_cpu(prof->control); 3975 - const u8 *pos = prof->variable; 3976 - 3977 - if (!(control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)) 3978 - return 0; 3979 - 3980 - if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 3981 - pos += 6; 3982 - if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 3983 - pos += 2; 3984 - if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 3985 - pos += 8; 3986 - if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 3987 - pos += 2; 3988 - if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 3989 - control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 3990 - if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 3991 - pos += 2; 3992 - else 3993 - pos += 1; 3994 - } 3995 - 3996 - return *pos; 3997 - } 3998 - 3999 - #define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f 4000 - #define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 4001 - #define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 4002 - #define IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT 0x0040 4003 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE 0x0780 4004 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_AP_REM 0 4005 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_OP_PARAM_UPDATE 1 4006 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_ADD_LINK 2 4007 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_DEL_LINK 3 4008 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_NSTR_STATUS 4 4009 - #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 4010 - 4011 - /** 4012 - * ieee80211_mle_reconf_sta_prof_size_ok - validate reconfiguration multi-link 4013 - * element sta profile size. 4014 - * @data: pointer to the sub element data 4015 - * @len: length of the containing sub element 4016 - * Return: %true if the STA profile is large enough, %false otherwise 4017 - */ 4018 - static inline bool ieee80211_mle_reconf_sta_prof_size_ok(const u8 *data, 4019 - size_t len) 4020 - { 4021 - const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 4022 - u16 control; 4023 - u8 fixed = sizeof(*prof); 4024 - u8 info_len = 1; 4025 - 4026 - if (len < fixed) 4027 - return false; 4028 - 4029 - control = le16_to_cpu(prof->control); 4030 - 4031 - if (control & IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT) 4032 - info_len += ETH_ALEN; 4033 - if (control & IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT) 4034 - info_len += 2; 4035 - if (control & IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT) 4036 - info_len += 2; 4037 - 4038 - return prof->sta_info_len >= info_len && 4039 - fixed + prof->sta_info_len - 1 <= len; 4040 - } 4041 - 4042 - #define IEEE80211_MLE_STA_EPCS_CONTROL_LINK_ID 0x000f 4043 - #define IEEE80211_EPCS_ENA_RESP_BODY_LEN 3 4044 - 4045 - static inline bool ieee80211_tid_to_link_map_size_ok(const u8 *data, size_t len) 4046 - { 4047 - const struct ieee80211_ttlm_elem *t2l = (const void *)data; 4048 - u8 control, fixed = sizeof(*t2l), elem_len = 0; 4049 - 4050 - if (len < fixed) 4051 - return false; 4052 - 4053 - control = t2l->control; 4054 - 4055 - if (control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT) 4056 - elem_len += 2; 4057 - if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) 4058 - elem_len += 3; 4059 - 4060 - if (!(control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP)) { 4061 - u8 bm_size; 4062 - 4063 - elem_len += 1; 4064 - if (len < fixed + elem_len) 4065 - return false; 4066 - 4067 - if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE) 4068 - bm_size = 1; 4069 - else 4070 - bm_size = 2; 4071 - 4072 - elem_len += hweight8(t2l->optional[0]) * bm_size; 4073 - } 4074 - 4075 - return len >= fixed + elem_len; 4076 - } 4077 - 4078 - /** 4079 - * ieee80211_emlsr_pad_delay_in_us - Fetch the EMLSR Padding delay 4080 - * in microseconds 4081 - * @eml_cap: EML capabilities field value from common info field of 4082 - * the Multi-link element 4083 - * Return: the EMLSR Padding delay (in microseconds) encoded in the 4084 - * EML Capabilities field 4085 - */ 4086 - 4087 - static inline u32 ieee80211_emlsr_pad_delay_in_us(u16 eml_cap) 4088 - { 4089 - /* IEEE Std 802.11be-2024 Table 9-417i—Encoding of the EMLSR 4090 - * Padding Delay subfield. 4091 - */ 4092 - u32 pad_delay = u16_get_bits(eml_cap, 4093 - IEEE80211_EML_CAP_EMLSR_PADDING_DELAY); 4094 - 4095 - if (!pad_delay || 4096 - pad_delay > IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US) 4097 - return 0; 4098 - 4099 - return 32 * (1 << (pad_delay - 1)); 4100 - } 4101 - 4102 - /** 4103 - * ieee80211_emlsr_trans_delay_in_us - Fetch the EMLSR Transition 4104 - * delay in microseconds 4105 - * @eml_cap: EML capabilities field value from common info field of 4106 - * the Multi-link element 4107 - * Return: the EMLSR Transition delay (in microseconds) encoded in the 4108 - * EML Capabilities field 4109 - */ 4110 - 4111 - static inline u32 ieee80211_emlsr_trans_delay_in_us(u16 eml_cap) 4112 - { 4113 - /* IEEE Std 802.11be-2024 Table 9-417j—Encoding of the EMLSR 4114 - * Transition Delay subfield. 4115 - */ 4116 - u32 trans_delay = 4117 - u16_get_bits(eml_cap, 4118 - IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY); 4119 - 4120 - /* invalid values also just use 0 */ 4121 - if (!trans_delay || 4122 - trans_delay > IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US) 4123 - return 0; 4124 - 4125 - return 16 * (1 << (trans_delay - 1)); 4126 - } 4127 - 4128 - /** 4129 - * ieee80211_eml_trans_timeout_in_us - Fetch the EMLSR Transition 4130 - * timeout value in microseconds 4131 - * @eml_cap: EML capabilities field value from common info field of 4132 - * the Multi-link element 4133 - * Return: the EMLSR Transition timeout (in microseconds) encoded in 4134 - * the EML Capabilities field 4135 - */ 4136 - 4137 - static inline u32 ieee80211_eml_trans_timeout_in_us(u16 eml_cap) 4138 - { 4139 - /* IEEE Std 802.11be-2024 Table 9-417m—Encoding of the 4140 - * Transition Timeout subfield. 4141 - */ 4142 - u8 timeout = u16_get_bits(eml_cap, 4143 - IEEE80211_EML_CAP_TRANSITION_TIMEOUT); 4144 - 4145 - /* invalid values also just use 0 */ 4146 - if (!timeout || timeout > IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU) 4147 - return 0; 4148 - 4149 - return 128 * (1 << (timeout - 1)); 4150 - } 4151 - 4152 - #define for_each_mle_subelement(_elem, _data, _len) \ 4153 - if (ieee80211_mle_size_ok(_data, _len)) \ 4154 - for_each_element(_elem, \ 4155 - _data + ieee80211_mle_common_size(_data),\ 4156 - _len - ieee80211_mle_common_size(_data)) 4157 - 4158 3858 /* NAN operation mode, as defined in Wi-Fi Aware (TM) specification Table 81 */ 4159 3859 #define NAN_OP_MODE_PHY_MODE_VHT 0x01 4160 3860 #define NAN_OP_MODE_PHY_MODE_HE 0x10 ··· 3443 4605 3444 4606 #include "ieee80211-ht.h" 3445 4607 #include "ieee80211-vht.h" 4608 + #include "ieee80211-he.h" 4609 + #include "ieee80211-eht.h" 3446 4610 #include "ieee80211-mesh.h" 3447 4611 3448 4612 #endif /* LINUX_IEEE80211_H */