1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* 19 * DOC: contains MLO manager public file containing STA functionality 20 */ 21 #ifndef _WLAN_MLO_MGR_STA_H_ 22 #define _WLAN_MLO_MGR_STA_H_ 23 24 #include <wlan_cm_ucfg_api.h> 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wlan_mlo_mgr_cmn.h> 27 #ifdef WLAN_FEATURE_11BE_MLO 28 #include <wlan_mlo_mgr_public_structs.h> 29 30 /** 31 * mlo_connect - Start the connection process 32 * 33 * @vdev: pointer to vdev 34 * @req: connection request 35 * 36 * Return: QDF_STATUS 37 */ 38 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev, 39 struct wlan_cm_connect_req *req); 40 41 /** 42 * mlo_sta_link_connect_notify - Called by connection manager to notify the 43 * STA link connect is complete 44 * 45 * @vdev: pointer to vdev 46 * @mlo_ie: MLO information element 47 * 48 * Connection manager will notify the MLO manager when the link has started 49 * and MLO manager will start the subsequent connections, if necessary 50 * 51 * Return: none 52 */ 53 void 54 mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev, 55 struct wlan_cm_connect_resp *rsp); 56 57 /** 58 * mlo_disconnect - Start the disconnection process 59 * 60 * @vdev: pointer to vdev 61 * @source: source of the request (can be connect or disconnect request) 62 * @reason_code: reason for disconnect 63 * @bssid: BSSID 64 * 65 * Return: QDF_STATUS 66 */ 67 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev, 68 enum wlan_cm_source source, 69 enum wlan_reason_code reason_code, 70 struct qdf_mac_addr *bssid); 71 72 /** 73 * mlo_sync_disconnect - Start the sync disconnection process 74 * 75 * @vdev: pointer to vdev 76 * @source: source of the request (can be connect or disconnect request) 77 * @reason_code: reason for disconnect 78 * @bssid: BSSID 79 * 80 * Return: QDF_STATUS 81 */ 82 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev, 83 enum wlan_cm_source source, 84 enum wlan_reason_code reason_code, 85 struct qdf_mac_addr *bssid); 86 87 /** 88 * mlo_sta_link_disconn_notify - Notifies that STA link disconnect completion 89 * 90 * @vdev: pointer to vdev 91 * @resp: disconnect resp 92 * 93 * Return: none 94 */ 95 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev, 96 struct wlan_cm_discon_rsp *resp); 97 98 /** 99 * mlo_is_mld_sta - Check if MLD associated with the vdev is a station 100 * 101 * @vdev: pointer to vdev 102 * 103 * Return: true if MLD is a station, false otherwise 104 */ 105 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev); 106 107 /** 108 * ucfg_mlo_is_mld_disconnected - Check whether MLD is disconnected 109 * 110 * @vdev: pointer to vdev 111 * 112 * Return: true if mld is disconnected, false otherwise 113 */ 114 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev); 115 116 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 117 /** 118 * ucfg_mlo_is_mld_connected - Check whether MLD is connected 119 * 120 * @vdev: pointer to vdev 121 * 122 * Return: true if mld is connected, false otherwise 123 */ 124 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev); 125 126 /** 127 * ucfg_mlo_mld_clear_mlo_cap - Clear MLO cap for all vdevs in MLD 128 * 129 * @vdev: pointer to vdev 130 * 131 * Return: None 132 */ 133 void ucfg_mlo_mld_clear_mlo_cap(struct wlan_objmgr_vdev *vdev); 134 #endif 135 136 /* 137 * ucfg_mlo_get_assoc_link_vdev - API to get assoc link vdev 138 * 139 * @mlo_dev_ctx: mlo dev ctx 140 * 141 * Return: MLD assoc link vdev 142 */ 143 struct wlan_objmgr_vdev * 144 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev); 145 146 /* 147 * wlan_mlo_get_assoc_link_vdev - API to get assoc link vdev 148 * 149 * @mlo_dev_ctx: mlo dev ctx 150 * 151 * Return: MLD assoc link vdev 152 */ 153 struct wlan_objmgr_vdev * 154 wlan_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev); 155 156 /* 157 * mlo_update_connected_links_bmap: update connected links bitmap 158 * 159 * @mlo_dev_ctx: mlo dev context ptr 160 * @ml_partner_info: ml parnter info ptr 161 * 162 * Return: none 163 */ 164 void 165 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx, 166 struct mlo_partner_info ml_parnter_info); 167 168 /* 169 * API to have operation on ml vdevs 170 */ 171 typedef void (*mlo_vdev_op_handler)(struct wlan_objmgr_vdev *vdev, 172 void *arg); 173 174 /* 175 * mlo_iterate_connected_vdev_list: Iterate on connected ML links 176 * 177 * @vdev: vdev object 178 * @handler: the handler will be called for each object in ML list 179 * @arg: argumet to be passed to handler 180 * 181 * Return: none 182 */ 183 static inline 184 void mlo_iterate_connected_vdev_list(struct wlan_objmgr_vdev *vdev, 185 mlo_vdev_op_handler handler, 186 void *arg) 187 { 188 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 189 struct wlan_mlo_sta *sta_ctx = NULL; 190 uint8_t i = 0; 191 192 if (!mlo_dev_ctx || !(wlan_vdev_mlme_is_mlo_vdev(vdev))) 193 return; 194 195 sta_ctx = mlo_dev_ctx->sta_ctx; 196 if (!sta_ctx) 197 return; 198 199 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 200 if (!mlo_dev_ctx->wlan_vdev_list[i]) 201 continue; 202 if (qdf_test_bit(i, sta_ctx->wlan_connected_links)) { 203 if (handler) 204 handler(mlo_dev_ctx->wlan_vdev_list[i], arg); 205 } 206 } 207 } 208 209 /* 210 * mlo_update_connect_req_links: update connect req links index 211 * 212 * @vdev: vdev object 213 * @value: set/clear the bit 214 * 215 * Return: none 216 */ 217 static inline void 218 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 219 { 220 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 221 struct wlan_mlo_sta *sta_ctx = NULL; 222 uint8_t i = 0; 223 224 if (!mlo_dev_ctx) 225 return; 226 227 sta_ctx = mlo_dev_ctx->sta_ctx; 228 if (!sta_ctx) 229 return; 230 231 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 232 if (!mlo_dev_ctx->wlan_vdev_list[i]) 233 continue; 234 235 if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) { 236 if (value) 237 qdf_set_bit(i, sta_ctx->wlan_connect_req_links); 238 else 239 qdf_clear_bit( 240 i, sta_ctx->wlan_connect_req_links); 241 } 242 } 243 } 244 245 /* 246 * mlo_is_vdev_connect_req_link: API to check if vdev is in active connection 247 * 248 * @vdev: vdev object 249 * 250 * Return: true is vdev is participating in active connect else false 251 */ 252 static inline bool 253 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev) 254 { 255 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 256 struct wlan_mlo_sta *sta_ctx = NULL; 257 258 if (!mlo_dev_ctx) 259 return false; 260 261 sta_ctx = mlo_dev_ctx->sta_ctx; 262 if (!sta_ctx) 263 return false; 264 265 if (qdf_test_bit( 266 mlo_get_link_vdev_ix(vdev->mlo_dev_ctx, vdev), 267 sta_ctx->wlan_connect_req_links)) 268 return true; 269 270 return false; 271 } 272 273 /* 274 * mlo_clear_connect_req_links: clear connect req links bitmap 275 * 276 * @vdev: vdev object 277 * 278 * Return: none 279 */ 280 static inline 281 void mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev) 282 { 283 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 284 struct wlan_mlo_sta *sta_ctx = NULL; 285 286 if (!mlo_dev_ctx) 287 return; 288 289 sta_ctx = mlo_dev_ctx->sta_ctx; 290 if (!sta_ctx) 291 return; 292 293 qdf_mem_zero(sta_ctx->wlan_connect_req_links, 294 sizeof(sta_ctx->wlan_connect_req_links)); 295 } 296 297 /* 298 * mlo_update_connected_links: update connected links index 299 * 300 * @vdev: vdev object 301 * @value: set/clear the bit 302 * 303 * Return: none 304 */ 305 static inline void 306 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 307 { 308 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 309 struct wlan_mlo_sta *sta_ctx = NULL; 310 uint8_t i = 0; 311 312 if (!mlo_dev_ctx) 313 return; 314 315 sta_ctx = mlo_dev_ctx->sta_ctx; 316 if (!sta_ctx) 317 return; 318 319 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 320 if (!mlo_dev_ctx->wlan_vdev_list[i]) 321 continue; 322 323 if (vdev == mlo_dev_ctx->wlan_vdev_list[i]) { 324 if (value) 325 qdf_set_bit(i, sta_ctx->wlan_connected_links); 326 else 327 qdf_clear_bit(i, sta_ctx->wlan_connected_links); 328 } 329 } 330 } 331 332 /* 333 * mlo_clear_connected_links: clear connected links bitmap 334 * 335 * @vdev: vdev object 336 * 337 * Return: none 338 */ 339 static inline 340 void mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev) 341 { 342 struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx; 343 struct wlan_mlo_sta *sta_ctx = NULL; 344 345 if (!mlo_dev_ctx) 346 return; 347 348 sta_ctx = mlo_dev_ctx->sta_ctx; 349 if (!sta_ctx) 350 return; 351 352 qdf_mem_zero(sta_ctx->wlan_connected_links, 353 sizeof(sta_ctx->wlan_connected_links)); 354 355 } 356 357 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 358 /* 359 * mlo_get_ml_vdev_by_mac: get ml vdev from mac 360 * 361 * @vdev: vdev object 362 * @macaddr: mac of vdev to be returned 363 * 364 * Return: vdev object if found else NULL 365 */ 366 struct wlan_objmgr_vdev * 367 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev, 368 struct qdf_mac_addr *macaddr); 369 #endif 370 371 /* 372 * mlo_get_chan_freq_by_bssid - Get channel freq by bssid 373 * 374 * @pdev: pdev pointer 375 * @bssid: link mac address 376 * 377 * Return: chan frequency 378 */ 379 qdf_freq_t 380 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev, 381 struct qdf_mac_addr *bssid); 382 383 /** 384 * mlo_get_assoc_rsp - Get Assoc response from mlo manager 385 * 386 * @vdev: vdev obj mgr 387 * @assoc_rsp_frame: association response frame ptr 388 * 389 * Return: none 390 */ 391 void mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev, 392 struct element_info *assoc_rsp_frame); 393 394 /** 395 * mlo_sta_save_quiet_status - save quiet status for given link of mlo station 396 * @mlo_dev_ctx: mlo context 397 * @link_id: link id 398 * @quiet_status: True if quiet starts. False if quiet stopps. 399 * 400 * Return: QDF_STATUS 401 */ 402 QDF_STATUS mlo_sta_save_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx, 403 uint8_t link_id, 404 bool quiet_status); 405 406 /** 407 * mlo_is_sta_in_quiet_status - is the link of given mlo sta is in quiet status 408 * @mlo_dev_ctx: mlo context 409 * @link_id: link id 410 * 411 * Return: true if the link of given mlo sta is in quiet status 412 */ 413 bool mlo_is_sta_in_quiet_status(struct wlan_mlo_dev_context *mlo_dev_ctx, 414 uint8_t link_id); 415 416 /** 417 * mlo_is_sta_inactivity_allowed_with_quiet() - Is link OK to force inactivity 418 * based on current quiet status 419 * of mlo connection 420 * @psoc: pointer to psoc 421 * @vdev_id_list: vdev id list 422 * @num_mlo: number of mlo vdev 423 * @mlo_idx: list of index of vdev_id_list if it is vdev id of mlo vdev 424 * @affected_links: number of links to be set inactivity 425 * @affected_list: list of vdev id to be set inactivity 426 * 427 * Return: true if any link not in mlo_vdev_list is not in quiet mode 428 */ 429 bool mlo_is_sta_inactivity_allowed_with_quiet(struct wlan_objmgr_psoc *psoc, 430 uint8_t *vdev_id_list, 431 uint8_t num_mlo, uint8_t *mlo_idx, 432 uint8_t affected_links, 433 uint8_t *affected_list); 434 435 /** 436 * mlo_is_sta_csa_synced - Is mlo sta csa parameters are synced or not 437 * 438 * @mlo_dev_ctx: mlo context 439 * @link_id: link id 440 * 441 * Return: true if mlo sta csa parameters of given link id is synced 442 */ 443 bool mlo_is_sta_csa_synced(struct wlan_mlo_dev_context *mlo_dev_ctx, 444 uint8_t link_id); 445 446 /** 447 * mlo_sta_csa_save_params - Save csa parameters for mlo station 448 * @mlo_dev_ctx: mlo context 449 * @link_id: link id 450 * @csa_param: csa parameters to be saved 451 * 452 * Return: QDF_STATUS 453 */ 454 QDF_STATUS mlo_sta_csa_save_params(struct wlan_mlo_dev_context *mlo_dev_ctx, 455 uint8_t link_id, 456 struct csa_offload_params *csa_param); 457 458 /** 459 * mlo_sta_up_active_notify - mlo sta up active notify 460 * @vdev: vdev obj mgr 461 * 462 * Return: QDF_STATUS 463 */ 464 QDF_STATUS mlo_sta_up_active_notify(struct wlan_objmgr_vdev *vdev); 465 466 /** 467 * mlo_is_sta_csa_param_handled - Is given csa_param handled or not 468 * @vdev: vdev obj mgr 469 * @csa_param: csa parameters to be checked 470 * 471 * Return: true if given csa parameters is handled 472 */ 473 bool mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev, 474 struct csa_offload_params *csa_param); 475 476 /** 477 * mlo_internal_disconnect_links - Internal disconnect for connection manager 478 * 479 * @vdev: vdev obj mgr 480 * 481 * Return: none 482 */ 483 void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev); 484 485 /** 486 * mlo_sta_get_vdev_list() - get mlo vdev list 487 * @vdev: vdev pointer 488 * @vdev_count: vdev count 489 * @wlan_vdev_list: vdev list 490 * 491 * Return: None 492 */ 493 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, uint16_t *vdev_count, 494 struct wlan_objmgr_vdev **wlan_vdev_list); 495 #else 496 static inline 497 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev, 498 struct wlan_cm_connect_req *req) 499 { 500 return wlan_cm_start_connect(vdev, req); 501 } 502 503 static inline 504 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev, 505 struct wlan_cm_connect_resp *rsp) 506 { } 507 508 static inline 509 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev, 510 enum wlan_cm_source source, 511 enum wlan_reason_code reason_code, 512 struct qdf_mac_addr *bssid) 513 { 514 QDF_STATUS status; 515 516 status = wlan_cm_disconnect(vdev, source, 517 reason_code, 518 bssid); 519 return status; 520 } 521 522 static inline 523 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev, 524 enum wlan_cm_source source, 525 enum wlan_reason_code reason_code, 526 struct qdf_mac_addr *bssid) 527 { 528 return wlan_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, 529 reason_code); 530 } 531 532 static inline 533 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev, 534 struct wlan_cm_discon_rsp *resp) 535 { } 536 537 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 538 static inline 539 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev) 540 { 541 return true; 542 } 543 544 static inline 545 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev) 546 { 547 return true; 548 } 549 #endif 550 551 static inline 552 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev) 553 { 554 return false; 555 } 556 557 static inline 558 struct wlan_objmgr_vdev * 559 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev) 560 { 561 return vdev; 562 } 563 564 static inline void 565 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 566 { } 567 568 static inline void 569 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx, 570 struct mlo_partner_info ml_parnter_info) 571 { } 572 573 static inline bool 574 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev) 575 { 576 return true; 577 } 578 579 static inline void 580 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 581 { } 582 583 static inline void 584 mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev) 585 { } 586 587 static inline void 588 mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev) 589 { } 590 591 static inline struct wlan_objmgr_vdev * 592 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev, 593 struct qdf_mac_addr *macaddr) 594 { 595 return vdev; 596 } 597 598 static inline qdf_freq_t 599 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev, 600 struct qdf_mac_addr *bssid) 601 { 602 return 0; 603 } 604 605 static inline void 606 mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev, 607 struct element_info *assoc_rsp_frame) 608 { 609 } 610 611 static inline bool 612 mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev, 613 struct csa_offload_params *csa_param) 614 { 615 return false; 616 } 617 618 static inline void mlo_internal_disconnect_links(struct wlan_objmgr_vdev *vdev) 619 { 620 } 621 622 static inline 623 void mlo_sta_get_vdev_list(struct wlan_objmgr_vdev *vdev, 624 uint16_t *vdev_count, 625 struct wlan_objmgr_vdev **wlan_vdev_list) 626 { 627 } 628 #endif 629 #endif 630