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 #else 476 static inline 477 QDF_STATUS mlo_connect(struct wlan_objmgr_vdev *vdev, 478 struct wlan_cm_connect_req *req) 479 { 480 return wlan_cm_start_connect(vdev, req); 481 } 482 483 static inline 484 void mlo_sta_link_connect_notify(struct wlan_objmgr_vdev *vdev, 485 struct wlan_cm_connect_resp *rsp) 486 { } 487 488 static inline 489 QDF_STATUS mlo_disconnect(struct wlan_objmgr_vdev *vdev, 490 enum wlan_cm_source source, 491 enum wlan_reason_code reason_code, 492 struct qdf_mac_addr *bssid) 493 { 494 QDF_STATUS status; 495 496 status = wlan_cm_disconnect(vdev, source, 497 reason_code, 498 bssid); 499 return status; 500 } 501 502 static inline 503 QDF_STATUS mlo_sync_disconnect(struct wlan_objmgr_vdev *vdev, 504 enum wlan_cm_source source, 505 enum wlan_reason_code reason_code, 506 struct qdf_mac_addr *bssid) 507 { 508 return wlan_cm_disconnect_sync(vdev, CM_OSIF_DISCONNECT, 509 reason_code); 510 } 511 512 static inline 513 void mlo_sta_link_disconn_notify(struct wlan_objmgr_vdev *vdev, 514 struct wlan_cm_discon_rsp *resp) 515 { } 516 517 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 518 static inline 519 bool ucfg_mlo_is_mld_connected(struct wlan_objmgr_vdev *vdev) 520 { 521 return true; 522 } 523 524 static inline 525 bool ucfg_mlo_is_mld_disconnected(struct wlan_objmgr_vdev *vdev) 526 { 527 return true; 528 } 529 #endif 530 531 static inline 532 bool mlo_is_mld_sta(struct wlan_objmgr_vdev *vdev) 533 { 534 return false; 535 } 536 537 static inline 538 struct wlan_objmgr_vdev * 539 ucfg_mlo_get_assoc_link_vdev(struct wlan_objmgr_vdev *vdev) 540 { 541 return vdev; 542 } 543 544 static inline void 545 mlo_update_connect_req_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 546 { } 547 548 static inline void 549 mlo_update_connected_links_bmap(struct wlan_mlo_dev_context *mlo_dev_ctx, 550 struct mlo_partner_info ml_parnter_info) 551 { } 552 553 static inline bool 554 mlo_is_vdev_connect_req_link(struct wlan_objmgr_vdev *vdev) 555 { 556 return true; 557 } 558 559 static inline void 560 mlo_update_connected_links(struct wlan_objmgr_vdev *vdev, uint8_t value) 561 { } 562 563 static inline void 564 mlo_clear_connect_req_links_bmap(struct wlan_objmgr_vdev *vdev) 565 { } 566 567 static inline void 568 mlo_clear_connected_links_bmap(struct wlan_objmgr_vdev *vdev) 569 { } 570 571 static inline struct wlan_objmgr_vdev * 572 mlo_get_ml_vdev_by_mac(struct wlan_objmgr_vdev *vdev, 573 struct qdf_mac_addr *macaddr) 574 { 575 return vdev; 576 } 577 578 static inline qdf_freq_t 579 mlo_get_chan_freq_by_bssid(struct wlan_objmgr_pdev *pdev, 580 struct qdf_mac_addr *bssid) 581 { 582 return 0; 583 } 584 585 static inline void 586 mlo_get_assoc_rsp(struct wlan_objmgr_vdev *vdev, 587 struct element_info *assoc_rsp_frame) 588 { 589 } 590 591 static inline bool 592 mlo_is_sta_csa_param_handled(struct wlan_objmgr_vdev *vdev, 593 struct csa_offload_params *csa_param) 594 { 595 return false; 596 } 597 #endif 598 #endif 599