1 /* 2 * Copyright (c) 2012-2015, 2020-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /** 19 * DOC: wlan_cm_api.c 20 * 21 * This file maintains definitaions public apis. 22 */ 23 24 #include <wlan_cm_api.h> 25 #include "connection_mgr/core/src/wlan_cm_main_api.h" 26 #include "connection_mgr/core/src/wlan_cm_roam.h" 27 #include <wlan_vdev_mgr_utils_api.h> 28 #ifdef WLAN_FEATURE_11BE_MLO 29 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 30 #include "wlan_mlo_mgr_roam.h" 31 #endif 32 #endif 33 34 QDF_STATUS wlan_cm_start_connect(struct wlan_objmgr_vdev *vdev, 35 struct wlan_cm_connect_req *req) 36 { 37 return cm_connect_start_req(vdev, req); 38 } 39 40 QDF_STATUS wlan_cm_disconnect(struct wlan_objmgr_vdev *vdev, 41 enum wlan_cm_source source, 42 enum wlan_reason_code reason_code, 43 struct qdf_mac_addr *bssid) 44 { 45 struct wlan_cm_disconnect_req req = {0}; 46 47 req.vdev_id = wlan_vdev_get_id(vdev); 48 req.source = source; 49 req.reason_code = reason_code; 50 if (bssid) 51 qdf_copy_macaddr(&req.bssid, bssid); 52 53 return cm_disconnect_start_req(vdev, &req); 54 } 55 56 QDF_STATUS wlan_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, 57 enum wlan_cm_source source, 58 enum wlan_reason_code reason_code) 59 { 60 struct wlan_cm_disconnect_req req = {0}; 61 62 req.vdev_id = wlan_vdev_get_id(vdev); 63 req.source = source; 64 req.reason_code = reason_code; 65 66 return cm_disconnect_start_req_sync(vdev, &req); 67 } 68 69 QDF_STATUS wlan_cm_bss_select_ind_rsp(struct wlan_objmgr_vdev *vdev, 70 QDF_STATUS status) 71 { 72 return cm_bss_select_ind_rsp(vdev, status); 73 } 74 75 QDF_STATUS wlan_cm_bss_peer_create_rsp(struct wlan_objmgr_vdev *vdev, 76 QDF_STATUS status, 77 struct qdf_mac_addr *peer_mac) 78 { 79 uint32_t prefix; 80 struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev); 81 82 if (!cm_ctx) 83 return QDF_STATUS_E_INVAL; 84 85 prefix = CM_ID_GET_PREFIX(cm_ctx->active_cm_id); 86 if (prefix == ROAM_REQ_PREFIX) 87 return cm_roam_bss_peer_create_rsp(vdev, status, peer_mac); 88 else 89 return cm_bss_peer_create_rsp(vdev, status, peer_mac); 90 } 91 92 QDF_STATUS wlan_cm_connect_rsp(struct wlan_objmgr_vdev *vdev, 93 struct wlan_cm_connect_resp *resp) 94 { 95 return cm_connect_rsp(vdev, resp); 96 } 97 98 QDF_STATUS wlan_cm_bss_peer_delete_ind(struct wlan_objmgr_vdev *vdev, 99 struct qdf_mac_addr *peer_mac) 100 { 101 return cm_bss_peer_delete_req(vdev, peer_mac); 102 } 103 104 QDF_STATUS wlan_cm_bss_peer_delete_rsp(struct wlan_objmgr_vdev *vdev, 105 uint32_t status) 106 { 107 return cm_vdev_down_req(vdev, status); 108 } 109 110 QDF_STATUS wlan_cm_disconnect_rsp(struct wlan_objmgr_vdev *vdev, 111 struct wlan_cm_discon_rsp *resp) 112 { 113 uint32_t prefix; 114 struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev); 115 116 if (!cm_ctx) 117 return QDF_STATUS_E_INVAL; 118 119 prefix = CM_ID_GET_PREFIX(cm_ctx->active_cm_id); 120 if (prefix == ROAM_REQ_PREFIX) 121 return cm_roam_disconnect_rsp(vdev, resp); 122 else 123 return cm_disconnect_rsp(vdev, resp); 124 } 125 126 #ifdef WLAN_FEATURE_HOST_ROAM 127 QDF_STATUS wlan_cm_reassoc_rsp(struct wlan_objmgr_vdev *vdev, 128 struct wlan_cm_connect_resp *resp) 129 { 130 return cm_reassoc_rsp(vdev, resp); 131 } 132 #endif 133 134 void wlan_cm_free_connect_req(struct wlan_cm_connect_req *connect_req) 135 { 136 if (!connect_req) 137 return; 138 139 cm_free_connect_req(connect_req); 140 } 141 142 void wlan_cm_free_connect_resp(struct wlan_cm_connect_resp *connect_rsp) 143 { 144 if (!connect_rsp) 145 return; 146 147 cm_free_connect_rsp(connect_rsp); 148 } 149 150 void wlan_cm_free_connect_req_param(struct wlan_cm_connect_req *req) 151 { 152 if (!req) 153 return; 154 155 cm_free_connect_req_param(req); 156 } 157 158 void wlan_cm_set_max_connect_attempts(struct wlan_objmgr_vdev *vdev, 159 uint8_t max_connect_attempts) 160 { 161 cm_set_max_connect_attempts(vdev, max_connect_attempts); 162 } 163 164 void wlan_cm_set_max_connect_timeout(struct wlan_objmgr_vdev *vdev, 165 uint32_t max_connect_timeout) 166 { 167 cm_set_max_connect_timeout(vdev, max_connect_timeout); 168 } 169 170 bool wlan_cm_is_vdev_connecting(struct wlan_objmgr_vdev *vdev) 171 { 172 return cm_is_vdev_connecting(vdev); 173 } 174 175 bool wlan_cm_is_vdev_connected(struct wlan_objmgr_vdev *vdev) 176 { 177 return cm_is_vdev_connected(vdev); 178 } 179 180 bool wlan_cm_is_vdev_active(struct wlan_objmgr_vdev *vdev) 181 { 182 return cm_is_vdev_active(vdev); 183 } 184 185 bool wlan_cm_is_vdev_disconnecting(struct wlan_objmgr_vdev *vdev) 186 { 187 return cm_is_vdev_disconnecting(vdev); 188 } 189 190 bool wlan_cm_is_vdev_disconnected(struct wlan_objmgr_vdev *vdev) 191 { 192 return cm_is_vdev_disconnected(vdev); 193 } 194 195 bool wlan_cm_is_vdev_idle_due_to_link_switch(struct wlan_objmgr_vdev *vdev) 196 { 197 return cm_is_vdev_idle_due_to_link_switch(vdev); 198 } 199 200 bool wlan_cm_is_vdev_roaming(struct wlan_objmgr_vdev *vdev) 201 { 202 return cm_is_vdev_roaming(vdev); 203 } 204 205 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 206 bool wlan_cm_is_vdev_roam_started(struct wlan_objmgr_vdev *vdev) 207 { 208 return cm_is_vdev_roam_started(vdev); 209 } 210 211 bool wlan_cm_is_vdev_roam_sync_inprogress(struct wlan_objmgr_vdev *vdev) 212 { 213 return cm_is_vdev_roam_sync_inprogress(vdev); 214 } 215 #endif 216 217 #ifdef WLAN_FEATURE_HOST_ROAM 218 bool wlan_cm_is_vdev_roam_preauth_state(struct wlan_objmgr_vdev *vdev) 219 { 220 return cm_is_vdev_roam_preauth_state(vdev); 221 } 222 223 bool wlan_cm_is_vdev_roam_reassoc_state(struct wlan_objmgr_vdev *vdev) 224 { 225 return cm_is_vdev_roam_reassoc_state(vdev); 226 } 227 #endif 228 229 enum wlan_cm_active_request_type 230 wlan_cm_get_active_req_type(struct wlan_objmgr_vdev *vdev) 231 { 232 return cm_get_active_req_type(vdev); 233 } 234 235 bool wlan_cm_get_active_connect_req(struct wlan_objmgr_vdev *vdev, 236 struct wlan_cm_vdev_connect_req *req) 237 { 238 return cm_get_active_connect_req(vdev, req); 239 } 240 241 QDF_STATUS 242 wlan_cm_get_active_connect_req_param(struct wlan_objmgr_vdev *vdev, 243 struct wlan_cm_connect_req *req) 244 { 245 return cm_get_active_connect_req_param(vdev, req); 246 } 247 248 cm_ext_t *wlan_cm_get_ext_hdl(struct wlan_objmgr_vdev *vdev) 249 { 250 return cm_get_ext_hdl(vdev); 251 } 252 253 bool wlan_cm_is_first_candidate_connect_attempt(struct wlan_objmgr_vdev *vdev) 254 { 255 return cm_is_first_candidate_connect_attempt(vdev); 256 } 257 258 bool wlan_cm_is_link_switch_disconnect_resp(struct wlan_cm_discon_rsp *resp) 259 { 260 return cm_is_link_switch_disconnect_resp(resp); 261 } 262 263 bool wlan_cm_is_link_switch_connect_resp(struct wlan_cm_connect_resp *resp) 264 { 265 return cm_is_link_switch_connect_resp(resp); 266 } 267 268 void wlan_cm_trigger_panic_on_cmd_timeout(struct wlan_objmgr_vdev *vdev, 269 enum qdf_hang_reason reason) 270 { 271 cm_trigger_panic_on_cmd_timeout(vdev, reason); 272 } 273 274 #ifdef WLAN_FEATURE_HOST_ROAM 275 bool wlan_cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev, 276 struct wlan_cm_vdev_reassoc_req *req) 277 { 278 return cm_get_active_reassoc_req(vdev, req); 279 } 280 #endif 281 282 bool wlan_cm_get_active_disconnect_req(struct wlan_objmgr_vdev *vdev, 283 struct wlan_cm_vdev_discon_req *req) 284 { 285 return cm_get_active_disconnect_req(vdev, req); 286 } 287 288 const char *wlan_cm_reason_code_to_str(enum wlan_reason_code reason) 289 { 290 if (reason > REASON_PROP_START) 291 return ""; 292 293 switch (reason) { 294 CASE_RETURN_STRING(REASON_UNSPEC_FAILURE); 295 CASE_RETURN_STRING(REASON_PREV_AUTH_NOT_VALID); 296 CASE_RETURN_STRING(REASON_DEAUTH_NETWORK_LEAVING); 297 CASE_RETURN_STRING(REASON_DISASSOC_DUE_TO_INACTIVITY); 298 CASE_RETURN_STRING(REASON_DISASSOC_AP_BUSY); 299 CASE_RETURN_STRING(REASON_CLASS2_FRAME_FROM_NON_AUTH_STA); 300 CASE_RETURN_STRING(REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA); 301 CASE_RETURN_STRING(REASON_DISASSOC_NETWORK_LEAVING); 302 CASE_RETURN_STRING(REASON_STA_NOT_AUTHENTICATED); 303 CASE_RETURN_STRING(REASON_BAD_PWR_CAPABILITY); 304 CASE_RETURN_STRING(REASON_BAD_SUPPORTED_CHANNELS); 305 CASE_RETURN_STRING(REASON_DISASSOC_BSS_TRANSITION); 306 CASE_RETURN_STRING(REASON_INVALID_IE); 307 CASE_RETURN_STRING(REASON_MIC_FAILURE); 308 CASE_RETURN_STRING(REASON_4WAY_HANDSHAKE_TIMEOUT); 309 CASE_RETURN_STRING(REASON_GROUP_KEY_UPDATE_TIMEOUT); 310 CASE_RETURN_STRING(REASON_IN_4WAY_DIFFERS); 311 CASE_RETURN_STRING(REASON_INVALID_GROUP_CIPHER); 312 CASE_RETURN_STRING(REASON_INVALID_PAIRWISE_CIPHER); 313 CASE_RETURN_STRING(REASON_INVALID_AKMP); 314 CASE_RETURN_STRING(REASON_UNSUPPORTED_RSNE_VER); 315 CASE_RETURN_STRING(REASON_INVALID_RSNE_CAPABILITIES); 316 CASE_RETURN_STRING(REASON_1X_AUTH_FAILURE); 317 CASE_RETURN_STRING(REASON_CIPHER_SUITE_REJECTED); 318 CASE_RETURN_STRING(REASON_TDLS_PEER_UNREACHABLE); 319 CASE_RETURN_STRING(REASON_TDLS_UNSPEC); 320 CASE_RETURN_STRING(REASON_DISASSOC_SSP_REQUESTED); 321 CASE_RETURN_STRING(REASON_NO_SSP_ROAMING_AGREEMENT); 322 CASE_RETURN_STRING(REASON_BAD_CIPHER_OR_AKM); 323 CASE_RETURN_STRING(REASON_LOCATION_NOT_AUTHORIZED); 324 CASE_RETURN_STRING(REASON_SERVICE_CHANGE_PRECLUDES_TS); 325 CASE_RETURN_STRING(REASON_QOS_UNSPECIFIED); 326 CASE_RETURN_STRING(REASON_NO_BANDWIDTH); 327 CASE_RETURN_STRING(REASON_XS_UNACKED_FRAMES); 328 CASE_RETURN_STRING(REASON_EXCEEDED_TXOP); 329 CASE_RETURN_STRING(REASON_STA_LEAVING); 330 CASE_RETURN_STRING(REASON_END_TS_BA_DLS); 331 CASE_RETURN_STRING(REASON_UNKNOWN_TS_BA); 332 CASE_RETURN_STRING(REASON_TIMEDOUT); 333 CASE_RETURN_STRING(REASON_PEERKEY_MISMATCH); 334 CASE_RETURN_STRING(REASON_AUTHORIZED_ACCESS_LIMIT_REACHED); 335 CASE_RETURN_STRING(REASON_EXTERNAL_SERVICE_REQUIREMENTS); 336 CASE_RETURN_STRING(REASON_INVALID_FT_ACTION_FRAME_COUNT); 337 CASE_RETURN_STRING(REASON_INVALID_PMKID); 338 CASE_RETURN_STRING(REASON_INVALID_MDE); 339 CASE_RETURN_STRING(REASON_INVALID_FTE); 340 CASE_RETURN_STRING(REASON_MESH_PEERING_CANCELLED); 341 CASE_RETURN_STRING(REASON_MESH_MAX_PEERS); 342 CASE_RETURN_STRING(REASON_MESH_CONFIG_POLICY_VIOLATION); 343 CASE_RETURN_STRING(REASON_MESH_CLOSE_RCVD); 344 CASE_RETURN_STRING(REASON_MESH_MAX_RETRIES); 345 CASE_RETURN_STRING(REASON_MESH_CONFIRM_TIMEOUT); 346 CASE_RETURN_STRING(REASON_MESH_INVALID_GTK); 347 CASE_RETURN_STRING(REASON_MESH_INCONSISTENT_PARAMS); 348 CASE_RETURN_STRING(REASON_MESH_INVALID_SECURITY_CAP); 349 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_PROXY_INFO); 350 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_FORWARDING_INFO); 351 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_DEST_UNREACHABLE); 352 CASE_RETURN_STRING(REASON_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS); 353 CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_REGULATORY_REQ); 354 CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_UNSPECIFIED); 355 CASE_RETURN_STRING(REASON_POOR_RSSI_CONDITIONS); 356 default: 357 return "Unknown"; 358 } 359 } 360 361 #ifdef WLAN_POLICY_MGR_ENABLE 362 void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, 363 wlan_cm_id cm_id, QDF_STATUS status) 364 { 365 uint32_t prefix; 366 367 prefix = CM_ID_GET_PREFIX(cm_id); 368 if (prefix == ROAM_REQ_PREFIX) 369 cm_reassoc_hw_mode_change_resp(pdev, vdev_id, cm_id, status); 370 else 371 cm_hw_mode_change_resp(pdev, vdev_id, cm_id, status); 372 } 373 #endif /* ifdef POLICY_MGR_ENABLE */ 374 375 #ifdef WLAN_FEATURE_LL_LT_SAP 376 void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 377 wlan_cm_id cm_id, QDF_STATUS status) 378 { 379 cm_bearer_switch_resp(psoc, vdev_id, cm_id, status); 380 } 381 #endif 382 383 #ifdef SM_ENG_HIST_ENABLE 384 void wlan_cm_sm_history_print(struct wlan_objmgr_vdev *vdev) 385 { 386 return cm_sm_history_print(vdev); 387 } 388 389 void wlan_cm_req_history_print(struct wlan_objmgr_vdev *vdev) 390 { 391 struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev); 392 393 if (!cm_ctx) 394 return; 395 396 cm_req_history_print(cm_ctx); 397 } 398 #endif /* SM_ENG_HIST_ENABLE */ 399 400 #ifndef CONN_MGR_ADV_FEATURE 401 void wlan_cm_set_candidate_advance_filter_cb( 402 struct wlan_objmgr_vdev *vdev, 403 void (*filter_fun)(struct wlan_objmgr_vdev *vdev, 404 struct scan_filter *filter)) 405 { 406 cm_set_candidate_advance_filter_cb(vdev, filter_fun); 407 } 408 409 void wlan_cm_set_candidate_custom_sort_cb( 410 struct wlan_objmgr_vdev *vdev, 411 void (*sort_fun)(struct wlan_objmgr_vdev *vdev, 412 qdf_list_t *list)) 413 { 414 cm_set_candidate_custom_sort_cb(vdev, sort_fun); 415 } 416 417 #endif 418 419 QDF_STATUS wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, 420 struct reduced_neighbor_report *rnr) 421 { 422 enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); 423 424 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) { 425 mlme_err("vdev %d Invalid mode %d", 426 wlan_vdev_get_id(vdev), op_mode); 427 return QDF_STATUS_E_NOSUPPORT; 428 } 429 430 return cm_get_rnr(vdev, cm_id, rnr); 431 } 432 433 void 434 wlan_cm_connect_resp_fill_mld_addr_from_cm_id(struct wlan_objmgr_vdev *vdev, 435 wlan_cm_id cm_id, 436 struct wlan_cm_connect_resp *rsp) 437 { 438 return cm_connect_resp_fill_mld_addr_from_cm_id(vdev, cm_id, rsp); 439 } 440 441 #ifdef WLAN_FEATURE_11BE_MLO 442 void 443 wlan_cm_connect_resp_fill_mld_addr_from_vdev_id(struct wlan_objmgr_psoc *psoc, 444 uint8_t vdev_id, 445 struct scan_cache_entry *entry, 446 struct wlan_cm_connect_resp *rsp) 447 { 448 struct wlan_objmgr_vdev *vdev; 449 450 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 451 WLAN_MLME_CM_ID); 452 if (!vdev) 453 return; 454 455 cm_connect_resp_fill_mld_addr_from_candidate(vdev, entry, rsp); 456 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 457 } 458 #endif 459 460 QDF_STATUS 461 wlan_cm_disc_cont_after_rso_stop(struct wlan_objmgr_vdev *vdev, 462 struct wlan_cm_vdev_discon_req *req) 463 { 464 return cm_handle_rso_stop_rsp(vdev, req); 465 } 466 467 #ifdef WLAN_FEATURE_11BE 468 QDF_STATUS wlan_cm_sta_set_chan_param(struct wlan_objmgr_vdev *vdev, 469 qdf_freq_t ch_freq, 470 enum phy_ch_width ori_bw, 471 uint16_t ori_punc, 472 uint8_t ccfs0, uint8_t ccfs1, 473 struct ch_params *chan_param) 474 { 475 uint16_t primary_puncture_bitmap = 0; 476 struct wlan_objmgr_pdev *pdev; 477 struct reg_channel_list chan_list; 478 qdf_freq_t sec_ch_2g_freq = 0; 479 qdf_freq_t center_freq_320 = 0; 480 qdf_freq_t center_freq_40 = 0; 481 uint8_t band_mask; 482 uint16_t new_punc = 0; 483 484 if (!vdev || !chan_param) { 485 mlme_err("invalid input parameters"); 486 return QDF_STATUS_E_INVAL; 487 } 488 pdev = wlan_vdev_get_pdev(vdev); 489 if (!pdev) { 490 mlme_err("invalid pdev"); 491 return QDF_STATUS_E_INVAL; 492 } 493 if (ori_bw == CH_WIDTH_320MHZ) { 494 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) 495 band_mask = BIT(REG_BAND_6G); 496 else 497 band_mask = BIT(REG_BAND_5G); 498 center_freq_320 = wlan_reg_chan_band_to_freq(pdev, ccfs1, 499 band_mask); 500 } else if (ori_bw == CH_WIDTH_40MHZ) { 501 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 502 band_mask = BIT(REG_BAND_2G); 503 center_freq_40 = wlan_reg_chan_band_to_freq(pdev, 504 ccfs0, 505 band_mask); 506 if (center_freq_40 == ch_freq + BW_10_MHZ) 507 sec_ch_2g_freq = ch_freq + BW_20_MHZ; 508 if (center_freq_40 == ch_freq - BW_10_MHZ) 509 sec_ch_2g_freq = ch_freq - BW_20_MHZ; 510 } 511 } 512 wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc, 513 ch_freq, 514 center_freq_320, 515 CH_WIDTH_20MHZ, 516 &primary_puncture_bitmap); 517 if (primary_puncture_bitmap) { 518 mlme_err("sta vdev %d freq %d RX bw %d puncture 0x%x primary chan is punctured", 519 wlan_vdev_get_id(vdev), ch_freq, 520 ori_bw, ori_punc); 521 return QDF_STATUS_E_FAULT; 522 } 523 if (chan_param->ch_width != CH_WIDTH_320MHZ) 524 center_freq_320 = 0; 525 qdf_mem_zero(&chan_list, sizeof(chan_list)); 526 wlan_reg_fill_channel_list_for_pwrmode(pdev, ch_freq, 527 sec_ch_2g_freq, 528 chan_param->ch_width, 529 center_freq_320, &chan_list, 530 REG_CURRENT_PWR_MODE, true); 531 *chan_param = chan_list.chan_param[0]; 532 if (chan_param->ch_width == ori_bw) 533 new_punc = ori_punc; 534 else 535 wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc, 536 ch_freq, 537 chan_param->mhz_freq_seg1, 538 chan_param->ch_width, 539 &new_punc); 540 541 chan_param->reg_punc_bitmap = new_punc; 542 543 return QDF_STATUS_SUCCESS; 544 } 545 546 QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev, 547 uint8_t *peer_mac, 548 uint16_t ori_punc, 549 enum phy_ch_width ori_bw, 550 uint8_t ccfs0, uint8_t ccfs1, 551 enum phy_ch_width new_bw) 552 { 553 struct wlan_channel *des_chan; 554 struct ch_params ch_param; 555 uint32_t bw_puncture = 0; 556 QDF_STATUS status = QDF_STATUS_E_INVAL; 557 558 if (!vdev || !peer_mac) { 559 mlme_err("invalid input parameters"); 560 return status; 561 } 562 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 563 if (!des_chan) { 564 mlme_err("invalid des chan"); 565 return status; 566 } 567 qdf_mem_zero(&ch_param, sizeof(ch_param)); 568 ch_param.ch_width = new_bw; 569 status = wlan_cm_sta_set_chan_param(vdev, des_chan->ch_freq, 570 ori_bw, ori_punc, ccfs0, 571 ccfs1, &ch_param); 572 if (QDF_IS_STATUS_ERROR(status)) 573 return status; 574 575 if (des_chan->puncture_bitmap == ch_param.reg_punc_bitmap && 576 des_chan->ch_width == ch_param.ch_width) 577 return status; 578 579 des_chan->ch_freq_seg1 = ch_param.center_freq_seg0; 580 des_chan->ch_freq_seg2 = ch_param.center_freq_seg1; 581 des_chan->ch_cfreq1 = ch_param.mhz_freq_seg0; 582 des_chan->ch_cfreq2 = ch_param.mhz_freq_seg1; 583 des_chan->puncture_bitmap = ch_param.reg_punc_bitmap; 584 des_chan->ch_width = ch_param.ch_width; 585 mlme_debug("sta vdev %d freq %d bw %d puncture 0x%x ch_cfreq1 %d ch_cfreq2 %d", 586 wlan_vdev_get_id(vdev), des_chan->ch_freq, 587 des_chan->ch_width, des_chan->puncture_bitmap, 588 des_chan->ch_cfreq1, des_chan->ch_cfreq2); 589 QDF_SET_BITS(bw_puncture, 0, 8, des_chan->ch_width); 590 QDF_SET_BITS(bw_puncture, 8, 16, des_chan->puncture_bitmap); 591 return wlan_util_vdev_peer_set_param_send(vdev, peer_mac, 592 WLAN_MLME_PEER_BW_PUNCTURE, 593 bw_puncture); 594 } 595 #endif /* WLAN_FEATURE_11BE */ 596 597 #ifdef WLAN_FEATURE_11BE_MLO 598 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 599 bool 600 wlan_cm_check_mlo_roam_auth_status(struct wlan_objmgr_vdev *vdev) 601 { 602 return mlo_roam_is_auth_status_connected(wlan_vdev_get_psoc(vdev), 603 wlan_vdev_get_id(vdev)); 604 } 605 #endif 606 #endif 607 enum MLO_TYPE 608 wlan_cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc, 609 struct scan_cache_entry *entry, 610 qdf_list_t *scan_list) 611 { 612 return cm_bss_mlo_type(psoc, entry, scan_list); 613 } 614