1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * DOC: contains MLO manager containing util public api's 20 */ 21 #ifndef _WLAN_UTILS_MLO_H_ 22 #define _WLAN_UTILS_MLO_H_ 23 24 #include <wlan_cmn_ieee80211.h> 25 #include "wlan_mlo_mgr_public_structs.h" 26 #include <wlan_cm_ucfg_api.h> 27 #include <wlan_objmgr_vdev_obj.h> 28 29 #ifdef WLAN_FEATURE_11BE_MLO 30 31 /** 32 * util_gen_link_assoc_req() - Generate link specific assoc request 33 * @frame: Pointer to original association request. This should not contain the 34 * 802.11 header, and must start from the fixed fields in the association 35 * request. This is required due to some caller semantics built into the end to 36 * end design. 37 * @frame_len: Length of original association request 38 * @isreassoc: Whether this is a re-association request 39 * @link_addr: Secondary link's MAC address 40 * @link_frame: Generated secondary link specific association request. Note that 41 * this will start from the 802.11 header (unlike the original association 42 * request). This should be ignored in the case of failure. 43 * @link_frame_maxsize: Maximum size of generated secondary link specific 44 * association request 45 * @link_frame_len: Pointer to location where populated length of generated 46 * secondary link specific association request should be written. This should be 47 * ignored in the case of failure. 48 * 49 * Generate a link specific logically equivalent association request for the 50 * secondary link from the original association request containing a Multi-Link 51 * element. This applies to both association and re-association requests. 52 * Currently, only two link MLO is supported. 53 * 54 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 55 * the reason for error in the case of failure. 56 */ 57 QDF_STATUS 58 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 59 struct qdf_mac_addr link_addr, 60 uint8_t *link_frame, 61 qdf_size_t link_frame_maxsize, 62 qdf_size_t *link_frame_len); 63 64 /** 65 * util_gen_link_assoc_rsp() - Generate link specific assoc response 66 * @frame: Pointer to original association response. This should not contain the 67 * 802.11 header, and must start from the fixed fields in the association 68 * response. This is required due to some caller semantics built into the end to 69 * end design. 70 * @frame_len: Length of original association response 71 * @isreassoc: Whether this is a re-association response 72 * @link_addr: Secondary link's MAC address 73 * @link_frame: Generated secondary link specific association response. Note 74 * that this will start from the 802.11 header (unlike the original association 75 * response). This should be ignored in the case of failure. 76 * @link_frame_maxsize: Maximum size of generated secondary link specific 77 * association response 78 * @link_frame_len: Pointer to location where populated length of generated 79 * secondary link specific association response should be written. This should 80 * be ignored in the case of failure. 81 * 82 * Generate a link specific logically equivalent association response for the 83 * secondary link from the original association response containing a Multi-Link 84 * element. This applies to both association and re-association responses. 85 * Currently, only two link MLO is supported. 86 * 87 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 88 * the reason for error in the case of failure. 89 */ 90 QDF_STATUS 91 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 92 struct qdf_mac_addr link_addr, 93 uint8_t *link_frame, 94 qdf_size_t link_frame_maxsize, 95 qdf_size_t *link_frame_len); 96 97 /** 98 * util_gen_link_probe_rsp() - Generate link specific probe response 99 * @frame: Pointer to original probe response. This should not contain the 100 * 802.11 header, and must start from the fixed fields in the probe 101 * response. This is required due to some caller semantics built into the end to 102 * end design. 103 * @frame_len: Length of original probe response 104 * @link_addr: Secondary link's MAC address 105 * @link_frame: Generated secondary link specific probe response. Note 106 * that this will start from the 802.11 header (unlike the original probe 107 * response). This should be ignored in the case of failure. 108 * @link_frame_maxsize: Maximum size of generated secondary link specific 109 * probe response 110 * @link_frame_len: Pointer to location where populated length of generated 111 * secondary link specific probe response should be written. This should 112 * be ignored in the case of failure. 113 * 114 * Generate a link specific logically equivalent probe response for the 115 * secondary link from the original probe response containing a Multi-Link 116 * element. This applies to both probe responses. 117 * Currently, only two link MLO is supported. 118 * 119 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 120 * the reason for error in the case of failure. 121 */ 122 QDF_STATUS 123 util_gen_link_probe_rsp(uint8_t *frame, qdf_size_t frame_len, 124 struct qdf_mac_addr link_addr, 125 uint8_t *link_frame, 126 qdf_size_t link_frame_maxsize, 127 qdf_size_t *link_frame_len); 128 129 /** 130 * util_find_mlie - Find the first Multi-Link element or the start of the first 131 * Multi-Link element fragment sequence in a given buffer containing elements, 132 * if a Multi-Link element or element fragment sequence exists in the given 133 * buffer. 134 * 135 * @buf: Buffer to be searched for the Multi-Link element or the start of the 136 * Multi-Link element fragment sequence 137 * @buflen: Length of the buffer 138 * @mlieseq: Pointer to location where the starting address of the Multi-Link 139 * element or Multi-Link element fragment sequence should be updated if found 140 * in the given buffer. The value NULL will be updated to this location if the 141 * element or element fragment sequence is not found. This should be ignored by 142 * the caller if the function returns error. 143 * @mlieseqlen: Pointer to location where the total length of the Multi-Link 144 * element or Multi-Link element fragment sequence should be updated if found 145 * in the given buffer. This should be ignored by the caller if the function 146 * returns error, or if the function indicates that the element or element 147 * fragment sequence was not found by providing a starting address of NULL. 148 * 149 * Find the first Multi-Link element or the start of the first Multi-Link 150 * element fragment sequence in a given buffer containing elements, if a 151 * Multi-Link element or element fragment sequence exists in the given buffer. 152 * The buffer should contain only 802.11 Information elements, and thus should 153 * not contain other information like 802.11 header, 802.11 frame body 154 * components like fields that are not elements (e.g. Capability Information 155 * field, Beacon Interval field), etc. 156 * 157 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 158 * the reason for error in the case of failure 159 */ 160 QDF_STATUS 161 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, 162 qdf_size_t *mlieseqlen); 163 164 /** 165 * util_get_mlie_variant() - Get ML IE variant 166 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 167 * fragment sequence 168 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 169 * fragment sequence 170 * @variant: Pointer to the location where the value of the variant should be 171 * updated. On success, the value should be interpreted by the caller as a 172 * member of enum wlan_ml_variant. (This enum is not directly used as an 173 * argument, so that non-MLO code that happens to call this function does not 174 * need to be aware of the definition of the enum, though such a call would 175 * ultimately result in an error). The value should be ignored by the caller if 176 * the function returns error. 177 * 178 * Get the variant of the given Multi-Link element or element fragment sequence. 179 * 180 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 181 * the reason for error in the case of failure 182 */ 183 QDF_STATUS 184 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen, 185 int *variant); 186 187 /** 188 * util_get_bvmlie_mldmacaddr() - Get the MLD MAC address 189 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 190 * fragment sequence 191 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 192 * fragment sequence 193 * @linkid: Pointer to the location where the MLD MAC address should be updated. 194 * This should be ignored by the caller if the function returns error. 195 * 196 * Get the MLD MAC address from a given Basic variant Multi-Link element 197 * or element fragment sequence. 198 * 199 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 200 * the reason for error in the case of failure 201 */ 202 QDF_STATUS 203 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen, 204 struct qdf_mac_addr *mldmacaddr); 205 206 /** 207 * util_get_bvmlie_eml_cap() - Get the EML capabilities 208 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 209 * fragment sequence 210 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 211 * fragment sequence 212 * @eml_cap_found: Pointer to the location where a boolean status should be 213 * updated indicating whether the EML cabalility was found or not. This should 214 * be ignored by the caller if the function returns error. 215 * @eml_cap: Pointer to the location where the EML capabilities should be 216 * updated. This should be ignored by the caller if the function indicates 217 * that the EML capability was not found. 218 * 219 * Get the EML capabilities from a given Basic variant Multi-Link element or 220 * element fragment sequence. 221 * 222 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 223 * the reason for error in the case of failure 224 */ 225 QDF_STATUS 226 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 227 bool *eml_cap_found, 228 uint16_t *eml_cap); 229 230 /** 231 * util_get_bvmlie_msd_cap() - Get the MSD capabilities for Basic variant 232 * MLO IE 233 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 234 * fragment sequence 235 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 236 * fragment sequence 237 * @msd_cap_found: Pointer to the location where a boolean status should be 238 * updated indicating whether the MSD cabalility was found or not. This should 239 * be ignored by the caller if the function returns error. 240 * @msd_cap: Pointer to the location where the MSD capabilities should be 241 * updated. This should be ignored by the caller if the function indicates 242 * that the MSD capability was not found. 243 * 244 * Get the MSD capabilities from a given Basic variant Multi-Link element or 245 * element fragment sequence. 246 * 247 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 248 * the reason for error in the case of failure 249 */ 250 QDF_STATUS 251 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 252 bool *msd_cap_found, uint16_t *msd_cap); 253 /** 254 * util_get_bvmlie_primary_linkid() - Get the link identifier 255 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 256 * fragment sequence 257 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 258 * fragment sequence 259 * @linkidfound: Pointer to the location where a boolean status should be 260 * updated indicating whether the link identifier was found or not. This should 261 * be ignored by the caller if the function returns error. 262 * @linkid: Pointer to the location where the value of the link identifier 263 * should be updated. This should be ignored by the caller if the function 264 * returns error, or if the function indicates that the link identifier was not 265 * found. 266 * 267 * Get the link identifier from a given Basic variant Multi-Link element or 268 * element fragment sequence, of the AP that transmits the Multi-Link 269 * element/element fragment sequence or the nontransmitted BSSID in the same 270 * multiple BSSID set as the AP that transmits the Multi-Link element/element 271 * fragment sequence and that is affiliated with the MLD that is described in 272 * the Multi-Link element. 273 * 274 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 275 * the reason for error in the case of failure 276 */ 277 QDF_STATUS 278 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 279 bool *linkidfound, uint8_t *linkid); 280 281 /** 282 * util_get_mlie_common_info_len() - Get the MLD common info len 283 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 284 * fragment sequence 285 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 286 * fragment sequence 287 * @commoninfo_len: Pointer to the location where the value of the MLD common 288 * info len should be updated. This should be ignored by the caller if the 289 * function returns error. 290 * 291 * Get the MLD common info len from Multi-Link element transmitted by the AP. 292 * 293 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 294 * the reason for error in the case of failure 295 */ 296 QDF_STATUS 297 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 298 uint8_t *commoninfo_len); 299 300 /** 301 * util_get_bvmlie_bssparamchangecnt() - Get the MLD BSS PARAM Change Count 302 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 303 * fragment sequence 304 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 305 * fragment sequence 306 * @bssparamchangecntfound: Pointer to the location where a boolean status 307 * should be updated indicating whether the MLD BSS PARAM Change Count was 308 * found or not. This should be ignored by the caller if the function 309 * returns error. 310 * @bssparamchangecnt: Pointer to the location where the value of the MLD BSS 311 * PARAM Change Count should be updated. This should be ignored by the caller 312 * if the function returns error, or if the function indicates that the MLD 313 * BSS PARAM Change Count was not found. 314 * 315 * Get the MLD BSS PARAM Change Count from Multi-Link element transmitted 316 * by the AP. 317 * 318 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 319 * the reason for error in the case of failure 320 */ 321 QDF_STATUS 322 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 323 bool *bssparamchangecntfound, 324 uint8_t *bssparamchangecnt); 325 326 /** 327 * util_get_bvmlie_mldcap() - Get the MLD capabilities 328 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 329 * fragment sequence 330 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 331 * fragment sequence 332 * @mldcapfound: Pointer to the location where a boolean status should be 333 * updated indicating whether the MLD capabilities was found or not. This should 334 * be ignored by the caller if the function returns error. 335 * @mldcap: Pointer to the location where the value of the MLD capabilities 336 * should be updated. This should be ignored by the caller if the function 337 * returns error, or if the function indicates that the MLD capabilities was not 338 * found. 339 * 340 * Get the MLD capabilities from a given Basic variant Multi-Link element or 341 * element fragment sequence, of the AP that transmits the Multi-Link 342 * element/element fragment sequence or the nontransmitted BSSID in the same 343 * multiple BSSID set as the AP that transmits the Multi-Link element/element 344 * fragment sequence and that is affiliated with the MLD that is described in 345 * the Multi-Link element. 346 * 347 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 348 * the reason for error in the case of failure 349 */ 350 QDF_STATUS 351 util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 352 bool *mldcapfound, uint16_t *mldcap); 353 354 /** 355 * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information 356 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 357 * fragment sequence 358 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 359 * fragment sequence 360 * @partner_info: Pointer to the location where the partner link information 361 * should be updated. This should be ignored by the caller if the function 362 * returns error. Note that success will be returned and the number of links in 363 * this structure will be reported as 0, if no Link Info is found, or no per-STA 364 * profile is found, or if none of the per-STA profiles includes a MAC address 365 * in the STA Info field (assuming no errors are encountered). 366 * 367 * Get partner link information in the per-STA profiles present in a Basic 368 * variant Multi-Link element. The partner link information is returned only for 369 * those per-STA profiles which have a MAC address in the STA Info field. 370 * 371 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 372 * the reason for error in the case of failure 373 */ 374 QDF_STATUS 375 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 376 qdf_size_t mlieseqlen, 377 struct mlo_partner_info *partner_info); 378 379 /** 380 * util_get_prvmlie_mldid - Get the MLD ID from a given Probe Request 381 * variant Multi-Link element , of the STA that transmits ML Probe Request 382 * with the Multi-Link element 383 * 384 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 385 * fragment sequence 386 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 387 * fragment sequence 388 * @mldidfound: Pointer to the location where a boolean status should be 389 * updated indicating whether the MLD ID was found or not. This should 390 * be ignored by the caller if the function returns error. 391 * @mldid: Pointer to the location where the value of the MLD ID 392 * should be updated. This should be ignored by the caller if the function 393 * returns error, or if the function indicates that the MLD ID was not 394 * found. 395 * 396 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 397 * the reason for error in the case of failure 398 */ 399 QDF_STATUS 400 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 401 bool *mldidfound, uint8_t *mldid); 402 403 /** 404 * util_get_prvmlie_persta_link_id() - Get per-STA probe req link information 405 * 406 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 407 * fragment sequence 408 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 409 * fragment sequence 410 * @probereq_info: Pointer to the location where the probe req link information 411 * should be updated. This should be ignored by the caller if the function 412 * returns error. Note that success will be returned and the number of links in 413 * this structure will be reported as 0, if no Link Info is found, or no per-STA 414 * profile is found. 415 * 416 * Get probe req link information in the per-STA profiles present in a Probe req 417 * variant Multi-Link element. 418 * 419 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 420 * the reason for error in the case of failure 421 */ 422 QDF_STATUS 423 util_get_prvmlie_persta_link_id(uint8_t *mlieseq, 424 qdf_size_t mlieseqlen, 425 struct mlo_probereq_info *probereq_info); 426 427 #else 428 static inline QDF_STATUS 429 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 430 struct qdf_mac_addr link_addr, 431 uint8_t *link_frame, 432 qdf_size_t link_frame_maxsize, 433 qdf_size_t *link_frame_len) 434 { 435 return QDF_STATUS_E_NOSUPPORT; 436 } 437 438 static inline QDF_STATUS 439 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 440 struct qdf_mac_addr link_addr, 441 uint8_t *link_frame, 442 qdf_size_t link_frame_maxsize, 443 qdf_size_t *link_frame_len) 444 { 445 return QDF_STATUS_E_NOSUPPORT; 446 } 447 448 static inline QDF_STATUS 449 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, 450 qdf_size_t *mlieseqlen) 451 { 452 return QDF_STATUS_E_NOSUPPORT; 453 } 454 455 static inline QDF_STATUS 456 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen, 457 int *variant) 458 { 459 return QDF_STATUS_E_NOSUPPORT; 460 } 461 462 static inline QDF_STATUS 463 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 464 uint8_t *commoninfo_len) 465 { 466 return QDF_STATUS_E_NOSUPPORT; 467 } 468 469 static inline QDF_STATUS 470 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 471 bool *bssparamchangecntfound, 472 uint8_t *bssparamchangecnt) 473 { 474 return QDF_STATUS_E_NOSUPPORT; 475 } 476 477 static inline QDF_STATUS 478 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen, 479 struct qdf_mac_addr *mldmacaddr) 480 { 481 return QDF_STATUS_E_NOSUPPORT; 482 } 483 484 static inline QDF_STATUS 485 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 486 bool *eml_cap_found, 487 uint16_t *eml_cap) 488 { 489 return QDF_STATUS_E_NOSUPPORT; 490 } 491 492 static inline QDF_STATUS 493 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 494 bool *msd_cap_found, 495 uint16_t *msd_cap) 496 { 497 return QDF_STATUS_E_NOSUPPORT; 498 } 499 500 static inline QDF_STATUS 501 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 502 bool *linkidfound, uint8_t *linkid) 503 { 504 return QDF_STATUS_E_NOSUPPORT; 505 } 506 507 static inline QDF_STATUS 508 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 509 qdf_size_t mlieseqlen, 510 struct mlo_partner_info *partner_info) 511 { 512 return QDF_STATUS_E_NOSUPPORT; 513 } 514 515 static inline QDF_STATUS 516 util_get_prvmlie_persta_link_id(uint8_t *mlieseq, 517 qdf_size_t mlieseqlen, 518 struct mlo_probereq_info *probereq_info) 519 { 520 return QDF_STATUS_E_NOSUPPORT; 521 } 522 523 static inline QDF_STATUS 524 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 525 bool *mldcapfound, uint8_t *mldcap) 526 { 527 return QDF_STATUS_E_NOSUPPORT; 528 } 529 530 #endif /* WLAN_FEATURE_11BE_MLO */ 531 #endif /* _WLAN_UTILS_MLO_H_ */ 532