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 150 * Multi-Link element fragment sequence in a given buffer containing elements, 151 * if a Multi-Link element or element fragment sequence exists in the given 152 * buffer. 153 * 154 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 155 * the reason for error in the case of failure 156 */ 157 QDF_STATUS 158 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, 159 qdf_size_t *mlieseqlen); 160 161 /** 162 * util_get_mlie_variant() - Get ML IE variant 163 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 164 * fragment sequence 165 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 166 * fragment sequence 167 * @variant: Pointer to the location where the value of the variant should be 168 * updated. On success, the value should be interpreted by the caller as a 169 * member of enum wlan_ml_variant. (This enum is not directly used as an 170 * argument, so that non-MLO code that happens to call this function does not 171 * need to be aware of the definition of the enum, though such a call would 172 * ultimately result in an error). The value should be ignored by the caller if 173 * the function returns error. 174 * 175 * Get the variant of the given Multi-Link element or element fragment sequence. 176 * 177 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 178 * the reason for error in the case of failure 179 */ 180 QDF_STATUS 181 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen, 182 int *variant); 183 184 /** 185 * util_get_bvmlie_mldmacaddr() - Get the MLD MAC address 186 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 187 * fragment sequence 188 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 189 * fragment sequence 190 * @linkid: Pointer to the location where the MLD MAC address should be updated. 191 * This should be ignored by the caller if the function returns error. 192 * 193 * Get the MLD MAC address from a given Basic variant Multi-Link element 194 * or element fragment sequence. 195 * 196 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 197 * the reason for error in the case of failure 198 */ 199 QDF_STATUS 200 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen, 201 struct qdf_mac_addr *mldmacaddr); 202 203 /** 204 * util_get_bvmlie_eml_cap() - Get the EML capabilities 205 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 206 * fragment sequence 207 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 208 * fragment sequence 209 * @eml_cap_found: Pointer to the location where a boolean status should be 210 * updated indicating whether the EML cabalility was found or not. This should 211 * be ignored by the caller if the function returns error. 212 * @eml_cap: Pointer to the location where the EML capabilities should be 213 * updated. This should be ignored by the caller if the function indicates 214 * that the EML capability was not found. 215 * 216 * Get the EML capabilities from a given Basic variant Multi-Link element or 217 * element fragment sequence. 218 * 219 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 220 * the reason for error in the case of failure 221 */ 222 QDF_STATUS 223 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 224 bool *eml_cap_found, 225 uint16_t *eml_cap); 226 227 /** 228 * util_get_bvmlie_msd_cap() - Get the MSD capabilities for Basic variant 229 * MLO IE 230 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 231 * fragment sequence 232 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 233 * fragment sequence 234 * @msd_cap_found: Pointer to the location where a boolean status should be 235 * updated indicating whether the MSD cabalility was found or not. This should 236 * be ignored by the caller if the function returns error. 237 * @msd_cap: Pointer to the location where the MSD capabilities should be 238 * updated. This should be ignored by the caller if the function indicates 239 * that the MSD capability was not found. 240 * 241 * Get the MSD capabilities from a given Basic variant Multi-Link element or 242 * element fragment sequence. 243 * 244 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 245 * the reason for error in the case of failure 246 */ 247 QDF_STATUS 248 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 249 bool *msd_cap_found, uint16_t *msd_cap); 250 /** 251 * util_get_bvmlie_primary_linkid() - Get the link identifier 252 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 253 * fragment sequence 254 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 255 * fragment sequence 256 * @linkidfound: Pointer to the location where a boolean status should be 257 * updated indicating whether the link identifier was found or not. This should 258 * be ignored by the caller if the function returns error. 259 * @linkid: Pointer to the location where the value of the link identifier 260 * should be updated. This should be ignored by the caller if the function 261 * returns error, or if the function indicates that the link identifier was not 262 * found. 263 * 264 * Get the link identifier from a given Basic variant Multi-Link element or 265 * element fragment sequence, of the AP that transmits the Multi-Link 266 * element/element fragment sequence or the nontransmitted BSSID in the same 267 * multiple BSSID set as the AP that transmits the Multi-Link element/element 268 * fragment sequence and that is affiliated with the MLD that is described in 269 * the Multi-Link element. 270 * 271 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 272 * the reason for error in the case of failure 273 */ 274 QDF_STATUS 275 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 276 bool *linkidfound, uint8_t *linkid); 277 278 /** 279 * util_get_mlie_common_info_len() - Get the MLD common info len 280 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 281 * fragment sequence 282 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 283 * fragment sequence 284 * @commoninfo_len: Pointer to the location where the value of the MLD common 285 * info len should be updated. This should be ignored by the caller if the 286 * function returns error. 287 * 288 * Get the MLD common info len from Multi-Link element transmitted by the AP. 289 * 290 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 291 * the reason for error in the case of failure 292 */ 293 QDF_STATUS 294 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 295 uint8_t *commoninfo_len); 296 297 /** 298 * util_get_bvmlie_bssparamchangecnt() - Get the MLD BSS PARAM Change Count 299 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 300 * fragment sequence 301 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 302 * fragment sequence 303 * @bssparamchangecntfound: Pointer to the location where a boolean status 304 * should be updated indicating whether the MLD BSS PARAM Change Count was 305 * found or not. This should be ignored by the caller if the function 306 * returns error. 307 * @bssparamchangecnt: Pointer to the location where the value of the MLD BSS 308 * PARAM Change Count should be updated. This should be ignored by the caller 309 * if the function returns error, or if the function indicates that the MLD 310 * BSS PARAM Change Count was not found. 311 * 312 * Get the MLD BSS PARAM Change Count from Multi-Link element transmitted 313 * by the AP. 314 * 315 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 316 * the reason for error in the case of failure 317 */ 318 QDF_STATUS 319 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 320 bool *bssparamchangecntfound, 321 uint8_t *bssparamchangecnt); 322 323 /** 324 * util_get_bvmlie_mldcap() - Get the MLD capabilities 325 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 326 * fragment sequence 327 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 328 * fragment sequence 329 * @mldcapfound: Pointer to the location where a boolean status should be 330 * updated indicating whether the MLD capabilities was found or not. This should 331 * be ignored by the caller if the function returns error. 332 * @mldcap: Pointer to the location where the value of the MLD capabilities 333 * should be updated. This should be ignored by the caller if the function 334 * returns error, or if the function indicates that the MLD capabilities was not 335 * found. 336 * 337 * Get the MLD capabilities from a given Basic variant Multi-Link element or 338 * element fragment sequence, of the AP that transmits the Multi-Link 339 * element/element fragment sequence or the nontransmitted BSSID in the same 340 * multiple BSSID set as the AP that transmits the Multi-Link element/element 341 * fragment sequence and that is affiliated with the MLD that is described in 342 * the Multi-Link element. 343 * 344 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 345 * the reason for error in the case of failure 346 */ 347 QDF_STATUS 348 util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 349 bool *mldcapfound, uint16_t *mldcap); 350 351 /** 352 * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information 353 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 354 * fragment sequence 355 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 356 * fragment sequence 357 * @partner_info: Pointer to the location where the partner link information 358 * should be updated. This should be ignored by the caller if the function 359 * returns error. Note that success will be returned and the number of links in 360 * this structure will be reported as 0, if no Link Info is found, or no per-STA 361 * profile is found, or if none of the per-STA profiles includes a MAC address 362 * in the STA Info field (assuming no errors are encountered). 363 * 364 * Get partner link information in the per-STA profiles present in a Basic 365 * variant Multi-Link element. The partner link information is returned only for 366 * those per-STA profiles which have a MAC address in the STA Info field. 367 * 368 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 369 * the reason for error in the case of failure 370 */ 371 QDF_STATUS 372 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 373 qdf_size_t mlieseqlen, 374 struct mlo_partner_info *partner_info); 375 376 /** 377 * util_get_prvmlie_mldid - Get the MLD ID from a given Probe Request 378 * variant Multi-Link element , of the STA that transmits ML Probe Request 379 * with the Multi-Link element 380 * 381 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 382 * fragment sequence 383 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 384 * fragment sequence 385 * @mldidfound: Pointer to the location where a boolean status should be 386 * updated indicating whether the MLD ID was found or not. This should 387 * be ignored by the caller if the function returns error. 388 * @mldid: Pointer to the location where the value of the MLD ID 389 * should be updated. This should be ignored by the caller if the function 390 * returns error, or if the function indicates that the MLD ID was not 391 * found. 392 * 393 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 394 * the reason for error in the case of failure 395 */ 396 QDF_STATUS 397 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 398 bool *mldidfound, uint8_t *mldid); 399 400 /** 401 * util_get_prvmlie_persta_link_id() - Get per-STA probe req link information 402 * 403 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 404 * fragment sequence 405 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 406 * fragment sequence 407 * @probereq_info: Pointer to the location where the probe req link information 408 * should be updated. This should be ignored by the caller if the function 409 * returns error. Note that success will be returned and the number of links in 410 * this structure will be reported as 0, if no Link Info is found, or no per-STA 411 * profile is found. 412 * 413 * Get probe req link information in the per-STA profiles present in a Probe req 414 * variant Multi-Link element. 415 * 416 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 417 * the reason for error in the case of failure 418 */ 419 QDF_STATUS 420 util_get_prvmlie_persta_link_id(uint8_t *mlieseq, 421 qdf_size_t mlieseqlen, 422 struct mlo_probereq_info *probereq_info); 423 424 #else 425 static inline QDF_STATUS 426 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 427 struct qdf_mac_addr link_addr, 428 uint8_t *link_frame, 429 qdf_size_t link_frame_maxsize, 430 qdf_size_t *link_frame_len) 431 { 432 return QDF_STATUS_E_NOSUPPORT; 433 } 434 435 static inline QDF_STATUS 436 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 437 struct qdf_mac_addr link_addr, 438 uint8_t *link_frame, 439 qdf_size_t link_frame_maxsize, 440 qdf_size_t *link_frame_len) 441 { 442 return QDF_STATUS_E_NOSUPPORT; 443 } 444 445 static inline QDF_STATUS 446 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, 447 qdf_size_t *mlieseqlen) 448 { 449 return QDF_STATUS_E_NOSUPPORT; 450 } 451 452 static inline QDF_STATUS 453 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen, 454 int *variant) 455 { 456 return QDF_STATUS_E_NOSUPPORT; 457 } 458 459 static inline QDF_STATUS 460 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 461 uint8_t *commoninfo_len) 462 { 463 return QDF_STATUS_E_NOSUPPORT; 464 } 465 466 static inline QDF_STATUS 467 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 468 bool *bssparamchangecntfound, 469 uint8_t *bssparamchangecnt) 470 { 471 return QDF_STATUS_E_NOSUPPORT; 472 } 473 474 static inline QDF_STATUS 475 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen, 476 struct qdf_mac_addr *mldmacaddr) 477 { 478 return QDF_STATUS_E_NOSUPPORT; 479 } 480 481 static inline QDF_STATUS 482 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 483 bool *eml_cap_found, 484 uint16_t *eml_cap) 485 { 486 return QDF_STATUS_E_NOSUPPORT; 487 } 488 489 static inline QDF_STATUS 490 util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 491 bool *msd_cap_found, 492 uint16_t *msd_cap) 493 { 494 return QDF_STATUS_E_NOSUPPORT; 495 } 496 497 static inline QDF_STATUS 498 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 499 bool *linkidfound, uint8_t *linkid) 500 { 501 return QDF_STATUS_E_NOSUPPORT; 502 } 503 504 static inline QDF_STATUS 505 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 506 qdf_size_t mlieseqlen, 507 struct mlo_partner_info *partner_info) 508 { 509 return QDF_STATUS_E_NOSUPPORT; 510 } 511 512 static inline QDF_STATUS 513 util_get_prvmlie_persta_link_id(uint8_t *mlieseq, 514 qdf_size_t mlieseqlen, 515 struct mlo_probereq_info *probereq_info) 516 { 517 return QDF_STATUS_E_NOSUPPORT; 518 } 519 520 static inline QDF_STATUS 521 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 522 bool *mldcapfound, uint8_t *mldcap) 523 { 524 return QDF_STATUS_E_NOSUPPORT; 525 } 526 527 #endif /* WLAN_FEATURE_11BE_MLO */ 528 #endif /* _WLAN_UTILS_MLO_H_ */ 529