1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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 (!(QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE) || 5054 QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))) { 5055 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5056 return; 5057 } 5058 if (pmk_cache) { 5059 qdf_mem_copy(&pmk_info.pmk, pmk_cache->pmk, pmk_cache->pmk_len); 5060 pmk_info.pmk_len = pmk_cache->pmk_len; 5061 wlan_mlme_clear_sae_single_pmk_info(vdev, &pmk_info); 5062 } else { 5063 wlan_mlme_clear_sae_single_pmk_info(vdev, NULL); 5064 } 5065 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5066 } 5067 #endif 5068 5069 #ifdef FEATURE_WLAN_ESE 5070 void csr_update_prev_ap_info(struct csr_roam_session *session, 5071 struct wlan_objmgr_vdev *vdev) 5072 { 5073 struct wlan_ssid ssid; 5074 QDF_STATUS status; 5075 enum QDF_OPMODE opmode; 5076 struct rso_config *rso_cfg; 5077 5078 opmode = wlan_vdev_mlme_get_opmode(vdev); 5079 rso_cfg = wlan_cm_get_rso_config(vdev); 5080 if (!rso_cfg) 5081 return; 5082 5083 if (!rso_cfg->is_ese_assoc || opmode != QDF_STA_MODE) 5084 return; 5085 status = wlan_vdev_mlme_get_ssid(vdev, ssid.ssid, &ssid.length); 5086 if (QDF_IS_STATUS_ERROR(status)) { 5087 sme_err(" failed to find SSID for vdev %d", session->vdev_id); 5088 return; 5089 } 5090 session->isPrevApInfoValid = true; 5091 session->roamTS1 = qdf_mc_timer_get_system_time(); 5092 } 5093 #endif 5094 5095 #ifdef WLAN_FEATURE_FILS_SK 5096 static QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev, 5097 struct bss_description *bss_desc, 5098 struct wlan_cm_vdev_connect_req *req) 5099 { 5100 uint8_t cache_id[CACHE_ID_LEN] = {0}; 5101 struct scan_cache_entry *entry; 5102 struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa; 5103 5104 if (!req->fils_info || !req->fils_info->is_fils_connection) { 5105 wlan_cm_update_mlme_fils_info(vdev, NULL); 5106 return QDF_STATUS_SUCCESS; 5107 } 5108 5109 if (bss_desc->fils_info_element.is_cache_id_present) { 5110 qdf_mem_copy(cache_id, bss_desc->fils_info_element.cache_id, 5111 CACHE_ID_LEN); 5112 sme_debug("FILS_PMKSA: cache_id[0]:%d, cache_id[1]:%d", 5113 cache_id[0], cache_id[1]); 5114 } 5115 entry = req->bss->entry; 5116 bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, &entry->bssid); 5117 fils_ssid_pmksa = 5118 wlan_crypto_get_fils_pmksa(vdev, cache_id, 5119 entry->ssid.ssid, 5120 entry->ssid.length); 5121 5122 if ((!req->fils_info->rrk_len || 5123 !req->fils_info->username_len) && 5124 !bss_desc->fils_info_element.is_cache_id_present && 5125 !bssid_lookup_pmksa && !fils_ssid_pmksa) 5126 return QDF_STATUS_E_FAILURE; 5127 5128 return wlan_cm_update_mlme_fils_info(vdev, req->fils_info); 5129 } 5130 #else 5131 static inline 5132 QDF_STATUS csr_cm_update_fils_info(struct wlan_objmgr_vdev *vdev, 5133 struct bss_description *bss_desc, 5134 struct wlan_cm_vdev_connect_req *req) 5135 { 5136 } 5137 #endif 5138 5139 #if defined(WLAN_FEATURE_HOST_ROAM) && defined(FEATURE_WLAN_ESE) 5140 static void csr_update_tspec_info(struct mac_context *mac_ctx, 5141 struct wlan_objmgr_vdev *vdev, 5142 tDot11fBeaconIEs *ie_struct) 5143 { 5144 struct mlme_legacy_priv *mlme_priv; 5145 tESETspecInfo *ese_tspec; 5146 5147 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 5148 if (!mlme_priv) 5149 return; 5150 if (!cm_is_ese_connection(vdev, ie_struct->ESEVersion.present)) 5151 return; 5152 5153 ese_tspec = &mlme_priv->connect_info.ese_tspec_info; 5154 qdf_mem_zero(ese_tspec, sizeof(tESETspecInfo)); 5155 ese_tspec->numTspecs = sme_qos_ese_retrieve_tspec_info(mac_ctx, 5156 wlan_vdev_get_id(vdev), 5157 ese_tspec->tspec); 5158 } 5159 #else 5160 static inline void csr_update_tspec_info(struct mac_context *mac_ctx, 5161 struct wlan_objmgr_vdev *vdev, 5162 tDot11fBeaconIEs *ie_struct) {} 5163 #endif 5164 5165 void cm_csr_send_set_ie(struct wlan_objmgr_vdev *vdev) 5166 { 5167 struct vdev_mlme_obj *vdev_mlme; 5168 5169 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 5170 if (!vdev_mlme) { 5171 sme_err("Failed to get vdev mlme obj!"); 5172 QDF_BUG(0); 5173 return; 5174 } 5175 5176 csr_send_set_ie(vdev_mlme->mgmt.generic.type, 5177 vdev_mlme->mgmt.generic.subtype, 5178 wlan_vdev_get_id(vdev)); 5179 } 5180 5181 QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev, 5182 struct wlan_cm_vdev_connect_req *req, 5183 struct cm_vdev_join_req *join_req, 5184 bool reassoc) 5185 { 5186 struct mac_context *mac_ctx; 5187 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5188 QDF_STATUS status; 5189 tDot11fBeaconIEs *ie_struct; 5190 struct bss_description *bss_desc; 5191 uint32_t ie_len, bss_len; 5192 5193 /* 5194 * This API is to update legacy struct and should be removed once 5195 * CSR is cleaned up fully. No new params should be added to CSR, use 5196 * vdev/pdev/psoc instead 5197 */ 5198 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5199 if (!mac_ctx) 5200 return QDF_STATUS_E_INVAL; 5201 5202 ie_len = util_scan_entry_ie_len(join_req->entry); 5203 bss_len = (uint16_t)(offsetof(struct bss_description, 5204 ieFields[0]) + ie_len); 5205 5206 bss_desc = qdf_mem_malloc(sizeof(*bss_desc) + bss_len); 5207 if (!bss_desc) 5208 return QDF_STATUS_E_NOMEM; 5209 5210 status = wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, 5211 join_req->entry); 5212 if (QDF_IS_STATUS_ERROR(status)) { 5213 qdf_mem_free(bss_desc); 5214 return QDF_STATUS_E_FAILURE; 5215 } 5216 5217 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc, 5218 &ie_struct); 5219 if (QDF_IS_STATUS_ERROR(status)) { 5220 sme_err("IE parsing failed vdev id %d", vdev_id); 5221 qdf_mem_free(bss_desc); 5222 return QDF_STATUS_E_FAILURE; 5223 } 5224 5225 if (reassoc) { 5226 csr_update_tspec_info(mac_ctx, vdev, ie_struct); 5227 } else { 5228 status = csr_cm_update_fils_info(vdev, bss_desc, req); 5229 if (QDF_IS_STATUS_ERROR(status)) { 5230 sme_err("failed to update fils info vdev id %d", 5231 vdev_id); 5232 qdf_mem_free(ie_struct); 5233 qdf_mem_free(bss_desc); 5234 return QDF_STATUS_E_FAILURE; 5235 } 5236 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5237 SME_QOS_CSR_JOIN_REQ, NULL); 5238 } 5239 5240 if ((wlan_reg_11d_enabled_on_host(mac_ctx->psoc)) && 5241 !ie_struct->Country.present) 5242 csr_apply_channel_power_info_wrapper(mac_ctx); 5243 5244 qdf_mem_free(ie_struct); 5245 qdf_mem_free(bss_desc); 5246 5247 cm_csr_set_joining(vdev_id); 5248 5249 return QDF_STATUS_SUCCESS; 5250 } 5251 5252 #ifdef FEATURE_WLAN_ESE 5253 static uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp) 5254 { 5255 return rsp->tspec_ie.len; 5256 } 5257 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session, 5258 uint8_t *frame_ptr, 5259 struct cm_vdev_join_rsp *rsp) 5260 { 5261 session->connectedInfo.nTspecIeLength = rsp->tspec_ie.len; 5262 if (rsp->tspec_ie.len) 5263 qdf_mem_copy(frame_ptr, rsp->tspec_ie.ptr, 5264 rsp->tspec_ie.len); 5265 } 5266 5267 #else 5268 static inline uint32_t csr_get_tspec_ie_len(struct cm_vdev_join_rsp *rsp) 5269 { 5270 return 0; 5271 } 5272 static inline void csr_copy_tspec_ie_len(struct csr_roam_session *session, 5273 uint8_t *frame_ptr, 5274 struct cm_vdev_join_rsp *rsp) 5275 {} 5276 #endif 5277 5278 static void csr_fill_connected_info(struct mac_context *mac_ctx, 5279 struct csr_roam_session *session, 5280 struct cm_vdev_join_rsp *rsp) 5281 { 5282 uint32_t len; 5283 struct wlan_connect_rsp_ies *connect_ies; 5284 uint8_t *frame_ptr; 5285 uint32_t beacon_data_len = 0; 5286 5287 connect_ies = &rsp->connect_rsp.connect_ies; 5288 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 5289 if (connect_ies->bcn_probe_rsp.len > sizeof(struct wlan_frame_hdr)) 5290 beacon_data_len = connect_ies->bcn_probe_rsp.len - 5291 sizeof(struct wlan_frame_hdr); 5292 len = beacon_data_len + connect_ies->assoc_req.len + 5293 connect_ies->assoc_rsp.len + rsp->ric_resp_ie.len + 5294 csr_get_tspec_ie_len(rsp); 5295 if (!len) 5296 return; 5297 5298 session->connectedInfo.pbFrames = qdf_mem_malloc(len); 5299 if (!session->connectedInfo.pbFrames) 5300 return; 5301 5302 frame_ptr = session->connectedInfo.pbFrames; 5303 session->connectedInfo.nBeaconLength = beacon_data_len; 5304 if (beacon_data_len) 5305 qdf_mem_copy(frame_ptr, 5306 connect_ies->bcn_probe_rsp.ptr + 5307 sizeof(struct wlan_frame_hdr), 5308 beacon_data_len); 5309 frame_ptr += beacon_data_len; 5310 5311 session->connectedInfo.nAssocReqLength = connect_ies->assoc_req.len; 5312 if (connect_ies->assoc_req.len) 5313 qdf_mem_copy(frame_ptr, 5314 connect_ies->assoc_req.ptr, 5315 connect_ies->assoc_req.len); 5316 frame_ptr += connect_ies->assoc_req.len; 5317 5318 session->connectedInfo.nAssocRspLength = connect_ies->assoc_rsp.len; 5319 if (connect_ies->assoc_rsp.len) 5320 qdf_mem_copy(frame_ptr, 5321 connect_ies->assoc_rsp.ptr, 5322 connect_ies->assoc_rsp.len); 5323 frame_ptr += connect_ies->assoc_rsp.len; 5324 5325 session->connectedInfo.nRICRspLength = rsp->ric_resp_ie.len; 5326 if (rsp->ric_resp_ie.len) 5327 qdf_mem_copy(frame_ptr, rsp->ric_resp_ie.ptr, 5328 rsp->ric_resp_ie.len); 5329 frame_ptr += rsp->ric_resp_ie.len; 5330 5331 csr_copy_tspec_ie_len(session, frame_ptr, rsp); 5332 } 5333 5334 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 5335 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx, 5336 uint8_t vdev_id) 5337 { 5338 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_DISCONNECT_IND, 5339 NULL); 5340 } 5341 5342 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx, 5343 uint8_t vdev_id, 5344 sme_QosAssocInfo *assoc_info) 5345 { 5346 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_ASSOC_COMPLETE, 5347 assoc_info); 5348 } 5349 5350 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 5351 static void 5352 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx, 5353 struct wlan_cm_connect_resp *connect_rsp) 5354 { 5355 if (IS_ROAM_REASON_DISCONNECTION( 5356 connect_rsp->roaming_info->roam_reason)) 5357 sme_qos_csr_event_ind(mac_ctx, connect_rsp->vdev_id, 5358 SME_QOS_CSR_DISCONNECT_ROAM_COMPLETE, 5359 NULL); 5360 } 5361 #else 5362 static inline void 5363 csr_qso_disconnect_complete_ind(struct mac_context *mac_ctx, 5364 struct wlan_cm_connect_resp *connect_rsp) {} 5365 #endif 5366 5367 static void 5368 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx, 5369 uint8_t vdev_id, 5370 sme_QosAssocInfo *assoc_info, 5371 struct wlan_cm_connect_resp *connect_rsp) 5372 { 5373 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_ASSOC_REQ, 5374 NULL); 5375 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_REQ, 5376 NULL); 5377 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_HANDOFF_COMPLETE, 5378 NULL); 5379 sme_qos_csr_event_ind(mac_ctx, vdev_id, SME_QOS_CSR_REASSOC_COMPLETE, 5380 assoc_info); 5381 5382 csr_qso_disconnect_complete_ind(mac_ctx, connect_rsp); 5383 } 5384 #else 5385 static inline void csr_qos_send_disconnect_ind(struct mac_context *mac_ctx, 5386 uint8_t vdev_id) 5387 {} 5388 5389 static inline void csr_qos_send_assoc_ind(struct mac_context *mac_ctx, 5390 uint8_t vdev_id, 5391 sme_QosAssocInfo *assoc_info) 5392 {} 5393 static inline void 5394 csr_qos_send_reassoc_ind(struct mac_context *mac_ctx, 5395 uint8_t vdev_id, 5396 sme_QosAssocInfo *assoc_info, 5397 struct wlan_cm_connect_resp *connect_rsp) 5398 {} 5399 #endif 5400 5401 static void 5402 csr_update_beacon_in_connect_rsp(struct scan_cache_entry *entry, 5403 struct wlan_connect_rsp_ies *connect_ies) 5404 { 5405 if (!entry) 5406 return; 5407 5408 /* no need to update if already present */ 5409 if (connect_ies->bcn_probe_rsp.ptr) 5410 return; 5411 5412 /* 5413 * In case connection to MBSSID: Non Tx BSS OR host reassoc, 5414 * vdev/peer manager doesn't send unicast probe req so fill the 5415 * beacon in connect resp IEs here. 5416 */ 5417 connect_ies->bcn_probe_rsp.len = 5418 util_scan_entry_frame_len(entry); 5419 connect_ies->bcn_probe_rsp.ptr = 5420 qdf_mem_malloc(connect_ies->bcn_probe_rsp.len); 5421 if (!connect_ies->bcn_probe_rsp.ptr) 5422 return; 5423 5424 qdf_mem_copy(connect_ies->bcn_probe_rsp.ptr, 5425 util_scan_entry_frame_ptr(entry), 5426 connect_ies->bcn_probe_rsp.len); 5427 } 5428 5429 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE 5430 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev) 5431 { 5432 return mlo_mgr_is_link_switch_in_progress(vdev); 5433 } 5434 #else 5435 static bool csr_is_link_switch_in_progress(struct wlan_objmgr_vdev *vdev) 5436 { 5437 return false; 5438 } 5439 #endif 5440 5441 static void csr_fill_connected_profile(struct mac_context *mac_ctx, 5442 struct csr_roam_session *session, 5443 struct wlan_objmgr_vdev *vdev, 5444 struct cm_vdev_join_rsp *rsp) 5445 { 5446 struct scan_filter *filter; 5447 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5448 QDF_STATUS status; 5449 qdf_list_t *list = NULL; 5450 qdf_list_node_t *cur_lst = NULL; 5451 struct scan_cache_node *cur_node = NULL; 5452 uint32_t bss_len, ie_len; 5453 struct bss_description *bss_desc = NULL; 5454 tDot11fBeaconIEs *bcn_ies; 5455 sme_QosAssocInfo assoc_info; 5456 struct cm_roam_values_copy src_cfg = {}; 5457 bool is_ese = false; 5458 uint8_t country_code[REG_ALPHA2_LEN + 1]; 5459 5460 session->modifyProfileFields.uapsd_mask = rsp->uapsd_mask; 5461 filter = qdf_mem_malloc(sizeof(*filter)); 5462 if (!filter) 5463 return; 5464 5465 filter->num_of_bssid = 1; 5466 qdf_copy_macaddr(&filter->bssid_list[0], &rsp->connect_rsp.bssid); 5467 filter->ignore_auth_enc_type = true; 5468 5469 status = wlan_vdev_mlme_get_ssid(vdev, filter->ssid_list[0].ssid, 5470 &filter->ssid_list[0].length); 5471 if (QDF_IS_STATUS_SUCCESS(status)) 5472 filter->num_of_ssid = 1; 5473 5474 list = wlan_scan_get_result(mac_ctx->pdev, filter); 5475 qdf_mem_free(filter); 5476 if (!list || (list && !qdf_list_size(list))) 5477 goto purge_list; 5478 5479 5480 qdf_list_peek_front(list, &cur_lst); 5481 if (!cur_lst) 5482 goto purge_list; 5483 5484 cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node); 5485 ie_len = util_scan_entry_ie_len(cur_node->entry); 5486 bss_len = (uint16_t)(offsetof(struct bss_description, 5487 ieFields[0]) + ie_len); 5488 bss_desc = qdf_mem_malloc(bss_len); 5489 if (!bss_desc) 5490 goto purge_list; 5491 5492 wlan_fill_bss_desc_from_scan_entry(mac_ctx, bss_desc, cur_node->entry); 5493 pe_debug("Dump scan entry frm:"); 5494 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, 5495 cur_node->entry->raw_frame.ptr, 5496 cur_node->entry->raw_frame.len); 5497 5498 src_cfg.uint_value = bss_desc->mbo_oce_enabled_ap; 5499 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, MBO_OCE_ENABLED_AP, 5500 &src_cfg); 5501 csr_fill_single_pmk(mac_ctx->psoc, vdev_id, bss_desc); 5502 status = wlan_get_parsed_bss_description_ies(mac_ctx, bss_desc, 5503 &bcn_ies); 5504 if (QDF_IS_STATUS_ERROR(status)) 5505 goto purge_list; 5506 5507 if (!bss_desc->beaconInterval) 5508 sme_err("ERROR: Beacon interval is ZERO"); 5509 5510 csr_update_beacon_in_connect_rsp(cur_node->entry, 5511 &rsp->connect_rsp.connect_ies); 5512 5513 assoc_info.bss_desc = bss_desc; 5514 if (rsp->connect_rsp.is_reassoc) { 5515 if (cm_is_ese_connection(vdev, bcn_ies->ESEVersion.present)) 5516 is_ese = true; 5517 wlan_cm_set_ese_assoc(mac_ctx->pdev, vdev_id, is_ese); 5518 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, UAPSD_MASK, 5519 &src_cfg); 5520 assoc_info.uapsd_mask = src_cfg.uint_value; 5521 csr_qos_send_reassoc_ind(mac_ctx, vdev_id, &assoc_info, 5522 &rsp->connect_rsp); 5523 if (src_cfg.uint_value) 5524 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id); 5525 } else { 5526 assoc_info.uapsd_mask = rsp->uapsd_mask; 5527 csr_qos_send_assoc_ind(mac_ctx, vdev_id, &assoc_info); 5528 } 5529 5530 if (rsp->connect_rsp.is_reassoc || 5531 csr_is_link_switch_in_progress(vdev)) 5532 mlme_set_mbssid_info(vdev, &cur_node->entry->mbssid_info, 5533 bss_desc->chan_freq); 5534 5535 if (bcn_ies->Country.present) 5536 qdf_mem_copy(country_code, bcn_ies->Country.country, 5537 REG_ALPHA2_LEN + 1); 5538 else 5539 qdf_mem_zero(country_code, REG_ALPHA2_LEN + 1); 5540 wlan_cm_set_country_code(mac_ctx->pdev, vdev_id, country_code); 5541 5542 qdf_mem_free(bcn_ies); 5543 5544 purge_list: 5545 if (bss_desc) 5546 qdf_mem_free(bss_desc); 5547 if (list) 5548 wlan_scan_purge_results(list); 5549 5550 } 5551 5552 QDF_STATUS cm_csr_connect_rsp(struct wlan_objmgr_vdev *vdev, 5553 struct cm_vdev_join_rsp *rsp) 5554 { 5555 struct mac_context *mac_ctx; 5556 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5557 struct csr_roam_session *session; 5558 struct cm_roam_values_copy src_config = {}; 5559 5560 /* 5561 * This API is to update legacy struct and should be removed once 5562 * CSR is cleaned up fully. No new params should be added to CSR, use 5563 * vdev/pdev/psoc instead 5564 */ 5565 if (QDF_IS_STATUS_ERROR(rsp->connect_rsp.connect_status)) 5566 return QDF_STATUS_SUCCESS; 5567 5568 /* handle below only in case of success */ 5569 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5570 if (!mac_ctx) 5571 return QDF_STATUS_E_INVAL; 5572 5573 session = CSR_GET_SESSION(mac_ctx, vdev_id); 5574 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 5575 sme_err("session not found for vdev_id %d", vdev_id); 5576 return QDF_STATUS_E_INVAL; 5577 } 5578 5579 if (!rsp->connect_rsp.is_reassoc) { 5580 if (rsp->uapsd_mask) 5581 sme_ps_start_uapsd(MAC_HANDLE(mac_ctx), vdev_id); 5582 src_config.uint_value = rsp->uapsd_mask; 5583 wlan_cm_roam_cfg_set_value(mac_ctx->psoc, vdev_id, UAPSD_MASK, 5584 &src_config); 5585 } 5586 session->nss = rsp->nss; 5587 csr_fill_connected_info(mac_ctx, session, rsp); 5588 csr_fill_connected_profile(mac_ctx, session, vdev, rsp); 5589 5590 return QDF_STATUS_SUCCESS; 5591 } 5592 5593 static void 5594 cm_update_rsn_ocv_cap(int32_t *rsn_cap, 5595 struct wlan_cm_connect_resp *rsp) 5596 { 5597 struct wlan_crypto_params crypto_params; 5598 uint8_t *ie_ptr; 5599 uint32_t ie_len; 5600 QDF_STATUS status; 5601 5602 /* no need to do anything if OCV is not set */ 5603 if (!(*rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) 5604 return; 5605 5606 if (!rsp->connect_ies.bcn_probe_rsp.ptr || 5607 !rsp->connect_ies.bcn_probe_rsp.len || 5608 (rsp->connect_ies.bcn_probe_rsp.len < 5609 (sizeof(struct wlan_frame_hdr) + 5610 offsetof(struct wlan_bcn_frame, ie)))) { 5611 sme_err("invalid beacon probe rsp len %d", 5612 rsp->connect_ies.bcn_probe_rsp.len); 5613 return; 5614 } 5615 5616 ie_len = (rsp->connect_ies.bcn_probe_rsp.len - 5617 sizeof(struct wlan_frame_hdr) - 5618 offsetof(struct wlan_bcn_frame, ie)); 5619 ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr + 5620 sizeof(struct wlan_frame_hdr) + 5621 offsetof(struct wlan_bcn_frame, ie)); 5622 5623 status = wlan_get_crypto_params_from_rsn_ie(&crypto_params, ie_ptr, 5624 ie_len); 5625 if (QDF_IS_STATUS_ERROR(status)) 5626 return; 5627 5628 if (!(crypto_params.rsn_caps & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) 5629 *rsn_cap &= ~WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED; 5630 } 5631 5632 QDF_STATUS 5633 cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev, 5634 struct wlan_cm_connect_resp *rsp) 5635 { 5636 mac_handle_t mac_handle; 5637 struct mac_context *mac_ctx; 5638 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5639 int32_t count; 5640 struct set_context_rsp install_key_rsp; 5641 int32_t rsn_cap, set_value; 5642 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5643 struct dual_sta_policy *dual_sta_policy; 5644 bool enable_mcc_adaptive_sch = false; 5645 struct qdf_mac_addr bc_mac = QDF_MAC_ADDR_BCAST_INIT; 5646 5647 /* 5648 * This API is to update legacy struct and should be removed once 5649 * CSR is cleaned up fully. No new params should be added to CSR, use 5650 * vdev/pdev/psoc instead 5651 */ 5652 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5653 5654 mac_ctx = MAC_CONTEXT(mac_handle); 5655 if (!mac_ctx) 5656 return QDF_STATUS_E_INVAL; 5657 5658 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 5659 if (!mlme_obj) 5660 return QDF_STATUS_E_INVAL; 5661 5662 if (QDF_IS_STATUS_ERROR(rsp->connect_status)) { 5663 cm_csr_set_idle(vdev_id); 5664 sme_qos_update_hand_off(vdev_id, false); 5665 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5666 SME_QOS_CSR_DISCONNECT_IND, NULL); 5667 /* Fill legacy structures from resp for failure */ 5668 5669 return QDF_STATUS_SUCCESS; 5670 } 5671 5672 dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; 5673 count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc, 5674 PM_STA_MODE, NULL); 5675 /* 5676 * send duty cycle percentage to FW only if STA + STA 5677 * concurrency is in MCC. 5678 */ 5679 sme_debug("Current iface vdev_id:%d, Primary vdev_id:%d, Dual sta policy:%d, count:%d", 5680 vdev_id, dual_sta_policy->primary_vdev_id, 5681 dual_sta_policy->concurrent_sta_policy, count); 5682 5683 if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX && 5684 dual_sta_policy->concurrent_sta_policy == 5685 QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 && 5686 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) { 5687 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc, 5688 &enable_mcc_adaptive_sch); 5689 if (enable_mcc_adaptive_sch) { 5690 sme_debug("Disable mcc_adaptive_scheduler"); 5691 policy_mgr_set_dynamic_mcc_adaptive_sch( 5692 mac_ctx->psoc, false); 5693 if (QDF_STATUS_SUCCESS != sme_set_mas(false)) { 5694 sme_err("Failed to disable mcc_adaptive_sched"); 5695 return -EAGAIN; 5696 } 5697 } 5698 set_value = 5699 wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev); 5700 sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA, 5701 set_value, VDEV_CMD); 5702 } else if (dual_sta_policy->concurrent_sta_policy == 5703 QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED && count == 2 && 5704 policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) { 5705 policy_mgr_get_mcc_adaptive_sch(mac_ctx->psoc, 5706 &enable_mcc_adaptive_sch); 5707 if (enable_mcc_adaptive_sch) { 5708 sme_debug("Enable mcc_adaptive_scheduler"); 5709 policy_mgr_set_dynamic_mcc_adaptive_sch( 5710 mac_ctx->psoc, true); 5711 if (QDF_STATUS_SUCCESS != sme_set_mas(true)) { 5712 sme_err("Failed to enable mcc_adaptive_sched"); 5713 return -EAGAIN; 5714 } 5715 } 5716 } else { 5717 QDF_STATUS status = QDF_STATUS_SUCCESS; 5718 uint32_t quota_val; 5719 5720 quota_val = 5721 ucfg_mlme_get_user_mcc_quota_percentage(mac_ctx->psoc); 5722 5723 if (quota_val) { 5724 if (enable_mcc_adaptive_sch) { 5725 policy_mgr_set_dynamic_mcc_adaptive_sch( 5726 mac_ctx->psoc, false); 5727 status = sme_set_mas(false); 5728 } 5729 if (status == QDF_STATUS_SUCCESS) 5730 sme_cli_set_command(wlan_vdev_get_id(vdev), 5731 WMA_VDEV_MCC_SET_TIME_QUOTA, 5732 quota_val, VDEV_CMD); 5733 } else { 5734 sme_debug("no applicable user mcc/quota"); 5735 } 5736 } 5737 5738 /* 5739 * For open mode authentication, send dummy install key response to 5740 * send OBSS scan and QOS event. 5741 */ 5742 if (!rsp->is_wps_connection && cm_is_open_mode(vdev)) { 5743 install_key_rsp.length = sizeof(install_key_rsp); 5744 install_key_rsp.status_code = eSIR_SME_SUCCESS; 5745 install_key_rsp.sessionId = vdev_id; 5746 /* use BC mac to enable OBSS scan */ 5747 qdf_copy_macaddr(&install_key_rsp.peer_macaddr, &bc_mac); 5748 csr_roam_chk_lnk_set_ctx_rsp(mac_ctx, 5749 (tSirSmeRsp *)&install_key_rsp); 5750 } 5751 5752 rsn_cap = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP); 5753 if (rsn_cap >= 0) { 5754 cm_update_rsn_ocv_cap(&rsn_cap, rsp); 5755 if (wma_cli_set2_command(vdev_id, wmi_vdev_param_rsn_capability, 5756 rsn_cap, 0, VDEV_CMD)) 5757 sme_err("Failed to update wmi_vdev_param_rsn_capability for vdev id %d", 5758 vdev_id); 5759 } 5760 5761 /* 5762 * Update the IEs after connection to reconfigure 5763 * any capability that changed during connection. 5764 */ 5765 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) 5766 sme_set_vdev_ies_per_band(mac_handle, vdev_id, 5767 wlan_vdev_mlme_get_opmode(vdev)); 5768 5769 return QDF_STATUS_SUCCESS; 5770 } 5771 5772 QDF_STATUS cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev *vdev, 5773 struct wlan_cm_vdev_discon_req *req) 5774 { 5775 struct mac_context *mac_ctx; 5776 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5777 struct csr_roam_session *session; 5778 5779 /* 5780 * This API is to update legacy struct and should be removed once 5781 * CSR is cleaned up fully. No new params should be added to CSR, use 5782 * vdev/pdev/psoc instead 5783 */ 5784 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5785 if (!mac_ctx) 5786 return QDF_STATUS_E_INVAL; 5787 5788 session = CSR_GET_SESSION(mac_ctx, vdev_id); 5789 if (!session || !CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 5790 sme_err("session not found for vdev_id %d", vdev_id); 5791 return QDF_STATUS_E_INVAL; 5792 } 5793 5794 cm_csr_set_joining(vdev_id); 5795 5796 /* Update the disconnect stats */ 5797 session->disconnect_stats.disconnection_cnt++; 5798 if (req->req.source == CM_PEER_DISCONNECT) { 5799 session->disconnect_stats.disassoc_by_peer++; 5800 } else if (req->req.source == CM_SB_DISCONNECT) { 5801 switch (req->req.reason_code) { 5802 case REASON_DISASSOC_DUE_TO_INACTIVITY: 5803 session->disconnect_stats.peer_kickout++; 5804 break; 5805 case REASON_BEACON_MISSED: 5806 session->disconnect_stats.bmiss++; 5807 break; 5808 default: 5809 /* Unknown reason code */ 5810 break; 5811 } 5812 } else if (req->req.source == CM_MLO_LINK_SWITCH_DISCONNECT) { 5813 /* Do not update any stats as session is going to be deleted*/ 5814 } else { 5815 session->disconnect_stats.disconnection_by_app++; 5816 } 5817 5818 csr_update_prev_ap_info(session, vdev); 5819 csr_qos_send_disconnect_ind(mac_ctx, vdev_id); 5820 5821 return QDF_STATUS_SUCCESS; 5822 } 5823 5824 QDF_STATUS 5825 cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev, 5826 struct wlan_cm_discon_rsp *rsp) 5827 { 5828 mac_handle_t mac_handle; 5829 struct mac_context *mac_ctx; 5830 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5831 struct wlan_mlme_psoc_ext_obj *mlme_obj; 5832 5833 /* 5834 * This API is to update legacy struct and should be removed once 5835 * CSR is cleaned up fully. No new params should be added to CSR, use 5836 * vdev/pdev/psoc instead 5837 */ 5838 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5839 5840 mac_ctx = MAC_CONTEXT(mac_handle); 5841 if (!mac_ctx) 5842 return QDF_STATUS_E_INVAL; 5843 5844 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 5845 if (!mlme_obj) 5846 return QDF_STATUS_E_INVAL; 5847 5848 cm_csr_set_idle(vdev_id); 5849 if (cm_is_vdev_roaming(vdev)) 5850 sme_qos_update_hand_off(vdev_id, false); 5851 csr_set_default_dot11_mode(mac_ctx); 5852 5853 /* 5854 * Update the IEs after disconnection to remove 5855 * any connection specific capability change and 5856 * to reset back to self cap 5857 */ 5858 if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) { 5859 wlan_cm_set_force_20mhz_in_24ghz(vdev, true); 5860 sme_set_vdev_ies_per_band(mac_handle, vdev_id, 5861 wlan_vdev_mlme_get_opmode(vdev)); 5862 } 5863 5864 return QDF_STATUS_SUCCESS; 5865 } 5866 5867 #ifdef WLAN_FEATURE_HOST_ROAM 5868 void cm_csr_preauth_done(struct wlan_objmgr_vdev *vdev) 5869 { 5870 struct mac_context *mac_ctx; 5871 uint8_t vdev_id = wlan_vdev_get_id(vdev); 5872 struct cm_roam_values_copy config; 5873 bool is_11r; 5874 5875 /* 5876 * This API is to update legacy struct and should be removed once 5877 * CSR is cleaned up fully. No new params should be added to CSR, use 5878 * vdev/pdev/psoc instead 5879 */ 5880 mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 5881 if (!mac_ctx) { 5882 sme_err("mac_ctx is NULL"); 5883 return; 5884 } 5885 5886 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, vdev_id, IS_11R_CONNECTION, 5887 &config); 5888 is_11r = config.bool_value; 5889 if (is_11r || wlan_cm_get_ese_assoc(mac_ctx->pdev, vdev_id)) 5890 sme_qos_csr_event_ind(mac_ctx, vdev_id, 5891 SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL); 5892 } 5893 #endif 5894 5895 /* */ 5896 QDF_STATUS csr_send_mb_disassoc_req_msg(struct mac_context *mac, 5897 uint32_t sessionId, 5898 tSirMacAddr bssId, uint16_t reasonCode) 5899 { 5900 struct disassoc_req *pMsg; 5901 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5902 5903 if (!CSR_IS_SESSION_VALID(mac, sessionId)) 5904 return QDF_STATUS_E_FAILURE; 5905 5906 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 5907 if (!pMsg) 5908 return QDF_STATUS_E_NOMEM; 5909 5910 pMsg->messageType = eWNI_SME_DISASSOC_REQ; 5911 pMsg->length = sizeof(*pMsg); 5912 pMsg->sessionId = sessionId; 5913 5914 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid); 5915 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE); 5916 pMsg->reasonCode = reasonCode; 5917 5918 /* Update the disconnect stats */ 5919 pSession->disconnect_stats.disconnection_cnt++; 5920 pSession->disconnect_stats.disconnection_by_app++; 5921 5922 return umac_send_mb_message_to_mac(pMsg); 5923 } 5924 5925 QDF_STATUS csr_send_chng_mcc_beacon_interval(struct mac_context *mac, 5926 uint32_t sessionId) 5927 { 5928 struct wlan_change_bi *pMsg; 5929 uint16_t len = 0; 5930 QDF_STATUS status = QDF_STATUS_SUCCESS; 5931 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5932 5933 if (!pSession) { 5934 sme_err("session %d not found", sessionId); 5935 return QDF_STATUS_E_FAILURE; 5936 } 5937 /* NO need to update the Beacon Params if update beacon parameter flag 5938 * is not set 5939 */ 5940 if (!mac->roam.roamSession[sessionId].update_bcn_int) 5941 return QDF_STATUS_SUCCESS; 5942 5943 mac->roam.roamSession[sessionId].update_bcn_int = 5944 false; 5945 5946 /* Create the message and send to lim */ 5947 len = sizeof(*pMsg); 5948 pMsg = qdf_mem_malloc(len); 5949 if (!pMsg) 5950 status = QDF_STATUS_E_NOMEM; 5951 else 5952 status = QDF_STATUS_SUCCESS; 5953 if (QDF_IS_STATUS_SUCCESS(status)) { 5954 pMsg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL; 5955 pMsg->length = len; 5956 5957 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, 5958 &pMsg->bssid); 5959 sme_debug("CSR Attempting to change BI for Bssid= " 5960 QDF_MAC_ADDR_FMT, 5961 QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); 5962 pMsg->session_id = sessionId; 5963 sme_debug("session %d BeaconInterval %d", 5964 sessionId, 5965 mac->roam.roamSession[sessionId].bcn_int); 5966 pMsg->beacon_interval = 5967 mac->roam.roamSession[sessionId].bcn_int; 5968 status = umac_send_mb_message_to_mac(pMsg); 5969 } 5970 return status; 5971 } 5972 5973 #ifdef QCA_HT_2040_COEX 5974 QDF_STATUS csr_set_ht2040_mode(struct mac_context *mac, uint32_t sessionId, 5975 ePhyChanBondState cbMode, bool obssEnabled) 5976 { 5977 struct set_ht2040_mode *pMsg; 5978 uint16_t len = 0; 5979 QDF_STATUS status = QDF_STATUS_SUCCESS; 5980 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 5981 5982 if (!pSession) { 5983 sme_err("session %d not found", sessionId); 5984 return QDF_STATUS_E_FAILURE; 5985 } 5986 5987 /* Create the message and send to lim */ 5988 len = sizeof(struct set_ht2040_mode); 5989 pMsg = qdf_mem_malloc(len); 5990 if (!pMsg) 5991 status = QDF_STATUS_E_NOMEM; 5992 else 5993 status = QDF_STATUS_SUCCESS; 5994 if (QDF_IS_STATUS_SUCCESS(status)) { 5995 qdf_mem_zero(pMsg, sizeof(struct set_ht2040_mode)); 5996 pMsg->messageType = eWNI_SME_SET_HT_2040_MODE; 5997 pMsg->length = len; 5998 5999 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, &pMsg->bssid); 6000 sme_debug( 6001 "CSR Attempting to set HT20/40 mode for Bssid= " 6002 QDF_MAC_ADDR_FMT, 6003 QDF_MAC_ADDR_REF(pMsg->bssid.bytes)); 6004 pMsg->sessionId = sessionId; 6005 sme_debug(" session %d HT20/40 mode %d", 6006 sessionId, cbMode); 6007 pMsg->cbMode = cbMode; 6008 pMsg->obssEnabled = obssEnabled; 6009 status = umac_send_mb_message_to_mac(pMsg); 6010 } 6011 return status; 6012 } 6013 #endif 6014 6015 QDF_STATUS csr_send_mb_deauth_req_msg(struct mac_context *mac, 6016 uint32_t vdev_id, 6017 tSirMacAddr bssId, uint16_t reasonCode) 6018 { 6019 struct deauth_req *pMsg; 6020 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); 6021 6022 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) 6023 return QDF_STATUS_E_FAILURE; 6024 6025 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6026 if (!pMsg) 6027 return QDF_STATUS_E_NOMEM; 6028 6029 pMsg->messageType = eWNI_SME_DEAUTH_REQ; 6030 pMsg->length = sizeof(*pMsg); 6031 pMsg->vdev_id = vdev_id; 6032 6033 wlan_mlme_get_mac_vdev_id(mac->pdev, vdev_id, &pMsg->bssid); 6034 /* Set the peer MAC address before sending the message to LIM */ 6035 qdf_mem_copy(&pMsg->peer_macaddr.bytes, bssId, QDF_MAC_ADDR_SIZE); 6036 pMsg->reasonCode = reasonCode; 6037 6038 /* Update the disconnect stats */ 6039 pSession->disconnect_stats.disconnection_cnt++; 6040 pSession->disconnect_stats.disconnection_by_app++; 6041 6042 return umac_send_mb_message_to_mac(pMsg); 6043 } 6044 6045 QDF_STATUS csr_send_mb_disassoc_cnf_msg(struct mac_context *mac, 6046 struct disassoc_ind *pDisassocInd) 6047 { 6048 QDF_STATUS status = QDF_STATUS_SUCCESS; 6049 struct disassoc_cnf *pMsg; 6050 6051 do { 6052 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6053 if (!pMsg) 6054 status = QDF_STATUS_E_NOMEM; 6055 else 6056 status = QDF_STATUS_SUCCESS; 6057 if (!QDF_IS_STATUS_SUCCESS(status)) 6058 break; 6059 pMsg->messageType = eWNI_SME_DISASSOC_CNF; 6060 pMsg->status_code = eSIR_SME_SUCCESS; 6061 pMsg->length = sizeof(*pMsg); 6062 pMsg->vdev_id = pDisassocInd->vdev_id; 6063 qdf_copy_macaddr(&pMsg->peer_macaddr, 6064 &pDisassocInd->peer_macaddr); 6065 status = QDF_STATUS_SUCCESS; 6066 if (!QDF_IS_STATUS_SUCCESS(status)) { 6067 qdf_mem_free(pMsg); 6068 break; 6069 } 6070 6071 qdf_copy_macaddr(&pMsg->bssid, &pDisassocInd->bssid); 6072 status = QDF_STATUS_SUCCESS; 6073 if (!QDF_IS_STATUS_SUCCESS(status)) { 6074 qdf_mem_free(pMsg); 6075 break; 6076 } 6077 6078 status = umac_send_mb_message_to_mac(pMsg); 6079 } while (0); 6080 return status; 6081 } 6082 6083 QDF_STATUS csr_send_mb_deauth_cnf_msg(struct mac_context *mac, 6084 struct deauth_ind *pDeauthInd) 6085 { 6086 QDF_STATUS status = QDF_STATUS_SUCCESS; 6087 struct deauth_cnf *pMsg; 6088 6089 do { 6090 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6091 if (!pMsg) 6092 status = QDF_STATUS_E_NOMEM; 6093 else 6094 status = QDF_STATUS_SUCCESS; 6095 if (!QDF_IS_STATUS_SUCCESS(status)) 6096 break; 6097 pMsg->messageType = eWNI_SME_DEAUTH_CNF; 6098 pMsg->status_code = eSIR_SME_SUCCESS; 6099 pMsg->length = sizeof(*pMsg); 6100 pMsg->vdev_id = pDeauthInd->vdev_id; 6101 qdf_copy_macaddr(&pMsg->bssid, &pDeauthInd->bssid); 6102 status = QDF_STATUS_SUCCESS; 6103 if (!QDF_IS_STATUS_SUCCESS(status)) { 6104 qdf_mem_free(pMsg); 6105 break; 6106 } 6107 qdf_copy_macaddr(&pMsg->peer_macaddr, 6108 &pDeauthInd->peer_macaddr); 6109 status = QDF_STATUS_SUCCESS; 6110 if (!QDF_IS_STATUS_SUCCESS(status)) { 6111 qdf_mem_free(pMsg); 6112 break; 6113 } 6114 status = umac_send_mb_message_to_mac(pMsg); 6115 } while (0); 6116 return status; 6117 } 6118 6119 QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac, 6120 struct assoc_ind *pAssocInd, 6121 QDF_STATUS Halstatus, 6122 enum wlan_status_code mac_status_code) 6123 { 6124 QDF_STATUS status = QDF_STATUS_SUCCESS; 6125 struct assoc_cnf *pMsg; 6126 struct scheduler_msg msg = { 0 }; 6127 6128 sme_debug("HalStatus: %d, mac_status_code %d", 6129 Halstatus, mac_status_code); 6130 do { 6131 pMsg = qdf_mem_malloc(sizeof(*pMsg)); 6132 if (!pMsg) 6133 return QDF_STATUS_E_NOMEM; 6134 pMsg->messageType = eWNI_SME_ASSOC_CNF; 6135 pMsg->length = sizeof(*pMsg); 6136 if (QDF_IS_STATUS_SUCCESS(Halstatus)) { 6137 pMsg->status_code = eSIR_SME_SUCCESS; 6138 } else { 6139 pMsg->status_code = eSIR_SME_ASSOC_REFUSED; 6140 pMsg->mac_status_code = mac_status_code; 6141 } 6142 /* bssId */ 6143 qdf_mem_copy(pMsg->bssid.bytes, pAssocInd->bssId, 6144 QDF_MAC_ADDR_SIZE); 6145 /* peerMacAddr */ 6146 qdf_mem_copy(pMsg->peer_macaddr.bytes, pAssocInd->peerMacAddr, 6147 QDF_MAC_ADDR_SIZE); 6148 /* aid */ 6149 pMsg->aid = pAssocInd->aid; 6150 /* OWE IE */ 6151 if (pAssocInd->owe_ie_len) { 6152 pMsg->owe_ie = qdf_mem_malloc(pAssocInd->owe_ie_len); 6153 if (!pMsg->owe_ie) 6154 return QDF_STATUS_E_NOMEM; 6155 qdf_mem_copy(pMsg->owe_ie, pAssocInd->owe_ie, 6156 pAssocInd->owe_ie_len); 6157 pMsg->owe_ie_len = pAssocInd->owe_ie_len; 6158 } 6159 6160 if (pAssocInd->ft_ie_len) { 6161 pMsg->ft_ie = qdf_mem_malloc(pAssocInd->ft_ie_len); 6162 if (!pMsg->ft_ie) 6163 return QDF_STATUS_E_NOMEM; 6164 qdf_mem_copy(pMsg->ft_ie, pAssocInd->ft_ie, 6165 pAssocInd->ft_ie_len); 6166 pMsg->ft_ie_len = pAssocInd->ft_ie_len; 6167 } 6168 pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb; 6169 6170 msg.type = pMsg->messageType; 6171 msg.bodyval = 0; 6172 msg.bodyptr = pMsg; 6173 /* pMsg is freed by umac_send_mb_message_to_mac in anycase*/ 6174 status = scheduler_post_msg_by_priority(QDF_MODULE_ID_PE, &msg, 6175 true); 6176 } while (0); 6177 return status; 6178 } 6179 6180 /** 6181 * csr_store_oce_cfg_flags_in_vdev() - fill OCE flags from ini 6182 * @mac: mac_context. 6183 * @vdev: Pointer to pdev obj 6184 * @vdev_id: vdev_id 6185 * 6186 * This API will store the oce flags in vdev mlme priv object 6187 * 6188 * Return: none 6189 */ 6190 static void csr_store_oce_cfg_flags_in_vdev(struct mac_context *mac, 6191 struct wlan_objmgr_pdev *pdev, 6192 uint8_t vdev_id) 6193 { 6194 uint8_t *vdev_dynamic_oce; 6195 struct wlan_objmgr_vdev *vdev = 6196 wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_LEGACY_MAC_ID); 6197 6198 if (!vdev) 6199 return; 6200 6201 vdev_dynamic_oce = mlme_get_dynamic_oce_flags(vdev); 6202 if (vdev_dynamic_oce) 6203 *vdev_dynamic_oce = mac->mlme_cfg->oce.feature_bitmap; 6204 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 6205 } 6206 6207 void csr_send_set_ie(uint8_t type, uint8_t sub_type, 6208 uint8_t vdev_id) 6209 { 6210 struct send_extcap_ie *msg; 6211 QDF_STATUS status; 6212 6213 sme_debug("send SET IE msg to PE"); 6214 6215 if (!(type == WLAN_VDEV_MLME_TYPE_STA || 6216 (type == WLAN_VDEV_MLME_TYPE_AP && 6217 sub_type == WLAN_VDEV_MLME_SUBTYPE_P2P_DEVICE))) { 6218 sme_debug("Failed to send set IE req for vdev_%d", vdev_id); 6219 return; 6220 } 6221 6222 msg = qdf_mem_malloc(sizeof(*msg)); 6223 if (!msg) 6224 return; 6225 6226 msg->msg_type = eWNI_SME_SET_IE_REQ; 6227 msg->session_id = vdev_id; 6228 msg->length = sizeof(*msg); 6229 status = umac_send_mb_message_to_mac(msg); 6230 if (!QDF_IS_STATUS_SUCCESS(status)) 6231 sme_debug("Failed to send set IE req for vdev_%d", vdev_id); 6232 } 6233 6234 void csr_get_vdev_type_nss(enum QDF_OPMODE dev_mode, uint8_t *nss_2g, 6235 uint8_t *nss_5g) 6236 { 6237 struct mac_context *mac_ctx = sme_get_mac_context(); 6238 6239 if (!mac_ctx) { 6240 sme_err("Invalid MAC context"); 6241 return; 6242 } 6243 6244 switch (dev_mode) { 6245 case QDF_STA_MODE: 6246 *nss_2g = mac_ctx->vdev_type_nss_2g.sta; 6247 *nss_5g = mac_ctx->vdev_type_nss_5g.sta; 6248 break; 6249 case QDF_SAP_MODE: 6250 *nss_2g = mac_ctx->vdev_type_nss_2g.sap; 6251 *nss_5g = mac_ctx->vdev_type_nss_5g.sap; 6252 break; 6253 case QDF_P2P_CLIENT_MODE: 6254 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_cli; 6255 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_cli; 6256 break; 6257 case QDF_P2P_GO_MODE: 6258 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_go; 6259 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_go; 6260 break; 6261 case QDF_P2P_DEVICE_MODE: 6262 *nss_2g = mac_ctx->vdev_type_nss_2g.p2p_dev; 6263 *nss_5g = mac_ctx->vdev_type_nss_5g.p2p_dev; 6264 break; 6265 case QDF_IBSS_MODE: 6266 *nss_2g = mac_ctx->vdev_type_nss_2g.ibss; 6267 *nss_5g = mac_ctx->vdev_type_nss_5g.ibss; 6268 break; 6269 case QDF_OCB_MODE: 6270 *nss_2g = mac_ctx->vdev_type_nss_2g.ocb; 6271 *nss_5g = mac_ctx->vdev_type_nss_5g.ocb; 6272 break; 6273 case QDF_NAN_DISC_MODE: 6274 *nss_2g = mac_ctx->vdev_type_nss_2g.nan; 6275 *nss_5g = mac_ctx->vdev_type_nss_5g.nan; 6276 break; 6277 case QDF_NDI_MODE: 6278 *nss_2g = mac_ctx->vdev_type_nss_2g.ndi; 6279 *nss_5g = mac_ctx->vdev_type_nss_5g.ndi; 6280 break; 6281 default: 6282 *nss_2g = 1; 6283 *nss_5g = 1; 6284 sme_err("Unknown device mode: %d", dev_mode); 6285 break; 6286 } 6287 sme_debug("mode - %d: nss_2g - %d, 5g - %d", 6288 dev_mode, *nss_2g, *nss_5g); 6289 } 6290 6291 QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme) 6292 { 6293 QDF_STATUS status; 6294 uint32_t existing_session_id; 6295 struct csr_roam_session *session; 6296 struct mlme_vht_capabilities_info *vht_cap_info; 6297 u8 vdev_id; 6298 struct qdf_mac_addr *mac_addr; 6299 mac_handle_t mac_handle; 6300 struct mac_context *mac_ctx; 6301 struct wlan_objmgr_vdev *vdev; 6302 struct wlan_vht_config vht_config; 6303 struct wlan_ht_config ht_cap; 6304 6305 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 6306 mac_ctx = MAC_CONTEXT(mac_handle); 6307 if (!mac_ctx) { 6308 QDF_ASSERT(0); 6309 return QDF_STATUS_E_INVAL; 6310 } 6311 6312 if (!(mac_ctx->mlme_cfg)) { 6313 sme_err("invalid mlme cfg"); 6314 return QDF_STATUS_E_FAILURE; 6315 } 6316 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; 6317 6318 vdev = vdev_mlme->vdev; 6319 6320 vdev_id = wlan_vdev_get_id(vdev); 6321 mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev); 6322 /* check to see if the mac address already belongs to a session */ 6323 status = csr_roam_get_session_id_from_bssid(mac_ctx, mac_addr, 6324 &existing_session_id); 6325 if (QDF_IS_STATUS_SUCCESS(status)) { 6326 sme_err("Session %d exists with mac address "QDF_MAC_ADDR_FMT, 6327 existing_session_id, 6328 QDF_MAC_ADDR_REF(mac_addr->bytes)); 6329 return QDF_STATUS_E_FAILURE; 6330 } 6331 6332 /* attempt to retrieve session for Id */ 6333 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6334 if (!session) { 6335 sme_err("Session does not exist for interface %d", vdev_id); 6336 return QDF_STATUS_E_FAILURE; 6337 } 6338 6339 /* check to see if the session is already active */ 6340 if (session->sessionActive) { 6341 sme_err("Cannot re-open active session with Id %d", vdev_id); 6342 return QDF_STATUS_E_FAILURE; 6343 } 6344 6345 session->sessionActive = true; 6346 session->vdev_id = vdev_id; 6347 6348 ht_cap.caps = 0; 6349 vht_config.caps = 0; 6350 ht_cap.ht_caps = mac_ctx->mlme_cfg->ht_caps.ht_cap_info; 6351 vdev_mlme->proto.ht_info.ht_caps = ht_cap.caps; 6352 6353 vht_config.max_mpdu_len = vht_cap_info->ampdu_len; 6354 vht_config.supported_channel_widthset = 6355 vht_cap_info->supp_chan_width; 6356 vht_config.ldpc_coding = vht_cap_info->ldpc_coding_cap; 6357 vht_config.shortgi80 = vht_cap_info->short_gi_80mhz; 6358 vht_config.shortgi160and80plus80 = 6359 vht_cap_info->short_gi_160mhz; 6360 vht_config.tx_stbc = vht_cap_info->tx_stbc; 6361 vht_config.rx_stbc = vht_cap_info->rx_stbc; 6362 vht_config.su_beam_former = vht_cap_info->su_bformer; 6363 vht_config.su_beam_formee = vht_cap_info->su_bformee; 6364 vht_config.csnof_beamformer_antSup = 6365 vht_cap_info->tx_bfee_ant_supp; 6366 vht_config.num_soundingdim = vht_cap_info->num_soundingdim; 6367 vht_config.mu_beam_former = vht_cap_info->mu_bformer; 6368 vht_config.mu_beam_formee = vht_cap_info->enable_mu_bformee; 6369 vht_config.vht_txops = vht_cap_info->txop_ps; 6370 vht_config.htc_vhtcap = vht_cap_info->htc_vhtc; 6371 vht_config.rx_antpattern = vht_cap_info->rx_antpattern; 6372 vht_config.tx_antpattern = vht_cap_info->tx_antpattern; 6373 6374 vht_config.max_ampdu_lenexp = 6375 vht_cap_info->ampdu_len_exponent; 6376 vdev_mlme->proto.vht_info.caps = vht_config.caps; 6377 csr_update_session_he_cap(mac_ctx, session); 6378 csr_update_session_eht_cap(mac_ctx, session); 6379 6380 csr_send_set_ie(vdev_mlme->mgmt.generic.type, 6381 vdev_mlme->mgmt.generic.subtype, 6382 wlan_vdev_get_id(vdev)); 6383 6384 if (vdev_mlme->mgmt.generic.type == WLAN_VDEV_MLME_TYPE_STA) { 6385 csr_store_oce_cfg_flags_in_vdev(mac_ctx, mac_ctx->pdev, 6386 wlan_vdev_get_id(vdev)); 6387 wlan_mlme_update_oce_flags(mac_ctx->pdev); 6388 } 6389 6390 return QDF_STATUS_SUCCESS; 6391 } 6392 6393 void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id) 6394 { 6395 if (CSR_IS_SESSION_VALID(mac, vdev_id)) { 6396 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, 6397 vdev_id); 6398 6399 csr_flush_roam_scan_chan_lists(mac, vdev_id); 6400 csr_roam_free_connected_info(mac, &pSession->connectedInfo); 6401 csr_init_session(mac, vdev_id); 6402 } 6403 } 6404 6405 QDF_STATUS csr_prepare_vdev_delete(struct mac_context *mac_ctx, 6406 struct wlan_objmgr_vdev *vdev) 6407 { 6408 QDF_STATUS status = QDF_STATUS_SUCCESS; 6409 struct csr_roam_session *session; 6410 uint8_t vdev_id = wlan_vdev_get_id(vdev); 6411 6412 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6413 if (!session) 6414 return QDF_STATUS_E_INVAL; 6415 6416 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) 6417 return QDF_STATUS_E_INVAL; 6418 6419 if (CSR_IS_WAIT_FOR_KEY(mac_ctx, vdev_id)) { 6420 sme_debug("Stop Wait for key timer and change substate to eCSR_ROAM_SUBSTATE_NONE"); 6421 cm_stop_wait_for_key_timer(mac_ctx->psoc, vdev_id); 6422 csr_roam_substate_change(mac_ctx, eCSR_ROAM_SUBSTATE_NONE, 6423 vdev_id); 6424 } 6425 6426 wlan_ser_vdev_queue_disable(vdev); 6427 /* Flush all the commands for vdev */ 6428 wlan_serialization_purge_all_cmd_by_vdev_id(mac_ctx->pdev, vdev_id); 6429 if (!mac_ctx->session_close_cb) { 6430 sme_err("no close session callback registered"); 6431 return QDF_STATUS_E_FAILURE; 6432 } 6433 6434 return status; 6435 } 6436 6437 static void csr_init_session(struct mac_context *mac, uint32_t sessionId) 6438 { 6439 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId); 6440 6441 if (!pSession) 6442 return; 6443 6444 pSession->sessionActive = false; 6445 pSession->vdev_id = WLAN_UMAC_VDEV_ID_MAX; 6446 pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; 6447 csr_roam_free_connected_info(mac, &pSession->connectedInfo); 6448 } 6449 6450 static void csr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev, 6451 void *object, void *arg) 6452 { 6453 struct bssid_search_arg *bssid_arg = arg; 6454 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; 6455 struct wlan_objmgr_peer *peer; 6456 6457 if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) 6458 return; 6459 6460 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_LEGACY_SME_ID); 6461 if (!peer) 6462 return; 6463 6464 if (WLAN_ADDR_EQ(bssid_arg->peer_addr.bytes, 6465 wlan_peer_get_macaddr(peer)) == QDF_STATUS_SUCCESS) 6466 bssid_arg->vdev_id = wlan_vdev_get_id(vdev); 6467 6468 wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID); 6469 } 6470 6471 QDF_STATUS csr_roam_get_session_id_from_bssid(struct mac_context *mac, 6472 struct qdf_mac_addr *bssid, 6473 uint32_t *pSessionId) 6474 { 6475 struct bssid_search_arg bssid_arg; 6476 6477 qdf_copy_macaddr(&bssid_arg.peer_addr, bssid); 6478 bssid_arg.vdev_id = WLAN_MAX_VDEVS; 6479 wlan_objmgr_pdev_iterate_obj_list(mac->pdev, WLAN_VDEV_OP, 6480 csr_get_vdev_id_from_bssid, 6481 &bssid_arg, 0, 6482 WLAN_LEGACY_SME_ID); 6483 if (bssid_arg.vdev_id >= WLAN_MAX_VDEVS) { 6484 *pSessionId = 0; 6485 return QDF_STATUS_E_FAILURE; 6486 } 6487 6488 *pSessionId = bssid_arg.vdev_id; 6489 6490 return QDF_STATUS_SUCCESS; 6491 } 6492 6493 QDF_STATUS csr_get_snr(struct mac_context *mac, 6494 tCsrSnrCallback callback, 6495 struct qdf_mac_addr bssId, void *pContext) 6496 { 6497 QDF_STATUS status = QDF_STATUS_SUCCESS; 6498 struct scheduler_msg msg = {0}; 6499 uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX; 6500 tAniGetSnrReq *pMsg; 6501 6502 pMsg = qdf_mem_malloc(sizeof(tAniGetSnrReq)); 6503 if (!pMsg) 6504 return QDF_STATUS_E_NOMEM; 6505 6506 status = csr_roam_get_session_id_from_bssid(mac, &bssId, &sessionId); 6507 if (!QDF_IS_STATUS_SUCCESS(status)) { 6508 qdf_mem_free(pMsg); 6509 sme_err("Couldn't find session_id for given BSSID"); 6510 return status; 6511 } 6512 6513 pMsg->msgType = eWNI_SME_GET_SNR_REQ; 6514 pMsg->msgLen = (uint16_t) sizeof(tAniGetSnrReq); 6515 pMsg->sessionId = sessionId; 6516 pMsg->snrCallback = callback; 6517 pMsg->pDevContext = pContext; 6518 msg.type = eWNI_SME_GET_SNR_REQ; 6519 msg.bodyptr = pMsg; 6520 msg.reserved = 0; 6521 6522 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6523 QDF_MODULE_ID_SME, 6524 QDF_MODULE_ID_SME, 6525 &msg)) { 6526 qdf_mem_free((void *)pMsg); 6527 status = QDF_STATUS_E_FAILURE; 6528 } 6529 6530 return status; 6531 } 6532 6533 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) 6534 QDF_STATUS csr_invoke_neighbor_report_request( 6535 uint8_t session_id, 6536 struct sRrmNeighborReq *neighbor_report_req, 6537 bool send_resp_to_host) 6538 { 6539 struct wmi_invoke_neighbor_report_params *invoke_params; 6540 struct scheduler_msg msg = {0}; 6541 6542 if (!neighbor_report_req) { 6543 sme_err("Invalid params"); 6544 return QDF_STATUS_E_INVAL; 6545 } 6546 6547 invoke_params = qdf_mem_malloc(sizeof(*invoke_params)); 6548 if (!invoke_params) 6549 return QDF_STATUS_E_NOMEM; 6550 6551 invoke_params->vdev_id = session_id; 6552 invoke_params->send_resp_to_host = send_resp_to_host; 6553 6554 if (!neighbor_report_req->no_ssid) { 6555 invoke_params->ssid.length = neighbor_report_req->ssid.length; 6556 qdf_mem_copy(invoke_params->ssid.ssid, 6557 neighbor_report_req->ssid.ssId, 6558 neighbor_report_req->ssid.length); 6559 } else { 6560 invoke_params->ssid.length = 0; 6561 } 6562 6563 sme_debug("Sending SIR_HAL_INVOKE_NEIGHBOR_REPORT"); 6564 6565 msg.type = SIR_HAL_INVOKE_NEIGHBOR_REPORT; 6566 msg.reserved = 0; 6567 msg.bodyptr = invoke_params; 6568 6569 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6570 QDF_MODULE_ID_WMA, 6571 QDF_MODULE_ID_WMA, 6572 &msg)) { 6573 sme_err("Not able to post message to WMA"); 6574 qdf_mem_free(invoke_params); 6575 return QDF_STATUS_E_FAILURE; 6576 } 6577 6578 return QDF_STATUS_SUCCESS; 6579 } 6580 6581 #ifdef FEATURE_WLAN_ESE 6582 void wlan_cm_ese_populate_additional_ies(struct wlan_objmgr_pdev *pdev, 6583 struct wlan_mlme_psoc_ext_obj *mlme_obj, 6584 uint8_t vdev_id, 6585 struct wlan_roam_scan_offload_params *rso_mode_cfg) 6586 { 6587 uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN] 6588 = { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 }; 6589 uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j; 6590 ese_wmm_tspec_ie *tspec_ie; 6591 tESETspecInfo ese_tspec; 6592 struct mac_context *mac_ctx; 6593 struct csr_roam_session *session; 6594 6595 mac_ctx = sme_get_mac_context(); 6596 if (!mac_ctx) { 6597 sme_err("mac_ctx is NULL"); 6598 return; 6599 } 6600 6601 session = CSR_GET_SESSION(mac_ctx, vdev_id); 6602 if (!session) { 6603 sme_err("session is null %d", vdev_id); 6604 return; 6605 } 6606 6607 tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN); 6608 if (csr_is_wmm_supported(mac_ctx) && 6609 mlme_obj->cfg.lfr.ese_enabled && 6610 wlan_cm_get_ese_assoc(pdev, session->vdev_id)) { 6611 ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info( 6612 mac_ctx, session->vdev_id, 6613 (tTspecInfo *)&ese_tspec.tspec[0]); 6614 qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr, 6615 SIR_MAC_OUI_WME_HDR_MIN); 6616 for (j = 0; j < ese_tspec.numTspecs; j++) { 6617 /* Populate the tspec_ie */ 6618 ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec, 6619 tspec_ie); 6620 wlan_cm_append_assoc_ies(rso_mode_cfg, 6621 WLAN_ELEMID_VENDOR, 6622 DOT11F_IE_WMMTSPEC_MAX_LEN, 6623 tspec_ie_buf); 6624 } 6625 } 6626 } 6627 #endif 6628 6629 uint8_t *wlan_cm_get_rrm_cap_ie_data(void) 6630 { 6631 struct mac_context *mac_ctx; 6632 6633 mac_ctx = sme_get_mac_context(); 6634 if (!mac_ctx) { 6635 sme_err("mac_ctx is NULL"); 6636 return NULL; 6637 } 6638 6639 return (uint8_t *)&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps; 6640 } 6641 #endif 6642 6643 tSmeCmd *csr_get_command_buffer(struct mac_context *mac) 6644 { 6645 tSmeCmd *pCmd = sme_get_command_buffer(mac); 6646 6647 if (pCmd) 6648 mac->roam.sPendingCommands++; 6649 6650 return pCmd; 6651 } 6652 6653 static void csr_free_cmd_memory(struct mac_context *mac, tSmeCmd *pCommand) 6654 { 6655 if (!pCommand) { 6656 sme_err("pCommand is NULL"); 6657 return; 6658 } 6659 switch (pCommand->command) { 6660 case eSmeCommandRoam: 6661 csr_release_command_roam(mac, pCommand); 6662 break; 6663 case eSmeCommandWmStatusChange: 6664 csr_release_command_wm_status_change(mac, pCommand); 6665 break; 6666 default: 6667 break; 6668 } 6669 } 6670 6671 void csr_release_command_buffer(struct mac_context *mac, tSmeCmd *pCommand) 6672 { 6673 if (mac->roam.sPendingCommands > 0) { 6674 /* 6675 * All command allocated through csr_get_command_buffer 6676 * need to decrement the pending count when releasing 6677 */ 6678 mac->roam.sPendingCommands--; 6679 csr_free_cmd_memory(mac, pCommand); 6680 sme_release_command(mac, pCommand); 6681 } else { 6682 sme_err("no pending commands"); 6683 QDF_ASSERT(0); 6684 } 6685 } 6686 6687 void csr_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd) 6688 { 6689 struct wlan_serialization_queued_cmd_info cmd_info; 6690 struct wlan_serialization_command cmd; 6691 struct wlan_objmgr_vdev *vdev; 6692 6693 if (!sme_cmd) { 6694 sme_err("sme_cmd is NULL"); 6695 return; 6696 } 6697 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 6698 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); 6699 if (!vdev) { 6700 sme_err("Invalid vdev"); 6701 return; 6702 } 6703 qdf_mem_zero(&cmd_info, 6704 sizeof(struct wlan_serialization_queued_cmd_info)); 6705 cmd_info.cmd_id = sme_cmd->cmd_id; 6706 cmd_info.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD; 6707 cmd_info.cmd_type = csr_get_cmd_type(sme_cmd); 6708 cmd_info.vdev = vdev; 6709 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command)); 6710 cmd.cmd_id = cmd_info.cmd_id; 6711 cmd.cmd_type = cmd_info.cmd_type; 6712 cmd.vdev = cmd_info.vdev; 6713 if (wlan_serialization_is_cmd_present_in_active_queue( 6714 mac_ctx->psoc, &cmd)) { 6715 cmd_info.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE; 6716 wlan_serialization_remove_cmd(&cmd_info); 6717 } else if (wlan_serialization_is_cmd_present_in_pending_queue( 6718 mac_ctx->psoc, &cmd)) { 6719 cmd_info.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE; 6720 wlan_serialization_cancel_request(&cmd_info); 6721 } else { 6722 sme_debug("can't find cmd_id %d cmd_type %d", cmd_info.cmd_id, 6723 cmd_info.cmd_type); 6724 } 6725 if (cmd_info.vdev) 6726 wlan_objmgr_vdev_release_ref(cmd_info.vdev, WLAN_LEGACY_SME_ID); 6727 } 6728 6729 6730 static enum wlan_serialization_cmd_type csr_get_roam_cmd_type( 6731 tSmeCmd *sme_cmd) 6732 { 6733 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 6734 6735 switch (sme_cmd->u.roamCmd.roamReason) { 6736 case eCsrForcedDisassocSta: 6737 cmd_type = WLAN_SER_CMD_FORCE_DISASSOC_STA; 6738 break; 6739 case eCsrForcedDeauthSta: 6740 cmd_type = WLAN_SER_CMD_FORCE_DEAUTH_STA; 6741 break; 6742 default: 6743 break; 6744 } 6745 6746 return cmd_type; 6747 } 6748 6749 enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd) 6750 { 6751 enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX; 6752 6753 switch (sme_cmd->command) { 6754 case eSmeCommandRoam: 6755 cmd_type = csr_get_roam_cmd_type(sme_cmd); 6756 break; 6757 case eSmeCommandWmStatusChange: 6758 cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE; 6759 break; 6760 case eSmeCommandAddTs: 6761 cmd_type = WLAN_SER_CMD_ADDTS; 6762 break; 6763 case eSmeCommandDelTs: 6764 cmd_type = WLAN_SER_CMD_DELTS; 6765 break; 6766 case e_sme_command_set_hw_mode: 6767 cmd_type = WLAN_SER_CMD_SET_HW_MODE; 6768 break; 6769 case e_sme_command_nss_update: 6770 cmd_type = WLAN_SER_CMD_NSS_UPDATE; 6771 break; 6772 case e_sme_command_set_dual_mac_config: 6773 cmd_type = WLAN_SER_CMD_SET_DUAL_MAC_CONFIG; 6774 break; 6775 case e_sme_command_set_antenna_mode: 6776 cmd_type = WLAN_SER_CMD_SET_ANTENNA_MODE; 6777 break; 6778 case e_sme_command_sap_ch_width_update: 6779 cmd_type = WLAN_SER_CMD_SAP_BW_UPDATE; 6780 break; 6781 default: 6782 break; 6783 } 6784 6785 return cmd_type; 6786 } 6787 6788 static uint32_t csr_get_monotonous_number(struct mac_context *mac_ctx) 6789 { 6790 uint32_t cmd_id; 6791 uint32_t mask = 0x00FFFFFF, prefix = 0x0D000000; 6792 6793 cmd_id = qdf_atomic_inc_return(&mac_ctx->global_cmd_id); 6794 cmd_id = (cmd_id & mask); 6795 cmd_id = (cmd_id | prefix); 6796 6797 return cmd_id; 6798 } 6799 6800 static void csr_fill_cmd_timeout(struct wlan_serialization_command *cmd) 6801 { 6802 switch (cmd->cmd_type) { 6803 case WLAN_SER_CMD_WM_STATUS_CHANGE: 6804 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT; 6805 break; 6806 case WLAN_SER_CMD_VDEV_START_BSS: 6807 cmd->cmd_timeout_duration = SME_CMD_VDEV_START_BSS_TIMEOUT; 6808 break; 6809 case WLAN_SER_CMD_VDEV_STOP_BSS: 6810 cmd->cmd_timeout_duration = SME_CMD_STOP_BSS_CMD_TIMEOUT; 6811 break; 6812 case WLAN_SER_CMD_FORCE_DISASSOC_STA: 6813 case WLAN_SER_CMD_FORCE_DEAUTH_STA: 6814 cmd->cmd_timeout_duration = SME_CMD_PEER_DISCONNECT_TIMEOUT; 6815 break; 6816 6817 case WLAN_SER_CMD_ADDTS: 6818 case WLAN_SER_CMD_DELTS: 6819 cmd->cmd_timeout_duration = SME_CMD_ADD_DEL_TS_TIMEOUT; 6820 break; 6821 case WLAN_SER_CMD_SET_HW_MODE: 6822 case WLAN_SER_CMD_NSS_UPDATE: 6823 case WLAN_SER_CMD_SET_DUAL_MAC_CONFIG: 6824 case WLAN_SER_CMD_SET_ANTENNA_MODE: 6825 case WLAN_SER_CMD_SAP_BW_UPDATE: 6826 cmd->cmd_timeout_duration = SME_CMD_POLICY_MGR_CMD_TIMEOUT; 6827 break; 6828 default: 6829 cmd->cmd_timeout_duration = SME_ACTIVE_LIST_CMD_TIMEOUT_VALUE; 6830 break; 6831 } 6832 } 6833 6834 QDF_STATUS csr_set_serialization_params_to_cmd(struct mac_context *mac_ctx, 6835 tSmeCmd *sme_cmd, struct wlan_serialization_command *cmd, 6836 uint8_t high_priority) 6837 { 6838 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6839 6840 if (!sme_cmd) { 6841 sme_err("Invalid sme_cmd"); 6842 return status; 6843 } 6844 if (!cmd) { 6845 sme_err("Invalid serialization_cmd"); 6846 return status; 6847 } 6848 6849 /* 6850 * no need to fill command id for non-scan as they will be 6851 * zero always 6852 */ 6853 sme_cmd->cmd_id = csr_get_monotonous_number(mac_ctx); 6854 cmd->cmd_id = sme_cmd->cmd_id; 6855 6856 cmd->cmd_type = csr_get_cmd_type(sme_cmd); 6857 if (cmd->cmd_type == WLAN_SER_CMD_MAX) { 6858 sme_err("serialization enum not found for sme_cmd type %d", 6859 sme_cmd->command); 6860 return status; 6861 } 6862 cmd->vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 6863 sme_cmd->vdev_id, WLAN_LEGACY_SME_ID); 6864 if (!cmd->vdev) { 6865 sme_err("vdev is NULL for vdev_id:%d", sme_cmd->vdev_id); 6866 return status; 6867 } 6868 cmd->umac_cmd = sme_cmd; 6869 6870 csr_fill_cmd_timeout(cmd); 6871 6872 cmd->source = WLAN_UMAC_COMP_MLME; 6873 cmd->cmd_cb = sme_ser_cmd_callback; 6874 cmd->is_high_priority = high_priority; 6875 cmd->is_blocking = true; 6876 6877 return QDF_STATUS_SUCCESS; 6878 } 6879 6880 QDF_STATUS csr_queue_sme_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd, 6881 bool high_priority) 6882 { 6883 struct wlan_serialization_command cmd; 6884 struct wlan_objmgr_vdev *vdev = NULL; 6885 enum wlan_serialization_status ser_cmd_status; 6886 QDF_STATUS status; 6887 6888 if (!SME_IS_START(mac_ctx)) { 6889 sme_err("Sme in stop state"); 6890 QDF_ASSERT(0); 6891 goto error; 6892 } 6893 6894 qdf_mem_zero(&cmd, sizeof(struct wlan_serialization_command)); 6895 status = csr_set_serialization_params_to_cmd(mac_ctx, sme_cmd, 6896 &cmd, high_priority); 6897 if (QDF_IS_STATUS_ERROR(status)) { 6898 sme_err("failed to set ser params"); 6899 goto error; 6900 } 6901 6902 vdev = cmd.vdev; 6903 ser_cmd_status = wlan_serialization_request(&cmd); 6904 6905 switch (ser_cmd_status) { 6906 case WLAN_SER_CMD_PENDING: 6907 case WLAN_SER_CMD_ACTIVE: 6908 /* Command posted to active/pending list */ 6909 status = QDF_STATUS_SUCCESS; 6910 break; 6911 default: 6912 sme_err("Failed to queue command %d with status:%d", 6913 sme_cmd->command, ser_cmd_status); 6914 status = QDF_STATUS_E_FAILURE; 6915 goto error; 6916 } 6917 6918 return status; 6919 6920 error: 6921 if (vdev) 6922 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6923 6924 csr_release_command_buffer(mac_ctx, sme_cmd); 6925 6926 return QDF_STATUS_E_FAILURE; 6927 } 6928 6929 QDF_STATUS csr_roam_update_config(struct mac_context *mac_ctx, uint8_t session_id, 6930 uint16_t capab, uint32_t value) 6931 { 6932 struct update_config *msg; 6933 QDF_STATUS status = QDF_STATUS_SUCCESS; 6934 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); 6935 6936 sme_debug("update HT config requested"); 6937 if (!session) { 6938 sme_err("Session does not exist for session id %d", session_id); 6939 return QDF_STATUS_E_FAILURE; 6940 } 6941 6942 msg = qdf_mem_malloc(sizeof(*msg)); 6943 if (!msg) 6944 return QDF_STATUS_E_NOMEM; 6945 6946 msg->messageType = eWNI_SME_UPDATE_CONFIG; 6947 msg->vdev_id = session_id; 6948 msg->capab = capab; 6949 msg->value = value; 6950 msg->length = sizeof(*msg); 6951 status = umac_send_mb_message_to_mac(msg); 6952 6953 return status; 6954 } 6955 6956 QDF_STATUS csr_send_channel_change_req(struct mac_context *mac, 6957 struct channel_change_req *req) 6958 { 6959 struct scheduler_msg msg = {0}; 6960 struct channel_change_req *ch_change_req; 6961 QDF_STATUS status; 6962 6963 ch_change_req = qdf_mem_malloc(sizeof(*ch_change_req)); 6964 if (!ch_change_req) 6965 return QDF_STATUS_E_NOMEM; 6966 6967 qdf_mem_copy(ch_change_req, req, sizeof(*ch_change_req)); 6968 msg.type = eWNI_SME_CHANNEL_CHANGE_REQ; 6969 msg.bodyptr = ch_change_req; 6970 msg.reserved = 0; 6971 6972 status = scheduler_post_message(QDF_MODULE_ID_SME, 6973 QDF_MODULE_ID_PE, 6974 QDF_MODULE_ID_PE, 6975 &msg); 6976 if (QDF_IS_STATUS_ERROR(status)) { 6977 sme_err("Failed to send channel change request with status : %d", 6978 status); 6979 qdf_mem_free(ch_change_req); 6980 } 6981 6982 return status; 6983 } 6984 /* 6985 * Post Beacon Tx Start request to LIM 6986 * immediately after SAP CAC WAIT is 6987 * completed without any RADAR indications. 6988 */ 6989 QDF_STATUS csr_roam_start_beacon_req(struct mac_context *mac, 6990 struct qdf_mac_addr bssid, 6991 uint8_t dfsCacWaitStatus) 6992 { 6993 QDF_STATUS status = QDF_STATUS_SUCCESS; 6994 tSirStartBeaconIndication *pMsg; 6995 6996 pMsg = qdf_mem_malloc(sizeof(tSirStartBeaconIndication)); 6997 if (!pMsg) 6998 return QDF_STATUS_E_NOMEM; 6999 7000 pMsg->messageType = eWNI_SME_START_BEACON_REQ; 7001 pMsg->messageLen = sizeof(tSirStartBeaconIndication); 7002 pMsg->beaconStartStatus = dfsCacWaitStatus; 7003 qdf_mem_copy(pMsg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE); 7004 7005 status = umac_send_mb_message_to_mac(pMsg); 7006 7007 return status; 7008 } 7009 7010 /* 7011 * csr_roam_modify_add_ies - 7012 * This function sends msg to modify the additional IE buffers in PE 7013 * 7014 * @mac: mac global structure 7015 * @pModifyIE: pointer to tSirModifyIE structure 7016 * @updateType: Type of buffer 7017 * 7018 * 7019 * Return: QDF_STATUS - Success or failure 7020 */ 7021 QDF_STATUS 7022 csr_roam_modify_add_ies(struct mac_context *mac, 7023 tSirModifyIE *pModifyIE, eUpdateIEsType updateType) 7024 { 7025 tpSirModifyIEsInd pModifyAddIEInd = NULL; 7026 uint8_t *pLocalBuffer = NULL; 7027 QDF_STATUS status; 7028 7029 /* following buffer will be freed by consumer (PE) */ 7030 pLocalBuffer = qdf_mem_malloc(pModifyIE->ieBufferlength); 7031 if (!pLocalBuffer) 7032 return QDF_STATUS_E_NOMEM; 7033 7034 pModifyAddIEInd = qdf_mem_malloc(sizeof(tSirModifyIEsInd)); 7035 if (!pModifyAddIEInd) { 7036 qdf_mem_free(pLocalBuffer); 7037 return QDF_STATUS_E_NOMEM; 7038 } 7039 7040 /*copy the IE buffer */ 7041 qdf_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer, 7042 pModifyIE->ieBufferlength); 7043 qdf_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd)); 7044 7045 pModifyAddIEInd->msgType = eWNI_SME_MODIFY_ADDITIONAL_IES; 7046 pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd); 7047 7048 qdf_copy_macaddr(&pModifyAddIEInd->modifyIE.bssid, &pModifyIE->bssid); 7049 7050 pModifyAddIEInd->modifyIE.vdev_id = pModifyIE->vdev_id; 7051 pModifyAddIEInd->modifyIE.notify = pModifyIE->notify; 7052 pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID; 7053 pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen; 7054 pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer; 7055 pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength; 7056 pModifyAddIEInd->modifyIE.oui_length = pModifyIE->oui_length; 7057 7058 pModifyAddIEInd->updateType = updateType; 7059 7060 status = umac_send_mb_message_to_mac(pModifyAddIEInd); 7061 if (!QDF_IS_STATUS_SUCCESS(status)) { 7062 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d", 7063 status); 7064 qdf_mem_free(pLocalBuffer); 7065 } 7066 return status; 7067 } 7068 7069 /* 7070 * csr_roam_update_add_ies - 7071 * This function sends msg to updates the additional IE buffers in PE 7072 * 7073 * @mac: mac global structure 7074 * @sessionId: SME session id 7075 * @bssid: BSSID 7076 * @additionIEBuffer: buffer containing addition IE from hostapd 7077 * @length: length of buffer 7078 * @updateType: Type of buffer 7079 * @append: append or replace completely 7080 * 7081 * 7082 * Return: QDF_STATUS - Success or failure 7083 */ 7084 QDF_STATUS 7085 csr_roam_update_add_ies(struct mac_context *mac, 7086 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType) 7087 { 7088 tpSirUpdateIEsInd pUpdateAddIEs = NULL; 7089 uint8_t *pLocalBuffer = NULL; 7090 QDF_STATUS status; 7091 7092 if (pUpdateIE->ieBufferlength != 0) { 7093 /* Following buffer will be freed by consumer (PE) */ 7094 pLocalBuffer = qdf_mem_malloc(pUpdateIE->ieBufferlength); 7095 if (!pLocalBuffer) { 7096 return QDF_STATUS_E_NOMEM; 7097 } 7098 qdf_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer, 7099 pUpdateIE->ieBufferlength); 7100 } 7101 7102 pUpdateAddIEs = qdf_mem_malloc(sizeof(tSirUpdateIEsInd)); 7103 if (!pUpdateAddIEs) { 7104 qdf_mem_free(pLocalBuffer); 7105 return QDF_STATUS_E_NOMEM; 7106 } 7107 7108 pUpdateAddIEs->msgType = eWNI_SME_UPDATE_ADDITIONAL_IES; 7109 pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd); 7110 7111 qdf_copy_macaddr(&pUpdateAddIEs->updateIE.bssid, &pUpdateIE->bssid); 7112 7113 pUpdateAddIEs->updateIE.vdev_id = pUpdateIE->vdev_id; 7114 pUpdateAddIEs->updateIE.append = pUpdateIE->append; 7115 pUpdateAddIEs->updateIE.notify = pUpdateIE->notify; 7116 pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength; 7117 pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer; 7118 7119 pUpdateAddIEs->updateType = updateType; 7120 7121 status = umac_send_mb_message_to_mac(pUpdateAddIEs); 7122 if (!QDF_IS_STATUS_SUCCESS(status)) { 7123 sme_err("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg status %d", 7124 status); 7125 qdf_mem_free(pLocalBuffer); 7126 } 7127 return status; 7128 } 7129 7130 /** 7131 * csr_send_ext_change_freq()- function to post send ECSA 7132 * action frame to lim. 7133 * @mac_ctx: pointer to global mac structure 7134 * @ch_freq: new channel freq to switch 7135 * @session_id: senssion it should be sent on. 7136 * 7137 * This function is called to post ECSA frame to lim. 7138 * 7139 * Return: success if msg posted to LIM else return failure 7140 */ 7141 QDF_STATUS csr_send_ext_change_freq(struct mac_context *mac_ctx, 7142 qdf_freq_t ch_freq, uint8_t session_id) 7143 { 7144 QDF_STATUS status = QDF_STATUS_SUCCESS; 7145 struct sir_sme_ext_cng_chan_req *msg; 7146 7147 msg = qdf_mem_malloc(sizeof(*msg)); 7148 if (!msg) 7149 return QDF_STATUS_E_NOMEM; 7150 7151 msg->message_type = eWNI_SME_EXT_CHANGE_CHANNEL; 7152 msg->length = sizeof(*msg); 7153 msg->new_ch_freq = ch_freq; 7154 msg->vdev_id = session_id; 7155 status = umac_send_mb_message_to_mac(msg); 7156 return status; 7157 } 7158 7159 QDF_STATUS csr_csa_restart(struct mac_context *mac_ctx, uint8_t vdev_id) 7160 { 7161 QDF_STATUS status; 7162 struct wlan_objmgr_vdev *vdev; 7163 struct scheduler_msg message = {0}; 7164 7165 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 7166 WLAN_LEGACY_MAC_ID); 7167 if (!vdev) { 7168 sme_err("VDEV not found for vdev id: %d", vdev_id); 7169 return QDF_STATUS_E_FAILURE; 7170 } 7171 7172 if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_AP_CSA_START, NULL); 7173 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7174 7175 /* Serialize the req through MC thread */ 7176 message.bodyval = vdev_id; 7177 message.type = eWNI_SME_CSA_RESTART_REQ; 7178 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE, 7179 QDF_MODULE_ID_PE, &message); 7180 if (!QDF_IS_STATUS_SUCCESS(status)) { 7181 sme_err("scheduler_post_msg failed!(err=%d)", status); 7182 status = QDF_STATUS_E_FAILURE; 7183 } 7184 7185 return status; 7186 } 7187 7188 QDF_STATUS csr_roam_send_chan_sw_ie_request(struct mac_context *mac_ctx, 7189 struct qdf_mac_addr bssid, 7190 uint32_t target_chan_freq, 7191 uint8_t csa_ie_reqd, 7192 struct ch_params *ch_params, 7193 uint32_t new_cac_ms) 7194 { 7195 QDF_STATUS status = QDF_STATUS_SUCCESS; 7196 tSirDfsCsaIeRequest *msg; 7197 7198 msg = qdf_mem_malloc(sizeof(tSirDfsCsaIeRequest)); 7199 if (!msg) 7200 return QDF_STATUS_E_NOMEM; 7201 7202 msg->msgType = eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ; 7203 msg->msgLen = sizeof(tSirDfsCsaIeRequest); 7204 7205 msg->target_chan_freq = target_chan_freq; 7206 msg->csaIeRequired = csa_ie_reqd; 7207 msg->ch_switch_beacon_cnt = 7208 mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt; 7209 if (mac_ctx->sap.one_time_csa_count) { 7210 msg->ch_switch_beacon_cnt = mac_ctx->sap.one_time_csa_count; 7211 mac_ctx->sap.one_time_csa_count = 0; 7212 } 7213 msg->ch_switch_mode = mac_ctx->sap.SapDfsInfo.sap_ch_switch_mode; 7214 msg->dfs_ch_switch_disable = 7215 mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch; 7216 msg->new_chan_cac_ms = new_cac_ms; 7217 qdf_mem_copy(msg->bssid, bssid.bytes, QDF_MAC_ADDR_SIZE); 7218 qdf_mem_copy(&msg->ch_params, ch_params, sizeof(struct ch_params)); 7219 7220 status = umac_send_mb_message_to_mac(msg); 7221 7222 return status; 7223 } 7224 7225 QDF_STATUS csr_sta_continue_csa(struct mac_context *mac_ctx, uint8_t vdev_id) 7226 { 7227 QDF_STATUS status; 7228 struct scheduler_msg message = {0}; 7229 7230 /* Serialize the req through MC thread */ 7231 message.bodyval = vdev_id; 7232 message.type = eWNI_SME_STA_CSA_CONTINUE_REQ; 7233 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE, 7234 QDF_MODULE_ID_PE, &message); 7235 if (!QDF_IS_STATUS_SUCCESS(status)) { 7236 sme_err("eWNI_SME_STA_CSA_CONTINUE_REQ failed!(err=%d)", 7237 status); 7238 status = QDF_STATUS_E_FAILURE; 7239 } 7240 7241 return status; 7242 } 7243 7244 /** 7245 * csr_update_op_class_array() - update op class for each band 7246 * @mac_ctx: mac global context 7247 * @op_classes: out param, operating class array to update 7248 * @channel_info: channel info 7249 * @ch_name: channel band name to display in debug messages 7250 * @i: out param, stores number of operating classes 7251 * 7252 * Return: void 7253 */ 7254 static void 7255 csr_update_op_class_array(struct mac_context *mac_ctx, 7256 uint8_t *op_classes, 7257 struct csr_channel *channel_info, 7258 char *ch_name, 7259 uint8_t *i) 7260 { 7261 uint8_t j = 0, idx = 0, class = 0; 7262 bool found = false; 7263 uint8_t num_channels = channel_info->numChannels; 7264 uint8_t ch_num; 7265 7266 sme_debug("Num %s channels, %d", ch_name, num_channels); 7267 7268 for (idx = 0; idx < num_channels && 7269 *i < (REG_MAX_SUPP_OPER_CLASSES - 1); idx++) { 7270 wlan_reg_freq_to_chan_op_class( 7271 mac_ctx->pdev, channel_info->channel_freq_list[idx], 7272 true, BIT(BEHAV_NONE), &class, &ch_num); 7273 7274 found = false; 7275 for (j = 0; j < REG_MAX_SUPP_OPER_CLASSES - 1; j++) { 7276 if (op_classes[j] == class) { 7277 found = true; 7278 break; 7279 } 7280 } 7281 7282 if (!found) { 7283 op_classes[*i] = class; 7284 *i = *i + 1; 7285 } 7286 } 7287 } 7288 7289 /** 7290 * csr_init_operating_classes() - update op class for all bands 7291 * @mac: pointer to mac context. 7292 * 7293 * Return: void 7294 */ 7295 static void csr_init_operating_classes(struct mac_context *mac) 7296 { 7297 uint8_t i = 0; 7298 uint8_t j = 0; 7299 uint8_t swap = 0; 7300 uint8_t numClasses = 0; 7301 uint8_t opClasses[REG_MAX_SUPP_OPER_CLASSES] = {0,}; 7302 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 7303 7304 wlan_reg_read_current_country(mac->psoc, reg_cc); 7305 sme_debug("Current Country = %s", reg_cc); 7306 7307 csr_update_op_class_array(mac, opClasses, 7308 &mac->scan.base_channels, "20MHz", &i); 7309 numClasses = i; 7310 7311 /* As per spec the operating classes should be in ascending order. 7312 * Bubble sort is fine since we don't have many classes 7313 */ 7314 for (i = 0; i < (numClasses - 1); i++) { 7315 for (j = 0; j < (numClasses - i - 1); j++) { 7316 /* For decreasing order use < */ 7317 if (opClasses[j] > opClasses[j + 1]) { 7318 swap = opClasses[j]; 7319 opClasses[j] = opClasses[j + 1]; 7320 opClasses[j + 1] = swap; 7321 } 7322 } 7323 } 7324 7325 /* Set the ordered list of op classes in regdomain 7326 * for use by other modules 7327 */ 7328 wlan_reg_dmn_set_curr_opclasses(numClasses, &opClasses[0]); 7329 } 7330 7331 /** 7332 * csr_process_set_hw_mode() - Set HW mode command to PE 7333 * @mac: Globacl MAC pointer 7334 * @command: Command received from SME 7335 * 7336 * Posts the set HW mode command to PE. This message passing 7337 * through PE is required for PE's internal management 7338 * 7339 * Return: None 7340 */ 7341 void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command) 7342 { 7343 uint32_t len; 7344 struct s_sir_set_hw_mode *cmd = NULL; 7345 QDF_STATUS status; 7346 struct scheduler_msg msg = {0}; 7347 struct sir_set_hw_mode_resp *param; 7348 enum policy_mgr_hw_mode_change hw_mode; 7349 enum policy_mgr_conc_next_action action; 7350 enum set_hw_mode_status hw_mode_change_status = 7351 SET_HW_MODE_STATUS_ECANCELED; 7352 7353 /* Setting HW mode is for the entire system. 7354 * So, no need to check session 7355 */ 7356 7357 if (!command) { 7358 sme_err("Set HW mode param is NULL"); 7359 goto fail; 7360 } 7361 7362 len = sizeof(*cmd); 7363 cmd = qdf_mem_malloc(len); 7364 if (!cmd) 7365 /* Probably the fail response will also fail during malloc. 7366 * Still proceeding to send response! 7367 */ 7368 goto fail; 7369 7370 action = command->u.set_hw_mode_cmd.action; 7371 7372 status = policy_mgr_validate_dbs_switch(mac->psoc, action); 7373 7374 if (QDF_IS_STATUS_ERROR(status)) { 7375 sme_debug("Hw mode change not sent to FW status = %d", status); 7376 if (status == QDF_STATUS_E_ALREADY) 7377 hw_mode_change_status = SET_HW_MODE_STATUS_ALREADY; 7378 goto fail; 7379 } 7380 7381 hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index( 7382 mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index); 7383 7384 if (POLICY_MGR_HW_MODE_NOT_IN_PROGRESS == hw_mode) { 7385 sme_err("hw_mode %d, failing", hw_mode); 7386 goto fail; 7387 } 7388 7389 policy_mgr_set_hw_mode_change_in_progress(mac->psoc, hw_mode); 7390 policy_mgr_reset_connection_update(mac->psoc); 7391 7392 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC == 7393 command->u.set_hw_mode_cmd.reason) && 7394 (true == mac->sme.get_connection_info_cb(NULL, NULL))) { 7395 sme_err("Set HW mode refused: conn in progress"); 7396 policy_mgr_restart_opportunistic_timer(mac->psoc, false); 7397 goto reset_state; 7398 } 7399 7400 if ((POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC == 7401 command->u.set_hw_mode_cmd.reason) && 7402 (!command->u.set_hw_mode_cmd.hw_mode_index && 7403 !policy_mgr_need_opportunistic_upgrade(mac->psoc, NULL))) { 7404 sme_err("Set HW mode to SMM not needed anymore"); 7405 goto reset_state; 7406 } 7407 7408 cmd->messageType = eWNI_SME_SET_HW_MODE_REQ; 7409 cmd->length = len; 7410 cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index; 7411 cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason; 7412 /* 7413 * Below callback and context info are not needed for PE as of now. 7414 * Storing the passed value in the same s_sir_set_hw_mode format. 7415 */ 7416 cmd->set_hw.set_hw_mode_cb = command->u.set_hw_mode_cmd.set_hw_mode_cb; 7417 7418 sme_debug( 7419 "Posting set hw mode req to PE session:%d reason:%d", 7420 command->u.set_hw_mode_cmd.session_id, 7421 command->u.set_hw_mode_cmd.reason); 7422 7423 status = umac_send_mb_message_to_mac(cmd); 7424 if (QDF_STATUS_SUCCESS != status) { 7425 sme_err("Posting to PE failed"); 7426 cmd = NULL; 7427 goto reset_state; 7428 } 7429 return; 7430 7431 reset_state: 7432 policy_mgr_set_hw_mode_change_in_progress(mac->psoc, 7433 POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); 7434 fail: 7435 if (cmd) 7436 qdf_mem_free(cmd); 7437 param = qdf_mem_malloc(sizeof(*param)); 7438 if (!param) 7439 return; 7440 7441 sme_debug("Sending set HW fail response to SME"); 7442 param->status = hw_mode_change_status; 7443 param->cfgd_hw_mode_index = 0; 7444 param->num_vdev_mac_entries = 0; 7445 msg.type = eWNI_SME_SET_HW_MODE_RESP; 7446 msg.bodyptr = param; 7447 msg.bodyval = 0; 7448 sys_process_mmh_msg(mac, &msg); 7449 } 7450 7451 /** 7452 * csr_process_set_dual_mac_config() - Set HW mode command to PE 7453 * @mac: Global MAC pointer 7454 * @command: Command received from SME 7455 * 7456 * Posts the set dual mac config command to PE. 7457 * 7458 * Return: None 7459 */ 7460 void csr_process_set_dual_mac_config(struct mac_context *mac, tSmeCmd *command) 7461 { 7462 uint32_t len; 7463 struct sir_set_dual_mac_cfg *cmd; 7464 QDF_STATUS status; 7465 struct scheduler_msg msg = {0}; 7466 struct sir_dual_mac_config_resp *param; 7467 7468 /* Setting MAC configuration is for the entire system. 7469 * So, no need to check session 7470 */ 7471 7472 if (!command) { 7473 sme_err("Set HW mode param is NULL"); 7474 goto fail; 7475 } 7476 7477 len = sizeof(*cmd); 7478 cmd = qdf_mem_malloc(len); 7479 if (!cmd) 7480 /* Probably the fail response will also fail during malloc. 7481 * Still proceeding to send response! 7482 */ 7483 goto fail; 7484 7485 cmd->message_type = eWNI_SME_SET_DUAL_MAC_CFG_REQ; 7486 cmd->length = len; 7487 cmd->set_dual_mac.scan_config = command->u.set_dual_mac_cmd.scan_config; 7488 cmd->set_dual_mac.fw_mode_config = 7489 command->u.set_dual_mac_cmd.fw_mode_config; 7490 /* 7491 * Below callback and context info are not needed for PE as of now. 7492 * Storing the passed value in the same sir_set_dual_mac_cfg format. 7493 */ 7494 cmd->set_dual_mac.set_dual_mac_cb = 7495 command->u.set_dual_mac_cmd.set_dual_mac_cb; 7496 7497 sme_debug("Posting eWNI_SME_SET_DUAL_MAC_CFG_REQ to PE: %x %x", 7498 cmd->set_dual_mac.scan_config, 7499 cmd->set_dual_mac.fw_mode_config); 7500 7501 status = umac_send_mb_message_to_mac(cmd); 7502 if (QDF_IS_STATUS_ERROR(status)) { 7503 sme_err("Posting to PE failed"); 7504 goto fail; 7505 } 7506 return; 7507 fail: 7508 param = qdf_mem_malloc(sizeof(*param)); 7509 if (!param) 7510 return; 7511 7512 sme_err("Sending set dual mac fail response to SME"); 7513 param->status = SET_HW_MODE_STATUS_ECANCELED; 7514 msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP; 7515 msg.bodyptr = param; 7516 msg.bodyval = 0; 7517 sys_process_mmh_msg(mac, &msg); 7518 } 7519 7520 /** 7521 * csr_process_set_antenna_mode() - Set antenna mode command to 7522 * PE 7523 * @mac: Global MAC pointer 7524 * @command: Command received from SME 7525 * 7526 * Posts the set dual mac config command to PE. 7527 * 7528 * Return: None 7529 */ 7530 void csr_process_set_antenna_mode(struct mac_context *mac, tSmeCmd *command) 7531 { 7532 uint32_t len; 7533 struct sir_set_antenna_mode *cmd; 7534 QDF_STATUS status; 7535 struct scheduler_msg msg = {0}; 7536 struct sir_antenna_mode_resp *param; 7537 7538 /* Setting MAC configuration is for the entire system. 7539 * So, no need to check session 7540 */ 7541 7542 if (!command) { 7543 sme_err("Set antenna mode param is NULL"); 7544 goto fail; 7545 } 7546 7547 len = sizeof(*cmd); 7548 cmd = qdf_mem_malloc(len); 7549 if (!cmd) 7550 goto fail; 7551 7552 cmd->message_type = eWNI_SME_SET_ANTENNA_MODE_REQ; 7553 cmd->length = len; 7554 cmd->set_antenna_mode = command->u.set_antenna_mode_cmd; 7555 7556 sme_debug( 7557 "Posting eWNI_SME_SET_ANTENNA_MODE_REQ to PE: %d %d", 7558 cmd->set_antenna_mode.num_rx_chains, 7559 cmd->set_antenna_mode.num_tx_chains); 7560 7561 status = umac_send_mb_message_to_mac(cmd); 7562 if (QDF_STATUS_SUCCESS != status) { 7563 sme_err("Posting to PE failed"); 7564 /* 7565 * umac_send_mb_message_to_mac would've released the mem 7566 * allocated by cmd. 7567 */ 7568 goto fail; 7569 } 7570 7571 return; 7572 fail: 7573 param = qdf_mem_malloc(sizeof(*param)); 7574 if (!param) 7575 return; 7576 7577 sme_err("Sending set dual mac fail response to SME"); 7578 param->status = SET_ANTENNA_MODE_STATUS_ECANCELED; 7579 msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP; 7580 msg.bodyptr = param; 7581 msg.bodyval = 0; 7582 sys_process_mmh_msg(mac, &msg); 7583 } 7584 7585 /** 7586 * csr_process_nss_update_req() - Update nss command to PE 7587 * @mac: Globacl MAC pointer 7588 * @command: Command received from SME 7589 * 7590 * Posts the nss update command to PE. This message passing 7591 * through PE is required for PE's internal management 7592 * 7593 * Return: None 7594 */ 7595 void csr_process_nss_update_req(struct mac_context *mac, tSmeCmd *command) 7596 { 7597 uint32_t len; 7598 struct sir_nss_update_request *msg; 7599 QDF_STATUS status; 7600 struct scheduler_msg msg_return = {0}; 7601 struct sir_bcn_update_rsp *param; 7602 struct csr_roam_session *session; 7603 7604 7605 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) { 7606 sme_err("Invalid session id %d", command->vdev_id); 7607 goto fail; 7608 } 7609 session = CSR_GET_SESSION(mac, command->vdev_id); 7610 7611 len = sizeof(*msg); 7612 msg = qdf_mem_malloc(len); 7613 if (!msg) 7614 /* Probably the fail response is also fail during malloc. 7615 * Still proceeding to send response! 7616 */ 7617 goto fail; 7618 7619 msg->msgType = eWNI_SME_NSS_UPDATE_REQ; 7620 msg->msgLen = sizeof(*msg); 7621 7622 msg->new_nss = command->u.nss_update_cmd.new_nss; 7623 msg->ch_width = command->u.nss_update_cmd.ch_width; 7624 msg->vdev_id = command->u.nss_update_cmd.session_id; 7625 7626 sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE"); 7627 7628 status = umac_send_mb_message_to_mac(msg); 7629 if (QDF_IS_STATUS_SUCCESS(status)) 7630 return; 7631 7632 sme_err("Posting to PE failed"); 7633 fail: 7634 param = qdf_mem_malloc(sizeof(*param)); 7635 if (!param) 7636 return; 7637 7638 sme_err("Sending nss update fail response to SME"); 7639 param->status = QDF_STATUS_E_FAILURE; 7640 param->vdev_id = command->u.nss_update_cmd.session_id; 7641 param->reason = REASON_NSS_UPDATE; 7642 msg_return.type = eWNI_SME_NSS_UPDATE_RSP; 7643 msg_return.bodyptr = param; 7644 msg_return.bodyval = 0; 7645 sys_process_mmh_msg(mac, &msg_return); 7646 } 7647 7648 /** 7649 * csr_process_sap_ch_width_update() - Update ch_width command to PE 7650 * @mac: Globacl MAC pointer 7651 * @command: Command received from SME 7652 * 7653 * Posts the ch_width update command to PE. This message passing 7654 * through PE is required for PE's internal management 7655 * 7656 * Return: None 7657 */ 7658 void csr_process_sap_ch_width_update(struct mac_context *mac, tSmeCmd *command) 7659 { 7660 uint32_t len; 7661 struct sir_sap_ch_width_update *msg; 7662 QDF_STATUS status; 7663 struct scheduler_msg msg_return = {0}; 7664 struct sir_bcn_update_rsp *param; 7665 enum policy_mgr_conn_update_reason reason = 7666 command->u.bw_update_cmd.reason; 7667 7668 if (!CSR_IS_SESSION_VALID(mac, command->vdev_id)) { 7669 sme_err("Invalid session id %d", command->vdev_id); 7670 goto fail; 7671 } 7672 7673 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) && 7674 (mac->sme.get_connection_info_cb(NULL, NULL))) { 7675 policy_mgr_restart_opportunistic_timer(mac->psoc, false); 7676 sme_info("Vdev %d : Avoid set BW as conn in progress", 7677 command->vdev_id); 7678 goto fail; 7679 } 7680 7681 if ((reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC) && 7682 (!policy_mgr_need_opportunistic_upgrade(mac->psoc, &reason))) { 7683 sme_info("Vdev %d: BW update not needed anymore", 7684 command->vdev_id); 7685 goto fail; 7686 } 7687 7688 len = sizeof(*msg); 7689 msg = qdf_mem_malloc(len); 7690 if (!msg) 7691 /* Probably the fail response is also fail during malloc. 7692 * Still proceeding to send response! 7693 */ 7694 goto fail; 7695 7696 msg->msgType = eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ; 7697 msg->msgLen = sizeof(*msg); 7698 7699 msg->ch_width = command->u.bw_update_cmd.ch_width; 7700 msg->vdev_id = command->u.bw_update_cmd.vdev_id; 7701 7702 sme_debug("Posting eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ to PE"); 7703 7704 status = umac_send_mb_message_to_mac(msg); 7705 if (QDF_IS_STATUS_SUCCESS(status)) 7706 return; 7707 7708 sme_err("Posting to PE failed"); 7709 fail: 7710 param = qdf_mem_malloc(sizeof(*param)); 7711 if (param) { 7712 param->status = QDF_STATUS_E_FAILURE; 7713 param->vdev_id = command->u.bw_update_cmd.vdev_id; 7714 param->reason = REASON_CH_WIDTH_UPDATE; 7715 } 7716 msg_return.type = eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP; 7717 msg_return.bodyptr = param; 7718 msg_return.bodyval = 0; 7719 sys_process_mmh_msg(mac, &msg_return); 7720 } 7721 7722 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 7723 #ifdef WLAN_FEATURE_SAE 7724 /** 7725 * csr_process_roam_auth_sae_callback() - API to trigger the 7726 * WPA3 pre-auth event for candidate AP received from firmware. 7727 * @mac_ctx: Global mac context pointer 7728 * @vdev_id: vdev id 7729 * @roam_bssid: Candidate BSSID to roam 7730 * @akm: Candidate AKM 7731 * 7732 * This function calls the hdd_sme_roam_callback with reason 7733 * eCSR_ROAM_SAE_COMPUTE to trigger SAE auth to supplicant. 7734 */ 7735 static QDF_STATUS 7736 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, 7737 uint8_t vdev_id, 7738 struct qdf_mac_addr roam_bssid, 7739 uint32_t akm) 7740 { 7741 struct csr_roam_info *roam_info; 7742 struct sir_sae_info sae_info; 7743 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 7744 7745 if (!session) { 7746 sme_err("WPA3 Preauth event with invalid session id:%d", 7747 vdev_id); 7748 return QDF_STATUS_E_FAILURE; 7749 } 7750 7751 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 7752 if (!roam_info) 7753 return QDF_STATUS_E_FAILURE; 7754 7755 sae_info.msg_len = sizeof(sae_info); 7756 sae_info.vdev_id = vdev_id; 7757 sae_info.akm = akm; 7758 wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id, 7759 sae_info.ssid.ssId, 7760 &sae_info.ssid.length); 7761 qdf_mem_copy(sae_info.peer_mac_addr.bytes, 7762 roam_bssid.bytes, QDF_MAC_ADDR_SIZE); 7763 7764 roam_info->sae_info = &sae_info; 7765 7766 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 7767 eCSR_ROAM_SAE_COMPUTE, eCSR_ROAM_RESULT_NONE); 7768 7769 qdf_mem_free(roam_info); 7770 7771 return QDF_STATUS_SUCCESS; 7772 } 7773 #else 7774 static inline QDF_STATUS 7775 csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx, 7776 uint8_t vdev_id, 7777 struct qdf_mac_addr roam_bssid, 7778 uint32_t akm) 7779 { 7780 return QDF_STATUS_E_NOSUPPORT; 7781 } 7782 #endif 7783 7784 QDF_STATUS 7785 csr_roam_auth_offload_callback(struct mac_context *mac_ctx, uint8_t vdev_id, 7786 struct qdf_mac_addr bssid, uint32_t akm) 7787 { 7788 QDF_STATUS status; 7789 7790 status = sme_acquire_global_lock(&mac_ctx->sme); 7791 if (!QDF_IS_STATUS_SUCCESS(status)) 7792 return status; 7793 7794 status = csr_process_roam_auth_sae_callback(mac_ctx, vdev_id, 7795 bssid, akm); 7796 7797 sme_release_global_lock(&mac_ctx->sme); 7798 7799 return status; 7800 7801 } 7802 #endif 7803 7804 QDF_STATUS csr_update_owe_info(struct mac_context *mac, 7805 struct assoc_ind *assoc_ind) 7806 { 7807 uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; 7808 QDF_STATUS status; 7809 7810 status = csr_roam_get_session_id_from_bssid(mac, 7811 (struct qdf_mac_addr *)assoc_ind->bssId, 7812 &session_id); 7813 if (!QDF_IS_STATUS_SUCCESS(status)) { 7814 sme_debug("Couldn't find session_id for given BSSID"); 7815 return QDF_STATUS_E_FAILURE; 7816 } 7817 7818 /* Send Association completion message to PE */ 7819 if (assoc_ind->owe_status) 7820 status = QDF_STATUS_E_INVAL; 7821 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status, 7822 assoc_ind->owe_status); 7823 /* 7824 * send a message to CSR itself just to avoid the EAPOL frames 7825 * going OTA before association response 7826 */ 7827 if (assoc_ind->owe_status == 0) 7828 status = csr_send_assoc_ind_to_upper_layer_cnf_msg(mac, 7829 assoc_ind, 7830 status, 7831 session_id); 7832 7833 return status; 7834 } 7835 7836 QDF_STATUS csr_update_ft_info(struct mac_context *mac, 7837 struct assoc_ind *assoc_ind) 7838 { 7839 QDF_STATUS status; 7840 7841 /* Send Association completion message to PE */ 7842 status = assoc_ind->ft_status ? QDF_STATUS_E_INVAL : QDF_STATUS_SUCCESS; 7843 assoc_ind->need_assoc_rsp_tx_cb = true; 7844 status = csr_send_assoc_cnf_msg(mac, assoc_ind, status, 7845 assoc_ind->ft_status); 7846 return status; 7847 } 7848 7849 /** 7850 * csr_set_sap_ser_params() - API to fill serialization parameters for 7851 * SAP requests 7852 * @cmd : Serialization command 7853 * @cmd_type: Type of serialization command 7854 * 7855 * Return: Void 7856 */ 7857 static void csr_set_sap_ser_params(struct wlan_serialization_command *cmd, 7858 enum wlan_serialization_cmd_type cmd_type) 7859 { 7860 cmd->cmd_type = cmd_type; 7861 cmd->source = WLAN_UMAC_COMP_MLME; 7862 cmd->cmd_cb = sme_sap_ser_callback; 7863 cmd->is_high_priority = false; 7864 cmd->is_blocking = true; 7865 return; 7866 } 7867 7868 QDF_STATUS csr_bss_start(struct mac_context *mac, uint32_t vdev_id, 7869 struct start_bss_config *bss_config) 7870 { 7871 struct wlan_serialization_command cmd = {0}; 7872 struct wlan_objmgr_vdev *vdev; 7873 struct start_bss_config *start_bss_cfg = NULL; 7874 enum QDF_OPMODE persona; 7875 enum wlan_serialization_status status; 7876 struct csr_roam_session *session; 7877 struct validate_bss_data candidate; 7878 7879 session = CSR_GET_SESSION(mac, vdev_id); 7880 if (!session) 7881 return QDF_STATUS_E_FAILURE; 7882 7883 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, 7884 WLAN_LEGACY_MAC_ID); 7885 if (!vdev) { 7886 sme_err("VDEV not found for vdev id : %d", vdev_id); 7887 return QDF_STATUS_E_FAILURE; 7888 } 7889 7890 persona = wlan_vdev_mlme_get_opmode(vdev); 7891 if (persona != QDF_SAP_MODE && persona != QDF_NDI_MODE && 7892 persona != QDF_P2P_GO_MODE) { 7893 sme_err("Start BSS request for invalid mode %d", persona); 7894 goto error; 7895 } 7896 7897 start_bss_cfg = qdf_mem_malloc(sizeof(struct start_bss_config)); 7898 if (!start_bss_cfg) { 7899 sme_err("SAP BSS config allocation failed"); 7900 goto error; 7901 } 7902 7903 qdf_mem_copy(start_bss_cfg, bss_config, 7904 sizeof(struct start_bss_config)); 7905 start_bss_cfg->cmd_id = csr_get_monotonous_number(mac); 7906 7907 session->cb_mode = start_bss_cfg->sec_ch_offset; 7908 session->bcn_int = bss_config->beaconInterval; 7909 candidate.beacon_interval = session->bcn_int; 7910 candidate.chan_freq = bss_config->oper_ch_freq; 7911 if_mgr_is_beacon_interval_valid(mac->pdev, vdev_id, 7912 &candidate); 7913 bss_config->beaconInterval = candidate.beacon_interval; 7914 session->bcn_int = candidate.beacon_interval; 7915 7916 cmd.cmd_id = start_bss_cfg->cmd_id; 7917 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_START_BSS); 7918 cmd.umac_cmd = start_bss_cfg; 7919 cmd.vdev = vdev; 7920 csr_fill_cmd_timeout(&cmd); 7921 7922 status = wlan_vdev_mlme_ser_start_bss(&cmd); 7923 switch (status) { 7924 case WLAN_SER_CMD_PENDING: 7925 case WLAN_SER_CMD_ACTIVE: 7926 break; 7927 default: 7928 sme_err("ser cmd status %d", status); 7929 goto error; 7930 } 7931 7932 return QDF_STATUS_SUCCESS; 7933 error: 7934 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7935 if (start_bss_cfg) 7936 qdf_mem_free(start_bss_cfg); 7937 7938 return QDF_STATUS_E_FAILURE; 7939 } 7940 7941 QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac, 7942 uint8_t vdev_id, 7943 eCsrRoamBssType bss_type) 7944 { 7945 struct wlan_objmgr_vdev *vdev; 7946 struct wlan_serialization_command cmd = {0}; 7947 enum wlan_serialization_status status; 7948 struct stop_bss_req *stop_bss_req; 7949 7950 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, vdev_id, 7951 WLAN_LEGACY_MAC_ID); 7952 if (!vdev) { 7953 sme_err("VDEV not found for vdev id : %d", vdev_id); 7954 return QDF_STATUS_E_FAILURE; 7955 } 7956 7957 /* Change the substate in case it is wait-for-key */ 7958 if (CSR_IS_WAIT_FOR_KEY(mac, vdev_id)) { 7959 cm_stop_wait_for_key_timer(mac->psoc, vdev_id); 7960 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_NONE, 7961 vdev_id); 7962 } 7963 7964 sme_debug("Stop BSS vdev_id: %d bss_type %d", vdev_id, bss_type); 7965 stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req)); 7966 if (!stop_bss_req) 7967 goto error; 7968 7969 stop_bss_req->vdev_id = vdev_id; 7970 stop_bss_req->cmd_id = csr_get_monotonous_number(mac); 7971 7972 cmd.cmd_id = stop_bss_req->cmd_id; 7973 csr_set_sap_ser_params(&cmd, WLAN_SER_CMD_VDEV_STOP_BSS); 7974 cmd.umac_cmd = stop_bss_req; 7975 cmd.vdev = vdev; 7976 csr_fill_cmd_timeout(&cmd); 7977 7978 status = wlan_vdev_mlme_ser_stop_bss(&cmd); 7979 switch (status) { 7980 case WLAN_SER_CMD_PENDING: 7981 case WLAN_SER_CMD_ACTIVE: 7982 break; 7983 default: 7984 sme_err("ser cmd status %d", status); 7985 goto error; 7986 } 7987 return QDF_STATUS_SUCCESS; 7988 7989 error: 7990 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 7991 qdf_mem_free(stop_bss_req); 7992 return QDF_STATUS_E_FAILURE; 7993 } 7994 7995 static void csr_process_stop_bss_response(struct mac_context *mac_ctx, 7996 uint32_t vdev_id) 7997 { 7998 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 7999 8000 if (CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(mac_ctx, vdev_id)) { 8001 csr_roam_free_connected_info(mac_ctx, &session->connectedInfo); 8002 csr_set_default_dot11_mode(mac_ctx); 8003 } 8004 8005 csr_roam_call_callback(mac_ctx, vdev_id, NULL, eCSR_ROAM_INFRA_IND, 8006 eCSR_ROAM_RESULT_INFRA_STOPPED); 8007 return; 8008 } 8009 8010 /** 8011 * csr_process_sap_results() - API to process the LIM response for 8012 * the messages posted by SAP module 8013 * @mac_ctx: mac context 8014 * @req: Serialization command posted by SAP 8015 * @rsp: Response from LIM 8016 * @result: Result from LIM 8017 * @vdev_id : vdev id 8018 * 8019 * Return: void 8020 */ 8021 static bool csr_process_sap_results(struct mac_context *mac_ctx, 8022 void *rsp, 8023 enum csr_sap_response_type result, 8024 uint8_t vdev_id) 8025 { 8026 struct csr_roam_info *roam_info; 8027 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, vdev_id); 8028 eRoamCmdStatus roam_status = eCSR_ROAM_INFRA_IND; 8029 eCsrRoamResult roam_result = eCSR_ROAM_RESULT_INFRA_START_FAILED; 8030 enum QDF_OPMODE opmode; 8031 8032 if (!session) { 8033 sme_err("session %d not found ", vdev_id); 8034 return false; 8035 } 8036 8037 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 8038 if (!roam_info) 8039 return false; 8040 8041 opmode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 8042 sme_debug("SAP result : %d", result); 8043 8044 switch (result) { 8045 case CSR_SAP_START_BSS_SUCCESS: 8046 csr_roam_process_start_bss_success(mac_ctx, roam_info, 8047 rsp, vdev_id); 8048 break; 8049 case CSR_SAP_START_BSS_FAILURE: 8050 if (opmode == QDF_NDI_MODE) { 8051 csr_roam_update_ndp_return_params(mac_ctx, 8052 CSR_SAP_START_BSS_FAILURE, 8053 &roam_status, 8054 &roam_result, 8055 roam_info); 8056 } 8057 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 8058 roam_status, roam_result); 8059 csr_set_default_dot11_mode(mac_ctx); 8060 break; 8061 case CSR_SAP_STOP_BSS_SUCCESS: 8062 case CSR_SAP_STOP_BSS_FAILURE: 8063 if (opmode == QDF_NDI_MODE) { 8064 qdf_mem_zero(roam_info, sizeof(*roam_info)); 8065 csr_roam_update_ndp_return_params(mac_ctx, result, 8066 &roam_status, 8067 &roam_result, 8068 roam_info); 8069 csr_roam_call_callback(mac_ctx, vdev_id, roam_info, 8070 roam_status, roam_result); 8071 } else { 8072 csr_process_stop_bss_response(mac_ctx, vdev_id); 8073 } 8074 break; 8075 default: 8076 sme_err("Invalid response"); 8077 break; 8078 } 8079 qdf_mem_free(roam_info); 8080 return true; 8081 } 8082 8083 static enum wlan_serialization_cmd_type 8084 get_cmd_type_from_result(enum csr_sap_response_type result) 8085 { 8086 switch (result) { 8087 case CSR_SAP_START_BSS_SUCCESS: 8088 case CSR_SAP_START_BSS_FAILURE: 8089 return WLAN_SER_CMD_VDEV_START_BSS; 8090 case CSR_SAP_STOP_BSS_SUCCESS: 8091 case CSR_SAP_STOP_BSS_FAILURE: 8092 return WLAN_SER_CMD_VDEV_STOP_BSS; 8093 default: 8094 return WLAN_SER_CMD_MAX; 8095 } 8096 } 8097 8098 static inline 8099 uint32_t get_cmd_id_from_cmd_type(void *cmd, 8100 enum wlan_serialization_cmd_type cmd_type) 8101 { 8102 switch (cmd_type) { 8103 case WLAN_SER_CMD_VDEV_START_BSS: 8104 return ((struct start_bss_config *)cmd)->cmd_id; 8105 case WLAN_SER_CMD_VDEV_STOP_BSS: 8106 return ((struct stop_bss_req *)cmd)->cmd_id; 8107 default: 8108 sme_err("Invalid cmd_type %d to be dequeued", cmd_type); 8109 return 0; 8110 } 8111 } 8112 8113 void csr_process_sap_response(struct mac_context *mac_ctx, 8114 enum csr_sap_response_type result, 8115 void *rsp, uint8_t vdev_id) 8116 { 8117 struct wlan_objmgr_vdev *vdev; 8118 void *req; 8119 uint32_t cmd_id; 8120 enum wlan_serialization_cmd_type cmd_type = 8121 get_cmd_type_from_result(result); 8122 8123 if (cmd_type >= WLAN_SER_CMD_MAX) { 8124 sme_err("Invalid command to be dequeued %d", cmd_type); 8125 return; 8126 } 8127 8128 req = wlan_serialization_get_active_cmd(mac_ctx->psoc, 8129 vdev_id, cmd_type); 8130 if (!req) { 8131 sme_err("No active command for response from LIM for cmd: %d vdev: %d", 8132 cmd_type, vdev_id); 8133 csr_process_sap_results(mac_ctx, rsp, result, vdev_id); 8134 return; 8135 } 8136 8137 csr_process_sap_results(mac_ctx, rsp, result, vdev_id); 8138 8139 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 8140 WLAN_LEGACY_MAC_ID); 8141 if (!vdev) { 8142 sme_err("vdev not found for vdev id: %d", vdev_id); 8143 return; 8144 } 8145 8146 cmd_id = get_cmd_id_from_cmd_type(req, cmd_type); 8147 sme_debug("Dequeue cmd id : %d type : %d", cmd_id, cmd_type); 8148 8149 wlan_vdev_mlme_ser_remove_request(vdev, cmd_id, cmd_type); 8150 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 8151 } 8152 8153 void csr_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, 8154 enum QDF_OPMODE device_mode) 8155 { 8156 struct sir_set_vdev_ies_per_band *p_msg; 8157 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8158 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8159 enum csr_cfgdot11mode curr_dot11_mode = 8160 mac_ctx->roam.configParam.uCfgDot11Mode; 8161 8162 p_msg = qdf_mem_malloc(sizeof(*p_msg)); 8163 if (!p_msg) 8164 return; 8165 8166 p_msg->vdev_id = vdev_id; 8167 p_msg->device_mode = device_mode; 8168 p_msg->dot11_mode = csr_get_vdev_dot11_mode(mac_ctx, vdev_id, 8169 curr_dot11_mode); 8170 p_msg->msg_type = eWNI_SME_SET_VDEV_IES_PER_BAND; 8171 p_msg->len = sizeof(*p_msg); 8172 sme_debug("SET_VDEV_IES_PER_BAND: vdev_id %d dot11mode %d dev_mode %d", 8173 vdev_id, p_msg->dot11_mode, device_mode); 8174 status = umac_send_mb_message_to_mac(p_msg); 8175 if (QDF_STATUS_SUCCESS != status) 8176 sme_err("Send eWNI_SME_SET_VDEV_IES_PER_BAND fail"); 8177 } 8178