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 #include "wlan_mlo_mgr_main.h" 19 #include "qdf_module.h" 20 #include "qdf_types.h" 21 #include "wlan_cmn.h" 22 #include "wlan_mlo_mgr_msgq.h" 23 #include "wlan_objmgr_peer_obj.h" 24 #include "wlan_mlo_mgr_peer.h" 25 #include "wlan_mlo_mgr_ap.h" 26 #include "wlan_crypto_global_api.h" 27 #include "wlan_mlo_mgr_setup.h" 28 #include "wlan_utility.h" 29 #include "wlan_mlo_epcs.h" 30 31 static void mlo_partner_peer_create_post(struct wlan_mlo_dev_context *ml_dev, 32 struct wlan_objmgr_vdev *vdev_link, 33 struct wlan_mlo_peer_context *ml_peer, 34 qdf_nbuf_t frm_buf, 35 struct mlo_partner_info *ml_info) 36 { 37 struct peer_create_notif_s peer_create; 38 QDF_STATUS status; 39 uint8_t i; 40 uint8_t link_id; 41 42 if (wlan_objmgr_vdev_try_get_ref(vdev_link, WLAN_MLO_MGR_ID) == 43 QDF_STATUS_SUCCESS) { 44 peer_create.vdev_link = vdev_link; 45 } else { 46 mlo_err("VDEV is not in created state"); 47 return; 48 } 49 50 wlan_mlo_peer_get_ref(ml_peer); 51 peer_create.ml_peer = ml_peer; 52 link_id = wlan_vdev_get_link_id(vdev_link); 53 for (i = 0; i < ml_info->num_partner_links; i++) { 54 if (link_id != ml_info->partner_link_info[i].link_id) 55 continue; 56 57 qdf_copy_macaddr(&peer_create.addr, 58 &ml_info->partner_link_info[i].link_addr); 59 break; 60 } 61 62 status = mlo_peer_create_get_frm_buf(ml_peer, &peer_create, frm_buf); 63 64 if (QDF_IS_STATUS_ERROR(status)) { 65 wlan_mlo_peer_release_ref(ml_peer); 66 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 67 mlo_err("nbuf clone is failed"); 68 return; 69 } 70 71 status = mlo_msgq_post(MLO_PEER_CREATE, ml_dev, &peer_create); 72 if (status != QDF_STATUS_SUCCESS) { 73 qdf_nbuf_free(frm_buf); 74 wlan_mlo_peer_release_ref(ml_peer); 75 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 76 } 77 } 78 79 static void mlo_partner_peer_reassoc_post(struct wlan_mlo_dev_context *ml_dev, 80 struct wlan_objmgr_vdev *vdev_link, 81 struct wlan_mlo_peer_context *ml_peer, 82 qdf_nbuf_t frm_buf, 83 struct mlo_partner_info *ml_info) 84 { 85 struct peer_create_notif_s peer_create; 86 QDF_STATUS status; 87 uint8_t i; 88 uint8_t link_id; 89 90 if (wlan_objmgr_vdev_try_get_ref(vdev_link, WLAN_MLO_MGR_ID) == 91 QDF_STATUS_SUCCESS) { 92 peer_create.vdev_link = vdev_link; 93 } else { 94 mlo_err("VDEV is not in created state"); 95 return; 96 } 97 98 wlan_mlo_peer_get_ref(ml_peer); 99 peer_create.ml_peer = ml_peer; 100 link_id = wlan_vdev_get_link_id(vdev_link); 101 for (i = 0; i < ml_info->num_partner_links; i++) { 102 if (link_id != ml_info->partner_link_info[i].link_id) 103 continue; 104 105 qdf_copy_macaddr(&peer_create.addr, 106 &ml_info->partner_link_info[i].link_addr); 107 break; 108 } 109 110 status = mlo_peer_create_get_frm_buf(ml_peer, &peer_create, frm_buf); 111 112 if (QDF_IS_STATUS_ERROR(status)) { 113 wlan_mlo_peer_release_ref(ml_peer); 114 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 115 mlo_err("nbuf clone is failed"); 116 return; 117 } 118 119 status = mlo_msgq_post(MLO_PEER_REASSOC, ml_dev, &peer_create); 120 if (status != QDF_STATUS_SUCCESS) { 121 qdf_nbuf_free(frm_buf); 122 wlan_mlo_peer_release_ref(ml_peer); 123 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 124 } 125 } 126 127 static void mlo_link_peer_assoc_notify(struct wlan_mlo_dev_context *ml_dev, 128 struct wlan_objmgr_peer *peer) 129 { 130 struct peer_assoc_notify_s peer_assoc; 131 QDF_STATUS status; 132 133 peer_assoc.peer = peer; 134 status = mlo_msgq_post(MLO_PEER_ASSOC, ml_dev, &peer_assoc); 135 if (status != QDF_STATUS_SUCCESS) 136 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 137 } 138 139 static void mlo_link_peer_send_assoc_fail(struct wlan_mlo_dev_context *ml_dev, 140 struct wlan_objmgr_peer *peer) 141 { 142 struct peer_assoc_fail_notify_s peer_assoc_fail; 143 QDF_STATUS status; 144 145 peer_assoc_fail.peer = peer; 146 status = mlo_msgq_post(MLO_PEER_ASSOC_FAIL, ml_dev, &peer_assoc_fail); 147 if (status != QDF_STATUS_SUCCESS) 148 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 149 } 150 151 static void mlo_link_peer_disconnect_notify(struct wlan_mlo_dev_context *ml_dev, 152 struct wlan_objmgr_peer *peer) 153 { 154 struct peer_discon_notify_s peer_disconn; 155 QDF_STATUS status; 156 struct wlan_objmgr_vdev *vdev; 157 enum QDF_OPMODE opmode; 158 159 vdev = wlan_peer_get_vdev(peer); 160 opmode = wlan_vdev_mlme_get_opmode(vdev); 161 162 if (opmode == QDF_SAP_MODE) { 163 peer_disconn.peer = peer; 164 status = mlo_msgq_post(MLO_PEER_DISCONNECT, ml_dev, 165 &peer_disconn); 166 if (status != QDF_STATUS_SUCCESS) 167 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 168 } else { 169 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 170 } 171 } 172 173 static void mlo_link_peer_deauth_init(struct wlan_mlo_dev_context *ml_dev, 174 struct wlan_objmgr_peer *peer, 175 uint8_t is_disassoc) 176 { 177 struct peer_deauth_notify_s peer_deauth; 178 QDF_STATUS status; 179 180 peer_deauth.peer = peer; 181 peer_deauth.is_disassoc = is_disassoc; 182 status = mlo_msgq_post(MLO_PEER_DEAUTH, ml_dev, &peer_deauth); 183 if (status != QDF_STATUS_SUCCESS) 184 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 185 } 186 187 #ifdef UMAC_MLO_AUTH_DEFER 188 static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev, 189 struct wlan_mlo_peer_context *ml_peer) 190 { 191 struct peer_auth_process_notif_s peer_auth; 192 struct mlpeer_auth_params *recv_auth; 193 uint8_t i; 194 QDF_STATUS status; 195 196 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 197 mlo_peer_lock_acquire(ml_peer); 198 recv_auth = ml_peer->pending_auth[i]; 199 if (!recv_auth) { 200 mlo_peer_lock_release(ml_peer); 201 continue; 202 } 203 peer_auth.auth_params = recv_auth; 204 ml_peer->pending_auth[i] = NULL; 205 206 mlo_peer_lock_release(ml_peer); 207 208 status = mlo_msgq_post(MLO_PEER_PENDING_AUTH, ml_dev, 209 &peer_auth); 210 if (QDF_IS_STATUS_ERROR(status)) 211 mlo_peer_free_auth_param(peer_auth.auth_params); 212 } 213 } 214 #else 215 static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev, 216 struct wlan_mlo_peer_context *ml_peer) 217 { 218 } 219 #endif 220 221 QDF_STATUS 222 wlan_mlo_peer_is_disconnect_progress(struct wlan_mlo_peer_context *ml_peer) 223 { 224 QDF_STATUS status; 225 226 if (!ml_peer) 227 return QDF_STATUS_E_FAILURE; 228 229 mlo_peer_lock_acquire(ml_peer); 230 231 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) 232 status = QDF_STATUS_SUCCESS; 233 else 234 status = QDF_STATUS_E_FAILURE; 235 236 mlo_peer_lock_release(ml_peer); 237 238 return status; 239 } 240 241 QDF_STATUS wlan_mlo_peer_is_assoc_done(struct wlan_mlo_peer_context *ml_peer) 242 { 243 QDF_STATUS status; 244 245 if (!ml_peer) 246 return QDF_STATUS_E_FAILURE; 247 248 mlo_peer_lock_acquire(ml_peer); 249 250 if (ml_peer->mlpeer_state == ML_PEER_ASSOC_DONE) 251 status = QDF_STATUS_SUCCESS; 252 else 253 status = QDF_STATUS_E_FAILURE; 254 255 mlo_peer_lock_release(ml_peer); 256 257 return status; 258 } 259 260 qdf_export_symbol(wlan_mlo_peer_is_assoc_done); 261 262 struct wlan_objmgr_peer *wlan_mlo_peer_get_assoc_peer( 263 struct wlan_mlo_peer_context *ml_peer) 264 { 265 struct wlan_mlo_link_peer_entry *peer_entry; 266 struct wlan_objmgr_peer *assoc_peer = NULL; 267 268 if (!ml_peer) 269 return NULL; 270 271 mlo_peer_lock_acquire(ml_peer); 272 273 peer_entry = &ml_peer->peer_list[0]; 274 275 if (peer_entry->link_peer) 276 assoc_peer = peer_entry->link_peer; 277 278 mlo_peer_lock_release(ml_peer); 279 280 return assoc_peer; 281 } 282 283 qdf_export_symbol(wlan_mlo_peer_get_assoc_peer); 284 285 struct wlan_objmgr_peer *wlan_mlo_peer_get_bridge_peer( 286 struct wlan_mlo_peer_context *ml_peer) 287 { 288 struct wlan_mlo_link_peer_entry *peer_entry = NULL; 289 struct wlan_objmgr_peer *bridge_peer = NULL; 290 struct wlan_objmgr_peer *link_peer = NULL; 291 int i = 0; 292 293 if (!ml_peer) 294 return NULL; 295 296 mlo_peer_lock_acquire(ml_peer); 297 298 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 299 peer_entry = &ml_peer->peer_list[i]; 300 if (!peer_entry) 301 continue; 302 303 link_peer = peer_entry->link_peer; 304 if (!link_peer) 305 continue; 306 307 if (wlan_peer_get_peer_type(link_peer) == 308 WLAN_PEER_MLO_BRIDGE) { 309 if (peer_entry->is_primary) 310 bridge_peer = link_peer; 311 else 312 mlo_err("Bridge peer is not primary"); 313 314 break; 315 } 316 } 317 mlo_peer_lock_release(ml_peer); 318 319 return bridge_peer; 320 } 321 322 qdf_export_symbol(wlan_mlo_peer_get_bridge_peer); 323 324 struct wlan_objmgr_vdev * 325 wlan_mlo_peer_get_primary_link_vdev(struct wlan_mlo_peer_context *ml_peer) 326 { 327 struct wlan_mlo_link_peer_entry *peer_entry = NULL; 328 struct wlan_objmgr_peer *link_peer; 329 struct wlan_objmgr_vdev *link_vdev; 330 uint8_t i; 331 332 if (!ml_peer) { 333 mlo_err("ml_peer is null"); 334 return NULL; 335 } 336 mlo_peer_lock_acquire(ml_peer); 337 338 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 339 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 340 mlo_peer_lock_release(ml_peer); 341 mlo_err("ml_peer is not created and association is not done"); 342 return NULL; 343 } 344 345 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 346 peer_entry = &ml_peer->peer_list[i]; 347 link_peer = peer_entry->link_peer; 348 if (!link_peer) 349 continue; 350 351 if (peer_entry->is_primary) { 352 link_vdev = wlan_peer_get_vdev(link_peer); 353 if (!link_vdev) { 354 mlo_peer_lock_release(ml_peer); 355 mlo_err("link vdev not found"); 356 return NULL; 357 } 358 if (wlan_objmgr_vdev_try_get_ref(link_vdev, WLAN_MLO_MGR_ID) != 359 QDF_STATUS_SUCCESS) { 360 mlo_peer_lock_release(ml_peer); 361 mlo_err("taking ref failed"); 362 return NULL; 363 } 364 mlo_peer_lock_release(ml_peer); 365 return link_vdev; 366 } 367 } 368 mlo_peer_lock_release(ml_peer); 369 mlo_err("None of the peer is designated as primary"); 370 371 return NULL; 372 } 373 374 bool mlo_peer_is_assoc_peer(struct wlan_mlo_peer_context *ml_peer, 375 struct wlan_objmgr_peer *peer) 376 { 377 struct wlan_mlo_link_peer_entry *peer_entry; 378 bool is_assoc_peer = false; 379 380 if (!ml_peer || !peer) 381 return is_assoc_peer; 382 383 peer_entry = &ml_peer->peer_list[0]; 384 385 if (peer_entry->link_peer == peer) 386 is_assoc_peer = true; 387 388 return is_assoc_peer; 389 } 390 391 bool wlan_mlo_peer_is_assoc_peer(struct wlan_mlo_peer_context *ml_peer, 392 struct wlan_objmgr_peer *peer) 393 { 394 bool is_assoc_peer = false; 395 396 if (!ml_peer || !peer) 397 return is_assoc_peer; 398 399 mlo_peer_lock_acquire(ml_peer); 400 401 is_assoc_peer = mlo_peer_is_assoc_peer(ml_peer, peer); 402 403 mlo_peer_lock_release(ml_peer); 404 405 return is_assoc_peer; 406 } 407 408 bool wlan_mlo_peer_is_link_peer(struct wlan_mlo_peer_context *ml_peer, 409 struct wlan_objmgr_peer *peer) 410 { 411 struct wlan_mlo_link_peer_entry *peer_entry; 412 bool is_link_peer = false; 413 uint16_t i; 414 415 if (!ml_peer || !peer) 416 return is_link_peer; 417 418 mlo_peer_lock_acquire(ml_peer); 419 420 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 421 peer_entry = &ml_peer->peer_list[i]; 422 if (!peer_entry->link_peer) 423 continue; 424 425 if (peer == peer_entry->link_peer) { 426 is_link_peer = true; 427 break; 428 } 429 } 430 431 mlo_peer_lock_release(ml_peer); 432 433 return is_link_peer; 434 } 435 436 void wlan_mlo_partner_peer_assoc_post(struct wlan_objmgr_peer *assoc_peer) 437 { 438 struct wlan_mlo_dev_context *ml_dev; 439 struct wlan_mlo_peer_context *ml_peer; 440 struct wlan_objmgr_peer *link_peer; 441 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 442 struct wlan_mlo_link_peer_entry *peer_entry; 443 uint16_t i; 444 445 ml_peer = assoc_peer->mlo_peer_ctx; 446 if (!ml_peer) 447 return; 448 449 mlo_peer_lock_acquire(ml_peer); 450 451 if (ml_peer->mlpeer_state != ML_PEER_CREATED) { 452 mlo_peer_lock_release(ml_peer); 453 return; 454 } 455 456 ml_peer->mlpeer_state = ML_PEER_ASSOC_DONE; 457 ml_dev = ml_peer->ml_dev; 458 459 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 460 link_peers[i] = NULL; 461 peer_entry = &ml_peer->peer_list[i]; 462 463 if (!peer_entry->link_peer) 464 continue; 465 466 if (peer_entry->link_peer == assoc_peer) 467 continue; 468 469 link_peer = peer_entry->link_peer; 470 471 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 472 QDF_STATUS_SUCCESS) 473 continue; 474 475 link_peers[i] = link_peer; 476 } 477 wlan_mlo_peer_wsi_link_add(ml_peer); 478 mlo_peer_lock_release(ml_peer); 479 480 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 481 if (!link_peers[i]) 482 continue; 483 484 /* Prepare and queue message */ 485 mlo_link_peer_assoc_notify(ml_dev, link_peers[i]); 486 } 487 } 488 489 void wlan_mlo_link_peer_assoc_set(struct wlan_objmgr_peer *peer, bool is_sent) 490 { 491 struct wlan_mlo_peer_context *ml_peer; 492 struct wlan_mlo_link_peer_entry *peer_entry; 493 uint16_t i; 494 495 ml_peer = peer->mlo_peer_ctx; 496 if (!ml_peer) 497 return; 498 499 mlo_peer_lock_acquire(ml_peer); 500 501 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 502 peer_entry = &ml_peer->peer_list[i]; 503 504 if (!peer_entry->link_peer) 505 continue; 506 507 if (peer_entry->link_peer == peer) { 508 peer_entry->peer_assoc_sent = is_sent; 509 break; 510 } 511 } 512 mlo_peer_lock_release(ml_peer); 513 } 514 515 qdf_export_symbol(wlan_mlo_link_peer_assoc_set); 516 517 void wlan_mlo_peer_get_del_hw_bitmap(struct wlan_objmgr_peer *peer, 518 uint32_t *hw_link_id_bitmap) 519 { 520 struct wlan_mlo_peer_context *ml_peer; 521 struct wlan_mlo_link_peer_entry *peer_entry; 522 uint16_t i; 523 524 ml_peer = peer->mlo_peer_ctx; 525 if (!ml_peer) 526 return; 527 528 mlo_peer_lock_acquire(ml_peer); 529 530 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 531 peer_entry = &ml_peer->peer_list[i]; 532 533 if (!peer_entry->link_peer) 534 continue; 535 536 if (peer_entry->link_peer == peer) { 537 /* Peer assoc is not sent, no need to send bitmap */ 538 if (!peer_entry->peer_assoc_sent) 539 break; 540 541 continue; 542 } 543 if (!peer_entry->peer_assoc_sent) 544 *hw_link_id_bitmap |= 1 << peer_entry->hw_link_id; 545 } 546 mlo_peer_lock_release(ml_peer); 547 } 548 549 qdf_export_symbol(wlan_mlo_peer_get_del_hw_bitmap); 550 551 void 552 wlan_mlo_peer_deauth_init(struct wlan_mlo_peer_context *ml_peer, 553 struct wlan_objmgr_peer *src_peer, 554 uint8_t is_disassoc) 555 { 556 struct wlan_mlo_dev_context *ml_dev; 557 struct wlan_objmgr_peer *link_peer; 558 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 559 struct wlan_mlo_link_peer_entry *peer_entry; 560 uint16_t i; 561 uint8_t deauth_sent = 0; 562 563 if (!ml_peer) 564 return; 565 566 mlo_peer_lock_acquire(ml_peer); 567 568 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 569 mlo_peer_lock_release(ml_peer); 570 return; 571 } 572 573 ml_dev = ml_peer->ml_dev; 574 575 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 576 link_peers[i] = NULL; 577 peer_entry = &ml_peer->peer_list[i]; 578 if (!peer_entry->link_peer) 579 continue; 580 581 link_peer = peer_entry->link_peer; 582 583 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 584 QDF_STATUS_SUCCESS) 585 continue; 586 587 link_peers[i] = link_peer; 588 } 589 590 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 591 592 mlo_peer_lock_release(ml_peer); 593 594 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 595 if (!link_peers[i]) 596 continue; 597 598 /* Prepare and queue message */ 599 /* skip sending deauth on src peer */ 600 if ((deauth_sent) || 601 (src_peer && (src_peer == link_peers[i]))) { 602 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 603 } else { 604 mlo_link_peer_deauth_init(ml_dev, link_peers[i], 605 is_disassoc); 606 deauth_sent = 1; 607 } 608 } 609 } 610 611 qdf_export_symbol(wlan_mlo_peer_deauth_init); 612 613 void wlan_mlo_peer_delete(struct wlan_mlo_peer_context *ml_peer) 614 { 615 struct wlan_mlo_dev_context *ml_dev; 616 struct wlan_objmgr_peer *link_peer; 617 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 618 struct wlan_mlo_link_peer_entry *peer_entry; 619 uint16_t i; 620 621 if (!ml_peer) 622 return; 623 624 mlo_peer_lock_acquire(ml_peer); 625 626 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 627 mlo_peer_lock_release(ml_peer); 628 return; 629 } 630 631 ml_dev = ml_peer->ml_dev; 632 633 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 634 link_peers[i] = NULL; 635 peer_entry = &ml_peer->peer_list[i]; 636 if (!peer_entry->link_peer) 637 continue; 638 639 link_peer = peer_entry->link_peer; 640 641 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 642 QDF_STATUS_SUCCESS) 643 continue; 644 645 link_peers[i] = link_peer; 646 } 647 648 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 649 650 mlo_peer_lock_release(ml_peer); 651 652 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 653 if (!link_peers[i]) 654 continue; 655 656 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 657 } 658 } 659 660 void 661 wlan_mlo_partner_peer_create_failed_notify( 662 struct wlan_mlo_peer_context *ml_peer) 663 { 664 struct wlan_mlo_dev_context *ml_dev; 665 struct wlan_objmgr_peer *link_peer; 666 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 667 struct wlan_mlo_link_peer_entry *peer_entry; 668 uint16_t i; 669 670 if (!ml_peer) 671 return; 672 673 mlo_peer_lock_acquire(ml_peer); 674 675 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 676 mlo_peer_lock_release(ml_peer); 677 return; 678 } 679 680 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 681 ml_dev = ml_peer->ml_dev; 682 683 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 684 link_peers[i] = NULL; 685 peer_entry = &ml_peer->peer_list[i]; 686 if (!peer_entry->link_peer) 687 continue; 688 689 link_peer = peer_entry->link_peer; 690 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 691 QDF_STATUS_SUCCESS) 692 continue; 693 694 link_peers[i] = link_peer; 695 } 696 mlo_peer_lock_release(ml_peer); 697 698 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 699 if (!link_peers[i]) 700 continue; 701 702 /* Prepare and queue message */ 703 if (i == 0) 704 mlo_link_peer_send_assoc_fail(ml_dev, link_peers[i]); 705 else 706 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 707 } 708 } 709 710 void wlan_mlo_partner_peer_disconnect_notify(struct wlan_objmgr_peer *src_peer) 711 { 712 struct wlan_mlo_dev_context *ml_dev; 713 struct wlan_mlo_peer_context *ml_peer; 714 struct wlan_objmgr_peer *link_peer; 715 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 716 struct wlan_mlo_link_peer_entry *peer_entry; 717 struct wlan_objmgr_vdev *vdev = NULL; 718 uint16_t i; 719 720 ml_peer = src_peer->mlo_peer_ctx; 721 if (!ml_peer) 722 return; 723 724 vdev = wlan_peer_get_vdev(src_peer); 725 if (!vdev) 726 return; 727 728 /* Do not change peer state to disconnect initiated for 729 * link switch case, this can lead to not sending deauth frame 730 * incase of actual disconnect and AP might drop the next connect 731 * request as it might think STA is still in connected state. 732 */ 733 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) 734 return; 735 736 mlo_peer_lock_acquire(ml_peer); 737 738 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 739 mlo_peer_lock_release(ml_peer); 740 return; 741 } 742 743 wlan_mlo_peer_wsi_link_delete(ml_peer); 744 745 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 746 747 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) { 748 mlo_peer_lock_release(ml_peer); 749 return; 750 } 751 752 ml_dev = ml_peer->ml_dev; 753 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 754 link_peers[i] = NULL; 755 peer_entry = &ml_peer->peer_list[i]; 756 if (!peer_entry->link_peer) { 757 mlo_debug("link peer is null"); 758 continue; 759 } 760 761 if (peer_entry->link_peer == src_peer) 762 continue; 763 764 link_peer = peer_entry->link_peer; 765 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 766 QDF_STATUS_SUCCESS) 767 continue; 768 769 link_peers[i] = link_peer; 770 } 771 mlo_peer_lock_release(ml_peer); 772 773 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 774 if (!link_peers[i]) 775 continue; 776 777 /* Prepare and queue message */ 778 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 779 } 780 } 781 782 qdf_export_symbol(wlan_mlo_partner_peer_disconnect_notify); 783 784 static void mlo_peer_populate_link_peer( 785 struct wlan_mlo_peer_context *ml_peer, 786 struct wlan_objmgr_peer *link_peer) 787 { 788 mlo_peer_lock_acquire(ml_peer); 789 wlan_mlo_peer_get_ref(ml_peer); 790 link_peer->mlo_peer_ctx = ml_peer; 791 mlo_peer_lock_release(ml_peer); 792 } 793 794 static void mlo_reset_link_peer( 795 struct wlan_mlo_peer_context *ml_peer, 796 struct wlan_objmgr_peer *link_peer) 797 { 798 mlo_peer_lock_acquire(ml_peer); 799 link_peer->mlo_peer_ctx = NULL; 800 wlan_peer_clear_mlo(link_peer); 801 mlo_peer_lock_release(ml_peer); 802 } 803 804 static void mlo_peer_free(struct wlan_mlo_peer_context *ml_peer) 805 { 806 struct wlan_mlo_dev_context *ml_dev; 807 808 ml_dev = ml_peer->ml_dev; 809 if (!ml_dev) { 810 mlo_err("ML DEV is NULL"); 811 return; 812 } 813 814 mlo_debug("ML Peer " QDF_MAC_ADDR_FMT " is freed", 815 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 816 mlo_peer_lock_destroy(ml_peer); 817 epcs_dev_peer_lock_destroy(&ml_peer->epcs_info); 818 mlo_ap_ml_ptqm_peerid_free(ml_dev, ml_peer->mlo_peer_id); 819 mlo_ap_ml_peerid_free(ml_peer->mlo_peer_id); 820 mlo_peer_free_aid(ml_dev, ml_peer); 821 mlo_peer_free_primary_umac(ml_dev, ml_peer); 822 qdf_mem_free(ml_peer); 823 } 824 825 void mlo_peer_cleanup(struct wlan_mlo_peer_context *ml_peer) 826 { 827 struct wlan_mlo_dev_context *ml_dev; 828 829 if (!ml_peer) { 830 mlo_err("ML PEER is NULL"); 831 return; 832 } 833 ml_dev = ml_peer->ml_dev; 834 if (!ml_dev) { 835 mlo_err("ML DEV is NULL"); 836 return; 837 } 838 839 mlo_dev_mlpeer_detach(ml_dev, ml_peer); 840 /* If any Auth req is received during ML peer delete */ 841 mlo_peer_process_pending_auth(ml_dev, ml_peer); 842 mlo_peer_free(ml_peer); 843 } 844 845 static QDF_STATUS mlo_peer_attach_link_peer( 846 struct wlan_mlo_peer_context *ml_peer, 847 struct wlan_objmgr_peer *link_peer, 848 qdf_nbuf_t frm_buf) 849 { 850 struct wlan_mlo_link_peer_entry *peer_entry; 851 QDF_STATUS status = QDF_STATUS_E_RESOURCES; 852 struct wlan_objmgr_pdev *pdev; 853 struct wlan_objmgr_vdev *vdev; 854 uint16_t i; 855 856 if (!link_peer) 857 return QDF_STATUS_E_FAILURE; 858 859 vdev = wlan_peer_get_vdev(link_peer); 860 if (!vdev) 861 return QDF_STATUS_E_FAILURE; 862 863 mlo_peer_lock_acquire(ml_peer); 864 865 if (ml_peer->mlpeer_state != ML_PEER_CREATED) { 866 mlo_peer_lock_release(ml_peer); 867 mlo_err("ML Peer " QDF_MAC_ADDR_FMT " is not in created state (state %d)", 868 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 869 ml_peer->mlpeer_state); 870 return status; 871 } 872 873 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 874 peer_entry = &ml_peer->peer_list[i]; 875 if (peer_entry->link_peer) 876 continue; 877 878 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 879 QDF_STATUS_SUCCESS) { 880 mlo_err("ML Peer " QDF_MAC_ADDR_FMT ", link peer " QDF_MAC_ADDR_FMT " is not in valid state", 881 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 882 QDF_MAC_ADDR_REF 883 (wlan_peer_get_macaddr(link_peer))); 884 break; 885 } 886 peer_entry->link_peer = link_peer; 887 qdf_atomic_inc(&vdev->vdev_objmgr.wlan_ml_peer_count); 888 qdf_copy_macaddr(&peer_entry->link_addr, 889 (struct qdf_mac_addr *)&link_peer->macaddr[0]); 890 891 peer_entry->link_ix = wlan_vdev_get_link_id(vdev); 892 pdev = wlan_vdev_get_pdev(wlan_peer_get_vdev(link_peer)); 893 peer_entry->hw_link_id = wlan_mlo_get_pdev_hw_link_id(pdev); 894 mlo_peer_assign_primary_umac(ml_peer, peer_entry); 895 if (frm_buf) 896 peer_entry->assoc_rsp_buf = frm_buf; 897 else 898 peer_entry->assoc_rsp_buf = NULL; 899 900 status = QDF_STATUS_SUCCESS; 901 break; 902 } 903 if (QDF_IS_STATUS_SUCCESS(status)) 904 ml_peer->link_peer_cnt++; 905 906 mlo_peer_lock_release(ml_peer); 907 908 return status; 909 } 910 911 qdf_nbuf_t mlo_peer_get_link_peer_assoc_resp_buf( 912 struct wlan_mlo_peer_context *ml_peer, 913 uint8_t link_ix) 914 { 915 struct wlan_mlo_link_peer_entry *peer_entry; 916 qdf_nbuf_t frm_buf = NULL; 917 uint8_t i; 918 919 if (!ml_peer) 920 return NULL; 921 922 if (link_ix > MAX_MLO_LINK_PEERS) 923 return NULL; 924 925 mlo_peer_lock_acquire(ml_peer); 926 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 927 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 928 mlo_peer_lock_release(ml_peer); 929 return NULL; 930 } 931 932 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 933 peer_entry = &ml_peer->peer_list[i]; 934 935 if (!peer_entry->link_peer) 936 continue; 937 938 if (peer_entry->link_ix == link_ix) { 939 if (!peer_entry->assoc_rsp_buf) 940 break; 941 942 frm_buf = qdf_nbuf_clone(peer_entry->assoc_rsp_buf); 943 break; 944 } 945 } 946 mlo_peer_lock_release(ml_peer); 947 948 return frm_buf; 949 } 950 951 void wlan_mlo_peer_free_all_link_assoc_resp_buf( 952 struct wlan_objmgr_peer *link_peer) 953 { 954 struct wlan_mlo_link_peer_entry *peer_entry; 955 struct wlan_mlo_peer_context *ml_peer; 956 uint8_t i; 957 958 ml_peer = link_peer->mlo_peer_ctx; 959 if (!ml_peer) 960 return; 961 962 mlo_peer_lock_acquire(ml_peer); 963 964 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 965 peer_entry = &ml_peer->peer_list[i]; 966 967 if (peer_entry->assoc_rsp_buf) { 968 qdf_nbuf_free(peer_entry->assoc_rsp_buf); 969 peer_entry->assoc_rsp_buf = NULL; 970 } 971 } 972 mlo_peer_lock_release(ml_peer); 973 } 974 975 static QDF_STATUS mlo_peer_detach_link_peer( 976 struct wlan_mlo_peer_context *ml_peer, 977 struct wlan_objmgr_peer *link_peer) 978 { 979 struct wlan_mlo_link_peer_entry *peer_entry; 980 QDF_STATUS status = QDF_STATUS_E_RESOURCES; 981 uint16_t i; 982 struct wlan_objmgr_vdev *vdev; 983 984 mlo_peer_lock_acquire(ml_peer); 985 986 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 987 peer_entry = &ml_peer->peer_list[i]; 988 if (!peer_entry->link_peer) 989 continue; 990 991 if (peer_entry->link_peer != link_peer) 992 continue; 993 994 if (peer_entry->assoc_rsp_buf) { 995 qdf_nbuf_free(peer_entry->assoc_rsp_buf); 996 peer_entry->assoc_rsp_buf = NULL; 997 } 998 vdev = wlan_peer_get_vdev(link_peer); 999 if (vdev) { 1000 qdf_atomic_dec(&vdev->vdev_objmgr.wlan_ml_peer_count); 1001 } else { 1002 mlo_err("vdev is null for ml_peer: " QDF_MAC_ADDR_FMT 1003 "mld mac addr: " QDF_MAC_ADDR_FMT, 1004 QDF_MAC_ADDR_REF(link_peer->macaddr), 1005 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1006 qdf_assert_always(vdev); 1007 } 1008 wlan_objmgr_peer_release_ref(link_peer, WLAN_MLO_MGR_ID); 1009 peer_entry->link_peer = NULL; 1010 ml_peer->link_peer_cnt--; 1011 status = QDF_STATUS_SUCCESS; 1012 break; 1013 } 1014 mlo_peer_lock_release(ml_peer); 1015 1016 return status; 1017 } 1018 #if defined (SAP_MULTI_LINK_EMULATION) 1019 /*Skip link vdev check. Second link does not have vdev*/ 1020 static QDF_STATUS mlo_dev_get_link_vdevs( 1021 struct wlan_objmgr_vdev *vdev, 1022 struct wlan_mlo_dev_context *ml_dev, 1023 struct mlo_partner_info *ml_info, 1024 struct wlan_objmgr_vdev *link_vdevs[]) 1025 { 1026 return QDF_STATUS_SUCCESS; 1027 } 1028 #else 1029 static QDF_STATUS mlo_dev_get_link_vdevs( 1030 struct wlan_objmgr_vdev *vdev, 1031 struct wlan_mlo_dev_context *ml_dev, 1032 struct mlo_partner_info *ml_info, 1033 struct wlan_objmgr_vdev *link_vdevs[]) 1034 { 1035 uint16_t i, j; 1036 struct wlan_objmgr_vdev *vdev_link; 1037 uint8_t link_id; 1038 1039 if (!ml_dev) { 1040 mlo_err("ml_dev is null"); 1041 return QDF_STATUS_E_INVAL; 1042 } 1043 1044 if (!ml_info) { 1045 mlo_err("ml_info is null"); 1046 return QDF_STATUS_E_INVAL; 1047 } 1048 1049 mlo_debug("num_partner_links %d", ml_info->num_partner_links); 1050 for (i = 0; i < ml_info->num_partner_links; i++) { 1051 link_id = ml_info->partner_link_info[i].link_id; 1052 vdev_link = mlo_get_vdev_by_link_id(vdev, link_id, 1053 WLAN_MLO_MGR_ID); 1054 if (vdev_link) { 1055 link_vdevs[i] = vdev_link; 1056 } else { 1057 /* release ref which were taken before failure */ 1058 for (j = 0; j < i; j++) { 1059 vdev_link = link_vdevs[j]; 1060 if (!vdev_link) 1061 continue; 1062 1063 wlan_objmgr_vdev_release_ref(vdev_link, 1064 WLAN_MLO_MGR_ID); 1065 } 1066 return QDF_STATUS_E_INVAL; 1067 } 1068 } 1069 1070 return QDF_STATUS_SUCCESS; 1071 } 1072 #endif 1073 1074 static void mlo_dev_release_link_vdevs( 1075 struct wlan_objmgr_vdev *link_vdevs[]) 1076 { 1077 uint16_t i; 1078 struct wlan_objmgr_vdev *vdev_link; 1079 1080 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1081 vdev_link = link_vdevs[i]; 1082 if (!vdev_link) 1083 continue; 1084 1085 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 1086 } 1087 } 1088 1089 #ifdef WLAN_FEATURE_11BE 1090 static void 1091 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer, 1092 struct mlo_partner_info *ml_info) 1093 { 1094 ml_peer->t2lm_policy.t2lm_enable_val = ml_info->t2lm_enable_val; 1095 } 1096 1097 static void 1098 wlan_mlo_peer_initialize_epcs_info(struct wlan_mlo_peer_context *ml_peer) 1099 { 1100 ml_peer->epcs_info.state = EPCS_DOWN; 1101 ml_peer->epcs_info.self_gen_dialog_token = 0; 1102 } 1103 1104 #else 1105 static void 1106 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer, 1107 struct mlo_partner_info *ml_info) 1108 {} 1109 1110 static void 1111 wlan_mlo_peer_initialize_epcs_info(struct wlan_mlo_peer_context *ml_peer) 1112 {} 1113 #endif /* WLAN_FEATURE_11BE */ 1114 1115 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) 1116 struct wlan_objmgr_vdev* 1117 mlo_get_link_vdev_from_psoc_id(struct wlan_mlo_dev_context *ml_dev, 1118 uint8_t psoc_id, bool get_bridge_vdev) 1119 { 1120 uint8_t i; 1121 uint16_t num_bridge_vdev = 0; 1122 uint8_t max_vdevs = WLAN_UMAC_MLO_MAX_BRIDGE_VDEVS; 1123 struct wlan_objmgr_vdev *link_vdev; 1124 QDF_STATUS status; 1125 1126 if (WLAN_OBJMGR_MAX_DEVICES <= psoc_id) 1127 return NULL; 1128 1129 if (!ml_dev) 1130 return NULL; 1131 1132 /* if there are no bridge vdevs available, 1133 * fall back to actual link vdevs 1134 */ 1135 status = mlo_ap_get_bridge_vdev_count(ml_dev, &num_bridge_vdev); 1136 if (!get_bridge_vdev || (status != QDF_STATUS_SUCCESS) || 1137 !num_bridge_vdev) 1138 max_vdevs = WLAN_UMAC_MLO_MAX_VDEVS; 1139 1140 for (i = 0; i < max_vdevs; i++) { 1141 if (max_vdevs == WLAN_UMAC_MLO_MAX_BRIDGE_VDEVS) 1142 link_vdev = ml_dev->wlan_bridge_vdev_list[i]; 1143 else 1144 link_vdev = ml_dev->wlan_vdev_list[i]; 1145 if (!link_vdev) 1146 continue; 1147 if (psoc_id != wlan_vdev_get_psoc_id(link_vdev)) 1148 continue; 1149 if (wlan_objmgr_vdev_try_get_ref(link_vdev, WLAN_MLO_MGR_ID) != 1150 QDF_STATUS_SUCCESS) { 1151 mlo_err("VDEV is not in created state"); 1152 return NULL; 1153 } 1154 return link_vdev; 1155 } 1156 1157 return NULL; 1158 } 1159 1160 static 1161 QDF_STATUS mlo_bridge_peer_create_post(struct wlan_mlo_dev_context *ml_dev, 1162 struct wlan_mlo_peer_context *ml_peer, 1163 uint8_t psoc_id) 1164 { 1165 struct peer_create_notif_s peer_create; 1166 struct wlan_objmgr_vdev *vdev_link; 1167 QDF_STATUS status; 1168 1169 /* Bridge peer not required */ 1170 if (psoc_id >= WLAN_OBJMGR_MAX_DEVICES) 1171 return QDF_STATUS_SUCCESS; 1172 1173 vdev_link = mlo_get_link_vdev_from_psoc_id(ml_dev, psoc_id, true); 1174 1175 if (!vdev_link) { 1176 mlo_err("VDEV derivation in unsuccessful for %u psoc", 1177 psoc_id); 1178 return QDF_STATUS_E_FAILURE; 1179 } 1180 1181 peer_create.vdev_link = vdev_link; 1182 wlan_mlo_peer_get_ref(ml_peer); 1183 peer_create.ml_peer = ml_peer; 1184 1185 qdf_copy_macaddr(&peer_create.addr, 1186 &ml_peer->peer_mld_addr); 1187 1188 peer_create.frm_buf = NULL; 1189 1190 status = mlo_msgq_post(MLO_BRIDGE_PEER_CREATE, ml_dev, &peer_create); 1191 if (status != QDF_STATUS_SUCCESS) { 1192 wlan_mlo_peer_release_ref(ml_peer); 1193 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 1194 } 1195 1196 return status; 1197 } 1198 1199 static QDF_STATUS 1200 wlan_mlo_get_bridge_peer_psoc_id(struct wlan_objmgr_vdev *vdev, 1201 struct wlan_mlo_peer_context *ml_peer, 1202 struct wlan_objmgr_vdev *link_vdevs[], 1203 uint8_t num_partner_links, 1204 uint8_t *bridge_psoc_id) 1205 { 1206 struct wlan_mlo_dev_context *ml_dev; 1207 struct wlan_objmgr_vdev *ml_vdev; 1208 uint8_t psoc_ids[WLAN_NUM_TWO_LINK_PSOC]; 1209 uint8_t comp_psoc_id, i, is_adjacent; 1210 uint8_t bridge_peer_psoc_id = WLAN_OBJMGR_MAX_DEVICES; 1211 uint16_t num_bridge_vdev = 0; 1212 uint8_t max_vdevs = WLAN_UMAC_MLO_MAX_BRIDGE_VDEVS; 1213 QDF_STATUS status; 1214 1215 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE) 1216 return QDF_STATUS_SUCCESS; 1217 1218 /* Return from here for 3 link association */ 1219 if (WLAN_NUM_TWO_LINK_PSOC != num_partner_links) 1220 return QDF_STATUS_SUCCESS; 1221 1222 ml_dev = vdev->mlo_dev_ctx; 1223 if (!ml_dev) 1224 return QDF_STATUS_E_FAILURE; 1225 1226 for (i = 0; i < WLAN_NUM_TWO_LINK_PSOC; i++) 1227 psoc_ids[i] = wlan_vdev_get_psoc_id(link_vdevs[i]); 1228 1229 status = mlo_chip_adjacent(psoc_ids[0], psoc_ids[1], 1230 &is_adjacent); 1231 if (QDF_STATUS_SUCCESS != status) { 1232 mlo_err("Unable to get chip adjacency for " QDF_MAC_ADDR_FMT ", psoc_0 %u, psoc_1 %u", 1233 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1234 psoc_ids[0], psoc_ids[1]); 1235 return status; 1236 } 1237 1238 if (is_adjacent) 1239 return QDF_STATUS_SUCCESS; 1240 1241 /* if there are no bridge vdevs available, 1242 * fall back to actual link vdevs 1243 */ 1244 status = mlo_ap_get_bridge_vdev_count(ml_dev, &num_bridge_vdev); 1245 if ((status != QDF_STATUS_SUCCESS) || !num_bridge_vdev) { 1246 mlo_err_rl("Using actual vdev as bridge vdev"); 1247 max_vdevs = WLAN_UMAC_MLO_MAX_VDEVS; 1248 } 1249 1250 for (i = 0; i < max_vdevs; i++) { 1251 if (max_vdevs == WLAN_UMAC_MLO_MAX_BRIDGE_VDEVS) 1252 ml_vdev = ml_dev->wlan_bridge_vdev_list[i]; 1253 else 1254 ml_vdev = ml_dev->wlan_vdev_list[i]; 1255 if (!ml_vdev || (wlan_vdev_is_up(ml_vdev) != QDF_STATUS_SUCCESS)) 1256 continue; 1257 comp_psoc_id = wlan_vdev_get_psoc_id(ml_vdev); 1258 if ((comp_psoc_id != psoc_ids[0]) && 1259 (comp_psoc_id != psoc_ids[1])) { 1260 bridge_peer_psoc_id = comp_psoc_id; 1261 break; 1262 } 1263 } 1264 1265 if (bridge_peer_psoc_id >= WLAN_OBJMGR_MAX_DEVICES) { 1266 mlo_err("Invalid psoc or psoc not found for " QDF_MAC_ADDR_FMT " psoc %u", 1267 ether_sprintf(ml_peer->peer_mld_addr.bytes), 1268 bridge_peer_psoc_id); 1269 return QDF_STATUS_E_FAILURE; 1270 } 1271 1272 /* Check if derived psoc is adjecent to both links */ 1273 for (i = 0; i < WLAN_NUM_TWO_LINK_PSOC; i++) { 1274 status = mlo_chip_adjacent(psoc_ids[i], bridge_peer_psoc_id, 1275 &is_adjacent); 1276 if (QDF_STATUS_SUCCESS != status) { 1277 mlo_err("Unable to get chip adjacency for " QDF_MAC_ADDR_FMT ", psoc_0 %u, psoc_1 %u", 1278 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1279 psoc_ids[i], bridge_peer_psoc_id); 1280 return status; 1281 } 1282 if (!is_adjacent) { 1283 mlo_err("Derived psoc is not adjecent to one of the links for " QDF_MAC_ADDR_FMT ", psoc_0 %u, psoc_1 %u psoc_2 %u", 1284 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1285 psoc_ids[0], psoc_ids[1], bridge_peer_psoc_id); 1286 return QDF_STATUS_E_FAILURE; 1287 } 1288 } 1289 1290 /* Add vdev corresponds to bridge link to link_vdevs so 1291 * that primary UMAC derivation follows 3-link assoc. 1292 */ 1293 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1294 if (link_vdevs[i]) 1295 continue; 1296 1297 link_vdevs[i] = mlo_get_link_vdev_from_psoc_id(ml_dev, 1298 bridge_peer_psoc_id, 1299 true); 1300 if (!link_vdevs[i]) 1301 return QDF_STATUS_E_FAILURE; 1302 1303 ml_peer->max_links++; 1304 *bridge_psoc_id = bridge_peer_psoc_id; 1305 break; 1306 } 1307 1308 if (i == WLAN_UMAC_MLO_MAX_VDEVS) { 1309 mlo_err("Unable to append bridge peer vdev to link vdev list"); 1310 return QDF_STATUS_E_FAILURE; 1311 } 1312 1313 mlo_debug("%u is adjecent psoc for " QDF_MAC_ADDR_FMT " is_adjacent %u", 1314 bridge_peer_psoc_id, 1315 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1316 is_adjacent); 1317 1318 return status; 1319 } 1320 #else 1321 static 1322 QDF_STATUS mlo_bridge_peer_create_post(struct wlan_mlo_dev_context *ml_dev, 1323 struct wlan_mlo_peer_context *ml_peer, 1324 uint8_t psoc_id) 1325 { 1326 return QDF_STATUS_SUCCESS; 1327 } 1328 1329 static QDF_STATUS 1330 wlan_mlo_get_bridge_peer_psoc_id(struct wlan_objmgr_vdev *vdev, 1331 struct wlan_mlo_peer_context *ml_peer, 1332 struct wlan_objmgr_vdev *link_vdevs[], 1333 uint8_t num_partner_links, 1334 uint8_t *bridge_psoc_id) 1335 { 1336 return QDF_STATUS_SUCCESS; 1337 } 1338 #endif 1339 1340 QDF_STATUS wlan_mlo_peer_asreq(struct wlan_objmgr_vdev *vdev, 1341 struct wlan_objmgr_peer *link_peer, 1342 struct mlo_partner_info *ml_info, 1343 qdf_nbuf_t frm_buf) 1344 { 1345 struct wlan_mlo_dev_context *ml_dev; 1346 struct wlan_mlo_peer_context *ml_peer = NULL; 1347 struct wlan_objmgr_vdev *link_vdevs[WLAN_UMAC_MLO_MAX_VDEVS] = { NULL }; 1348 struct wlan_objmgr_vdev *vdev_link; 1349 QDF_STATUS status; 1350 uint16_t i; 1351 uint16_t j; 1352 uint16_t link_count; 1353 struct wlan_mlo_link_peer_entry *peer_entry; 1354 struct wlan_objmgr_peer *iter_peer; 1355 1356 /* get ML VDEV from VDEV */ 1357 ml_dev = vdev->mlo_dev_ctx; 1358 if (!ml_dev) { 1359 mlo_err("ML dev ctx is NULL"); 1360 return QDF_STATUS_E_NULL_VALUE; 1361 } 1362 1363 ml_peer = link_peer->mlo_peer_ctx; 1364 if (!ml_peer) { 1365 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " ML peer is NULL", 1366 ml_dev->mld_id, 1367 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1368 1369 return QDF_STATUS_E_FAILURE; 1370 } 1371 1372 if (!wlan_mlo_peer_is_assoc_peer(ml_peer, link_peer)) { 1373 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT "Assoc req received on non-assoc peer" QDF_MAC_ADDR_FMT, 1374 ml_dev->mld_id, 1375 QDF_MAC_ADDR_REF(link_peer->mldaddr), 1376 QDF_MAC_ADDR_REF(link_peer->macaddr)); 1377 1378 return QDF_STATUS_E_FAILURE; 1379 } 1380 1381 status = mlo_dev_get_link_vdevs(vdev, ml_dev, 1382 ml_info, link_vdevs); 1383 if (QDF_IS_STATUS_ERROR(status)) { 1384 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " get link vdevs failed", 1385 ml_dev->mld_id, 1386 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1387 return QDF_STATUS_E_FAILURE; 1388 } 1389 1390 /* If ML peer state is not in Assoc done state, drop REASSOC req */ 1391 if (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE) { 1392 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " invalid state %d", 1393 ml_dev->mld_id, 1394 QDF_MAC_ADDR_REF(link_peer->mldaddr), 1395 ml_peer->mlpeer_state); 1396 1397 mlo_dev_release_link_vdevs(link_vdevs); 1398 1399 return QDF_STATUS_E_FAILURE; 1400 } 1401 1402 link_count = 0; 1403 for (j = 0; j < ml_peer->max_links; j++) { 1404 peer_entry = &ml_peer->peer_list[j]; 1405 iter_peer = peer_entry->link_peer; 1406 if (!iter_peer) 1407 continue; 1408 1409 if (wlan_peer_get_peer_type(iter_peer) == 1410 WLAN_PEER_MLO_BRIDGE) { 1411 link_count++; 1412 continue; 1413 } 1414 1415 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1416 vdev_link = link_vdevs[i]; 1417 if (!vdev_link) 1418 continue; 1419 1420 if (vdev_link != wlan_peer_get_vdev(iter_peer)) 1421 continue; 1422 1423 link_count++; 1424 break; 1425 } 1426 } 1427 if (link_count != ml_peer->link_peer_cnt) { 1428 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " incorrect link peers", 1429 ml_dev->mld_id, 1430 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1431 mlo_dev_release_link_vdevs(link_vdevs); 1432 1433 return QDF_STATUS_E_INVAL; 1434 } 1435 1436 /* Notify other vdevs about assoc req */ 1437 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1438 vdev_link = link_vdevs[i]; 1439 if (!vdev_link) 1440 continue; 1441 1442 if (vdev_link == vdev) 1443 continue; 1444 1445 mlo_partner_peer_reassoc_post(ml_dev, vdev_link, 1446 ml_peer, frm_buf, ml_info); 1447 } 1448 1449 mlo_dev_release_link_vdevs(link_vdevs); 1450 1451 if (QDF_IS_STATUS_ERROR(wlan_mlo_validate_reassocreq(ml_peer))) { 1452 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " reassoc proc is failed %pK", 1453 ml_dev->mld_id, 1454 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1455 ml_peer); 1456 1457 return QDF_STATUS_E_FAILURE; 1458 } 1459 1460 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " reassoc handled %pK", 1461 ml_dev->mld_id, 1462 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1463 ml_peer); 1464 1465 return QDF_STATUS_SUCCESS; 1466 } 1467 #if defined (SAP_MULTI_LINK_EMULATION) 1468 static void 1469 set_assoc_peer_for_2link_sap(struct wlan_objmgr_peer *assoc_peer, 1470 struct wlan_mlo_peer_context *ml_peer) 1471 { 1472 assoc_peer = ml_peer->peer_list[0].link_peer; 1473 if (assoc_peer) 1474 mlo_mlme_peer_assoc_resp(assoc_peer); 1475 } 1476 #else 1477 static void 1478 set_assoc_peer_for_2link_sap(struct wlan_objmgr_peer *assoc_peer, 1479 struct wlan_mlo_peer_context *ml_peer) 1480 { 1481 } 1482 #endif 1483 QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev, 1484 struct wlan_objmgr_peer *link_peer, 1485 struct mlo_partner_info *ml_info, 1486 qdf_nbuf_t frm_buf, 1487 uint16_t aid) 1488 { 1489 struct wlan_mlo_dev_context *ml_dev; 1490 struct wlan_mlo_peer_context *ml_peer = NULL; 1491 struct wlan_objmgr_vdev *link_vdevs[WLAN_UMAC_MLO_MAX_VDEVS] = { NULL }; 1492 struct wlan_objmgr_vdev *tmp_link_vdevs[WLAN_UMAC_MLO_MAX_VDEVS] = { NULL }; 1493 struct wlan_objmgr_vdev *vdev_link; 1494 QDF_STATUS status; 1495 uint16_t i, j; 1496 struct wlan_objmgr_peer *assoc_peer = NULL; 1497 uint8_t bridge_peer_psoc_id = WLAN_OBJMGR_MAX_DEVICES; 1498 bool is_ml_peer_attached = false; 1499 1500 /* get ML VDEV from VDEV */ 1501 ml_dev = vdev->mlo_dev_ctx; 1502 1503 if (!ml_dev) { 1504 mlo_err("ML dev ctx is NULL"); 1505 return QDF_STATUS_E_NULL_VALUE; 1506 } 1507 1508 /* Check resources of Partner VDEV */ 1509 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1510 if (wlan_mlo_is_mld_ctx_exist( 1511 (struct qdf_mac_addr *)&link_peer->mldaddr[0])) { 1512 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " is matching with one of the MLD address in the system", 1513 ml_dev->mld_id, 1514 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1515 return QDF_STATUS_E_FAILURE; 1516 } 1517 /* Limit max assoc links */ 1518 if (ml_info->num_partner_links > WLAN_UMAC_MLO_ASSOC_MAX_SUPPORTED_LINKS) { 1519 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " exceeds MAX assoc limit of %d", 1520 ml_dev->mld_id, 1521 QDF_MAC_ADDR_REF(link_peer->mldaddr), 1522 WLAN_UMAC_MLO_ASSOC_MAX_SUPPORTED_LINKS); 1523 return QDF_STATUS_E_RESOURCES; 1524 } 1525 1526 status = mlo_dev_get_link_vdevs(vdev, ml_dev, 1527 ml_info, link_vdevs); 1528 if (QDF_IS_STATUS_ERROR(status)) { 1529 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " get link vdevs failed", 1530 ml_dev->mld_id, 1531 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1532 return QDF_STATUS_E_FAILURE; 1533 } 1534 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1535 vdev_link = link_vdevs[i]; 1536 if (!vdev_link) { 1537 mlo_debug("vdev_link is null"); 1538 continue; 1539 } 1540 1541 if (wlan_vdev_is_mlo_peer_create_allowed(vdev_link) 1542 != QDF_STATUS_SUCCESS) { 1543 mlo_dev_release_link_vdevs(link_vdevs); 1544 1545 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " create not allowed on link vdev %d", 1546 ml_dev->mld_id, 1547 QDF_MAC_ADDR_REF 1548 (link_peer->mldaddr), 1549 wlan_vdev_get_id(vdev_link)); 1550 return QDF_STATUS_E_INVAL; 1551 } 1552 } 1553 1554 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1555 vdev_link = link_vdevs[i]; 1556 if (vdev_link && (vdev_link != vdev) && 1557 (wlan_vdev_get_peer_count(vdev_link) > 1558 wlan_vdev_get_max_peer_count(vdev_link))) { 1559 mlo_dev_release_link_vdevs(link_vdevs); 1560 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " Max peer count reached on link vdev %d", 1561 ml_dev->mld_id, 1562 QDF_MAC_ADDR_REF 1563 (link_peer->mldaddr), 1564 wlan_vdev_get_id(vdev_link)); 1565 return QDF_STATUS_E_RESOURCES; 1566 } 1567 } 1568 } 1569 /* When roam to MLO AP, partner link vdev1 is updated first, 1570 * ml peer need be created and attached for partner link peer. 1571 * 1572 * When roam target AP and current AP have same MLD address, don't 1573 * delete old ML peer and re-create new one, just update different 1574 * info. 1575 */ 1576 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) { 1577 ml_peer = wlan_mlo_get_mlpeer(ml_dev, 1578 (struct qdf_mac_addr *)&link_peer->mldaddr[0]); 1579 if (ml_peer) { 1580 mlo_debug("ML Peer " QDF_MAC_ADDR_FMT 1581 " existed, state %d", 1582 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1583 ml_peer->mlpeer_state); 1584 ml_peer->mlpeer_state = ML_PEER_CREATED; 1585 ml_peer->max_links = ml_info->num_partner_links; 1586 wlan_mlo_peer_set_t2lm_enable_val(ml_peer, ml_info); 1587 is_ml_peer_attached = true; 1588 } 1589 } 1590 if (!ml_peer) { 1591 /* Allocate MLO peer */ 1592 ml_peer = qdf_mem_malloc(sizeof(*ml_peer)); 1593 if (!ml_peer) { 1594 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " mem alloc failed", 1595 ml_dev->mld_id, 1596 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 1597 mlo_dev_release_link_vdevs(link_vdevs); 1598 return QDF_STATUS_E_NOMEM; 1599 } 1600 1601 qdf_atomic_init(&ml_peer->ref_cnt); 1602 mlo_peer_lock_create(ml_peer); 1603 ml_peer->ml_dev = ml_dev; 1604 ml_peer->mlpeer_state = ML_PEER_CREATED; 1605 ml_peer->max_links = ml_info->num_partner_links; 1606 ml_peer->primary_umac_psoc_id = ML_PRIMARY_UMAC_ID_INVAL; 1607 ml_peer->migrate_primary_umac_psoc_id = 1608 ML_PRIMARY_UMAC_ID_INVAL; 1609 ml_peer->primary_umac_migration_in_progress = false; 1610 1611 ml_peer->mlo_peer_id = mlo_ap_ml_peerid_alloc(); 1612 if (ml_peer->mlo_peer_id == MLO_INVALID_PEER_ID) { 1613 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " invalid ml peer id", 1614 ml_dev->mld_id, 1615 QDF_MAC_ADDR_REF 1616 (ml_peer->peer_mld_addr.bytes)); 1617 mlo_peer_free(ml_peer); 1618 mlo_dev_release_link_vdevs(link_vdevs); 1619 return QDF_STATUS_E_RESOURCES; 1620 } 1621 1622 qdf_copy_macaddr((struct qdf_mac_addr *)&ml_peer->peer_mld_addr, 1623 (struct qdf_mac_addr *)&link_peer->mldaddr[0]); 1624 wlan_mlo_peer_set_t2lm_enable_val(ml_peer, ml_info); 1625 epcs_dev_peer_lock_create(&ml_peer->epcs_info); 1626 wlan_mlo_peer_initialize_epcs_info(ml_peer); 1627 1628 /* Allocate AID */ 1629 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1630 if (aid == (uint16_t)-1) { 1631 status = mlo_peer_allocate_aid(ml_dev, ml_peer); 1632 if (status != QDF_STATUS_SUCCESS) { 1633 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " aid alloc failed", 1634 ml_dev->mld_id, 1635 QDF_MAC_ADDR_REF 1636 (ml_peer->peer_mld_addr.bytes)); 1637 mlo_peer_free(ml_peer); 1638 mlo_dev_release_link_vdevs(link_vdevs); 1639 return status; 1640 } 1641 } else { 1642 ml_peer->assoc_id = aid; 1643 } 1644 } 1645 } 1646 1647 /* Populate Link peer pointer, peer MAC address, 1648 * MLD address. HW link ID, update ref count 1649 */ 1650 status = mlo_peer_attach_link_peer(ml_peer, link_peer, NULL); 1651 if (QDF_IS_STATUS_ERROR(status)) { 1652 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " link peer attach failed", 1653 ml_dev->mld_id, 1654 QDF_MAC_ADDR_REF 1655 (ml_peer->peer_mld_addr.bytes)); 1656 /* If there is another link peer attached for this ML peer, 1657 * ml peer can't be detached and freed. 1658 */ 1659 if (is_ml_peer_attached && ml_peer->link_peer_cnt) 1660 return status; 1661 if (is_ml_peer_attached) 1662 mlo_dev_mlpeer_detach(ml_dev, ml_peer); 1663 mlo_peer_free(ml_peer); 1664 mlo_dev_release_link_vdevs(link_vdevs); 1665 return status; 1666 } 1667 1668 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1669 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1670 if (!link_vdevs[i]) { 1671 mlo_debug("vdev_link is null"); 1672 continue; 1673 } 1674 1675 if (wlan_objmgr_vdev_try_get_ref(link_vdevs[i], WLAN_MLO_MGR_ID) != 1676 QDF_STATUS_SUCCESS) { 1677 mlo_err("VDEV is not in created state"); 1678 /* release ref which were taken before failure */ 1679 for (j = 0; j < i; j++) { 1680 if (!link_vdevs[i]) 1681 continue; 1682 1683 wlan_objmgr_vdev_release_ref(link_vdevs[i], 1684 WLAN_MLO_MGR_ID); 1685 } 1686 mlo_reset_link_peer(ml_peer, link_peer); 1687 mlo_peer_free(ml_peer); 1688 mlo_dev_release_link_vdevs(link_vdevs); 1689 1690 return QDF_STATUS_E_FAILURE; 1691 } 1692 tmp_link_vdevs[i] = link_vdevs[i]; 1693 } 1694 1695 status = wlan_mlo_get_bridge_peer_psoc_id(vdev, ml_peer, 1696 tmp_link_vdevs, 1697 ml_info->num_partner_links, 1698 &bridge_peer_psoc_id); 1699 if (QDF_STATUS_SUCCESS != status) { 1700 mlo_err("MLD ID %d: Failed to derive bridge peer psoc id", 1701 ml_dev->mld_id); 1702 mlo_reset_link_peer(ml_peer, link_peer); 1703 mlo_peer_free(ml_peer); 1704 mlo_dev_release_link_vdevs(link_vdevs); 1705 mlo_dev_release_link_vdevs(tmp_link_vdevs); 1706 wlan_objmgr_peer_release_ref(link_peer, 1707 WLAN_MLO_MGR_ID); 1708 return QDF_STATUS_E_FAILURE; 1709 } 1710 } 1711 1712 /* Allocate Primary UMAC */ 1713 mlo_peer_allocate_primary_umac(ml_dev, ml_peer, tmp_link_vdevs); 1714 1715 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) 1716 mlo_dev_release_link_vdevs(tmp_link_vdevs); 1717 1718 /* Store AID, MLO Peer pointer in link peer, take link peer ref count */ 1719 mlo_peer_populate_link_peer(ml_peer, link_peer); 1720 1721 mlo_peer_populate_nawds_params(ml_peer, ml_info); 1722 mlo_peer_populate_mesh_params(ml_peer, ml_info); 1723 1724 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) || 1725 ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) && 1726 !is_ml_peer_attached)) { 1727 /* Reject creation for AP mode, If ML peer is present with 1728 * MLD MAC address, For PSTA case, all MLD STAs are connected 1729 * to same MLD AP, it can have duplicate MLD address entries 1730 * for STA MLDs 1731 */ 1732 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) && 1733 mlo_mgr_ml_peer_exist_on_diff_ml_ctx(&link_peer->mldaddr[0], 1734 NULL)) { 1735 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " is exists, creation failed", 1736 ml_dev->mld_id, 1737 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 1738 mlo_reset_link_peer(ml_peer, link_peer); 1739 mlo_peer_free(ml_peer); 1740 mlo_dev_release_link_vdevs(link_vdevs); 1741 wlan_objmgr_peer_release_ref(link_peer, 1742 WLAN_MLO_MGR_ID); 1743 return QDF_STATUS_E_EXISTS; 1744 } 1745 1746 /* Attach MLO peer to ML Peer table */ 1747 status = mlo_dev_mlpeer_attach(ml_dev, ml_peer); 1748 if (status != QDF_STATUS_SUCCESS) { 1749 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " attach failed", 1750 ml_dev->mld_id, 1751 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 1752 mlo_reset_link_peer(ml_peer, link_peer); 1753 wlan_objmgr_peer_release_ref(link_peer, 1754 WLAN_MLO_MGR_ID); 1755 mlo_peer_free(ml_peer); 1756 mlo_dev_release_link_vdevs(link_vdevs); 1757 return status; 1758 } 1759 } 1760 1761 wlan_mlo_peer_get_ref(ml_peer); 1762 1763 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1764 /* Notify other vdevs about link peer creation */ 1765 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1766 vdev_link = link_vdevs[i]; 1767 if (!vdev_link) 1768 continue; 1769 1770 if (vdev_link == vdev) 1771 continue; 1772 1773 mlo_partner_peer_create_post(ml_dev, vdev_link, 1774 ml_peer, frm_buf, ml_info); 1775 } 1776 /* Create bridge peer */ 1777 status = mlo_bridge_peer_create_post(ml_dev, ml_peer, 1778 bridge_peer_psoc_id); 1779 if (QDF_STATUS_SUCCESS != status) { 1780 mlo_err("MLD ID %d: Bridge peer creation failed", 1781 ml_dev->mld_id); 1782 wlan_mlo_partner_peer_create_failed_notify(ml_peer); 1783 mlo_dev_release_link_vdevs(link_vdevs); 1784 wlan_mlo_peer_release_ref(ml_peer); 1785 return QDF_STATUS_E_FAILURE; 1786 } 1787 } 1788 mlo_dev_release_link_vdevs(link_vdevs); 1789 1790 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 1791 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " allocation failed", 1792 ml_dev->mld_id, 1793 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 1794 wlan_mlo_peer_release_ref(ml_peer); 1795 return QDF_STATUS_E_FAILURE; 1796 } 1797 1798 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " allocated %pK", 1799 ml_dev->mld_id, 1800 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 1801 ml_peer); 1802 1803 /* 1804 * wlan_mlo_peer_create() is trigggered after getting peer 1805 * assoc confirm from FW. For single link MLO connection, it is 1806 * OK to trigger assoc response from here. 1807 */ 1808 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) && 1809 (!wlan_mlo_peer_is_nawds(ml_peer))) { 1810 if ((ml_peer->max_links == 1) && 1811 (ml_peer->link_peer_cnt == 1)) { 1812 assoc_peer = ml_peer->peer_list[0].link_peer; 1813 if (assoc_peer) 1814 mlo_mlme_peer_assoc_resp(assoc_peer); 1815 } else { 1816 set_assoc_peer_for_2link_sap(assoc_peer, ml_peer); 1817 } 1818 } 1819 1820 1821 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) 1822 wlan_clear_peer_level_tid_to_link_mapping(vdev); 1823 1824 wlan_mlo_peer_release_ref(ml_peer); 1825 1826 return QDF_STATUS_SUCCESS; 1827 } 1828 1829 QDF_STATUS wlan_mlo_link_peer_attach(struct wlan_mlo_peer_context *ml_peer, 1830 struct wlan_objmgr_peer *peer, 1831 qdf_nbuf_t frm_buf) 1832 { 1833 QDF_STATUS status; 1834 struct wlan_objmgr_peer *assoc_peer; 1835 struct wlan_objmgr_vdev *vdev = NULL; 1836 1837 if (!ml_peer) 1838 return QDF_STATUS_E_FAILURE; 1839 1840 vdev = wlan_peer_get_vdev(peer); 1841 if (!vdev) 1842 return QDF_STATUS_E_FAILURE; 1843 1844 /* Populate Link peer pointer, peer MAC address, 1845 * MLD address. HW link ID, update ref count 1846 */ 1847 status = mlo_peer_attach_link_peer(ml_peer, peer, frm_buf); 1848 if (QDF_IS_STATUS_ERROR(status)) 1849 return status; 1850 1851 /* Store AID, MLO Peer pointer in link peer, take link peer ref count */ 1852 mlo_peer_populate_link_peer(ml_peer, peer); 1853 1854 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1855 if (ml_peer->max_links == ml_peer->link_peer_cnt) { 1856 assoc_peer = ml_peer->peer_list[0].link_peer; 1857 if (assoc_peer) 1858 mlo_mlme_peer_assoc_resp(assoc_peer); 1859 } 1860 } 1861 1862 return status; 1863 } 1864 1865 QDF_STATUS wlan_mlo_link_asresp_attach(struct wlan_mlo_peer_context *ml_peer, 1866 struct wlan_objmgr_peer *peer, 1867 qdf_nbuf_t frm_buf) 1868 { 1869 uint16_t i; 1870 struct wlan_mlo_link_peer_entry *peer_entry; 1871 1872 if (!ml_peer) { 1873 mlo_err(" ml peer is NULL"); 1874 return QDF_STATUS_E_FAILURE; 1875 } 1876 1877 if (!peer) { 1878 ml_peer->link_asresp_cnt++; 1879 mlo_err(" ml peer or link peer pointer is NULL"); 1880 return QDF_STATUS_E_FAILURE; 1881 } 1882 mlo_peer_lock_acquire(ml_peer); 1883 1884 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1885 peer_entry = &ml_peer->peer_list[i]; 1886 if (!peer_entry->link_peer) 1887 continue; 1888 1889 if (peer == peer_entry->link_peer) { 1890 ml_peer->link_asresp_cnt++; 1891 /* Free previous assoc resp buffer */ 1892 if (peer_entry->assoc_rsp_buf) { 1893 qdf_nbuf_free(peer_entry->assoc_rsp_buf); 1894 peer_entry->assoc_rsp_buf = NULL; 1895 } 1896 1897 if (frm_buf) 1898 peer_entry->assoc_rsp_buf = frm_buf; 1899 else 1900 peer_entry->assoc_rsp_buf = NULL; 1901 1902 break; 1903 } 1904 } 1905 1906 mlo_peer_lock_release(ml_peer); 1907 1908 return QDF_STATUS_SUCCESS; 1909 } 1910 1911 QDF_STATUS wlan_mlo_link_peer_delete(struct wlan_objmgr_peer *peer) 1912 { 1913 struct wlan_mlo_peer_context *ml_peer; 1914 1915 ml_peer = peer->mlo_peer_ctx; 1916 1917 if (!ml_peer) 1918 return QDF_STATUS_E_NOENT; 1919 1920 if (ml_peer->mlpeer_state != ML_PEER_DISCONN_INITIATED) 1921 wlan_mlo_peer_wsi_link_delete(ml_peer); 1922 1923 mlo_reset_link_peer(ml_peer, peer); 1924 mlo_peer_detach_link_peer(ml_peer, peer); 1925 1926 if (ml_peer->mlpeer_state != ML_PEER_DISCONN_INITIATED) 1927 wlan_mlo_peer_wsi_link_add(ml_peer); 1928 1929 wlan_mlo_peer_release_ref(ml_peer); 1930 1931 return QDF_STATUS_SUCCESS; 1932 } 1933 1934 qdf_export_symbol(wlan_mlo_link_peer_delete); 1935 1936 qdf_nbuf_t mlo_peer_get_link_peer_assoc_req_buf( 1937 struct wlan_mlo_peer_context *ml_peer, 1938 uint8_t link_ix) 1939 { 1940 struct wlan_objmgr_peer *peer = NULL; 1941 qdf_nbuf_t assocbuf = NULL; 1942 1943 if (!ml_peer) 1944 return NULL; 1945 1946 peer = wlan_mlo_peer_get_assoc_peer(ml_peer); 1947 if (!peer) 1948 return NULL; 1949 1950 assocbuf = mlo_mlme_get_link_assoc_req(peer, link_ix); 1951 1952 return assocbuf; 1953 } 1954 1955 void wlan_mlo_peer_get_links_info(struct wlan_objmgr_peer *peer, 1956 struct mlo_tgt_partner_info *ml_links) 1957 { 1958 struct wlan_mlo_peer_context *ml_peer; 1959 struct wlan_mlo_link_peer_entry *peer_entry; 1960 struct wlan_objmgr_peer *link_peer; 1961 struct wlan_objmgr_vdev *link_vdev; 1962 uint8_t i, ix, idx = 0; 1963 struct wlan_mlo_eml_cap *ml_emlcap; 1964 1965 ml_peer = peer->mlo_peer_ctx; 1966 ml_links->num_partner_links = 0; 1967 1968 if (!ml_peer) 1969 return; 1970 1971 ml_emlcap = &ml_peer->mlpeer_emlcap; 1972 1973 mlo_peer_lock_acquire(ml_peer); 1974 1975 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 1976 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 1977 mlo_peer_lock_release(ml_peer); 1978 return; 1979 } 1980 1981 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1982 peer_entry = &ml_peer->peer_list[i]; 1983 link_peer = peer_entry->link_peer; 1984 1985 if (!link_peer) 1986 continue; 1987 idx++; 1988 if (link_peer == peer) 1989 continue; 1990 link_vdev = wlan_peer_get_vdev(link_peer); 1991 if (!link_vdev) 1992 continue; 1993 1994 if (ml_links->num_partner_links >= WLAN_UMAC_MLO_MAX_VDEVS) 1995 break; 1996 1997 ix = ml_links->num_partner_links; 1998 ml_links->link_info[ix].vdev_id = wlan_vdev_get_id(link_vdev); 1999 ml_links->link_info[ix].hw_mld_link_id = peer_entry->hw_link_id; 2000 ml_links->link_info[ix].mlo_enabled = 1; 2001 ml_links->link_info[ix].mlo_assoc_link = 2002 wlan_peer_mlme_is_assoc_peer(link_peer); 2003 ml_links->link_info[ix].mlo_primary_umac = 2004 peer_entry->is_primary; 2005 ml_links->link_info[ix].mlo_logical_link_index_valid = 1; 2006 ml_links->link_info[ix].emlsr_support = ml_emlcap->emlsr_supp; 2007 ml_links->link_info[ix].logical_link_index = idx - 1; 2008 ml_links->link_info[ix].mlo_bridge_peer = link_peer->mlo_bridge_peer; 2009 ml_links->num_partner_links++; 2010 } 2011 mlo_peer_lock_release(ml_peer); 2012 } 2013 2014 qdf_export_symbol(wlan_mlo_peer_get_links_info); 2015 2016 uint8_t wlan_mlo_peer_get_primary_peer_link_id(struct wlan_objmgr_peer *peer) 2017 { 2018 struct wlan_mlo_peer_context *ml_peer; 2019 2020 ml_peer = peer->mlo_peer_ctx; 2021 2022 if (!ml_peer) { 2023 mlo_err("ml_peer is null"); 2024 return WLAN_LINK_ID_INVALID; 2025 } 2026 2027 return wlan_mlo_peer_get_primary_peer_link_id_by_ml_peer(ml_peer); 2028 } 2029 2030 qdf_export_symbol(wlan_mlo_peer_get_primary_peer_link_id); 2031 2032 uint8_t wlan_mlo_peer_get_primary_peer_link_id_by_ml_peer( 2033 struct wlan_mlo_peer_context *ml_peer) 2034 { 2035 struct wlan_mlo_link_peer_entry *peer_entry; 2036 struct wlan_objmgr_peer *link_peer; 2037 struct wlan_objmgr_vdev *link_vdev; 2038 uint8_t i, vdev_link_id; 2039 2040 if (!ml_peer) { 2041 mlo_err("ml_peer is null"); 2042 return WLAN_LINK_ID_INVALID; 2043 } 2044 mlo_peer_lock_acquire(ml_peer); 2045 2046 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 2047 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 2048 mlo_peer_lock_release(ml_peer); 2049 mlo_err("ml_peer is not created and association is not done"); 2050 return WLAN_LINK_ID_INVALID; 2051 } 2052 2053 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 2054 peer_entry = &ml_peer->peer_list[i]; 2055 link_peer = peer_entry->link_peer; 2056 if (!link_peer) 2057 continue; 2058 2059 if (peer_entry->is_primary) { 2060 link_vdev = wlan_peer_get_vdev(link_peer); 2061 if (!link_vdev) { 2062 mlo_peer_lock_release(ml_peer); 2063 mlo_err("link vdev not found"); 2064 return WLAN_LINK_ID_INVALID; 2065 } 2066 vdev_link_id = wlan_vdev_get_link_id(link_vdev); 2067 mlo_peer_lock_release(ml_peer); 2068 return vdev_link_id; 2069 } 2070 } 2071 mlo_peer_lock_release(ml_peer); 2072 mlo_err("None of the peer is designated as primary"); 2073 return WLAN_LINK_ID_INVALID; 2074 } 2075 2076 qdf_export_symbol(wlan_mlo_peer_get_primary_peer_link_id_by_ml_peer); 2077 2078 #ifdef WLAN_MLO_MULTI_CHIP 2079 void wlan_mlo_peer_get_str_capability(struct wlan_objmgr_peer *peer, 2080 uint8_t *str_capability) 2081 { 2082 struct wlan_mlo_peer_context *ml_peer; 2083 uint8_t i; 2084 2085 if (!str_capability) 2086 return; 2087 2088 *str_capability = 1; 2089 if (!peer) 2090 return; 2091 ml_peer = peer->mlo_peer_ctx; 2092 if (!ml_peer) 2093 return; 2094 2095 mlo_peer_lock_acquire(ml_peer); 2096 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 2097 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 2098 mlo_peer_lock_release(ml_peer); 2099 return; 2100 } 2101 2102 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 2103 if (ml_peer->mlpeer_nstrinfo[i].link_id >= MAX_MLO_LINKS) 2104 continue; 2105 if (ml_peer->mlpeer_nstrinfo[i].nstr_lp_present) { 2106 *str_capability = 0; 2107 break; 2108 } 2109 } 2110 mlo_peer_lock_release(ml_peer); 2111 } 2112 2113 void wlan_mlo_peer_get_eml_capability(struct wlan_objmgr_peer *peer, 2114 uint8_t *is_emlsr_capable, 2115 uint8_t *is_emlmr_capable) 2116 { 2117 struct wlan_mlo_peer_context *ml_peer; 2118 2119 if (!is_emlsr_capable || !is_emlmr_capable) 2120 return; 2121 2122 *is_emlsr_capable = 0; 2123 *is_emlmr_capable = 0; 2124 if (!peer) 2125 return; 2126 ml_peer = peer->mlo_peer_ctx; 2127 if (!ml_peer) 2128 return; 2129 2130 mlo_peer_lock_acquire(ml_peer); 2131 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 2132 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 2133 mlo_peer_lock_release(ml_peer); 2134 return; 2135 } 2136 *is_emlsr_capable = ml_peer->mlpeer_emlcap.emlsr_supp; 2137 *is_emlmr_capable = ml_peer->mlpeer_emlcap.emlmr_supp; 2138 mlo_peer_lock_release(ml_peer); 2139 } 2140 #endif 2141 2142 void wlan_mlo_peer_get_partner_links_info(struct wlan_objmgr_peer *peer, 2143 struct mlo_partner_info *ml_links) 2144 { 2145 struct wlan_mlo_peer_context *ml_peer; 2146 struct wlan_mlo_link_peer_entry *peer_entry; 2147 struct wlan_objmgr_peer *link_peer; 2148 struct wlan_objmgr_vdev *link_vdev; 2149 uint8_t i, ix; 2150 2151 ml_peer = peer->mlo_peer_ctx; 2152 ml_links->num_partner_links = 0; 2153 2154 if (!ml_peer) 2155 return; 2156 2157 mlo_peer_lock_acquire(ml_peer); 2158 2159 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 2160 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 2161 mlo_peer_lock_release(ml_peer); 2162 return; 2163 } 2164 2165 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 2166 peer_entry = &ml_peer->peer_list[i]; 2167 link_peer = peer_entry->link_peer; 2168 2169 if (!link_peer) 2170 continue; 2171 2172 if (link_peer == peer) 2173 continue; 2174 2175 link_vdev = wlan_peer_get_vdev(link_peer); 2176 if (!link_vdev) 2177 continue; 2178 2179 if (ml_links->num_partner_links >= WLAN_UMAC_MLO_MAX_VDEVS) 2180 break; 2181 2182 ix = ml_links->num_partner_links; 2183 ml_links->partner_link_info[ix].link_id = peer_entry->link_ix; 2184 ml_links->partner_link_info[ix].is_bridge = 2185 (wlan_peer_get_peer_type(link_peer) == WLAN_PEER_MLO_BRIDGE); 2186 2187 qdf_copy_macaddr(&ml_links->partner_link_info[ix].link_addr, 2188 &peer_entry->link_addr); 2189 ml_links->num_partner_links++; 2190 } 2191 mlo_peer_lock_release(ml_peer); 2192 } 2193 2194 qdf_export_symbol(wlan_mlo_peer_get_partner_links_info); 2195 2196 #ifdef UMAC_SUPPORT_MLNAWDS 2197 bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer) 2198 { 2199 bool status = false; 2200 2201 if (!ml_peer) 2202 return status; 2203 2204 mlo_peer_lock_acquire(ml_peer); 2205 if (ml_peer->is_nawds_ml_peer) 2206 status = true; 2207 mlo_peer_lock_release(ml_peer); 2208 2209 return status; 2210 } 2211 2212 qdf_export_symbol(wlan_mlo_peer_is_nawds); 2213 #endif 2214 2215 #ifdef MESH_MODE_SUPPORT 2216 bool wlan_mlo_peer_is_mesh(struct wlan_mlo_peer_context *ml_peer) 2217 { 2218 bool status = false; 2219 2220 if (!ml_peer) 2221 return status; 2222 2223 mlo_peer_lock_acquire(ml_peer); 2224 if (ml_peer->is_mesh_ml_peer) 2225 status = true; 2226 mlo_peer_lock_release(ml_peer); 2227 2228 return status; 2229 } 2230 2231 qdf_export_symbol(wlan_mlo_peer_is_mesh); 2232 #endif 2233 2234 #ifdef UMAC_MLO_AUTH_DEFER 2235 void mlo_peer_free_auth_param(struct mlpeer_auth_params *auth_params) 2236 { 2237 if (auth_params->rs) 2238 qdf_mem_free(auth_params->rs); 2239 2240 if (auth_params->wbuf) 2241 qdf_nbuf_free(auth_params->wbuf); 2242 2243 qdf_mem_free(auth_params); 2244 } 2245 2246 QDF_STATUS mlo_peer_link_auth_defer(struct wlan_mlo_peer_context *ml_peer, 2247 struct qdf_mac_addr *link_mac, 2248 struct mlpeer_auth_params *auth_params) 2249 { 2250 uint8_t i; 2251 uint8_t free_entries = 0; 2252 struct mlpeer_auth_params *recv_auth; 2253 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2254 2255 if (!ml_peer) 2256 return status; 2257 2258 mlo_peer_lock_acquire(ml_peer); 2259 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 2260 recv_auth = ml_peer->pending_auth[i]; 2261 if (!recv_auth) { 2262 free_entries++; 2263 continue; 2264 } 2265 /* overwrite the entry with latest entry */ 2266 if (qdf_is_macaddr_equal(link_mac, &recv_auth->link_addr)) { 2267 mlo_peer_free_auth_param(recv_auth); 2268 ml_peer->pending_auth[i] = auth_params; 2269 mlo_peer_lock_release(ml_peer); 2270 2271 return QDF_STATUS_SUCCESS; 2272 } 2273 } 2274 2275 if (!free_entries) { 2276 mlo_peer_lock_release(ml_peer); 2277 return QDF_STATUS_E_FAILURE; 2278 } 2279 2280 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 2281 recv_auth = ml_peer->pending_auth[i]; 2282 if (!recv_auth) { 2283 ml_peer->pending_auth[i] = auth_params; 2284 status = QDF_STATUS_SUCCESS; 2285 break; 2286 } 2287 } 2288 mlo_peer_lock_release(ml_peer); 2289 2290 return status; 2291 } 2292 2293 bool wlan_mlo_partner_peer_delete_is_allowed(struct wlan_objmgr_peer *src_peer) 2294 { 2295 struct wlan_objmgr_vdev *vdev = NULL; 2296 struct wlan_mlo_peer_context *ml_peer; 2297 2298 vdev = wlan_peer_get_vdev(src_peer); 2299 if (!vdev) 2300 return false; 2301 2302 ml_peer = src_peer->mlo_peer_ctx; 2303 if (!wlan_peer_is_mlo(src_peer) || !ml_peer) 2304 return false; 2305 2306 if (wlan_vdev_mlme_op_flags_get(vdev, WLAN_VDEV_OP_MLO_STOP_LINK_DEL) || 2307 wlan_vdev_mlme_op_flags_get(vdev, 2308 WLAN_VDEV_OP_MLO_LINK_TBTT_COMPLETE)) { 2309 /* Single LINK MLO connection */ 2310 if (ml_peer->link_peer_cnt == 1) 2311 return false; 2312 2313 /* 2314 * If this link is primary TQM and there is no ongoing migration 2315 * from this link, then issue full disconnect. 2316 */ 2317 if ((wlan_mlo_peer_get_primary_peer_link_id(src_peer) != 2318 wlan_vdev_get_link_id(vdev)) || 2319 ml_peer->primary_umac_migration_in_progress) 2320 return false; 2321 } 2322 2323 return true; 2324 } 2325 2326 qdf_export_symbol(wlan_mlo_partner_peer_delete_is_allowed); 2327 #endif 2328 2329 QDF_STATUS wlan_mlo_validate_reassocreq(struct wlan_mlo_peer_context *ml_peer) 2330 { 2331 uint16_t i; 2332 struct wlan_mlo_link_peer_entry *peer_entry; 2333 QDF_STATUS status = QDF_STATUS_SUCCESS; 2334 2335 if (!ml_peer) { 2336 mlo_err(" ml peer is NULL"); 2337 return QDF_STATUS_E_FAILURE; 2338 } 2339 2340 mlo_peer_lock_acquire(ml_peer); 2341 2342 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 2343 peer_entry = &ml_peer->peer_list[i]; 2344 if (!peer_entry->link_peer) 2345 continue; 2346 2347 /* Check non-assoc link peer Assoc resp buf is valid 2348 * (exclude bridge peer) 2349 */ 2350 if (i && !peer_entry->assoc_rsp_buf && 2351 (wlan_peer_get_peer_type(peer_entry->link_peer) != 2352 WLAN_PEER_MLO_BRIDGE)) { 2353 status = QDF_STATUS_E_FAILURE; 2354 break; 2355 } 2356 } 2357 2358 mlo_peer_lock_release(ml_peer); 2359 2360 return status; 2361 } 2362 2363 #ifdef WLAN_WSI_STATS_SUPPORT 2364 static uint32_t 2365 wlan_mlo_psoc_get_mlo_grp_idx(struct mlo_mgr_context *mlo_mgr, 2366 uint32_t psoc_id) 2367 { 2368 struct mlo_wsi_info *wsi_info = NULL; 2369 struct mlo_wsi_psoc_grp *mlo_psoc_grp; 2370 uint8_t grp_id, i; 2371 2372 if (!mlo_mgr) 2373 return MLO_WSI_MAX_MLO_GRPS; 2374 2375 /* Retrieve the WSI link info structure */ 2376 wsi_info = mlo_mgr->wsi_info; 2377 if (!wsi_info) 2378 return MLO_WSI_MAX_MLO_GRPS; 2379 2380 for (grp_id = 0; grp_id < MLO_WSI_MAX_MLO_GRPS; grp_id++) { 2381 mlo_psoc_grp = &wsi_info->mlo_psoc_grp[grp_id]; 2382 for (i = 0; i < mlo_psoc_grp->num_psoc; i++) { 2383 if (mlo_psoc_grp->psoc_order[i] == psoc_id) 2384 return grp_id; 2385 } 2386 } 2387 2388 return MLO_WSI_MAX_MLO_GRPS; 2389 } 2390 2391 QDF_STATUS wlan_mlo_wsi_link_info_send_cmd(void) 2392 { 2393 struct mlo_mgr_context *mlo_mgr = NULL; 2394 struct mlo_wsi_info *wsi_info = NULL; 2395 struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops = NULL; 2396 struct wlan_objmgr_psoc *psoc_objmgr = NULL; 2397 struct wlan_objmgr_pdev *pdev = NULL; 2398 QDF_STATUS error = QDF_STATUS_SUCCESS; 2399 int i, j; 2400 2401 /* Retrieve the MLO manager context */ 2402 mlo_mgr = wlan_objmgr_get_mlo_ctx(); 2403 if (!mlo_mgr) 2404 return QDF_STATUS_E_INVAL; 2405 2406 /* Retrieve the WSI link info structure */ 2407 wsi_info = mlo_mgr->wsi_info; 2408 if (!wsi_info) 2409 return QDF_STATUS_E_INVAL; 2410 2411 if (wsi_info->block_wmi_cmd) { 2412 mlo_debug("WMI command is blocked"); 2413 return error; 2414 } 2415 /* 2416 * Check each PSOC if the WMI command needs to be sent 2417 * and send it for each PDEV in that PSOC 2418 */ 2419 for (i = 0; i < WLAN_OBJMGR_MAX_DEVICES; i++) { 2420 if (!wsi_info->link_stats[i].send_wmi_cmd) 2421 continue; 2422 2423 psoc_objmgr = wlan_objmgr_get_psoc_by_id(i, WLAN_MLO_MGR_ID); 2424 if (!psoc_objmgr) { 2425 mlo_err("Could not get PSOC obj for index %d", i); 2426 continue; 2427 } 2428 2429 mlo_tx_ops = &psoc_objmgr->soc_cb.tx_ops->mlo_ops; 2430 if (!mlo_tx_ops || !mlo_tx_ops->send_wsi_link_info_cmd) { 2431 mlo_err("mlo_tx_ops is null"); 2432 wlan_objmgr_psoc_release_ref(psoc_objmgr, 2433 WLAN_MLO_MGR_ID); 2434 return QDF_STATUS_E_NULL_VALUE; 2435 } 2436 2437 for (j = 0; j < psoc_objmgr->soc_objmgr.wlan_pdev_count; j++) { 2438 pdev = psoc_objmgr->soc_objmgr.wlan_pdev_list[j]; 2439 if (!pdev) 2440 continue; 2441 2442 if (mlo_tx_ops->send_wsi_link_info_cmd( 2443 pdev, &wsi_info->link_stats[i]) != 2444 QDF_STATUS_SUCCESS) { 2445 mlo_err("Could not send WMI command for PDEV %d in PSOC %d", 2446 j, i); 2447 error = QDF_STATUS_E_FAILURE; 2448 } else { 2449 wsi_info->link_stats[i].send_wmi_cmd = false; 2450 } 2451 } 2452 wlan_objmgr_psoc_release_ref(psoc_objmgr, WLAN_MLO_MGR_ID); 2453 } 2454 2455 return error; 2456 } 2457 2458 static uint32_t wlan_mlo_psoc_get_ix_in_grp(struct mlo_mgr_context *mlo_mgr, 2459 uint32_t grp_id, 2460 uint32_t prim_psoc_id) 2461 { 2462 uint32_t i; 2463 2464 if (!mlo_mgr) { 2465 mlo_err("NULL mlo_mgr"); 2466 return 0xFF; 2467 } 2468 2469 /* Iterate through the PSOC order and find the ID */ 2470 for (i = 0; i < mlo_mgr->wsi_info->mlo_psoc_grp[grp_id].num_psoc; i++) { 2471 if (mlo_mgr->wsi_info->mlo_psoc_grp[grp_id].psoc_order[i] == 2472 prim_psoc_id) { 2473 return i; 2474 } 2475 } 2476 2477 return 0xFF; 2478 } 2479 2480 static uint32_t 2481 wlan_mlo_get_wsi_next_psoc(struct mlo_wsi_psoc_grp *mlo_psoc_grp, 2482 uint32_t prim_psoc_id, uint32_t n) 2483 { 2484 uint32_t i, j; 2485 uint32_t psoc_index = MLO_WSI_PSOC_ID_MAX; 2486 2487 if (!n) 2488 return psoc_index; 2489 2490 for (i = 0; i < mlo_psoc_grp->num_psoc; i++) { 2491 if (mlo_psoc_grp->psoc_order[i] == prim_psoc_id) { 2492 psoc_index = i; 2493 break; 2494 } 2495 } 2496 2497 if (psoc_index == MLO_WSI_PSOC_ID_MAX) 2498 return psoc_index; 2499 2500 for (i = 1; i <= WLAN_OBJMGR_MAX_DEVICES; i++) { 2501 j = (psoc_index + i) % WLAN_OBJMGR_MAX_DEVICES; 2502 if (mlo_psoc_grp->psoc_order[j] != MLO_WSI_PSOC_ID_MAX) 2503 n--; 2504 if (!n) 2505 return mlo_psoc_grp->psoc_order[j]; 2506 } 2507 2508 return MLO_WSI_PSOC_ID_MAX; 2509 } 2510 2511 static QDF_STATUS 2512 wlan_mlo_peer_wsi_link_update(struct wlan_mlo_peer_context *ml_peer, bool add) 2513 { 2514 struct mlo_mgr_context *mlo_mgr = NULL; 2515 struct mlo_wsi_info *wsi_info = NULL; 2516 struct wlan_mlo_link_peer_entry *peer_entry = NULL; 2517 uint32_t prim_psoc_id = 0xFF; 2518 uint32_t sec_psoc_id[MAX_MLO_LINK_PEERS] = {0xFF}; 2519 uint32_t hops, hop_id; 2520 uint32_t prim_grp_idx, sec_grp_idx; 2521 uint32_t prim_psoc_ix_grp, sec_psoc_ix_grp; 2522 uint32_t i, j, n; 2523 struct mlo_wsi_psoc_grp *mlo_psoc_grp; 2524 struct wlan_objmgr_psoc *psoc; 2525 2526 /* Check if ml_peer is valid */ 2527 if (!ml_peer) { 2528 mlo_err("ML peer is null"); 2529 return QDF_STATUS_E_INVAL; 2530 } 2531 2532 /* Retrieve the MLO manager context */ 2533 mlo_mgr = wlan_objmgr_get_mlo_ctx(); 2534 if (!mlo_mgr) { 2535 mlo_err("ML MGR is NULL for ML peer" QDF_MAC_ADDR_FMT, 2536 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 2537 return QDF_STATUS_E_INVAL; 2538 } 2539 2540 /* Retrieve the WSI link info structure */ 2541 wsi_info = mlo_mgr->wsi_info; 2542 if (!wsi_info) { 2543 mlo_err("WSI Info is NULL for ML peer" QDF_MAC_ADDR_FMT, 2544 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 2545 return QDF_STATUS_E_INVAL; 2546 } 2547 2548 prim_psoc_id = ml_peer->primary_umac_psoc_id; 2549 /* Populate the primary PSOC ID of the respective group */ 2550 prim_grp_idx = wlan_mlo_psoc_get_mlo_grp_idx(mlo_mgr, prim_psoc_id); 2551 if (prim_grp_idx == MLO_WSI_MAX_MLO_GRPS) { 2552 mlo_err("Group index is invalid for ML peer" QDF_MAC_ADDR_FMT, 2553 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 2554 return QDF_STATUS_E_INVAL; 2555 } 2556 2557 /* Populate MLO primary and secondary link */ 2558 for (i = 0, j = 0; i < MAX_MLO_LINK_PEERS; i++) { 2559 peer_entry = &ml_peer->peer_list[i]; 2560 if (!peer_entry->link_peer) { 2561 mlo_debug("link peer is null"); 2562 continue; 2563 } 2564 2565 psoc = wlan_peer_get_psoc(peer_entry->link_peer); 2566 if (!mlo_get_wsi_stats_info_support(psoc)) { 2567 mlo_debug("WSI stats support is not enabled on psoc %d", 2568 wlan_psoc_get_id(psoc)); 2569 return QDF_STATUS_E_INVAL; 2570 } 2571 2572 /* 2573 * Consider all non-primary peers as secondary links. 2574 * Additionally, consider all active peers as secondary link if 2575 * the TQM is on another PSOC with bridge peer. 2576 */ 2577 if (!peer_entry->is_primary) { 2578 sec_psoc_id[j] = wlan_vdev_get_psoc_id( 2579 wlan_peer_get_vdev( 2580 peer_entry->link_peer)); 2581 2582 sec_grp_idx = wlan_mlo_psoc_get_mlo_grp_idx 2583 (mlo_mgr, 2584 sec_psoc_id[j]); 2585 if (sec_grp_idx != prim_grp_idx) { 2586 mlo_err("Secondary link is not part of same MLO group as primary link"); 2587 continue; 2588 } 2589 j++; 2590 } 2591 } 2592 2593 /* 2594 * Logic for finding ingress and egress stats: 2595 * For a given MLO group, there is a PSOC order 2596 * 2597 * If there is secondary link, Increment the egress count for 2598 * the primary PSOC 2599 * (1) Iterate through each secondary link 2600 * (1.1) Set the WMI command to true for that PSOC 2601 * (1.2) Calculate the number of hops from the secondary link 2602 * to that primary link within the group. 2603 * (1.3) Iterate through a decrement sequence from the hop_count 2604 * (1.3.1) Increment the ingress count for that PSOC index 2605 */ 2606 prim_psoc_ix_grp = wlan_mlo_psoc_get_ix_in_grp(mlo_mgr, prim_grp_idx, 2607 prim_psoc_id); 2608 2609 wsi_info->link_stats[prim_psoc_id].send_wmi_cmd = true; 2610 mlo_psoc_grp = &wsi_info->mlo_psoc_grp[prim_grp_idx]; 2611 2612 if (j) { 2613 wsi_info->link_stats[prim_psoc_id].send_wmi_cmd = true; 2614 if (add) 2615 wsi_info->link_stats[prim_psoc_id].egress_cnt++; 2616 else 2617 wsi_info->link_stats[prim_psoc_id].egress_cnt--; 2618 } 2619 2620 n = 1; 2621 for (i = 0; i < j; i++) { 2622 sec_psoc_ix_grp = wlan_mlo_psoc_get_ix_in_grp(mlo_mgr, 2623 prim_grp_idx, 2624 sec_psoc_id[i]); 2625 hops = qdf_min(mlo_psoc_grp->num_psoc - 2626 (prim_psoc_ix_grp - sec_psoc_ix_grp), 2627 (sec_psoc_ix_grp - prim_psoc_ix_grp)); 2628 2629 2630 if (hops > n) { 2631 hop_id = wlan_mlo_get_wsi_next_psoc(mlo_psoc_grp, 2632 prim_psoc_id, n); 2633 n++; 2634 if (hop_id == MLO_WSI_PSOC_ID_MAX) 2635 continue; 2636 2637 wsi_info->link_stats[hop_id].send_wmi_cmd = true; 2638 if (add) 2639 wsi_info->link_stats[hop_id].ingress_cnt++; 2640 else 2641 wsi_info->link_stats[hop_id].ingress_cnt--; 2642 } 2643 } 2644 2645 /* Check if WMI bit is set, if yes, then send the command */ 2646 if (wlan_mlo_wsi_link_info_send_cmd() != QDF_STATUS_SUCCESS) { 2647 mlo_err("WSI link info not sent for ML peer" QDF_MAC_ADDR_FMT, 2648 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 2649 return QDF_STATUS_E_FAILURE; 2650 } 2651 2652 return QDF_STATUS_SUCCESS; 2653 } 2654 2655 QDF_STATUS wlan_mlo_peer_wsi_link_add(struct wlan_mlo_peer_context *ml_peer) 2656 { 2657 if (!ml_peer) { 2658 mlo_err("Invalid peer"); 2659 return QDF_STATUS_E_INVAL; 2660 } 2661 2662 return wlan_mlo_peer_wsi_link_update(ml_peer, 1); 2663 } 2664 2665 QDF_STATUS wlan_mlo_peer_wsi_link_delete(struct wlan_mlo_peer_context *ml_peer) 2666 { 2667 if (!ml_peer) { 2668 mlo_err("Invalid peer"); 2669 return QDF_STATUS_E_INVAL; 2670 } 2671 2672 return wlan_mlo_peer_wsi_link_update(ml_peer, 0); 2673 } 2674 2675 void wlan_mlo_wsi_stats_block_cmd(void) 2676 { 2677 struct mlo_mgr_context *mlo_mgr = NULL; 2678 struct mlo_wsi_info *wsi_info = NULL; 2679 2680 /* Retrieve the MLO manager context */ 2681 mlo_mgr = wlan_objmgr_get_mlo_ctx(); 2682 if (!mlo_mgr) 2683 return; 2684 2685 /* Retrieve the WSI link info structure */ 2686 wsi_info = mlo_mgr->wsi_info; 2687 if (!wsi_info) 2688 return; 2689 2690 wsi_info->block_wmi_cmd++; 2691 } 2692 2693 void wlan_mlo_wsi_stats_allow_cmd(void) 2694 { 2695 struct mlo_mgr_context *mlo_mgr = NULL; 2696 struct mlo_wsi_info *wsi_info = NULL; 2697 2698 /* Retrieve the MLO manager context */ 2699 mlo_mgr = wlan_objmgr_get_mlo_ctx(); 2700 if (!mlo_mgr) 2701 return; 2702 2703 /* Retrieve the WSI link info structure */ 2704 wsi_info = mlo_mgr->wsi_info; 2705 if (!wsi_info) 2706 return; 2707 2708 if (wsi_info->block_wmi_cmd) 2709 wsi_info->block_wmi_cmd--; 2710 } 2711 2712 #else 2713 void wlan_mlo_wsi_stats_block_cmd(void) 2714 { 2715 } 2716 2717 void wlan_mlo_wsi_stats_allow_cmd(void) 2718 { 2719 } 2720 2721 QDF_STATUS wlan_mlo_wsi_link_info_send_cmd(void) 2722 { 2723 return QDF_STATUS_SUCCESS; 2724 } 2725 2726 QDF_STATUS wlan_mlo_peer_wsi_link_add(struct wlan_mlo_peer_context *ml_peer) 2727 { 2728 return QDF_STATUS_SUCCESS; 2729 } 2730 2731 QDF_STATUS wlan_mlo_peer_wsi_link_delete(struct wlan_mlo_peer_context *ml_peer) 2732 { 2733 return QDF_STATUS_SUCCESS; 2734 } 2735 #endif 2736 2737 void wlan_mlo_ap_vdev_add_assoc_entry(struct wlan_objmgr_vdev *vdev, 2738 struct qdf_mac_addr *mld_addr) 2739 { 2740 struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx; 2741 struct wlan_mlo_sta_assoc_pending_list *assoc_list; 2742 struct wlan_mlo_sta_entry *sta_entry = NULL; 2743 2744 if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev)) 2745 return; 2746 2747 assoc_list = &mld_ctx->ap_ctx->assoc_list; 2748 2749 sta_entry = wlan_mlo_ap_vdev_find_assoc_entry(vdev, mld_addr); 2750 if (sta_entry) { 2751 mlo_err("Duplicate entry " QDF_MAC_ADDR_FMT, 2752 QDF_MAC_ADDR_REF(mld_addr->bytes)); 2753 return; 2754 } 2755 2756 sta_entry = qdf_mem_malloc(sizeof(*sta_entry)); 2757 if (!sta_entry) 2758 return; 2759 2760 qdf_copy_macaddr((struct qdf_mac_addr *)&sta_entry->peer_mld_addr, 2761 (struct qdf_mac_addr *)&mld_addr[0]); 2762 2763 qdf_spin_lock_bh(&assoc_list->list_lock); 2764 qdf_list_insert_back(&assoc_list->peer_list, &sta_entry->mac_node); 2765 qdf_spin_unlock_bh(&assoc_list->list_lock); 2766 } 2767 2768 void wlan_mlo_ap_vdev_del_assoc_entry(struct wlan_objmgr_vdev *vdev, 2769 struct qdf_mac_addr *mld_addr) 2770 { 2771 struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx; 2772 struct wlan_mlo_sta_assoc_pending_list *assoc_list; 2773 struct wlan_mlo_sta_entry *sta_entry = NULL; 2774 2775 if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev)) 2776 return; 2777 2778 assoc_list = &mld_ctx->ap_ctx->assoc_list; 2779 sta_entry = wlan_mlo_ap_vdev_find_assoc_entry(vdev, mld_addr); 2780 if (!sta_entry) 2781 return; 2782 2783 qdf_spin_lock_bh(&assoc_list->list_lock); 2784 qdf_list_remove_node(&assoc_list->peer_list, &sta_entry->mac_node); 2785 qdf_spin_unlock_bh(&assoc_list->list_lock); 2786 2787 qdf_mem_free(sta_entry); 2788 } 2789 2790 static inline struct wlan_mlo_sta_entry * 2791 wlan_mlo_assoc_list_peek_head(qdf_list_t *assoc_list) 2792 { 2793 struct wlan_mlo_sta_entry *sta_entry = NULL; 2794 qdf_list_node_t *list_node = NULL; 2795 2796 /* This API is invoked with lock acquired, do not add log prints */ 2797 if (qdf_list_peek_front(assoc_list, &list_node) != QDF_STATUS_SUCCESS) 2798 return NULL; 2799 2800 sta_entry = qdf_container_of(list_node, 2801 struct wlan_mlo_sta_entry, mac_node); 2802 return sta_entry; 2803 } 2804 2805 static inline struct wlan_mlo_sta_entry * 2806 wlan_mlo_sta_get_next_sta_entry(qdf_list_t *assoc_list, 2807 struct wlan_mlo_sta_entry *sta_entry) 2808 { 2809 struct wlan_mlo_sta_entry *next_sta_entry = NULL; 2810 qdf_list_node_t *node = &sta_entry->mac_node; 2811 qdf_list_node_t *next_node = NULL; 2812 2813 /* This API is invoked with lock acquired, do not add log prints */ 2814 if (!node) 2815 return NULL; 2816 2817 if (qdf_list_peek_next(assoc_list, node, &next_node) != 2818 QDF_STATUS_SUCCESS) 2819 return NULL; 2820 2821 next_sta_entry = qdf_container_of(next_node, 2822 struct wlan_mlo_sta_entry, mac_node); 2823 return next_sta_entry; 2824 } 2825 2826 struct wlan_mlo_sta_entry * 2827 wlan_mlo_ap_vdev_find_assoc_entry(struct wlan_objmgr_vdev *vdev, 2828 struct qdf_mac_addr *mld_addr) 2829 { 2830 struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx; 2831 struct wlan_mlo_sta_assoc_pending_list *assoc_list; 2832 struct wlan_mlo_sta_entry *sta_entry = NULL; 2833 struct wlan_mlo_sta_entry *next_sta_entry = NULL; 2834 2835 if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev)) 2836 return NULL; 2837 2838 assoc_list = &mld_ctx->ap_ctx->assoc_list; 2839 if (qdf_list_empty(&assoc_list->peer_list)) { 2840 mlo_info("list is empty"); 2841 return NULL; 2842 } 2843 qdf_spin_lock_bh(&assoc_list->list_lock); 2844 2845 sta_entry = wlan_mlo_assoc_list_peek_head(&assoc_list->peer_list); 2846 while (sta_entry) { 2847 if (qdf_is_macaddr_equal(&sta_entry->peer_mld_addr, mld_addr)) { 2848 qdf_spin_unlock_bh(&assoc_list->list_lock); 2849 return sta_entry; 2850 } 2851 2852 next_sta_entry = 2853 wlan_mlo_sta_get_next_sta_entry(&assoc_list->peer_list, 2854 sta_entry); 2855 sta_entry = next_sta_entry; 2856 } 2857 qdf_spin_unlock_bh(&assoc_list->list_lock); 2858 2859 return NULL; 2860 } 2861 2862