1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 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 public file containing STA functionality 20 */ 21 #ifndef _WLAN_MLO_MGR_STA_H_ 22 #define _WLAN_MLO_MGR_STA_H_ 23 24 #include <wlan_cm_ucfg_api.h> 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wlan_mlo_mgr_cmn.h> 27 #ifdef WLAN_FEATURE_11BE_MLO 28 #include <wlan_mlo_mgr_public_structs.h> 29 #include <wlan_mlo_mgr_peer.h> 30 31 /** 32 * mlo_connect - Start the connection process 33 * @vdev: pointer to vdev 34 * @req: connection request 35 * 36 * Return: QDF_STATUS 37 */ 38 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev, 39 struct wlan_cm_connect_req *req); 40 41 /** 42 * mlo_sta_link_connect_notify - Called by connection manager to notify the 43 * STA link connect is complete 44 * @vdev: pointer to vdev 45 * @rsp: MLO connect response 46 * 47 * Connection manager will notify the MLO manager when the link has started 48 * and MLO manager will start the subsequent connections, if necessary 49 * 50 * Return: none 51 */ 52 void 53 mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev, 54 struct wlan_cm_connect_resp *rsp); 55 56 /** 57 * mlo_disconnect - Start the disconnection process 58 * @vdev: pointer to vdev 59 * @source: source of the request (can be connect or disconnect request) 60 * @reason_code: reason for disconnect 61 * @bssid: BSSID 62 * 63 * Return: QDF_STATUS 64 */ 65 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev, 66 enum wlan_cm_source source, 67 enum wlan_reason_code reason_code, 68 struct qdf_mac_addr *bssid); 69 70 /** 71 * mlo_sync_disconnect - Start the sync disconnection process 72 * @vdev: pointer to vdev 73 * @source: source of the request (can be connect or disconnect request) 74 * @reason_code: reason for disconnect 75 * @bssid: BSSID 76 * 77 * Return: QDF_STATUS 78 */ 79 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev, 80 enum wlan_cm_source source, 81 enum wlan_reason_code reason_code, 82 struct qdf_mac_addr *bssid); 83 84 /** 85 * mlo_sta_link_disconn_notify - Notifies that STA link disconnect completion 86 * @vdev: pointer to vdev 87 * @resp: disconnect resp 88 * 89 * Return: none 90 */ 91 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev, 92 struct wlan_cm_discon_rsp *resp); 93 94 /** 95 * mlo_handle_sta_link_connect_failure - Notifies that STA link connect failure 96 * @vdev: pointer to vdev 97 * @rsp: connect resp 98 * 99 * Return: none 100 */ 101 void mlo_handle_sta_link_connect_failure(struct wlan_objmgr_vdev *vdev, 102 struct wlan_cm_connect_resp *rsp); 103 104 /** 105 * mlo_handle_pending_disconnect - Handle pending disconnect if received 106 * while link connect is ongoing. 107 * @vdev: pointer to vdev 108 * 109 * Return: none 110 */ 111 void mlo_handle_pending_disconnect(struct wlan_objmgr_vdev *vdev); 112 113 /** 114 * mlo_is_mld_sta - Check if MLD associated with the vdev is a station 115 * @vdev: pointer to vdev 116 * 117 * Return: true if MLD is a station, false otherwise 118 */ 119 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev); 120 121 /** 122 * ucfg_mlo_is_mld_disconnected - Check whether MLD is disconnected 123 * @vdev: pointer to vdev 124 * 125 * Return: true if mld is disconnected, false otherwise 126 */ 127 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev); 128 129 /** 130 * mlo_is_mld_disconnecting_connecting - Check whether MLD is disconnecting or 131 * connecting 132 * @vdev: pointer to vdev 133 * 134 * Return: true if mld is disconnecting or connecting, false otherwise 135 */ 136 bool mlo_is_mld_disconnecting_connecting(struct wlan_objmgr_vdev *vdev); 137 138 /** 139 * mlo_is_ml_connection_in_progress - Check whether MLD assoc or link vdev is 140 * connecting 141 * 142 * @psoc: pointer to psoc 143 * @vdev_id: vdev id 144 * 145 * Return: true if mld is disconnecting, false otherwise 146 */ 147 bool mlo_is_ml_connection_in_progress(struct wlan_objmgr_psoc *psoc, 148 uint8_t vdev_id); 149 150 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 151 /** 152 * ucfg_mlo_is_mld_connected - Check whether MLD is connected 153 * @vdev: pointer to vdev 154 * 155 * Return: true if mld is connected, false otherwise 156 */ 157 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev); 158 159 /** 160 * ucfg_mlo_mld_clear_mlo_cap - Clear MLO cap for all vdevs in MLD 161 * @vdev: pointer to vdev 162 * 163 * Return: None 164 */ 165 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev); 166 #endif 167 168 #ifdef WLAN_MLO_MULTI_CHIP 169 /** 170 * mlo_get_central_umac_id - get central umac in 3 link topology 171 * @psoc_ids: pointer to psoc_ids 172 * 173 * Return: central umac if success, -1 all soc are adjacent to each other 174 */ 175 176 int8_t mlo_get_central_umac_id(uint8_t *psoc_ids); 177 178 /** 179 * mlo_check_topology() - check topology of the psoc's in STA 180 * @pdev: pdev pointer 181 * @vdev: vdev pointer 182 * @aplinks: Number of active links on ap side 183 * 184 * Return: QDF_STATUS 185 */ 186 187 QDF_STATUS mlo_check_topology(struct wlan_objmgr_pdev *pdev, 188 struct wlan_objmgr_vdev *vdev, 189 uint8_t aplinks); 190 /** 191 * mlo_update_partner_bridge_info() - Update parter info of bridge vap 192 * @ml_dev: ML dev context 193 * @partner_info: partner info that needs to be updated 194 * 195 * Return: none 196 */ 197 198 void mlo_update_partner_bridge_info(struct wlan_mlo_dev_context *ml_dev, 199 struct mlo_partner_info *partner_info); 200 /** 201 * mlo_get_total_links() - get total links supported by device 202 * @pdev: pdev pointer 203 * 204 * Return: Number of total links supported 205 */ 206 207 uint8_t mlo_get_total_links(struct wlan_objmgr_pdev *pdev); 208 209 /** 210 * mlo_is_sta_bridge_vdev() - Check if the vdev is sta bridge vdev 211 * @vdev: vdev pointer 212 * 213 * Return: True if STA bridge vdev else false 214 */ 215 216 bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev); 217 218 /** 219 * mlo_sta_bridge_exists() - Check if bridge vdev exists in a STA MLD 220 * @vdev: vdev pointer 221 * 222 * Return: True if Bridge Vdev exists else false 223 */ 224 bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev); 225 226 /** 227 * mlo_is_force_central_primary() - Check if central vdev is forced 228 * as primary 229 * @vdev: vdev pointer 230 * 231 * Return: True if Central Vdev is force as primary else false 232 */ 233 234 bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev); 235 236 /** 237 * mlo_set_sta_ctx_bss_mld_addr() - Save BSS MLD in sta ctx 238 * @vdev: vdev pointer 239 * @bss_mld_addr: MLD Address of BSS 240 * 241 * Return: none 242 */ 243 244 static inline 245 void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev, 246 struct qdf_mac_addr *bss_mld_addr) 247 { 248 struct wlan_mlo_dev_context *ml_dev = NULL; 249 250 if (!vdev || !vdev->mlo_dev_ctx || !bss_mld_addr) 251 return; 252 253 ml_dev = vdev->mlo_dev_ctx; 254 if (mlo_sta_bridge_exists(vdev) && 255 qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) { 256 if (qdf_is_macaddr_zero(bss_mld_addr)) 257 return; 258 qdf_copy_macaddr(&ml_dev->bridge_sta_ctx->bss_mld_addr, 259 bss_mld_addr); 260 } 261 } 262 263 /** 264 * mlo_get_sta_ctx_bss_mld_addr() - Get BSS MLD from sta ctx 265 * @vdev: vdev pointer 266 * 267 * Return: pointer to qdf_mac_addr 268 */ 269 270 static inline 271 struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev) 272 { 273 struct wlan_mlo_dev_context *ml_dev = NULL; 274 struct qdf_mac_addr *mld_addr; 275 276 if (!vdev || !vdev->mlo_dev_ctx) 277 return NULL; 278 279 ml_dev = vdev->mlo_dev_ctx; 280 if (mlo_sta_bridge_exists(vdev) && 281 !qdf_is_macaddr_zero(&ml_dev->bridge_sta_ctx->bss_mld_addr)) { 282 mld_addr = &ml_dev->bridge_sta_ctx->bss_mld_addr; 283 return mld_addr; 284 } 285 return NULL; 286 } 287 288 /** 289 * mlo_clear_bridge_sta_ctx() - clear bridge_sta_ctx 290 * @vdev: vdev object 291 * 292 * Return: none 293 */ 294 static inline 295 void mlo_clear_bridge_sta_ctx(struct wlan_objmgr_vdev *vdev) 296 { 297 struct wlan_mlo_dev_context *ml_dev = NULL; 298 struct wlan_objmgr_vdev *tmp_vdev = NULL; 299 uint8_t bridge_umac_id = -1; 300 301 if (!vdev || !vdev->mlo_dev_ctx) 302 return; 303 304 ml_dev = vdev->mlo_dev_ctx; 305 if (ml_dev->bridge_sta_ctx) { 306 bridge_umac_id = ml_dev->bridge_sta_ctx->bridge_umac_id; 307 qdf_mem_zero(ml_dev->bridge_sta_ctx, 308 sizeof(struct wlan_mlo_bridge_sta)); 309 } 310 if (mlo_is_force_central_primary(vdev)) { 311 tmp_vdev = mlo_get_link_vdev_from_psoc_id(ml_dev, 312 bridge_umac_id, 313 false); 314 if (!tmp_vdev) { 315 mlo_err("VDEV derivation failed for %u psoc wds bridge", 316 bridge_umac_id); 317 return; 318 } 319 tmp_vdev->vdev_objmgr.mlo_central_vdev = false; 320 wlan_objmgr_vdev_release_ref(tmp_vdev, WLAN_MLO_MGR_ID); 321 } 322 } 323 324 #else 325 static inline 326 void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev, 327 struct qdf_mac_addr *bss_mld_addr) 328 { } 329 330 static inline 331 struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev) 332 { 333 return NULL; 334 } 335 336 static inline 337 bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev) 338 { 339 return false; 340 } 341 342 static inline 343 bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev) 344 { 345 return false; 346 } 347 348 static inline 349 bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev) 350 { 351 return false; 352 } 353 354 static inline 355 void mlo_clear_bridge_sta_ctx(struct wlan_objmgr_vdev *vdev) 356 { } 357 #endif 358 /** 359 * wlan_mlo_get_tdls_link_vdev() - API to get tdls link vdev 360 * @vdev: vdev object 361 * 362 * Return: MLD tdls link vdev 363 */ 364 struct wlan_objmgr_vdev * 365 wlan_mlo_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev); 366 367 /** 368 * ucfg_mlo_get_assoc_link_vdev - API to get assoc link vdev 369 * @vdev: vdev object 370 * 371 * Return: MLD assoc link vdev 372 */ 373 struct wlan_objmgr_vdev * 374 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev); 375 376 /** 377 * wlan_mlo_get_assoc_link_vdev - API to get assoc link vdev 378 * @vdev: vdev object 379 * 380 * Return: MLD assoc link vdev 381 */ 382 struct wlan_objmgr_vdev * 383 wlan_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev); 384 385 /** 386 * mlo_update_connected_links_bmap: update connected links bitmap 387 * @mlo_dev_ctx: mlo dev context ptr 388 * @ml_partner_info: ml parnter info ptr 389 * 390 * Return: none 391 */ 392 void 393 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx, 394 struct mlo_partner_info ml_partner_info); 395 396 /** 397 * mlo_clear_connected_links_bmap() - clear connected links bitmap 398 * @vdev: vdev object 399 * 400 * Return: none 401 */ 402 void mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev); 403 404 /** 405 * mlo_set_cu_bpcc() - set the bpcc per link id 406 * @vdev: vdev object 407 * @vdev_id: the id of vdev 408 * @bpcc: bss parameters change count 409 * 410 * Return: QDF_STATUS 411 */ 412 QDF_STATUS mlo_set_cu_bpcc(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id, 413 uint8_t bpcc); 414 415 /** 416 * mlo_get_cu_bpcc() - get the bpcc per link id 417 * @vdev: vdev object 418 * @vdev_id: the id of vdev 419 * @bpcc: the bss parameters change count pointer to save value 420 * 421 * Return: QDF_STATUS 422 */ 423 QDF_STATUS mlo_get_cu_bpcc(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id, 424 uint8_t *bpcc); 425 426 /** 427 * mlo_init_cu_bpcc() - initialize the bpcc for vdev 428 * @mlo_dev_ctx: wlan mlo dev context 429 * @vdev_id: vdev id 430 * 431 * Return: void 432 */ 433 void mlo_init_cu_bpcc(struct wlan_mlo_dev_context *mlo_dev_ctx, 434 uint8_t vdev_id); 435 436 /** 437 * mlo_clear_cu_bpcc() - clear the bpcc info 438 * @vdev: vdev object 439 * 440 * Return: void 441 */ 442 void mlo_clear_cu_bpcc(struct wlan_objmgr_vdev *vdev); 443 444 /** 445 * typedef mlo_vdev_op_handler() - API to have operation on ml vdevs 446 * @vdev: vdev object 447 * @arg: operation-specific argument 448 */ 449 typedef void (*mlo_vdev_op_handler)(struct wlan_objmgr_vdev *vdev, 450 void *arg); 451 452 /** 453 * mlo_iterate_connected_vdev_list: Iterate on connected ML links 454 * @vdev: vdev object 455 * @handler: the handler will be called for each object in ML list 456 * @arg: argument to be passed to handler 457 * 458 * Return: none 459 */ 460 static inline 461 void mlo_iterate_connected_vdev_list(struct wlan_objmgr_vdev *vdev, 462 mlo_vdev_op_handler handler, 463 void *arg) 464 { 465 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 466 struct wlan_mlo_sta *sta_ctx = NULL; 467 uint8_t i = 0; 468 469 if (!mlo_dev_ctx || !(wlan_vdev_mlme_is_mlo_vdev(vdev))) 470 return; 471 472 sta_ctx = mlo_dev_ctx->sta_ctx; 473 if (!sta_ctx) 474 return; 475 476 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 477 if (!mlo_dev_ctx->wlan_vdev_list[i]) 478 continue; 479 if (qdf_test_bit(i, sta_ctx->wlan_connected_links)) { 480 if (handler) 481 handler(mlo_dev_ctx->wlan_vdev_list[i], arg); 482 } 483 } 484 } 485 486 /** 487 * call_handler_for_standalone_ap: Iterate on all standalone ML vdevs in 488 * ML AP context and call handler only for standalone AP 489 * 490 * @ap_dev_ctx: AP vdev context 491 * @handler: the handler will be called for each object in ML list 492 * @arg: argument to be passed to handler 493 * 494 * Return: none 495 */ 496 static inline void 497 call_handler_for_standalone_ap(struct wlan_mlo_dev_context *ap_dev_ctx, 498 mlo_vdev_op_handler handler, void *arg) 499 { 500 struct wlan_objmgr_vdev *ml_ap_vdev = NULL; 501 int i; 502 503 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 504 /* For each vdev in ML AP context, check if its PDEV has any 505 * STA. If it doesn't, call the handler for that particular 506 * VDEV. 507 */ 508 if (!ap_dev_ctx->wlan_vdev_list[i]) 509 continue; 510 ml_ap_vdev = ap_dev_ctx->wlan_vdev_list[i]; 511 handler(ml_ap_vdev, arg); 512 } 513 } 514 515 /** 516 * mlo_iterate_ml_standalone_vdev_list: Iterate on all standalone ML vdevs in 517 * ML link 518 * 519 * @vdev: vdev object 520 * @handler: the handler will be called for each object in ML list 521 * @arg: argument to be passed to handler 522 * 523 * Return: none 524 */ 525 static inline 526 void mlo_iterate_ml_standalone_vdev_list(struct wlan_objmgr_vdev *vdev, 527 mlo_vdev_op_handler handler, 528 void *arg) 529 { 530 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 531 struct wlan_mlo_sta *sta_ctx = NULL; 532 uint8_t i = 0; 533 struct wlan_objmgr_pdev *pdev = NULL; 534 struct wlan_objmgr_vdev *vdev_temp = NULL; 535 struct wlan_mlo_dev_context *ap_ml_ctx; 536 qdf_list_t *vdev_list; 537 538 if (!mlo_dev_ctx || !(wlan_vdev_mlme_is_mlo_vdev(vdev)) || !handler) 539 return; 540 541 sta_ctx = mlo_dev_ctx->sta_ctx; 542 if (!sta_ctx) 543 return; 544 545 /* If repeater is configured as dependent WDS repeater, 546 * bring up/bring down all the standalone AP vaps in it once all 547 * the other AP vaps present in the AP ML context are up/down. 548 */ 549 550 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 551 if (!mlo_dev_ctx->wlan_vdev_list[i]) 552 continue; 553 554 pdev = wlan_vdev_get_pdev(mlo_dev_ctx->wlan_vdev_list[i]); 555 vdev_list = &pdev->pdev_objmgr.wlan_vdev_list; 556 vdev_temp = wlan_pdev_vdev_list_peek_head(vdev_list); 557 while (vdev_temp) { 558 // Get all VDEVs of the STA vap from its PDEV 559 if ((vdev_temp != vdev) && 560 wlan_vdev_mlme_get_opmode(vdev_temp) == 561 QDF_SAP_MODE) { 562 ap_ml_ctx = vdev_temp->mlo_dev_ctx; 563 if (!ap_ml_ctx) 564 return; 565 566 call_handler_for_standalone_ap(ap_ml_ctx, 567 handler, arg); 568 } 569 570 vdev_temp = wlan_vdev_get_next_vdev_of_pdev( 571 vdev_list, vdev_temp); 572 } 573 } 574 } 575 576 /** 577 * mlo_update_connect_req_links: update connect req links index 578 * @vdev: vdev object 579 * @value: set/clear the bit 580 * 581 * Return: none 582 */ 583 static inline void 584 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 585 { 586 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 587 struct wlan_mlo_sta *sta_ctx = NULL; 588 uint8_t i = 0; 589 590 if (!mlo_dev_ctx) 591 return; 592 593 sta_ctx = mlo_dev_ctx->sta_ctx; 594 if (!sta_ctx) 595 return; 596 597 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 598 if (!mlo_dev_ctx->wlan_vdev_list[i]) 599 continue; 600 601 if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) { 602 if (value) 603 qdf_set_bit(i, sta_ctx->wlan_connect_req_links); 604 else 605 qdf_clear_bit( 606 i, sta_ctx->wlan_connect_req_links); 607 } 608 } 609 } 610 611 /** 612 * mlo_is_vdev_connect_req_link: API to check if vdev is in active connection 613 * @vdev: vdev object 614 * 615 * Return: true is vdev is participating in active connect else false 616 */ 617 static inline bool 618 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev) 619 { 620 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 621 struct wlan_mlo_sta *sta_ctx = NULL; 622 623 if (!mlo_dev_ctx) 624 return false; 625 626 sta_ctx = mlo_dev_ctx->sta_ctx; 627 if (!sta_ctx) 628 return false; 629 630 if (qdf_test_bit( 631 mlo_get_link_vdev_ix(vdev->mlo_dev_ctx, vdev), 632 sta_ctx->wlan_connect_req_links)) 633 return true; 634 635 return false; 636 } 637 638 /** 639 * mlo_clear_connect_req_links_bmap() - clear connect req links bitmap 640 * @vdev: vdev object 641 * 642 * Return: none 643 */ 644 static inline 645 void mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev) 646 { 647 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 648 struct wlan_mlo_sta *sta_ctx = NULL; 649 650 if (!mlo_dev_ctx) 651 return; 652 653 sta_ctx = mlo_dev_ctx->sta_ctx; 654 if (!sta_ctx) 655 return; 656 657 qdf_mem_zero(sta_ctx->wlan_connect_req_links, 658 sizeof(sta_ctx->wlan_connect_req_links)); 659 } 660 661 /** 662 * mlo_update_connected_links: update connected links index 663 * @vdev: vdev object 664 * @value: set/clear the bit 665 * 666 * Return: none 667 */ 668 static inline void 669 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 670 { 671 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 672 struct wlan_mlo_sta *sta_ctx = NULL; 673 uint8_t i = 0; 674 675 if (!mlo_dev_ctx) 676 return; 677 678 sta_ctx = mlo_dev_ctx->sta_ctx; 679 if (!sta_ctx) 680 return; 681 682 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 683 if (!mlo_dev_ctx->wlan_vdev_list[i]) 684 continue; 685 686 if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) { 687 if (value) 688 qdf_set_bit(i, sta_ctx->wlan_connected_links); 689 else 690 qdf_clear_bit(i, sta_ctx->wlan_connected_links); 691 } 692 } 693 } 694 695 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 696 /** 697 * mlo_get_ml_vdev_by_mac: get ml vdev from mac 698 * @vdev: vdev object 699 * @macaddr: mac of vdev to be returned 700 * 701 * Return: vdev object if found else NULL 702 */ 703 struct wlan_objmgr_vdev * 704 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev, 705 struct qdf_mac_addr *macaddr); 706 #endif 707 708 /** 709 * mlo_get_chan_freq_by_bssid - Get channel freq by bssid 710 * @pdev: pdev pointer 711 * @bssid: link mac address 712 * 713 * Return: chan frequency 714 */ 715 qdf_freq_t 716 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev, 717 struct qdf_mac_addr *bssid); 718 719 /** 720 * mlo_get_assoc_rsp - Get Assoc response from mlo manager 721 * @vdev: vdev obj mgr 722 * @assoc_rsp_frame: association response frame ptr 723 * 724 * Return: none 725 */ 726 void mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev, 727 struct element_info *assoc_rsp_frame); 728 729 /** 730 * mlo_sta_save_quiet_status - save quiet status for given link of mlo station 731 * @mlo_dev_ctx: mlo context 732 * @link_id: link id 733 * @quiet_status: True if quiet starts. False if quiet stops. 734 * 735 * Return: QDF_STATUS 736 */ 737 QDF_STATUS mlo_sta_save_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx, 738 uint8_t link_id, 739 bool quiet_status); 740 741 /** 742 * mlo_is_sta_in_quiet_status - is the link of given mlo sta is in quiet status 743 * @mlo_dev_ctx: mlo context 744 * @link_id: link id 745 * 746 * Return: true if the link of given mlo sta is in quiet status 747 */ 748 bool mlo_is_sta_in_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx, 749 uint8_t link_id); 750 751 /** 752 * mlo_is_sta_inactivity_allowed_with_quiet() - Is link OK to force inactivity 753 * based on current quiet status 754 * of mlo connection 755 * @psoc: pointer to psoc 756 * @vdev_id_list: vdev id list 757 * @num_mlo: number of mlo vdev 758 * @mlo_idx: list of index of vdev_id_list if it is vdev id of mlo vdev 759 * @affected_links: number of links to be set inactivity 760 * @affected_list: list of vdev id to be set inactivity 761 * 762 * Return: true if any link not in mlo_vdev_list is not in quiet mode 763 */ 764 bool mlo_is_sta_inactivity_allowed_with_quiet(struct wlan_objmgr_psoc *psoc, 765 uint8_t *vdev_id_list, 766 uint8_t num_mlo, uint8_t *mlo_idx, 767 uint8_t affected_links, 768 uint8_t *affected_list); 769 770 /** 771 * mlo_is_sta_csa_synced - Is mlo sta csa parameters are synced or not 772 * @mlo_dev_ctx: mlo context 773 * @link_id: link id 774 * 775 * Return: true if mlo sta csa parameters of given link id is synced 776 */ 777 bool mlo_is_sta_csa_synced(struct wlan_mlo_dev_context *mlo_dev_ctx, 778 uint8_t link_id); 779 780 /** 781 * mlo_sta_csa_save_params - Save csa parameters for mlo station 782 * @mlo_dev_ctx: mlo context 783 * @link_id: link id 784 * @csa_param: csa parameters to be saved 785 * 786 * Return: QDF_STATUS 787 */ 788 QDF_STATUS mlo_sta_csa_save_params(struct wlan_mlo_dev_context *mlo_dev_ctx, 789 uint8_t link_id, 790 struct csa_offload_params *csa_param); 791 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 792 /** 793 * mlo_sta_handle_csa_standby_link - Handle csa parameters for standby link 794 * @mlo_dev_ctx: mlo context 795 * @link_id: link id 796 * @csa_param: csa parameters to be saved 797 * @vdev: vdev obj mgr 798 * 799 * Return: QDF_STATUS 800 */ 801 QDF_STATUS mlo_sta_handle_csa_standby_link( 802 struct wlan_mlo_dev_context *mlo_dev_ctx, 803 uint8_t link_id, 804 struct csa_offload_params *csa_param, 805 struct wlan_objmgr_vdev *vdev); 806 #else 807 static inline 808 QDF_STATUS mlo_sta_handle_csa_standby_link( 809 struct wlan_mlo_dev_context *mlo_dev_ctx, 810 uint8_t link_id, 811 struct csa_offload_params *csa_param, 812 struct wlan_objmgr_vdev *vdev) 813 { 814 return QDF_STATUS_SUCCESS; 815 } 816 #endif 817 /** 818 * mlo_sta_up_active_notify - mlo sta up active notify 819 * @vdev: vdev obj mgr 820 * 821 * Return: QDF_STATUS 822 */ 823 QDF_STATUS mlo_sta_up_active_notify(struct wlan_objmgr_vdev *vdev); 824 825 /** 826 * mlo_is_sta_csa_param_handled - Is given csa_param handled or not 827 * @vdev: vdev obj mgr 828 * @csa_param: csa parameters to be checked 829 * 830 * Return: true if given csa parameters is handled 831 */ 832 bool mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev, 833 struct csa_offload_params *csa_param); 834 835 /** 836 * mlo_internal_disconnect_links - Internal disconnect for connection manager 837 * @vdev: vdev obj mgr 838 * 839 * Return: none 840 */ 841 void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev); 842 843 /** 844 * mlo_sta_vdev_get_reconfig_timer_state() - Get ml reconfig timer state on 845 * vdev 846 * @vdev: vdev pointer 847 * 848 * Return: true if reconfig timer is active, otherwise false 849 */ 850 bool mlo_sta_vdev_get_reconfig_timer_state(struct wlan_objmgr_vdev *vdev); 851 852 /** 853 * mlo_sta_stop_reconfig_timer_by_vdev() - Stop ml reconfig timer 854 * @vdev: vdev pointer 855 * 856 * Return: None 857 */ 858 void mlo_sta_stop_reconfig_timer_by_vdev(struct wlan_objmgr_vdev *vdev); 859 860 /** 861 * mlo_sta_stop_reconfig_timer() - Stop reconfig timer on all vdev on ml dev 862 * @vdev: vdev pointer 863 * 864 * Return: None 865 */ 866 void mlo_sta_stop_reconfig_timer(struct wlan_objmgr_vdev *vdev); 867 868 /** 869 * mlo_sta_get_vdev_list() - get mlo vdev list 870 * @vdev: vdev pointer 871 * @vdev_count: vdev count 872 * @wlan_vdev_list: vdev list 873 * 874 * Return: None 875 */ 876 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, uint16_t *vdev_count, 877 struct wlan_objmgr_vdev **wlan_vdev_list); 878 879 /** 880 * mlo_process_ml_reconfig_ie() - process ml reconfig ie for vdev 881 * @vdev: vdev pointer 882 * @scan_entry: RootAP scan entry 883 * @ml_ie: Pointer to ML IE 884 * @ml_ie_len: Length of ML IE 885 * @partner_info: Cached partner info 886 * 887 * Return: None 888 */ 889 void mlo_process_ml_reconfig_ie(struct wlan_objmgr_vdev *vdev, 890 struct scan_cache_entry *scan_entry, 891 uint8_t *ml_ie, qdf_size_t ml_ie_len, 892 struct mlo_partner_info *partner_info); 893 894 /** 895 * wlan_mlo_send_vdev_pause() - send MLO vdev pause to FW 896 * @psoc: pointer to psoc 897 * @vdev: vdev pointer 898 * @session_id: session ID 899 * @vdev_pause_dur: vdev pause duration 900 * 901 * Return: None 902 */ 903 void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, 904 struct wlan_objmgr_vdev *vdev, 905 uint16_t session_id, 906 uint16_t vdev_pause_dur); 907 908 /** 909 * mlo_allocate_and_copy_ies() - allocate and copy ies 910 * @target: target connect req pointer 911 * @source: source connect req pointer 912 * 913 * Return: None 914 */ 915 void 916 mlo_allocate_and_copy_ies(struct wlan_cm_connect_req *target, 917 struct wlan_cm_connect_req *source); 918 919 /** 920 * mlo_free_connect_ies() - free connect ies 921 * @connect_req: connect req pointer 922 * 923 * Return: None 924 */ 925 void 926 mlo_free_connect_ies(struct wlan_cm_connect_req *connect_req); 927 928 /** 929 * mlo_get_link_state_context() - get ml link context 930 * @psoc: psoc handler 931 * @resp_cb: api to handle link state callback 932 * @context: response context 933 * @vdev_id: vdev id 934 */ 935 QDF_STATUS 936 mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc, 937 get_ml_link_state_cb *resp_cb, 938 void **context, uint8_t vdev_id); 939 #else 940 static inline 941 void mlo_clear_bridge_sta_ctx(struct wlan_objmgr_vdev *vdev) 942 { } 943 944 static inline 945 void mlo_set_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev, 946 struct qdf_mac_addr *bss_mld_addr) 947 { } 948 949 static inline 950 struct qdf_mac_addr *mlo_get_sta_ctx_bss_mld_addr(struct wlan_objmgr_vdev *vdev) 951 { 952 return NULL; 953 } 954 955 static inline 956 bool mlo_is_sta_bridge_vdev(struct wlan_objmgr_vdev *vdev) 957 { 958 return false; 959 } 960 961 static inline 962 bool mlo_sta_bridge_exists(struct wlan_objmgr_vdev *vdev) 963 { 964 return false; 965 } 966 967 static inline 968 bool mlo_is_force_central_primary(struct wlan_objmgr_vdev *vdev) 969 { 970 return false; 971 } 972 973 static inline 974 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev, 975 struct wlan_cm_connect_req *req) 976 { 977 return wlan_cm_start_connect(vdev, req); 978 } 979 980 static inline 981 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev, 982 struct wlan_cm_connect_resp *rsp) 983 { } 984 985 static inline 986 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev, 987 enum wlan_cm_source source, 988 enum wlan_reason_code reason_code, 989 struct qdf_mac_addr *bssid) 990 { 991 QDF_STATUS status; 992 993 status = wlan_cm_disconnect(vdev, source, 994 reason_code, 995 bssid); 996 return status; 997 } 998 999 static inline 1000 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev, 1001 enum wlan_cm_source source, 1002 enum wlan_reason_code reason_code, 1003 struct qdf_mac_addr *bssid) 1004 { 1005 return wlan_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, 1006 reason_code); 1007 } 1008 1009 static inline 1010 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev, 1011 struct wlan_cm_discon_rsp *resp) 1012 { } 1013 1014 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 1015 static inline 1016 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev) 1017 { 1018 return true; 1019 } 1020 1021 static inline 1022 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev) 1023 { 1024 return true; 1025 } 1026 #endif 1027 1028 static inline 1029 bool mlo_is_mld_disconnecting_connecting(struct wlan_objmgr_vdev *vdev) 1030 { 1031 return false; 1032 } 1033 1034 static inline 1035 bool mlo_is_ml_connection_in_progress(struct wlan_objmgr_psoc *psoc, 1036 uint8_t vdev_id) 1037 { 1038 return false; 1039 } 1040 1041 static inline 1042 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev) 1043 { 1044 return false; 1045 } 1046 1047 static inline 1048 struct wlan_objmgr_vdev * 1049 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev) 1050 { 1051 return vdev; 1052 } 1053 1054 static inline void 1055 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 1056 { } 1057 1058 static inline void 1059 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx, 1060 struct mlo_partner_info ml_parnter_info) 1061 { } 1062 1063 static inline bool 1064 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev) 1065 { 1066 return true; 1067 } 1068 1069 static inline void 1070 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 1071 { } 1072 1073 static inline void 1074 mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev) 1075 { } 1076 1077 static inline void 1078 mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev) 1079 { } 1080 1081 static inline struct wlan_objmgr_vdev * 1082 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev, 1083 struct qdf_mac_addr *macaddr) 1084 { 1085 return vdev; 1086 } 1087 1088 static inline qdf_freq_t 1089 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev, 1090 struct qdf_mac_addr *bssid) 1091 { 1092 return 0; 1093 } 1094 1095 static inline void 1096 mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev, 1097 struct element_info *assoc_rsp_frame) 1098 { 1099 } 1100 1101 static inline bool 1102 mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev, 1103 struct csa_offload_params *csa_param) 1104 { 1105 return false; 1106 } 1107 1108 static inline void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev) 1109 { 1110 } 1111 1112 static inline 1113 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, 1114 uint16_t *vdev_count, 1115 struct wlan_objmgr_vdev **wlan_vdev_list) 1116 { 1117 } 1118 1119 static inline bool 1120 mlo_sta_vdev_get_reconfig_timer_state(struct wlan_objmgr_vdev *vdev) 1121 { 1122 return false; 1123 } 1124 1125 static inline void 1126 mlo_sta_stop_reconfig_timer_by_vdev(struct wlan_objmgr_vdev *vdev) 1127 { 1128 } 1129 1130 static inline void mlo_sta_stop_reconfig_timer(struct wlan_objmgr_vdev *vdev) 1131 { 1132 } 1133 1134 static inline 1135 void mlo_process_ml_reconfig_ie(struct wlan_objmgr_vdev *vdev, 1136 struct scan_cache_entry *scan_entry, 1137 uint8_t *ml_ie, qdf_size_t ml_ie_len, 1138 struct mlo_partner_info *partner_info) 1139 { } 1140 #ifdef WLAN_FEATURE_11BE_MLO 1141 static inline QDF_STATUS 1142 mlo_get_link_state_context(struct wlan_objmgr_psoc *psoc, 1143 get_ml_link_state_cb *resp_cb, 1144 void **context, uint8_t vdev_id) 1145 { 1146 return QDF_STATUS_SUCCESS; 1147 } 1148 #endif 1149 1150 static inline 1151 void wlan_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc, 1152 struct wlan_objmgr_vdev *vdev, 1153 uint16_t session_id, 1154 uint16_t vdev_pause_dur) 1155 {} 1156 #endif 1157 1158 #if defined(WLAN_FEATURE_11BE_MLO_ADV_FEATURE) && defined(WLAN_FEATURE_11BE_MLO) 1159 /** 1160 * mlo_defer_set_keys: Defer MLO set keys for link 1161 * @vdev: vdev obj 1162 * @link_id: link_id 1163 * @value: bool true or false 1164 * Return: none 1165 */ 1166 void mlo_defer_set_keys(struct wlan_objmgr_vdev *vdev, 1167 uint8_t link_id, bool value); 1168 1169 /** 1170 * mlo_is_set_key_defered: Verify whether the set key deferred for the link 1171 * @vdev: vdev obj 1172 * @link_id: link_id 1173 * Return: boolean value true or false 1174 */ 1175 bool mlo_is_set_key_defered(struct wlan_objmgr_vdev *vdev, 1176 uint8_t link_id); 1177 1178 /** 1179 * mlo_is_any_link_disconnecting: Check if any ML link is disconnecting 1180 * @vdev: vdev obj 1181 * 1182 * Check connection manager state machine if any ML link is disconnecting 1183 * 1184 * Return: boolean value true or false 1185 */ 1186 bool mlo_is_any_link_disconnecting(struct wlan_objmgr_vdev *vdev); 1187 1188 /** 1189 * mlo_set_chan_switch_in_progress: Set/clear the flag upon CSA at MLD level 1190 * @vdev: vdev obj 1191 * @val: Carries true if CSA is started on any of the ML links. This carries 1192 * false once CSA is completed. 1193 * 1194 * This API is to set/clear the flag ml_chan_switch_in_progress upon 1195 * CSA start/CSA completion on any of the ML links. 1196 * 1197 * Return: QDF_STATUS 1198 */ 1199 QDF_STATUS 1200 mlo_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, bool val); 1201 1202 /** 1203 * mlo_is_chan_switch_in_progress: Check if ML level CSA flag is set 1204 * @vdev: vdev obj 1205 * 1206 * This API is to check the flag ml_chan_switch_in_progress upon 1207 * CSA start/CSA completion on any of the ML links. 1208 * 1209 * Return: True if flag ml_chan_switch_in_progress is set, false otherwise 1210 */ 1211 bool mlo_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev); 1212 #else 1213 static inline 1214 void mlo_defer_set_keys(struct wlan_objmgr_vdev *vdev, 1215 uint8_t link_id, bool value) 1216 { 1217 } 1218 1219 static inline 1220 bool mlo_is_set_key_defered(struct wlan_objmgr_vdev *vdev, 1221 uint8_t link_id) 1222 { 1223 return false; 1224 } 1225 1226 static inline 1227 bool mlo_is_any_link_disconnecting(struct wlan_objmgr_vdev *vdev) 1228 { 1229 return false; 1230 } 1231 1232 static inline QDF_STATUS 1233 mlo_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev, bool val) 1234 { 1235 return QDF_STATUS_E_NOSUPPORT; 1236 } 1237 1238 static inline bool 1239 mlo_is_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev) 1240 { 1241 return false; 1242 } 1243 #endif 1244 #endif 1245