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_roaming(struct wlan_objmgr_vdev *vdev) 196 { 197 return cm_is_vdev_roaming(vdev); 198 } 199 200 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 201 bool wlan_cm_is_vdev_roam_started(struct wlan_objmgr_vdev *vdev) 202 { 203 return cm_is_vdev_roam_started(vdev); 204 } 205 206 bool wlan_cm_is_vdev_roam_sync_inprogress(struct wlan_objmgr_vdev *vdev) 207 { 208 return cm_is_vdev_roam_sync_inprogress(vdev); 209 } 210 #endif 211 212 #ifdef WLAN_FEATURE_HOST_ROAM 213 bool wlan_cm_is_vdev_roam_preauth_state(struct wlan_objmgr_vdev *vdev) 214 { 215 return cm_is_vdev_roam_preauth_state(vdev); 216 } 217 218 bool wlan_cm_is_vdev_roam_reassoc_state(struct wlan_objmgr_vdev *vdev) 219 { 220 return cm_is_vdev_roam_reassoc_state(vdev); 221 } 222 #endif 223 224 enum wlan_cm_active_request_type 225 wlan_cm_get_active_req_type(struct wlan_objmgr_vdev *vdev) 226 { 227 return cm_get_active_req_type(vdev); 228 } 229 230 bool wlan_cm_get_active_connect_req(struct wlan_objmgr_vdev *vdev, 231 struct wlan_cm_vdev_connect_req *req) 232 { 233 return cm_get_active_connect_req(vdev, req); 234 } 235 236 QDF_STATUS 237 wlan_cm_get_active_connect_req_param(struct wlan_objmgr_vdev *vdev, 238 struct wlan_cm_connect_req *req) 239 { 240 return cm_get_active_connect_req_param(vdev, req); 241 } 242 243 cm_ext_t *wlan_cm_get_ext_hdl(struct wlan_objmgr_vdev *vdev) 244 { 245 return cm_get_ext_hdl(vdev); 246 } 247 248 bool wlan_cm_is_first_candidate_connect_attempt(struct wlan_objmgr_vdev *vdev) 249 { 250 return cm_is_first_candidate_connect_attempt(vdev); 251 } 252 253 #ifdef WLAN_FEATURE_HOST_ROAM 254 bool wlan_cm_get_active_reassoc_req(struct wlan_objmgr_vdev *vdev, 255 struct wlan_cm_vdev_reassoc_req *req) 256 { 257 return cm_get_active_reassoc_req(vdev, req); 258 } 259 #endif 260 261 bool wlan_cm_get_active_disconnect_req(struct wlan_objmgr_vdev *vdev, 262 struct wlan_cm_vdev_discon_req *req) 263 { 264 return cm_get_active_disconnect_req(vdev, req); 265 } 266 267 const char *wlan_cm_reason_code_to_str(enum wlan_reason_code reason) 268 { 269 if (reason > REASON_PROP_START) 270 return ""; 271 272 switch (reason) { 273 CASE_RETURN_STRING(REASON_UNSPEC_FAILURE); 274 CASE_RETURN_STRING(REASON_PREV_AUTH_NOT_VALID); 275 CASE_RETURN_STRING(REASON_DEAUTH_NETWORK_LEAVING); 276 CASE_RETURN_STRING(REASON_DISASSOC_DUE_TO_INACTIVITY); 277 CASE_RETURN_STRING(REASON_DISASSOC_AP_BUSY); 278 CASE_RETURN_STRING(REASON_CLASS2_FRAME_FROM_NON_AUTH_STA); 279 CASE_RETURN_STRING(REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA); 280 CASE_RETURN_STRING(REASON_DISASSOC_NETWORK_LEAVING); 281 CASE_RETURN_STRING(REASON_STA_NOT_AUTHENTICATED); 282 CASE_RETURN_STRING(REASON_BAD_PWR_CAPABILITY); 283 CASE_RETURN_STRING(REASON_BAD_SUPPORTED_CHANNELS); 284 CASE_RETURN_STRING(REASON_DISASSOC_BSS_TRANSITION); 285 CASE_RETURN_STRING(REASON_INVALID_IE); 286 CASE_RETURN_STRING(REASON_MIC_FAILURE); 287 CASE_RETURN_STRING(REASON_4WAY_HANDSHAKE_TIMEOUT); 288 CASE_RETURN_STRING(REASON_GROUP_KEY_UPDATE_TIMEOUT); 289 CASE_RETURN_STRING(REASON_IN_4WAY_DIFFERS); 290 CASE_RETURN_STRING(REASON_INVALID_GROUP_CIPHER); 291 CASE_RETURN_STRING(REASON_INVALID_PAIRWISE_CIPHER); 292 CASE_RETURN_STRING(REASON_INVALID_AKMP); 293 CASE_RETURN_STRING(REASON_UNSUPPORTED_RSNE_VER); 294 CASE_RETURN_STRING(REASON_INVALID_RSNE_CAPABILITIES); 295 CASE_RETURN_STRING(REASON_1X_AUTH_FAILURE); 296 CASE_RETURN_STRING(REASON_CIPHER_SUITE_REJECTED); 297 CASE_RETURN_STRING(REASON_TDLS_PEER_UNREACHABLE); 298 CASE_RETURN_STRING(REASON_TDLS_UNSPEC); 299 CASE_RETURN_STRING(REASON_DISASSOC_SSP_REQUESTED); 300 CASE_RETURN_STRING(REASON_NO_SSP_ROAMING_AGREEMENT); 301 CASE_RETURN_STRING(REASON_BAD_CIPHER_OR_AKM); 302 CASE_RETURN_STRING(REASON_LOCATION_NOT_AUTHORIZED); 303 CASE_RETURN_STRING(REASON_SERVICE_CHANGE_PRECLUDES_TS); 304 CASE_RETURN_STRING(REASON_QOS_UNSPECIFIED); 305 CASE_RETURN_STRING(REASON_NO_BANDWIDTH); 306 CASE_RETURN_STRING(REASON_XS_UNACKED_FRAMES); 307 CASE_RETURN_STRING(REASON_EXCEEDED_TXOP); 308 CASE_RETURN_STRING(REASON_STA_LEAVING); 309 CASE_RETURN_STRING(REASON_END_TS_BA_DLS); 310 CASE_RETURN_STRING(REASON_UNKNOWN_TS_BA); 311 CASE_RETURN_STRING(REASON_TIMEDOUT); 312 CASE_RETURN_STRING(REASON_PEERKEY_MISMATCH); 313 CASE_RETURN_STRING(REASON_AUTHORIZED_ACCESS_LIMIT_REACHED); 314 CASE_RETURN_STRING(REASON_EXTERNAL_SERVICE_REQUIREMENTS); 315 CASE_RETURN_STRING(REASON_INVALID_FT_ACTION_FRAME_COUNT); 316 CASE_RETURN_STRING(REASON_INVALID_PMKID); 317 CASE_RETURN_STRING(REASON_INVALID_MDE); 318 CASE_RETURN_STRING(REASON_INVALID_FTE); 319 CASE_RETURN_STRING(REASON_MESH_PEERING_CANCELLED); 320 CASE_RETURN_STRING(REASON_MESH_MAX_PEERS); 321 CASE_RETURN_STRING(REASON_MESH_CONFIG_POLICY_VIOLATION); 322 CASE_RETURN_STRING(REASON_MESH_CLOSE_RCVD); 323 CASE_RETURN_STRING(REASON_MESH_MAX_RETRIES); 324 CASE_RETURN_STRING(REASON_MESH_CONFIRM_TIMEOUT); 325 CASE_RETURN_STRING(REASON_MESH_INVALID_GTK); 326 CASE_RETURN_STRING(REASON_MESH_INCONSISTENT_PARAMS); 327 CASE_RETURN_STRING(REASON_MESH_INVALID_SECURITY_CAP); 328 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_PROXY_INFO); 329 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_NO_FORWARDING_INFO); 330 CASE_RETURN_STRING(REASON_MESH_PATH_ERROR_DEST_UNREACHABLE); 331 CASE_RETURN_STRING(REASON_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS); 332 CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_REGULATORY_REQ); 333 CASE_RETURN_STRING(REASON_MESH_CHANNEL_SWITCH_UNSPECIFIED); 334 CASE_RETURN_STRING(REASON_POOR_RSSI_CONDITIONS); 335 default: 336 return "Unknown"; 337 } 338 } 339 340 #ifdef WLAN_POLICY_MGR_ENABLE 341 void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, 342 wlan_cm_id cm_id, QDF_STATUS status) 343 { 344 uint32_t prefix; 345 346 prefix = CM_ID_GET_PREFIX(cm_id); 347 if (prefix == ROAM_REQ_PREFIX) 348 cm_reassoc_hw_mode_change_resp(pdev, vdev_id, cm_id, status); 349 else 350 cm_hw_mode_change_resp(pdev, vdev_id, cm_id, status); 351 } 352 #endif /* ifdef POLICY_MGR_ENABLE */ 353 354 #ifdef SM_ENG_HIST_ENABLE 355 void wlan_cm_sm_history_print(struct wlan_objmgr_vdev *vdev) 356 { 357 return cm_sm_history_print(vdev); 358 } 359 360 void wlan_cm_req_history_print(struct wlan_objmgr_vdev *vdev) 361 { 362 struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev); 363 364 if (!cm_ctx) 365 return; 366 367 cm_req_history_print(cm_ctx); 368 } 369 #endif /* SM_ENG_HIST_ENABLE */ 370 371 #ifndef CONN_MGR_ADV_FEATURE 372 void wlan_cm_set_candidate_advance_filter_cb( 373 struct wlan_objmgr_vdev *vdev, 374 void (*filter_fun)(struct wlan_objmgr_vdev *vdev, 375 struct scan_filter *filter)) 376 { 377 cm_set_candidate_advance_filter_cb(vdev, filter_fun); 378 } 379 380 void wlan_cm_set_candidate_custom_sort_cb( 381 struct wlan_objmgr_vdev *vdev, 382 void (*sort_fun)(struct wlan_objmgr_vdev *vdev, 383 qdf_list_t *list)) 384 { 385 cm_set_candidate_custom_sort_cb(vdev, sort_fun); 386 } 387 388 #endif 389 390 QDF_STATUS wlan_cm_get_rnr(struct wlan_objmgr_vdev *vdev, wlan_cm_id cm_id, 391 struct reduced_neighbor_report *rnr) 392 { 393 enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); 394 395 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) { 396 mlme_err("vdev %d Invalid mode %d", 397 wlan_vdev_get_id(vdev), op_mode); 398 return QDF_STATUS_E_NOSUPPORT; 399 } 400 401 return cm_get_rnr(vdev, cm_id, rnr); 402 } 403 404 void 405 wlan_cm_connect_resp_fill_mld_addr_from_cm_id(struct wlan_objmgr_vdev *vdev, 406 wlan_cm_id cm_id, 407 struct wlan_cm_connect_resp *rsp) 408 { 409 return cm_connect_resp_fill_mld_addr_from_cm_id(vdev, cm_id, rsp); 410 } 411 412 #ifdef WLAN_FEATURE_11BE_MLO 413 void 414 wlan_cm_connect_resp_fill_mld_addr_from_vdev_id(struct wlan_objmgr_psoc *psoc, 415 uint8_t vdev_id, 416 struct scan_cache_entry *entry, 417 struct wlan_cm_connect_resp *rsp) 418 { 419 struct wlan_objmgr_vdev *vdev; 420 421 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 422 WLAN_MLME_CM_ID); 423 if (!vdev) 424 return; 425 426 cm_connect_resp_fill_mld_addr_from_candidate(vdev, entry, rsp); 427 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID); 428 } 429 #endif 430 431 QDF_STATUS 432 wlan_cm_disc_cont_after_rso_stop(struct wlan_objmgr_vdev *vdev, 433 struct wlan_cm_vdev_discon_req *req) 434 { 435 return cm_handle_rso_stop_rsp(vdev, req); 436 } 437 438 #ifdef WLAN_FEATURE_11BE 439 QDF_STATUS wlan_cm_sta_set_chan_param(struct wlan_objmgr_vdev *vdev, 440 qdf_freq_t ch_freq, 441 enum phy_ch_width ori_bw, 442 uint16_t ori_punc, 443 uint8_t ccfs0, uint8_t ccfs1, 444 struct ch_params *chan_param) 445 { 446 uint16_t primary_puncture_bitmap = 0; 447 struct wlan_objmgr_pdev *pdev; 448 struct reg_channel_list chan_list; 449 qdf_freq_t sec_ch_2g_freq = 0; 450 qdf_freq_t center_freq_320 = 0; 451 qdf_freq_t center_freq_40 = 0; 452 uint8_t band_mask; 453 uint16_t new_punc = 0; 454 455 if (!vdev || !chan_param) { 456 mlme_err("invalid input parameters"); 457 return QDF_STATUS_E_INVAL; 458 } 459 pdev = wlan_vdev_get_pdev(vdev); 460 if (!pdev) { 461 mlme_err("invalid pdev"); 462 return QDF_STATUS_E_INVAL; 463 } 464 if (ori_bw == CH_WIDTH_320MHZ) { 465 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) 466 band_mask = BIT(REG_BAND_6G); 467 else 468 band_mask = BIT(REG_BAND_5G); 469 center_freq_320 = wlan_reg_chan_band_to_freq(pdev, ccfs1, 470 band_mask); 471 } else if (ori_bw == CH_WIDTH_40MHZ) { 472 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) { 473 band_mask = BIT(REG_BAND_2G); 474 center_freq_40 = wlan_reg_chan_band_to_freq(pdev, 475 ccfs0, 476 band_mask); 477 if (center_freq_40 == ch_freq + BW_10_MHZ) 478 sec_ch_2g_freq = ch_freq + BW_20_MHZ; 479 if (center_freq_40 == ch_freq - BW_10_MHZ) 480 sec_ch_2g_freq = ch_freq - BW_20_MHZ; 481 } 482 } 483 wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc, 484 ch_freq, 485 center_freq_320, 486 CH_WIDTH_20MHZ, 487 &primary_puncture_bitmap); 488 if (primary_puncture_bitmap) { 489 mlme_err("sta vdev %d freq %d RX bw %d puncture 0x%x primary chan is punctured", 490 wlan_vdev_get_id(vdev), ch_freq, 491 ori_bw, ori_punc); 492 return QDF_STATUS_E_FAULT; 493 } 494 if (chan_param->ch_width != CH_WIDTH_320MHZ) 495 center_freq_320 = 0; 496 qdf_mem_zero(&chan_list, sizeof(chan_list)); 497 wlan_reg_fill_channel_list_for_pwrmode(pdev, ch_freq, 498 sec_ch_2g_freq, 499 chan_param->ch_width, 500 center_freq_320, &chan_list, 501 REG_CURRENT_PWR_MODE, true); 502 *chan_param = chan_list.chan_param[0]; 503 if (chan_param->ch_width == ori_bw) 504 new_punc = ori_punc; 505 else 506 wlan_reg_extract_puncture_by_bw(ori_bw, ori_punc, 507 ch_freq, 508 chan_param->mhz_freq_seg1, 509 chan_param->ch_width, 510 &new_punc); 511 512 chan_param->reg_punc_bitmap = new_punc; 513 514 return QDF_STATUS_SUCCESS; 515 } 516 517 QDF_STATUS wlan_cm_sta_update_bw_puncture(struct wlan_objmgr_vdev *vdev, 518 uint8_t *peer_mac, 519 uint16_t ori_punc, 520 enum phy_ch_width ori_bw, 521 uint8_t ccfs0, uint8_t ccfs1, 522 enum phy_ch_width new_bw) 523 { 524 struct wlan_channel *des_chan; 525 struct ch_params ch_param; 526 uint32_t bw_puncture = 0; 527 QDF_STATUS status = QDF_STATUS_E_INVAL; 528 529 if (!vdev || !peer_mac) { 530 mlme_err("invalid input parameters"); 531 return status; 532 } 533 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 534 if (!des_chan) { 535 mlme_err("invalid des chan"); 536 return status; 537 } 538 qdf_mem_zero(&ch_param, sizeof(ch_param)); 539 ch_param.ch_width = new_bw; 540 status = wlan_cm_sta_set_chan_param(vdev, des_chan->ch_freq, 541 ori_bw, ori_punc, ccfs0, 542 ccfs1, &ch_param); 543 if (QDF_IS_STATUS_ERROR(status)) 544 return status; 545 546 if (des_chan->puncture_bitmap == ch_param.reg_punc_bitmap && 547 des_chan->ch_width == ch_param.ch_width) 548 return status; 549 550 des_chan->ch_freq_seg1 = ch_param.center_freq_seg0; 551 des_chan->ch_freq_seg2 = ch_param.center_freq_seg1; 552 des_chan->ch_cfreq1 = ch_param.mhz_freq_seg0; 553 des_chan->ch_cfreq2 = ch_param.mhz_freq_seg1; 554 des_chan->puncture_bitmap = ch_param.reg_punc_bitmap; 555 des_chan->ch_width = ch_param.ch_width; 556 mlme_debug("sta vdev %d freq %d bw %d puncture 0x%x ch_cfreq1 %d ch_cfreq2 %d", 557 wlan_vdev_get_id(vdev), des_chan->ch_freq, 558 des_chan->ch_width, des_chan->puncture_bitmap, 559 des_chan->ch_cfreq1, des_chan->ch_cfreq2); 560 QDF_SET_BITS(bw_puncture, 0, 8, des_chan->ch_width); 561 QDF_SET_BITS(bw_puncture, 8, 16, des_chan->puncture_bitmap); 562 return wlan_util_vdev_peer_set_param_send(vdev, peer_mac, 563 WLAN_MLME_PEER_BW_PUNCTURE, 564 bw_puncture); 565 } 566 #endif /* WLAN_FEATURE_11BE */ 567 568 #ifdef WLAN_FEATURE_11BE_MLO 569 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 570 bool 571 wlan_cm_check_mlo_roam_auth_status(struct wlan_objmgr_vdev *vdev) 572 { 573 return mlo_roam_is_auth_status_connected(wlan_vdev_get_psoc(vdev), 574 wlan_vdev_get_id(vdev)); 575 } 576 #endif 577 #endif 578 enum MLO_TYPE 579 wlan_cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc, 580 struct scan_cache_entry *entry, 581 qdf_list_t *scan_list) 582 { 583 return cm_bss_mlo_type(psoc, entry, scan_list); 584 } 585