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_primary_linkid() - Get the link identifier 229 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 230 * fragment sequence 231 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 232 * fragment sequence 233 * @linkidfound: Pointer to the location where a boolean status should be 234 * updated indicating whether the link identifier was found or not. This should 235 * be ignored by the caller if the function returns error. 236 * @linkid: Pointer to the location where the value of the link identifier 237 * should be updated. This should be ignored by the caller if the function 238 * returns error, or if the function indicates that the link identifier was not 239 * found. 240 * 241 * Get the link identifier from a given Basic variant Multi-Link element or 242 * element fragment sequence, of the AP that transmits the Multi-Link 243 * element/element fragment sequence or the nontransmitted BSSID in the same 244 * multiple BSSID set as the AP that transmits the Multi-Link element/element 245 * fragment sequence and that is affiliated with the MLD that is described in 246 * the Multi-Link element. 247 * 248 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 249 * the reason for error in the case of failure 250 */ 251 QDF_STATUS 252 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 253 bool *linkidfound, uint8_t *linkid); 254 255 /** 256 * util_get_mlie_common_info_len() - Get the MLD common info len 257 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 258 * fragment sequence 259 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 260 * fragment sequence 261 * @commoninfo_len: Pointer to the location where the value of the MLD common 262 * info len should be updated. This should be ignored by the caller if the 263 * function returns error. 264 * 265 * Get the MLD common info len from Multi-Link element transmitted by the AP. 266 * 267 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 268 * the reason for error in the case of failure 269 */ 270 QDF_STATUS 271 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 272 uint8_t *commoninfo_len); 273 274 /** 275 * util_get_bvmlie_bssparamchangecnt() - Get the MLD BSS PARAM Change Count 276 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 277 * fragment sequence 278 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 279 * fragment sequence 280 * @bssparamchangecntfound: Pointer to the location where a boolean status 281 * should be updated indicating whether the MLD BSS PARAM Change Count was 282 * found or not. This should be ignored by the caller if the function 283 * returns error. 284 * @bssparamchangecnt: Pointer to the location where the value of the MLD BSS 285 * PARAM Change Count should be updated. This should be ignored by the caller 286 * if the function returns error, or if the function indicates that the MLD 287 * BSS PARAM Change Count was not found. 288 * 289 * Get the MLD BSS PARAM Change Count from Multi-Link element transmitted 290 * by the AP. 291 * 292 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 293 * the reason for error in the case of failure 294 */ 295 QDF_STATUS 296 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 297 bool *bssparamchangecntfound, 298 uint8_t *bssparamchangecnt); 299 300 /** 301 * util_get_bvmlie_mldcap() - Get the MLD capabilities 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 * @mldcapfound: Pointer to the location where a boolean status should be 307 * updated indicating whether the MLD capabilities was found or not. This should 308 * be ignored by the caller if the function returns error. 309 * @mldcap: Pointer to the location where the value of the MLD capabilities 310 * should be updated. This should be ignored by the caller if the function 311 * returns error, or if the function indicates that the MLD capabilities was not 312 * found. 313 * 314 * Get the MLD capabilities from a given Basic variant Multi-Link element or 315 * element fragment sequence, of the AP that transmits the Multi-Link 316 * element/element fragment sequence or the nontransmitted BSSID in the same 317 * multiple BSSID set as the AP that transmits the Multi-Link element/element 318 * fragment sequence and that is affiliated with the MLD that is described in 319 * the Multi-Link element. 320 * 321 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 322 * the reason for error in the case of failure 323 */ 324 QDF_STATUS 325 util_get_bvmlie_mldcap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 326 bool *mldcapfound, uint16_t *mldcap); 327 328 /** 329 * util_get_bvmlie_persta_partner_info() - Get per-STA partner link information 330 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 331 * fragment sequence 332 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 333 * fragment sequence 334 * @partner_info: Pointer to the location where the partner link information 335 * should be updated. This should be ignored by the caller if the function 336 * returns error. Note that success will be returned and the number of links in 337 * this structure will be reported as 0, if no Link Info is found, or no per-STA 338 * profile is found, or if none of the per-STA profiles includes a MAC address 339 * in the STA Info field (assuming no errors are encountered). 340 * 341 * Get partner link information in the per-STA profiles present in a Basic 342 * variant Multi-Link element. The partner link information is returned only for 343 * those per-STA profiles which have a MAC address in the STA Info field. 344 * 345 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 346 * the reason for error in the case of failure 347 */ 348 QDF_STATUS 349 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 350 qdf_size_t mlieseqlen, 351 struct mlo_partner_info *partner_info); 352 353 /** 354 * util_get_prvmlie_mldid - Get the MLD ID from a given Probe Request 355 * variant Multi-Link element , of the STA that transmits ML Probe Request 356 * with the Multi-Link element 357 * 358 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 359 * fragment sequence 360 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 361 * fragment sequence 362 * @mldidfound: Pointer to the location where a boolean status should be 363 * updated indicating whether the MLD ID was found or not. This should 364 * be ignored by the caller if the function returns error. 365 * @mldid: Pointer to the location where the value of the MLD ID 366 * should be updated. This should be ignored by the caller if the function 367 * returns error, or if the function indicates that the MLD ID was not 368 * found. 369 * 370 * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving 371 * the reason for error in the case of failure 372 */ 373 QDF_STATUS 374 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 375 bool *mldidfound, uint8_t *mldid); 376 377 /** 378 * util_get_prvmlie_persta_link_id() - Get per-STA probe req link information 379 * 380 * @mlieseq: Starting address of the Multi-Link element or Multi-Link element 381 * fragment sequence 382 * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element 383 * fragment sequence 384 * @probereq_info: Pointer to the location where the probe req link information 385 * should be updated. This should be ignored by the caller if the function 386 * returns error. Note that success will be returned and the number of links in 387 * this structure will be reported as 0, if no Link Info is found, or no per-STA 388 * profile is found. 389 * 390 * Get probe req link information in the per-STA profiles present in a Probe req 391 * variant Multi-Link element. 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_persta_link_id(uint8_t *mlieseq, 398 qdf_size_t mlieseqlen, 399 struct mlo_probereq_info *probereq_info); 400 401 #else 402 static inline QDF_STATUS 403 util_gen_link_assoc_req(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 404 struct qdf_mac_addr link_addr, 405 uint8_t *link_frame, 406 qdf_size_t link_frame_maxsize, 407 qdf_size_t *link_frame_len) 408 { 409 return QDF_STATUS_E_NOSUPPORT; 410 } 411 412 static inline QDF_STATUS 413 util_gen_link_assoc_rsp(uint8_t *frame, qdf_size_t frame_len, bool isreassoc, 414 struct qdf_mac_addr link_addr, 415 uint8_t *link_frame, 416 qdf_size_t link_frame_maxsize, 417 qdf_size_t *link_frame_len) 418 { 419 return QDF_STATUS_E_NOSUPPORT; 420 } 421 422 static inline QDF_STATUS 423 util_find_mlie(uint8_t *buf, qdf_size_t buflen, uint8_t **mlieseq, 424 qdf_size_t *mlieseqlen) 425 { 426 return QDF_STATUS_E_NOSUPPORT; 427 } 428 429 static inline QDF_STATUS 430 util_get_mlie_variant(uint8_t *mlieseq, qdf_size_t mlieseqlen, 431 int *variant) 432 { 433 return QDF_STATUS_E_NOSUPPORT; 434 } 435 436 static inline QDF_STATUS 437 util_get_mlie_common_info_len(uint8_t *mlieseq, qdf_size_t mlieseqlen, 438 uint8_t *commoninfo_len) 439 { 440 return QDF_STATUS_E_NOSUPPORT; 441 } 442 443 static inline QDF_STATUS 444 util_get_bvmlie_bssparamchangecnt(uint8_t *mlieseq, qdf_size_t mlieseqlen, 445 bool *bssparamchangecntfound, 446 uint8_t *bssparamchangecnt) 447 { 448 return QDF_STATUS_E_NOSUPPORT; 449 } 450 451 static inline QDF_STATUS 452 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen, 453 struct qdf_mac_addr *mldmacaddr) 454 { 455 return QDF_STATUS_E_NOSUPPORT; 456 } 457 458 static inline QDF_STATUS 459 util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen, 460 bool *eml_cap_found, 461 uint16_t *eml_cap) 462 { 463 return QDF_STATUS_E_NOSUPPORT; 464 } 465 466 static inline QDF_STATUS 467 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 468 bool *linkidfound, uint8_t *linkid) 469 { 470 return QDF_STATUS_E_NOSUPPORT; 471 } 472 473 static inline QDF_STATUS 474 util_get_bvmlie_persta_partner_info(uint8_t *mlieseq, 475 qdf_size_t mlieseqlen, 476 struct mlo_partner_info *partner_info) 477 { 478 return QDF_STATUS_E_NOSUPPORT; 479 } 480 481 static inline QDF_STATUS 482 util_get_prvmlie_persta_link_id(uint8_t *mlieseq, 483 qdf_size_t mlieseqlen, 484 struct mlo_probereq_info *probereq_info) 485 { 486 return QDF_STATUS_E_NOSUPPORT; 487 } 488 489 static inline QDF_STATUS 490 util_get_prvmlie_mldid(uint8_t *mlieseq, qdf_size_t mlieseqlen, 491 bool *mldcapfound, uint8_t *mldcap) 492 { 493 return QDF_STATUS_E_NOSUPPORT; 494 } 495 496 #endif /* WLAN_FEATURE_11BE_MLO */ 497 #endif /* _WLAN_UTILS_MLO_H_ */ 498