1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * DOC: csr_api_roam.c 22 * 23 * Implementation for the Common Roaming interfaces. 24 */ 25 #include "ani_global.h" /* for struct mac_context **/ 26 #include "wma_types.h" 27 #include "wma_if.h" /* for STA_INVALID_IDX. */ 28 #include "csr_inside_api.h" 29 #include <include/wlan_psoc_mlme.h> 30 #include "sme_trace.h" 31 #include "sme_qos_internal.h" 32 #include "sme_inside.h" 33 #include "host_diag_core_event.h" 34 #include "host_diag_core_log.h" 35 #include "csr_api.h" 36 #include "csr_internal.h" 37 #include "cds_reg_service.h" 38 #include "mac_trace.h" 39 #include "cds_regdomain.h" 40 #include "cds_utils.h" 41 #include "sir_types.h" 42 #include "cfg_ucfg_api.h" 43 #include "sme_power_save_api.h" 44 #include "wma.h" 45 #include "wlan_policy_mgr_api.h" 46 #include "sme_nan_datapath.h" 47 #include "pld_common.h" 48 #include "wlan_reg_services_api.h" 49 #include "qdf_crypto.h" 50 #include <wlan_logging_sock_svc.h> 51 #include "wlan_objmgr_psoc_obj.h" 52 #include <wlan_scan_ucfg_api.h> 53 #include <wlan_cp_stats_mc_ucfg_api.h> 54 #include <wlan_tdls_tgt_api.h> 55 #include <wlan_cfg80211_scan.h> 56 #include <wlan_scan_public_structs.h> 57 #include <wlan_action_oui_public_struct.h> 58 #include <wlan_action_oui_ucfg_api.h> 59 #include "wlan_mlme_api.h" 60 #include "wlan_mlme_ucfg_api.h" 61 #include <wlan_utility.h> 62 #include "cfg_mlme.h" 63 #include "wlan_mlme_public_struct.h" 64 #include <wlan_crypto_global_api.h> 65 #include "wlan_qct_sys.h" 66 #include "wlan_dlm_api.h" 67 #include "wlan_policy_mgr_i.h" 68 #include "wlan_scan_utils_api.h" 69 #include "wlan_p2p_cfg_api.h" 70 #include "cfg_nan_api.h" 71 #include "nan_ucfg_api.h" 72 #include <../../core/src/wlan_cm_vdev_api.h> 73 #include "wlan_reg_ucfg_api.h" 74 75 #include <ol_defines.h> 76 #include "wlan_pkt_capture_ucfg_api.h" 77 #include "wlan_psoc_mlme_api.h" 78 #include "wlan_cm_roam_api.h" 79 #include "wlan_if_mgr_public_struct.h" 80 #include "wlan_if_mgr_ucfg_api.h" 81 #include "wlan_if_mgr_roam.h" 82 #include "wlan_roam_debug.h" 83 #include "wlan_cm_roam_public_struct.h" 84 #include "wlan_mlme_twt_api.h" 85 #include <wlan_serialization_api.h> 86 #include <wlan_vdev_mlme_ser_if.h> 87 #include "wlan_mlo_mgr_sta.h" 88 #include "wlan_mlo_mgr_roam.h" 89 90 #define MAX_PWR_FCC_CHAN_12 8 91 #define MAX_PWR_FCC_CHAN_13 2 92 #define MAX_CB_VALUE_IN_INI (2) 93 94 #define MAX_SOCIAL_CHANNELS 3 95 96 /* packet dump timer duration of 60 secs */ 97 #define PKT_DUMP_TIMER_DURATION 60 98 99 #ifdef WLAN_FEATURE_SAE 100 /** 101 * csr_sae_callback - Update SAE info to CSR roam session 102 * @mac_ctx: MAC context 103 * @msg_ptr: pointer to SAE message 104 * 105 * API to update SAE info to roam csr session 106 * 107 * Return: QDF_STATUS 108 */ 109 static QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx, 110 tSirSmeRsp *msg_ptr) 111 { 112 struct csr_roam_info *roam_info; 113 uint32_t session_id; 114 struct sir_sae_info *sae_info; 115 116 sae_info = (struct sir_sae_info *) msg_ptr; 117 if (!sae_info) { 118 sme_err("SAE info is NULL"); 119 return QDF_STATUS_E_FAILURE; 120 } 121 122 sme_debug("vdev_id %d "QDF_MAC_ADDR_FMT, 123 sae_info->vdev_id, 124 QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes)); 125 126 session_id = sae_info->vdev_id; 127 if (session_id == WLAN_UMAC_VDEV_ID_MAX) 128 return QDF_STATUS_E_INVAL; 129 130 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 131 if (!roam_info) 132 return QDF_STATUS_E_FAILURE; 133 134 roam_info->sae_info = sae_info; 135 136 csr_roam_call_callback(mac_ctx, session_id, roam_info, 137 eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE); 138 qdf_mem_free(roam_info); 139 140 return QDF_STATUS_SUCCESS; 141 } 142 #else 143 static inline QDF_STATUS csr_sae_callback(struct mac_context *mac_ctx, 144 tSirSmeRsp *msg_ptr) 145 { 146 return QDF_STATUS_SUCCESS; 147 } 148 #endif 149 150 static const uint32_t 151 social_channel_freq[MAX_SOCIAL_CHANNELS] = { 2412, 2437, 2462 }; 152 153 static void init_config_param(struct mac_context *mac); 154 static QDF_STATUS csr_roam_open(struct mac_context *mac); 155 static QDF_STATUS csr_roam_close(struct mac_context *mac); 156 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo); 157 static QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, 158 tCsr11dinfo *ps11dinfo); 159 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac, 160 struct csr_roam_connectedinfo * 161 pConnectedInfo); 162 static void csr_init_session(struct mac_context *mac, uint32_t sessionId); 163 164 static void csr_init_operating_classes(struct mac_context *mac); 165 166 static void csr_add_len_of_social_channels(struct mac_context *mac, 167 uint8_t *num_chan); 168 static void csr_add_social_channels(struct mac_context *mac, 169 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, 170 uint8_t *num_chan); 171 172 #ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY 173 static struct csr_roam_session *csr_roam_roam_session; 174 175 /* Allocate and initialize global variables */ 176 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac) 177 { 178 uint32_t buf_size; 179 QDF_STATUS status; 180 181 buf_size = WLAN_MAX_VDEVS * sizeof(struct csr_roam_session); 182 183 csr_roam_roam_session = qdf_mem_malloc(buf_size); 184 if (csr_roam_roam_session) { 185 mac->roam.roamSession = csr_roam_roam_session; 186 status = QDF_STATUS_SUCCESS; 187 } else { 188 status = QDF_STATUS_E_NOMEM; 189 } 190 191 return status; 192 } 193 194 /* Free memory allocated dynamically */ 195 static inline void csr_roam_free_globals(void) 196 { 197 qdf_mem_free(csr_roam_roam_session); 198 csr_roam_roam_session = NULL; 199 } 200 201 #else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */ 202 static struct csr_roam_session csr_roam_roam_session[WLAN_MAX_VDEVS]; 203 204 /* Initialize global variables */ 205 static QDF_STATUS csr_roam_init_globals(struct mac_context *mac) 206 { 207 qdf_mem_zero(&csr_roam_roam_session, 208 sizeof(csr_roam_roam_session)); 209 mac->roam.roamSession = csr_roam_roam_session; 210 211 return QDF_STATUS_SUCCESS; 212 } 213 214 static inline void csr_roam_free_globals(void) 215 { 216 } 217 #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */ 218 219 static void csr_roam_de_init_globals(struct mac_context *mac) 220 { 221 csr_roam_free_globals(); 222 mac->roam.roamSession = NULL; 223 } 224 225 /** 226 * csr_roam_lost_link - Process lost link indication 227 * @mac: MAC context 228 * @session_id: Session id of the current session 229 * @type: Type of the indication 230 * @sir_msg: sme response message 231 * 232 * Return: QDF_STATUS 233 */ 234 static 235 QDF_STATUS csr_roam_lost_link(struct mac_context *mac, uint32_t session_id, 236 uint32_t type, tSirSmeRsp *sir_msg) 237 { 238 QDF_STATUS status = QDF_STATUS_SUCCESS; 239 struct deauth_ind *deauth_ind_msg = NULL; 240 struct disassoc_ind *disassoc_ind_msg = NULL; 241 242 sme_debug("vdev_id %d type %d ", session_id, type); 243 244 if (type == eWNI_SME_DISASSOC_IND) { 245 disassoc_ind_msg = (struct disassoc_ind *)sir_msg; 246 status = csr_send_mb_disassoc_cnf_msg(mac, disassoc_ind_msg); 247 } else if (type == eWNI_SME_DEAUTH_IND) { 248 deauth_ind_msg = (struct deauth_ind *)sir_msg; 249 status = csr_send_mb_deauth_cnf_msg(mac, deauth_ind_msg); 250 } 251 252 return status; 253 } 254 255 /** 256 * csr_process_deauth_disassoc_cmd - Process deauth/disassoc command 257 * @mac: MAC context 258 * @sme_cmd: sme command which needs to be processed 259 * 260 * This function processes deauth or disassoc command 261 * 262 * Return: None 263 */ 264 static void csr_process_deauth_disassoc_cmd(struct mac_context *mac, 265 tSmeCmd *sme_cmd) 266 { 267 if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta) { 268 sme_debug("Disassoc vdev_id %d with reason: %d peer " 269 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id, 270 sme_cmd->u.roamCmd.reason, 271 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac)); 272 csr_send_mb_disassoc_req_msg(mac, sme_cmd->vdev_id, 273 sme_cmd->u.roamCmd.peerMac, 274 sme_cmd->u.roamCmd.reason); 275 } else if (sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) { 276 sme_debug("Deauth vdev_id %d with reason: %d peer " 277 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id, 278 sme_cmd->u.roamCmd.reason, 279 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac)); 280 csr_send_mb_deauth_req_msg(mac, sme_cmd->vdev_id, 281 sme_cmd->u.roamCmd.peerMac, 282 sme_cmd->u.roamCmd.reason); 283 } else { 284 sme_info("Invalid command, vdev_id %d reason: %d peer " 285 QDF_MAC_ADDR_FMT, sme_cmd->vdev_id, 286 sme_cmd->u.roamCmd.reason, 287 QDF_MAC_ADDR_REF(sme_cmd->u.roamCmd.peerMac)); 288 } 289 } 290 291 /** 292 * csr_process_wmm_status_change_cmd - Process wmm status change command 293 * @mac: MAC context 294 * @sme_cmd: sme command which needs to be processed 295 * 296 * Return: None 297 */ 298 static void csr_process_wmm_status_change_cmd(struct mac_context *mac, 299 tSmeCmd *sme_cmd) 300 { 301 QDF_STATUS status = QDF_STATUS_E_FAILURE; 302 tSirSmeRsp *sir_msg; 303 304 if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDisassociated) { 305 sir_msg = 306 (tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u. 307 DisassocIndMsg; 308 status = csr_roam_lost_link(mac, sme_cmd->vdev_id, 309 eWNI_SME_DISASSOC_IND, 310 sir_msg); 311 } else if (sme_cmd->u.wmStatusChangeCmd.Type == eCsrDeauthenticated) { 312 sir_msg = (tSirSmeRsp *)&sme_cmd->u.wmStatusChangeCmd.u. 313 DeauthIndMsg; 314 status = csr_roam_lost_link(mac, sme_cmd->vdev_id, 315 eWNI_SME_DEAUTH_IND, 316 sir_msg); 317 } 318 if (QDF_IS_STATUS_ERROR(status)) { 319 sme_info("Failed to issue lost link command, status %d", 320 status); 321 /* 322 * As status returned is not success, there is nothing else 323 * left to do so release WM status change command here. 324 */ 325 csr_roam_wm_status_change_complete(mac, sme_cmd->vdev_id); 326 } 327 } 328 329 /** 330 * csr_get_active_peer_disconnect_command - Get active peer disconnect command 331 * from serialization. 332 * @mac: MAC context 333 * @vdev_id: Vdev id for which active command needs to be return 334 * 335 * Return: None 336 */ 337 static tSmeCmd *csr_get_active_peer_disconnect_command(struct mac_context *mac, 338 uint8_t vdev_id) 339 { 340 tSmeCmd *sme_cmd; 341 342 sme_cmd = wlan_serialization_get_active_cmd( 343 mac->psoc, vdev_id, 344 WLAN_SER_CMD_FORCE_DEAUTH_STA); 345 if (sme_cmd) 346 return sme_cmd; 347 348 sme_cmd = wlan_serialization_get_active_cmd( 349 mac->psoc, vdev_id, 350 WLAN_SER_CMD_FORCE_DISASSOC_STA); 351 if (sme_cmd) 352 return sme_cmd; 353 354 return wlan_serialization_get_active_cmd(mac->psoc, vdev_id, 355 WLAN_SER_CMD_WM_STATUS_CHANGE); 356 } 357 358 /** 359 * csr_continue_peer_disconnect_after_get_stats - Continue peer disconnect after 360 * getting peer disconnect stats 361 * @mac: MAC context 362 * 363 * Process the active serialization command after getting disconnect peer 364 * stats or after peer stats request gets timed out 365 * 366 * Return: None 367 */ 368 static void 369 csr_continue_peer_disconnect_after_get_stats(struct mac_context *mac) 370 { 371 tSmeCmd *sme_cmd; 372 QDF_STATUS status; 373 struct wlan_mlme_psoc_ext_obj *mlme_obj; 374 375 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 376 if (!mlme_obj) { 377 sme_err("NULL mlme psoc object"); 378 return; 379 } 380 381 status = sme_acquire_global_lock(&mac->sme); 382 if (QDF_IS_STATUS_ERROR(status)) { 383 sme_err("can't acquire sme global lock"); 384 return; 385 } 386 387 sme_cmd = csr_get_active_peer_disconnect_command( 388 mac, 389 mlme_obj->disconnect_stats_param.vdev_id); 390 if (!sme_cmd) { 391 sme_err("sme_cmd is NULL"); 392 goto release_lock; 393 } 394 395 if (qdf_atomic_inc_return( 396 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed) > 397 1) { 398 sme_info("Command %d already in process", sme_cmd->command); 399 goto release_lock; 400 } 401 402 switch (sme_cmd->command) { 403 case eSmeCommandRoam: 404 csr_process_deauth_disassoc_cmd(mac, sme_cmd); 405 break; 406 407 case eSmeCommandWmStatusChange: 408 csr_process_wmm_status_change_cmd(mac, sme_cmd); 409 break; 410 default: 411 sme_info("Invalid command %d vdev_id %d", sme_cmd->command, 412 mlme_obj->disconnect_stats_param.vdev_id); 413 } 414 release_lock: 415 sme_release_global_lock(&mac->sme); 416 } 417 418 /** 419 * csr_disconnect_stats_timer_cb - Disconnect stats timer callback 420 * @user_data: Void pointer to mac context 421 * 422 * Return: None 423 */ 424 static void csr_disconnect_stats_timer_cb(void *user_data) 425 { 426 struct mac_context *mac = (struct mac_context *)user_data; 427 428 if (!mac) { 429 sme_err("Invalid mac ctx"); 430 return; 431 } 432 433 sme_debug("Disconnect peer stats timed out"); 434 csr_continue_peer_disconnect_after_get_stats(mac); 435 } 436 437 /** 438 * csr_init_disconnect_stats_timer - Init Disconnect stats timer 439 * @mac: MAC context 440 * 441 * Return: None 442 */ 443 static void csr_init_disconnect_stats_timer(struct mac_context *mac) 444 { 445 struct wlan_mlme_psoc_ext_obj *mlme_obj; 446 447 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 448 if (!mlme_obj) { 449 sme_err("NULL mlme psoc object"); 450 return; 451 } 452 453 qdf_mc_timer_init(&mlme_obj->disconnect_stats_param.disconn_stats_timer, 454 QDF_TIMER_TYPE_SW, 455 csr_disconnect_stats_timer_cb, mac); 456 457 qdf_atomic_init( 458 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed); 459 } 460 461 /** 462 * csr_deinit_disconnect_stats_timer - Deinit Disconnect stats timer 463 * @mac: MAC context 464 * 465 * Return: None 466 */ 467 static void csr_deinit_disconnect_stats_timer(struct mac_context *mac) 468 { 469 struct wlan_mlme_psoc_ext_obj *mlme_obj; 470 471 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 472 if (!mlme_obj) { 473 sme_err("NULL mlme psoc object"); 474 return; 475 } 476 477 if (QDF_TIMER_STATE_RUNNING == 478 qdf_mc_timer_get_current_state( 479 &mlme_obj->disconnect_stats_param.disconn_stats_timer)) 480 qdf_mc_timer_stop( 481 &mlme_obj->disconnect_stats_param.disconn_stats_timer); 482 483 qdf_mc_timer_destroy( 484 &mlme_obj->disconnect_stats_param.disconn_stats_timer); 485 } 486 487 QDF_STATUS csr_open(struct mac_context *mac) 488 { 489 QDF_STATUS status = QDF_STATUS_SUCCESS; 490 uint32_t i; 491 492 do { 493 /* Initialize CSR Roam Globals */ 494 status = csr_roam_init_globals(mac); 495 if (!QDF_IS_STATUS_SUCCESS(status)) 496 break; 497 498 for (i = 0; i < WLAN_MAX_VDEVS; i++) 499 csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, i); 500 501 init_config_param(mac); 502 status = csr_scan_open(mac); 503 if (!QDF_IS_STATUS_SUCCESS(status)) { 504 csr_roam_free_globals(); 505 break; 506 } 507 status = csr_roam_open(mac); 508 if (!QDF_IS_STATUS_SUCCESS(status)) { 509 csr_roam_free_globals(); 510 break; 511 } 512 csr_init_disconnect_stats_timer(mac); 513 } while (0); 514 515 return status; 516 } 517 518 QDF_STATUS csr_init_chan_list(struct mac_context *mac) 519 { 520 QDF_STATUS status; 521 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 522 523 wlan_reg_read_current_country(mac->psoc, reg_cc); 524 sme_debug("init time country code %.2s", reg_cc); 525 526 status = csr_get_channel_and_power_list(mac); 527 528 return status; 529 } 530 531 QDF_STATUS csr_set_channels(struct mac_context *mac, 532 struct csr_config_params *pParam) 533 { 534 QDF_STATUS status = QDF_STATUS_SUCCESS; 535 uint8_t index = 0; 536 537 for (index = 0; index < mac->scan.base_channels.numChannels; 538 index++) { 539 pParam->Csr11dinfo.Channels.channel_freq_list[index] = 540 mac->scan.base_channels.channel_freq_list[index]; 541 pParam->Csr11dinfo.ChnPower[index].first_chan_freq = 542 mac->scan.base_channels.channel_freq_list[index]; 543 pParam->Csr11dinfo.ChnPower[index].numChannels = 1; 544 pParam->Csr11dinfo.ChnPower[index].maxtxPower = 545 mac->scan.defaultPowerTable[index].tx_power; 546 } 547 pParam->Csr11dinfo.Channels.numChannels = 548 mac->scan.base_channels.numChannels; 549 550 return status; 551 } 552 553 QDF_STATUS csr_close(struct mac_context *mac) 554 { 555 QDF_STATUS status = QDF_STATUS_SUCCESS; 556 557 csr_deinit_disconnect_stats_timer(mac); 558 559 csr_roam_close(mac); 560 csr_scan_close(mac); 561 /* DeInit Globals */ 562 csr_roam_de_init_globals(mac); 563 return status; 564 } 565 566 static int8_t 567 csr_find_channel_pwr(struct channel_power *pdefaultPowerTable, 568 uint32_t chan_freq) 569 { 570 uint8_t i; 571 /* TODO: if defaultPowerTable is guaranteed to be in ascending */ 572 /* order of channel numbers, we can employ binary search */ 573 for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) { 574 if (pdefaultPowerTable[i].center_freq == chan_freq) 575 return pdefaultPowerTable[i].tx_power; 576 } 577 /* could not find the channel list in default list */ 578 /* this should not have occurred */ 579 QDF_ASSERT(0); 580 return 0; 581 } 582 583 /** 584 * csr_roam_arrange_ch_list() - Updates the channel list modified with greedy 585 * order for 5 Ghz preference and DFS channels. 586 * @mac_ctx: pointer to mac context. 587 * @chan_list: channel list updated with greedy channel order. 588 * @num_channel: Number of channels in list 589 * 590 * To allow Early Stop Roaming Scan feature to co-exist with 5G preference, 591 * this function moves 5G channels ahead of 2G channels. This function can 592 * also move 2G channels, ahead of DFS channel or vice versa. Order is 593 * maintained among same category channels 594 * 595 * Return: None 596 */ 597 static void csr_roam_arrange_ch_list(struct mac_context *mac_ctx, 598 tSirUpdateChanParam *chan_list, uint8_t num_channel) 599 { 600 bool prefer_5g = CSR_IS_ROAM_PREFER_5GHZ(mac_ctx); 601 bool prefer_dfs = CSR_IS_DFS_CH_ROAM_ALLOWED(mac_ctx); 602 int i, j = 0; 603 tSirUpdateChanParam *tmp_list = NULL; 604 605 if (!prefer_5g) 606 return; 607 608 tmp_list = qdf_mem_malloc(sizeof(tSirUpdateChanParam) * num_channel); 609 if (!tmp_list) 610 return; 611 612 /* Fist copy Non-DFS 5g channels */ 613 for (i = 0; i < num_channel; i++) { 614 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq) && 615 !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 616 chan_list[i].freq)) { 617 qdf_mem_copy(&tmp_list[j++], 618 &chan_list[i], sizeof(tSirUpdateChanParam)); 619 chan_list[i].freq = 0; 620 } 621 } 622 if (prefer_dfs) { 623 /* next copy DFS channels (remaining channels in 5G) */ 624 for (i = 0; i < num_channel; i++) { 625 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_list[i].freq)) { 626 qdf_mem_copy(&tmp_list[j++], &chan_list[i], 627 sizeof(tSirUpdateChanParam)); 628 chan_list[i].freq = 0; 629 } 630 } 631 } else { 632 /* next copy 2G channels */ 633 for (i = 0; i < num_channel; i++) { 634 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_list[i].freq)) { 635 qdf_mem_copy(&tmp_list[j++], &chan_list[i], 636 sizeof(tSirUpdateChanParam)); 637 chan_list[i].freq = 0; 638 } 639 } 640 } 641 /* copy rest of the channels in same order to tmp list */ 642 for (i = 0; i < num_channel; i++) { 643 if (chan_list[i].freq) { 644 qdf_mem_copy(&tmp_list[j++], &chan_list[i], 645 sizeof(tSirUpdateChanParam)); 646 chan_list[i].freq = 0; 647 } 648 } 649 /* copy tmp list to original channel list buffer */ 650 qdf_mem_copy(chan_list, tmp_list, 651 sizeof(tSirUpdateChanParam) * num_channel); 652 qdf_mem_free(tmp_list); 653 } 654 655 /** 656 * csr_roam_sort_channel_for_early_stop() - Sort the channels 657 * @mac_ctx: mac global context 658 * @chan_list: Original channel list from the upper layers 659 * @num_channel: Number of original channels 660 * 661 * For Early stop scan feature, the channel list should be in an order, 662 * where-in there is a maximum chance to detect an AP in the initial 663 * channels in the list so that the scanning can be stopped early as the 664 * feature demands. 665 * Below fixed greedy channel list has been provided 666 * based on most of the enterprise wifi installations across the globe. 667 * 668 * Identify all the greedy channels within the channel list from user space. 669 * Identify all the non-greedy channels in the user space channel list. 670 * Merge greedy channels followed by non-greedy channels back into the 671 * chan_list. 672 * 673 * Return: None 674 */ 675 static void csr_roam_sort_channel_for_early_stop(struct mac_context *mac_ctx, 676 tSirUpdateChanList *chan_list, uint8_t num_channel) 677 { 678 tSirUpdateChanList *chan_list_greedy, *chan_list_non_greedy; 679 uint8_t i, j; 680 static const uint32_t fixed_greedy_freq_list[] = {2412, 2437, 2462, 681 5180, 5240, 5200, 5220, 2457, 2417, 2452, 5745, 5785, 5805, 682 2422, 2427, 2447, 5765, 5825, 2442, 2432, 5680, 5700, 5260, 683 5580, 5280, 5520, 5320, 5300, 5500, 5600, 2472, 2484, 5560, 684 5660, 5755, 5775}; 685 uint8_t num_fixed_greedy_chan; 686 uint8_t num_greedy_chan = 0; 687 uint8_t num_non_greedy_chan = 0; 688 uint8_t match_found = false; 689 uint32_t buf_size; 690 691 buf_size = sizeof(tSirUpdateChanList) + 692 (sizeof(tSirUpdateChanParam) * num_channel); 693 chan_list_greedy = qdf_mem_malloc(buf_size); 694 chan_list_non_greedy = qdf_mem_malloc(buf_size); 695 if (!chan_list_greedy || !chan_list_non_greedy) 696 goto scan_list_sort_error; 697 /* 698 * fixed_greedy_freq_list is an evaluated freq list based on most of 699 * the enterprise wifi deployments and the order of the channels 700 * determines the highest possibility of finding an AP. 701 * chan_list is the channel list provided by upper layers based on the 702 * regulatory domain. 703 */ 704 num_fixed_greedy_chan = sizeof(fixed_greedy_freq_list) / 705 sizeof(uint32_t); 706 /* 707 * Browse through the chan_list and put all the non-greedy channels 708 * into a separate list by name chan_list_non_greedy 709 */ 710 for (i = 0; i < num_channel; i++) { 711 for (j = 0; j < num_fixed_greedy_chan; j++) { 712 if (chan_list->chanParam[i].freq == 713 fixed_greedy_freq_list[j]) { 714 match_found = true; 715 break; 716 } 717 } 718 if (!match_found) { 719 qdf_mem_copy( 720 &chan_list_non_greedy->chanParam[num_non_greedy_chan], 721 &chan_list->chanParam[i], 722 sizeof(tSirUpdateChanParam)); 723 num_non_greedy_chan++; 724 } else { 725 match_found = false; 726 } 727 } 728 /* 729 * Browse through the fixed_greedy_chan_list and put all the greedy 730 * channels in the chan_list into a separate list by name 731 * chan_list_greedy 732 */ 733 for (i = 0; i < num_fixed_greedy_chan; i++) { 734 for (j = 0; j < num_channel; j++) { 735 if (fixed_greedy_freq_list[i] == 736 chan_list->chanParam[j].freq) { 737 qdf_mem_copy( 738 &chan_list_greedy->chanParam[num_greedy_chan], 739 &chan_list->chanParam[j], 740 sizeof(tSirUpdateChanParam)); 741 num_greedy_chan++; 742 break; 743 } 744 } 745 } 746 sme_debug("greedy=%d, non-greedy=%d, tot=%d", num_greedy_chan, 747 num_non_greedy_chan, num_channel); 748 if ((num_greedy_chan + num_non_greedy_chan) != num_channel) { 749 sme_err("incorrect sorting of channels"); 750 goto scan_list_sort_error; 751 } 752 /* Copy the Greedy channels first */ 753 i = 0; 754 qdf_mem_copy(&chan_list->chanParam[i], 755 &chan_list_greedy->chanParam[i], 756 num_greedy_chan * sizeof(tSirUpdateChanParam)); 757 /* Copy the remaining Non Greedy channels */ 758 i = num_greedy_chan; 759 j = 0; 760 qdf_mem_copy(&chan_list->chanParam[i], 761 &chan_list_non_greedy->chanParam[j], 762 num_non_greedy_chan * sizeof(tSirUpdateChanParam)); 763 764 /* Update channel list for 5g preference and allow DFS roam */ 765 csr_roam_arrange_ch_list(mac_ctx, chan_list->chanParam, num_channel); 766 scan_list_sort_error: 767 qdf_mem_free(chan_list_greedy); 768 qdf_mem_free(chan_list_non_greedy); 769 } 770 771 /** 772 * csr_emu_chan_req() - update the required channel list for emulation 773 * @channel: channel number to check 774 * 775 * To reduce scan time during emulation platforms, this function 776 * restricts the scanning to be done on selected channels 777 * 778 * Return: QDF_STATUS enumeration 779 */ 780 #ifdef QCA_WIFI_EMULATION 781 #define SCAN_CHAN_LIST_5G_LEN 6 782 #define SCAN_CHAN_LIST_2G_LEN 3 783 #define SCAN_CHAN_LIST_6G_LEN 3 784 static const uint16_t 785 csr_scan_chan_list_5g[SCAN_CHAN_LIST_5G_LEN] = { 5180, 5220, 5260, 5280, 5700, 5745 }; 786 static const uint16_t 787 csr_scan_chan_list_2g[SCAN_CHAN_LIST_2G_LEN] = { 2412, 2437, 2462 }; 788 static const uint16_t 789 csr_scan_chan_list_6g[SCAN_CHAN_LIST_6G_LEN] = { 6055, 6135, 6215 }; 790 791 static QDF_STATUS csr_emu_chan_req(uint32_t channel) 792 { 793 int i; 794 795 if (WLAN_REG_IS_24GHZ_CH_FREQ(channel)) { 796 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_2g); i++) { 797 if (csr_scan_chan_list_2g[i] == channel) 798 return QDF_STATUS_SUCCESS; 799 } 800 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(channel)) { 801 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_5g); i++) { 802 if (csr_scan_chan_list_5g[i] == channel) 803 return QDF_STATUS_SUCCESS; 804 } 805 } else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(channel)) { 806 for (i = 0; i < QDF_ARRAY_SIZE(csr_scan_chan_list_6g); i++) { 807 if (csr_scan_chan_list_6g[i] == channel) 808 return QDF_STATUS_SUCCESS; 809 } 810 } 811 return QDF_STATUS_E_FAILURE; 812 } 813 #else 814 static QDF_STATUS csr_emu_chan_req(uint32_t channel_num) 815 { 816 return QDF_STATUS_SUCCESS; 817 } 818 #endif 819 820 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY 821 static void csr_add_len_of_social_channels(struct mac_context *mac, 822 uint8_t *num_chan) 823 { 824 uint8_t i; 825 uint8_t no_chan = *num_chan; 826 827 sme_debug("add len of social channels, before adding - num_chan:%hu", 828 *num_chan); 829 if (CSR_IS_5G_BAND_ONLY(mac)) { 830 for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { 831 if (wlan_reg_get_channel_state_for_pwrmode( 832 mac->pdev, social_channel_freq[i], 833 REG_CURRENT_PWR_MODE) == 834 CHANNEL_STATE_ENABLE) 835 no_chan++; 836 } 837 } 838 *num_chan = no_chan; 839 sme_debug("after adding - num_chan:%hu", *num_chan); 840 } 841 842 static void csr_add_social_channels(struct mac_context *mac, 843 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, 844 uint8_t *num_chan) 845 { 846 uint8_t i; 847 uint8_t no_chan = *num_chan; 848 849 sme_debug("add social channels chan_list %pK, num_chan %hu", chan_list, 850 *num_chan); 851 if (CSR_IS_5G_BAND_ONLY(mac)) { 852 for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { 853 if (wlan_reg_get_channel_state_for_pwrmode( 854 mac->pdev, social_channel_freq[i], 855 REG_CURRENT_PWR_MODE) != 856 CHANNEL_STATE_ENABLE) 857 continue; 858 chan_list->chanParam[no_chan].freq = 859 social_channel_freq[i]; 860 chan_list->chanParam[no_chan].pwr = 861 csr_find_channel_pwr(pScan->defaultPowerTable, 862 social_channel_freq[i]); 863 chan_list->chanParam[no_chan].dfsSet = false; 864 if (cds_is_5_mhz_enabled()) 865 chan_list->chanParam[no_chan].quarter_rate 866 = 1; 867 else if (cds_is_10_mhz_enabled()) 868 chan_list->chanParam[no_chan].half_rate = 1; 869 no_chan++; 870 } 871 sme_debug("after adding -num_chan %hu", no_chan); 872 } 873 *num_chan = no_chan; 874 } 875 #else 876 static void csr_add_len_of_social_channels(struct mac_context *mac, 877 uint8_t *num_chan) 878 { 879 sme_debug("skip adding len of social channels"); 880 } 881 static void csr_add_social_channels(struct mac_context *mac, 882 tSirUpdateChanList *chan_list, struct csr_scanstruct *pScan, 883 uint8_t *num_chan) 884 { 885 sme_debug("skip social channels"); 886 } 887 #endif 888 889 /** 890 * csr_scan_event_handler() - callback for scan event 891 * @vdev: wlan objmgr vdev pointer 892 * @event: scan event 893 * @arg: global mac context pointer 894 * 895 * Return: void 896 */ 897 static void csr_scan_event_handler(struct wlan_objmgr_vdev *vdev, 898 struct scan_event *event, 899 void *arg) 900 { 901 bool success = false; 902 QDF_STATUS lock_status; 903 struct mac_context *mac = arg; 904 905 if (!mac) 906 return; 907 908 if (!util_is_scan_completed(event, &success)) 909 return; 910 911 lock_status = sme_acquire_global_lock(&mac->sme); 912 if (QDF_IS_STATUS_ERROR(lock_status)) 913 return; 914 915 if (mac->scan.pending_channel_list_req) 916 csr_update_channel_list(mac); 917 sme_release_global_lock(&mac->sme); 918 } 919 920 /** 921 * csr_update_roam_pcl_per_connected_sta_vdev() - Update roam pcl per connected 922 * STA 923 * @psoc: pointer to psoc object 924 * 925 * Return: None 926 */ 927 static void csr_update_roam_pcl_per_connected_sta_vdev( 928 struct wlan_objmgr_psoc *psoc) 929 { 930 struct wlan_objmgr_vdev *vdev; 931 uint32_t vdev_id; 932 933 for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) { 934 vdev = 935 wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 936 WLAN_LEGACY_SME_ID); 937 938 if (!vdev) 939 continue; 940 941 if (vdev->vdev_mlme.vdev_opmode != QDF_STA_MODE) 942 goto next; 943 944 if (!wlan_cm_is_vdev_connected(vdev)) 945 goto next; 946 947 policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE, 948 vdev_id); 949 next: 950 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 951 } 952 } 953 954 QDF_STATUS csr_update_channel_list(struct mac_context *mac) 955 { 956 tSirUpdateChanList *pChanList; 957 struct csr_scanstruct *pScan = &mac->scan; 958 uint8_t numChan = pScan->base_channels.numChannels; 959 uint8_t num_channel = 0; 960 uint32_t bufLen; 961 struct scheduler_msg msg = {0}; 962 uint8_t i; 963 uint8_t channel_state; 964 uint16_t unsafe_chan[NUM_CHANNELS]; 965 uint16_t unsafe_chan_cnt = 0; 966 uint16_t cnt = 0; 967 uint32_t channel_freq; 968 bool is_unsafe_chan; 969 bool is_same_band; 970 bool is_5mhz_enabled; 971 bool is_10mhz_enabled; 972 enum scm_scan_status scan_status; 973 QDF_STATUS lock_status; 974 struct rso_roam_policy_params *roam_policy; 975 struct wlan_mlme_psoc_ext_obj *mlme_obj; 976 977 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 978 979 if (!qdf_ctx) 980 return QDF_STATUS_E_FAILURE; 981 982 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 983 if (!mlme_obj) 984 return QDF_STATUS_E_FAILURE; 985 roam_policy = &mlme_obj->cfg.lfr.rso_user_config.policy_params; 986 lock_status = sme_acquire_global_lock(&mac->sme); 987 if (QDF_IS_STATUS_ERROR(lock_status)) 988 return lock_status; 989 990 if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { 991 scan_status = wlan_get_pdev_status(mac->pdev); 992 if (scan_status == SCAN_IS_ACTIVE || 993 scan_status == SCAN_IS_ACTIVE_AND_PENDING) { 994 mac->scan.pending_channel_list_req = true; 995 sme_release_global_lock(&mac->sme); 996 sme_debug("scan in progress postpone channel list req "); 997 return QDF_STATUS_SUCCESS; 998 } 999 mac->scan.pending_channel_list_req = false; 1000 } 1001 sme_release_global_lock(&mac->sme); 1002 1003 pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan, 1004 &unsafe_chan_cnt, 1005 sizeof(unsafe_chan)); 1006 1007 csr_add_len_of_social_channels(mac, &numChan); 1008 1009 bufLen = sizeof(tSirUpdateChanList) + 1010 (sizeof(tSirUpdateChanParam) * (numChan)); 1011 1012 csr_init_operating_classes(mac); 1013 pChanList = qdf_mem_malloc(bufLen); 1014 if (!pChanList) 1015 return QDF_STATUS_E_NOMEM; 1016 1017 is_5mhz_enabled = cds_is_5_mhz_enabled(); 1018 if (is_5mhz_enabled) 1019 sme_nofl_debug("quarter_rate enabled"); 1020 is_10mhz_enabled = cds_is_10_mhz_enabled(); 1021 if (is_10mhz_enabled) 1022 sme_nofl_debug("half_rate enabled"); 1023 1024 for (i = 0; i < pScan->base_channels.numChannels; i++) { 1025 if (QDF_STATUS_SUCCESS != 1026 csr_emu_chan_req(pScan->base_channels.channel_freq_list[i])) 1027 continue; 1028 1029 channel_freq = pScan->base_channels.channel_freq_list[i]; 1030 /* Scan is not performed on DSRC channels*/ 1031 if (wlan_reg_is_dsrc_freq(channel_freq)) 1032 continue; 1033 1034 channel_state = 1035 wlan_reg_get_channel_state_for_pwrmode( 1036 mac->pdev, channel_freq, 1037 REG_CURRENT_PWR_MODE); 1038 if ((CHANNEL_STATE_ENABLE == channel_state) || 1039 mac->scan.fEnableDFSChnlScan) { 1040 if (wlan_reg_is_6ghz_chan_freq(channel_freq) && 1041 !wlan_reg_is_6ghz_band_set(mac->pdev)) { 1042 sme_debug("skip 6ghz frequency %d", 1043 channel_freq); 1044 continue; 1045 } 1046 if ((roam_policy->dfs_mode == 1047 STA_ROAM_POLICY_DFS_DISABLED) && 1048 (channel_state == CHANNEL_STATE_DFS)) { 1049 sme_debug("skip dfs channel frequency %d", 1050 channel_freq); 1051 continue; 1052 } 1053 if (roam_policy->skip_unsafe_channels && 1054 unsafe_chan_cnt) { 1055 is_unsafe_chan = false; 1056 for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) { 1057 if (unsafe_chan[cnt] == channel_freq) { 1058 is_unsafe_chan = true; 1059 break; 1060 } 1061 } 1062 is_same_band = 1063 (WLAN_REG_IS_24GHZ_CH_FREQ( 1064 channel_freq) && 1065 roam_policy->sap_operating_band == 1066 BAND_2G) || 1067 (WLAN_REG_IS_5GHZ_CH_FREQ( 1068 channel_freq) && 1069 roam_policy->sap_operating_band == 1070 BAND_5G); 1071 if (is_unsafe_chan && is_same_band) { 1072 sme_debug("ignoring unsafe channel freq %d", 1073 channel_freq); 1074 continue; 1075 } 1076 } 1077 pChanList->chanParam[num_channel].freq = 1078 pScan->base_channels.channel_freq_list[i]; 1079 pChanList->chanParam[num_channel].pwr = 1080 csr_find_channel_pwr( 1081 pScan->defaultPowerTable, 1082 pScan->base_channels.channel_freq_list[i]); 1083 1084 if (pScan->fcc_constraint) { 1085 if (2467 == 1086 pScan->base_channels.channel_freq_list[i]) { 1087 pChanList->chanParam[num_channel].pwr = 1088 MAX_PWR_FCC_CHAN_12; 1089 sme_debug("txpow for channel 12 is %d", 1090 MAX_PWR_FCC_CHAN_12); 1091 } 1092 if (2472 == 1093 pScan->base_channels.channel_freq_list[i]) { 1094 pChanList->chanParam[num_channel].pwr = 1095 MAX_PWR_FCC_CHAN_13; 1096 sme_debug("txpow for channel 13 is %d", 1097 MAX_PWR_FCC_CHAN_13); 1098 } 1099 } 1100 1101 if (!ucfg_is_nan_allowed_on_freq(mac->pdev, 1102 pChanList->chanParam[num_channel].freq)) 1103 pChanList->chanParam[num_channel].nan_disabled = 1104 true; 1105 1106 if (CHANNEL_STATE_DFS == channel_state) 1107 pChanList->chanParam[num_channel].dfsSet = 1108 true; 1109 1110 pChanList->chanParam[num_channel].quarter_rate = 1111 is_5mhz_enabled; 1112 1113 pChanList->chanParam[num_channel].half_rate = 1114 is_10mhz_enabled; 1115 1116 num_channel++; 1117 } 1118 } 1119 1120 csr_add_social_channels(mac, pChanList, pScan, &num_channel); 1121 1122 if (mac->mlme_cfg->lfr.early_stop_scan_enable) 1123 csr_roam_sort_channel_for_early_stop(mac, pChanList, 1124 num_channel); 1125 else 1126 sme_debug("Early Stop Scan Feature not supported"); 1127 1128 if ((mac->roam.configParam.uCfgDot11Mode == 1129 eCSR_CFG_DOT11_MODE_AUTO) || 1130 (mac->roam.configParam.uCfgDot11Mode == 1131 eCSR_CFG_DOT11_MODE_11AC) || 1132 (mac->roam.configParam.uCfgDot11Mode == 1133 eCSR_CFG_DOT11_MODE_11AC_ONLY)) { 1134 pChanList->vht_en = true; 1135 if (mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) 1136 pChanList->vht_24_en = true; 1137 } 1138 if ((mac->roam.configParam.uCfgDot11Mode == 1139 eCSR_CFG_DOT11_MODE_AUTO) || 1140 (mac->roam.configParam.uCfgDot11Mode == 1141 eCSR_CFG_DOT11_MODE_11N) || 1142 (mac->roam.configParam.uCfgDot11Mode == 1143 eCSR_CFG_DOT11_MODE_11N_ONLY)) { 1144 pChanList->ht_en = true; 1145 } 1146 if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) || 1147 (mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AX) || 1148 (mac->roam.configParam.uCfgDot11Mode == 1149 eCSR_CFG_DOT11_MODE_11AX_ONLY)) 1150 pChanList->he_en = true; 1151 #ifdef WLAN_FEATURE_11BE 1152 if ((mac->roam.configParam.uCfgDot11Mode == eCSR_CFG_DOT11_MODE_AUTO) || 1153 CSR_IS_CFG_DOT11_PHY_MODE_11BE( 1154 mac->roam.configParam.uCfgDot11Mode) || 1155 CSR_IS_CFG_DOT11_PHY_MODE_11BE_ONLY( 1156 mac->roam.configParam.uCfgDot11Mode)) 1157 pChanList->eht_en = true; 1158 #endif 1159 1160 pChanList->numChan = num_channel; 1161 mlme_store_fw_scan_channels(mac->psoc, pChanList); 1162 1163 msg.type = WMA_UPDATE_CHAN_LIST_REQ; 1164 msg.reserved = 0; 1165 msg.bodyptr = pChanList; 1166 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 1167 NO_SESSION, msg.type)); 1168 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 1169 QDF_MODULE_ID_WMA, 1170 QDF_MODULE_ID_WMA, 1171 &msg)) { 1172 qdf_mem_free(pChanList); 1173 return QDF_STATUS_E_FAILURE; 1174 } 1175 1176 csr_update_roam_pcl_per_connected_sta_vdev(mac->psoc); 1177 return QDF_STATUS_SUCCESS; 1178 } 1179 1180 QDF_STATUS csr_start(struct mac_context *mac) 1181 { 1182 QDF_STATUS status = QDF_STATUS_SUCCESS; 1183 uint32_t i; 1184 1185 do { 1186 for (i = 0; i < WLAN_MAX_VDEVS; i++) 1187 csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, i); 1188 1189 mac->roam.sPendingCommands = 0; 1190 1191 if (mac->mlme_cfg->reg.enable_pending_chan_list_req) { 1192 status = ucfg_scan_register_event_handler(mac->pdev, 1193 csr_scan_event_handler, mac); 1194 1195 if (QDF_IS_STATUS_ERROR(status)) 1196 sme_err("scan event registration failed "); 1197 } 1198 } while (0); 1199 return status; 1200 } 1201 1202 QDF_STATUS csr_stop(struct mac_context *mac) 1203 { 1204 uint32_t sessionId; 1205 1206 if (mac->mlme_cfg->reg.enable_pending_chan_list_req) 1207 ucfg_scan_unregister_event_handler(mac->pdev, 1208 csr_scan_event_handler, 1209 mac); 1210 wlan_scan_psoc_set_disable(mac->psoc, REASON_SYSTEM_DOWN); 1211 1212 /* 1213 * purge all serialization command if there are any pending to make 1214 * sure memory and vdev ref are freed. 1215 */ 1216 csr_purge_pdev_all_ser_cmd_list(mac); 1217 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) 1218 csr_cleanup_vdev_session(mac, sessionId); 1219 1220 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) 1221 if (CSR_IS_SESSION_VALID(mac, sessionId)) 1222 ucfg_scan_flush_results(mac->pdev, NULL); 1223 1224 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) { 1225 csr_roam_state_change(mac, eCSR_ROAMING_STATE_STOP, sessionId); 1226 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, 1227 sessionId); 1228 } 1229 1230 return QDF_STATUS_SUCCESS; 1231 } 1232 1233 QDF_STATUS csr_ready(struct mac_context *mac) 1234 { 1235 QDF_STATUS status = QDF_STATUS_SUCCESS; 1236 /* If the gScanAgingTime is set to '0' then scan results aging timeout 1237 * based on timer feature is not enabled 1238 */ 1239 status = csr_apply_channel_and_power_list(mac); 1240 if (!QDF_IS_STATUS_SUCCESS(status)) 1241 sme_err("csr_apply_channel_and_power_list failed status: %d", 1242 status); 1243 1244 return status; 1245 } 1246 1247 void csr_set_default_dot11_mode(struct mac_context *mac) 1248 { 1249 mac->mlme_cfg->dot11_mode.dot11_mode = 1250 csr_translate_to_wni_cfg_dot11_mode(mac, 1251 mac->roam.configParam.uCfgDot11Mode); 1252 } 1253 1254 void csr_set_global_cfgs(struct mac_context *mac) 1255 { 1256 wlan_mlme_set_frag_threshold(mac->psoc, csr_get_frag_thresh(mac)); 1257 wlan_mlme_set_rts_threshold(mac->psoc, csr_get_rts_thresh(mac)); 1258 /* For now we will just use the 5GHz CB mode ini parameter to decide 1259 * whether CB supported or not in Probes when there is no session 1260 * Once session is established we will use the session related params 1261 * stored in PE session for CB mode 1262 */ 1263 if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_5GHZ, 1264 mac->roam.configParam.channelBondingMode5GHz)) 1265 ucfg_mlme_set_channel_bonding_5ghz(mac->psoc, 1266 mac->roam.configParam. 1267 channelBondingMode5GHz); 1268 if (cfg_in_range(CFG_CHANNEL_BONDING_MODE_24GHZ, 1269 mac->roam.configParam.channelBondingMode24GHz)) 1270 ucfg_mlme_set_channel_bonding_24ghz(mac->psoc, 1271 mac->roam.configParam. 1272 channelBondingMode24GHz); 1273 1274 mac->mlme_cfg->timeouts.heart_beat_threshold = 1275 cfg_default(CFG_HEART_BEAT_THRESHOLD); 1276 1277 /* Update the operating mode to configured value during 1278 * initialization, So that client can advertise full 1279 * capabilities in Probe request frame. 1280 */ 1281 csr_set_default_dot11_mode(mac); 1282 } 1283 1284 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) && \ 1285 defined(CONNECTIVITY_PKTLOG) 1286 /** 1287 * csr_packetdump_timer_handler() - packet dump timer 1288 * handler 1289 * @pv: user data 1290 * 1291 * This function is used to handle packet dump timer 1292 * 1293 * Return: None 1294 * 1295 */ 1296 static void csr_packetdump_timer_handler(void *pv) 1297 { 1298 sme_debug("Invoking packetdump deregistration API"); 1299 wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID); 1300 } 1301 1302 void csr_packetdump_timer_start(void) 1303 { 1304 QDF_STATUS status; 1305 mac_handle_t mac_handle; 1306 struct mac_context *mac; 1307 QDF_TIMER_STATE cur_state; 1308 1309 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1310 mac = MAC_CONTEXT(mac_handle); 1311 if (!mac) { 1312 QDF_ASSERT(0); 1313 return; 1314 } 1315 cur_state = qdf_mc_timer_get_current_state(&mac->roam.packetdump_timer); 1316 if (cur_state == QDF_TIMER_STATE_STARTING || 1317 cur_state == QDF_TIMER_STATE_STARTING) { 1318 sme_debug("packetdump_timer is already started: %d", cur_state); 1319 return; 1320 } 1321 1322 status = qdf_mc_timer_start(&mac->roam.packetdump_timer, 1323 (PKT_DUMP_TIMER_DURATION * 1324 QDF_MC_TIMER_TO_SEC_UNIT) / 1325 QDF_MC_TIMER_TO_MS_UNIT); 1326 if (!QDF_IS_STATUS_SUCCESS(status)) 1327 sme_debug("cannot start packetdump timer status: %d", status); 1328 } 1329 1330 void csr_packetdump_timer_stop(void) 1331 { 1332 QDF_STATUS status; 1333 mac_handle_t mac_handle; 1334 struct mac_context *mac; 1335 1336 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 1337 mac = MAC_CONTEXT(mac_handle); 1338 if (!mac) { 1339 QDF_ASSERT(0); 1340 return; 1341 } 1342 1343 status = qdf_mc_timer_stop(&mac->roam.packetdump_timer); 1344 if (!QDF_IS_STATUS_SUCCESS(status)) 1345 sme_err("cannot stop packetdump timer"); 1346 } 1347 1348 static QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac) 1349 { 1350 QDF_STATUS status = QDF_STATUS_SUCCESS; 1351 1352 if (!mac) { 1353 QDF_ASSERT(0); 1354 return -EINVAL; 1355 } 1356 1357 status = qdf_mc_timer_init(&mac->roam.packetdump_timer, 1358 QDF_TIMER_TYPE_SW, 1359 csr_packetdump_timer_handler, 1360 mac); 1361 if (!QDF_IS_STATUS_SUCCESS(status)) { 1362 sme_err("cannot allocate memory for packetdump timer"); 1363 return status; 1364 } 1365 1366 return status; 1367 } 1368 1369 static void csr_packetdump_timer_deinit(struct mac_context *mac) 1370 { 1371 if (!mac) { 1372 QDF_ASSERT(0); 1373 return; 1374 } 1375 1376 qdf_mc_timer_stop(&mac->roam.packetdump_timer); 1377 qdf_mc_timer_destroy(&mac->roam.packetdump_timer); 1378 } 1379 #else 1380 static inline QDF_STATUS csr_packetdump_timer_init(struct mac_context *mac) 1381 { 1382 return QDF_STATUS_SUCCESS; 1383 } 1384 1385 static inline void csr_packetdump_timer_deinit(struct mac_context *mac) {} 1386 #endif 1387 1388 static QDF_STATUS csr_roam_open(struct mac_context *mac) 1389 { 1390 QDF_STATUS status = QDF_STATUS_SUCCESS; 1391 1392 status = csr_packetdump_timer_init(mac); 1393 if (QDF_IS_STATUS_ERROR(status)) 1394 return status; 1395 1396 spin_lock_init(&mac->roam.roam_state_lock); 1397 1398 return status; 1399 } 1400 1401 static QDF_STATUS csr_roam_close(struct mac_context *mac) 1402 { 1403 uint32_t sessionId; 1404 struct csr_roam_session *session; 1405 1406 /* 1407 * purge all serialization command if there are any pending to make 1408 * sure memory and vdev ref are freed. 1409 */ 1410 csr_purge_pdev_all_ser_cmd_list(mac); 1411 for (sessionId = 0; sessionId < WLAN_MAX_VDEVS; sessionId++) { 1412 session = CSR_GET_SESSION(mac, sessionId); 1413 if (!session) 1414 continue; 1415 csr_cleanup_vdev_session(mac, sessionId); 1416 } 1417 1418 csr_packetdump_timer_deinit(mac); 1419 return QDF_STATUS_SUCCESS; 1420 } 1421 1422 static QDF_STATUS csr_roam_free_connected_info(struct mac_context *mac, 1423 struct csr_roam_connectedinfo * 1424 pConnectedInfo) 1425 { 1426 QDF_STATUS status = QDF_STATUS_SUCCESS; 1427 1428 if (pConnectedInfo->pbFrames) { 1429 qdf_mem_free(pConnectedInfo->pbFrames); 1430 pConnectedInfo->pbFrames = NULL; 1431 } 1432 pConnectedInfo->nBeaconLength = 0; 1433 pConnectedInfo->nAssocReqLength = 0; 1434 pConnectedInfo->nAssocRspLength = 0; 1435 pConnectedInfo->nRICRspLength = 0; 1436 #ifdef FEATURE_WLAN_ESE 1437 pConnectedInfo->nTspecIeLength = 0; 1438 #endif 1439 return status; 1440 } 1441 1442 void csr_release_command_roam(struct mac_context *mac, tSmeCmd *pCommand) 1443 { 1444 csr_reinit_roam_cmd(mac, pCommand); 1445 } 1446 1447 void csr_release_command_wm_status_change(struct mac_context *mac, 1448 tSmeCmd *pCommand) 1449 { 1450 csr_reinit_wm_status_change_cmd(mac, pCommand); 1451 } 1452 1453 void csr_roam_substate_change(struct mac_context *mac, 1454 enum csr_roam_substate NewSubstate, uint32_t sessionId) 1455 { 1456 if (sessionId >= WLAN_MAX_VDEVS) { 1457 sme_err("Invalid no of concurrent sessions %d", 1458 sessionId); 1459 return; 1460 } 1461 if (mac->roam.curSubState[sessionId] == NewSubstate) 1462 return; 1463 sme_nofl_debug("CSR RoamSubstate: [ %s <== %s ]", 1464 mac_trace_getcsr_roam_sub_state(NewSubstate), 1465 mac_trace_getcsr_roam_sub_state(mac->roam. 1466 curSubState[sessionId])); 1467 spin_lock(&mac->roam.roam_state_lock); 1468 mac->roam.curSubState[sessionId] = NewSubstate; 1469 spin_unlock(&mac->roam.roam_state_lock); 1470 } 1471 1472 enum csr_roam_state csr_roam_state_change(struct mac_context *mac, 1473 enum csr_roam_state NewRoamState, 1474 uint8_t sessionId) 1475 { 1476 enum csr_roam_state PreviousState; 1477 1478 PreviousState = mac->roam.curState[sessionId]; 1479 1480 if (NewRoamState == mac->roam.curState[sessionId]) 1481 return PreviousState; 1482 1483 sme_nofl_debug("CSR RoamState[%d]: [ %s <== %s ]", sessionId, 1484 mac_trace_getcsr_roam_state(NewRoamState), 1485 mac_trace_getcsr_roam_state( 1486 mac->roam.curState[sessionId])); 1487 /* 1488 * Whenever we transition OUT of the Roaming state, 1489 * clear the Roaming substate. 1490 */ 1491 if (CSR_IS_ROAM_JOINING(mac, sessionId)) { 1492 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, 1493 sessionId); 1494 } 1495 1496 mac->roam.curState[sessionId] = NewRoamState; 1497 1498 return PreviousState; 1499 } 1500 1501 static void init_config_param(struct mac_context *mac) 1502 { 1503 mac->roam.configParam.channelBondingMode24GHz = 1504 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; 1505 mac->roam.configParam.channelBondingMode5GHz = 1506 WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; 1507 1508 mac->roam.configParam.phyMode = eCSR_DOT11_MODE_AUTO; 1509 mac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO; 1510 mac->roam.configParam.HeartbeatThresh50 = 40; 1511 mac->roam.configParam.Is11eSupportEnabled = true; 1512 mac->roam.configParam.WMMSupportMode = WMM_USER_MODE_AUTO; 1513 mac->roam.configParam.ProprietaryRatesEnabled = true; 1514 1515 mac->roam.configParam.nVhtChannelWidth = 1516 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1; 1517 } 1518 1519 /** 1520 * csr_flush_roam_scan_chan_lists() - Flush the roam channel lists 1521 * @mac: Global MAC context 1522 * @vdev_id: vdev id 1523 * 1524 * Flush the roam channel lists pref_chan_info and specific_chan_info. 1525 * 1526 * Return: None 1527 */ 1528 static void 1529 csr_flush_roam_scan_chan_lists(struct mac_context *mac, uint8_t vdev_id) 1530 { 1531 struct wlan_objmgr_vdev *vdev; 1532 struct rso_config *rso_cfg; 1533 struct rso_cfg_params *cfg_params; 1534 1535 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, 1536 WLAN_LEGACY_SME_ID); 1537 if (!vdev) 1538 return; 1539 1540 rso_cfg = wlan_cm_get_rso_config(vdev); 1541 if (!rso_cfg) { 1542 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1543 return; 1544 } 1545 cfg_params = &rso_cfg->cfg_param; 1546 wlan_cm_flush_roam_channel_list(&cfg_params->pref_chan_info); 1547 wlan_cm_flush_roam_channel_list(&cfg_params->specific_chan_info); 1548 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1549 } 1550 1551 #ifdef FEATURE_WLAN_ESE 1552 /** 1553 * csr_roam_is_ese_assoc() - is this ese association 1554 * @mac_ctx: Global MAC context 1555 * @session_id: session identifier 1556 * 1557 * Returns whether the current association is a ESE assoc or not. 1558 * 1559 * Return: true if ese association; false otherwise 1560 */ 1561 bool csr_roam_is_ese_assoc(struct mac_context *mac_ctx, uint32_t session_id) 1562 { 1563 return wlan_cm_get_ese_assoc(mac_ctx->pdev, session_id); 1564 } 1565 1566 1567 /** 1568 * csr_tsm_stats_rsp_processor() - tsm stats response processor 1569 * @mac: Global MAC context 1570 * @pMsg: Message pointer 1571 * 1572 * Return: None 1573 */ 1574 static void csr_tsm_stats_rsp_processor(struct mac_context *mac, void *pMsg) 1575 { 1576 tAniGetTsmStatsRsp *pTsmStatsRsp = (tAniGetTsmStatsRsp *) pMsg; 1577 1578 if (pTsmStatsRsp) { 1579 /* 1580 * Get roam Rssi request is backed up and passed back 1581 * to the response, Extract the request message 1582 * to fetch callback. 1583 */ 1584 tpAniGetTsmStatsReq reqBkp 1585 = (tAniGetTsmStatsReq *) pTsmStatsRsp->tsmStatsReq; 1586 1587 if (reqBkp) { 1588 if (reqBkp->tsmStatsCallback) { 1589 ((tCsrTsmStatsCallback) 1590 (reqBkp->tsmStatsCallback))(pTsmStatsRsp-> 1591 tsmMetrics, 1592 reqBkp-> 1593 pDevContext); 1594 reqBkp->tsmStatsCallback = NULL; 1595 } 1596 qdf_mem_free(reqBkp); 1597 pTsmStatsRsp->tsmStatsReq = NULL; 1598 } else { 1599 if (reqBkp) { 1600 qdf_mem_free(reqBkp); 1601 pTsmStatsRsp->tsmStatsReq = NULL; 1602 } 1603 } 1604 } else { 1605 sme_err("pTsmStatsRsp is NULL"); 1606 } 1607 } 1608 1609 /** 1610 * csr_send_ese_adjacent_ap_rep_ind() - ese send adjacent ap report 1611 * @mac: Global MAC context 1612 * @pSession: Session pointer 1613 * 1614 * Return: None 1615 */ 1616 static void csr_send_ese_adjacent_ap_rep_ind(struct mac_context *mac, 1617 struct csr_roam_session *pSession) 1618 { 1619 uint32_t roamTS2 = 0; 1620 struct csr_roam_info *roam_info; 1621 struct pe_session *pe_session = NULL; 1622 uint8_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 1623 struct qdf_mac_addr connected_bssid; 1624 1625 if (!pSession) { 1626 sme_err("pSession is NULL"); 1627 return; 1628 } 1629 1630 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 1631 if (!roam_info) 1632 return; 1633 roamTS2 = qdf_mc_timer_get_system_time(); 1634 roam_info->tsmRoamDelay = roamTS2 - pSession->roamTS1; 1635 wlan_mlme_get_bssid_vdev_id(mac->pdev, pSession->vdev_id, 1636 &connected_bssid); 1637 sme_debug("Bssid(" QDF_MAC_ADDR_FMT ") Roaming Delay(%u ms)", 1638 QDF_MAC_ADDR_REF(connected_bssid.bytes), 1639 roam_info->tsmRoamDelay); 1640 1641 pe_session = pe_find_session_by_bssid(mac, connected_bssid.bytes, 1642 &sessionId); 1643 if (!pe_session) { 1644 sme_err("session %d not found", sessionId); 1645 qdf_mem_free(roam_info); 1646 return; 1647 } 1648 1649 pe_session->eseContext.tsm.tsmMetrics.RoamingDly 1650 = roam_info->tsmRoamDelay; 1651 1652 csr_roam_call_callback(mac, pSession->vdev_id, roam_info, 1653 eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0); 1654 qdf_mem_free(roam_info); 1655 } 1656 1657 /** 1658 * csr_get_tsm_stats() - get tsm stats 1659 * @mac: Global MAC context 1660 * @callback: TSM stats callback 1661 * @staId: Station id 1662 * @bssId: bssid 1663 * @pContext: pointer to context 1664 * @tid: traffic id 1665 * 1666 * Return: QDF_STATUS enumeration 1667 */ 1668 QDF_STATUS csr_get_tsm_stats(struct mac_context *mac, 1669 tCsrTsmStatsCallback callback, 1670 struct qdf_mac_addr bssId, 1671 void *pContext, uint8_t tid) 1672 { 1673 QDF_STATUS status = QDF_STATUS_SUCCESS; 1674 tAniGetTsmStatsReq *pMsg = NULL; 1675 1676 pMsg = qdf_mem_malloc(sizeof(tAniGetTsmStatsReq)); 1677 if (!pMsg) { 1678 return QDF_STATUS_E_NOMEM; 1679 } 1680 /* need to initiate a stats request to PE */ 1681 pMsg->msgType = eWNI_SME_GET_TSM_STATS_REQ; 1682 pMsg->msgLen = (uint16_t) sizeof(tAniGetTsmStatsReq); 1683 pMsg->tid = tid; 1684 qdf_copy_macaddr(&pMsg->bssId, &bssId); 1685 pMsg->tsmStatsCallback = callback; 1686 pMsg->pDevContext = pContext; 1687 status = umac_send_mb_message_to_mac(pMsg); 1688 if (!QDF_IS_STATUS_SUCCESS(status)) { 1689 sme_debug("Failed to send down the TSM req (status=%d)", status); 1690 /* pMsg is freed by cds_send_mb_message_to_mac */ 1691 status = QDF_STATUS_E_FAILURE; 1692 } 1693 return status; 1694 } 1695 #endif /* FEATURE_WLAN_ESE */ 1696 1697 /* The funcns csr_convert_cb_ini_value_to_phy_cb_state and 1698 * csr_convert_phy_cb_state_to_ini_value have been introduced 1699 * to convert the ini value to the ENUM used in csr and MAC for CB state 1700 * Ideally we should have kept the ini value and enum value same and 1701 * representing the same cb values as in 11n standard i.e. 1702 * Set to 1 (SCA) if the secondary channel is above the primary channel 1703 * Set to 3 (SCB) if the secondary channel is below the primary channel 1704 * Set to 0 (SCN) if no secondary channel is present 1705 * However, since our driver is already distributed we will keep the ini 1706 * definition as it is which is: 1707 * 0 - secondary none 1708 * 1 - secondary LOW 1709 * 2 - secondary HIGH 1710 * and convert to enum value used within the driver in 1711 * csr_change_default_config_param using this funcn 1712 * The enum values are as follows: 1713 * PHY_SINGLE_CHANNEL_CENTERED = 0 1714 * PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1 1715 * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 1716 */ 1717 ePhyChanBondState csr_convert_cb_ini_value_to_phy_cb_state(uint32_t cbIniValue) 1718 { 1719 1720 ePhyChanBondState phyCbState; 1721 1722 switch (cbIniValue) { 1723 /* secondary none */ 1724 case eCSR_INI_SINGLE_CHANNEL_CENTERED: 1725 phyCbState = PHY_SINGLE_CHANNEL_CENTERED; 1726 break; 1727 /* secondary LOW */ 1728 case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: 1729 phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; 1730 break; 1731 /* secondary HIGH */ 1732 case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: 1733 phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; 1734 break; 1735 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: 1736 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; 1737 break; 1738 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: 1739 phyCbState = 1740 PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; 1741 break; 1742 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: 1743 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; 1744 break; 1745 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 1746 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; 1747 break; 1748 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 1749 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; 1750 break; 1751 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 1752 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; 1753 break; 1754 case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 1755 phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; 1756 break; 1757 default: 1758 /* If an invalid value is passed, disable CHANNEL BONDING */ 1759 phyCbState = PHY_SINGLE_CHANNEL_CENTERED; 1760 break; 1761 } 1762 return phyCbState; 1763 } 1764 1765 static 1766 uint32_t csr_convert_phy_cb_state_to_ini_value(ePhyChanBondState phyCbState) 1767 { 1768 uint32_t cbIniValue; 1769 1770 switch (phyCbState) { 1771 /* secondary none */ 1772 case PHY_SINGLE_CHANNEL_CENTERED: 1773 cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED; 1774 break; 1775 /* secondary LOW */ 1776 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 1777 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; 1778 break; 1779 /* secondary HIGH */ 1780 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 1781 cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; 1782 break; 1783 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: 1784 cbIniValue = 1785 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; 1786 break; 1787 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: 1788 cbIniValue = 1789 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; 1790 break; 1791 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: 1792 cbIniValue = 1793 eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; 1794 break; 1795 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: 1796 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; 1797 break; 1798 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: 1799 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; 1800 break; 1801 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: 1802 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; 1803 break; 1804 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: 1805 cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; 1806 break; 1807 default: 1808 /* return some invalid value */ 1809 cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX; 1810 break; 1811 } 1812 return cbIniValue; 1813 } 1814 1815 #ifdef WLAN_FEATURE_11BE 1816 void csr_update_session_eht_cap(struct mac_context *mac_ctx, 1817 struct csr_roam_session *session) 1818 { 1819 tDot11fIEeht_cap *eht_cap; 1820 struct wlan_objmgr_vdev *vdev; 1821 struct mlme_legacy_priv *mlme_priv; 1822 1823 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 1824 session->vdev_id, 1825 WLAN_LEGACY_SME_ID); 1826 if (!vdev) 1827 return; 1828 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 1829 if (!mlme_priv) { 1830 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1831 return; 1832 } 1833 qdf_mem_copy(&mlme_priv->eht_config, 1834 &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap, 1835 sizeof(mlme_priv->eht_config)); 1836 eht_cap = &mlme_priv->eht_config; 1837 eht_cap->present = true; 1838 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1839 } 1840 #endif 1841 1842 #ifdef WLAN_FEATURE_11AX 1843 void csr_update_session_he_cap(struct mac_context *mac_ctx, 1844 struct csr_roam_session *session) 1845 { 1846 enum QDF_OPMODE persona; 1847 tDot11fIEhe_cap *he_cap; 1848 struct wlan_objmgr_vdev *vdev; 1849 struct mlme_legacy_priv *mlme_priv; 1850 1851 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 1852 session->vdev_id, 1853 WLAN_LEGACY_SME_ID); 1854 if (!vdev) 1855 return; 1856 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 1857 if (!mlme_priv) { 1858 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1859 return; 1860 } 1861 qdf_mem_copy(&mlme_priv->he_config, 1862 &mac_ctx->mlme_cfg->he_caps.dot11_he_cap, 1863 sizeof(mlme_priv->he_config)); 1864 he_cap = &mlme_priv->he_config; 1865 he_cap->present = true; 1866 /* 1867 * Do not advertise requester role for SAP & responder role 1868 * for STA 1869 */ 1870 persona = wlan_vdev_mlme_get_opmode(vdev); 1871 if (persona == QDF_SAP_MODE || persona == QDF_P2P_GO_MODE) { 1872 he_cap->twt_request = false; 1873 if (!he_cap->twt_responder) 1874 he_cap->flex_twt_sched = false; 1875 1876 } else if (persona == QDF_STA_MODE || persona == QDF_P2P_CLIENT_MODE) { 1877 he_cap->twt_responder = false; 1878 if (!he_cap->twt_request) 1879 he_cap->flex_twt_sched = false; 1880 } 1881 1882 if (he_cap->ppet_present) { 1883 /* till now operating channel is not decided yet, use 5g cap */ 1884 qdf_mem_copy(he_cap->ppet.ppe_threshold.ppe_th, 1885 mac_ctx->mlme_cfg->he_caps.he_ppet_5g, 1886 WNI_CFG_HE_PPET_LEN); 1887 he_cap->ppet.ppe_threshold.num_ppe_th = 1888 lim_truncate_ppet(he_cap->ppet.ppe_threshold.ppe_th, 1889 WNI_CFG_HE_PPET_LEN); 1890 } else { 1891 he_cap->ppet.ppe_threshold.num_ppe_th = 0; 1892 } 1893 mlme_priv->he_sta_obsspd = mac_ctx->mlme_cfg->he_caps.he_sta_obsspd; 1894 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1895 } 1896 #endif 1897 1898 QDF_STATUS csr_change_default_config_param(struct mac_context *mac, 1899 struct csr_config_params *pParam) 1900 { 1901 QDF_STATUS status = QDF_STATUS_SUCCESS; 1902 1903 if (pParam) { 1904 mac->roam.configParam.is_force_1x1 = 1905 pParam->is_force_1x1; 1906 mac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode; 1907 mac->mlme_cfg->wmm_params.wme_enabled = 1908 (pParam->WMMSupportMode == WMM_USER_MODE_NO_QOS) ? 0 : 1; 1909 mac->roam.configParam.Is11eSupportEnabled = 1910 pParam->Is11eSupportEnabled; 1911 1912 mac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode; 1913 mac->roam.configParam.mcc_rts_cts_prot_enable = 1914 pParam->mcc_rts_cts_prot_enable; 1915 mac->roam.configParam.mcc_bcast_prob_resp_enable = 1916 pParam->mcc_bcast_prob_resp_enable; 1917 mac->roam.configParam.fAllowMCCGODiffBI = 1918 pParam->fAllowMCCGODiffBI; 1919 1920 /* channelBondingMode5GHz plays a dual role right now 1921 * INFRA STA will use this non zero value as CB enabled 1922 * and SOFTAP will use this non-zero value to determine 1923 * the secondary channel offset. This is how 1924 * channelBondingMode5GHz works now and this is kept intact 1925 * to avoid any cfg.ini change. 1926 */ 1927 if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI) 1928 sme_warn("Invalid CB value from ini in 2.4GHz band %d, CB DISABLED", 1929 pParam->channelBondingMode24GHz); 1930 mac->roam.configParam.channelBondingMode24GHz = 1931 csr_convert_cb_ini_value_to_phy_cb_state(pParam-> 1932 channelBondingMode24GHz); 1933 if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI) 1934 sme_warn("Invalid CB value from ini in 5GHz band %d, CB DISABLED", 1935 pParam->channelBondingMode5GHz); 1936 mac->roam.configParam.channelBondingMode5GHz = 1937 csr_convert_cb_ini_value_to_phy_cb_state(pParam-> 1938 channelBondingMode5GHz); 1939 sme_debug("cb mode 2g %d 5g %d", 1940 mac->roam.configParam.channelBondingMode24GHz, 1941 mac->roam.configParam.channelBondingMode5GHz); 1942 mac->roam.configParam.phyMode = pParam->phyMode; 1943 mac->roam.configParam.HeartbeatThresh50 = 1944 pParam->HeartbeatThresh50; 1945 mac->roam.configParam.ProprietaryRatesEnabled = 1946 pParam->ProprietaryRatesEnabled; 1947 1948 mac->roam.configParam.wep_tkip_in_he = pParam->wep_tkip_in_he; 1949 1950 mac->roam.configParam.uCfgDot11Mode = 1951 csr_get_cfg_dot11_mode_from_csr_phy_mode(false, 1952 mac->roam.configParam. 1953 phyMode); 1954 1955 /* Assign this before calling csr_init11d_info */ 1956 if (wlan_reg_11d_enabled_on_host(mac->psoc)) 1957 status = csr_init11d_info(mac, &pParam->Csr11dinfo); 1958 1959 /* Initialize the power + channel information if 11h is 1960 * enabled. If 11d is enabled this information has already 1961 * been initialized 1962 */ 1963 if (csr_is11h_supported(mac) && 1964 !wlan_reg_11d_enabled_on_host(mac->psoc)) 1965 csr_init_channel_power_list(mac, &pParam->Csr11dinfo); 1966 1967 mac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan; 1968 mac->roam.configParam.send_smps_action = 1969 pParam->send_smps_action; 1970 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 1971 mac->roam.configParam.cc_switch_mode = pParam->cc_switch_mode; 1972 #endif 1973 mac->roam.configParam.obssEnabled = pParam->obssEnabled; 1974 mac->roam.configParam.conc_custom_rule1 = 1975 pParam->conc_custom_rule1; 1976 mac->roam.configParam.conc_custom_rule2 = 1977 pParam->conc_custom_rule2; 1978 mac->roam.configParam.is_sta_connection_in_5gz_enabled = 1979 pParam->is_sta_connection_in_5gz_enabled; 1980 1981 /* update interface configuration */ 1982 mac->sme.max_intf_count = pParam->max_intf_count; 1983 1984 mac->f_sta_miracast_mcc_rest_time_val = 1985 pParam->f_sta_miracast_mcc_rest_time_val; 1986 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 1987 mac->sap.sap_channel_avoidance = 1988 pParam->sap_channel_avoidance; 1989 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 1990 } 1991 return status; 1992 } 1993 1994 QDF_STATUS csr_get_config_param(struct mac_context *mac, 1995 struct csr_config_params *pParam) 1996 { 1997 struct csr_config *cfg_params = &mac->roam.configParam; 1998 1999 if (!pParam) 2000 return QDF_STATUS_E_INVAL; 2001 2002 pParam->is_force_1x1 = cfg_params->is_force_1x1; 2003 pParam->WMMSupportMode = cfg_params->WMMSupportMode; 2004 pParam->Is11eSupportEnabled = cfg_params->Is11eSupportEnabled; 2005 pParam->channelBondingMode24GHz = csr_convert_phy_cb_state_to_ini_value( 2006 cfg_params->channelBondingMode24GHz); 2007 pParam->channelBondingMode5GHz = csr_convert_phy_cb_state_to_ini_value( 2008 cfg_params->channelBondingMode5GHz); 2009 pParam->phyMode = cfg_params->phyMode; 2010 pParam->HeartbeatThresh50 = cfg_params->HeartbeatThresh50; 2011 pParam->ProprietaryRatesEnabled = cfg_params->ProprietaryRatesEnabled; 2012 pParam->fEnableDFSChnlScan = mac->scan.fEnableDFSChnlScan; 2013 pParam->fEnableMCCMode = cfg_params->fenableMCCMode; 2014 pParam->fAllowMCCGODiffBI = cfg_params->fAllowMCCGODiffBI; 2015 2016 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 2017 pParam->cc_switch_mode = cfg_params->cc_switch_mode; 2018 #endif 2019 pParam->wep_tkip_in_he = cfg_params->wep_tkip_in_he; 2020 csr_set_channels(mac, pParam); 2021 pParam->obssEnabled = cfg_params->obssEnabled; 2022 pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1; 2023 pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2; 2024 pParam->is_sta_connection_in_5gz_enabled = 2025 cfg_params->is_sta_connection_in_5gz_enabled; 2026 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE 2027 pParam->sap_channel_avoidance = mac->sap.sap_channel_avoidance; 2028 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ 2029 pParam->max_intf_count = mac->sme.max_intf_count; 2030 pParam->f_sta_miracast_mcc_rest_time_val = 2031 mac->f_sta_miracast_mcc_rest_time_val; 2032 pParam->send_smps_action = mac->roam.configParam.send_smps_action; 2033 2034 return QDF_STATUS_SUCCESS; 2035 } 2036 2037 /** 2038 * csr_prune_ch_list() - prunes the channel list to keep only a type of channels 2039 * @ch_lst: existing channel list 2040 * @is_24_GHz: indicates if 2.5 GHz or 5 GHz channels are required 2041 * 2042 * Return: void 2043 */ 2044 static void csr_prune_ch_list(struct csr_channel *ch_lst, bool is_24_GHz) 2045 { 2046 uint8_t idx = 0, num_channels = 0; 2047 2048 for ( ; idx < ch_lst->numChannels; idx++) { 2049 if (is_24_GHz) { 2050 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) { 2051 ch_lst->channel_freq_list[num_channels] = 2052 ch_lst->channel_freq_list[idx]; 2053 num_channels++; 2054 } 2055 } else { 2056 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_lst->channel_freq_list[idx])) { 2057 ch_lst->channel_freq_list[num_channels] = 2058 ch_lst->channel_freq_list[idx]; 2059 num_channels++; 2060 } 2061 } 2062 } 2063 /* 2064 * Cleanup the rest of channels. Note we only need to clean up the 2065 * channels if we had to trim the list. Calling qdf_mem_set() with a 0 2066 * size is going to throw asserts on the debug builds so let's be a bit 2067 * smarter about that. Zero out the reset of the channels only if we 2068 * need to. The amount of memory to clear is the number of channesl that 2069 * we trimmed (ch_lst->numChannels - num_channels) times the size of a 2070 * channel in the structure. 2071 */ 2072 if (ch_lst->numChannels > num_channels) { 2073 qdf_mem_zero(&ch_lst->channel_freq_list[num_channels], 2074 sizeof(ch_lst->channel_freq_list[0]) * 2075 (ch_lst->numChannels - num_channels)); 2076 } 2077 ch_lst->numChannels = num_channels; 2078 } 2079 2080 /** 2081 * csr_prune_channel_list_for_mode() - prunes the channel list 2082 * @mac_ctx: global mac context 2083 * @ch_lst: existing channel list 2084 * 2085 * Prunes the channel list according to band stored in mac_ctx 2086 * 2087 * Return: void 2088 */ 2089 void csr_prune_channel_list_for_mode(struct mac_context *mac_ctx, 2090 struct csr_channel *ch_lst) 2091 { 2092 /* for dual band NICs, don't need to trim the channel list.... */ 2093 if (CSR_IS_OPEARTING_DUAL_BAND(mac_ctx)) 2094 return; 2095 /* 2096 * 2.4 GHz band operation requires the channel list to be trimmed to 2097 * the 2.4 GHz channels only 2098 */ 2099 if (CSR_IS_24_BAND_ONLY(mac_ctx)) 2100 csr_prune_ch_list(ch_lst, true); 2101 else if (CSR_IS_5G_BAND_ONLY(mac_ctx)) 2102 csr_prune_ch_list(ch_lst, false); 2103 } 2104 2105 #define INFRA_AP_DEFAULT_CHAN_FREQ 2437 2106 2107 QDF_STATUS csr_get_channel_and_power_list(struct mac_context *mac) 2108 { 2109 QDF_STATUS status = QDF_STATUS_SUCCESS; 2110 uint8_t num20MHzChannelsFound = 0; 2111 QDF_STATUS qdf_status; 2112 uint8_t Index = 0; 2113 2114 qdf_status = wlan_reg_get_channel_list_with_power_for_freq( 2115 mac->pdev, 2116 mac->scan.defaultPowerTable, 2117 &num20MHzChannelsFound); 2118 2119 if ((QDF_STATUS_SUCCESS != qdf_status) || 2120 (num20MHzChannelsFound == 0)) { 2121 sme_err("failed to get channels"); 2122 status = QDF_STATUS_E_FAILURE; 2123 } else { 2124 if (num20MHzChannelsFound > CFG_VALID_CHANNEL_LIST_LEN) 2125 num20MHzChannelsFound = CFG_VALID_CHANNEL_LIST_LEN; 2126 /* Move the channel list to the global data */ 2127 /* structure -- this will be used as the scan list */ 2128 for (Index = 0; Index < num20MHzChannelsFound; Index++) 2129 mac->scan.base_channels.channel_freq_list[Index] = 2130 mac->scan.defaultPowerTable[Index].center_freq; 2131 mac->scan.base_channels.numChannels = 2132 num20MHzChannelsFound; 2133 } 2134 return status; 2135 } 2136 2137 QDF_STATUS csr_apply_channel_and_power_list(struct mac_context *mac) 2138 { 2139 QDF_STATUS status = QDF_STATUS_SUCCESS; 2140 2141 csr_prune_channel_list_for_mode(mac, &mac->scan.base_channels); 2142 csr_save_channel_power_for_band(mac, false); 2143 csr_save_channel_power_for_band(mac, true); 2144 csr_apply_channel_power_info_to_fw(mac, 2145 &mac->scan.base_channels); 2146 2147 csr_init_operating_classes(mac); 2148 return status; 2149 } 2150 2151 static QDF_STATUS csr_init11d_info(struct mac_context *mac, tCsr11dinfo *ps11dinfo) 2152 { 2153 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2154 uint8_t index; 2155 uint32_t count = 0; 2156 struct pwr_channel_info *pChanInfo; 2157 struct pwr_channel_info *pChanInfoStart; 2158 bool applyConfig = true; 2159 2160 if (!ps11dinfo) 2161 return status; 2162 2163 if (ps11dinfo->Channels.numChannels 2164 && (CFG_VALID_CHANNEL_LIST_LEN >= 2165 ps11dinfo->Channels.numChannels)) { 2166 mac->scan.base_channels.numChannels = 2167 ps11dinfo->Channels.numChannels; 2168 qdf_mem_copy(mac->scan.base_channels.channel_freq_list, 2169 ps11dinfo->Channels.channel_freq_list, 2170 ps11dinfo->Channels.numChannels); 2171 } else { 2172 /* No change */ 2173 return QDF_STATUS_SUCCESS; 2174 } 2175 /* legacy maintenance */ 2176 2177 /* need to add the max power channel list */ 2178 pChanInfo = 2179 qdf_mem_malloc(sizeof(struct pwr_channel_info) * 2180 CFG_VALID_CHANNEL_LIST_LEN); 2181 if (pChanInfo) { 2182 pChanInfoStart = pChanInfo; 2183 for (index = 0; index < ps11dinfo->Channels.numChannels; 2184 index++) { 2185 pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq; 2186 pChanInfo->num_chan = 2187 ps11dinfo->ChnPower[index].numChannels; 2188 pChanInfo->max_tx_pwr = 2189 ps11dinfo->ChnPower[index].maxtxPower; 2190 pChanInfo++; 2191 count++; 2192 } 2193 if (count) { 2194 status = csr_save_to_channel_power2_g_5_g(mac, 2195 count * 2196 sizeof(struct pwr_channel_info), 2197 pChanInfoStart); 2198 } 2199 qdf_mem_free(pChanInfoStart); 2200 } 2201 /* Only apply them to CFG when not in STOP state. 2202 * Otherwise they will be applied later 2203 */ 2204 if (QDF_IS_STATUS_SUCCESS(status)) { 2205 for (index = 0; index < WLAN_MAX_VDEVS; index++) { 2206 if ((CSR_IS_SESSION_VALID(mac, index)) 2207 && CSR_IS_ROAM_STOP(mac, index)) { 2208 applyConfig = false; 2209 } 2210 } 2211 2212 if (true == applyConfig) { 2213 /* Apply the base channel list, power info, 2214 * and set the Country code. 2215 */ 2216 csr_apply_channel_power_info_to_fw(mac, 2217 &mac->scan. 2218 base_channels); 2219 } 2220 } 2221 return status; 2222 } 2223 2224 /* Initialize the Channel + Power List in the local cache and in the CFG */ 2225 QDF_STATUS csr_init_channel_power_list(struct mac_context *mac, 2226 tCsr11dinfo *ps11dinfo) 2227 { 2228 uint8_t index; 2229 uint32_t count = 0; 2230 struct pwr_channel_info *pChanInfo; 2231 struct pwr_channel_info *pChanInfoStart; 2232 2233 if (!ps11dinfo || !mac) 2234 return QDF_STATUS_E_FAILURE; 2235 2236 pChanInfo = 2237 qdf_mem_malloc(sizeof(struct pwr_channel_info) * 2238 CFG_VALID_CHANNEL_LIST_LEN); 2239 if (pChanInfo) { 2240 pChanInfoStart = pChanInfo; 2241 2242 for (index = 0; index < ps11dinfo->Channels.numChannels; 2243 index++) { 2244 pChanInfo->first_freq = ps11dinfo->ChnPower[index].first_chan_freq; 2245 pChanInfo->num_chan = 2246 ps11dinfo->ChnPower[index].numChannels; 2247 pChanInfo->max_tx_pwr = 2248 ps11dinfo->ChnPower[index].maxtxPower; 2249 pChanInfo++; 2250 count++; 2251 } 2252 if (count) { 2253 csr_save_to_channel_power2_g_5_g(mac, 2254 count * 2255 sizeof(struct pwr_channel_info), 2256 pChanInfoStart); 2257 } 2258 qdf_mem_free(pChanInfoStart); 2259 } 2260 2261 return QDF_STATUS_SUCCESS; 2262 } 2263 2264 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR 2265 #ifdef WLAN_UNIT_TEST 2266 void csr_cm_get_sta_cxn_info(struct mac_context *mac_ctx, uint8_t vdev_id, 2267 char *buf, uint32_t buf_sz) 2268 { 2269 struct wlan_objmgr_vdev *vdev; 2270 2271 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 2272 WLAN_LEGACY_MAC_ID); 2273 if (!vdev) { 2274 sme_err("vdev object is NULL for vdev %d", vdev_id); 2275 return; 2276 } 2277 2278 cm_get_sta_cxn_info(vdev, buf, buf_sz); 2279 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 2280 2281 } 2282 #endif 2283 #endif 2284 2285 QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId, 2286 struct csr_roam_info *roam_info, 2287 eRoamCmdStatus u1, eCsrRoamResult u2) 2288 { 2289 QDF_STATUS status = QDF_STATUS_SUCCESS; 2290 struct csr_roam_session *pSession; 2291 qdf_freq_t chan_freq; 2292 2293 if (!CSR_IS_SESSION_VALID(mac, sessionId)) { 2294 sme_err("Session ID: %d is not valid", sessionId); 2295 QDF_ASSERT(0); 2296 return QDF_STATUS_E_FAILURE; 2297 } 2298 pSession = CSR_GET_SESSION(mac, sessionId); 2299 2300 if (false == pSession->sessionActive) { 2301 sme_debug("Session is not Active"); 2302 return QDF_STATUS_E_FAILURE; 2303 } 2304 chan_freq = wlan_get_operation_chan_freq_vdev_id(mac->pdev, sessionId); 2305 2306 if (mac->session_roam_complete_cb) 2307 status = mac->session_roam_complete_cb(mac->psoc, sessionId, 2308 roam_info, u1, u2); 2309 2310 return status; 2311 } 2312 2313 static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd, 2314 struct qdf_mac_addr peer_macaddr, 2315 uint8_t vdev_id) 2316 { 2317 if (sme_cmd->command == eSmeCommandRoam && 2318 (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta || 2319 sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) && 2320 !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac, 2321 QDF_MAC_ADDR_SIZE)) 2322 return true; 2323 2324 if (sme_cmd->command == eSmeCommandWmStatusChange) { 2325 struct wmstatus_changecmd *wms_cmd; 2326 2327 wms_cmd = &sme_cmd->u.wmStatusChangeCmd; 2328 if (wms_cmd->Type == eCsrDisassociated && 2329 !qdf_mem_cmp(peer_macaddr.bytes, 2330 wms_cmd->u.DisassocIndMsg.peer_macaddr.bytes, 2331 QDF_MAC_ADDR_SIZE)) 2332 return true; 2333 2334 if (wms_cmd->Type == eCsrDeauthenticated && 2335 !qdf_mem_cmp(peer_macaddr.bytes, 2336 wms_cmd->u.DeauthIndMsg.peer_macaddr.bytes, 2337 QDF_MAC_ADDR_SIZE)) 2338 return true; 2339 } 2340 2341 return false; 2342 } 2343 2344 static bool 2345 csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx, 2346 uint8_t vdev_id, 2347 struct qdf_mac_addr peer_macaddr) 2348 { 2349 tListElem *entry = NULL; 2350 tSmeCmd *sme_cmd; 2351 2352 entry = csr_nonscan_pending_ll_peek_head(mac_ctx, LL_ACCESS_NOLOCK); 2353 while (entry) { 2354 sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); 2355 if ((sme_cmd->vdev_id == vdev_id) && 2356 csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id)) 2357 return true; 2358 entry = csr_nonscan_pending_ll_next(mac_ctx, entry, 2359 LL_ACCESS_NOLOCK); 2360 } 2361 2362 return false; 2363 } 2364 2365 static bool 2366 csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx, 2367 uint8_t vdev_id, 2368 struct qdf_mac_addr peer_macaddr) 2369 { 2370 tSmeCmd *sme_cmd; 2371 2372 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id, 2373 WLAN_SER_CMD_FORCE_DEAUTH_STA); 2374 2375 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id)) 2376 return true; 2377 2378 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id, 2379 WLAN_SER_CMD_FORCE_DISASSOC_STA); 2380 2381 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id)) 2382 return true; 2383 2384 /* 2385 * WLAN_SER_CMD_WM_STATUS_CHANGE is of two type, the handling 2386 * should take care of both the types. 2387 */ 2388 sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id, 2389 WLAN_SER_CMD_WM_STATUS_CHANGE); 2390 if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id)) 2391 return true; 2392 2393 return false; 2394 } 2395 2396 /* 2397 * csr_is_deauth_disassoc_already_active() - Function to check if deauth or 2398 * disassoc is already in progress. 2399 * @mac_ctx: Global MAC context 2400 * @vdev_id: vdev id 2401 * @peer_macaddr: Peer MAC address 2402 * 2403 * Return: True if deauth/disassoc indication can be dropped 2404 * else false 2405 */ 2406 static bool 2407 csr_is_deauth_disassoc_already_active(struct mac_context *mac_ctx, 2408 uint8_t vdev_id, 2409 struct qdf_mac_addr peer_macaddr) 2410 { 2411 bool ret = csr_is_deauth_disassoc_in_pending_q(mac_ctx, 2412 vdev_id, 2413 peer_macaddr); 2414 if (!ret) 2415 /** 2416 * commands are not found in pending queue, check in active 2417 * queue as well 2418 */ 2419 ret = csr_is_deauth_disassoc_in_active_q(mac_ctx, 2420 vdev_id, 2421 peer_macaddr); 2422 2423 if (ret) 2424 sme_debug("Deauth/Disassoc already in progress for "QDF_MAC_ADDR_FMT, 2425 QDF_MAC_ADDR_REF(peer_macaddr.bytes)); 2426 2427 return ret; 2428 } 2429 2430 /** 2431 * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station 2432 * @sessionId: Session Id for Soft AP 2433 * @p_del_sta_params: Pointer to parameters of the station to disassoc 2434 * 2435 * CSR function that HDD calls to delete a associated station 2436 * 2437 * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error 2438 */ 2439 QDF_STATUS csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac, 2440 uint32_t sessionId, 2441 struct csr_del_sta_params 2442 *p_del_sta_params) 2443 2444 { 2445 QDF_STATUS status = QDF_STATUS_SUCCESS; 2446 tSmeCmd *pCommand; 2447 2448 do { 2449 if (csr_is_deauth_disassoc_already_active(mac, sessionId, 2450 p_del_sta_params->peerMacAddr)) 2451 break; 2452 pCommand = csr_get_command_buffer(mac); 2453 if (!pCommand) { 2454 sme_err("fail to get command buffer"); 2455 status = QDF_STATUS_E_RESOURCES; 2456 break; 2457 } 2458 pCommand->command = eSmeCommandRoam; 2459 pCommand->vdev_id = (uint8_t) sessionId; 2460 pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta; 2461 qdf_mem_copy(pCommand->u.roamCmd.peerMac, 2462 p_del_sta_params->peerMacAddr.bytes, 2463 sizeof(pCommand->u.roamCmd.peerMac)); 2464 pCommand->u.roamCmd.reason = p_del_sta_params->reason_code; 2465 2466 status = csr_queue_sme_command(mac, pCommand, false); 2467 if (!QDF_IS_STATUS_SUCCESS(status)) 2468 sme_err("fail to send message status: %d", status); 2469 } while (0); 2470 2471 return status; 2472 } 2473 2474 /** 2475 * csr_roam_issue_deauthSta() - delete a associated station 2476 * @sessionId: Session Id for Soft AP 2477 * @pDelStaParams: Pointer to parameters of the station to deauthenticate 2478 * 2479 * CSR function that HDD calls to delete a associated station 2480 * 2481 * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error 2482 */ 2483 QDF_STATUS csr_roam_issue_deauth_sta_cmd(struct mac_context *mac, 2484 uint32_t sessionId, 2485 struct csr_del_sta_params *pDelStaParams) 2486 { 2487 QDF_STATUS status = QDF_STATUS_SUCCESS; 2488 tSmeCmd *pCommand; 2489 2490 do { 2491 if (csr_is_deauth_disassoc_already_active(mac, sessionId, 2492 pDelStaParams->peerMacAddr)) 2493 break; 2494 pCommand = csr_get_command_buffer(mac); 2495 if (!pCommand) { 2496 sme_err("fail to get command buffer"); 2497 status = QDF_STATUS_E_RESOURCES; 2498 break; 2499 } 2500 pCommand->command = eSmeCommandRoam; 2501 pCommand->vdev_id = (uint8_t) sessionId; 2502 pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta; 2503 qdf_mem_copy(pCommand->u.roamCmd.peerMac, 2504 pDelStaParams->peerMacAddr.bytes, 2505 sizeof(tSirMacAddr)); 2506 pCommand->u.roamCmd.reason = pDelStaParams->reason_code; 2507 2508 status = csr_queue_sme_command(mac, pCommand, false); 2509 if (!QDF_IS_STATUS_SUCCESS(status)) 2510 sme_err("fail to send message status: %d", status); 2511 } while (0); 2512 2513 return status; 2514 } 2515 2516 /** 2517 * csr_get_peer_stats_cb - Peer stats callback 2518 * @ev: stats event 2519 * @cookie: Void pointer to mac contaxt 2520 * 2521 * Return: None 2522 */ 2523 static void csr_get_peer_stats_cb(struct stats_event *ev, void *cookie) 2524 { 2525 struct mac_context *mac = (struct mac_context *)cookie; 2526 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2527 2528 if (!mac) { 2529 sme_err("Invalid mac ctx"); 2530 return; 2531 } 2532 2533 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 2534 if (!mlme_obj) { 2535 sme_err("NULL mlme psoc object"); 2536 return; 2537 } 2538 2539 qdf_mc_timer_stop( 2540 &mlme_obj->disconnect_stats_param.disconn_stats_timer); 2541 2542 if (!ev->peer_stats) { 2543 sme_debug("no peer stats"); 2544 goto disconnect_stats_complete; 2545 } 2546 2547 mac->peer_rssi = ev->peer_stats->peer_rssi; 2548 mac->peer_txrate = ev->peer_stats->tx_rate; 2549 mac->peer_rxrate = ev->peer_stats->rx_rate; 2550 if (!ev->peer_extended_stats) { 2551 sme_debug("no peer extended stats"); 2552 goto disconnect_stats_complete; 2553 } 2554 mac->rx_mc_bc_cnt = ev->peer_extended_stats->rx_mc_bc_cnt; 2555 2556 disconnect_stats_complete: 2557 sme_debug("peer rssi %d tx_rate %d rx_rate %d rx_mc_bc_cnt %d", 2558 mac->peer_rssi, mac->peer_txrate, mac->peer_rxrate, 2559 mac->rx_mc_bc_cnt); 2560 csr_continue_peer_disconnect_after_get_stats(mac); 2561 } 2562 2563 /** 2564 * csr_get_peer_stats - Get Peer stats 2565 * @mac: MAC contaxt 2566 * @session_id: Current session id 2567 * @peer_mac: Peer mac address 2568 * 2569 * Return: None 2570 */ 2571 static void csr_get_peer_stats(struct mac_context *mac, uint32_t session_id, 2572 struct qdf_mac_addr peer_mac) 2573 { 2574 struct wlan_objmgr_vdev *vdev; 2575 struct request_info info = {0}; 2576 QDF_STATUS status; 2577 struct wlan_mlme_psoc_ext_obj *mlme_obj; 2578 2579 mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); 2580 if (!mlme_obj) { 2581 sme_err("NULL mlme psoc object"); 2582 return; 2583 } 2584 /* Reset is_disconn_stats_completed before error handing. */ 2585 qdf_atomic_set( 2586 &mlme_obj->disconnect_stats_param.is_disconn_stats_completed, 2587 0); 2588 2589 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session_id, 2590 WLAN_LEGACY_SME_ID); 2591 2592 if (!vdev) { 2593 csr_continue_peer_disconnect_after_get_stats(mac); 2594 return; 2595 } 2596 2597 info.cookie = mac; 2598 info.u.get_peer_rssi_cb = csr_get_peer_stats_cb; 2599 info.vdev_id = wlan_vdev_get_id(vdev); 2600 info.pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)); 2601 qdf_mem_copy(info.peer_mac_addr, &peer_mac, QDF_MAC_ADDR_SIZE); 2602 sme_debug("peer_mac" QDF_MAC_ADDR_FMT, 2603 QDF_MAC_ADDR_REF(peer_mac.bytes)); 2604 mlme_obj->disconnect_stats_param.vdev_id = info.vdev_id; 2605 status = ucfg_mc_cp_stats_send_stats_request(vdev, TYPE_PEER_STATS, 2606 &info); 2607 if (QDF_IS_STATUS_ERROR(status)) { 2608 sme_err("stats req failed: %d", status); 2609 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 2610 csr_continue_peer_disconnect_after_get_stats(mac); 2611 return; 2612 } 2613 2614 qdf_mc_timer_start( 2615 &mlme_obj->disconnect_stats_param.disconn_stats_timer, 2616 SME_CMD_GET_DISCONNECT_STATS_TIMEOUT); 2617 2618 wma_get_rx_retry_cnt(mac, session_id, info.peer_mac_addr); 2619 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 2620 } 2621 2622 QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) 2623 { 2624 QDF_STATUS status = QDF_STATUS_SUCCESS; 2625 uint32_t sessionId = pCommand->vdev_id; 2626 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 2627 struct qdf_mac_addr peer_mac; 2628 2629 if (!pSession) { 2630 sme_err("session %d not found", sessionId); 2631 return QDF_STATUS_E_FAILURE; 2632 } 2633 sme_debug("Roam Reason: %d sessionId: %d", 2634 pCommand->u.roamCmd.roamReason, sessionId); 2635 2636 switch (pCommand->u.roamCmd.roamReason) { 2637 case eCsrForcedDisassocSta: 2638 case eCsrForcedDeauthSta: 2639 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, 2640 sessionId); 2641 if (pCommand->u.roamCmd.roamReason == eCsrForcedDeauthSta) 2642 csr_roam_substate_change(mac, 2643 eCSR_ROAM_SUBSTATE_DEAUTH_REQ, 2644 sessionId); 2645 else 2646 csr_roam_substate_change( 2647 mac, 2648 eCSR_ROAM_SUBSTATE_DISASSOC_REQ, 2649 sessionId); 2650 2651 qdf_mem_copy(&peer_mac, &pCommand->u.roamCmd.peerMac, 2652 QDF_MAC_ADDR_SIZE); 2653 /* 2654 * Get peer stats before peer gets deleted so that these stats 2655 * can be given to user space when big data stats are queried. 2656 * Once peer stats are retrieved deauth sta will continue 2657 */ 2658 csr_get_peer_stats(mac, sessionId, peer_mac); 2659 break; 2660 } 2661 return status; 2662 } 2663 2664 void csr_reinit_roam_cmd(struct mac_context *mac, tSmeCmd *pCommand) 2665 { 2666 /* Because u.roamCmd is union and share with scanCmd and StatusChange */ 2667 qdf_mem_zero(&pCommand->u.roamCmd, sizeof(struct roam_cmd)); 2668 } 2669 2670 void csr_reinit_wm_status_change_cmd(struct mac_context *mac, 2671 tSmeCmd *pCommand) 2672 { 2673 qdf_mem_zero(&pCommand->u.wmStatusChangeCmd, 2674 sizeof(struct wmstatus_changecmd)); 2675 } 2676 2677 void csr_roam_complete(struct mac_context *mac_ctx, uint8_t session_id) 2678 { 2679 tSmeCmd *sme_cmd; 2680 struct wlan_serialization_command *cmd; 2681 2682 cmd = wlan_serialization_peek_head_active_cmd_using_psoc( 2683 mac_ctx->psoc, false); 2684 if (!cmd) { 2685 sme_err("Roam completion called but cmd is not active"); 2686 return; 2687 } 2688 sme_cmd = cmd->umac_cmd; 2689 if (!sme_cmd) { 2690 sme_err("sme_cmd is NULL"); 2691 return; 2692 } 2693 if (eSmeCommandRoam == sme_cmd->command) { 2694 csr_roam_process_results_default(mac_ctx, sme_cmd); 2695 csr_release_command(mac_ctx, sme_cmd); 2696 } 2697 } 2698 2699 /* Returns whether the current association is a 11r assoc or not */ 2700 bool csr_roam_is11r_assoc(struct mac_context *mac, uint8_t sessionId) 2701 { 2702 struct cm_roam_values_copy config; 2703 2704 wlan_cm_roam_cfg_get_value(mac->psoc, sessionId, IS_11R_CONNECTION, 2705 &config); 2706 2707 return config.bool_value; 2708 } 2709 2710 void csr_roam_process_results_default(struct mac_context *mac_ctx, 2711 tSmeCmd *cmd) 2712 { 2713 uint32_t session_id = cmd->vdev_id; 2714 struct csr_roam_session *session; 2715 struct csr_roam_info *roam_info; 2716 QDF_STATUS status; 2717 enum QDF_OPMODE opmode; 2718 2719 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 2720 sme_err("Invalid session id %d", session_id); 2721 return; 2722 } 2723 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id); 2724 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 2725 if (!roam_info) 2726 return; 2727 session = CSR_GET_SESSION(mac_ctx, session_id); 2728 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, session_id)) { 2729 /* 2730 * do not free for the other profiles as we need 2731 * to send down stop BSS later 2732 */ 2733 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 2734 csr_set_default_dot11_mode(mac_ctx); 2735 } 2736 2737 switch (cmd->u.roamCmd.roamReason) { 2738 case eCsrForcedDisassocSta: 2739 case eCsrForcedDeauthSta: 2740 roam_info->rssi = mac_ctx->peer_rssi; 2741 roam_info->tx_rate = mac_ctx->peer_txrate; 2742 roam_info->rx_rate = mac_ctx->peer_rxrate; 2743 roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; 2744 roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt; 2745 2746 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, 2747 session_id); 2748 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 2749 qdf_mem_copy(roam_info->peerMac.bytes, 2750 cmd->u.roamCmd.peerMac, 2751 sizeof(tSirMacAddr)); 2752 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; 2753 /* Update the MAC reason code */ 2754 roam_info->disassoc_reason = cmd->u.roamCmd.reason; 2755 roam_info->status_code = eSIR_SME_SUCCESS; 2756 status = csr_roam_call_callback(mac_ctx, session_id, 2757 roam_info, 2758 eCSR_ROAM_LOSTLINK, 2759 eCSR_ROAM_RESULT_FORCED); 2760 } 2761 break; 2762 default: 2763 csr_roam_state_change(mac_ctx, 2764 eCSR_ROAMING_STATE_IDLE, session_id); 2765 break; 2766 } 2767 qdf_mem_free(roam_info); 2768 } 2769 2770 /** 2771 * csr_roam_process_start_bss_success() - Process the result for start bss 2772 * @mac_ctx: Global MAC Context 2773 * @context: Additional data in context of the cmd 2774 * @vdev_id: vdev id 2775 * 2776 * Return: None 2777 */ 2778 static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx, 2779 struct csr_roam_info *roam_info, 2780 void *context, uint8_t vdev_id) 2781 { 2782 struct csr_roam_session *session; 2783 struct start_bss_rsp *start_bss_rsp = NULL; 2784 eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND; 2785 eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_STARTED; 2786 tSirMacAddr bcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2787 QDF_STATUS status; 2788 enum QDF_OPMODE opmode; 2789 uint8_t wmm_mode = 0, value = 0; 2790 2791 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 2792 sme_err("Invalid session id %d", vdev_id); 2793 return; 2794 } 2795 session = CSR_GET_SESSION(mac_ctx, vdev_id); 2796 2797 sme_debug("Start BSS success"); 2798 start_bss_rsp = (struct start_bss_rsp *)context; 2799 2800 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 2801 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) 2802 session->connectState = 2803 eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED; 2804 else if (opmode == QDF_NDI_MODE) 2805 session->connectState = eCSR_CONNECT_STATE_TYPE_NDI_STARTED; 2806 else 2807 session->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED; 2808 2809 if (opmode == QDF_NDI_MODE) { 2810 status = ucfg_mlme_get_wmm_mode(mac_ctx->psoc, &wmm_mode); 2811 if (!QDF_IS_STATUS_SUCCESS(status)) 2812 return; 2813 if (wmm_mode == WMM_USER_MODE_NO_QOS) { 2814 session->modifyProfileFields.uapsd_mask = 0; 2815 } else { 2816 status = 2817 ucfg_mlme_get_wmm_uapsd_mask(mac_ctx->psoc, &value); 2818 if (!QDF_IS_STATUS_SUCCESS(status)) 2819 return; 2820 session->modifyProfileFields.uapsd_mask = value; 2821 } 2822 } 2823 csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, vdev_id); 2824 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 2825 wlan_mlme_get_mac_vdev_id(mac_ctx->pdev, vdev_id, &roam_info->bssid); 2826 2827 /* We are done with the IEs so free it */ 2828 /* 2829 * Only set context for non-WDS_STA. We don't even need it for 2830 * WDS_AP. But since the encryption. 2831 * is WPA2-PSK so it won't matter. 2832 */ 2833 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 2834 if (wlan_is_open_wep_cipher(mac_ctx->pdev, vdev_id)) { 2835 csr_issue_set_context_req_helper(mac_ctx, vdev_id, 2836 &bcast_mac, false, 2837 false, 0); 2838 } 2839 } 2840 2841 /* 2842 * Only tell upper layer is we start the BSS because Vista doesn't like 2843 * multiple connection indications. If we don't start the BSS ourself, 2844 * handler of eSIR_SME_JOINED_NEW_BSS will trigger the connection start 2845 * indication in Vista 2846 */ 2847 roam_info->staId = (uint8_t)start_bss_rsp->staId; 2848 if (opmode == QDF_NDI_MODE) { 2849 csr_roam_update_ndp_return_params(mac_ctx, 2850 CSR_SAP_START_BSS_SUCCESS, 2851 &roam_status, 2852 &roam_result, 2853 roam_info); 2854 } 2855 /* 2856 * Only tell upper layer is we start the BSS because Vista 2857 * doesn't like multiple connection indications. If we don't 2858 * start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS 2859 * will trigger the connection start indication in Vista 2860 */ 2861 roam_info->status_code = eSIR_SME_SUCCESS; 2862 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 2863 roam_status, roam_result); 2864 } 2865 2866 static void csr_flush_pending_start_bss_cmd(struct mac_context *mac_ctx, 2867 uint8_t vdev_id) 2868 { 2869 struct wlan_serialization_queued_cmd_info cmd = {0}; 2870 struct wlan_objmgr_vdev *vdev; 2871 2872 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 2873 WLAN_LEGACY_SME_ID); 2874 if (!vdev) { 2875 sme_err("vdev not found for id %d", vdev_id); 2876 return; 2877 } 2878 2879 /* Flush any pending vdev start command */ 2880 cmd.vdev = vdev; 2881 cmd.cmd_type = WLAN_SER_CMD_VDEV_START_BSS; 2882 cmd.req_type = WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE; 2883 cmd.requestor = WLAN_UMAC_COMP_MLME; 2884 cmd.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE; 2885 2886 wlan_serialization_cancel_request(&cmd); 2887 2888 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 2889 } 2890 2891 bool cm_csr_is_ss_wait_for_key(uint8_t vdev_id) 2892 { 2893 struct mac_context *mac; 2894 bool is_wait_for_key = false; 2895 2896 mac = sme_get_mac_context(); 2897 if (!mac) { 2898 sme_err("mac_ctx is NULL"); 2899 return is_wait_for_key; 2900 } 2901 2902 spin_lock(&mac->roam.roam_state_lock); 2903 if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) 2904 is_wait_for_key = true; 2905 spin_unlock(&mac->roam.roam_state_lock); 2906 2907 return is_wait_for_key; 2908 } 2909 2910 void cm_csr_set_ss_wait_for_key(uint8_t vdev_id) 2911 { 2912 struct mac_context *mac; 2913 2914 mac = sme_get_mac_context(); 2915 if (!mac) { 2916 sme_err("mac_ctx is NULL"); 2917 return; 2918 } 2919 2920 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, 2921 vdev_id); 2922 } 2923 2924 void cm_csr_set_joining(uint8_t vdev_id) 2925 { 2926 struct mac_context *mac; 2927 2928 mac = sme_get_mac_context(); 2929 if (!mac) { 2930 sme_err("mac_ctx is NULL"); 2931 return; 2932 } 2933 2934 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, vdev_id); 2935 } 2936 2937 void cm_csr_set_joined(uint8_t vdev_id) 2938 { 2939 struct mac_context *mac; 2940 2941 mac = sme_get_mac_context(); 2942 if (!mac) { 2943 sme_err("mac_ctx is NULL"); 2944 return; 2945 } 2946 2947 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINED, vdev_id); 2948 } 2949 2950 void cm_csr_set_idle(uint8_t vdev_id) 2951 { 2952 struct mac_context *mac; 2953 2954 mac = sme_get_mac_context(); 2955 if (!mac) { 2956 sme_err("mac_ctx is NULL"); 2957 return; 2958 } 2959 2960 csr_roam_state_change(mac, eCSR_ROAMING_STATE_IDLE, vdev_id); 2961 } 2962 2963 void cm_csr_set_ss_none(uint8_t vdev_id) 2964 { 2965 struct mac_context *mac; 2966 2967 mac = sme_get_mac_context(); 2968 if (!mac) { 2969 sme_err("mac_ctx is NULL"); 2970 return; 2971 } 2972 2973 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, 2974 vdev_id); 2975 } 2976 2977 QDF_STATUS csr_roam_ndi_stop(struct mac_context *mac_ctx, uint8_t vdev_id) 2978 { 2979 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2980 bool is_vdev_up; 2981 bool is_start_bss_in_active_q = false; 2982 2983 csr_flush_pending_start_bss_cmd(mac_ctx, vdev_id); 2984 2985 is_vdev_up = wlan_is_vdev_id_up(mac_ctx->pdev, vdev_id); 2986 if (wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id, 2987 WLAN_SER_CMD_VDEV_START_BSS)) 2988 is_start_bss_in_active_q = true; 2989 2990 sme_debug("vdev_id: %d is_vdev_up %d is_start_bss_in_active_q %d", 2991 vdev_id, is_vdev_up, is_start_bss_in_active_q); 2992 2993 if (is_vdev_up || is_start_bss_in_active_q) 2994 status = csr_roam_issue_stop_bss_cmd(mac_ctx, vdev_id, 2995 eCSR_BSS_TYPE_NDI); 2996 return status; 2997 } 2998 2999 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 3000 static void csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3001 struct bss_description *bss_desc) 3002 { 3003 struct cm_roam_values_copy src_cfg = {}; 3004 3005 src_cfg.bool_value = bss_desc->is_single_pmk; 3006 wlan_cm_roam_cfg_set_value(psoc, vdev_id, 3007 IS_SINGLE_PMK, &src_cfg); 3008 } 3009 #else 3010 static inline void 3011 csr_fill_single_pmk(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 3012 struct bss_description *bss_desc) 3013 {} 3014 #endif 3015 3016 void csr_roam_roaming_state_stop_bss_rsp_processor(struct mac_context *mac, 3017 void *msg) 3018 { 3019 struct stop_bss_rsp *stop_bss_rsp = (struct stop_bss_rsp *)msg; 3020 uint8_t vdev_id = stop_bss_rsp->vdev_id; 3021 enum csr_sap_response_type result_code = CSR_SAP_STOP_BSS_SUCCESS; 3022 3023 sme_debug("Received stop bss rsp on vdev: %d", vdev_id); 3024 mac->roam.roamSession[vdev_id].connectState = 3025 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; 3026 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac, vdev_id)) { 3027 if (stop_bss_rsp->status_code != eSIR_SME_SUCCESS) 3028 result_code = CSR_SAP_STOP_BSS_FAILURE; 3029 csr_process_sap_response(mac, result_code, NULL, vdev_id); 3030 } 3031 } 3032 3033 static 3034 void csr_roam_roaming_state_disassoc_rsp_processor(struct mac_context *mac, 3035 struct disassoc_rsp *rsp) 3036 { 3037 struct csr_roam_session *pSession; 3038 3039 sme_debug("Received disassoc response for vdev : %d status : %d", 3040 rsp->sessionId, rsp->status_code); 3041 3042 pSession = CSR_GET_SESSION(mac, rsp->sessionId); 3043 if (!pSession) { 3044 sme_err("session not found"); 3045 return; 3046 } 3047 3048 csr_roam_complete(mac, rsp->sessionId); 3049 } 3050 3051 static void csr_roam_roaming_state_deauth_rsp_processor(struct mac_context *mac, 3052 struct deauth_rsp *rsp) 3053 { 3054 csr_roam_complete(mac, rsp->sessionId); 3055 } 3056 3057 void 3058 csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context *mac, 3059 void *msg) 3060 { 3061 enum csr_sap_response_type result; 3062 struct start_bss_rsp *start_bss_rsp = (struct start_bss_rsp *)msg; 3063 3064 if (!CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(mac, start_bss_rsp->vdev_id)) { 3065 sme_err(" Start bss received in invalid state"); 3066 return; 3067 } 3068 3069 sme_debug("Start Bss response status : %d", 3070 start_bss_rsp->status_code); 3071 if (start_bss_rsp->status_code == eSIR_SME_SUCCESS) 3072 result = CSR_SAP_START_BSS_SUCCESS; 3073 else 3074 result = CSR_SAP_START_BSS_FAILURE; 3075 3076 csr_process_sap_response(mac, result, start_bss_rsp, 3077 start_bss_rsp->vdev_id); 3078 } 3079 3080 3081 /** 3082 * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD. 3083 * 3084 * @mac_ctx: mac global context 3085 * @msg_ptr: incoming message 3086 * 3087 * This function gives final disconnect event to HDD after all cleanup in 3088 * lower layers is done. 3089 * 3090 * Return: None 3091 */ 3092 static void 3093 csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx, 3094 tSirSmeRsp *msg_ptr) 3095 { 3096 struct sir_sme_discon_done_ind *discon_ind = 3097 (struct sir_sme_discon_done_ind *)(msg_ptr); 3098 struct csr_roam_info *roam_info; 3099 uint8_t vdev_id; 3100 3101 vdev_id = discon_ind->session_id; 3102 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 3103 if (!roam_info) 3104 return; 3105 3106 sme_debug("DISCONNECT_DONE_IND RC:%d", discon_ind->reason_code); 3107 3108 if (CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 3109 roam_info->reasonCode = discon_ind->reason_code; 3110 roam_info->status_code = eSIR_SME_STA_NOT_ASSOCIATED; 3111 qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac, 3112 ETH_ALEN); 3113 3114 roam_info->rssi = mac_ctx->peer_rssi; 3115 roam_info->tx_rate = mac_ctx->peer_txrate; 3116 roam_info->rx_rate = mac_ctx->peer_rxrate; 3117 roam_info->disassoc_reason = discon_ind->reason_code; 3118 roam_info->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; 3119 roam_info->rx_retry_cnt = mac_ctx->rx_retry_cnt; 3120 csr_roam_call_callback(mac_ctx, vdev_id, 3121 roam_info, eCSR_ROAM_LOSTLINK, 3122 eCSR_ROAM_RESULT_DISASSOC_IND); 3123 } else { 3124 sme_err("Inactive vdev_id %d", vdev_id); 3125 } 3126 3127 /* 3128 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND 3129 * has been sent to HDD and there is nothing else left to do. 3130 */ 3131 csr_roam_wm_status_change_complete(mac_ctx, vdev_id); 3132 qdf_mem_free(roam_info); 3133 } 3134 3135 /** 3136 * csr_roaming_state_msg_processor() - process roaming messages 3137 * @mac: mac global context 3138 * @msg_buf: message buffer 3139 * 3140 * We need to be careful on whether to cast msg_buf (pSmeRsp) to other type of 3141 * structures. It depends on how the message is constructed. If the message is 3142 * sent by lim_send_sme_rsp, the msg_buf is only a generic response and can only 3143 * be used as pointer to tSirSmeRsp. For the messages where sender allocates 3144 * memory for specific structures, then it can be cast accordingly. 3145 * 3146 * Return: status of operation 3147 */ 3148 void csr_roaming_state_msg_processor(struct mac_context *mac, void *msg_buf) 3149 { 3150 tSirSmeRsp *pSmeRsp; 3151 3152 pSmeRsp = (tSirSmeRsp *)msg_buf; 3153 3154 switch (pSmeRsp->messageType) { 3155 case eWNI_SME_DISASSOC_RSP: 3156 /* or the Disassociate response message... */ 3157 if (CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(mac, pSmeRsp->vdev_id)) { 3158 sme_debug("eWNI_SME_DISASSOC_RSP subState = %s", 3159 mac_trace_getcsr_roam_sub_state( 3160 mac->roam.curSubState[pSmeRsp->vdev_id])); 3161 csr_roam_roaming_state_disassoc_rsp_processor(mac, 3162 (struct disassoc_rsp *) pSmeRsp); 3163 } 3164 break; 3165 case eWNI_SME_DEAUTH_RSP: 3166 /* or the Deauthentication response message... */ 3167 if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(mac, pSmeRsp->vdev_id)) 3168 csr_roam_roaming_state_deauth_rsp_processor(mac, 3169 (struct deauth_rsp *) pSmeRsp); 3170 break; 3171 /* In case CSR issues STOP_BSS, we need to tell HDD about peer departed 3172 * because PE is removing them 3173 */ 3174 case eWNI_SME_TRIGGER_SAE: 3175 sme_debug("Invoke SAE callback"); 3176 csr_sae_callback(mac, pSmeRsp); 3177 break; 3178 3179 case eWNI_SME_SETCONTEXT_RSP: 3180 csr_roam_check_for_link_status_change(mac, pSmeRsp); 3181 break; 3182 3183 case eWNI_SME_DISCONNECT_DONE_IND: 3184 csr_roam_send_disconnect_done_indication(mac, pSmeRsp); 3185 break; 3186 3187 case eWNI_SME_UPPER_LAYER_ASSOC_CNF: 3188 csr_roam_joined_state_msg_processor(mac, pSmeRsp); 3189 break; 3190 default: 3191 sme_debug("Unexpected message type: %d[0x%X] received in substate %s", 3192 pSmeRsp->messageType, pSmeRsp->messageType, 3193 mac_trace_getcsr_roam_sub_state( 3194 mac->roam.curSubState[pSmeRsp->vdev_id])); 3195 /* If we are connected, check the link status change */ 3196 if (!csr_is_conn_state_disconnected(mac, pSmeRsp->vdev_id)) 3197 csr_roam_check_for_link_status_change(mac, pSmeRsp); 3198 break; 3199 } 3200 } 3201 3202 #ifdef WLAN_FEATURE_11BE_MLO 3203 static void 3204 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info, 3205 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf, 3206 uint32_t num_bytes) 3207 { 3208 qdf_mem_copy(roam_info->peer_mld.bytes, 3209 pUpperLayerAssocCnf->peer_mld_addr, 3210 num_bytes); 3211 } 3212 #else /* WLAN_FEATURE_11BE_MLO */ 3213 static inline void 3214 csr_roam_assoc_cnf_mld_copy(struct csr_roam_info *roam_info, 3215 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf, 3216 uint32_t num_bytes) 3217 { 3218 } 3219 #endif /* WLAN_FEATURE_11BE_MLO */ 3220 3221 void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *msg_buf) 3222 { 3223 tSirSmeRsp *pSirMsg = (tSirSmeRsp *)msg_buf; 3224 3225 switch (pSirMsg->messageType) { 3226 case eWNI_SME_UPPER_LAYER_ASSOC_CNF: 3227 { 3228 struct csr_roam_session *pSession; 3229 tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf; 3230 struct csr_roam_info *roam_info; 3231 uint32_t sessionId; 3232 QDF_STATUS status; 3233 enum QDF_OPMODE opmode; 3234 3235 sme_debug("ASSOCIATION confirmation can be given to upper layer "); 3236 pUpperLayerAssocCnf = 3237 (tSirSmeAssocIndToUpperLayerCnf *)msg_buf; 3238 status = csr_roam_get_session_id_from_bssid(mac, 3239 (struct qdf_mac_addr *) 3240 pUpperLayerAssocCnf-> 3241 bssId, &sessionId); 3242 pSession = CSR_GET_SESSION(mac, sessionId); 3243 3244 if (!pSession) { 3245 sme_err("session %d not found", sessionId); 3246 if (pUpperLayerAssocCnf->ies) 3247 qdf_mem_free(pUpperLayerAssocCnf->ies); 3248 return; 3249 } 3250 3251 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 3252 if (!roam_info) { 3253 if (pUpperLayerAssocCnf->ies) 3254 qdf_mem_free(pUpperLayerAssocCnf->ies); 3255 return; 3256 } 3257 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, sessionId); 3258 /* send the status code as Success */ 3259 roam_info->status_code = eSIR_SME_SUCCESS; 3260 roam_info->staId = (uint8_t) pUpperLayerAssocCnf->aid; 3261 roam_info->rsnIELen = 3262 (uint8_t) pUpperLayerAssocCnf->rsnIE.length; 3263 roam_info->prsnIE = 3264 pUpperLayerAssocCnf->rsnIE.rsnIEdata; 3265 #ifdef FEATURE_WLAN_WAPI 3266 roam_info->wapiIELen = 3267 (uint8_t) pUpperLayerAssocCnf->wapiIE.length; 3268 roam_info->pwapiIE = 3269 pUpperLayerAssocCnf->wapiIE.wapiIEdata; 3270 #endif 3271 roam_info->addIELen = 3272 (uint8_t) pUpperLayerAssocCnf->addIE.length; 3273 roam_info->paddIE = 3274 pUpperLayerAssocCnf->addIE.addIEdata; 3275 qdf_mem_copy(roam_info->peerMac.bytes, 3276 pUpperLayerAssocCnf->peerMacAddr, 3277 sizeof(tSirMacAddr)); 3278 csr_roam_assoc_cnf_mld_copy(roam_info, 3279 pUpperLayerAssocCnf, 3280 sizeof(tSirMacAddr)); 3281 qdf_mem_copy(&roam_info->bssid, 3282 pUpperLayerAssocCnf->bssId, 3283 sizeof(struct qdf_mac_addr)); 3284 roam_info->wmmEnabledSta = 3285 pUpperLayerAssocCnf->wmmEnabledSta; 3286 roam_info->timingMeasCap = 3287 pUpperLayerAssocCnf->timingMeasCap; 3288 qdf_mem_copy(&roam_info->chan_info, 3289 &pUpperLayerAssocCnf->chan_info, 3290 sizeof(struct oem_channel_info)); 3291 3292 roam_info->ampdu = pUpperLayerAssocCnf->ampdu; 3293 roam_info->sgi_enable = pUpperLayerAssocCnf->sgi_enable; 3294 roam_info->tx_stbc = pUpperLayerAssocCnf->tx_stbc; 3295 roam_info->rx_stbc = pUpperLayerAssocCnf->rx_stbc; 3296 roam_info->ch_width = pUpperLayerAssocCnf->ch_width; 3297 roam_info->mode = pUpperLayerAssocCnf->mode; 3298 roam_info->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx; 3299 roam_info->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx; 3300 roam_info->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx; 3301 roam_info->max_real_mcs_idx = 3302 pUpperLayerAssocCnf->max_real_mcs_idx; 3303 roam_info->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map; 3304 roam_info->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map; 3305 roam_info->ecsa_capable = pUpperLayerAssocCnf->ecsa_capable; 3306 roam_info->ext_cap = pUpperLayerAssocCnf->ext_cap; 3307 roam_info->supported_band = 3308 pUpperLayerAssocCnf->supported_band; 3309 if (pUpperLayerAssocCnf->ht_caps.present) 3310 roam_info->ht_caps = pUpperLayerAssocCnf->ht_caps; 3311 if (pUpperLayerAssocCnf->vht_caps.present) 3312 roam_info->vht_caps = pUpperLayerAssocCnf->vht_caps; 3313 roam_info->capability_info = 3314 pUpperLayerAssocCnf->capability_info; 3315 roam_info->he_caps_present = 3316 pUpperLayerAssocCnf->he_caps_present; 3317 roam_info->eht_caps_present = 3318 pUpperLayerAssocCnf->eht_caps_present; 3319 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 3320 if (pUpperLayerAssocCnf->ies_len > 0) { 3321 roam_info->assocReqLength = 3322 pUpperLayerAssocCnf->ies_len; 3323 roam_info->assocReqPtr = 3324 pUpperLayerAssocCnf->ies; 3325 } 3326 3327 mac->roam.roamSession[sessionId].connectState = 3328 eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; 3329 roam_info->fReassocReq = 3330 pUpperLayerAssocCnf->reassocReq; 3331 status = csr_roam_call_callback(mac, sessionId, 3332 roam_info, 3333 eCSR_ROAM_INFRA_IND, 3334 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); 3335 } 3336 if (pUpperLayerAssocCnf->ies) 3337 qdf_mem_free(pUpperLayerAssocCnf->ies); 3338 qdf_mem_free(roam_info); 3339 } 3340 break; 3341 default: 3342 csr_roam_check_for_link_status_change(mac, pSirMsg); 3343 break; 3344 } 3345 } 3346 3347 /** 3348 * csr_update_wep_key_peer_macaddr() - Update wep key peer mac addr 3349 * @vdev: vdev object 3350 * @crypto_key: crypto key info 3351 * @unicast: uncast or broadcast 3352 * @mac_addr: peer mac address 3353 * 3354 * Update peer mac address to key context before set wep key to target. 3355 * 3356 * Return void 3357 */ 3358 static void 3359 csr_update_wep_key_peer_macaddr(struct wlan_objmgr_vdev *vdev, 3360 struct wlan_crypto_key *crypto_key, 3361 bool unicast, 3362 struct qdf_mac_addr *mac_addr) 3363 { 3364 if (!crypto_key || !vdev) { 3365 sme_err("vdev or crytpo_key null"); 3366 return; 3367 } 3368 3369 if (unicast) { 3370 qdf_mem_copy(&crypto_key->macaddr, mac_addr, 3371 QDF_MAC_ADDR_SIZE); 3372 } else { 3373 if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE || 3374 vdev->vdev_mlme.vdev_opmode == QDF_P2P_CLIENT_MODE) 3375 qdf_mem_copy(&crypto_key->macaddr, mac_addr, 3376 QDF_MAC_ADDR_SIZE); 3377 else 3378 qdf_mem_copy(&crypto_key->macaddr, 3379 vdev->vdev_mlme.macaddr, 3380 QDF_MAC_ADDR_SIZE); 3381 } 3382 } 3383 3384 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR 3385 static void 3386 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, 3387 struct csr_roam_session *session, 3388 struct set_context_rsp *pRsp) 3389 { 3390 WLAN_HOST_DIAG_EVENT_DEF(setKeyEvent, 3391 host_event_wlan_security_payload_type); 3392 struct wlan_objmgr_vdev *vdev; 3393 3394 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, 3395 session->vdev_id, 3396 WLAN_LEGACY_SME_ID); 3397 if (!vdev) 3398 return; 3399 if (cm_is_open_mode(vdev)) { 3400 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 3401 return; 3402 } 3403 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 3404 3405 qdf_mem_zero(&setKeyEvent, 3406 sizeof(host_event_wlan_security_payload_type)); 3407 if (qdf_is_macaddr_group(&pRsp->peer_macaddr)) 3408 setKeyEvent.eventId = 3409 WLAN_SECURITY_EVENT_SET_BCAST_RSP; 3410 else 3411 setKeyEvent.eventId = 3412 WLAN_SECURITY_EVENT_SET_UNICAST_RSP; 3413 cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc, 3414 &setKeyEvent.authMode, 3415 &setKeyEvent.encryptionModeUnicast, 3416 &setKeyEvent.encryptionModeMulticast, 3417 session->vdev_id); 3418 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session->vdev_id, 3419 (struct qdf_mac_addr *)&setKeyEvent.bssid); 3420 if (eSIR_SME_SUCCESS != pRsp->status_code) 3421 setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; 3422 WLAN_HOST_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); 3423 } 3424 #else /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ 3425 static void 3426 csr_roam_diag_set_ctx_rsp(struct mac_context *mac_ctx, 3427 struct csr_roam_session *session, 3428 struct set_context_rsp *pRsp) 3429 { 3430 } 3431 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ 3432 3433 #ifdef WLAN_FEATURE_11BE_MLO 3434 static QDF_STATUS 3435 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id) 3436 { 3437 struct wlan_objmgr_vdev *vdev = NULL; 3438 struct wlan_objmgr_vdev *assoc_vdev = NULL; 3439 3440 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 3441 vdev_id, 3442 WLAN_MLME_OBJMGR_ID); 3443 if (!vdev) { 3444 sme_err("vdev object is NULL for vdev %d", vdev_id); 3445 return QDF_STATUS_E_FAILURE; 3446 } 3447 3448 if (wlan_vdev_mlme_is_mlo_vdev(vdev) && 3449 mlo_check_if_all_links_up(vdev)) { 3450 assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev); 3451 if (!assoc_vdev) { 3452 sme_err("Assoc vdev is null"); 3453 wlan_objmgr_vdev_release_ref(vdev, 3454 WLAN_MLME_OBJMGR_ID); 3455 return QDF_STATUS_E_FAILURE; 3456 } 3457 cm_roam_start_init_on_connect(mac_ctx->pdev, 3458 wlan_vdev_get_id(assoc_vdev)); 3459 } else if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) { 3460 cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id); 3461 } 3462 wlan_objmgr_vdev_release_ref(vdev, 3463 WLAN_MLME_OBJMGR_ID); 3464 return QDF_STATUS_SUCCESS; 3465 } 3466 #else 3467 static QDF_STATUS 3468 csr_roam_send_rso_enable(struct mac_context *mac_ctx, uint8_t vdev_id) 3469 { 3470 cm_roam_start_init_on_connect(mac_ctx->pdev, vdev_id); 3471 return QDF_STATUS_SUCCESS; 3472 } 3473 #endif 3474 3475 static void 3476 csr_roam_chk_lnk_set_ctx_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 3477 { 3478 struct csr_roam_session *session; 3479 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 3480 QDF_STATUS status; 3481 qdf_freq_t chan_freq; 3482 struct csr_roam_info *roam_info; 3483 eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; 3484 struct set_context_rsp *pRsp = (struct set_context_rsp *)msg_ptr; 3485 struct qdf_mac_addr connected_bssid; 3486 3487 if (!pRsp) { 3488 sme_err("set key response is NULL"); 3489 return; 3490 } 3491 3492 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 3493 if (!roam_info) 3494 return; 3495 sessionId = pRsp->sessionId; 3496 session = CSR_GET_SESSION(mac_ctx, sessionId); 3497 if (!session) { 3498 sme_err("session %d not found", sessionId); 3499 qdf_mem_free(roam_info); 3500 return; 3501 } 3502 3503 csr_roam_diag_set_ctx_rsp(mac_ctx, session, pRsp); 3504 chan_freq = wlan_get_operation_chan_freq_vdev_id(mac_ctx->pdev, 3505 sessionId); 3506 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId, 3507 &connected_bssid); 3508 sme_debug("vdev %d, Status %d, peer_macaddr "QDF_MAC_ADDR_FMT " obss offload %d freq %d opmode %d", 3509 pRsp->sessionId, pRsp->status_code, 3510 QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes), 3511 mac_ctx->obss_scan_offload, chan_freq, 3512 wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId)); 3513 3514 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, sessionId)) { 3515 /* We are done with authentication, whethere succeed or not */ 3516 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, 3517 sessionId); 3518 cm_stop_wait_for_key_timer(mac_ctx->psoc, sessionId); 3519 if (QDF_IS_STATUS_ERROR(csr_roam_send_rso_enable(mac_ctx, 3520 sessionId))) { 3521 qdf_mem_free(roam_info); 3522 return; 3523 } 3524 } 3525 if (eSIR_SME_SUCCESS == pRsp->status_code) { 3526 qdf_copy_macaddr(&roam_info->peerMac, &pRsp->peer_macaddr); 3527 /* Make sure we install the GTK before indicating to HDD as 3528 * authenticated. This is to prevent broadcast packets go out 3529 * after PTK and before GTK. 3530 */ 3531 if (qdf_is_macaddr_broadcast(&pRsp->peer_macaddr)) { 3532 /* 3533 * OBSS SCAN Indication will be sent to Firmware 3534 * to start OBSS Scan 3535 */ 3536 if (mac_ctx->obss_scan_offload && 3537 wlan_reg_is_24ghz_ch_freq(chan_freq) && 3538 cm_is_vdevid_connected(mac_ctx->pdev, sessionId)) { 3539 struct sme_obss_ht40_scanind_msg *msg; 3540 3541 msg = qdf_mem_malloc(sizeof( 3542 struct sme_obss_ht40_scanind_msg)); 3543 if (!msg) { 3544 qdf_mem_free(roam_info); 3545 return; 3546 } 3547 3548 msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND; 3549 msg->length = 3550 sizeof(struct sme_obss_ht40_scanind_msg); 3551 qdf_copy_macaddr(&msg->mac_addr, 3552 &connected_bssid); 3553 status = umac_send_mb_message_to_mac(msg); 3554 } 3555 result = eCSR_ROAM_RESULT_AUTHENTICATED; 3556 } else { 3557 result = eCSR_ROAM_RESULT_NONE; 3558 } 3559 } else { 3560 result = eCSR_ROAM_RESULT_FAILURE; 3561 sme_err( 3562 "CSR: setkey command failed(err=%d) PeerMac " 3563 QDF_MAC_ADDR_FMT, 3564 pRsp->status_code, 3565 QDF_MAC_ADDR_REF(pRsp->peer_macaddr.bytes)); 3566 } 3567 csr_roam_call_callback(mac_ctx, sessionId, roam_info, 3568 eCSR_ROAM_SET_KEY_COMPLETE, result); 3569 /* Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS 3570 * can go ahead and initiate the TSPEC if any are pending 3571 */ 3572 sme_qos_csr_event_ind(mac_ctx, (uint8_t)sessionId, 3573 SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL); 3574 #ifdef FEATURE_WLAN_ESE 3575 /* Send Adjacent AP repot to new AP. */ 3576 if (result == eCSR_ROAM_RESULT_AUTHENTICATED && 3577 session->isPrevApInfoValid && 3578 wlan_cm_get_ese_assoc(mac_ctx->pdev, sessionId)) { 3579 csr_send_ese_adjacent_ap_rep_ind(mac_ctx, session); 3580 session->isPrevApInfoValid = false; 3581 } 3582 #endif 3583 qdf_mem_free(roam_info); 3584 } 3585 3586 static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx, 3587 uint32_t session_id, 3588 bool add_key, bool unicast, 3589 uint8_t key_idx, 3590 struct qdf_mac_addr *mac_addr) 3591 { 3592 enum wlan_crypto_cipher_type cipher; 3593 struct wlan_crypto_key *crypto_key; 3594 uint8_t wep_key_idx = 0; 3595 struct wlan_objmgr_vdev *vdev; 3596 3597 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id, 3598 WLAN_LEGACY_MAC_ID); 3599 if (!vdev) { 3600 sme_err("VDEV object not found for session_id %d", session_id); 3601 return QDF_STATUS_E_INVAL; 3602 } 3603 cipher = wlan_crypto_get_cipher(vdev, unicast, key_idx); 3604 if (IS_WEP_CIPHER(cipher)) { 3605 wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast); 3606 crypto_key = wlan_crypto_get_key(vdev, wep_key_idx); 3607 csr_update_wep_key_peer_macaddr(vdev, crypto_key, unicast, 3608 mac_addr); 3609 } else { 3610 crypto_key = wlan_crypto_get_key(vdev, key_idx); 3611 } 3612 3613 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 3614 3615 sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d", 3616 session_id, cipher, unicast, key_idx, wep_key_idx, add_key); 3617 if (!IS_WEP_CIPHER(cipher) && !add_key) 3618 return QDF_STATUS_E_INVAL; 3619 3620 return ucfg_crypto_set_key_req(vdev, crypto_key, (unicast ? 3621 WLAN_CRYPTO_KEY_TYPE_UNICAST : 3622 WLAN_CRYPTO_KEY_TYPE_GROUP)); 3623 } 3624 3625 QDF_STATUS 3626 csr_issue_set_context_req_helper(struct mac_context *mac_ctx, 3627 uint32_t vdev_id, tSirMacAddr *bssid, 3628 bool addkey, bool unicast, uint8_t key_id) 3629 { 3630 return csr_roam_issue_set_context_req(mac_ctx, vdev_id, addkey, 3631 unicast, key_id, 3632 (struct qdf_mac_addr *)bssid); 3633 } 3634 3635 static 3636 bool csr_roam_issue_wm_status_change(struct mac_context *mac, uint32_t sessionId, 3637 enum csr_roam_wmstatus_changetypes Type, 3638 tSirSmeRsp *pSmeRsp) 3639 { 3640 bool fCommandQueued = false; 3641 tSmeCmd *pCommand; 3642 3643 do { 3644 /* Validate the type is ok... */ 3645 if ((eCsrDisassociated != Type) 3646 && (eCsrDeauthenticated != Type)) 3647 break; 3648 pCommand = csr_get_command_buffer(mac); 3649 if (!pCommand) { 3650 sme_err(" fail to get command buffer"); 3651 break; 3652 } 3653 3654 pCommand->command = eSmeCommandWmStatusChange; 3655 pCommand->vdev_id = (uint8_t) sessionId; 3656 pCommand->u.wmStatusChangeCmd.Type = Type; 3657 if (eCsrDisassociated == Type) { 3658 qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u. 3659 DisassocIndMsg, pSmeRsp, 3660 sizeof(pCommand->u.wmStatusChangeCmd.u. 3661 DisassocIndMsg)); 3662 } else { 3663 qdf_mem_copy(&pCommand->u.wmStatusChangeCmd.u. 3664 DeauthIndMsg, pSmeRsp, 3665 sizeof(pCommand->u.wmStatusChangeCmd.u. 3666 DeauthIndMsg)); 3667 } 3668 if (QDF_IS_STATUS_SUCCESS 3669 (csr_queue_sme_command(mac, pCommand, false))) 3670 fCommandQueued = true; 3671 else 3672 sme_err("fail to send message"); 3673 } while (0); 3674 return fCommandQueued; 3675 } 3676 3677 static void csr_update_snr(struct mac_context *mac, void *pMsg) 3678 { 3679 tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq *) pMsg; 3680 3681 if (pGetSnrReq) { 3682 if (QDF_STATUS_SUCCESS != wma_get_snr(pGetSnrReq)) { 3683 sme_err("Error in wma_get_snr"); 3684 return; 3685 } 3686 3687 } else 3688 sme_err("pGetSnrReq is NULL"); 3689 } 3690 3691 /** 3692 * csr_translate_akm_type() - Convert ani_akm_type value to equivalent 3693 * enum csr_akm_type 3694 * @akm_type: value of type ani_akm_type 3695 * 3696 * Return: enum csr_akm_type value 3697 */ 3698 static enum csr_akm_type csr_translate_akm_type(enum ani_akm_type akm_type) 3699 { 3700 enum csr_akm_type csr_akm_type; 3701 3702 switch (akm_type) 3703 { 3704 case ANI_AKM_TYPE_NONE: 3705 csr_akm_type = eCSR_AUTH_TYPE_NONE; 3706 break; 3707 #ifdef WLAN_FEATURE_SAE 3708 case ANI_AKM_TYPE_SAE: 3709 csr_akm_type = eCSR_AUTH_TYPE_SAE; 3710 break; 3711 #endif 3712 case ANI_AKM_TYPE_WPA: 3713 csr_akm_type = eCSR_AUTH_TYPE_WPA; 3714 break; 3715 case ANI_AKM_TYPE_WPA_PSK: 3716 csr_akm_type = eCSR_AUTH_TYPE_WPA_PSK; 3717 break; 3718 case ANI_AKM_TYPE_RSN: 3719 csr_akm_type = eCSR_AUTH_TYPE_RSN; 3720 break; 3721 case ANI_AKM_TYPE_RSN_PSK: 3722 csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK; 3723 break; 3724 case ANI_AKM_TYPE_FT_RSN: 3725 csr_akm_type = eCSR_AUTH_TYPE_FT_RSN; 3726 break; 3727 case ANI_AKM_TYPE_FT_RSN_PSK: 3728 csr_akm_type = eCSR_AUTH_TYPE_FT_RSN_PSK; 3729 break; 3730 #ifdef FEATURE_WLAN_ESE 3731 case ANI_AKM_TYPE_CCKM: 3732 csr_akm_type = eCSR_AUTH_TYPE_CCKM_RSN; 3733 break; 3734 #endif 3735 case ANI_AKM_TYPE_RSN_PSK_SHA256: 3736 csr_akm_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; 3737 break; 3738 case ANI_AKM_TYPE_RSN_8021X_SHA256: 3739 csr_akm_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; 3740 break; 3741 case ANI_AKM_TYPE_FILS_SHA256: 3742 csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA256; 3743 break; 3744 case ANI_AKM_TYPE_FILS_SHA384: 3745 csr_akm_type = eCSR_AUTH_TYPE_FILS_SHA384; 3746 break; 3747 case ANI_AKM_TYPE_FT_FILS_SHA256: 3748 csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA256; 3749 break; 3750 case ANI_AKM_TYPE_FT_FILS_SHA384: 3751 csr_akm_type = eCSR_AUTH_TYPE_FT_FILS_SHA384; 3752 break; 3753 case ANI_AKM_TYPE_DPP_RSN: 3754 csr_akm_type = eCSR_AUTH_TYPE_DPP_RSN; 3755 break; 3756 case ANI_AKM_TYPE_OWE: 3757 csr_akm_type = eCSR_AUTH_TYPE_OWE; 3758 break; 3759 case ANI_AKM_TYPE_SUITEB_EAP_SHA256: 3760 csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA256; 3761 break; 3762 case ANI_AKM_TYPE_SUITEB_EAP_SHA384: 3763 csr_akm_type = eCSR_AUTH_TYPE_SUITEB_EAP_SHA384; 3764 break; 3765 case ANI_AKM_TYPE_OSEN: 3766 csr_akm_type = eCSR_AUTH_TYPE_OSEN; 3767 break; 3768 default: 3769 csr_akm_type = eCSR_AUTH_TYPE_UNKNOWN; 3770 } 3771 3772 return csr_akm_type; 3773 } 3774 3775 #ifdef WLAN_FEATURE_11BE_MLO 3776 static void 3777 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf, 3778 struct assoc_ind *ind) 3779 { 3780 qdf_mem_copy(&cnf->peer_mld_addr, &ind->peer_mld_addr, 3781 sizeof(cnf->peer_mld_addr)); 3782 } 3783 #else /* WLAN_FEATURE_11BE_MLO */ 3784 static inline void 3785 csr_send_assoc_ind_to_upper_layer_mac_copy(tSirSmeAssocIndToUpperLayerCnf *cnf, 3786 struct assoc_ind *ind) 3787 { 3788 } 3789 #endif /* WLAN_FEATURE_11BE_MLO */ 3790 3791 static QDF_STATUS 3792 csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac, 3793 struct assoc_ind *ind, 3794 QDF_STATUS status, 3795 uint8_t vdev_id) 3796 { 3797 struct scheduler_msg msg = {0}; 3798 tSirSmeAssocIndToUpperLayerCnf *cnf; 3799 3800 cnf = qdf_mem_malloc(sizeof(*cnf)); 3801 if (!cnf) 3802 return QDF_STATUS_E_NOMEM; 3803 3804 cnf->messageType = eWNI_SME_UPPER_LAYER_ASSOC_CNF; 3805 cnf->length = sizeof(*cnf); 3806 cnf->sessionId = vdev_id; 3807 3808 if (QDF_IS_STATUS_SUCCESS(status)) 3809 cnf->status_code = eSIR_SME_SUCCESS; 3810 else 3811 cnf->status_code = eSIR_SME_ASSOC_REFUSED; 3812 qdf_mem_copy(&cnf->bssId, &ind->bssId, sizeof(cnf->bssId)); 3813 qdf_mem_copy(&cnf->peerMacAddr, &ind->peerMacAddr, 3814 sizeof(cnf->peerMacAddr)); 3815 csr_send_assoc_ind_to_upper_layer_mac_copy(cnf, ind); 3816 cnf->aid = ind->staId; 3817 cnf->wmmEnabledSta = ind->wmmEnabledSta; 3818 cnf->rsnIE = ind->rsnIE; 3819 #ifdef FEATURE_WLAN_WAPI 3820 cnf->wapiIE = ind->wapiIE; 3821 #endif 3822 cnf->addIE = ind->addIE; 3823 cnf->reassocReq = ind->reassocReq; 3824 cnf->timingMeasCap = ind->timingMeasCap; 3825 cnf->chan_info = ind->chan_info; 3826 cnf->ampdu = ind->ampdu; 3827 cnf->sgi_enable = ind->sgi_enable; 3828 cnf->tx_stbc = ind->tx_stbc; 3829 cnf->ch_width = ind->ch_width; 3830 cnf->mode = ind->mode; 3831 cnf->rx_stbc = ind->rx_stbc; 3832 cnf->max_supp_idx = ind->max_supp_idx; 3833 cnf->max_ext_idx = ind->max_ext_idx; 3834 cnf->max_mcs_idx = ind->max_mcs_idx; 3835 cnf->max_real_mcs_idx = ind->max_real_mcs_idx; 3836 cnf->rx_mcs_map = ind->rx_mcs_map; 3837 cnf->tx_mcs_map = ind->tx_mcs_map; 3838 cnf->ecsa_capable = ind->ecsa_capable; 3839 cnf->ext_cap = ind->ext_cap; 3840 cnf->supported_band = ind->supported_band; 3841 if (ind->HTCaps.present) 3842 cnf->ht_caps = ind->HTCaps; 3843 if (ind->VHTCaps.present) 3844 cnf->vht_caps = ind->VHTCaps; 3845 cnf->capability_info = ind->capability_info; 3846 cnf->he_caps_present = ind->he_caps_present; 3847 cnf->eht_caps_present = ind->eht_caps_present; 3848 if (ind->assocReqPtr) { 3849 if (ind->assocReqLength < MAX_ASSOC_REQ_IE_LEN) { 3850 cnf->ies = qdf_mem_malloc(ind->assocReqLength); 3851 if (!cnf->ies) { 3852 qdf_mem_free(cnf); 3853 return QDF_STATUS_E_NOMEM; 3854 } 3855 cnf->ies_len = ind->assocReqLength; 3856 qdf_mem_copy(cnf->ies, ind->assocReqPtr, 3857 cnf->ies_len); 3858 } else { 3859 sme_err("Assoc Ie length is too long"); 3860 } 3861 } 3862 3863 msg.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; 3864 msg.bodyptr = cnf; 3865 sys_process_mmh_msg(mac, &msg); 3866 3867 return QDF_STATUS_SUCCESS; 3868 } 3869 3870 static void 3871 csr_roam_chk_lnk_assoc_ind_upper_layer( 3872 struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 3873 { 3874 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; 3875 struct assoc_ind *assoc_ind; 3876 QDF_STATUS status; 3877 3878 assoc_ind = (struct assoc_ind *)msg_ptr; 3879 status = csr_roam_get_session_id_from_bssid( 3880 mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId, 3881 &session_id); 3882 if (!QDF_IS_STATUS_SUCCESS(status)) { 3883 sme_debug("Couldn't find session_id for given BSSID"); 3884 goto free_mem; 3885 } 3886 csr_send_assoc_ind_to_upper_layer_cnf_msg( 3887 mac_ctx, assoc_ind, status, session_id); 3888 /*in the association response tx compete case, 3889 *memory for assoc_ind->assocReqPtr will be malloced 3890 *in the lim_assoc_rsp_tx_complete -> lim_fill_sme_assoc_ind_params 3891 *and then assoc_ind will pass here, so after using it 3892 *in the csr_send_assoc_ind_to_upper_layer_cnf_msg and 3893 *then free the memory here. 3894 */ 3895 free_mem: 3896 if (assoc_ind->assocReqLength != 0 && assoc_ind->assocReqPtr) 3897 qdf_mem_free(assoc_ind->assocReqPtr); 3898 } 3899 3900 static void 3901 csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 3902 { 3903 struct csr_roam_session *session; 3904 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 3905 QDF_STATUS status; 3906 struct csr_roam_info *roam_info; 3907 struct assoc_ind *pAssocInd; 3908 enum wlan_status_code mac_status_code = STATUS_SUCCESS; 3909 enum csr_akm_type csr_akm_type; 3910 enum QDF_OPMODE opmode; 3911 3912 sme_debug("Receive WNI_SME_ASSOC_IND from SME"); 3913 pAssocInd = (struct assoc_ind *) msg_ptr; 3914 sme_debug("Receive WNI_SME_ASSOC_IND from SME vdev id %d", 3915 pAssocInd->sessionId); 3916 status = csr_roam_get_session_id_from_bssid(mac_ctx, 3917 (struct qdf_mac_addr *) pAssocInd->bssId, 3918 &sessionId); 3919 if (!QDF_IS_STATUS_SUCCESS(status)) { 3920 sme_debug("Couldn't find session_id for given BSSID" QDF_MAC_ADDR_FMT, 3921 QDF_MAC_ADDR_REF(pAssocInd->bssId)); 3922 return; 3923 } 3924 session = CSR_GET_SESSION(mac_ctx, sessionId); 3925 if (!session) { 3926 sme_err("session %d not found", sessionId); 3927 return; 3928 } 3929 csr_akm_type = csr_translate_akm_type(pAssocInd->akm_type); 3930 3931 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 3932 if (!roam_info) 3933 return; 3934 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId); 3935 /* Required for indicating the frames to upper layer */ 3936 roam_info->assocReqLength = pAssocInd->assocReqLength; 3937 roam_info->assocReqPtr = pAssocInd->assocReqPtr; 3938 roam_info->status_code = eSIR_SME_SUCCESS; 3939 roam_info->staId = (uint8_t)pAssocInd->staId; 3940 roam_info->rsnIELen = (uint8_t)pAssocInd->rsnIE.length; 3941 roam_info->prsnIE = pAssocInd->rsnIE.rsnIEdata; 3942 #ifdef FEATURE_WLAN_WAPI 3943 roam_info->wapiIELen = (uint8_t)pAssocInd->wapiIE.length; 3944 roam_info->pwapiIE = pAssocInd->wapiIE.wapiIEdata; 3945 #endif 3946 roam_info->addIELen = (uint8_t)pAssocInd->addIE.length; 3947 roam_info->paddIE = pAssocInd->addIE.addIEdata; 3948 roam_info->fReassocReq = pAssocInd->reassocReq; 3949 qdf_mem_copy(roam_info->peerMac.bytes, 3950 pAssocInd->peerMacAddr, 3951 sizeof(tSirMacAddr)); 3952 qdf_mem_copy(roam_info->bssid.bytes, 3953 pAssocInd->bssId, 3954 sizeof(struct qdf_mac_addr)); 3955 roam_info->wmmEnabledSta = pAssocInd->wmmEnabledSta; 3956 roam_info->timingMeasCap = pAssocInd->timingMeasCap; 3957 roam_info->ecsa_capable = pAssocInd->ecsa_capable; 3958 qdf_mem_copy(&roam_info->chan_info, 3959 &pAssocInd->chan_info, 3960 sizeof(struct oem_channel_info)); 3961 3962 if (pAssocInd->HTCaps.present) 3963 qdf_mem_copy(&roam_info->ht_caps, 3964 &pAssocInd->HTCaps, 3965 sizeof(tDot11fIEHTCaps)); 3966 if (pAssocInd->VHTCaps.present) 3967 qdf_mem_copy(&roam_info->vht_caps, 3968 &pAssocInd->VHTCaps, 3969 sizeof(tDot11fIEVHTCaps)); 3970 roam_info->capability_info = pAssocInd->capability_info; 3971 roam_info->he_caps_present = pAssocInd->he_caps_present; 3972 roam_info->eht_caps_present = pAssocInd->eht_caps_present; 3973 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 3974 if (wlan_is_open_wep_cipher(mac_ctx->pdev, sessionId)) { 3975 csr_issue_set_context_req_helper(mac_ctx, sessionId, 3976 &roam_info->peerMac.bytes, false, true, 3977 0); 3978 roam_info->fAuthRequired = false; 3979 } else { 3980 roam_info->fAuthRequired = true; 3981 } 3982 sme_debug("Receive AUTH_TYPE of %d", csr_akm_type); 3983 if (csr_akm_type == eCSR_AUTH_TYPE_OWE) { 3984 roam_info->owe_pending_assoc_ind = qdf_mem_malloc( 3985 sizeof(*pAssocInd)); 3986 if (roam_info->owe_pending_assoc_ind) 3987 qdf_mem_copy(roam_info->owe_pending_assoc_ind, 3988 pAssocInd, sizeof(*pAssocInd)); 3989 } else if (csr_akm_type == eCSR_AUTH_TYPE_FT_RSN_PSK) { 3990 roam_info->ft_pending_assoc_ind = qdf_mem_malloc( 3991 sizeof(*pAssocInd)); 3992 if (roam_info->ft_pending_assoc_ind) 3993 qdf_mem_copy(roam_info->ft_pending_assoc_ind, 3994 pAssocInd, sizeof(*pAssocInd)); 3995 } 3996 status = csr_roam_call_callback(mac_ctx, sessionId, 3997 roam_info, eCSR_ROAM_INFRA_IND, 3998 eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND); 3999 if (!QDF_IS_STATUS_SUCCESS(status)) { 4000 /* Refused due to Mac filtering */ 4001 if (roam_info->owe_pending_assoc_ind) { 4002 qdf_mem_free(roam_info->owe_pending_assoc_ind); 4003 roam_info->owe_pending_assoc_ind = NULL; 4004 } else if (roam_info->ft_pending_assoc_ind) { 4005 qdf_mem_free(roam_info->ft_pending_assoc_ind); 4006 roam_info->ft_pending_assoc_ind = NULL; 4007 } 4008 roam_info->status_code = eSIR_SME_ASSOC_REFUSED; 4009 } 4010 } 4011 sme_debug("csr_akm_type: %d", csr_akm_type); 4012 4013 if (csr_akm_type != eCSR_AUTH_TYPE_OWE && 4014 csr_akm_type != eCSR_AUTH_TYPE_FT_RSN_PSK) { 4015 if ((opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) && 4016 roam_info->status_code != eSIR_SME_ASSOC_REFUSED) 4017 pAssocInd->need_assoc_rsp_tx_cb = true; 4018 /* Send Association completion message to PE */ 4019 status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status, 4020 mac_status_code); 4021 } 4022 4023 qdf_mem_free(roam_info); 4024 } 4025 4026 /* csr_if_peer_present() - Check whether peer is present or not 4027 * @mac_ctx: Pointer to mac context 4028 * @bssid: Pointer to bssid address 4029 * @peer_macaddr: Pointer to peer mac address 4030 * 4031 * Consider a case 4032 * 1. SAP received south bound disconnect command 4033 * 2. At same time, SAP CSA to DFS channel happened and thus peers are deleted. 4034 * 3. Later same peer got re-added and south bound disconnect command becomes 4035 * active for same peer. 4036 * 4037 * When SAP receives south bound disconnect command req, driver will post to 4038 * schedular thread and it will wait in SME message queue. When SAP CSA to DFS 4039 * channel happens, driver will post to schedular thread and it will wait in PE 4040 * message queue. Since PE has higher priority than SME message queue, so it 4041 * will process first. As part of CSA, it will delete all peer including sta 4042 * hash entry. 4043 * After CSA, south bound disconnect command got queue to serialization and 4044 * same peer got re-added again. When south bound disconnect command becomes 4045 * active, the states will not be proper because for old peer, disassocTrigger 4046 * is eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and when new peer gets 4047 * re-added, disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH and 4048 * thus response to CSR will not be proper. Due to this south bound disconnect 4049 * command will not remove from active queue which leads to active command 4050 * timeout. 4051 * Validate the peer before sending to serialization to avoid queuing command 4052 * if peer is already deleted. 4053 * 4054 * Return: True if peer is present otherwise return false 4055 */ 4056 static bool csr_if_peer_present(struct mac_context *mac_ctx, 4057 uint8_t *bssid, 4058 uint8_t *peer_macaddr) 4059 { 4060 struct wlan_objmgr_peer *peer; 4061 uint8_t pdev_id; 4062 4063 pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev); 4064 4065 peer = wlan_objmgr_get_peer_by_mac_n_vdev(mac_ctx->psoc, pdev_id, 4066 bssid, peer_macaddr, 4067 WLAN_LEGACY_SME_ID); 4068 4069 if (!peer) { 4070 sme_info("peer not found for mac: " QDF_MAC_ADDR_FMT "and bssid: " 4071 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr), 4072 QDF_MAC_ADDR_REF(bssid)); 4073 return false; 4074 } 4075 4076 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID); 4077 return true; 4078 } 4079 4080 static void 4081 csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4082 { 4083 struct csr_roam_session *session; 4084 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4085 struct disassoc_ind *pDisassocInd; 4086 4087 /* 4088 * Check if AP dis-associated us because of MIC failure. If so, 4089 * then we need to take action immediately and not wait till the 4090 * the WmStatusChange requests is pushed and processed 4091 */ 4092 pDisassocInd = (struct disassoc_ind *)msg_ptr; 4093 sessionId = pDisassocInd->vdev_id; 4094 sme_debug("Disassoc Indication from MAC for vdev_id %d bssid " QDF_MAC_ADDR_FMT, 4095 pDisassocInd->vdev_id, 4096 QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes)); 4097 4098 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { 4099 sme_err("vdev:%d Invalid session. BSSID: " QDF_MAC_ADDR_FMT, 4100 sessionId, QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes)); 4101 4102 return; 4103 } 4104 4105 if (!csr_if_peer_present(mac_ctx, &pDisassocInd->bssid.bytes[0], 4106 &pDisassocInd->peer_macaddr.bytes[0])) 4107 return; 4108 4109 if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, 4110 pDisassocInd->peer_macaddr)) 4111 return; 4112 4113 sme_nofl_info("disassoc from peer " QDF_MAC_ADDR_FMT 4114 "reason: %d status: %d vid %d", 4115 QDF_MAC_ADDR_REF(pDisassocInd->peer_macaddr.bytes), 4116 pDisassocInd->reasonCode, 4117 pDisassocInd->status_code, sessionId); 4118 session = CSR_GET_SESSION(mac_ctx, sessionId); 4119 if (!session) { 4120 sme_err("session: %d not found", sessionId); 4121 return; 4122 } 4123 /* Update the disconnect stats */ 4124 session->disconnect_stats.disconnection_cnt++; 4125 session->disconnect_stats.disassoc_by_peer++; 4126 4127 csr_roam_issue_wm_status_change(mac_ctx, sessionId, 4128 eCsrDisassociated, msg_ptr); 4129 } 4130 4131 static void 4132 csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4133 { 4134 struct csr_roam_session *session; 4135 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4136 struct deauth_ind *pDeauthInd; 4137 4138 pDeauthInd = (struct deauth_ind *)msg_ptr; 4139 sme_debug("DEAUTH Indication from MAC for vdev_id %d bssid "QDF_MAC_ADDR_FMT, 4140 pDeauthInd->vdev_id, 4141 QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes)); 4142 4143 sessionId = pDeauthInd->vdev_id; 4144 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { 4145 sme_err("vdev %d: Invalid session BSSID: " QDF_MAC_ADDR_FMT, 4146 pDeauthInd->vdev_id, 4147 QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes)); 4148 return; 4149 } 4150 4151 if (!csr_if_peer_present(mac_ctx, &pDeauthInd->bssid.bytes[0], 4152 &pDeauthInd->peer_macaddr.bytes[0])) 4153 return; 4154 4155 if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, 4156 pDeauthInd->peer_macaddr)) 4157 return; 4158 session = CSR_GET_SESSION(mac_ctx, sessionId); 4159 if (!session) { 4160 sme_err("session %d not found", sessionId); 4161 return; 4162 } 4163 /* Update the disconnect stats */ 4164 switch (pDeauthInd->reasonCode) { 4165 case REASON_DISASSOC_DUE_TO_INACTIVITY: 4166 session->disconnect_stats.disconnection_cnt++; 4167 session->disconnect_stats.peer_kickout++; 4168 break; 4169 case REASON_UNSPEC_FAILURE: 4170 case REASON_PREV_AUTH_NOT_VALID: 4171 case REASON_DEAUTH_NETWORK_LEAVING: 4172 case REASON_CLASS2_FRAME_FROM_NON_AUTH_STA: 4173 case REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA: 4174 case REASON_STA_NOT_AUTHENTICATED: 4175 session->disconnect_stats.disconnection_cnt++; 4176 session->disconnect_stats.deauth_by_peer++; 4177 break; 4178 case REASON_BEACON_MISSED: 4179 session->disconnect_stats.disconnection_cnt++; 4180 session->disconnect_stats.bmiss++; 4181 break; 4182 default: 4183 /* Unknown reason code */ 4184 break; 4185 } 4186 4187 csr_roam_issue_wm_status_change(mac_ctx, sessionId, 4188 eCsrDeauthenticated, 4189 msg_ptr); 4190 } 4191 4192 static void 4193 csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4194 { 4195 struct csr_roam_session *session; 4196 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4197 QDF_STATUS status; 4198 struct switch_channel_ind *pSwitchChnInd; 4199 struct csr_roam_info *roam_info; 4200 4201 /* in case of STA, the SWITCH_CHANNEL originates from its AP */ 4202 sme_debug("eWNI_SME_SWITCH_CHL_IND from SME"); 4203 pSwitchChnInd = (struct switch_channel_ind *)msg_ptr; 4204 /* Update with the new channel id. The channel id is hidden in the 4205 * status_code. 4206 */ 4207 status = csr_roam_get_session_id_from_bssid(mac_ctx, 4208 &pSwitchChnInd->bssid, &sessionId); 4209 if (QDF_IS_STATUS_ERROR(status)) 4210 return; 4211 4212 session = CSR_GET_SESSION(mac_ctx, sessionId); 4213 if (!session) { 4214 sme_err("session %d not found", sessionId); 4215 return; 4216 } 4217 4218 if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) { 4219 sme_err("Channel switch failed"); 4220 return; 4221 } 4222 /* Update the occupied channel list with the new switched channel */ 4223 wlan_cm_init_occupied_ch_freq_list(mac_ctx->pdev, mac_ctx->psoc, 4224 sessionId); 4225 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4226 if (!roam_info) 4227 return; 4228 roam_info->chan_info.mhz = pSwitchChnInd->freq; 4229 roam_info->chan_info.ch_width = pSwitchChnInd->chan_params.ch_width; 4230 roam_info->chan_info.sec_ch_offset = 4231 pSwitchChnInd->chan_params.sec_ch_offset; 4232 roam_info->chan_info.band_center_freq1 = 4233 pSwitchChnInd->chan_params.mhz_freq_seg0; 4234 roam_info->chan_info.band_center_freq2 = 4235 pSwitchChnInd->chan_params.mhz_freq_seg1; 4236 4237 if (IS_WLAN_PHYMODE_HT(pSwitchChnInd->ch_phymode)) 4238 roam_info->mode = SIR_SME_PHY_MODE_HT; 4239 else if (IS_WLAN_PHYMODE_VHT(pSwitchChnInd->ch_phymode) || 4240 IS_WLAN_PHYMODE_HE(pSwitchChnInd->ch_phymode)) 4241 roam_info->mode = SIR_SME_PHY_MODE_VHT; 4242 #ifdef WLAN_FEATURE_11BE 4243 else if (IS_WLAN_PHYMODE_EHT(pSwitchChnInd->ch_phymode)) 4244 roam_info->mode = SIR_SME_PHY_MODE_VHT; 4245 #endif 4246 else 4247 roam_info->mode = SIR_SME_PHY_MODE_LEGACY; 4248 4249 status = csr_roam_call_callback(mac_ctx, sessionId, roam_info, 4250 eCSR_ROAM_STA_CHANNEL_SWITCH, 4251 eCSR_ROAM_RESULT_NONE); 4252 qdf_mem_free(roam_info); 4253 } 4254 4255 static void 4256 csr_roam_chk_lnk_deauth_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4257 { 4258 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4259 QDF_STATUS status; 4260 struct csr_roam_info *roam_info; 4261 struct deauth_rsp *pDeauthRsp = (struct deauth_rsp *) msg_ptr; 4262 enum QDF_OPMODE opmode; 4263 4264 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4265 if (!roam_info) 4266 return; 4267 sme_debug("eWNI_SME_DEAUTH_RSP from SME"); 4268 sessionId = pDeauthRsp->sessionId; 4269 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { 4270 qdf_mem_free(roam_info); 4271 return; 4272 } 4273 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId); 4274 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 4275 qdf_copy_macaddr(&roam_info->peerMac, 4276 &pDeauthRsp->peer_macaddr); 4277 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; 4278 roam_info->status_code = pDeauthRsp->status_code; 4279 status = csr_roam_call_callback(mac_ctx, sessionId, 4280 roam_info, eCSR_ROAM_LOSTLINK, 4281 eCSR_ROAM_RESULT_FORCED); 4282 } 4283 qdf_mem_free(roam_info); 4284 } 4285 4286 static void 4287 csr_roam_chk_lnk_disassoc_rsp(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4288 { 4289 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4290 QDF_STATUS status; 4291 struct csr_roam_info *roam_info; 4292 enum QDF_OPMODE opmode; 4293 /* 4294 * session id is invalid here so cant use it to access the array 4295 * curSubstate as index 4296 */ 4297 struct disassoc_rsp *pDisassocRsp = (struct disassoc_rsp *) msg_ptr; 4298 4299 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4300 if (!roam_info) 4301 return; 4302 sme_debug("eWNI_SME_DISASSOC_RSP from SME "); 4303 sessionId = pDisassocRsp->sessionId; 4304 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) { 4305 qdf_mem_free(roam_info); 4306 return; 4307 } 4308 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, sessionId); 4309 if (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) { 4310 qdf_copy_macaddr(&roam_info->peerMac, 4311 &pDisassocRsp->peer_macaddr); 4312 roam_info->reasonCode = eCSR_ROAM_RESULT_FORCED; 4313 roam_info->status_code = pDisassocRsp->status_code; 4314 status = csr_roam_call_callback(mac_ctx, sessionId, 4315 roam_info, 4316 eCSR_ROAM_LOSTLINK, 4317 eCSR_ROAM_RESULT_FORCED); 4318 } 4319 qdf_mem_free(roam_info); 4320 } 4321 4322 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR 4323 static void 4324 csr_roam_diag_mic_fail(struct mac_context *mac_ctx, uint32_t sessionId) 4325 { 4326 WLAN_HOST_DIAG_EVENT_DEF(secEvent, 4327 host_event_wlan_security_payload_type); 4328 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, sessionId); 4329 4330 if (!session) { 4331 sme_err("session %d not found", sessionId); 4332 return; 4333 } 4334 qdf_mem_zero(&secEvent, sizeof(host_event_wlan_security_payload_type)); 4335 secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR; 4336 cm_diag_get_auth_enc_type_vdev_id(mac_ctx->psoc, 4337 &secEvent.authMode, 4338 &secEvent.encryptionModeUnicast, 4339 &secEvent.encryptionModeMulticast, 4340 sessionId); 4341 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, sessionId, 4342 (struct qdf_mac_addr *)&secEvent.bssid); 4343 WLAN_HOST_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); 4344 } 4345 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ 4346 4347 static void 4348 csr_roam_chk_lnk_mic_fail_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4349 { 4350 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4351 QDF_STATUS status; 4352 struct csr_roam_info *roam_info; 4353 struct mic_failure_ind *mic_ind = (struct mic_failure_ind *)msg_ptr; 4354 eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; 4355 4356 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4357 if (!roam_info) 4358 return; 4359 status = csr_roam_get_session_id_from_bssid(mac_ctx, 4360 &mic_ind->bssId, &sessionId); 4361 if (QDF_IS_STATUS_SUCCESS(status)) { 4362 roam_info->u.pMICFailureInfo = &mic_ind->info; 4363 if (mic_ind->info.multicast) 4364 result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP; 4365 else 4366 result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; 4367 csr_roam_call_callback(mac_ctx, sessionId, roam_info, 4368 eCSR_ROAM_MIC_ERROR_IND, result); 4369 } 4370 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR 4371 csr_roam_diag_mic_fail(mac_ctx, sessionId); 4372 #endif /* FEATURE_WLAN_DIAG_SUPPORT_CSR */ 4373 qdf_mem_free(roam_info); 4374 } 4375 4376 static void 4377 csr_roam_chk_lnk_pbs_probe_req_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4378 { 4379 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4380 QDF_STATUS status; 4381 struct csr_roam_info *roam_info; 4382 tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd) msg_ptr; 4383 4384 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4385 if (!roam_info) 4386 return; 4387 sme_debug("WPS PBC Probe request Indication from SME"); 4388 4389 status = csr_roam_get_session_id_from_bssid(mac_ctx, 4390 &pProbeReqInd->bssid, &sessionId); 4391 if (QDF_IS_STATUS_SUCCESS(status)) { 4392 roam_info->u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq; 4393 csr_roam_call_callback(mac_ctx, sessionId, roam_info, 4394 eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, 4395 eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND); 4396 } 4397 qdf_mem_free(roam_info); 4398 } 4399 4400 static void 4401 csr_roam_chk_lnk_max_assoc_exceeded(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) 4402 { 4403 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 4404 tSmeMaxAssocInd *pSmeMaxAssocInd; 4405 struct csr_roam_info *roam_info; 4406 4407 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 4408 if (!roam_info) 4409 return; 4410 pSmeMaxAssocInd = (tSmeMaxAssocInd *) msg_ptr; 4411 sme_debug( 4412 "max assoc have been reached, new peer cannot be accepted"); 4413 sessionId = pSmeMaxAssocInd->sessionId; 4414 qdf_copy_macaddr(&roam_info->peerMac, &pSmeMaxAssocInd->peer_mac); 4415 csr_roam_call_callback(mac_ctx, sessionId, roam_info, 4416 eCSR_ROAM_INFRA_IND, 4417 eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED); 4418 qdf_mem_free(roam_info); 4419 } 4420 4421 void csr_roam_check_for_link_status_change(struct mac_context *mac, 4422 tSirSmeRsp *pSirMsg) 4423 { 4424 if (!pSirMsg) { 4425 sme_err("pSirMsg is NULL"); 4426 return; 4427 } 4428 switch (pSirMsg->messageType) { 4429 case eWNI_SME_ASSOC_IND: 4430 csr_roam_chk_lnk_assoc_ind(mac, pSirMsg); 4431 break; 4432 case eWNI_SME_ASSOC_IND_UPPER_LAYER: 4433 csr_roam_chk_lnk_assoc_ind_upper_layer(mac, pSirMsg); 4434 break; 4435 case eWNI_SME_DISASSOC_IND: 4436 csr_roam_chk_lnk_disassoc_ind(mac, pSirMsg); 4437 break; 4438 case eWNI_SME_DISCONNECT_DONE_IND: 4439 csr_roam_send_disconnect_done_indication(mac, pSirMsg); 4440 break; 4441 case eWNI_SME_DEAUTH_IND: 4442 csr_roam_chk_lnk_deauth_ind(mac, pSirMsg); 4443 break; 4444 case eWNI_SME_SWITCH_CHL_IND: 4445 csr_roam_chk_lnk_swt_ch_ind(mac, pSirMsg); 4446 break; 4447 case eWNI_SME_DEAUTH_RSP: 4448 csr_roam_chk_lnk_deauth_rsp(mac, pSirMsg); 4449 break; 4450 case eWNI_SME_DISASSOC_RSP: 4451 csr_roam_chk_lnk_disassoc_rsp(mac, pSirMsg); 4452 break; 4453 case eWNI_SME_MIC_FAILURE_IND: 4454 csr_roam_chk_lnk_mic_fail_ind(mac, pSirMsg); 4455 break; 4456 case eWNI_SME_WPS_PBC_PROBE_REQ_IND: 4457 csr_roam_chk_lnk_pbs_probe_req_ind(mac, pSirMsg); 4458 break; 4459 case eWNI_SME_SETCONTEXT_RSP: 4460 csr_roam_chk_lnk_set_ctx_rsp(mac, pSirMsg); 4461 break; 4462 #ifdef FEATURE_WLAN_ESE 4463 case eWNI_SME_GET_TSM_STATS_RSP: 4464 sme_debug("TSM Stats rsp from PE"); 4465 csr_tsm_stats_rsp_processor(mac, pSirMsg); 4466 break; 4467 #endif /* FEATURE_WLAN_ESE */ 4468 case eWNI_SME_GET_SNR_REQ: 4469 sme_debug("GetSnrReq from self"); 4470 csr_update_snr(mac, pSirMsg); 4471 break; 4472 case eWNI_SME_MAX_ASSOC_EXCEEDED: 4473 csr_roam_chk_lnk_max_assoc_exceeded(mac, pSirMsg); 4474 break; 4475 default: 4476 break; 4477 } /* end switch on message type */ 4478 } 4479 4480 void csr_roam_wm_status_change_complete(struct mac_context *mac, 4481 uint8_t session_id) 4482 { 4483 tListElem *pEntry; 4484 tSmeCmd *pCommand; 4485 4486 pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 4487 if (pEntry) { 4488 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); 4489 if (eSmeCommandWmStatusChange == pCommand->command) { 4490 /* Nothing to process in a Lost Link completion.... It just kicks off a */ 4491 /* roaming sequence. */ 4492 if (csr_nonscan_active_ll_remove_entry(mac, pEntry, 4493 LL_ACCESS_LOCK)) { 4494 csr_release_command(mac, pCommand); 4495 } else { 4496 sme_err("Failed to release command"); 4497 } 4498 } else { 4499 sme_warn("CSR: LOST LINK command is not ACTIVE ..."); 4500 } 4501 } else { 4502 sme_warn("CSR: NO commands are ACTIVE ..."); 4503 } 4504 } 4505 4506 void csr_roam_process_wm_status_change_command( 4507 struct mac_context *mac, tSmeCmd *pCommand) 4508 { 4509 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, 4510 pCommand->vdev_id); 4511 struct qdf_mac_addr peer_mac; 4512 4513 if (!pSession) { 4514 sme_err("session %d not found", pCommand->vdev_id); 4515 csr_roam_wm_status_change_complete(mac, pCommand->vdev_id); 4516 } 4517 sme_debug("session:%d, CmdType : %d", 4518 pCommand->vdev_id, pCommand->u.wmStatusChangeCmd.Type); 4519 4520 switch (pCommand->u.wmStatusChangeCmd.Type) { 4521 case eCsrDisassociated: 4522 qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd. 4523 u.DisassocIndMsg.peer_macaddr, 4524 QDF_MAC_ADDR_SIZE); 4525 /* 4526 * Get peer stats before peer gets deleted so that these stats 4527 * can be given to user space when big data stats are queried. 4528 * Once peer stats are retrieved disassoc sta will continue 4529 */ 4530 csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac); 4531 break; 4532 case eCsrDeauthenticated: 4533 qdf_mem_copy(&peer_mac, &pCommand->u.wmStatusChangeCmd. 4534 u.DeauthIndMsg.peer_macaddr, 4535 QDF_MAC_ADDR_SIZE); 4536 /* 4537 * Get peer stats before peer gets deleted so that these stats 4538 * can be given to user space when big data stats are queried. 4539 * Once peer stats are retrieved deauth sta will continue 4540 */ 4541 csr_get_peer_stats(mac, pCommand->vdev_id, peer_mac); 4542 break; 4543 default: 4544 sme_warn("gets an unknown command %d", 4545 pCommand->u.wmStatusChangeCmd.Type); 4546 csr_roam_wm_status_change_complete(mac, pCommand->vdev_id); 4547 break; 4548 } 4549 } 4550 4551 /** 4552 * csr_compute_mode_and_band() - computes dot11mode 4553 * @mac: mac global context 4554 * @dot11_mode: out param, do11 mode calculated 4555 * @band: out param, band caclculated 4556 * @opr_ch_freq: operating channel freq in MHz 4557 * 4558 * This function finds dot11 mode based on current mode, operating channel and 4559 * fw supported modes. 4560 * 4561 * Return: void 4562 */ 4563 static void 4564 csr_compute_mode_and_band(struct mac_context *mac_ctx, 4565 enum csr_cfgdot11mode *dot11_mode, 4566 enum reg_wifi_band *band, 4567 uint32_t opr_ch_freq) 4568 { 4569 bool vht_24_ghz = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band; 4570 4571 switch (mac_ctx->roam.configParam.uCfgDot11Mode) { 4572 case eCSR_CFG_DOT11_MODE_11A: 4573 *dot11_mode = eCSR_CFG_DOT11_MODE_11A; 4574 *band = REG_BAND_5G; 4575 break; 4576 case eCSR_CFG_DOT11_MODE_11B: 4577 *dot11_mode = eCSR_CFG_DOT11_MODE_11B; 4578 *band = REG_BAND_2G; 4579 break; 4580 case eCSR_CFG_DOT11_MODE_11G: 4581 *dot11_mode = eCSR_CFG_DOT11_MODE_11G; 4582 *band = REG_BAND_2G; 4583 break; 4584 case eCSR_CFG_DOT11_MODE_11N: 4585 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4586 *band = wlan_reg_freq_to_band(opr_ch_freq); 4587 break; 4588 case eCSR_CFG_DOT11_MODE_11AC: 4589 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 4590 /* 4591 * If the operating channel is in 2.4 GHz band, check 4592 * for INI item to disable VHT operation in 2.4 GHz band 4593 */ 4594 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && 4595 !vht_24_ghz) 4596 /* Disable 11AC operation */ 4597 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4598 else 4599 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC; 4600 } else { 4601 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4602 } 4603 *band = wlan_reg_freq_to_band(opr_ch_freq); 4604 break; 4605 case eCSR_CFG_DOT11_MODE_11AC_ONLY: 4606 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 4607 /* 4608 * If the operating channel is in 2.4 GHz band, check 4609 * for INI item to disable VHT operation in 2.4 GHz band 4610 */ 4611 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && 4612 !vht_24_ghz) 4613 /* Disable 11AC operation */ 4614 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4615 else 4616 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; 4617 } else { 4618 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4619 } 4620 *band = wlan_reg_freq_to_band(opr_ch_freq); 4621 break; 4622 case eCSR_CFG_DOT11_MODE_11AX: 4623 case eCSR_CFG_DOT11_MODE_11AX_ONLY: 4624 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) { 4625 *dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode; 4626 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 4627 /* 4628 * If the operating channel is in 2.4 GHz band, check 4629 * for INI item to disable VHT operation in 2.4 GHz band 4630 */ 4631 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && 4632 !vht_24_ghz) 4633 /* Disable 11AC operation */ 4634 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4635 else 4636 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC; 4637 } else { 4638 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4639 } 4640 *band = wlan_reg_freq_to_band(opr_ch_freq); 4641 break; 4642 #ifdef WLAN_FEATURE_11BE 4643 case eCSR_CFG_DOT11_MODE_11BE: 4644 case eCSR_CFG_DOT11_MODE_11BE_ONLY: 4645 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) { 4646 *dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode; 4647 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) { 4648 *dot11_mode = eCSR_CFG_DOT11_MODE_11AX; 4649 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 4650 /* 4651 * If the operating channel is in 2.4 GHz band, check 4652 * for INI item to disable VHT operation in 2.4 GHz band 4653 */ 4654 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && 4655 !vht_24_ghz) 4656 /* Disable 11AC operation */ 4657 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4658 else 4659 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC; 4660 } else { 4661 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4662 } 4663 *band = wlan_reg_freq_to_band(opr_ch_freq); 4664 break; 4665 #endif 4666 case eCSR_CFG_DOT11_MODE_AUTO: 4667 #ifdef WLAN_FEATURE_11BE 4668 if (IS_FEATURE_11BE_SUPPORTED_BY_FW) { 4669 *dot11_mode = eCSR_CFG_DOT11_MODE_11BE; 4670 } else 4671 #endif 4672 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) { 4673 *dot11_mode = eCSR_CFG_DOT11_MODE_11AX; 4674 } else if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 4675 /* 4676 * If the operating channel is in 2.4 GHz band, 4677 * check for INI item to disable VHT operation 4678 * in 2.4 GHz band 4679 */ 4680 if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq) && 4681 !vht_24_ghz) 4682 /* Disable 11AC operation */ 4683 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4684 else 4685 *dot11_mode = eCSR_CFG_DOT11_MODE_11AC; 4686 } else { 4687 *dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4688 } 4689 *band = wlan_reg_freq_to_band(opr_ch_freq); 4690 break; 4691 default: 4692 /* 4693 * Global dot11 Mode setting is 11a/b/g. use the channel number 4694 * to determine the Mode setting. 4695 */ 4696 if (eCSR_OPERATING_CHANNEL_AUTO == opr_ch_freq) { 4697 *band = (mac_ctx->mlme_cfg->gen.band == BAND_2G ? 4698 REG_BAND_2G : REG_BAND_5G); 4699 if (REG_BAND_2G == *band) { 4700 *dot11_mode = eCSR_CFG_DOT11_MODE_11B; 4701 } else { 4702 /* prefer 5GHz */ 4703 *band = REG_BAND_5G; 4704 *dot11_mode = eCSR_CFG_DOT11_MODE_11A; 4705 } 4706 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(opr_ch_freq)) { 4707 *dot11_mode = eCSR_CFG_DOT11_MODE_11B; 4708 *band = REG_BAND_2G; 4709 } else { 4710 /* else, it's a 5.0GHz channel. Set mode to 11a. */ 4711 *dot11_mode = eCSR_CFG_DOT11_MODE_11A; 4712 *band = REG_BAND_5G; 4713 } 4714 break; 4715 } /* switch */ 4716 } 4717 4718 /** 4719 * csr_roam_get_phy_mode_band_for_bss() - This function returns band and mode 4720 * information. 4721 * @mac_ctx: mac global context 4722 * dot11_cfg: pointer to dot11 config 4723 * 4724 * This function finds dot11 mode based on current mode, operating channel and 4725 * fw supported modes. The only tricky part is that if phyMode is set to 11abg, 4726 * this function may return eCSR_CFG_DOT11_MODE_11B instead of 4727 * eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick. 4728 * 4729 * Return: dot11mode 4730 */ 4731 enum csr_cfgdot11mode 4732 csr_roam_get_phy_mode_band_for_bss(struct mac_context *mac_ctx, 4733 struct bss_dot11_config *dot11_cfg) 4734 { 4735 enum reg_wifi_band band = REG_BAND_2G; 4736 qdf_freq_t opr_freq = 0; 4737 bool is_11n_allowed; 4738 enum csr_cfgdot11mode curr_mode = 4739 mac_ctx->roam.configParam.uCfgDot11Mode; 4740 enum csr_cfgdot11mode cfg_dot11_mode; 4741 enum QDF_OPMODE opmode; 4742 bool is_ap = false; 4743 uint8_t privacy; 4744 uint8_t vdev_id = dot11_cfg->vdev_id; 4745 4746 if (dot11_cfg->bss_op_ch_freq) 4747 opr_freq = dot11_cfg->bss_op_ch_freq; 4748 4749 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 4750 is_ap = (opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE); 4751 cfg_dot11_mode = 4752 csr_get_cfg_dot11_mode_from_csr_phy_mode(is_ap, 4753 dot11_cfg->phy_mode); 4754 privacy = dot11_cfg->privacy; 4755 4756 /* 4757 * If the global setting for dot11Mode is set to auto/abg, we overwrite 4758 * the setting in the profile. 4759 */ 4760 if ((!is_ap && ((eCSR_CFG_DOT11_MODE_AUTO == curr_mode) || 4761 (eCSR_CFG_DOT11_MODE_ABG == curr_mode))) || 4762 (eCSR_CFG_DOT11_MODE_AUTO == cfg_dot11_mode) || 4763 (eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode)) { 4764 csr_compute_mode_and_band(mac_ctx, &cfg_dot11_mode, 4765 &band, opr_freq); 4766 } /* if( eCSR_CFG_DOT11_MODE_ABG == cfg_dot11_mode ) */ 4767 else { 4768 /* dot11 mode is set, lets pick the band */ 4769 if (0 == opr_freq) { 4770 /* channel is Auto also. */ 4771 if (mac_ctx->mlme_cfg->gen.band == BAND_ALL) { 4772 /* prefer 5GHz */ 4773 band = REG_BAND_5G; 4774 } 4775 } else{ 4776 band = wlan_reg_freq_to_band(opr_freq); 4777 } 4778 } 4779 4780 dot11_cfg->p_band = band; 4781 if (opr_freq == 2484 && wlan_reg_is_24ghz_ch_freq(opr_freq)) { 4782 sme_err("Switching to Dot11B mode"); 4783 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11B; 4784 } 4785 4786 if (wlan_reg_is_24ghz_ch_freq(opr_freq) && 4787 !mac_ctx->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && 4788 (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode || 4789 eCSR_CFG_DOT11_MODE_11AC_ONLY == cfg_dot11_mode)) 4790 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11N; 4791 /* 4792 * Incase of WEP Security encryption type is coming as part of add key. 4793 * So while STart BSS dont have information 4794 */ 4795 is_11n_allowed = wlan_vdev_id_is_11n_allowed(mac_ctx->pdev, vdev_id); 4796 if ((!is_11n_allowed || (privacy && 4797 wlan_vdev_id_is_open_cipher(mac_ctx->pdev, vdev_id))) && 4798 ((eCSR_CFG_DOT11_MODE_11N == cfg_dot11_mode) || 4799 (eCSR_CFG_DOT11_MODE_11AC == cfg_dot11_mode) || 4800 (eCSR_CFG_DOT11_MODE_11AX == cfg_dot11_mode) || 4801 CSR_IS_CFG_DOT11_PHY_MODE_11BE(cfg_dot11_mode))) { 4802 /* We cannot do 11n here */ 4803 if (wlan_reg_is_24ghz_ch_freq(opr_freq)) 4804 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11G; 4805 else 4806 cfg_dot11_mode = eCSR_CFG_DOT11_MODE_11A; 4807 } 4808 sme_debug("dot11mode: %d phyMode %d is_11n_allowed %d privacy %d chan freq %d fw sup AX %d", 4809 cfg_dot11_mode, dot11_cfg->phy_mode, is_11n_allowed, 4810 privacy, opr_freq, 4811 IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)); 4812 4813 #ifdef WLAN_FEATURE_11BE 4814 sme_debug("BE :%d", IS_FEATURE_SUPPORTED_BY_FW(DOT11BE)); 4815 #endif 4816 return cfg_dot11_mode; 4817 } 4818 4819 QDF_STATUS csr_get_cfg_valid_channels(struct mac_context *mac, 4820 qdf_freq_t *ch_freq_list, 4821 uint32_t *num_ch_freq) 4822 { 4823 uint8_t num_chan_temp = 0; 4824 int i; 4825 uint32_t *valid_ch_freq_list = 4826 mac->mlme_cfg->reg.valid_channel_freq_list; 4827 4828 *num_ch_freq = mac->mlme_cfg->reg.valid_channel_list_num; 4829 4830 for (i = 0; i < *num_ch_freq; i++) { 4831 if (!wlan_reg_is_dsrc_freq(valid_ch_freq_list[i])) { 4832 ch_freq_list[num_chan_temp] = valid_ch_freq_list[i]; 4833 num_chan_temp++; 4834 } 4835 } 4836 4837 *num_ch_freq = num_chan_temp; 4838 return QDF_STATUS_SUCCESS; 4839 } 4840 4841 /** 4842 * csr_convert_mode_to_nw_type() - convert mode into network type 4843 * @dot11_mode: dot11_mode 4844 * @band: 2.4 or 5 GHz 4845 * 4846 * Return: tSirNwType 4847 */ 4848 tSirNwType 4849 csr_convert_mode_to_nw_type(enum csr_cfgdot11mode dot11_mode, 4850 enum reg_wifi_band band) 4851 { 4852 switch (dot11_mode) { 4853 case eCSR_CFG_DOT11_MODE_11G: 4854 return eSIR_11G_NW_TYPE; 4855 case eCSR_CFG_DOT11_MODE_11B: 4856 return eSIR_11B_NW_TYPE; 4857 case eCSR_CFG_DOT11_MODE_11A: 4858 return eSIR_11A_NW_TYPE; 4859 case eCSR_CFG_DOT11_MODE_11N: 4860 default: 4861 /* 4862 * Because LIM only verifies it against 11a, 11b or 11g, set 4863 * only 11g or 11a here 4864 */ 4865 if (REG_BAND_2G == band) 4866 return eSIR_11G_NW_TYPE; 4867 else 4868 return eSIR_11A_NW_TYPE; 4869 } 4870 return eSIR_DONOT_USE_NW_TYPE; 4871 } 4872 4873 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 4874 #ifdef WLAN_FEATURE_11BE_MLO 4875 static bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev, 4876 struct wlan_crypto_pmksa *pmksa) 4877 { 4878 struct qdf_mac_addr bss_peer_mld_mac = {0}; 4879 4880 wlan_vdev_get_bss_peer_mld_mac(vdev, &bss_peer_mld_mac); 4881 4882 return qdf_is_macaddr_equal(&bss_peer_mld_mac, &pmksa->bssid); 4883 } 4884 #else 4885 static inline bool csr_pmk_match_mlo_address(struct wlan_objmgr_vdev *vdev, 4886 struct wlan_crypto_pmksa *pmksa) 4887 { 4888 return false; 4889 } 4890 #endif 4891 4892 void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id, 4893 struct wlan_crypto_pmksa *pmk_cache) 4894 { 4895 if (!mac_ctx) { 4896 sme_err("Mac_ctx is NULL"); 4897 return; 4898 } 4899 wlan_cm_get_psk_pmk(mac_ctx->pdev, session_id, pmk_cache->pmk, 4900 &pmk_cache->pmk_len); 4901 } 4902 4903 QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, 4904 struct wlan_crypto_pmksa *pmksa, 4905 uint8_t vdev_id, bool update_to_fw) 4906 { 4907 struct wlan_objmgr_vdev *vdev; 4908 struct qdf_mac_addr connected_bssid = {0}; 4909 QDF_STATUS status; 4910 4911 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 4912 WLAN_LEGACY_SME_ID); 4913 if (!vdev) { 4914 sme_err("vdev is NULL"); 4915 return QDF_STATUS_E_FAILURE; 4916 } 4917 4918 wlan_mlme_get_bssid_vdev_id(mac->pdev, vdev_id, &connected_bssid); 4919 4920 /* 4921 * If the set_pmksa is received from the userspace in 4922 * connected state and if the connected BSSID is not 4923 * same as the PMKSA entry bssid, then reject this 4924 * global cache updation. 4925 * 4926 * Also for FILS connection, the set_pmksa will not have 4927 * the BSSID. So avoid this check for FILS connection. 4928 */ 4929 if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP && 4930 !pmksa->ssid_len && 4931 !qdf_is_macaddr_equal(&connected_bssid, &pmksa->bssid) && 4932 !csr_pmk_match_mlo_address(vdev, pmksa)) { 4933 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 4934 sme_debug("Set pmksa received for non-connected bss"); 4935 return QDF_STATUS_E_INVAL; 4936 } 4937 4938 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 4939 4940 wlan_cm_set_psk_pmk(mac->pdev, vdev_id, pmksa->pmk, pmksa->pmk_len); 4941 if (update_to_fw) { 4942 status = wlan_roam_update_cfg(mac->psoc, vdev_id, 4943 REASON_ROAM_PSK_PMK_CHANGED); 4944 if (status == QDF_STATUS_E_INVAL) 4945 wlan_mlme_defer_pmk_set_in_roaming(mac->psoc, vdev_id, 4946 true); 4947 } 4948 4949 return QDF_STATUS_SUCCESS; 4950 } 4951 4952 QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint8_t vdev_id, 4953 struct wlan_crypto_pmksa *pmk_cache) 4954 { 4955 struct wlan_objmgr_vdev *vdev; 4956 int32_t akm; 4957 4958 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) { 4959 sme_err("session %d not found", vdev_id); 4960 return QDF_STATUS_E_INVAL; 4961 } 4962 4963 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 4964 WLAN_LEGACY_SME_ID); 4965 if (!vdev) { 4966 sme_err("vdev is NULL"); 4967 return QDF_STATUS_E_FAILURE; 4968 } 4969 4970 akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 4971 4972 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 4973 4974 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) { 4975 sme_debug("PMK update is not required for ESE"); 4976 return QDF_STATUS_SUCCESS; 4977 } 4978 4979 if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) || 4980 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) || 4981 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) || 4982 QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) { 4983 sme_debug("Auth type: %x update the MDID in cache", akm); 4984 cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache); 4985 } else { 4986 struct cm_roam_values_copy src_cfg = {}; 4987 struct scan_filter *scan_filter; 4988 qdf_list_t *list = NULL; 4989 struct scan_cache_node *first_node = NULL; 4990 struct rsn_mdie *mdie = NULL; 4991 qdf_list_node_t *cur_node = NULL; 4992 4993 scan_filter = qdf_mem_malloc(sizeof(*scan_filter)); 4994 if (!scan_filter) 4995 return QDF_STATUS_E_NOMEM; 4996 scan_filter->num_of_bssid = 1; 4997 qdf_mem_copy(scan_filter->bssid_list[0].bytes, 4998 &pmk_cache->bssid, sizeof(struct qdf_mac_addr)); 4999 list = wlan_scan_get_result(mac->pdev, scan_filter); 5000 qdf_mem_free(scan_filter); 5001 if (!list || (list && !qdf_list_size(list))) { 5002 sme_debug("Scan list is empty"); 5003 goto err; 5004 } 5005 qdf_list_peek_front(list, &cur_node); 5006 first_node = qdf_container_of(cur_node, 5007 struct scan_cache_node, 5008 node); 5009 if (first_node && first_node->entry) 5010 mdie = (struct rsn_mdie *) 5011 util_scan_entry_mdie(first_node->entry); 5012 if (mdie) { 5013 sme_debug("Update MDID in cache from scan_res"); 5014 src_cfg.bool_value = true; 5015 src_cfg.uint_value = 5016 (mdie->mobility_domain[0] | 5017 (mdie->mobility_domain[1] << 8)); 5018 wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 5019 MOBILITY_DOMAIN, &src_cfg); 5020 cm_update_pmk_cache_ft(mac->psoc, vdev_id, pmk_cache); 5021 } 5022 err: 5023 if (list) 5024 wlan_scan_purge_results(list); 5025 } 5026 return QDF_STATUS_SUCCESS; 5027 } 5028 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ 5029 5030 #if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) 5031 void csr_clear_sae_single_pmk(struct wlan_objmgr_psoc *psoc, 5032 uint8_t vdev_id, 5033 struct wlan_crypto_pmksa *pmk_cache) 5034 { 5035 struct wlan_objmgr_vdev *vdev; 5036 int32_t keymgmt; 5037 struct mlme_pmk_info pmk_info; 5038 5039 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 5040 WLAN_LEGACY_SME_ID); 5041 if (!vdev) { 5042 sme_err("vdev is NULL"); 5043 return; 5044 } 5045 5046 keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); 5047 if (keymgmt < 0) { 5048 sme_err("Invalid mgmt cipher"); 5049 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5050 return; 5051 } 5052 5053 if (!(keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE))) { 5054 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5055 return; 5056 } 5057 if (pmk_cache) { 5058 qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len); 5059 pmk_info.pmk_len = pmk_cache->pmk_len; 5060 wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info); 5061 } else { 5062 wlan_mlme_clear_sae_single_pmk_info(vdev, NULL); 5063 } 5064 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5065 } 5066 #endif 5067 5068 #ifdef FEATURE_WLAN_ESE 5069 void csr_update_prev_ap_info(struct csr_roam_session *session, 5070 struct wlan_objmgr_vdev *vdev) 5071 { 5072 struct wlan_ssid ssid; 5073 QDF_STATUS status; 5074 enum QDF_OPMODE opmode; 5075 struct rso_config *rso_cfg; 5076 5077 opmode = wlan_vdev_mlme_get_opmode(vdev); 5078 rso_cfg = wlan_cm_get_rso_config(vdev); 5079 if (!rso_cfg) 5080 return; 5081 5082 if (!rso_cfg->is_ese_assoc || opmode != QDF_STA_MODE) 5083 return; 5084 status = wlan_vdev_mlme_get_ssid(vdev, ssid.ssid, &ssid.length); 5085 if (QDF_IS_STATUS_ERROR(status)) { 5086 sme_err(" failed to find SSID for vdev %d", session->vdev_id); 5087 return; 5088 } 5089 session->isPrevApInfoValid = true; 5090 session->roamTS1 = qdf_mc_timer_get_system_time(); 5091 } 5092 #endif 5093 5094 #ifdef WLAN_FEATURE_FILS_SK 5095 static QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev, 5096 struct bss_description *bss_desc, 5097 struct wlan_cm_vdev_connect_req *req) 5098 { 5099 uint8_t cache_id[CACHE_ID_LEN] = {0}; 5100 struct scan_cache_entry *entry; 5101 struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa; 5102 5103 if (!req->fils_info || !req->fils_info->is_fils_connection) { 5104 wlan_cm_update_mlme_fils_info(vdev, NULL); 5105 return QDF_STATUS_SUCCESS; 5106 } 5107 5108 if (bss_desc->fils_info_element.is_cache_id_present) { 5109 qdf_mem_copy(cache_id, bss_desc->fils_info_element.cache_id, 5110 CACHE_ID_LEN); 5111 sme_debug("FILS_PMKSA: cache_id[0]:%d, cache_id[1]:%d", 5112 cache_id[0], cache_id[1]); 5113 } 5114 entry = req->bss->entry; 5115 bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, &entry->bssid); 5116 fils_ssid_pmksa = 5117 wlan_crypto_get_fils_pmksa(vdev, cache_id, 5118 entry->ssid.ssid, 5119 entry->ssid.length); 5120 5121 if ((!req->fils_info->rrk_len || 5122 !req->fils_info->username_len) && 5123 !bss_desc->fils_info_element.is_cache_id_present && 5124 !bssid_lookup_pmksa && !fils_ssid_pmksa) 5125 return QDF_STATUS_E_FAILURE; 5126 5127 return wlan_cm_update_mlme_fils_info(vdev, req->fils_info); 5128 } 5129 #else 5130 static inline 5131 QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev, 5132 struct bss_description *bss_desc, 5133 struct wlan_cm_vdev_connect_req *req) 5134 { 5135 } 5136 #endif 5137 5138 #if defined(WLAN_FEATURE_HOST_ROAM) && defined(FEATURE_WLAN_ESE) 5139 static void csr_update_tspec_info(struct mac_context *mac_ctx, 5140 struct wlan_objmgr_vdev *vdev, 5141 tDot11fBeaconIEs *ie_struct) 5142 { 5143 struct mlme_legacy_priv *mlme_priv; 5144 tESETspecInfo *ese_tspec; 5145 5146 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 5147 if (!mlme_priv) 5148 return; 5149 if (!cm_is_ese_connection(vdev, ie_struct->ESEVersion.present)) 5150 return; 5151 5152 ese_tspec = &mlme_priv->connect_info.ese_tspec_info; 5153 qdf_mem_zero(ese_tspec, sizeof(tESETspecInfo)); 5154 ese_tspec->numTspecs = sme_qos_ese_retrieve_tspec_info(mac_ctx, 5155 wlan_vdev_get_id(vdev), 5156 ese_tspec->tspec); 5157 } 5158 #else 5159 static inline void csr_update_tspec_info(struct mac_context *mac_ctx, 5160 struct wlan_objmgr_vdev *vdev, 5161 tDot11fBeaconIEs *ie_struct) {} 5162 #endif 5163 5164 void cm_csr_send_set_ie(struct wlan_objmgr_vdev *vdev) 5165 { 5166 struct vdev_mlme_obj *vdev_mlme; 5167 5168 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 5169 if (!vdev_mlme) { 5170 sme_err("Failed to get vdev mlme obj!"); 5171 QDF_BUG(0); 5172 return; 5173 } 5174 5175 csr_send_set_ie(vdev_mlme->mgmt.generic.type, 5176 vdev_mlme->mgmt.generic.subtype, 5177 wlan_vdev_get_id(vdev)); 5178 } 5179 5180 QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev, 5181 struct wlan_cm_vdev_connect_req *req, 5182 struct cm_vdev_join_req *join_req, 5183 bool reassoc) 5184 { 5185 struct mac_context *mac_ctx; 5186 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5187 QDF_STATUS status; 5188 tDot11fBeaconIEs *ie_struct; 5189 struct bss_description *bss_desc; 5190 uint32_t ie_len, bss_len; 5191 5192 /* 5193 * This API is to update legacy struct and should be removed once 5194 * CSR is cleaned up fully. No new params should be added to CSR, use 5195 * vdev/pdev/psoc instead 5196 */ 5197 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5198 if (!mac_ctx) 5199 return QDF_STATUS_E_INVAL; 5200 5201 ie_len = util_scan_entry_ie_len(join_req->entry); 5202 bss_len = (uint16_t)(offsetof(struct bss_description, 5203 ieFields[0]) + ie_len); 5204 5205 bss_desc = qdf_mem_malloc(sizeof(*bss_desc) + bss_len); 5206 if (!bss_desc) 5207 return QDF_STATUS_E_NOMEM; 5208 5209 status = wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, 5210 join_req->entry); 5211 if (QDF_IS_STATUS_ERROR(status)) { 5212 qdf_mem_free(bss_desc); 5213 return QDF_STATUS_E_FAILURE; 5214 } 5215 5216 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc, 5217 &ie_struct); 5218 if (QDF_IS_STATUS_ERROR(status)) { 5219 sme_err("IE parsing failed vdev id %d", vdev_id); 5220 qdf_mem_free(bss_desc); 5221 return QDF_STATUS_E_FAILURE; 5222 } 5223 5224 if (reassoc) { 5225 csr_update_tspec_info(mac_ctx, vdev, ie_struct); 5226 } else { 5227 status = csr_cm_update_fils_info(vdev, bss_desc, req); 5228 if (QDF_IS_STATUS_ERROR(status)) { 5229 sme_err("failed to update fils info vdev id %d", 5230 vdev_id); 5231 qdf_mem_free(ie_struct); 5232 qdf_mem_free(bss_desc); 5233 return QDF_STATUS_E_FAILURE; 5234 } 5235 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5236 SME_QOS_CSR_JOIN_REQ, NULL); 5237 } 5238 5239 if ((wlan_reg_11d_enabled_on_host(mac_ctx->psoc)) && 5240 !ie_struct->Country.present) 5241 csr_apply_channel_power_info_wrapper(mac_ctx); 5242 5243 qdf_mem_free(ie_struct); 5244 qdf_mem_free(bss_desc); 5245 5246 cm_csr_set_joining(vdev_id); 5247 5248 return QDF_STATUS_SUCCESS; 5249 } 5250 5251 #ifdef FEATURE_WLAN_ESE 5252 static uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp) 5253 { 5254 return rsp->tspec_ie.len; 5255 } 5256 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session, 5257 uint8_t *frame_ptr, 5258 struct cm_vdev_join_rsp *rsp) 5259 { 5260 session->connectedInfo.nTspecIeLength = rsp->tspec_ie.len; 5261 if (rsp->tspec_ie.len) 5262 qdf_mem_copy(frame_ptr, rsp->tspec_ie.ptr, 5263 rsp->tspec_ie.len); 5264 } 5265 5266 #else 5267 static inline uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp) 5268 { 5269 return 0; 5270 } 5271 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session, 5272 uint8_t *frame_ptr, 5273 struct cm_vdev_join_rsp *rsp) 5274 {} 5275 #endif 5276 5277 static void csr_fill_connected_info(struct mac_context *mac_ctx, 5278 struct csr_roam_session *session, 5279 struct cm_vdev_join_rsp *rsp) 5280 { 5281 uint32_t len; 5282 struct wlan_connect_rsp_ies *connect_ies; 5283 uint8_t *frame_ptr; 5284 uint32_t beacon_data_len = 0; 5285 5286 connect_ies = &rsp->connect_rsp.connect_ies; 5287 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 5288 if (connect_ies->bcn_probe_rsp.len > sizeof(struct wlan_frame_hdr)) 5289 beacon_data_len = connect_ies->bcn_probe_rsp.len - 5290 sizeof(struct wlan_frame_hdr); 5291 len = beacon_data_len + connect_ies->assoc_req.len + 5292 connect_ies->assoc_rsp.len + rsp->ric_resp_ie.len + 5293 csr_get_tspec_ie_len(rsp); 5294 if (!len) 5295 return; 5296 5297 session->connectedInfo.pbFrames = qdf_mem_malloc(len); 5298 if (!session->connectedInfo.pbFrames) 5299 return; 5300 5301 frame_ptr = session->connectedInfo.pbFrames; 5302 session->connectedInfo.nBeaconLength = beacon_data_len; 5303 if (beacon_data_len) 5304 qdf_mem_copy(frame_ptr, 5305 connect_ies->bcn_probe_rsp.ptr + 5306 sizeof(struct wlan_frame_hdr), 5307 beacon_data_len); 5308 frame_ptr += beacon_data_len; 5309 5310 session->connectedInfo.nAssocReqLength = connect_ies->assoc_req.len; 5311 if (connect_ies->assoc_req.len) 5312 qdf_mem_copy(frame_ptr, 5313 connect_ies->assoc_req.ptr, 5314 connect_ies->assoc_req.len); 5315 frame_ptr += connect_ies->assoc_req.len; 5316 5317 session->connectedInfo.nAssocRspLength = connect_ies->assoc_rsp.len; 5318 if (connect_ies->assoc_rsp.len) 5319 qdf_mem_copy(frame_ptr, 5320 connect_ies->assoc_rsp.ptr, 5321 connect_ies->assoc_rsp.len); 5322 frame_ptr += connect_ies->assoc_rsp.len; 5323 5324 session->connectedInfo.nRICRspLength = rsp->ric_resp_ie.len; 5325 if (rsp->ric_resp_ie.len) 5326 qdf_mem_copy(frame_ptr, rsp->ric_resp_ie.ptr, 5327 rsp->ric_resp_ie.len); 5328 frame_ptr += rsp->ric_resp_ie.len; 5329 5330 csr_copy_tspec_ie_len(session, frame_ptr, rsp); 5331 } 5332 5333 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 5334 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx, 5335 uint8_t vdev_id) 5336 { 5337 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_DISCONNECT_IND, 5338 NULL); 5339 } 5340 5341 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx, 5342 uint8_t vdev_id, 5343 sme_QosAssocInfo *assoc_info) 5344 { 5345 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_ASSOC_COMPLETE, 5346 assoc_info); 5347 } 5348 5349 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 5350 static void 5351 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx, 5352 struct wlan_cm_connect_resp *connect_rsp) 5353 { 5354 if (IS_ROAM_REASON_DISCONNECTION( 5355 connect_rsp->roaming_info->roam_reason)) 5356 sme_qos_csr_event_ind(mac_ctx, connect_rsp->vdev_id, 5357 SME_QOS_CSR_DISCONNECT_ROAM_COMPLETE, 5358 NULL); 5359 } 5360 #else 5361 static inline void 5362 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx, 5363 struct wlan_cm_connect_resp *connect_rsp) {} 5364 #endif 5365 5366 static void 5367 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx, 5368 uint8_t vdev_id, 5369 sme_QosAssocInfo *assoc_info, 5370 struct wlan_cm_connect_resp *connect_rsp) 5371 { 5372 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_ASSOC_REQ, 5373 NULL); 5374 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_REQ, 5375 NULL); 5376 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE, 5377 NULL); 5378 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_COMPLETE, 5379 assoc_info); 5380 5381 csr_qso_disconnect_complete_ind(mac_ctx, connect_rsp); 5382 } 5383 #else 5384 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx, 5385 uint8_t vdev_id) 5386 {} 5387 5388 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx, 5389 uint8_t vdev_id, 5390 sme_QosAssocInfo *assoc_info) 5391 {} 5392 static inline void 5393 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx, 5394 uint8_t vdev_id, 5395 sme_QosAssocInfo *assoc_info, 5396 struct wlan_cm_connect_resp *connect_rsp) 5397 {} 5398 #endif 5399 5400 static void 5401 csr_update_beacon_in_connect_rsp(struct scan_cache_entry *entry, 5402 struct wlan_connect_rsp_ies *connect_ies) 5403 { 5404 if (!entry) 5405 return; 5406 5407 /* no need to update if already present */ 5408 if (connect_ies->bcn_probe_rsp.ptr) 5409 return; 5410 5411 /* 5412 * In case connection to MBSSID: Non Tx BSS OR host reassoc, 5413 * vdev/peer manager doesn't send unicast probe req so fill the 5414 * beacon in connect resp IEs here. 5415 */ 5416 connect_ies->bcn_probe_rsp.len = 5417 util_scan_entry_frame_len(entry); 5418 connect_ies->bcn_probe_rsp.ptr = 5419 qdf_mem_malloc(connect_ies->bcn_probe_rsp.len); 5420 if (!connect_ies->bcn_probe_rsp.ptr) 5421 return; 5422 5423 qdf_mem_copy(connect_ies->bcn_probe_rsp.ptr, 5424 util_scan_entry_frame_ptr(entry), 5425 connect_ies->bcn_probe_rsp.len); 5426 } 5427 5428 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 5429 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev) 5430 { 5431 return mlo_mgr_is_link_switch_in_progress(vdev); 5432 } 5433 #else 5434 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev) 5435 { 5436 return false; 5437 } 5438 #endif 5439 5440 static void csr_fill_connected_profile(struct mac_context *mac_ctx, 5441 struct csr_roam_session *session, 5442 struct wlan_objmgr_vdev *vdev, 5443 struct cm_vdev_join_rsp *rsp) 5444 { 5445 struct scan_filter *filter; 5446 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5447 QDF_STATUS status; 5448 qdf_list_t *list = NULL; 5449 qdf_list_node_t *cur_lst = NULL; 5450 struct scan_cache_node *cur_node = NULL; 5451 uint32_t bss_len, ie_len; 5452 struct bss_description *bss_desc = NULL; 5453 tDot11fBeaconIEs *bcn_ies; 5454 sme_QosAssocInfo assoc_info; 5455 struct cm_roam_values_copy src_cfg = {}; 5456 bool is_ese = false; 5457 uint8_t country_code[REG_ALPHA2_LEN + 1]; 5458 5459 session->modifyProfileFields.uapsd_mask = rsp->uapsd_mask; 5460 filter = qdf_mem_malloc(sizeof(*filter)); 5461 if (!filter) 5462 return; 5463 5464 filter->num_of_bssid = 1; 5465 qdf_copy_macaddr(&filter->bssid_list[0], &rsp->connect_rsp.bssid); 5466 filter->ignore_auth_enc_type = true; 5467 5468 status = wlan_vdev_mlme_get_ssid(vdev, filter->ssid_list[0].ssid, 5469 &filter->ssid_list[0].length); 5470 if (QDF_IS_STATUS_SUCCESS(status)) 5471 filter->num_of_ssid = 1; 5472 5473 list = wlan_scan_get_result(mac_ctx->pdev, filter); 5474 qdf_mem_free(filter); 5475 if (!list || (list && !qdf_list_size(list))) 5476 goto purge_list; 5477 5478 5479 qdf_list_peek_front(list, &cur_lst); 5480 if (!cur_lst) 5481 goto purge_list; 5482 5483 cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); 5484 ie_len = util_scan_entry_ie_len(cur_node->entry); 5485 bss_len = (uint16_t)(offsetof(struct bss_description, 5486 ieFields[0]) + ie_len); 5487 bss_desc = qdf_mem_malloc(bss_len); 5488 if (!bss_desc) 5489 goto purge_list; 5490 5491 wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, cur_node->entry); 5492 pe_debug("Dump scan entry frm:"); 5493 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, 5494 cur_node->entry->raw_frame.ptr, 5495 cur_node->entry->raw_frame.len); 5496 5497 src_cfg.uint_value = bss_desc->mbo_oce_enabled_ap; 5498 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, MBO_OCE_ENABLED_AP, 5499 &src_cfg); 5500 csr_fill_single_pmk(mac_ctx->psoc, vdev_id, bss_desc); 5501 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc, 5502 &bcn_ies); 5503 if (QDF_IS_STATUS_ERROR(status)) 5504 goto purge_list; 5505 5506 if (!bss_desc->beaconInterval) 5507 sme_err("ERROR: Beacon interval is ZERO"); 5508 5509 csr_update_beacon_in_connect_rsp(cur_node->entry, 5510 &rsp->connect_rsp.connect_ies); 5511 5512 assoc_info.bss_desc = bss_desc; 5513 if (rsp->connect_rsp.is_reassoc) { 5514 if (cm_is_ese_connection(vdev, bcn_ies->ESEVersion.present)) 5515 is_ese = true; 5516 wlan_cm_set_ese_assoc(mac_ctx->pdev, vdev_id, is_ese); 5517 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, UAPSD_MASK, 5518 &src_cfg); 5519 assoc_info.uapsd_mask = src_cfg.uint_value; 5520 csr_qos_send_reassoc_ind(mac_ctx, vdev_id, &assoc_info, 5521 &rsp->connect_rsp); 5522 if (src_cfg.uint_value) 5523 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id); 5524 } else { 5525 assoc_info.uapsd_mask = rsp->uapsd_mask; 5526 csr_qos_send_assoc_ind(mac_ctx, vdev_id, &assoc_info); 5527 } 5528 5529 if (rsp->connect_rsp.is_reassoc || 5530 csr_is_link_switch_in_progress(vdev)) 5531 mlme_set_mbssid_info(vdev, &cur_node->entry->mbssid_info); 5532 5533 if (bcn_ies->Country.present) 5534 qdf_mem_copy(country_code, bcn_ies->Country.country, 5535 REG_ALPHA2_LEN + 1); 5536 else 5537 qdf_mem_zero(country_code, REG_ALPHA2_LEN + 1); 5538 wlan_cm_set_country_code(mac_ctx->pdev, vdev_id, country_code); 5539 5540 qdf_mem_free(bcn_ies); 5541 5542 purge_list: 5543 if (bss_desc) 5544 qdf_mem_free(bss_desc); 5545 if (list) 5546 wlan_scan_purge_results(list); 5547 5548 } 5549 5550 QDF_STATUS cm_csr_connect_rsp(struct wlan_objmgr_vdev *vdev, 5551 struct cm_vdev_join_rsp *rsp) 5552 { 5553 struct mac_context *mac_ctx; 5554 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5555 struct csr_roam_session *session; 5556 struct cm_roam_values_copy src_config = {}; 5557 5558 /* 5559 * This API is to update legacy struct and should be removed once 5560 * CSR is cleaned up fully. No new params should be added to CSR, use 5561 * vdev/pdev/psoc instead 5562 */ 5563 if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status)) 5564 return QDF_STATUS_SUCCESS; 5565 5566 /* handle below only in case of success */ 5567 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5568 if (!mac_ctx) 5569 return QDF_STATUS_E_INVAL; 5570 5571 session = CSR_GET_SESSION(mac_ctx, vdev_id); 5572 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 5573 sme_err("session not found for vdev_id %d", vdev_id); 5574 return QDF_STATUS_E_INVAL; 5575 } 5576 5577 if (!rsp->connect_rsp.is_reassoc) { 5578 if (rsp->uapsd_mask) 5579 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id); 5580 src_config.uint_value = rsp->uapsd_mask; 5581 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, UAPSD_MASK, 5582 &src_config); 5583 } 5584 session->nss = rsp->nss; 5585 csr_fill_connected_info(mac_ctx, session, rsp); 5586 csr_fill_connected_profile(mac_ctx, session, vdev, rsp); 5587 5588 return QDF_STATUS_SUCCESS; 5589 } 5590 5591 static void 5592 cm_update_rsn_ocv_cap(int32_t *rsn_cap, 5593 struct wlan_cm_connect_resp *rsp) 5594 { 5595 struct wlan_crypto_params crypto_params; 5596 uint8_t *ie_ptr; 5597 uint32_t ie_len; 5598 QDF_STATUS status; 5599 5600 /* no need to do anything if OCV is not set */ 5601 if (!(*rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) 5602 return; 5603 5604 if (!rsp->connect_ies.bcn_probe_rsp.ptr || 5605 !rsp->connect_ies.bcn_probe_rsp.len || 5606 (rsp->connect_ies.bcn_probe_rsp.len < 5607 (sizeof(struct wlan_frame_hdr) + 5608 offsetof(struct wlan_bcn_frame, ie)))) { 5609 sme_err("invalid beacon probe rsp len %d", 5610 rsp->connect_ies.bcn_probe_rsp.len); 5611 return; 5612 } 5613 5614 ie_len = (rsp->connect_ies.bcn_probe_rsp.len - 5615 sizeof(struct wlan_frame_hdr) - 5616 offsetof(struct wlan_bcn_frame, ie)); 5617 ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr + 5618 sizeof(struct wlan_frame_hdr) + 5619 offsetof(struct wlan_bcn_frame, ie)); 5620 5621 status = wlan_get_crypto_params_from_rsn_ie(&crypto_params, ie_ptr, 5622 ie_len); 5623 if (QDF_IS_STATUS_ERROR(status)) 5624 return; 5625 5626 if (!(crypto_params.rsn_caps & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) 5627 *rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED; 5628 } 5629 5630 QDF_STATUS 5631 cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev, 5632 struct wlan_cm_connect_resp *rsp) 5633 { 5634 mac_handle_t mac_handle; 5635 struct mac_context *mac_ctx; 5636 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5637 int32_t count; 5638 struct set_context_rsp install_key_rsp; 5639 int32_t rsn_cap, set_value; 5640 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5641 struct dual_sta_policy *dual_sta_policy; 5642 bool enable_mcc_adaptive_sch = false; 5643 struct qdf_mac_addr bc_mac = QDF_MAC_ADDR_BCAST_INIT; 5644 5645 /* 5646 * This API is to update legacy struct and should be removed once 5647 * CSR is cleaned up fully. No new params should be added to CSR, use 5648 * vdev/pdev/psoc instead 5649 */ 5650 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5651 5652 mac_ctx = MAC_CONTEXT(mac_handle); 5653 if (!mac_ctx) 5654 return QDF_STATUS_E_INVAL; 5655 5656 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 5657 if (!mlme_obj) 5658 return QDF_STATUS_E_INVAL; 5659 5660 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) { 5661 cm_csr_set_idle(vdev_id); 5662 sme_qos_update_hand_off(vdev_id, false); 5663 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5664 SME_QOS_CSR_DISCONNECT_IND, NULL); 5665 /* Fill legacy structures from resp for failure */ 5666 5667 return QDF_STATUS_SUCCESS; 5668 } 5669 5670 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 5671 count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 5672 PM_STA_MODE, NULL); 5673 /* 5674 * send duty cycle percentage to FW only if STA + STA 5675 * concurrency is in MCC. 5676 */ 5677 sme_debug("Current iface vdev_id:%d, Primary vdev_id:%d, Dual sta policy:%d, count:%d", 5678 vdev_id, dual_sta_policy->primary_vdev_id, 5679 dual_sta_policy->concurrent_sta_policy, count); 5680 5681 if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX && 5682 dual_sta_policy->concurrent_sta_policy == 5683 QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 && 5684 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) { 5685 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc, 5686 &enable_mcc_adaptive_sch); 5687 if (enable_mcc_adaptive_sch) { 5688 sme_debug("Disable mcc_adaptive_scheduler"); 5689 policy_mgr_set_dynamic_mcc_adaptive_sch( 5690 mac_ctx->psoc, false); 5691 if (QDF_STATUS_SUCCESS != sme_set_mas(false)) { 5692 sme_err("Failed to disable mcc_adaptive_sched"); 5693 return -EAGAIN; 5694 } 5695 } 5696 set_value = 5697 wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev); 5698 sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA, 5699 set_value, VDEV_CMD); 5700 } else if (dual_sta_policy->concurrent_sta_policy == 5701 QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED && count == 2 && 5702 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) { 5703 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc, 5704 &enable_mcc_adaptive_sch); 5705 if (enable_mcc_adaptive_sch) { 5706 sme_debug("Enable mcc_adaptive_scheduler"); 5707 policy_mgr_set_dynamic_mcc_adaptive_sch( 5708 mac_ctx->psoc, true); 5709 if (QDF_STATUS_SUCCESS != sme_set_mas(true)) { 5710 sme_err("Failed to enable mcc_adaptive_sched"); 5711 return -EAGAIN; 5712 } 5713 } 5714 } else { 5715 QDF_STATUS status = QDF_STATUS_SUCCESS; 5716 uint32_t quota_val; 5717 5718 quota_val = 5719 ucfg_mlme_get_user_mcc_quota_percentage(mac_ctx->psoc); 5720 5721 if (quota_val) { 5722 if (enable_mcc_adaptive_sch) { 5723 policy_mgr_set_dynamic_mcc_adaptive_sch( 5724 mac_ctx->psoc, false); 5725 status = sme_set_mas(false); 5726 } 5727 if (status == QDF_STATUS_SUCCESS) 5728 sme_cli_set_command(wlan_vdev_get_id(vdev), 5729 WMA_VDEV_MCC_SET_TIME_QUOTA, 5730 quota_val, VDEV_CMD); 5731 } else { 5732 sme_debug("no applicable user mcc/quota"); 5733 } 5734 } 5735 5736 /* 5737 * For open mode authentication, send dummy install key response to 5738 * send OBSS scan and QOS event. 5739 */ 5740 if (!rsp->is_wps_connection && cm_is_open_mode(vdev)) { 5741 install_key_rsp.length = sizeof(install_key_rsp); 5742 install_key_rsp.status_code = eSIR_SME_SUCCESS; 5743 install_key_rsp.sessionId = vdev_id; 5744 /* use BC mac to enable OBSS scan */ 5745 qdf_copy_macaddr(&install_key_rsp.peer_macaddr, &bc_mac); 5746 csr_roam_chk_lnk_set_ctx_rsp(mac_ctx, 5747 (tSirSmeRsp *)&install_key_rsp); 5748 } 5749 5750 rsn_cap = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP); 5751 if (rsn_cap >= 0) { 5752 cm_update_rsn_ocv_cap(&rsn_cap, rsp); 5753 if (wma_cli_set2_command(vdev_id, wmi_vdev_param_rsn_capability, 5754 rsn_cap, 0, VDEV_CMD)) 5755 sme_err("Failed to update wmi_vdev_param_rsn_capability for vdev id %d", 5756 vdev_id); 5757 } 5758 5759 /* 5760 * Update the IEs after connection to reconfigure 5761 * any capability that changed during connection. 5762 */ 5763 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) 5764 sme_set_vdev_ies_per_band(mac_handle, vdev_id, 5765 wlan_vdev_mlme_get_opmode(vdev)); 5766 5767 return QDF_STATUS_SUCCESS; 5768 } 5769 5770 QDF_STATUS cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev *vdev, 5771 struct wlan_cm_vdev_discon_req *req) 5772 { 5773 struct mac_context *mac_ctx; 5774 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5775 struct csr_roam_session *session; 5776 5777 /* 5778 * This API is to update legacy struct and should be removed once 5779 * CSR is cleaned up fully. No new params should be added to CSR, use 5780 * vdev/pdev/psoc instead 5781 */ 5782 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5783 if (!mac_ctx) 5784 return QDF_STATUS_E_INVAL; 5785 5786 session = CSR_GET_SESSION(mac_ctx, vdev_id); 5787 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 5788 sme_err("session not found for vdev_id %d", vdev_id); 5789 return QDF_STATUS_E_INVAL; 5790 } 5791 5792 cm_csr_set_joining(vdev_id); 5793 5794 /* Update the disconnect stats */ 5795 session->disconnect_stats.disconnection_cnt++; 5796 if (req->req.source == CM_PEER_DISCONNECT) { 5797 session->disconnect_stats.disassoc_by_peer++; 5798 } else if (req->req.source == CM_SB_DISCONNECT) { 5799 switch (req->req.reason_code) { 5800 case REASON_DISASSOC_DUE_TO_INACTIVITY: 5801 session->disconnect_stats.peer_kickout++; 5802 break; 5803 case REASON_BEACON_MISSED: 5804 session->disconnect_stats.bmiss++; 5805 break; 5806 default: 5807 /* Unknown reason code */ 5808 break; 5809 } 5810 } else if (req->req.source == CM_MLO_LINK_SWITCH_DISCONNECT) { 5811 /* Do not update any stats as session is going to be deleted*/ 5812 } else { 5813 session->disconnect_stats.disconnection_by_app++; 5814 } 5815 5816 csr_update_prev_ap_info(session, vdev); 5817 csr_qos_send_disconnect_ind(mac_ctx, vdev_id); 5818 5819 return QDF_STATUS_SUCCESS; 5820 } 5821 5822 QDF_STATUS 5823 cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev, 5824 struct wlan_cm_discon_rsp *rsp) 5825 { 5826 mac_handle_t mac_handle; 5827 struct mac_context *mac_ctx; 5828 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5829 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5830 5831 /* 5832 * This API is to update legacy struct and should be removed once 5833 * CSR is cleaned up fully. No new params should be added to CSR, use 5834 * vdev/pdev/psoc instead 5835 */ 5836 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5837 5838 mac_ctx = MAC_CONTEXT(mac_handle); 5839 if (!mac_ctx) 5840 return QDF_STATUS_E_INVAL; 5841 5842 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 5843 if (!mlme_obj) 5844 return QDF_STATUS_E_INVAL; 5845 5846 cm_csr_set_idle(vdev_id); 5847 if (cm_is_vdev_roaming(vdev)) 5848 sme_qos_update_hand_off(vdev_id, false); 5849 csr_set_default_dot11_mode(mac_ctx); 5850 5851 /* 5852 * Update the IEs after disconnection to remove 5853 * any connection specific capability change and 5854 * to reset back to self cap 5855 */ 5856 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) { 5857 wlan_cm_set_force_20mhz_in_24ghz(vdev, true); 5858 sme_set_vdev_ies_per_band(mac_handle, vdev_id, 5859 wlan_vdev_mlme_get_opmode(vdev)); 5860 } 5861 5862 return QDF_STATUS_SUCCESS; 5863 } 5864 5865 #ifdef WLAN_FEATURE_HOST_ROAM 5866 void cm_csr_preauth_done(struct wlan_objmgr_vdev *vdev) 5867 { 5868 struct mac_context *mac_ctx; 5869 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5870 struct cm_roam_values_copy config; 5871 bool is_11r; 5872 5873 /* 5874 * This API is to update legacy struct and should be removed once 5875 * CSR is cleaned up fully. No new params should be added to CSR, use 5876 * vdev/pdev/psoc instead 5877 */ 5878 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5879 if (!mac_ctx) { 5880 sme_err("mac_ctx is NULL"); 5881 return; 5882 } 5883 5884 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, IS_11R_CONNECTION, 5885 &config); 5886 is_11r = config.bool_value; 5887 if (is_11r || wlan_cm_get_ese_assoc(mac_ctx->pdev, vdev_id)) 5888 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5889 SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL); 5890 } 5891 #endif 5892 5893 /* */ 5894 QDF_STATUS csr_send_mb_disassoc_req_msg(struct mac_context *mac, 5895 uint32_t sessionId, 5896 tSirMacAddr bssId, uint16_t reasonCode) 5897 { 5898 struct disassoc_req *pMsg; 5899 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5900 5901 if (!CSR_IS_SESSION_VALID(mac, sessionId)) 5902 return QDF_STATUS_E_FAILURE; 5903 5904 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 5905 if (!pMsg) 5906 return QDF_STATUS_E_NOMEM; 5907 5908 pMsg->messageType = eWNI_SME_DISASSOC_REQ; 5909 pMsg->length = sizeof(*pMsg); 5910 pMsg->sessionId = sessionId; 5911 5912 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid); 5913 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE); 5914 pMsg->reasonCode = reasonCode; 5915 5916 /* Update the disconnect stats */ 5917 pSession->disconnect_stats.disconnection_cnt++; 5918 pSession->disconnect_stats.disconnection_by_app++; 5919 5920 return umac_send_mb_message_to_mac(pMsg); 5921 } 5922 5923 QDF_STATUS csr_send_chng_mcc_beacon_interval(struct mac_context *mac, 5924 uint32_t sessionId) 5925 { 5926 struct wlan_change_bi *pMsg; 5927 uint16_t len = 0; 5928 QDF_STATUS status = QDF_STATUS_SUCCESS; 5929 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5930 5931 if (!pSession) { 5932 sme_err("session %d not found", sessionId); 5933 return QDF_STATUS_E_FAILURE; 5934 } 5935 /* NO need to update the Beacon Params if update beacon parameter flag 5936 * is not set 5937 */ 5938 if (!mac->roam.roamSession[sessionId].update_bcn_int) 5939 return QDF_STATUS_SUCCESS; 5940 5941 mac->roam.roamSession[sessionId].update_bcn_int = 5942 false; 5943 5944 /* Create the message and send to lim */ 5945 len = sizeof(*pMsg); 5946 pMsg = qdf_mem_malloc(len); 5947 if (!pMsg) 5948 status = QDF_STATUS_E_NOMEM; 5949 else 5950 status = QDF_STATUS_SUCCESS; 5951 if (QDF_IS_STATUS_SUCCESS(status)) { 5952 pMsg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL; 5953 pMsg->length = len; 5954 5955 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, 5956 &pMsg->bssid); 5957 sme_debug("CSR Attempting to change BI for Bssid= " 5958 QDF_MAC_ADDR_FMT, 5959 QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); 5960 pMsg->session_id = sessionId; 5961 sme_debug("session %d BeaconInterval %d", 5962 sessionId, 5963 mac->roam.roamSession[sessionId].bcn_int); 5964 pMsg->beacon_interval = 5965 mac->roam.roamSession[sessionId].bcn_int; 5966 status = umac_send_mb_message_to_mac(pMsg); 5967 } 5968 return status; 5969 } 5970 5971 #ifdef QCA_HT_2040_COEX 5972 QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId, 5973 ePhyChanBondState cbMode, bool obssEnabled) 5974 { 5975 struct set_ht2040_mode *pMsg; 5976 uint16_t len = 0; 5977 QDF_STATUS status = QDF_STATUS_SUCCESS; 5978 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5979 5980 if (!pSession) { 5981 sme_err("session %d not found", sessionId); 5982 return QDF_STATUS_E_FAILURE; 5983 } 5984 5985 /* Create the message and send to lim */ 5986 len = sizeof(struct set_ht2040_mode); 5987 pMsg = qdf_mem_malloc(len); 5988 if (!pMsg) 5989 status = QDF_STATUS_E_NOMEM; 5990 else 5991 status = QDF_STATUS_SUCCESS; 5992 if (QDF_IS_STATUS_SUCCESS(status)) { 5993 qdf_mem_zero(pMsg, sizeof(struct set_ht2040_mode)); 5994 pMsg->messageType = eWNI_SME_SET_HT_2040_MODE; 5995 pMsg->length = len; 5996 5997 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid); 5998 sme_debug( 5999 "CSR Attempting to set HT20/40 mode for Bssid= " 6000 QDF_MAC_ADDR_FMT, 6001 QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); 6002 pMsg->sessionId = sessionId; 6003 sme_debug(" session %d HT20/40 mode %d", 6004 sessionId, cbMode); 6005 pMsg->cbMode = cbMode; 6006 pMsg->obssEnabled = obssEnabled; 6007 status = umac_send_mb_message_to_mac(pMsg); 6008 } 6009 return status; 6010 } 6011 #endif 6012 6013 QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac, 6014 uint32_t vdev_id, 6015 tSirMacAddr bssId, uint16_t reasonCode) 6016 { 6017 struct deauth_req *pMsg; 6018 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); 6019 6020 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) 6021 return QDF_STATUS_E_FAILURE; 6022 6023 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6024 if (!pMsg) 6025 return QDF_STATUS_E_NOMEM; 6026 6027 pMsg->messageType = eWNI_SME_DEAUTH_REQ; 6028 pMsg->length = sizeof(*pMsg); 6029 pMsg->vdev_id = vdev_id; 6030 6031 wlan_mlme_get_mac_vdev_id(mac->pdev, vdev_id, &pMsg->bssid); 6032 /* Set the peer MAC address before sending the message to LIM */ 6033 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE); 6034 pMsg->reasonCode = reasonCode; 6035 6036 /* Update the disconnect stats */ 6037 pSession->disconnect_stats.disconnection_cnt++; 6038 pSession->disconnect_stats.disconnection_by_app++; 6039 6040 return umac_send_mb_message_to_mac(pMsg); 6041 } 6042 6043 QDF_STATUS csr_send_mb_disassoc_cnf_msg(struct mac_context *mac, 6044 struct disassoc_ind *pDisassocInd) 6045 { 6046 QDF_STATUS status = QDF_STATUS_SUCCESS; 6047 struct disassoc_cnf *pMsg; 6048 6049 do { 6050 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6051 if (!pMsg) 6052 status = QDF_STATUS_E_NOMEM; 6053 else 6054 status = QDF_STATUS_SUCCESS; 6055 if (!QDF_IS_STATUS_SUCCESS(status)) 6056 break; 6057 pMsg->messageType = eWNI_SME_DISASSOC_CNF; 6058 pMsg->status_code = eSIR_SME_SUCCESS; 6059 pMsg->length = sizeof(*pMsg); 6060 pMsg->vdev_id = pDisassocInd->vdev_id; 6061 qdf_copy_macaddr(&pMsg->peer_macaddr, 6062 &pDisassocInd->peer_macaddr); 6063 status = QDF_STATUS_SUCCESS; 6064 if (!QDF_IS_STATUS_SUCCESS(status)) { 6065 qdf_mem_free(pMsg); 6066 break; 6067 } 6068 6069 qdf_copy_macaddr(&pMsg->bssid, &pDisassocInd->bssid); 6070 status = QDF_STATUS_SUCCESS; 6071 if (!QDF_IS_STATUS_SUCCESS(status)) { 6072 qdf_mem_free(pMsg); 6073 break; 6074 } 6075 6076 status = umac_send_mb_message_to_mac(pMsg); 6077 } while (0); 6078 return status; 6079 } 6080 6081 QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac, 6082 struct deauth_ind *pDeauthInd) 6083 { 6084 QDF_STATUS status = QDF_STATUS_SUCCESS; 6085 struct deauth_cnf *pMsg; 6086 6087 do { 6088 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6089 if (!pMsg) 6090 status = QDF_STATUS_E_NOMEM; 6091 else 6092 status = QDF_STATUS_SUCCESS; 6093 if (!QDF_IS_STATUS_SUCCESS(status)) 6094 break; 6095 pMsg->messageType = eWNI_SME_DEAUTH_CNF; 6096 pMsg->status_code = eSIR_SME_SUCCESS; 6097 pMsg->length = sizeof(*pMsg); 6098 pMsg->vdev_id = pDeauthInd->vdev_id; 6099 qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid); 6100 status = QDF_STATUS_SUCCESS; 6101 if (!QDF_IS_STATUS_SUCCESS(status)) { 6102 qdf_mem_free(pMsg); 6103 break; 6104 } 6105 qdf_copy_macaddr(&pMsg->peer_macaddr, 6106 &pDeauthInd->peer_macaddr); 6107 status = QDF_STATUS_SUCCESS; 6108 if (!QDF_IS_STATUS_SUCCESS(status)) { 6109 qdf_mem_free(pMsg); 6110 break; 6111 } 6112 status = umac_send_mb_message_to_mac(pMsg); 6113 } while (0); 6114 return status; 6115 } 6116 6117 QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac, 6118 struct assoc_ind *pAssocInd, 6119 QDF_STATUS Halstatus, 6120 enum wlan_status_code mac_status_code) 6121 { 6122 QDF_STATUS status = QDF_STATUS_SUCCESS; 6123 struct assoc_cnf *pMsg; 6124 struct scheduler_msg msg = { 0 }; 6125 6126 sme_debug("HalStatus: %d, mac_status_code %d", 6127 Halstatus, mac_status_code); 6128 do { 6129 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6130 if (!pMsg) 6131 return QDF_STATUS_E_NOMEM; 6132 pMsg->messageType = eWNI_SME_ASSOC_CNF; 6133 pMsg->length = sizeof(*pMsg); 6134 if (QDF_IS_STATUS_SUCCESS(Halstatus)) { 6135 pMsg->status_code = eSIR_SME_SUCCESS; 6136 } else { 6137 pMsg->status_code = eSIR_SME_ASSOC_REFUSED; 6138 pMsg->mac_status_code = mac_status_code; 6139 } 6140 /* bssId */ 6141 qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId, 6142 QDF_MAC_ADDR_SIZE); 6143 /* peerMacAddr */ 6144 qdf_mem_copy(pMsg->peer_macaddr.bytes, pAssocInd->peerMacAddr, 6145 QDF_MAC_ADDR_SIZE); 6146 /* aid */ 6147 pMsg->aid = pAssocInd->aid; 6148 /* OWE IE */ 6149 if (pAssocInd->owe_ie_len) { 6150 pMsg->owe_ie = qdf_mem_malloc(pAssocInd->owe_ie_len); 6151 if (!pMsg->owe_ie) 6152 return QDF_STATUS_E_NOMEM; 6153 qdf_mem_copy(pMsg->owe_ie, pAssocInd->owe_ie, 6154 pAssocInd->owe_ie_len); 6155 pMsg->owe_ie_len = pAssocInd->owe_ie_len; 6156 } 6157 6158 if (pAssocInd->ft_ie_len) { 6159 pMsg->ft_ie = qdf_mem_malloc(pAssocInd->ft_ie_len); 6160 if (!pMsg->ft_ie) 6161 return QDF_STATUS_E_NOMEM; 6162 qdf_mem_copy(pMsg->ft_ie, pAssocInd->ft_ie, 6163 pAssocInd->ft_ie_len); 6164 pMsg->ft_ie_len = pAssocInd->ft_ie_len; 6165 } 6166 pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb; 6167 6168 msg.type = pMsg->messageType; 6169 msg.bodyval = 0; 6170 msg.bodyptr = pMsg; 6171 /* pMsg is freed by umac_send_mb_message_to_mac in anycase*/ 6172 status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE, &msg, 6173 true); 6174 } while (0); 6175 return status; 6176 } 6177 6178 /** 6179 * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini 6180 * @mac: mac_context. 6181 * @vdev: Pointer to pdev obj 6182 * @vdev_id: vdev_id 6183 * 6184 * This API will store the oce flags in vdev mlme priv object 6185 * 6186 * Return: none 6187 */ 6188 static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac, 6189 struct wlan_objmgr_pdev *pdev, 6190 uint8_t vdev_id) 6191 { 6192 uint8_t *vdev_dynamic_oce; 6193 struct wlan_objmgr_vdev *vdev = 6194 wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_LEGACY_MAC_ID); 6195 6196 if (!vdev) 6197 return; 6198 6199 vdev_dynamic_oce = mlme_get_dynamic_oce_flags(vdev); 6200 if (vdev_dynamic_oce) 6201 *vdev_dynamic_oce = mac->mlme_cfg->oce.feature_bitmap; 6202 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 6203 } 6204 6205 void csr_send_set_ie(uint8_t type, uint8_t sub_type, 6206 uint8_t vdev_id) 6207 { 6208 struct send_extcap_ie *msg; 6209 QDF_STATUS status; 6210 6211 sme_debug("send SET IE msg to PE"); 6212 6213 if (!(type == WLAN_VDEV_MLME_TYPE_STA || 6214 (type == WLAN_VDEV_MLME_TYPE_AP && 6215 sub_type == WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE))) { 6216 sme_debug("Failed to send set IE req for vdev_%d", vdev_id); 6217 return; 6218 } 6219 6220 msg = qdf_mem_malloc(sizeof(*msg)); 6221 if (!msg) 6222 return; 6223 6224 msg->msg_type = eWNI_SME_SET_IE_REQ; 6225 msg->session_id = vdev_id; 6226 msg->length = sizeof(*msg); 6227 status = umac_send_mb_message_to_mac(msg); 6228 if (!QDF_IS_STATUS_SUCCESS(status)) 6229 sme_debug("Failed to send set IE req for vdev_%d", vdev_id); 6230 } 6231 6232 void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, 6233 uint8_t *nss_5g) 6234 { 6235 struct mac_context *mac_ctx = sme_get_mac_context(); 6236 6237 if (!mac_ctx) { 6238 sme_err("Invalid MAC context"); 6239 return; 6240 } 6241 6242 switch (dev_mode) { 6243 case QDF_STA_MODE: 6244 *nss_2g = mac_ctx->vdev_type_nss_2g.sta; 6245 *nss_5g = mac_ctx->vdev_type_nss_5g.sta; 6246 break; 6247 case QDF_SAP_MODE: 6248 *nss_2g = mac_ctx->vdev_type_nss_2g.sap; 6249 *nss_5g = mac_ctx->vdev_type_nss_5g.sap; 6250 break; 6251 case QDF_P2P_CLIENT_MODE: 6252 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli; 6253 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli; 6254 break; 6255 case QDF_P2P_GO_MODE: 6256 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go; 6257 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go; 6258 break; 6259 case QDF_P2P_DEVICE_MODE: 6260 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev; 6261 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev; 6262 break; 6263 case QDF_IBSS_MODE: 6264 *nss_2g = mac_ctx->vdev_type_nss_2g.ibss; 6265 *nss_5g = mac_ctx->vdev_type_nss_5g.ibss; 6266 break; 6267 case QDF_OCB_MODE: 6268 *nss_2g = mac_ctx->vdev_type_nss_2g.ocb; 6269 *nss_5g = mac_ctx->vdev_type_nss_5g.ocb; 6270 break; 6271 case QDF_NAN_DISC_MODE: 6272 *nss_2g = mac_ctx->vdev_type_nss_2g.nan; 6273 *nss_5g = mac_ctx->vdev_type_nss_5g.nan; 6274 break; 6275 case QDF_NDI_MODE: 6276 *nss_2g = mac_ctx->vdev_type_nss_2g.ndi; 6277 *nss_5g = mac_ctx->vdev_type_nss_5g.ndi; 6278 break; 6279 default: 6280 *nss_2g = 1; 6281 *nss_5g = 1; 6282 sme_err("Unknown device mode: %d", dev_mode); 6283 break; 6284 } 6285 sme_debug("mode - %d: nss_2g - %d, 5g - %d", 6286 dev_mode, *nss_2g, *nss_5g); 6287 } 6288 6289 QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme) 6290 { 6291 QDF_STATUS status; 6292 uint32_t existing_session_id; 6293 struct csr_roam_session *session; 6294 struct mlme_vht_capabilities_info *vht_cap_info; 6295 u8 vdev_id; 6296 struct qdf_mac_addr *mac_addr; 6297 mac_handle_t mac_handle; 6298 struct mac_context *mac_ctx; 6299 struct wlan_objmgr_vdev *vdev; 6300 struct wlan_vht_config vht_config; 6301 struct wlan_ht_config ht_cap; 6302 6303 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 6304 mac_ctx = MAC_CONTEXT(mac_handle); 6305 if (!mac_ctx) { 6306 QDF_ASSERT(0); 6307 return QDF_STATUS_E_INVAL; 6308 } 6309 6310 if (!(mac_ctx->mlme_cfg)) { 6311 sme_err("invalid mlme cfg"); 6312 return QDF_STATUS_E_FAILURE; 6313 } 6314 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; 6315 6316 vdev = vdev_mlme->vdev; 6317 6318 vdev_id = wlan_vdev_get_id(vdev); 6319 mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev); 6320 /* check to see if the mac address already belongs to a session */ 6321 status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr, 6322 &existing_session_id); 6323 if (QDF_IS_STATUS_SUCCESS(status)) { 6324 sme_err("Session %d exists with mac address "QDF_MAC_ADDR_FMT, 6325 existing_session_id, 6326 QDF_MAC_ADDR_REF(mac_addr->bytes)); 6327 return QDF_STATUS_E_FAILURE; 6328 } 6329 6330 /* attempt to retrieve session for Id */ 6331 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6332 if (!session) { 6333 sme_err("Session does not exist for interface %d", vdev_id); 6334 return QDF_STATUS_E_FAILURE; 6335 } 6336 6337 /* check to see if the session is already active */ 6338 if (session->sessionActive) { 6339 sme_err("Cannot re-open active session with Id %d", vdev_id); 6340 return QDF_STATUS_E_FAILURE; 6341 } 6342 6343 session->sessionActive = true; 6344 session->vdev_id = vdev_id; 6345 6346 ht_cap.caps = 0; 6347 vht_config.caps = 0; 6348 ht_cap.ht_caps = mac_ctx->mlme_cfg->ht_caps.ht_cap_info; 6349 vdev_mlme->proto.ht_info.ht_caps = ht_cap.caps; 6350 6351 vht_config.max_mpdu_len = vht_cap_info->ampdu_len; 6352 vht_config.supported_channel_widthset = 6353 vht_cap_info->supp_chan_width; 6354 vht_config.ldpc_coding = vht_cap_info->ldpc_coding_cap; 6355 vht_config.shortgi80 = vht_cap_info->short_gi_80mhz; 6356 vht_config.shortgi160and80plus80 = 6357 vht_cap_info->short_gi_160mhz; 6358 vht_config.tx_stbc = vht_cap_info->tx_stbc; 6359 vht_config.rx_stbc = vht_cap_info->rx_stbc; 6360 vht_config.su_beam_former = vht_cap_info->su_bformer; 6361 vht_config.su_beam_formee = vht_cap_info->su_bformee; 6362 vht_config.csnof_beamformer_antSup = 6363 vht_cap_info->tx_bfee_ant_supp; 6364 vht_config.num_soundingdim = vht_cap_info->num_soundingdim; 6365 vht_config.mu_beam_former = vht_cap_info->mu_bformer; 6366 vht_config.mu_beam_formee = vht_cap_info->enable_mu_bformee; 6367 vht_config.vht_txops = vht_cap_info->txop_ps; 6368 vht_config.htc_vhtcap = vht_cap_info->htc_vhtc; 6369 vht_config.rx_antpattern = vht_cap_info->rx_antpattern; 6370 vht_config.tx_antpattern = vht_cap_info->tx_antpattern; 6371 6372 vht_config.max_ampdu_lenexp = 6373 vht_cap_info->ampdu_len_exponent; 6374 vdev_mlme->proto.vht_info.caps = vht_config.caps; 6375 csr_update_session_he_cap(mac_ctx, session); 6376 csr_update_session_eht_cap(mac_ctx, session); 6377 6378 csr_send_set_ie(vdev_mlme->mgmt.generic.type, 6379 vdev_mlme->mgmt.generic.subtype, 6380 wlan_vdev_get_id(vdev)); 6381 6382 if (vdev_mlme->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_STA) { 6383 csr_store_oce_cfg_flags_in_vdev(mac_ctx, mac_ctx->pdev, 6384 wlan_vdev_get_id(vdev)); 6385 wlan_mlme_update_oce_flags(mac_ctx->pdev); 6386 } 6387 6388 return QDF_STATUS_SUCCESS; 6389 } 6390 6391 void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id) 6392 { 6393 if (CSR_IS_SESSION_VALID(mac, vdev_id)) { 6394 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, 6395 vdev_id); 6396 6397 csr_flush_roam_scan_chan_lists(mac, vdev_id); 6398 csr_roam_free_connected_info(mac, &pSession->connectedInfo); 6399 csr_init_session(mac, vdev_id); 6400 } 6401 } 6402 6403 QDF_STATUS csr_prepare_vdev_delete(struct mac_context *mac_ctx, 6404 struct wlan_objmgr_vdev *vdev) 6405 { 6406 QDF_STATUS status = QDF_STATUS_SUCCESS; 6407 struct csr_roam_session *session; 6408 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6409 6410 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6411 if (!session) 6412 return QDF_STATUS_E_INVAL; 6413 6414 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) 6415 return QDF_STATUS_E_INVAL; 6416 6417 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, vdev_id)) { 6418 sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE"); 6419 cm_stop_wait_for_key_timer(mac_ctx->psoc, vdev_id); 6420 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, 6421 vdev_id); 6422 } 6423 6424 wlan_ser_vdev_queue_disable(vdev); 6425 /* Flush all the commands for vdev */ 6426 wlan_serialization_purge_all_cmd_by_vdev_id(mac_ctx->pdev, vdev_id); 6427 if (!mac_ctx->session_close_cb) { 6428 sme_err("no close session callback registered"); 6429 return QDF_STATUS_E_FAILURE; 6430 } 6431 6432 return status; 6433 } 6434 6435 static void csr_init_session(struct mac_context *mac, uint32_t sessionId) 6436 { 6437 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 6438 6439 if (!pSession) 6440 return; 6441 6442 pSession->sessionActive = false; 6443 pSession->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 6444 pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; 6445 csr_roam_free_connected_info(mac, &pSession->connectedInfo); 6446 } 6447 6448 static void csr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev, 6449 void *object, void *arg) 6450 { 6451 struct bssid_search_arg *bssid_arg = arg; 6452 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 6453 struct wlan_objmgr_peer *peer; 6454 6455 if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) 6456 return; 6457 6458 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_LEGACY_SME_ID); 6459 if (!peer) 6460 return; 6461 6462 if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes, 6463 wlan_peer_get_macaddr(peer)) == QDF_STATUS_SUCCESS) 6464 bssid_arg->vdev_id = wlan_vdev_get_id(vdev); 6465 6466 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID); 6467 } 6468 6469 QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac, 6470 struct qdf_mac_addr *bssid, 6471 uint32_t *pSessionId) 6472 { 6473 struct bssid_search_arg bssid_arg; 6474 6475 qdf_copy_macaddr(&bssid_arg.peer_addr, bssid); 6476 bssid_arg.vdev_id = WLAN_MAX_VDEVS; 6477 wlan_objmgr_pdev_iterate_obj_list(mac->pdev, WLAN_VDEV_OP, 6478 csr_get_vdev_id_from_bssid, 6479 &bssid_arg, 0, 6480 WLAN_LEGACY_SME_ID); 6481 if (bssid_arg.vdev_id >= WLAN_MAX_VDEVS) { 6482 *pSessionId = 0; 6483 return QDF_STATUS_E_FAILURE; 6484 } 6485 6486 *pSessionId = bssid_arg.vdev_id; 6487 6488 return QDF_STATUS_SUCCESS; 6489 } 6490 6491 QDF_STATUS csr_get_snr(struct mac_context *mac, 6492 tCsrSnrCallback callback, 6493 struct qdf_mac_addr bssId, void *pContext) 6494 { 6495 QDF_STATUS status = QDF_STATUS_SUCCESS; 6496 struct scheduler_msg msg = {0}; 6497 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 6498 tAniGetSnrReq *pMsg; 6499 6500 pMsg = qdf_mem_malloc(sizeof(tAniGetSnrReq)); 6501 if (!pMsg) 6502 return QDF_STATUS_E_NOMEM; 6503 6504 status = csr_roam_get_session_id_from_bssid(mac, &bssId, &sessionId); 6505 if (!QDF_IS_STATUS_SUCCESS(status)) { 6506 qdf_mem_free(pMsg); 6507 sme_err("Couldn't find session_id for given BSSID"); 6508 return status; 6509 } 6510 6511 pMsg->msgType = eWNI_SME_GET_SNR_REQ; 6512 pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq); 6513 pMsg->sessionId = sessionId; 6514 pMsg->snrCallback = callback; 6515 pMsg->pDevContext = pContext; 6516 msg.type = eWNI_SME_GET_SNR_REQ; 6517 msg.bodyptr = pMsg; 6518 msg.reserved = 0; 6519 6520 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6521 QDF_MODULE_ID_SME, 6522 QDF_MODULE_ID_SME, 6523 &msg)) { 6524 qdf_mem_free((void *)pMsg); 6525 status = QDF_STATUS_E_FAILURE; 6526 } 6527 6528 return status; 6529 } 6530 6531 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) 6532 QDF_STATUS csr_invoke_neighbor_report_request( 6533 uint8_t session_id, 6534 struct sRrmNeighborReq *neighbor_report_req, 6535 bool send_resp_to_host) 6536 { 6537 struct wmi_invoke_neighbor_report_params *invoke_params; 6538 struct scheduler_msg msg = {0}; 6539 6540 if (!neighbor_report_req) { 6541 sme_err("Invalid params"); 6542 return QDF_STATUS_E_INVAL; 6543 } 6544 6545 invoke_params = qdf_mem_malloc(sizeof(*invoke_params)); 6546 if (!invoke_params) 6547 return QDF_STATUS_E_NOMEM; 6548 6549 invoke_params->vdev_id = session_id; 6550 invoke_params->send_resp_to_host = send_resp_to_host; 6551 6552 if (!neighbor_report_req->no_ssid) { 6553 invoke_params->ssid.length = neighbor_report_req->ssid.length; 6554 qdf_mem_copy(invoke_params->ssid.ssid, 6555 neighbor_report_req->ssid.ssId, 6556 neighbor_report_req->ssid.length); 6557 } else { 6558 invoke_params->ssid.length = 0; 6559 } 6560 6561 sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT"); 6562 6563 msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT; 6564 msg.reserved = 0; 6565 msg.bodyptr = invoke_params; 6566 6567 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6568 QDF_MODULE_ID_WMA, 6569 QDF_MODULE_ID_WMA, 6570 &msg)) { 6571 sme_err("Not able to post message to WMA"); 6572 qdf_mem_free(invoke_params); 6573 return QDF_STATUS_E_FAILURE; 6574 } 6575 6576 return QDF_STATUS_SUCCESS; 6577 } 6578 6579 #ifdef FEATURE_WLAN_ESE 6580 void wlan_cm_ese_populate_additional_ies(struct wlan_objmgr_pdev *pdev, 6581 struct wlan_mlme_psoc_ext_obj *mlme_obj, 6582 uint8_t vdev_id, 6583 struct wlan_roam_scan_offload_params *rso_mode_cfg) 6584 { 6585 uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN] 6586 = { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 }; 6587 uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j; 6588 ese_wmm_tspec_ie *tspec_ie; 6589 tESETspecInfo ese_tspec; 6590 struct mac_context *mac_ctx; 6591 struct csr_roam_session *session; 6592 6593 mac_ctx = sme_get_mac_context(); 6594 if (!mac_ctx) { 6595 sme_err("mac_ctx is NULL"); 6596 return; 6597 } 6598 6599 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6600 if (!session) { 6601 sme_err("session is null %d", vdev_id); 6602 return; 6603 } 6604 6605 tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN); 6606 if (csr_is_wmm_supported(mac_ctx) && 6607 mlme_obj->cfg.lfr.ese_enabled && 6608 wlan_cm_get_ese_assoc(pdev, session->vdev_id)) { 6609 ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info( 6610 mac_ctx, session->vdev_id, 6611 (tTspecInfo *)&ese_tspec.tspec[0]); 6612 qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr, 6613 SIR_MAC_OUI_WME_HDR_MIN); 6614 for (j = 0; j < ese_tspec.numTspecs; j++) { 6615 /* Populate the tspec_ie */ 6616 ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec, 6617 tspec_ie); 6618 wlan_cm_append_assoc_ies(rso_mode_cfg, 6619 WLAN_ELEMID_VENDOR, 6620 DOT11F_IE_WMMTSPEC_MAX_LEN, 6621 tspec_ie_buf); 6622 } 6623 } 6624 } 6625 #endif 6626 6627 uint8_t *wlan_cm_get_rrm_cap_ie_data(void) 6628 { 6629 struct mac_context *mac_ctx; 6630 6631 mac_ctx = sme_get_mac_context(); 6632 if (!mac_ctx) { 6633 sme_err("mac_ctx is NULL"); 6634 return NULL; 6635 } 6636 6637 return (uint8_t *)&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps; 6638 } 6639 #endif 6640 6641 tSmeCmd *csr_get_command_buffer(struct mac_context *mac) 6642 { 6643 tSmeCmd *pCmd = sme_get_command_buffer(mac); 6644 6645 if (pCmd) 6646 mac->roam.sPendingCommands++; 6647 6648 return pCmd; 6649 } 6650 6651 static void csr_free_cmd_memory(struct mac_context *mac, tSmeCmd *pCommand) 6652 { 6653 if (!pCommand) { 6654 sme_err("pCommand is NULL"); 6655 return; 6656 } 6657 switch (pCommand->command) { 6658 case eSmeCommandRoam: 6659 csr_release_command_roam(mac, pCommand); 6660 break; 6661 case eSmeCommandWmStatusChange: 6662 csr_release_command_wm_status_change(mac, pCommand); 6663 break; 6664 default: 6665 break; 6666 } 6667 } 6668 6669 void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand) 6670 { 6671 if (mac->roam.sPendingCommands > 0) { 6672 /* 6673 * All command allocated through csr_get_command_buffer 6674 * need to decrement the pending count when releasing 6675 */ 6676 mac->roam.sPendingCommands--; 6677 csr_free_cmd_memory(mac, pCommand); 6678 sme_release_command(mac, pCommand); 6679 } else { 6680 sme_err("no pending commands"); 6681 QDF_ASSERT(0); 6682 } 6683 } 6684 6685 void csr_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd) 6686 { 6687 struct wlan_serialization_queued_cmd_info cmd_info; 6688 struct wlan_serialization_command cmd; 6689 struct wlan_objmgr_vdev *vdev; 6690 6691 if (!sme_cmd) { 6692 sme_err("sme_cmd is NULL"); 6693 return; 6694 } 6695 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 6696 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); 6697 if (!vdev) { 6698 sme_err("Invalid vdev"); 6699 return; 6700 } 6701 qdf_mem_zero(&cmd_info, 6702 sizeof(struct wlan_serialization_queued_cmd_info)); 6703 cmd_info.cmd_id = sme_cmd->cmd_id; 6704 cmd_info.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD; 6705 cmd_info.cmd_type = csr_get_cmd_type(sme_cmd); 6706 cmd_info.vdev = vdev; 6707 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command)); 6708 cmd.cmd_id = cmd_info.cmd_id; 6709 cmd.cmd_type = cmd_info.cmd_type; 6710 cmd.vdev = cmd_info.vdev; 6711 if (wlan_serialization_is_cmd_present_in_active_queue( 6712 mac_ctx->psoc, &cmd)) { 6713 cmd_info.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE; 6714 wlan_serialization_remove_cmd(&cmd_info); 6715 } else if (wlan_serialization_is_cmd_present_in_pending_queue( 6716 mac_ctx->psoc, &cmd)) { 6717 cmd_info.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE; 6718 wlan_serialization_cancel_request(&cmd_info); 6719 } else { 6720 sme_debug("can't find cmd_id %d cmd_type %d", cmd_info.cmd_id, 6721 cmd_info.cmd_type); 6722 } 6723 if (cmd_info.vdev) 6724 wlan_objmgr_vdev_release_ref(cmd_info.vdev, WLAN_LEGACY_SME_ID); 6725 } 6726 6727 6728 static enum wlan_serialization_cmd_type csr_get_roam_cmd_type( 6729 tSmeCmd *sme_cmd) 6730 { 6731 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 6732 6733 switch (sme_cmd->u.roamCmd.roamReason) { 6734 case eCsrForcedDisassocSta: 6735 cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_STA; 6736 break; 6737 case eCsrForcedDeauthSta: 6738 cmd_type = WLAN_SER_CMD_FORCE_DEAUTH_STA; 6739 break; 6740 default: 6741 break; 6742 } 6743 6744 return cmd_type; 6745 } 6746 6747 enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd) 6748 { 6749 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 6750 6751 switch (sme_cmd->command) { 6752 case eSmeCommandRoam: 6753 cmd_type = csr_get_roam_cmd_type(sme_cmd); 6754 break; 6755 case eSmeCommandWmStatusChange: 6756 cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE; 6757 break; 6758 case eSmeCommandAddTs: 6759 cmd_type = WLAN_SER_CMD_ADDTS; 6760 break; 6761 case eSmeCommandDelTs: 6762 cmd_type = WLAN_SER_CMD_DELTS; 6763 break; 6764 case e_sme_command_set_hw_mode: 6765 cmd_type = WLAN_SER_CMD_SET_HW_MODE; 6766 break; 6767 case e_sme_command_nss_update: 6768 cmd_type = WLAN_SER_CMD_NSS_UPDATE; 6769 break; 6770 case e_sme_command_set_dual_mac_config: 6771 cmd_type = WLAN_SER_CMD_SET_DUAL_MAC_CONFIG; 6772 break; 6773 case e_sme_command_set_antenna_mode: 6774 cmd_type = WLAN_SER_CMD_SET_ANTENNA_MODE; 6775 break; 6776 case e_sme_command_sap_ch_width_update: 6777 cmd_type = WLAN_SER_CMD_SAP_BW_UPDATE; 6778 break; 6779 default: 6780 break; 6781 } 6782 6783 return cmd_type; 6784 } 6785 6786 static uint32_t csr_get_monotonous_number(struct mac_context *mac_ctx) 6787 { 6788 uint32_t cmd_id; 6789 uint32_t mask = 0x00FFFFFF, prefix = 0x0D000000; 6790 6791 cmd_id = qdf_atomic_inc_return(&mac_ctx->global_cmd_id); 6792 cmd_id = (cmd_id & mask); 6793 cmd_id = (cmd_id | prefix); 6794 6795 return cmd_id; 6796 } 6797 6798 static void csr_fill_cmd_timeout(struct wlan_serialization_command *cmd) 6799 { 6800 switch (cmd->cmd_type) { 6801 case WLAN_SER_CMD_WM_STATUS_CHANGE: 6802 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT; 6803 break; 6804 case WLAN_SER_CMD_VDEV_START_BSS: 6805 cmd->cmd_timeout_duration = SME_CMD_VDEV_START_BSS_TIMEOUT; 6806 break; 6807 case WLAN_SER_CMD_VDEV_STOP_BSS: 6808 cmd->cmd_timeout_duration = SME_CMD_STOP_BSS_CMD_TIMEOUT; 6809 break; 6810 case WLAN_SER_CMD_FORCE_DISASSOC_STA: 6811 case WLAN_SER_CMD_FORCE_DEAUTH_STA: 6812 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT; 6813 break; 6814 6815 case WLAN_SER_CMD_ADDTS: 6816 case WLAN_SER_CMD_DELTS: 6817 cmd->cmd_timeout_duration = SME_CMD_ADD_DEL_TS_TIMEOUT; 6818 break; 6819 case WLAN_SER_CMD_SET_HW_MODE: 6820 case WLAN_SER_CMD_NSS_UPDATE: 6821 case WLAN_SER_CMD_SET_DUAL_MAC_CONFIG: 6822 case WLAN_SER_CMD_SET_ANTENNA_MODE: 6823 case WLAN_SER_CMD_SAP_BW_UPDATE: 6824 cmd->cmd_timeout_duration = SME_CMD_POLICY_MGR_CMD_TIMEOUT; 6825 break; 6826 default: 6827 cmd->cmd_timeout_duration = SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE; 6828 break; 6829 } 6830 } 6831 6832 QDF_STATUS csr_set_serialization_params_to_cmd(struct mac_context *mac_ctx, 6833 tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd, 6834 uint8_t high_priority) 6835 { 6836 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6837 6838 if (!sme_cmd) { 6839 sme_err("Invalid sme_cmd"); 6840 return status; 6841 } 6842 if (!cmd) { 6843 sme_err("Invalid serialization_cmd"); 6844 return status; 6845 } 6846 6847 /* 6848 * no need to fill command id for non-scan as they will be 6849 * zero always 6850 */ 6851 sme_cmd->cmd_id = csr_get_monotonous_number(mac_ctx); 6852 cmd->cmd_id = sme_cmd->cmd_id; 6853 6854 cmd->cmd_type = csr_get_cmd_type(sme_cmd); 6855 if (cmd->cmd_type == WLAN_SER_CMD_MAX) { 6856 sme_err("serialization enum not found for sme_cmd type %d", 6857 sme_cmd->command); 6858 return status; 6859 } 6860 cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 6861 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); 6862 if (!cmd->vdev) { 6863 sme_err("vdev is NULL for vdev_id:%d", sme_cmd->vdev_id); 6864 return status; 6865 } 6866 cmd->umac_cmd = sme_cmd; 6867 6868 csr_fill_cmd_timeout(cmd); 6869 6870 cmd->source = WLAN_UMAC_COMP_MLME; 6871 cmd->cmd_cb = sme_ser_cmd_callback; 6872 cmd->is_high_priority = high_priority; 6873 cmd->is_blocking = true; 6874 6875 return QDF_STATUS_SUCCESS; 6876 } 6877 6878 QDF_STATUS csr_queue_sme_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd, 6879 bool high_priority) 6880 { 6881 struct wlan_serialization_command cmd; 6882 struct wlan_objmgr_vdev *vdev = NULL; 6883 enum wlan_serialization_status ser_cmd_status; 6884 QDF_STATUS status; 6885 6886 if (!SME_IS_START(mac_ctx)) { 6887 sme_err("Sme in stop state"); 6888 QDF_ASSERT(0); 6889 goto error; 6890 } 6891 6892 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command)); 6893 status = csr_set_serialization_params_to_cmd(mac_ctx, sme_cmd, 6894 &cmd, high_priority); 6895 if (QDF_IS_STATUS_ERROR(status)) { 6896 sme_err("failed to set ser params"); 6897 goto error; 6898 } 6899 6900 vdev = cmd.vdev; 6901 ser_cmd_status = wlan_serialization_request(&cmd); 6902 6903 switch (ser_cmd_status) { 6904 case WLAN_SER_CMD_PENDING: 6905 case WLAN_SER_CMD_ACTIVE: 6906 /* Command posted to active/pending list */ 6907 status = QDF_STATUS_SUCCESS; 6908 break; 6909 default: 6910 sme_err("Failed to queue command %d with status:%d", 6911 sme_cmd->command, ser_cmd_status); 6912 status = QDF_STATUS_E_FAILURE; 6913 goto error; 6914 } 6915 6916 return status; 6917 6918 error: 6919 if (vdev) 6920 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6921 6922 csr_release_command_buffer(mac_ctx, sme_cmd); 6923 6924 return QDF_STATUS_E_FAILURE; 6925 } 6926 6927 QDF_STATUS csr_roam_update_config(struct mac_context *mac_ctx, uint8_t session_id, 6928 uint16_t capab, uint32_t value) 6929 { 6930 struct update_config *msg; 6931 QDF_STATUS status = QDF_STATUS_SUCCESS; 6932 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); 6933 6934 sme_debug("update HT config requested"); 6935 if (!session) { 6936 sme_err("Session does not exist for session id %d", session_id); 6937 return QDF_STATUS_E_FAILURE; 6938 } 6939 6940 msg = qdf_mem_malloc(sizeof(*msg)); 6941 if (!msg) 6942 return QDF_STATUS_E_NOMEM; 6943 6944 msg->messageType = eWNI_SME_UPDATE_CONFIG; 6945 msg->vdev_id = session_id; 6946 msg->capab = capab; 6947 msg->value = value; 6948 msg->length = sizeof(*msg); 6949 status = umac_send_mb_message_to_mac(msg); 6950 6951 return status; 6952 } 6953 6954 QDF_STATUS csr_send_channel_change_req(struct mac_context *mac, 6955 struct channel_change_req *req) 6956 { 6957 struct scheduler_msg msg = {0}; 6958 struct channel_change_req *ch_change_req; 6959 QDF_STATUS status; 6960 6961 ch_change_req = qdf_mem_malloc(sizeof(*ch_change_req)); 6962 if (!ch_change_req) 6963 return QDF_STATUS_E_NOMEM; 6964 6965 qdf_mem_copy(ch_change_req, req, sizeof(*ch_change_req)); 6966 msg.type = eWNI_SME_CHANNEL_CHANGE_REQ; 6967 msg.bodyptr = ch_change_req; 6968 msg.reserved = 0; 6969 6970 status = scheduler_post_message(QDF_MODULE_ID_SME, 6971 QDF_MODULE_ID_PE, 6972 QDF_MODULE_ID_PE, 6973 &msg); 6974 if (QDF_IS_STATUS_ERROR(status)) { 6975 sme_err("Failed to send channel change request with status : %d", 6976 status); 6977 qdf_mem_free(ch_change_req); 6978 } 6979 6980 return status; 6981 } 6982 /* 6983 * Post Beacon Tx Start request to LIM 6984 * immediately after SAP CAC WAIT is 6985 * completed without any RADAR indications. 6986 */ 6987 QDF_STATUS csr_roam_start_beacon_req(struct mac_context *mac, 6988 struct qdf_mac_addr bssid, 6989 uint8_t dfsCacWaitStatus) 6990 { 6991 QDF_STATUS status = QDF_STATUS_SUCCESS; 6992 tSirStartBeaconIndication *pMsg; 6993 6994 pMsg = qdf_mem_malloc(sizeof(tSirStartBeaconIndication)); 6995 if (!pMsg) 6996 return QDF_STATUS_E_NOMEM; 6997 6998 pMsg->messageType = eWNI_SME_START_BEACON_REQ; 6999 pMsg->messageLen = sizeof(tSirStartBeaconIndication); 7000 pMsg->beaconStartStatus = dfsCacWaitStatus; 7001 qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE); 7002 7003 status = umac_send_mb_message_to_mac(pMsg); 7004 7005 return status; 7006 } 7007 7008 /* 7009 * csr_roam_modify_add_ies - 7010 * This function sends msg to modify the additional IE buffers in PE 7011 * 7012 * @mac: mac global structure 7013 * @pModifyIE: pointer to tSirModifyIE structure 7014 * @updateType: Type of buffer 7015 * 7016 * 7017 * Return: QDF_STATUS - Success or failure 7018 */ 7019 QDF_STATUS 7020 csr_roam_modify_add_ies(struct mac_context *mac, 7021 tSirModifyIE *pModifyIE, eUpdateIEsType updateType) 7022 { 7023 tpSirModifyIEsInd pModifyAddIEInd = NULL; 7024 uint8_t *pLocalBuffer = NULL; 7025 QDF_STATUS status; 7026 7027 /* following buffer will be freed by consumer (PE) */ 7028 pLocalBuffer = qdf_mem_malloc(pModifyIE->ieBufferlength); 7029 if (!pLocalBuffer) 7030 return QDF_STATUS_E_NOMEM; 7031 7032 pModifyAddIEInd = qdf_mem_malloc(sizeof(tSirModifyIEsInd)); 7033 if (!pModifyAddIEInd) { 7034 qdf_mem_free(pLocalBuffer); 7035 return QDF_STATUS_E_NOMEM; 7036 } 7037 7038 /*copy the IE buffer */ 7039 qdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer, 7040 pModifyIE->ieBufferlength); 7041 qdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd)); 7042 7043 pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES; 7044 pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd); 7045 7046 qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid); 7047 7048 pModifyAddIEInd->modifyIE.vdev_id = pModifyIE->vdev_id; 7049 pModifyAddIEInd->modifyIE.notify = pModifyIE->notify; 7050 pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID; 7051 pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen; 7052 pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer; 7053 pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength; 7054 pModifyAddIEInd->modifyIE.oui_length = pModifyIE->oui_length; 7055 7056 pModifyAddIEInd->updateType = updateType; 7057 7058 status = umac_send_mb_message_to_mac(pModifyAddIEInd); 7059 if (!QDF_IS_STATUS_SUCCESS(status)) { 7060 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d", 7061 status); 7062 qdf_mem_free(pLocalBuffer); 7063 } 7064 return status; 7065 } 7066 7067 /* 7068 * csr_roam_update_add_ies - 7069 * This function sends msg to updates the additional IE buffers in PE 7070 * 7071 * @mac: mac global structure 7072 * @sessionId: SME session id 7073 * @bssid: BSSID 7074 * @additionIEBuffer: buffer containing addition IE from hostapd 7075 * @length: length of buffer 7076 * @updateType: Type of buffer 7077 * @append: append or replace completely 7078 * 7079 * 7080 * Return: QDF_STATUS - Success or failure 7081 */ 7082 QDF_STATUS 7083 csr_roam_update_add_ies(struct mac_context *mac, 7084 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType) 7085 { 7086 tpSirUpdateIEsInd pUpdateAddIEs = NULL; 7087 uint8_t *pLocalBuffer = NULL; 7088 QDF_STATUS status; 7089 7090 if (pUpdateIE->ieBufferlength != 0) { 7091 /* Following buffer will be freed by consumer (PE) */ 7092 pLocalBuffer = qdf_mem_malloc(pUpdateIE->ieBufferlength); 7093 if (!pLocalBuffer) { 7094 return QDF_STATUS_E_NOMEM; 7095 } 7096 qdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer, 7097 pUpdateIE->ieBufferlength); 7098 } 7099 7100 pUpdateAddIEs = qdf_mem_malloc(sizeof(tSirUpdateIEsInd)); 7101 if (!pUpdateAddIEs) { 7102 qdf_mem_free(pLocalBuffer); 7103 return QDF_STATUS_E_NOMEM; 7104 } 7105 7106 pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES; 7107 pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd); 7108 7109 qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid); 7110 7111 pUpdateAddIEs->updateIE.vdev_id = pUpdateIE->vdev_id; 7112 pUpdateAddIEs->updateIE.append = pUpdateIE->append; 7113 pUpdateAddIEs->updateIE.notify = pUpdateIE->notify; 7114 pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength; 7115 pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer; 7116 7117 pUpdateAddIEs->updateType = updateType; 7118 7119 status = umac_send_mb_message_to_mac(pUpdateAddIEs); 7120 if (!QDF_IS_STATUS_SUCCESS(status)) { 7121 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d", 7122 status); 7123 qdf_mem_free(pLocalBuffer); 7124 } 7125 return status; 7126 } 7127 7128 /** 7129 * csr_send_ext_change_freq()- function to post send ECSA 7130 * action frame to lim. 7131 * @mac_ctx: pointer to global mac structure 7132 * @ch_freq: new channel freq to switch 7133 * @session_id: senssion it should be sent on. 7134 * 7135 * This function is called to post ECSA frame to lim. 7136 * 7137 * Return: success if msg posted to LIM else return failure 7138 */ 7139 QDF_STATUS csr_send_ext_change_freq(struct mac_context *mac_ctx, 7140 qdf_freq_t ch_freq, uint8_t session_id) 7141 { 7142 QDF_STATUS status = QDF_STATUS_SUCCESS; 7143 struct sir_sme_ext_cng_chan_req *msg; 7144 7145 msg = qdf_mem_malloc(sizeof(*msg)); 7146 if (!msg) 7147 return QDF_STATUS_E_NOMEM; 7148 7149 msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL; 7150 msg->length = sizeof(*msg); 7151 msg->new_ch_freq = ch_freq; 7152 msg->vdev_id = session_id; 7153 status = umac_send_mb_message_to_mac(msg); 7154 return status; 7155 } 7156 7157 QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t vdev_id) 7158 { 7159 QDF_STATUS status; 7160 struct wlan_objmgr_vdev *vdev; 7161 struct scheduler_msg message = {0}; 7162 7163 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 7164 WLAN_LEGACY_MAC_ID); 7165 if (!vdev) { 7166 sme_err("VDEV not found for vdev id: %d", vdev_id); 7167 return QDF_STATUS_E_FAILURE; 7168 } 7169 7170 if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_AP_CSA_START, NULL); 7171 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7172 7173 /* Serialize the req through MC thread */ 7174 message.bodyval = vdev_id; 7175 message.type = eWNI_SME_CSA_RESTART_REQ; 7176 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE, 7177 QDF_MODULE_ID_PE, &message); 7178 if (!QDF_IS_STATUS_SUCCESS(status)) { 7179 sme_err("scheduler_post_msg failed!(err=%d)", status); 7180 status = QDF_STATUS_E_FAILURE; 7181 } 7182 7183 return status; 7184 } 7185 7186 QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx, 7187 struct qdf_mac_addr bssid, 7188 uint32_t target_chan_freq, 7189 uint8_t csa_ie_reqd, 7190 struct ch_params *ch_params, 7191 uint32_t new_cac_ms) 7192 { 7193 QDF_STATUS status = QDF_STATUS_SUCCESS; 7194 tSirDfsCsaIeRequest *msg; 7195 7196 msg = qdf_mem_malloc(sizeof(tSirDfsCsaIeRequest)); 7197 if (!msg) 7198 return QDF_STATUS_E_NOMEM; 7199 7200 msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ; 7201 msg->msgLen = sizeof(tSirDfsCsaIeRequest); 7202 7203 msg->target_chan_freq = target_chan_freq; 7204 msg->csaIeRequired = csa_ie_reqd; 7205 msg->ch_switch_beacon_cnt = 7206 mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt; 7207 if (mac_ctx->sap.one_time_csa_count) { 7208 msg->ch_switch_beacon_cnt = mac_ctx->sap.one_time_csa_count; 7209 mac_ctx->sap.one_time_csa_count = 0; 7210 } 7211 msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode; 7212 msg->dfs_ch_switch_disable = 7213 mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch; 7214 msg->new_chan_cac_ms = new_cac_ms; 7215 qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE); 7216 qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params)); 7217 7218 status = umac_send_mb_message_to_mac(msg); 7219 7220 return status; 7221 } 7222 7223 QDF_STATUS csr_sta_continue_csa(struct mac_context *mac_ctx, uint8_t vdev_id) 7224 { 7225 QDF_STATUS status; 7226 struct scheduler_msg message = {0}; 7227 7228 /* Serialize the req through MC thread */ 7229 message.bodyval = vdev_id; 7230 message.type = eWNI_SME_STA_CSA_CONTINUE_REQ; 7231 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE, 7232 QDF_MODULE_ID_PE, &message); 7233 if (!QDF_IS_STATUS_SUCCESS(status)) { 7234 sme_err("eWNI_SME_STA_CSA_CONTINUE_REQ failed!(err=%d)", 7235 status); 7236 status = QDF_STATUS_E_FAILURE; 7237 } 7238 7239 return status; 7240 } 7241 7242 /** 7243 * csr_update_op_class_array() - update op class for each band 7244 * @mac_ctx: mac global context 7245 * @op_classes: out param, operating class array to update 7246 * @channel_info: channel info 7247 * @ch_name: channel band name to display in debug messages 7248 * @i: out param, stores number of operating classes 7249 * 7250 * Return: void 7251 */ 7252 static void 7253 csr_update_op_class_array(struct mac_context *mac_ctx, 7254 uint8_t *op_classes, 7255 struct csr_channel *channel_info, 7256 char *ch_name, 7257 uint8_t *i) 7258 { 7259 uint8_t j = 0, idx = 0, class = 0; 7260 bool found = false; 7261 uint8_t num_channels = channel_info->numChannels; 7262 uint8_t ch_num; 7263 7264 sme_debug("Num %s channels, %d", ch_name, num_channels); 7265 7266 for (idx = 0; idx < num_channels && 7267 *i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) { 7268 wlan_reg_freq_to_chan_op_class( 7269 mac_ctx->pdev, channel_info->channel_freq_list[idx], 7270 true, BIT(BEHAV_NONE), &class, &ch_num); 7271 7272 found = false; 7273 for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; j++) { 7274 if (op_classes[j] == class) { 7275 found = true; 7276 break; 7277 } 7278 } 7279 7280 if (!found) { 7281 op_classes[*i] = class; 7282 *i = *i + 1; 7283 } 7284 } 7285 } 7286 7287 /** 7288 * csr_init_operating_classes() - update op class for all bands 7289 * @mac: pointer to mac context. 7290 * 7291 * Return: void 7292 */ 7293 static void csr_init_operating_classes(struct mac_context *mac) 7294 { 7295 uint8_t i = 0; 7296 uint8_t j = 0; 7297 uint8_t swap = 0; 7298 uint8_t numClasses = 0; 7299 uint8_t opClasses[REG_MAX_SUPP_OPER_CLASSES] = {0,}; 7300 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 7301 7302 wlan_reg_read_current_country(mac->psoc, reg_cc); 7303 sme_debug("Current Country = %s", reg_cc); 7304 7305 csr_update_op_class_array(mac, opClasses, 7306 &mac->scan.base_channels, "20MHz", &i); 7307 numClasses = i; 7308 7309 /* As per spec the operating classes should be in ascending order. 7310 * Bubble sort is fine since we don't have many classes 7311 */ 7312 for (i = 0; i < (numClasses - 1); i++) { 7313 for (j = 0; j < (numClasses - i - 1); j++) { 7314 /* For decreasing order use < */ 7315 if (opClasses[j] > opClasses[j + 1]) { 7316 swap = opClasses[j]; 7317 opClasses[j] = opClasses[j + 1]; 7318 opClasses[j + 1] = swap; 7319 } 7320 } 7321 } 7322 7323 /* Set the ordered list of op classes in regdomain 7324 * for use by other modules 7325 */ 7326 wlan_reg_dmn_set_curr_opclasses(numClasses, &opClasses[0]); 7327 } 7328 7329 /** 7330 * csr_process_set_hw_mode() - Set HW mode command to PE 7331 * @mac: Globacl MAC pointer 7332 * @command: Command received from SME 7333 * 7334 * Posts the set HW mode command to PE. This message passing 7335 * through PE is required for PE's internal management 7336 * 7337 * Return: None 7338 */ 7339 void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command) 7340 { 7341 uint32_t len; 7342 struct s_sir_set_hw_mode *cmd = NULL; 7343 QDF_STATUS status; 7344 struct scheduler_msg msg = {0}; 7345 struct sir_set_hw_mode_resp *param; 7346 enum policy_mgr_hw_mode_change hw_mode; 7347 enum policy_mgr_conc_next_action action; 7348 enum set_hw_mode_status hw_mode_change_status = 7349 SET_HW_MODE_STATUS_ECANCELED; 7350 7351 /* Setting HW mode is for the entire system. 7352 * So, no need to check session 7353 */ 7354 7355 if (!command) { 7356 sme_err("Set HW mode param is NULL"); 7357 goto fail; 7358 } 7359 7360 len = sizeof(*cmd); 7361 cmd = qdf_mem_malloc(len); 7362 if (!cmd) 7363 /* Probably the fail response will also fail during malloc. 7364 * Still proceeding to send response! 7365 */ 7366 goto fail; 7367 7368 action = command->u.set_hw_mode_cmd.action; 7369 7370 status = policy_mgr_validate_dbs_switch(mac->psoc, action); 7371 7372 if (QDF_IS_STATUS_ERROR(status)) { 7373 sme_debug("Hw mode change not sent to FW status = %d", status); 7374 if (status == QDF_STATUS_E_ALREADY) 7375 hw_mode_change_status = SET_HW_MODE_STATUS_ALREADY; 7376 goto fail; 7377 } 7378 7379 hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index( 7380 mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index); 7381 7382 if (POLICY_MGR_HW_MODE_NOT_IN_PROGRESS == hw_mode) { 7383 sme_err("hw_mode %d, failing", hw_mode); 7384 goto fail; 7385 } 7386 7387 policy_mgr_set_hw_mode_change_in_progress(mac->psoc, hw_mode); 7388 policy_mgr_reset_connection_update(mac->psoc); 7389 7390 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC == 7391 command->u.set_hw_mode_cmd.reason) && 7392 (true == mac->sme.get_connection_info_cb(NULL, NULL))) { 7393 sme_err("Set HW mode refused: conn in progress"); 7394 policy_mgr_restart_opportunistic_timer(mac->psoc, false); 7395 goto reset_state; 7396 } 7397 7398 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC == 7399 command->u.set_hw_mode_cmd.reason) && 7400 (!command->u.set_hw_mode_cmd.hw_mode_index && 7401 !policy_mgr_need_opportunistic_upgrade(mac->psoc, NULL))) { 7402 sme_err("Set HW mode to SMM not needed anymore"); 7403 goto reset_state; 7404 } 7405 7406 cmd->messageType = eWNI_SME_SET_HW_MODE_REQ; 7407 cmd->length = len; 7408 cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index; 7409 cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason; 7410 /* 7411 * Below callback and context info are not needed for PE as of now. 7412 * Storing the passed value in the same s_sir_set_hw_mode format. 7413 */ 7414 cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb; 7415 7416 sme_debug( 7417 "Posting set hw mode req to PE session:%d reason:%d", 7418 command->u.set_hw_mode_cmd.session_id, 7419 command->u.set_hw_mode_cmd.reason); 7420 7421 status = umac_send_mb_message_to_mac(cmd); 7422 if (QDF_STATUS_SUCCESS != status) { 7423 sme_err("Posting to PE failed"); 7424 cmd = NULL; 7425 goto reset_state; 7426 } 7427 return; 7428 7429 reset_state: 7430 policy_mgr_set_hw_mode_change_in_progress(mac->psoc, 7431 POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); 7432 fail: 7433 if (cmd) 7434 qdf_mem_free(cmd); 7435 param = qdf_mem_malloc(sizeof(*param)); 7436 if (!param) 7437 return; 7438 7439 sme_debug("Sending set HW fail response to SME"); 7440 param->status = hw_mode_change_status; 7441 param->cfgd_hw_mode_index = 0; 7442 param->num_vdev_mac_entries = 0; 7443 msg.type = eWNI_SME_SET_HW_MODE_RESP; 7444 msg.bodyptr = param; 7445 msg.bodyval = 0; 7446 sys_process_mmh_msg(mac, &msg); 7447 } 7448 7449 /** 7450 * csr_process_set_dual_mac_config() - Set HW mode command to PE 7451 * @mac: Global MAC pointer 7452 * @command: Command received from SME 7453 * 7454 * Posts the set dual mac config command to PE. 7455 * 7456 * Return: None 7457 */ 7458 void csr_process_set_dual_mac_config(struct mac_context *mac, tSmeCmd *command) 7459 { 7460 uint32_t len; 7461 struct sir_set_dual_mac_cfg *cmd; 7462 QDF_STATUS status; 7463 struct scheduler_msg msg = {0}; 7464 struct sir_dual_mac_config_resp *param; 7465 7466 /* Setting MAC configuration is for the entire system. 7467 * So, no need to check session 7468 */ 7469 7470 if (!command) { 7471 sme_err("Set HW mode param is NULL"); 7472 goto fail; 7473 } 7474 7475 len = sizeof(*cmd); 7476 cmd = qdf_mem_malloc(len); 7477 if (!cmd) 7478 /* Probably the fail response will also fail during malloc. 7479 * Still proceeding to send response! 7480 */ 7481 goto fail; 7482 7483 cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ; 7484 cmd->length = len; 7485 cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config; 7486 cmd->set_dual_mac.fw_mode_config = 7487 command->u.set_dual_mac_cmd.fw_mode_config; 7488 /* 7489 * Below callback and context info are not needed for PE as of now. 7490 * Storing the passed value in the same sir_set_dual_mac_cfg format. 7491 */ 7492 cmd->set_dual_mac.set_dual_mac_cb = 7493 command->u.set_dual_mac_cmd.set_dual_mac_cb; 7494 7495 sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x", 7496 cmd->set_dual_mac.scan_config, 7497 cmd->set_dual_mac.fw_mode_config); 7498 7499 status = umac_send_mb_message_to_mac(cmd); 7500 if (QDF_IS_STATUS_ERROR(status)) { 7501 sme_err("Posting to PE failed"); 7502 goto fail; 7503 } 7504 return; 7505 fail: 7506 param = qdf_mem_malloc(sizeof(*param)); 7507 if (!param) 7508 return; 7509 7510 sme_err("Sending set dual mac fail response to SME"); 7511 param->status = SET_HW_MODE_STATUS_ECANCELED; 7512 msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP; 7513 msg.bodyptr = param; 7514 msg.bodyval = 0; 7515 sys_process_mmh_msg(mac, &msg); 7516 } 7517 7518 /** 7519 * csr_process_set_antenna_mode() - Set antenna mode command to 7520 * PE 7521 * @mac: Global MAC pointer 7522 * @command: Command received from SME 7523 * 7524 * Posts the set dual mac config command to PE. 7525 * 7526 * Return: None 7527 */ 7528 void csr_process_set_antenna_mode(struct mac_context *mac, tSmeCmd *command) 7529 { 7530 uint32_t len; 7531 struct sir_set_antenna_mode *cmd; 7532 QDF_STATUS status; 7533 struct scheduler_msg msg = {0}; 7534 struct sir_antenna_mode_resp *param; 7535 7536 /* Setting MAC configuration is for the entire system. 7537 * So, no need to check session 7538 */ 7539 7540 if (!command) { 7541 sme_err("Set antenna mode param is NULL"); 7542 goto fail; 7543 } 7544 7545 len = sizeof(*cmd); 7546 cmd = qdf_mem_malloc(len); 7547 if (!cmd) 7548 goto fail; 7549 7550 cmd->message_type = eWNI_SME_SET_ANTENNA_MODE_REQ; 7551 cmd->length = len; 7552 cmd->set_antenna_mode = command->u.set_antenna_mode_cmd; 7553 7554 sme_debug( 7555 "Posting eWNI_SME_SET_ANTENNA_MODE_REQ to PE: %d %d", 7556 cmd->set_antenna_mode.num_rx_chains, 7557 cmd->set_antenna_mode.num_tx_chains); 7558 7559 status = umac_send_mb_message_to_mac(cmd); 7560 if (QDF_STATUS_SUCCESS != status) { 7561 sme_err("Posting to PE failed"); 7562 /* 7563 * umac_send_mb_message_to_mac would've released the mem 7564 * allocated by cmd. 7565 */ 7566 goto fail; 7567 } 7568 7569 return; 7570 fail: 7571 param = qdf_mem_malloc(sizeof(*param)); 7572 if (!param) 7573 return; 7574 7575 sme_err("Sending set dual mac fail response to SME"); 7576 param->status = SET_ANTENNA_MODE_STATUS_ECANCELED; 7577 msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP; 7578 msg.bodyptr = param; 7579 msg.bodyval = 0; 7580 sys_process_mmh_msg(mac, &msg); 7581 } 7582 7583 /** 7584 * csr_process_nss_update_req() - Update nss command to PE 7585 * @mac: Globacl MAC pointer 7586 * @command: Command received from SME 7587 * 7588 * Posts the nss update command to PE. This message passing 7589 * through PE is required for PE's internal management 7590 * 7591 * Return: None 7592 */ 7593 void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command) 7594 { 7595 uint32_t len; 7596 struct sir_nss_update_request *msg; 7597 QDF_STATUS status; 7598 struct scheduler_msg msg_return = {0}; 7599 struct sir_bcn_update_rsp *param; 7600 struct csr_roam_session *session; 7601 7602 7603 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) { 7604 sme_err("Invalid session id %d", command->vdev_id); 7605 goto fail; 7606 } 7607 session = CSR_GET_SESSION(mac, command->vdev_id); 7608 7609 len = sizeof(*msg); 7610 msg = qdf_mem_malloc(len); 7611 if (!msg) 7612 /* Probably the fail response is also fail during malloc. 7613 * Still proceeding to send response! 7614 */ 7615 goto fail; 7616 7617 msg->msgType = eWNI_SME_NSS_UPDATE_REQ; 7618 msg->msgLen = sizeof(*msg); 7619 7620 msg->new_nss = command->u.nss_update_cmd.new_nss; 7621 msg->ch_width = command->u.nss_update_cmd.ch_width; 7622 msg->vdev_id = command->u.nss_update_cmd.session_id; 7623 7624 sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE"); 7625 7626 status = umac_send_mb_message_to_mac(msg); 7627 if (QDF_IS_STATUS_SUCCESS(status)) 7628 return; 7629 7630 sme_err("Posting to PE failed"); 7631 fail: 7632 param = qdf_mem_malloc(sizeof(*param)); 7633 if (!param) 7634 return; 7635 7636 sme_err("Sending nss update fail response to SME"); 7637 param->status = QDF_STATUS_E_FAILURE; 7638 param->vdev_id = command->u.nss_update_cmd.session_id; 7639 param->reason = REASON_NSS_UPDATE; 7640 msg_return.type = eWNI_SME_NSS_UPDATE_RSP; 7641 msg_return.bodyptr = param; 7642 msg_return.bodyval = 0; 7643 sys_process_mmh_msg(mac, &msg_return); 7644 } 7645 7646 /** 7647 * csr_process_sap_ch_width_update() - Update ch_width command to PE 7648 * @mac: Globacl MAC pointer 7649 * @command: Command received from SME 7650 * 7651 * Posts the ch_width update command to PE. This message passing 7652 * through PE is required for PE's internal management 7653 * 7654 * Return: None 7655 */ 7656 void csr_process_sap_ch_width_update(struct mac_context *mac, tSmeCmd *command) 7657 { 7658 uint32_t len; 7659 struct sir_sap_ch_width_update *msg; 7660 QDF_STATUS status; 7661 struct scheduler_msg msg_return = {0}; 7662 struct sir_bcn_update_rsp *param; 7663 enum policy_mgr_conn_update_reason reason = 7664 command->u.bw_update_cmd.reason; 7665 7666 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) { 7667 sme_err("Invalid session id %d", command->vdev_id); 7668 goto fail; 7669 } 7670 7671 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) && 7672 (mac->sme.get_connection_info_cb(NULL, NULL))) { 7673 policy_mgr_restart_opportunistic_timer(mac->psoc, false); 7674 sme_info("Vdev %d : Avoid set BW as conn in progress", 7675 command->vdev_id); 7676 goto fail; 7677 } 7678 7679 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) && 7680 (!policy_mgr_need_opportunistic_upgrade(mac->psoc, &reason))) { 7681 sme_info("Vdev %d: BW update not needed anymore", 7682 command->vdev_id); 7683 goto fail; 7684 } 7685 7686 len = sizeof(*msg); 7687 msg = qdf_mem_malloc(len); 7688 if (!msg) 7689 /* Probably the fail response is also fail during malloc. 7690 * Still proceeding to send response! 7691 */ 7692 goto fail; 7693 7694 msg->msgType = eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ; 7695 msg->msgLen = sizeof(*msg); 7696 7697 msg->ch_width = command->u.bw_update_cmd.ch_width; 7698 msg->vdev_id = command->u.bw_update_cmd.vdev_id; 7699 7700 sme_debug("Posting eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ to PE"); 7701 7702 status = umac_send_mb_message_to_mac(msg); 7703 if (QDF_IS_STATUS_SUCCESS(status)) 7704 return; 7705 7706 sme_err("Posting to PE failed"); 7707 fail: 7708 param = qdf_mem_malloc(sizeof(*param)); 7709 if (param) { 7710 param->status = QDF_STATUS_E_FAILURE; 7711 param->vdev_id = command->u.bw_update_cmd.vdev_id; 7712 param->reason = REASON_CH_WIDTH_UPDATE; 7713 } 7714 msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP; 7715 msg_return.bodyptr = param; 7716 msg_return.bodyval = 0; 7717 sys_process_mmh_msg(mac, &msg_return); 7718 } 7719 7720 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7721 #ifdef WLAN_FEATURE_SAE 7722 /** 7723 * csr_process_roam_auth_sae_callback() - API to trigger the 7724 * WPA3 pre-auth event for candidate AP received from firmware. 7725 * @mac_ctx: Global mac context pointer 7726 * @vdev_id: vdev id 7727 * @roam_bssid: Candidate BSSID to roam 7728 * @akm: Candidate AKM 7729 * 7730 * This function calls the hdd_sme_roam_callback with reason 7731 * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant. 7732 */ 7733 static QDF_STATUS 7734 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, 7735 uint8_t vdev_id, 7736 struct qdf_mac_addr roam_bssid, 7737 uint32_t akm) 7738 { 7739 struct csr_roam_info *roam_info; 7740 struct sir_sae_info sae_info; 7741 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 7742 7743 if (!session) { 7744 sme_err("WPA3 Preauth event with invalid session id:%d", 7745 vdev_id); 7746 return QDF_STATUS_E_FAILURE; 7747 } 7748 7749 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 7750 if (!roam_info) 7751 return QDF_STATUS_E_FAILURE; 7752 7753 sae_info.msg_len = sizeof(sae_info); 7754 sae_info.vdev_id = vdev_id; 7755 sae_info.akm = akm; 7756 wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id, 7757 sae_info.ssid.ssId, 7758 &sae_info.ssid.length); 7759 qdf_mem_copy(sae_info.peer_mac_addr.bytes, 7760 roam_bssid.bytes, QDF_MAC_ADDR_SIZE); 7761 7762 roam_info->sae_info = &sae_info; 7763 7764 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 7765 eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE); 7766 7767 qdf_mem_free(roam_info); 7768 7769 return QDF_STATUS_SUCCESS; 7770 } 7771 #else 7772 static inline QDF_STATUS 7773 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, 7774 uint8_t vdev_id, 7775 struct qdf_mac_addr roam_bssid, 7776 uint32_t akm) 7777 { 7778 return QDF_STATUS_E_NOSUPPORT; 7779 } 7780 #endif 7781 7782 QDF_STATUS 7783 csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id, 7784 struct qdf_mac_addr bssid, uint32_t akm) 7785 { 7786 QDF_STATUS status; 7787 7788 status = sme_acquire_global_lock(&mac_ctx->sme); 7789 if (!QDF_IS_STATUS_SUCCESS(status)) 7790 return status; 7791 7792 status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id, 7793 bssid, akm); 7794 7795 sme_release_global_lock(&mac_ctx->sme); 7796 7797 return status; 7798 7799 } 7800 #endif 7801 7802 QDF_STATUS csr_update_owe_info(struct mac_context *mac, 7803 struct assoc_ind *assoc_ind) 7804 { 7805 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; 7806 QDF_STATUS status; 7807 7808 status = csr_roam_get_session_id_from_bssid(mac, 7809 (struct qdf_mac_addr *)assoc_ind->bssId, 7810 &session_id); 7811 if (!QDF_IS_STATUS_SUCCESS(status)) { 7812 sme_debug("Couldn't find session_id for given BSSID"); 7813 return QDF_STATUS_E_FAILURE; 7814 } 7815 7816 /* Send Association completion message to PE */ 7817 if (assoc_ind->owe_status) 7818 status = QDF_STATUS_E_INVAL; 7819 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status, 7820 assoc_ind->owe_status); 7821 /* 7822 * send a message to CSR itself just to avoid the EAPOL frames 7823 * going OTA before association response 7824 */ 7825 if (assoc_ind->owe_status == 0) 7826 status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac, 7827 assoc_ind, 7828 status, 7829 session_id); 7830 7831 return status; 7832 } 7833 7834 QDF_STATUS csr_update_ft_info(struct mac_context *mac, 7835 struct assoc_ind *assoc_ind) 7836 { 7837 QDF_STATUS status; 7838 7839 /* Send Association completion message to PE */ 7840 status = assoc_ind->ft_status ? QDF_STATUS_E_INVAL : QDF_STATUS_SUCCESS; 7841 assoc_ind->need_assoc_rsp_tx_cb = true; 7842 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status, 7843 assoc_ind->ft_status); 7844 return status; 7845 } 7846 7847 /** 7848 * csr_set_sap_ser_params() - API to fill serialization parameters for 7849 * SAP requests 7850 * @cmd : Serialization command 7851 * @cmd_type: Type of serialization command 7852 * 7853 * Return: Void 7854 */ 7855 static void csr_set_sap_ser_params(struct wlan_serialization_command *cmd, 7856 enum wlan_serialization_cmd_type cmd_type) 7857 { 7858 cmd->cmd_type = cmd_type; 7859 cmd->source = WLAN_UMAC_COMP_MLME; 7860 cmd->cmd_cb = sme_sap_ser_callback; 7861 cmd->is_high_priority = false; 7862 cmd->is_blocking = true; 7863 return; 7864 } 7865 7866 QDF_STATUS csr_bss_start(struct mac_context *mac, uint32_t vdev_id, 7867 struct start_bss_config *bss_config) 7868 { 7869 struct wlan_serialization_command cmd = {0}; 7870 struct wlan_objmgr_vdev *vdev; 7871 struct start_bss_config *start_bss_cfg = NULL; 7872 enum QDF_OPMODE persona; 7873 enum wlan_serialization_status status; 7874 struct csr_roam_session *session; 7875 struct validate_bss_data candidate; 7876 7877 session = CSR_GET_SESSION(mac, vdev_id); 7878 if (!session) 7879 return QDF_STATUS_E_FAILURE; 7880 7881 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, 7882 WLAN_LEGACY_MAC_ID); 7883 if (!vdev) { 7884 sme_err("VDEV not found for vdev id : %d", vdev_id); 7885 return QDF_STATUS_E_FAILURE; 7886 } 7887 7888 persona = wlan_vdev_mlme_get_opmode(vdev); 7889 if (persona != QDF_SAP_MODE && persona != QDF_NDI_MODE && 7890 persona != QDF_P2P_GO_MODE) { 7891 sme_err("Start BSS request for invalid mode %d", persona); 7892 goto error; 7893 } 7894 7895 start_bss_cfg = qdf_mem_malloc(sizeof(struct start_bss_config)); 7896 if (!start_bss_cfg) { 7897 sme_err("SAP BSS config allocation failed"); 7898 goto error; 7899 } 7900 7901 qdf_mem_copy(start_bss_cfg, bss_config, 7902 sizeof(struct start_bss_config)); 7903 start_bss_cfg->cmd_id = csr_get_monotonous_number(mac); 7904 7905 session->cb_mode = start_bss_cfg->sec_ch_offset; 7906 session->bcn_int = bss_config->beaconInterval; 7907 candidate.beacon_interval = session->bcn_int; 7908 candidate.chan_freq = bss_config->oper_ch_freq; 7909 if_mgr_is_beacon_interval_valid(mac->pdev, vdev_id, 7910 &candidate); 7911 bss_config->beaconInterval = candidate.beacon_interval; 7912 session->bcn_int = candidate.beacon_interval; 7913 7914 cmd.cmd_id = start_bss_cfg->cmd_id; 7915 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_START_BSS); 7916 cmd.umac_cmd = start_bss_cfg; 7917 cmd.vdev = vdev; 7918 csr_fill_cmd_timeout(&cmd); 7919 7920 status = wlan_vdev_mlme_ser_start_bss(&cmd); 7921 switch (status) { 7922 case WLAN_SER_CMD_PENDING: 7923 case WLAN_SER_CMD_ACTIVE: 7924 break; 7925 default: 7926 sme_err("ser cmd status %d", status); 7927 goto error; 7928 } 7929 7930 return QDF_STATUS_SUCCESS; 7931 error: 7932 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7933 if (start_bss_cfg) 7934 qdf_mem_free(start_bss_cfg); 7935 7936 return QDF_STATUS_E_FAILURE; 7937 } 7938 7939 QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac, 7940 uint8_t vdev_id, 7941 eCsrRoamBssType bss_type) 7942 { 7943 struct wlan_objmgr_vdev *vdev; 7944 struct wlan_serialization_command cmd = {0}; 7945 enum wlan_serialization_status status; 7946 struct stop_bss_req *stop_bss_req; 7947 7948 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, 7949 WLAN_LEGACY_MAC_ID); 7950 if (!vdev) { 7951 sme_err("VDEV not found for vdev id : %d", vdev_id); 7952 return QDF_STATUS_E_FAILURE; 7953 } 7954 7955 /* Change the substate in case it is wait-for-key */ 7956 if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) { 7957 cm_stop_wait_for_key_timer(mac->psoc, vdev_id); 7958 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, 7959 vdev_id); 7960 } 7961 7962 sme_debug("Stop BSS vdev_id: %d bss_type %d", vdev_id, bss_type); 7963 stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req)); 7964 if (!stop_bss_req) 7965 goto error; 7966 7967 stop_bss_req->vdev_id = vdev_id; 7968 stop_bss_req->cmd_id = csr_get_monotonous_number(mac); 7969 7970 cmd.cmd_id = stop_bss_req->cmd_id; 7971 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_STOP_BSS); 7972 cmd.umac_cmd = stop_bss_req; 7973 cmd.vdev = vdev; 7974 csr_fill_cmd_timeout(&cmd); 7975 7976 status = wlan_vdev_mlme_ser_stop_bss(&cmd); 7977 switch (status) { 7978 case WLAN_SER_CMD_PENDING: 7979 case WLAN_SER_CMD_ACTIVE: 7980 break; 7981 default: 7982 sme_err("ser cmd status %d", status); 7983 goto error; 7984 } 7985 return QDF_STATUS_SUCCESS; 7986 7987 error: 7988 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7989 qdf_mem_free(stop_bss_req); 7990 return QDF_STATUS_E_FAILURE; 7991 } 7992 7993 static void csr_process_stop_bss_response(struct mac_context *mac_ctx, 7994 uint32_t vdev_id) 7995 { 7996 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 7997 7998 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, vdev_id)) { 7999 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 8000 csr_set_default_dot11_mode(mac_ctx); 8001 } 8002 8003 csr_roam_call_callback(mac_ctx, vdev_id, NULL, eCSR_ROAM_INFRA_IND, 8004 eCSR_ROAM_RESULT_INFRA_STOPPED); 8005 return; 8006 } 8007 8008 /** 8009 * csr_process_sap_results() - API to process the LIM response for 8010 * the messages posted by SAP module 8011 * @mac_ctx: mac context 8012 * @req: Serialization command posted by SAP 8013 * @rsp: Response from LIM 8014 * @result: Result from LIM 8015 * @vdev_id : vdev id 8016 * 8017 * Return: void 8018 */ 8019 static bool csr_process_sap_results(struct mac_context *mac_ctx, 8020 void *rsp, 8021 enum csr_sap_response_type result, 8022 uint8_t vdev_id) 8023 { 8024 struct csr_roam_info *roam_info; 8025 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 8026 eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND; 8027 eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED; 8028 enum QDF_OPMODE opmode; 8029 8030 if (!session) { 8031 sme_err("session %d not found ", vdev_id); 8032 return false; 8033 } 8034 8035 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 8036 if (!roam_info) 8037 return false; 8038 8039 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 8040 sme_debug("SAP result : %d", result); 8041 8042 switch (result) { 8043 case CSR_SAP_START_BSS_SUCCESS: 8044 csr_roam_process_start_bss_success(mac_ctx, roam_info, 8045 rsp, vdev_id); 8046 break; 8047 case CSR_SAP_START_BSS_FAILURE: 8048 if (opmode == QDF_NDI_MODE) { 8049 csr_roam_update_ndp_return_params(mac_ctx, 8050 CSR_SAP_START_BSS_FAILURE, 8051 &roam_status, 8052 &roam_result, 8053 roam_info); 8054 } 8055 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 8056 roam_status, roam_result); 8057 csr_set_default_dot11_mode(mac_ctx); 8058 break; 8059 case CSR_SAP_STOP_BSS_SUCCESS: 8060 case CSR_SAP_STOP_BSS_FAILURE: 8061 if (opmode == QDF_NDI_MODE) { 8062 qdf_mem_zero(roam_info, sizeof(*roam_info)); 8063 csr_roam_update_ndp_return_params(mac_ctx, result, 8064 &roam_status, 8065 &roam_result, 8066 roam_info); 8067 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 8068 roam_status, roam_result); 8069 } else { 8070 csr_process_stop_bss_response(mac_ctx, vdev_id); 8071 } 8072 break; 8073 default: 8074 sme_err("Invalid response"); 8075 break; 8076 } 8077 qdf_mem_free(roam_info); 8078 return true; 8079 } 8080 8081 static enum wlan_serialization_cmd_type 8082 get_cmd_type_from_result(enum csr_sap_response_type result) 8083 { 8084 switch (result) { 8085 case CSR_SAP_START_BSS_SUCCESS: 8086 case CSR_SAP_START_BSS_FAILURE: 8087 return WLAN_SER_CMD_VDEV_START_BSS; 8088 case CSR_SAP_STOP_BSS_SUCCESS: 8089 case CSR_SAP_STOP_BSS_FAILURE: 8090 return WLAN_SER_CMD_VDEV_STOP_BSS; 8091 default: 8092 return WLAN_SER_CMD_MAX; 8093 } 8094 } 8095 8096 static inline 8097 uint32_t get_cmd_id_from_cmd_type(void *cmd, 8098 enum wlan_serialization_cmd_type cmd_type) 8099 { 8100 switch (cmd_type) { 8101 case WLAN_SER_CMD_VDEV_START_BSS: 8102 return ((struct start_bss_config *)cmd)->cmd_id; 8103 case WLAN_SER_CMD_VDEV_STOP_BSS: 8104 return ((struct stop_bss_req *)cmd)->cmd_id; 8105 default: 8106 sme_err("Invalid cmd_type %d to be dequeued", cmd_type); 8107 return 0; 8108 } 8109 } 8110 8111 void csr_process_sap_response(struct mac_context *mac_ctx, 8112 enum csr_sap_response_type result, 8113 void *rsp, uint8_t vdev_id) 8114 { 8115 struct wlan_objmgr_vdev *vdev; 8116 void *req; 8117 uint32_t cmd_id; 8118 enum wlan_serialization_cmd_type cmd_type = 8119 get_cmd_type_from_result(result); 8120 8121 if (cmd_type >= WLAN_SER_CMD_MAX) { 8122 sme_err("Invalid command to be dequeued %d", cmd_type); 8123 return; 8124 } 8125 8126 req = wlan_serialization_get_active_cmd(mac_ctx->psoc, 8127 vdev_id, cmd_type); 8128 if (!req) { 8129 sme_err("No active command for response from LIM for cmd: %d vdev: %d", 8130 cmd_type, vdev_id); 8131 csr_process_sap_results(mac_ctx, rsp, result, vdev_id); 8132 return; 8133 } 8134 8135 csr_process_sap_results(mac_ctx, rsp, result, vdev_id); 8136 8137 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 8138 WLAN_LEGACY_MAC_ID); 8139 if (!vdev) { 8140 sme_err("vdev not found for vdev id: %d", vdev_id); 8141 return; 8142 } 8143 8144 cmd_id = get_cmd_id_from_cmd_type(req, cmd_type); 8145 sme_debug("Dequeue cmd id : %d type : %d", cmd_id, cmd_type); 8146 8147 wlan_vdev_mlme_ser_remove_request(vdev, cmd_id, cmd_type); 8148 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 8149 } 8150 8151 void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, 8152 enum QDF_OPMODE device_mode) 8153 { 8154 struct sir_set_vdev_ies_per_band *p_msg; 8155 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8156 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8157 enum csr_cfgdot11mode curr_dot11_mode = 8158 mac_ctx->roam.configParam.uCfgDot11Mode; 8159 8160 p_msg = qdf_mem_malloc(sizeof(*p_msg)); 8161 if (!p_msg) 8162 return; 8163 8164 p_msg->vdev_id = vdev_id; 8165 p_msg->device_mode = device_mode; 8166 p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id, 8167 curr_dot11_mode); 8168 p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND; 8169 p_msg->len = sizeof(*p_msg); 8170 sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d", 8171 vdev_id, p_msg->dot11_mode, device_mode); 8172 status = umac_send_mb_message_to_mac(p_msg); 8173 if (QDF_STATUS_SUCCESS != status) 8174 sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail"); 8175 } 8176