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 #define IEEE80211_EML_CTRL_EMLSR_MODE BIT(0) 562 #define IEEE80211_EML_CTRL_EMLMR_MODE BIT(1) 563 #define IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE BIT(2) 564 #define IEEE80211_EML_CTRL_INDEV_COEX_ACT BIT(3) 565 566 #define IEEE80211_EML_EMLSR_PAD_DELAY 0x07 567 #define IEEE80211_EML_EMLSR_TRANS_DELAY 0x38 568 569 #define IEEE80211_EML_EMLMR_RX_MCS_MAP 0xf0 570 #define IEEE80211_EML_EMLMR_TX_MCS_MAP 0x0f 571 572 /* no fixed fields in PRIO_ACCESS */ 573 574 /** 575 * ieee80211_mle_common_size - check multi-link element common size 576 * @data: multi-link element, must already be checked for size using 577 * ieee80211_mle_size_ok() 578 * Return: the size of the multi-link element's "common" subfield 579 */ 580 static inline u8 ieee80211_mle_common_size(const u8 *data) 581 { 582 const struct ieee80211_multi_link_elem *mle = (const void *)data; 583 u16 control = le16_to_cpu(mle->control); 584 585 switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 586 case IEEE80211_ML_CONTROL_TYPE_BASIC: 587 case IEEE80211_ML_CONTROL_TYPE_PREQ: 588 case IEEE80211_ML_CONTROL_TYPE_TDLS: 589 case IEEE80211_ML_CONTROL_TYPE_RECONF: 590 case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 591 /* 592 * The length is the first octet pointed by mle->variable so no 593 * need to add anything 594 */ 595 break; 596 default: 597 WARN_ON(1); 598 return 0; 599 } 600 601 return sizeof(*mle) + mle->variable[0]; 602 } 603 604 /** 605 * ieee80211_mle_get_link_id - returns the link ID 606 * @data: the basic multi link element 607 * Return: the link ID, or -1 if not present 608 * 609 * The element is assumed to be of the correct type (BASIC) and big enough, 610 * this must be checked using ieee80211_mle_type_ok(). 611 */ 612 static inline int ieee80211_mle_get_link_id(const u8 *data) 613 { 614 const struct ieee80211_multi_link_elem *mle = (const void *)data; 615 u16 control = le16_to_cpu(mle->control); 616 const u8 *common = mle->variable; 617 618 /* common points now at the beginning of ieee80211_mle_basic_common_info */ 619 common += sizeof(struct ieee80211_mle_basic_common_info); 620 621 if (!(control & IEEE80211_MLC_BASIC_PRES_LINK_ID)) 622 return -1; 623 624 return *common; 625 } 626 627 /** 628 * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count 629 * @data: pointer to the basic multi link element 630 * Return: the BSS Parameter Change Count field value, or -1 if not present 631 * 632 * The element is assumed to be of the correct type (BASIC) and big enough, 633 * this must be checked using ieee80211_mle_type_ok(). 634 */ 635 static inline int 636 ieee80211_mle_get_bss_param_ch_cnt(const u8 *data) 637 { 638 const struct ieee80211_multi_link_elem *mle = (const void *)data; 639 u16 control = le16_to_cpu(mle->control); 640 const u8 *common = mle->variable; 641 642 /* common points now at the beginning of ieee80211_mle_basic_common_info */ 643 common += sizeof(struct ieee80211_mle_basic_common_info); 644 645 if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) 646 return -1; 647 648 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 649 common += 1; 650 651 return *common; 652 } 653 654 /** 655 * ieee80211_mle_get_eml_med_sync_delay - returns the medium sync delay 656 * @data: pointer to the multi-link element 657 * Return: the medium synchronization delay field value from the multi-link 658 * element, or the default value (%IEEE80211_MED_SYNC_DELAY_DEFAULT) 659 * if not present 660 * 661 * The element is assumed to be of the correct type (BASIC) and big enough, 662 * this must be checked using ieee80211_mle_type_ok(). 663 */ 664 static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data) 665 { 666 const struct ieee80211_multi_link_elem *mle = (const void *)data; 667 u16 control = le16_to_cpu(mle->control); 668 const u8 *common = mle->variable; 669 670 /* common points now at the beginning of ieee80211_mle_basic_common_info */ 671 common += sizeof(struct ieee80211_mle_basic_common_info); 672 673 if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) 674 return IEEE80211_MED_SYNC_DELAY_DEFAULT; 675 676 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 677 common += 1; 678 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 679 common += 1; 680 681 return get_unaligned_le16(common); 682 } 683 684 /** 685 * ieee80211_mle_get_eml_cap - returns the EML capability 686 * @data: pointer to the multi-link element 687 * Return: the EML capability field value from the multi-link element, 688 * or 0 if not present 689 * 690 * The element is assumed to be of the correct type (BASIC) and big enough, 691 * this must be checked using ieee80211_mle_type_ok(). 692 */ 693 static inline u16 ieee80211_mle_get_eml_cap(const u8 *data) 694 { 695 const struct ieee80211_multi_link_elem *mle = (const void *)data; 696 u16 control = le16_to_cpu(mle->control); 697 const u8 *common = mle->variable; 698 699 /* common points now at the beginning of ieee80211_mle_basic_common_info */ 700 common += sizeof(struct ieee80211_mle_basic_common_info); 701 702 if (!(control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)) 703 return 0; 704 705 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 706 common += 1; 707 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 708 common += 1; 709 if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 710 common += 2; 711 712 return get_unaligned_le16(common); 713 } 714 715 /** 716 * ieee80211_mle_get_mld_capa_op - returns the MLD capabilities and operations. 717 * @data: pointer to the multi-link element 718 * Return: the MLD capabilities and operations field value from the multi-link 719 * element, or 0 if not present 720 * 721 * The element is assumed to be of the correct type (BASIC) and big enough, 722 * this must be checked using ieee80211_mle_type_ok(). 723 */ 724 static inline u16 ieee80211_mle_get_mld_capa_op(const u8 *data) 725 { 726 const struct ieee80211_multi_link_elem *mle = (const void *)data; 727 u16 control = le16_to_cpu(mle->control); 728 const u8 *common = mle->variable; 729 730 /* 731 * common points now at the beginning of 732 * ieee80211_mle_basic_common_info 733 */ 734 common += sizeof(struct ieee80211_mle_basic_common_info); 735 736 if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)) 737 return 0; 738 739 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 740 common += 1; 741 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 742 common += 1; 743 if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 744 common += 2; 745 if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 746 common += 2; 747 748 return get_unaligned_le16(common); 749 } 750 751 /* Defined in Figure 9-1074t in P802.11be_D7.0 */ 752 #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_PARAM_UPDATE 0x0001 753 #define IEEE80211_EHT_ML_EXT_MLD_CAPA_OP_RECO_MAX_LINKS_MASK 0x001e 754 #define IEEE80211_EHT_ML_EXT_MLD_CAPA_NSTR_UPDATE 0x0020 755 #define IEEE80211_EHT_ML_EXT_MLD_CAPA_EMLSR_ENA_ON_ONE_LINK 0x0040 756 #define IEEE80211_EHT_ML_EXT_MLD_CAPA_BTM_MLD_RECO_MULTI_AP 0x0080 757 758 /** 759 * ieee80211_mle_get_ext_mld_capa_op - returns the extended MLD capabilities 760 * and operations. 761 * @data: pointer to the multi-link element 762 * Return: the extended MLD capabilities and operations field value from 763 * the multi-link element, or 0 if not present 764 * 765 * The element is assumed to be of the correct type (BASIC) and big enough, 766 * this must be checked using ieee80211_mle_type_ok(). 767 */ 768 static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data) 769 { 770 const struct ieee80211_multi_link_elem *mle = (const void *)data; 771 u16 control = le16_to_cpu(mle->control); 772 const u8 *common = mle->variable; 773 774 /* 775 * common points now at the beginning of 776 * ieee80211_mle_basic_common_info 777 */ 778 common += sizeof(struct ieee80211_mle_basic_common_info); 779 780 if (!(control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)) 781 return 0; 782 783 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 784 common += 1; 785 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 786 common += 1; 787 if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 788 common += 2; 789 if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 790 common += 2; 791 if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 792 common += 2; 793 if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 794 common += 1; 795 796 return get_unaligned_le16(common); 797 } 798 799 /** 800 * ieee80211_mle_get_mld_id - returns the MLD ID 801 * @data: pointer to the multi-link element 802 * Return: The MLD ID in the given multi-link element, or 0 if not present 803 * 804 * The element is assumed to be of the correct type (BASIC) and big enough, 805 * this must be checked using ieee80211_mle_type_ok(). 806 */ 807 static inline u8 ieee80211_mle_get_mld_id(const u8 *data) 808 { 809 const struct ieee80211_multi_link_elem *mle = (const void *)data; 810 u16 control = le16_to_cpu(mle->control); 811 const u8 *common = mle->variable; 812 813 /* 814 * common points now at the beginning of 815 * ieee80211_mle_basic_common_info 816 */ 817 common += sizeof(struct ieee80211_mle_basic_common_info); 818 819 if (!(control & IEEE80211_MLC_BASIC_PRES_MLD_ID)) 820 return 0; 821 822 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 823 common += 1; 824 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 825 common += 1; 826 if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 827 common += 2; 828 if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 829 common += 2; 830 if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 831 common += 2; 832 833 return *common; 834 } 835 836 /** 837 * ieee80211_mle_size_ok - validate multi-link element size 838 * @data: pointer to the element data 839 * @len: length of the containing element 840 * Return: whether or not the multi-link element size is OK 841 */ 842 static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) 843 { 844 const struct ieee80211_multi_link_elem *mle = (const void *)data; 845 u8 fixed = sizeof(*mle); 846 u8 common = 0; 847 bool check_common_len = false; 848 u16 control; 849 850 if (!data || len < fixed) 851 return false; 852 853 control = le16_to_cpu(mle->control); 854 855 switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) { 856 case IEEE80211_ML_CONTROL_TYPE_BASIC: 857 common += sizeof(struct ieee80211_mle_basic_common_info); 858 check_common_len = true; 859 if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) 860 common += 1; 861 if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) 862 common += 1; 863 if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) 864 common += 2; 865 if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA) 866 common += 2; 867 if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP) 868 common += 2; 869 if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID) 870 common += 1; 871 if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP) 872 common += 2; 873 break; 874 case IEEE80211_ML_CONTROL_TYPE_PREQ: 875 common += sizeof(struct ieee80211_mle_preq_common_info); 876 if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID) 877 common += 1; 878 check_common_len = true; 879 break; 880 case IEEE80211_ML_CONTROL_TYPE_RECONF: 881 if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) 882 common += ETH_ALEN; 883 if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA) 884 common += 2; 885 if (control & IEEE80211_MLC_RECONF_PRES_MLD_CAPA_OP) 886 common += 2; 887 if (control & IEEE80211_MLC_RECONF_PRES_EXT_MLD_CAPA_OP) 888 common += 2; 889 break; 890 case IEEE80211_ML_CONTROL_TYPE_TDLS: 891 common += sizeof(struct ieee80211_mle_tdls_common_info); 892 check_common_len = true; 893 break; 894 case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 895 common = ETH_ALEN + 1; 896 break; 897 default: 898 /* we don't know this type */ 899 return true; 900 } 901 902 if (len < fixed + common) 903 return false; 904 905 if (!check_common_len) 906 return true; 907 908 /* if present, common length is the first octet there */ 909 return mle->variable[0] >= common; 910 } 911 912 /** 913 * ieee80211_mle_type_ok - validate multi-link element type and size 914 * @data: pointer to the element data 915 * @type: expected type of the element 916 * @len: length of the containing element 917 * Return: whether or not the multi-link element type matches and size is OK 918 */ 919 static inline bool ieee80211_mle_type_ok(const u8 *data, u8 type, size_t len) 920 { 921 const struct ieee80211_multi_link_elem *mle = (const void *)data; 922 u16 control; 923 924 if (!ieee80211_mle_size_ok(data, len)) 925 return false; 926 927 control = le16_to_cpu(mle->control); 928 929 if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) == type) 930 return true; 931 932 return false; 933 } 934 935 enum ieee80211_mle_subelems { 936 IEEE80211_MLE_SUBELEM_PER_STA_PROFILE = 0, 937 IEEE80211_MLE_SUBELEM_FRAGMENT = 254, 938 }; 939 940 #define IEEE80211_MLE_STA_CONTROL_LINK_ID 0x000f 941 #define IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE 0x0010 942 #define IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 943 #define IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT 0x0040 944 #define IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT 0x0080 945 #define IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT 0x0100 946 #define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200 947 #define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400 948 #define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800 949 950 struct ieee80211_mle_per_sta_profile { 951 __le16 control; 952 u8 sta_info_len; 953 u8 variable[]; 954 } __packed; 955 956 /** 957 * ieee80211_mle_basic_sta_prof_size_ok - validate basic multi-link element sta 958 * profile size 959 * @data: pointer to the sub element data 960 * @len: length of the containing sub element 961 * Return: %true if the STA profile is large enough, %false otherwise 962 */ 963 static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data, 964 size_t len) 965 { 966 const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 967 u16 control; 968 u8 fixed = sizeof(*prof); 969 u8 info_len = 1; 970 971 if (len < fixed) 972 return false; 973 974 control = le16_to_cpu(prof->control); 975 976 if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 977 info_len += 6; 978 if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 979 info_len += 2; 980 if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 981 info_len += 8; 982 if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 983 info_len += 2; 984 if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 985 control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 986 if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 987 info_len += 2; 988 else 989 info_len += 1; 990 } 991 if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) 992 info_len += 1; 993 994 return prof->sta_info_len >= info_len && 995 fixed + prof->sta_info_len - 1 <= len; 996 } 997 998 /** 999 * ieee80211_mle_basic_sta_prof_bss_param_ch_cnt - get per-STA profile BSS 1000 * parameter change count 1001 * @prof: the per-STA profile, having been checked with 1002 * ieee80211_mle_basic_sta_prof_size_ok() for the correct length 1003 * 1004 * Return: The BSS parameter change count value if present, 0 otherwise. 1005 */ 1006 static inline u8 1007 ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta_profile *prof) 1008 { 1009 u16 control = le16_to_cpu(prof->control); 1010 const u8 *pos = prof->variable; 1011 1012 if (!(control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)) 1013 return 0; 1014 1015 if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) 1016 pos += 6; 1017 if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) 1018 pos += 2; 1019 if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) 1020 pos += 8; 1021 if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) 1022 pos += 2; 1023 if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && 1024 control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { 1025 if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) 1026 pos += 2; 1027 else 1028 pos += 1; 1029 } 1030 1031 return *pos; 1032 } 1033 1034 #define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f 1035 #define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 1036 #define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 1037 #define IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT 0x0040 1038 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE 0x0780 1039 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_AP_REM 0 1040 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_OP_PARAM_UPDATE 1 1041 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_ADD_LINK 2 1042 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_DEL_LINK 3 1043 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_TYPE_NSTR_STATUS 4 1044 #define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 1045 1046 /** 1047 * ieee80211_mle_reconf_sta_prof_size_ok - validate reconfiguration multi-link 1048 * element sta profile size. 1049 * @data: pointer to the sub element data 1050 * @len: length of the containing sub element 1051 * Return: %true if the STA profile is large enough, %false otherwise 1052 */ 1053 static inline bool ieee80211_mle_reconf_sta_prof_size_ok(const u8 *data, 1054 size_t len) 1055 { 1056 const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; 1057 u16 control; 1058 u8 fixed = sizeof(*prof); 1059 u8 info_len = 1; 1060 1061 if (len < fixed) 1062 return false; 1063 1064 control = le16_to_cpu(prof->control); 1065 1066 if (control & IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT) 1067 info_len += ETH_ALEN; 1068 if (control & IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT) 1069 info_len += 2; 1070 if (control & IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT) 1071 info_len += 2; 1072 1073 return prof->sta_info_len >= info_len && 1074 fixed + prof->sta_info_len - 1 <= len; 1075 } 1076 1077 #define IEEE80211_MLE_STA_EPCS_CONTROL_LINK_ID 0x000f 1078 #define IEEE80211_EPCS_ENA_RESP_BODY_LEN 3 1079 1080 static inline bool ieee80211_tid_to_link_map_size_ok(const u8 *data, size_t len) 1081 { 1082 const struct ieee80211_ttlm_elem *t2l = (const void *)data; 1083 u8 control, fixed = sizeof(*t2l), elem_len = 0; 1084 1085 if (len < fixed) 1086 return false; 1087 1088 control = t2l->control; 1089 1090 if (control & IEEE80211_TTLM_CONTROL_SWITCH_TIME_PRESENT) 1091 elem_len += 2; 1092 if (control & IEEE80211_TTLM_CONTROL_EXPECTED_DUR_PRESENT) 1093 elem_len += 3; 1094 1095 if (!(control & IEEE80211_TTLM_CONTROL_DEF_LINK_MAP)) { 1096 u8 bm_size; 1097 1098 elem_len += 1; 1099 if (len < fixed + elem_len) 1100 return false; 1101 1102 if (control & IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE) 1103 bm_size = 1; 1104 else 1105 bm_size = 2; 1106 1107 elem_len += hweight8(t2l->optional[0]) * bm_size; 1108 } 1109 1110 return len >= fixed + elem_len; 1111 } 1112 1113 /** 1114 * ieee80211_emlsr_pad_delay_in_us - Fetch the EMLSR Padding delay 1115 * in microseconds 1116 * @eml_cap: EML capabilities field value from common info field of 1117 * the Multi-link element 1118 * Return: the EMLSR Padding delay (in microseconds) encoded in the 1119 * EML Capabilities field 1120 */ 1121 1122 static inline u32 ieee80211_emlsr_pad_delay_in_us(u16 eml_cap) 1123 { 1124 /* IEEE Std 802.11be-2024 Table 9-417i—Encoding of the EMLSR 1125 * Padding Delay subfield. 1126 */ 1127 u32 pad_delay = u16_get_bits(eml_cap, 1128 IEEE80211_EML_CAP_EMLSR_PADDING_DELAY); 1129 1130 if (!pad_delay || 1131 pad_delay > IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_256US) 1132 return 0; 1133 1134 return 32 * (1 << (pad_delay - 1)); 1135 } 1136 1137 /** 1138 * ieee80211_emlsr_trans_delay_in_us - Fetch the EMLSR Transition 1139 * delay in microseconds 1140 * @eml_cap: EML capabilities field value from common info field of 1141 * the Multi-link element 1142 * Return: the EMLSR Transition delay (in microseconds) encoded in the 1143 * EML Capabilities field 1144 */ 1145 1146 static inline u32 ieee80211_emlsr_trans_delay_in_us(u16 eml_cap) 1147 { 1148 /* IEEE Std 802.11be-2024 Table 9-417j—Encoding of the EMLSR 1149 * Transition Delay subfield. 1150 */ 1151 u32 trans_delay = 1152 u16_get_bits(eml_cap, 1153 IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY); 1154 1155 /* invalid values also just use 0 */ 1156 if (!trans_delay || 1157 trans_delay > IEEE80211_EML_CAP_EMLSR_TRANSITION_DELAY_256US) 1158 return 0; 1159 1160 return 16 * (1 << (trans_delay - 1)); 1161 } 1162 1163 /** 1164 * ieee80211_eml_trans_timeout_in_us - Fetch the EMLSR Transition 1165 * timeout value in microseconds 1166 * @eml_cap: EML capabilities field value from common info field of 1167 * the Multi-link element 1168 * Return: the EMLSR Transition timeout (in microseconds) encoded in 1169 * the EML Capabilities field 1170 */ 1171 1172 static inline u32 ieee80211_eml_trans_timeout_in_us(u16 eml_cap) 1173 { 1174 /* IEEE Std 802.11be-2024 Table 9-417m—Encoding of the 1175 * Transition Timeout subfield. 1176 */ 1177 u8 timeout = u16_get_bits(eml_cap, 1178 IEEE80211_EML_CAP_TRANSITION_TIMEOUT); 1179 1180 /* invalid values also just use 0 */ 1181 if (!timeout || timeout > IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU) 1182 return 0; 1183 1184 return 128 * (1 << (timeout - 1)); 1185 } 1186 1187 #define for_each_mle_subelement(_elem, _data, _len) \ 1188 if (ieee80211_mle_size_ok(_data, _len)) \ 1189 for_each_element(_elem, \ 1190 _data + ieee80211_mle_common_size(_data),\ 1191 _len - ieee80211_mle_common_size(_data)) 1192 1193 #endif /* LINUX_IEEE80211_EHT_H */ 1194