1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #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 28 static void mlo_partner_peer_create_post(struct wlan_mlo_dev_context *ml_dev, 29 struct wlan_objmgr_vdev *vdev_link, 30 struct wlan_mlo_peer_context *ml_peer, 31 qdf_nbuf_t frm_buf, 32 struct mlo_partner_info *ml_info) 33 { 34 struct peer_create_notif_s peer_create; 35 QDF_STATUS status; 36 uint8_t i; 37 uint8_t link_id; 38 39 if (wlan_objmgr_vdev_try_get_ref(vdev_link, WLAN_MLO_MGR_ID) == 40 QDF_STATUS_SUCCESS) { 41 peer_create.vdev_link = vdev_link; 42 } else { 43 mlo_err("VDEV is not in created state"); 44 return; 45 } 46 47 wlan_mlo_peer_get_ref(ml_peer); 48 peer_create.ml_peer = ml_peer; 49 link_id = wlan_vdev_get_link_id(vdev_link); 50 for (i = 0; i < ml_info->num_partner_links; i++) { 51 if (link_id != ml_info->partner_link_info[i].link_id) 52 continue; 53 54 qdf_copy_macaddr(&peer_create.addr, 55 &ml_info->partner_link_info[i].link_addr); 56 break; 57 } 58 59 status = mlo_peer_create_get_frm_buf(ml_peer, &peer_create, frm_buf); 60 61 if (QDF_IS_STATUS_ERROR(status)) { 62 wlan_mlo_peer_release_ref(ml_peer); 63 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 64 mlo_err("nbuf clone is failed"); 65 return; 66 } 67 68 status = mlo_msgq_post(MLO_PEER_CREATE, ml_dev, &peer_create); 69 if (status != QDF_STATUS_SUCCESS) { 70 qdf_nbuf_free(frm_buf); 71 wlan_mlo_peer_release_ref(ml_peer); 72 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 73 } 74 } 75 76 static void mlo_link_peer_assoc_notify(struct wlan_mlo_dev_context *ml_dev, 77 struct wlan_objmgr_peer *peer) 78 { 79 struct peer_assoc_notify_s peer_assoc; 80 QDF_STATUS status; 81 82 peer_assoc.peer = peer; 83 status = mlo_msgq_post(MLO_PEER_ASSOC, ml_dev, &peer_assoc); 84 if (status != QDF_STATUS_SUCCESS) 85 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 86 } 87 88 static void mlo_link_peer_send_assoc_fail(struct wlan_mlo_dev_context *ml_dev, 89 struct wlan_objmgr_peer *peer) 90 { 91 struct peer_assoc_fail_notify_s peer_assoc_fail; 92 QDF_STATUS status; 93 94 peer_assoc_fail.peer = peer; 95 status = mlo_msgq_post(MLO_PEER_ASSOC_FAIL, ml_dev, &peer_assoc_fail); 96 if (status != QDF_STATUS_SUCCESS) 97 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 98 } 99 100 static void mlo_link_peer_disconnect_notify(struct wlan_mlo_dev_context *ml_dev, 101 struct wlan_objmgr_peer *peer) 102 { 103 struct peer_discon_notify_s peer_disconn; 104 QDF_STATUS status; 105 struct wlan_objmgr_vdev *vdev; 106 enum QDF_OPMODE opmode; 107 108 vdev = wlan_peer_get_vdev(peer); 109 opmode = wlan_vdev_mlme_get_opmode(vdev); 110 111 if (opmode == QDF_SAP_MODE) { 112 peer_disconn.peer = peer; 113 status = mlo_msgq_post(MLO_PEER_DISCONNECT, ml_dev, 114 &peer_disconn); 115 if (status != QDF_STATUS_SUCCESS) 116 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 117 } else { 118 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 119 } 120 } 121 122 static void mlo_link_peer_deauth_init(struct wlan_mlo_dev_context *ml_dev, 123 struct wlan_objmgr_peer *peer) 124 { 125 struct peer_deauth_notify_s peer_deauth; 126 QDF_STATUS status; 127 128 peer_deauth.peer = peer; 129 status = mlo_msgq_post(MLO_PEER_DEAUTH, ml_dev, &peer_deauth); 130 if (status != QDF_STATUS_SUCCESS) 131 wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID); 132 } 133 134 #ifdef UMAC_MLO_AUTH_DEFER 135 static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev, 136 struct wlan_mlo_peer_context *ml_peer) 137 { 138 struct peer_auth_process_notif_s peer_auth; 139 struct mlpeer_auth_params *recv_auth; 140 uint8_t i; 141 QDF_STATUS status; 142 143 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 144 mlo_peer_lock_acquire(ml_peer); 145 recv_auth = ml_peer->pending_auth[i]; 146 if (!recv_auth) { 147 mlo_peer_lock_release(ml_peer); 148 continue; 149 } 150 peer_auth.auth_params = recv_auth; 151 ml_peer->pending_auth[i] = NULL; 152 153 mlo_peer_lock_release(ml_peer); 154 155 status = mlo_msgq_post(MLO_PEER_PENDING_AUTH, ml_dev, 156 &peer_auth); 157 if (QDF_IS_STATUS_ERROR(status)) 158 mlo_peer_free_auth_param(peer_auth.auth_params); 159 } 160 } 161 #else 162 static void mlo_peer_process_pending_auth(struct wlan_mlo_dev_context *ml_dev, 163 struct wlan_mlo_peer_context *ml_peer) 164 { 165 } 166 #endif 167 168 QDF_STATUS 169 wlan_mlo_peer_is_disconnect_progress(struct wlan_mlo_peer_context *ml_peer) 170 { 171 QDF_STATUS status; 172 173 if (!ml_peer) 174 return QDF_STATUS_E_FAILURE; 175 176 mlo_peer_lock_acquire(ml_peer); 177 178 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) 179 status = QDF_STATUS_SUCCESS; 180 else 181 status = QDF_STATUS_E_FAILURE; 182 183 mlo_peer_lock_release(ml_peer); 184 185 return status; 186 } 187 188 QDF_STATUS wlan_mlo_peer_is_assoc_done(struct wlan_mlo_peer_context *ml_peer) 189 { 190 QDF_STATUS status; 191 192 if (!ml_peer) 193 return QDF_STATUS_E_FAILURE; 194 195 mlo_peer_lock_acquire(ml_peer); 196 197 if (ml_peer->mlpeer_state == ML_PEER_ASSOC_DONE) 198 status = QDF_STATUS_SUCCESS; 199 else 200 status = QDF_STATUS_E_FAILURE; 201 202 mlo_peer_lock_release(ml_peer); 203 204 return status; 205 } 206 207 struct wlan_objmgr_peer *wlan_mlo_peer_get_assoc_peer( 208 struct wlan_mlo_peer_context *ml_peer) 209 { 210 struct wlan_mlo_link_peer_entry *peer_entry; 211 struct wlan_objmgr_peer *assoc_peer = NULL; 212 213 if (!ml_peer) 214 return NULL; 215 216 mlo_peer_lock_acquire(ml_peer); 217 218 peer_entry = &ml_peer->peer_list[0]; 219 220 if (peer_entry->link_peer) 221 assoc_peer = peer_entry->link_peer; 222 223 mlo_peer_lock_release(ml_peer); 224 225 return assoc_peer; 226 } 227 228 bool mlo_peer_is_assoc_peer(struct wlan_mlo_peer_context *ml_peer, 229 struct wlan_objmgr_peer *peer) 230 { 231 struct wlan_mlo_link_peer_entry *peer_entry; 232 bool is_assoc_peer = false; 233 234 if (!ml_peer || !peer) 235 return is_assoc_peer; 236 237 peer_entry = &ml_peer->peer_list[0]; 238 239 if (peer_entry->link_peer != peer) 240 is_assoc_peer = true; 241 242 return is_assoc_peer; 243 } 244 245 bool wlan_mlo_peer_is_assoc_peer(struct wlan_mlo_peer_context *ml_peer, 246 struct wlan_objmgr_peer *peer) 247 { 248 bool is_assoc_peer = false; 249 250 if (!ml_peer || !peer) 251 return is_assoc_peer; 252 253 mlo_peer_lock_acquire(ml_peer); 254 255 is_assoc_peer = mlo_peer_is_assoc_peer(ml_peer, peer); 256 257 mlo_peer_lock_release(ml_peer); 258 259 return is_assoc_peer; 260 } 261 262 void wlan_mlo_partner_peer_assoc_post(struct wlan_objmgr_peer *assoc_peer) 263 { 264 struct wlan_mlo_dev_context *ml_dev; 265 struct wlan_mlo_peer_context *ml_peer; 266 struct wlan_objmgr_peer *link_peer; 267 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 268 struct wlan_mlo_link_peer_entry *peer_entry; 269 uint16_t i; 270 271 ml_peer = assoc_peer->mlo_peer_ctx; 272 if (!ml_peer) 273 return; 274 275 mlo_peer_lock_acquire(ml_peer); 276 277 if (ml_peer->mlpeer_state != ML_PEER_CREATED) { 278 mlo_peer_lock_release(ml_peer); 279 return; 280 } 281 282 ml_peer->mlpeer_state = ML_PEER_ASSOC_DONE; 283 ml_dev = ml_peer->ml_dev; 284 285 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 286 link_peers[i] = NULL; 287 peer_entry = &ml_peer->peer_list[i]; 288 289 if (!peer_entry->link_peer) 290 continue; 291 292 if (peer_entry->link_peer == assoc_peer) 293 continue; 294 295 link_peer = peer_entry->link_peer; 296 297 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 298 QDF_STATUS_SUCCESS) 299 continue; 300 301 link_peers[i] = link_peer; 302 } 303 mlo_peer_lock_release(ml_peer); 304 305 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 306 if (!link_peers[i]) 307 continue; 308 309 /* Prepare and queue message */ 310 mlo_link_peer_assoc_notify(ml_dev, link_peers[i]); 311 } 312 } 313 314 void 315 wlan_mlo_peer_deauth_init(struct wlan_mlo_peer_context *ml_peer) 316 { 317 struct wlan_mlo_dev_context *ml_dev; 318 struct wlan_objmgr_peer *link_peer; 319 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 320 struct wlan_mlo_link_peer_entry *peer_entry; 321 uint16_t i; 322 323 if (!ml_peer) 324 return; 325 326 mlo_peer_lock_acquire(ml_peer); 327 328 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 329 mlo_peer_lock_release(ml_peer); 330 return; 331 } 332 333 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 334 ml_dev = ml_peer->ml_dev; 335 336 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 337 link_peers[i] = NULL; 338 peer_entry = &ml_peer->peer_list[i]; 339 if (!peer_entry->link_peer) 340 continue; 341 342 link_peer = peer_entry->link_peer; 343 /* Skip Deauth if PMF is enabled for the station */ 344 if ((i == 0) && 345 (wlan_crypto_is_pmf_enabled(wlan_peer_get_vdev(link_peer), 346 link_peer))) { 347 mlo_peer_lock_release(ml_peer); 348 return; 349 } 350 351 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 352 QDF_STATUS_SUCCESS) 353 continue; 354 355 link_peers[i] = link_peer; 356 } 357 mlo_peer_lock_release(ml_peer); 358 359 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 360 if (!link_peers[i]) 361 continue; 362 363 /* Prepare and queue message */ 364 if (i == 0) 365 mlo_link_peer_deauth_init(ml_dev, link_peers[i]); 366 else 367 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 368 } 369 370 return; 371 } 372 373 void 374 wlan_mlo_partner_peer_create_failed_notify( 375 struct wlan_mlo_peer_context *ml_peer) 376 { 377 struct wlan_mlo_dev_context *ml_dev; 378 struct wlan_objmgr_peer *link_peer; 379 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 380 struct wlan_mlo_link_peer_entry *peer_entry; 381 uint16_t i; 382 383 if (!ml_peer) 384 return; 385 386 mlo_peer_lock_acquire(ml_peer); 387 388 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 389 mlo_peer_lock_release(ml_peer); 390 return; 391 } 392 393 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 394 ml_dev = ml_peer->ml_dev; 395 396 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 397 link_peers[i] = NULL; 398 peer_entry = &ml_peer->peer_list[i]; 399 if (!peer_entry->link_peer) 400 continue; 401 402 link_peer = peer_entry->link_peer; 403 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 404 QDF_STATUS_SUCCESS) 405 continue; 406 407 link_peers[i] = link_peer; 408 } 409 mlo_peer_lock_release(ml_peer); 410 411 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 412 if (!link_peers[i]) 413 continue; 414 415 /* Prepare and queue message */ 416 if (i == 0) 417 mlo_link_peer_send_assoc_fail(ml_dev, link_peers[i]); 418 else 419 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 420 } 421 } 422 423 void wlan_mlo_partner_peer_disconnect_notify(struct wlan_objmgr_peer *src_peer) 424 { 425 struct wlan_mlo_dev_context *ml_dev; 426 struct wlan_mlo_peer_context *ml_peer; 427 struct wlan_objmgr_peer *link_peer; 428 struct wlan_objmgr_peer *link_peers[MAX_MLO_LINK_PEERS]; 429 struct wlan_mlo_link_peer_entry *peer_entry; 430 struct wlan_objmgr_vdev *vdev = NULL; 431 uint16_t i; 432 433 ml_peer = src_peer->mlo_peer_ctx; 434 if (!ml_peer) 435 return; 436 437 mlo_peer_lock_acquire(ml_peer); 438 439 if (ml_peer->mlpeer_state == ML_PEER_DISCONN_INITIATED) { 440 mlo_peer_lock_release(ml_peer); 441 return; 442 } 443 444 ml_peer->mlpeer_state = ML_PEER_DISCONN_INITIATED; 445 446 vdev = wlan_peer_get_vdev(src_peer); 447 if (!vdev || wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) { 448 mlo_peer_lock_release(ml_peer); 449 return; 450 } 451 452 ml_dev = ml_peer->ml_dev; 453 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 454 link_peers[i] = NULL; 455 peer_entry = &ml_peer->peer_list[i]; 456 if (!peer_entry->link_peer) { 457 mlo_debug("link peer is null"); 458 continue; 459 } 460 461 if (peer_entry->link_peer == src_peer) 462 continue; 463 464 link_peer = peer_entry->link_peer; 465 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 466 QDF_STATUS_SUCCESS) 467 continue; 468 469 link_peers[i] = link_peer; 470 } 471 mlo_peer_lock_release(ml_peer); 472 473 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 474 if (!link_peers[i]) 475 continue; 476 477 /* Prepare and queue message */ 478 mlo_link_peer_disconnect_notify(ml_dev, link_peers[i]); 479 } 480 } 481 482 static void mlo_peer_populate_link_peer( 483 struct wlan_mlo_peer_context *ml_peer, 484 struct wlan_objmgr_peer *link_peer) 485 { 486 mlo_peer_lock_acquire(ml_peer); 487 wlan_mlo_peer_get_ref(ml_peer); 488 link_peer->mlo_peer_ctx = ml_peer; 489 mlo_peer_lock_release(ml_peer); 490 } 491 492 static void mlo_reset_link_peer( 493 struct wlan_mlo_peer_context *ml_peer, 494 struct wlan_objmgr_peer *link_peer) 495 { 496 mlo_peer_lock_acquire(ml_peer); 497 link_peer->mlo_peer_ctx = NULL; 498 wlan_peer_clear_mlo(link_peer); 499 mlo_peer_lock_release(ml_peer); 500 } 501 502 static void mlo_peer_free(struct wlan_mlo_peer_context *ml_peer) 503 { 504 struct wlan_mlo_dev_context *ml_dev; 505 506 ml_dev = ml_peer->ml_dev; 507 if (!ml_dev) { 508 mlo_err("ML DEV is NULL"); 509 return; 510 } 511 512 mlo_peer_lock_destroy(ml_peer); 513 mlo_ap_ml_peerid_free(ml_peer->mlo_peer_id); 514 mlo_peer_free_aid(ml_dev, ml_peer); 515 mlo_peer_free_primary_umac(ml_dev, ml_peer); 516 qdf_mem_free(ml_peer); 517 } 518 519 void mlo_peer_cleanup(struct wlan_mlo_peer_context *ml_peer) 520 { 521 struct wlan_mlo_dev_context *ml_dev; 522 523 if (!ml_peer) { 524 mlo_err("ML PEER is NULL"); 525 return; 526 } 527 ml_dev = ml_peer->ml_dev; 528 if (!ml_dev) { 529 mlo_err("ML DEV is NULL"); 530 return; 531 } 532 533 mlo_dev_mlpeer_detach(ml_dev, ml_peer); 534 /* If any Auth req is received during ML peer delete */ 535 mlo_peer_process_pending_auth(ml_dev, ml_peer); 536 mlo_peer_free(ml_peer); 537 } 538 539 static QDF_STATUS mlo_peer_attach_link_peer( 540 struct wlan_mlo_peer_context *ml_peer, 541 struct wlan_objmgr_peer *link_peer, 542 qdf_nbuf_t frm_buf) 543 { 544 struct wlan_mlo_link_peer_entry *peer_entry; 545 QDF_STATUS status = QDF_STATUS_E_RESOURCES; 546 struct wlan_objmgr_pdev *pdev; 547 struct wlan_objmgr_vdev *vdev; 548 uint16_t i; 549 550 if (!link_peer) 551 return QDF_STATUS_E_FAILURE; 552 553 vdev = wlan_peer_get_vdev(link_peer); 554 if (!vdev) 555 return QDF_STATUS_E_FAILURE; 556 557 mlo_peer_lock_acquire(ml_peer); 558 559 if (ml_peer->mlpeer_state != ML_PEER_CREATED) { 560 mlo_peer_lock_release(ml_peer); 561 mlo_err("ML Peer " QDF_MAC_ADDR_FMT " is not in created state (state %d)", 562 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 563 ml_peer->mlpeer_state); 564 return status; 565 } 566 567 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 568 peer_entry = &ml_peer->peer_list[i]; 569 if (peer_entry->link_peer) 570 continue; 571 572 if (wlan_objmgr_peer_try_get_ref(link_peer, WLAN_MLO_MGR_ID) != 573 QDF_STATUS_SUCCESS) { 574 mlo_err("ML Peer " QDF_MAC_ADDR_FMT ", link peer " QDF_MAC_ADDR_FMT " is not in valid state", 575 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 576 QDF_MAC_ADDR_REF 577 (wlan_peer_get_macaddr(link_peer))); 578 break; 579 } 580 peer_entry->link_peer = link_peer; 581 qdf_copy_macaddr(&peer_entry->link_addr, 582 (struct qdf_mac_addr *)&link_peer->macaddr[0]); 583 584 peer_entry->link_ix = wlan_vdev_get_link_id(vdev); 585 pdev = wlan_vdev_get_pdev(wlan_peer_get_vdev(link_peer)); 586 peer_entry->hw_link_id = wlan_mlo_get_pdev_hw_link_id(pdev); 587 mlo_peer_assign_primary_umac(ml_peer, peer_entry); 588 if (frm_buf) 589 peer_entry->assoc_rsp_buf = frm_buf; 590 else 591 peer_entry->assoc_rsp_buf = NULL; 592 593 status = QDF_STATUS_SUCCESS; 594 break; 595 } 596 if (QDF_IS_STATUS_SUCCESS(status)) 597 ml_peer->link_peer_cnt++; 598 599 mlo_peer_lock_release(ml_peer); 600 601 return status; 602 } 603 604 qdf_nbuf_t mlo_peer_get_link_peer_assoc_resp_buf( 605 struct wlan_mlo_peer_context *ml_peer, 606 uint8_t link_ix) 607 { 608 struct wlan_mlo_link_peer_entry *peer_entry; 609 qdf_nbuf_t frm_buf = NULL; 610 uint8_t i; 611 612 if (!ml_peer) 613 return NULL; 614 615 if (link_ix > MAX_MLO_LINK_PEERS) 616 return NULL; 617 618 mlo_peer_lock_acquire(ml_peer); 619 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 620 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 621 mlo_peer_lock_release(ml_peer); 622 return NULL; 623 } 624 625 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 626 peer_entry = &ml_peer->peer_list[i]; 627 628 if (!peer_entry->link_peer) 629 continue; 630 631 if (peer_entry->link_ix == link_ix) { 632 frm_buf = qdf_nbuf_clone(peer_entry->assoc_rsp_buf); 633 break; 634 } 635 } 636 mlo_peer_lock_release(ml_peer); 637 638 return frm_buf; 639 } 640 641 void wlan_mlo_peer_free_all_link_assoc_resp_buf( 642 struct wlan_objmgr_peer *link_peer) 643 { 644 struct wlan_mlo_link_peer_entry *peer_entry; 645 struct wlan_mlo_peer_context *ml_peer; 646 uint8_t i; 647 648 ml_peer = link_peer->mlo_peer_ctx; 649 if (!ml_peer) 650 return; 651 652 mlo_peer_lock_acquire(ml_peer); 653 654 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 655 peer_entry = &ml_peer->peer_list[i]; 656 657 if (peer_entry->assoc_rsp_buf) { 658 qdf_nbuf_free(peer_entry->assoc_rsp_buf); 659 peer_entry->assoc_rsp_buf = NULL; 660 } 661 } 662 mlo_peer_lock_release(ml_peer); 663 } 664 665 static QDF_STATUS mlo_peer_detach_link_peer( 666 struct wlan_mlo_peer_context *ml_peer, 667 struct wlan_objmgr_peer *link_peer) 668 { 669 struct wlan_mlo_link_peer_entry *peer_entry; 670 QDF_STATUS status = QDF_STATUS_E_RESOURCES; 671 uint16_t i; 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 status; 678 } 679 680 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 681 peer_entry = &ml_peer->peer_list[i]; 682 if (!peer_entry->link_peer) 683 continue; 684 685 if (peer_entry->link_peer != link_peer) 686 continue; 687 688 if (peer_entry->assoc_rsp_buf) { 689 qdf_nbuf_free(peer_entry->assoc_rsp_buf); 690 peer_entry->assoc_rsp_buf = NULL; 691 } 692 693 wlan_objmgr_peer_release_ref(link_peer, WLAN_MLO_MGR_ID); 694 peer_entry->link_peer = NULL; 695 ml_peer->link_peer_cnt--; 696 status = QDF_STATUS_SUCCESS; 697 break; 698 } 699 mlo_peer_lock_release(ml_peer); 700 701 return status; 702 } 703 704 static QDF_STATUS mlo_dev_get_link_vdevs( 705 struct wlan_objmgr_vdev *vdev, 706 struct wlan_mlo_dev_context *ml_dev, 707 struct mlo_partner_info *ml_info, 708 struct wlan_objmgr_vdev *link_vdevs[]) 709 { 710 uint16_t i, j; 711 struct wlan_objmgr_vdev *vdev_link; 712 uint8_t link_id; 713 714 if (!ml_dev) { 715 mlo_err("ml_dev is null"); 716 return QDF_STATUS_E_INVAL; 717 } 718 719 if (!ml_info) { 720 mlo_err("ml_info is null"); 721 return QDF_STATUS_E_INVAL; 722 } 723 724 mlo_debug("num_partner_links %d", ml_info->num_partner_links); 725 for (i = 0; i < ml_info->num_partner_links; i++) { 726 link_id = ml_info->partner_link_info[i].link_id; 727 vdev_link = mlo_get_vdev_by_link_id(vdev, link_id); 728 if (vdev_link) { 729 link_vdevs[i] = vdev_link; 730 } else { 731 /* release ref which were taken before failure */ 732 for (j = 0; j < i; j++) { 733 vdev_link = link_vdevs[j]; 734 if (!vdev_link) 735 continue; 736 737 wlan_objmgr_vdev_release_ref(vdev_link, 738 WLAN_MLO_MGR_ID); 739 } 740 return QDF_STATUS_E_INVAL; 741 } 742 } 743 744 return QDF_STATUS_SUCCESS; 745 } 746 747 static void mlo_dev_release_link_vdevs( 748 struct wlan_objmgr_vdev *link_vdevs[]) 749 { 750 uint16_t i; 751 struct wlan_objmgr_vdev *vdev_link; 752 753 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 754 vdev_link = link_vdevs[i]; 755 if (!vdev_link) 756 continue; 757 758 wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID); 759 } 760 } 761 762 #ifdef WLAN_FEATURE_11BE 763 static void 764 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer, 765 struct mlo_partner_info *ml_info) 766 { 767 ml_peer->t2lm_policy.t2lm_enable_val = ml_info->t2lm_enable_val; 768 } 769 #else 770 static void 771 wlan_mlo_peer_set_t2lm_enable_val(struct wlan_mlo_peer_context *ml_peer, 772 struct mlo_partner_info *ml_info) 773 {} 774 #endif /* WLAN_FEATURE_11BE */ 775 776 QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev, 777 struct wlan_objmgr_peer *link_peer, 778 struct mlo_partner_info *ml_info, 779 qdf_nbuf_t frm_buf, 780 uint16_t aid) 781 { 782 struct wlan_mlo_dev_context *ml_dev; 783 struct wlan_mlo_peer_context *ml_peer = NULL; 784 struct wlan_objmgr_vdev *link_vdevs[WLAN_UMAC_MLO_MAX_VDEVS] = { NULL }; 785 struct wlan_objmgr_vdev *vdev_link; 786 QDF_STATUS status; 787 uint16_t i; 788 struct wlan_objmgr_peer *assoc_peer; 789 790 /* get ML VDEV from VDEV */ 791 ml_dev = vdev->mlo_dev_ctx; 792 793 if (!ml_dev) { 794 mlo_err("ML dev ctx is NULL"); 795 return QDF_STATUS_E_NULL_VALUE; 796 } 797 798 /* Check resources of Partner VDEV */ 799 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 800 if (wlan_mlo_is_mld_ctx_exist( 801 (struct qdf_mac_addr *)&link_peer->mldaddr[0])) { 802 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " is matching with one of the MLD address in the system", 803 ml_dev->mld_id, 804 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 805 return QDF_STATUS_E_FAILURE; 806 } 807 status = mlo_dev_get_link_vdevs(vdev, ml_dev, 808 ml_info, link_vdevs); 809 if (QDF_IS_STATUS_ERROR(status)) { 810 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " get link vdevs failed", 811 ml_dev->mld_id, 812 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 813 return QDF_STATUS_E_FAILURE; 814 } 815 816 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 817 vdev_link = link_vdevs[i]; 818 if (!vdev_link) { 819 mlo_debug("vdev_link is null"); 820 continue; 821 } 822 823 if (wlan_vdev_is_mlo_peer_create_allowed(vdev_link) 824 != QDF_STATUS_SUCCESS) { 825 mlo_dev_release_link_vdevs(link_vdevs); 826 827 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " create not allowed on link vdev %d", 828 ml_dev->mld_id, 829 QDF_MAC_ADDR_REF 830 (link_peer->mldaddr), 831 wlan_vdev_get_id(vdev_link)); 832 return QDF_STATUS_E_INVAL; 833 } 834 } 835 836 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 837 vdev_link = link_vdevs[i]; 838 if (vdev_link && (vdev_link != vdev) && 839 (wlan_vdev_get_peer_count(vdev_link) > 840 wlan_vdev_get_max_peer_count(vdev_link))) { 841 mlo_dev_release_link_vdevs(link_vdevs); 842 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " Max peer count reached on link vdev %d", 843 ml_dev->mld_id, 844 QDF_MAC_ADDR_REF 845 (link_peer->mldaddr), 846 wlan_vdev_get_id(vdev_link)); 847 return QDF_STATUS_E_RESOURCES; 848 } 849 } 850 } 851 852 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) 853 ml_peer = wlan_mlo_get_mlpeer(ml_dev, 854 (struct qdf_mac_addr *)&link_peer->mldaddr[0]); 855 856 if (!ml_peer) { 857 /* Allocate MLO peer */ 858 ml_peer = qdf_mem_malloc(sizeof(*ml_peer)); 859 if (!ml_peer) { 860 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " mem alloc failed", 861 ml_dev->mld_id, 862 QDF_MAC_ADDR_REF(link_peer->mldaddr)); 863 mlo_dev_release_link_vdevs(link_vdevs); 864 return QDF_STATUS_E_NOMEM; 865 } 866 867 qdf_atomic_init(&ml_peer->ref_cnt); 868 mlo_peer_lock_create(ml_peer); 869 ml_peer->ml_dev = ml_dev; 870 ml_peer->mlpeer_state = ML_PEER_CREATED; 871 ml_peer->max_links = ml_info->num_partner_links; 872 ml_peer->primary_umac_psoc_id = ML_PRIMARY_UMAC_ID_INVAL; 873 874 ml_peer->mlo_peer_id = mlo_ap_ml_peerid_alloc(); 875 if (ml_peer->mlo_peer_id == MLO_INVALID_PEER_ID) { 876 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " invalid ml peer id", 877 ml_dev->mld_id, 878 QDF_MAC_ADDR_REF 879 (ml_peer->peer_mld_addr.bytes)); 880 mlo_peer_free(ml_peer); 881 mlo_dev_release_link_vdevs(link_vdevs); 882 return QDF_STATUS_E_RESOURCES; 883 } 884 885 qdf_copy_macaddr((struct qdf_mac_addr *)&ml_peer->peer_mld_addr, 886 (struct qdf_mac_addr *)&link_peer->mldaddr[0]); 887 wlan_mlo_peer_set_t2lm_enable_val(ml_peer, ml_info); 888 889 /* Allocate AID */ 890 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 891 if (aid == (uint16_t)-1) { 892 status = mlo_peer_allocate_aid(ml_dev, ml_peer); 893 if (status != QDF_STATUS_SUCCESS) { 894 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " aid alloc failed", 895 ml_dev->mld_id, 896 QDF_MAC_ADDR_REF 897 (ml_peer->peer_mld_addr.bytes)); 898 mlo_peer_free(ml_peer); 899 mlo_dev_release_link_vdevs(link_vdevs); 900 return status; 901 } 902 } else { 903 ml_peer->assoc_id = aid; 904 } 905 } 906 } 907 908 /* Populate Link peer pointer, peer MAC address, 909 * MLD address. HW link ID, update ref count 910 */ 911 status = mlo_peer_attach_link_peer(ml_peer, link_peer, NULL); 912 if (QDF_IS_STATUS_ERROR(status)) { 913 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " link peer attach failed", 914 ml_dev->mld_id, 915 QDF_MAC_ADDR_REF 916 (ml_peer->peer_mld_addr.bytes)); 917 mlo_peer_free(ml_peer); 918 mlo_dev_release_link_vdevs(link_vdevs); 919 return status; 920 } 921 922 /* Allocate Primary UMAC */ 923 mlo_peer_allocate_primary_umac(ml_dev, ml_peer, link_vdevs); 924 925 /* Store AID, MLO Peer pointer in link peer, take link peer ref count */ 926 mlo_peer_populate_link_peer(ml_peer, link_peer); 927 928 mlo_peer_populate_nawds_params(ml_peer, ml_info); 929 930 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) || 931 ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) && 932 !wlan_vdev_mlme_is_mlo_link_vdev(vdev))) { 933 /* Attach MLO peer to ML Peer table */ 934 status = mlo_dev_mlpeer_attach(ml_dev, ml_peer); 935 if (status != QDF_STATUS_SUCCESS) { 936 mlo_err("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " attach failed", 937 ml_dev->mld_id, 938 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 939 mlo_reset_link_peer(ml_peer, link_peer); 940 wlan_objmgr_peer_release_ref(link_peer, 941 WLAN_MLO_MGR_ID); 942 mlo_peer_free(ml_peer); 943 mlo_dev_release_link_vdevs(link_vdevs); 944 return status; 945 } 946 } 947 948 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 949 /* Notify other vdevs about link peer creation */ 950 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 951 vdev_link = link_vdevs[i]; 952 if (!vdev_link) 953 continue; 954 955 if (vdev_link == vdev) 956 continue; 957 958 mlo_partner_peer_create_post(ml_dev, vdev_link, 959 ml_peer, frm_buf, ml_info); 960 } 961 } 962 mlo_dev_release_link_vdevs(link_vdevs); 963 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " allocated %pK", 964 ml_dev->mld_id, 965 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), 966 ml_peer); 967 968 /* 969 * wlan_mlo_peer_create() is trigggered after getting peer 970 * assoc confirm from FW. For single link MLO connection, it is 971 * OK to trigger assoc response from here. 972 */ 973 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) && 974 (!wlan_mlo_peer_is_nawds(ml_peer))) { 975 if (ml_peer->max_links == ml_peer->link_peer_cnt) { 976 assoc_peer = ml_peer->peer_list[0].link_peer; 977 if (assoc_peer) 978 mlo_mlme_peer_assoc_resp(assoc_peer); 979 } 980 } 981 982 return QDF_STATUS_SUCCESS; 983 } 984 985 QDF_STATUS wlan_mlo_link_peer_attach(struct wlan_mlo_peer_context *ml_peer, 986 struct wlan_objmgr_peer *peer, 987 qdf_nbuf_t frm_buf) 988 { 989 QDF_STATUS status; 990 struct wlan_objmgr_peer *assoc_peer; 991 struct wlan_objmgr_vdev *vdev = NULL; 992 993 if (!ml_peer) 994 return QDF_STATUS_E_FAILURE; 995 996 vdev = wlan_peer_get_vdev(peer); 997 if (!vdev) 998 return QDF_STATUS_E_FAILURE; 999 1000 /* Populate Link peer pointer, peer MAC address, 1001 * MLD address. HW link ID, update ref count 1002 */ 1003 status = mlo_peer_attach_link_peer(ml_peer, peer, frm_buf); 1004 if (QDF_IS_STATUS_ERROR(status)) 1005 return status; 1006 1007 /* Store AID, MLO Peer pointer in link peer, take link peer ref count */ 1008 mlo_peer_populate_link_peer(ml_peer, peer); 1009 1010 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) { 1011 if (ml_peer->max_links == ml_peer->link_peer_cnt) { 1012 assoc_peer = ml_peer->peer_list[0].link_peer; 1013 if (assoc_peer) 1014 mlo_mlme_peer_assoc_resp(assoc_peer); 1015 } 1016 } 1017 1018 return status; 1019 } 1020 1021 QDF_STATUS wlan_mlo_link_peer_delete(struct wlan_objmgr_peer *peer) 1022 { 1023 struct wlan_mlo_peer_context *ml_peer; 1024 1025 ml_peer = peer->mlo_peer_ctx; 1026 1027 if (!ml_peer) 1028 return QDF_STATUS_E_NOENT; 1029 1030 mlo_reset_link_peer(ml_peer, peer); 1031 mlo_peer_detach_link_peer(ml_peer, peer); 1032 wlan_mlo_peer_release_ref(ml_peer); 1033 1034 return QDF_STATUS_SUCCESS; 1035 } 1036 1037 qdf_export_symbol(wlan_mlo_link_peer_delete); 1038 1039 qdf_nbuf_t mlo_peer_get_link_peer_assoc_req_buf( 1040 struct wlan_mlo_peer_context *ml_peer, 1041 uint8_t link_ix) 1042 { 1043 struct wlan_objmgr_peer *peer = NULL; 1044 qdf_nbuf_t assocbuf = NULL; 1045 1046 if (!ml_peer) 1047 return NULL; 1048 1049 peer = wlan_mlo_peer_get_assoc_peer(ml_peer); 1050 if (!peer) 1051 return NULL; 1052 1053 assocbuf = mlo_mlme_get_link_assoc_req(peer, link_ix); 1054 1055 return assocbuf; 1056 } 1057 1058 void wlan_mlo_peer_get_links_info(struct wlan_objmgr_peer *peer, 1059 struct mlo_tgt_partner_info *ml_links) 1060 { 1061 struct wlan_mlo_peer_context *ml_peer; 1062 struct wlan_mlo_link_peer_entry *peer_entry; 1063 struct wlan_objmgr_peer *link_peer; 1064 struct wlan_objmgr_vdev *link_vdev; 1065 uint8_t i, ix; 1066 1067 ml_peer = peer->mlo_peer_ctx; 1068 ml_links->num_partner_links = 0; 1069 1070 if (!ml_peer) 1071 return; 1072 1073 mlo_peer_lock_acquire(ml_peer); 1074 1075 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 1076 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 1077 mlo_peer_lock_release(ml_peer); 1078 return; 1079 } 1080 1081 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1082 peer_entry = &ml_peer->peer_list[i]; 1083 link_peer = peer_entry->link_peer; 1084 1085 if (!link_peer) 1086 continue; 1087 1088 if (link_peer == peer) 1089 continue; 1090 1091 link_vdev = wlan_peer_get_vdev(link_peer); 1092 if (!link_vdev) 1093 continue; 1094 1095 if (ml_links->num_partner_links >= WLAN_UMAC_MLO_MAX_VDEVS) 1096 break; 1097 1098 ix = ml_links->num_partner_links; 1099 ml_links->link_info[ix].vdev_id = wlan_vdev_get_id(link_vdev); 1100 ml_links->link_info[ix].hw_mld_link_id = peer_entry->hw_link_id; 1101 ml_links->num_partner_links++; 1102 } 1103 mlo_peer_lock_release(ml_peer); 1104 } 1105 1106 qdf_export_symbol(wlan_mlo_peer_get_links_info); 1107 1108 void wlan_mlo_peer_get_partner_links_info(struct wlan_objmgr_peer *peer, 1109 struct mlo_partner_info *ml_links) 1110 { 1111 struct wlan_mlo_peer_context *ml_peer; 1112 struct wlan_mlo_link_peer_entry *peer_entry; 1113 struct wlan_objmgr_peer *link_peer; 1114 struct wlan_objmgr_vdev *link_vdev; 1115 uint8_t i, ix; 1116 1117 ml_peer = peer->mlo_peer_ctx; 1118 ml_links->num_partner_links = 0; 1119 1120 if (!ml_peer) 1121 return; 1122 1123 mlo_peer_lock_acquire(ml_peer); 1124 1125 if ((ml_peer->mlpeer_state != ML_PEER_CREATED) && 1126 (ml_peer->mlpeer_state != ML_PEER_ASSOC_DONE)) { 1127 mlo_peer_lock_release(ml_peer); 1128 return; 1129 } 1130 1131 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1132 peer_entry = &ml_peer->peer_list[i]; 1133 link_peer = peer_entry->link_peer; 1134 1135 if (!link_peer) 1136 continue; 1137 1138 if (link_peer == peer) 1139 continue; 1140 1141 link_vdev = wlan_peer_get_vdev(link_peer); 1142 if (!link_vdev) 1143 continue; 1144 1145 if (ml_links->num_partner_links >= WLAN_UMAC_MLO_MAX_VDEVS) 1146 break; 1147 1148 ix = ml_links->num_partner_links; 1149 ml_links->partner_link_info[ix].link_id = peer_entry->link_ix; 1150 1151 qdf_copy_macaddr(&ml_links->partner_link_info[ix].link_addr, 1152 &peer_entry->link_addr); 1153 ml_links->num_partner_links++; 1154 } 1155 mlo_peer_lock_release(ml_peer); 1156 } 1157 1158 qdf_export_symbol(wlan_mlo_peer_get_partner_links_info); 1159 1160 #ifdef UMAC_SUPPORT_MLNAWDS 1161 bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer) 1162 { 1163 bool status = false; 1164 1165 if (!ml_peer) 1166 return status; 1167 1168 mlo_peer_lock_acquire(ml_peer); 1169 if (ml_peer->is_nawds_ml_peer) 1170 status = true; 1171 mlo_peer_lock_release(ml_peer); 1172 1173 return status; 1174 } 1175 1176 qdf_export_symbol(wlan_mlo_peer_is_nawds); 1177 #endif 1178 1179 #ifdef UMAC_MLO_AUTH_DEFER 1180 void mlo_peer_free_auth_param(struct mlpeer_auth_params *auth_params) 1181 { 1182 if (auth_params->rs) 1183 qdf_mem_free(auth_params->rs); 1184 1185 if (auth_params->wbuf) 1186 qdf_nbuf_free(auth_params->wbuf); 1187 1188 qdf_mem_free(auth_params); 1189 } 1190 1191 QDF_STATUS mlo_peer_link_auth_defer(struct wlan_mlo_peer_context *ml_peer, 1192 struct qdf_mac_addr *link_mac, 1193 struct mlpeer_auth_params *auth_params) 1194 { 1195 uint8_t i; 1196 uint8_t free_entries = 0; 1197 struct mlpeer_auth_params *recv_auth; 1198 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1199 1200 if (!ml_peer) 1201 return status; 1202 1203 mlo_peer_lock_acquire(ml_peer); 1204 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1205 recv_auth = ml_peer->pending_auth[i]; 1206 if (!recv_auth) { 1207 free_entries++; 1208 continue; 1209 } 1210 /* overwrite the entry with latest entry */ 1211 if (qdf_is_macaddr_equal(link_mac, &recv_auth->link_addr)) { 1212 mlo_peer_free_auth_param(recv_auth); 1213 ml_peer->pending_auth[i] = auth_params; 1214 mlo_peer_lock_release(ml_peer); 1215 1216 return QDF_STATUS_SUCCESS; 1217 } 1218 } 1219 1220 if (!free_entries) { 1221 mlo_peer_lock_release(ml_peer); 1222 return QDF_STATUS_E_FAILURE; 1223 } 1224 1225 for (i = 0; i < MAX_MLO_LINK_PEERS; i++) { 1226 recv_auth = ml_peer->pending_auth[i]; 1227 if (!recv_auth) { 1228 ml_peer->pending_auth[i] = auth_params; 1229 status = QDF_STATUS_SUCCESS; 1230 break; 1231 } 1232 } 1233 mlo_peer_lock_release(ml_peer); 1234 1235 return status; 1236 } 1237 #endif 1238