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: sme_api.c 22 * 23 * Definitions for SME APIs 24 */ 25 26 /* Include Files */ 27 #include <sir_common.h> 28 #include <ani_global.h> 29 #include "sme_api.h" 30 #include "csr_inside_api.h" 31 #include "sme_inside.h" 32 #include "csr_internal.h" 33 #include "wma_types.h" 34 #include "wma_if.h" 35 #include "wma.h" 36 #include "wma_fips_api.h" 37 #include "wma_fw_state.h" 38 #include "qdf_trace.h" 39 #include "sme_trace.h" 40 #include "qdf_types.h" 41 #include "qdf_util.h" 42 #include "qdf_trace.h" 43 #include "cds_utils.h" 44 #include "sap_api.h" 45 #include "mac_trace.h" 46 #include "cds_regdomain.h" 47 #include "sme_power_save_api.h" 48 #include "wma.h" 49 #include "wma_twt.h" 50 #include "sch_api.h" 51 #include "sme_nan_datapath.h" 52 #include "csr_api.h" 53 #include "wlan_reg_services_api.h" 54 #include <wlan_scan_ucfg_api.h> 55 #include "wlan_reg_ucfg_api.h" 56 #include "ol_txrx.h" 57 #include "wifi_pos_api.h" 58 #include "net/cfg80211.h" 59 #include "wifi_pos_pasn_api.h" 60 #include <wlan_spectral_utils_api.h> 61 #include "wlan_mlme_public_struct.h" 62 #include "wlan_mlme_main.h" 63 #include "cfg_ucfg_api.h" 64 #include "wlan_fwol_ucfg_api.h" 65 #include <wlan_coex_ucfg_api.h> 66 #include "wlan_crypto_global_api.h" 67 #include "wlan_mlme_ucfg_api.h" 68 #include "wlan_psoc_mlme_api.h" 69 #include "mac_init_api.h" 70 #include "wlan_cm_roam_api.h" 71 #include "wlan_cm_tgt_if_tx_api.h" 72 #include "wlan_cm_api.h" 73 #include "wlan_mlme_twt_public_struct.h" 74 #include "wlan_mlme_twt_api.h" 75 #include "wlan_mlme_twt_ucfg_api.h" 76 #include "parser_api.h" 77 #include <../../core/src/wlan_cm_vdev_api.h> 78 #include <wlan_mlme_twt_api.h> 79 #include "wlan_cm_roam_ucfg_api.h" 80 #include <cm_utf.h> 81 #include <wlan_mlo_mgr_sta.h> 82 #include <wlan_mlo_mgr_main.h> 83 #include "wlan_policy_mgr_ucfg.h" 84 #include "wlan_wifi_pos_interface.h" 85 #include "wlan_cp_stats_mc_ucfg_api.h" 86 #include "wlan_psoc_mlme_ucfg_api.h" 87 #include <wlan_mlo_link_force.h> 88 #include "wma_eht.h" 89 #include "wlan_policy_mgr_ll_sap.h" 90 #include "wlan_vdev_mgr_ucfg_api.h" 91 #include "wlan_vdev_mlme_main.h" 92 #include "wlan_tdls_api.h" 93 94 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac); 95 96 static void sme_disconnect_connected_sessions(struct mac_context *mac, 97 enum wlan_reason_code reason); 98 99 static QDF_STATUS sme_handle_generic_change_country_code(struct mac_context *mac, 100 void *msg_buf); 101 102 static QDF_STATUS sme_process_nss_update_resp(struct mac_context *mac, uint8_t *msg); 103 104 /* Channel Change Response Indication Handler */ 105 static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac, 106 uint16_t msg_type, void *msg_buf); 107 108 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac, 109 struct stats_ext_event *msg); 110 111 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac); 112 113 /* Internal SME APIs */ sme_acquire_global_lock(struct sme_context * sme)114 QDF_STATUS sme_acquire_global_lock(struct sme_context *sme) 115 { 116 if (!sme) 117 return QDF_STATUS_E_INVAL; 118 119 return qdf_mutex_acquire(&sme->sme_global_lock); 120 } 121 sme_release_global_lock(struct sme_context * sme)122 QDF_STATUS sme_release_global_lock(struct sme_context *sme) 123 { 124 if (!sme) 125 return QDF_STATUS_E_INVAL; 126 127 return qdf_mutex_release(&sme->sme_global_lock); 128 } 129 sme_get_mac_context(void)130 struct mac_context *sme_get_mac_context(void) 131 { 132 struct mac_context *mac_ctx; 133 mac_handle_t mac_handle; 134 135 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 136 if (!mac_handle) 137 return NULL; 138 139 mac_ctx = MAC_CONTEXT(mac_handle); 140 141 return mac_ctx; 142 } 143 144 /** 145 * sme_process_set_hw_mode_resp() - Process set HW mode response 146 * @mac: Global MAC pointer 147 * @msg: HW mode response 148 * 149 * Processes the HW mode response and invokes the HDD callback 150 * to process further 151 */ sme_process_set_hw_mode_resp(struct mac_context * mac,uint8_t * msg)152 static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t *msg) 153 { 154 tListElem *entry; 155 tSmeCmd *command = NULL; 156 bool found; 157 policy_mgr_pdev_set_hw_mode_cback callback = NULL; 158 struct sir_set_hw_mode_resp *param; 159 enum policy_mgr_conn_update_reason reason; 160 161 uint32_t session_id; 162 uint32_t request_id; 163 164 param = (struct sir_set_hw_mode_resp *)msg; 165 if (!param) { 166 sme_err("HW mode resp param is NULL"); 167 /* Not returning. Need to check if active command list 168 * needs to be freed 169 */ 170 } 171 172 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 173 if (!entry) { 174 sme_err("No cmd found in active list"); 175 return QDF_STATUS_E_FAILURE; 176 } 177 178 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 179 if (!command) { 180 sme_err("Base address is NULL"); 181 return QDF_STATUS_E_FAILURE; 182 } 183 184 if (e_sme_command_set_hw_mode != command->command) { 185 sme_err("Command mismatch!"); 186 return QDF_STATUS_E_FAILURE; 187 } 188 189 callback = command->u.set_hw_mode_cmd.set_hw_mode_cb; 190 reason = command->u.set_hw_mode_cmd.reason; 191 session_id = command->u.set_hw_mode_cmd.session_id; 192 request_id = command->u.set_hw_mode_cmd.request_id; 193 194 sme_debug("reason: %d session: %d", 195 command->u.set_hw_mode_cmd.reason, 196 command->u.set_hw_mode_cmd.session_id); 197 198 if (!callback) { 199 sme_err("Callback does not exist"); 200 goto end; 201 } 202 203 if (!param) { 204 sme_err("Callback failed since HW mode params is NULL"); 205 goto end; 206 } 207 208 /* Irrespective of the reason for which the hw mode change request 209 * was issued, the policy manager connection table needs to be updated 210 * with the new vdev-mac id mapping, tx/rx spatial streams etc., if the 211 * set hw mode was successful. 212 */ 213 callback(param->status, 214 param->cfgd_hw_mode_index, 215 param->num_vdev_mac_entries, 216 param->vdev_mac_map, 217 command->u.set_hw_mode_cmd.next_action, 218 command->u.set_hw_mode_cmd.reason, 219 command->u.set_hw_mode_cmd.session_id, 220 command->u.set_hw_mode_cmd.context, 221 command->u.set_hw_mode_cmd.request_id); 222 if (!CSR_IS_SESSION_VALID(mac, session_id)) { 223 sme_err("session %d is invalid", session_id); 224 goto end; 225 } 226 227 if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA) { 228 sme_debug("Continue channel switch for STA on vdev %d", 229 session_id); 230 csr_sta_continue_csa(mac, session_id); 231 } 232 233 if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP) { 234 sme_debug("Continue channel switch for SAP on vdev %d", 235 session_id); 236 csr_csa_restart(mac, session_id); 237 } 238 239 if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT || 240 reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM) { 241 QDF_STATUS status = QDF_STATUS_E_FAILURE; 242 243 sme_debug("Continue connect/reassoc on vdev %d reason %d status %d cm_id 0x%x", 244 session_id, reason, param->status, request_id); 245 if (param->status == SET_HW_MODE_STATUS_OK || 246 param->status == SET_HW_MODE_STATUS_ALREADY) 247 status = QDF_STATUS_SUCCESS; 248 249 wlan_cm_handle_hw_mode_change_resp(mac->pdev, session_id, 250 request_id, 251 status); 252 } 253 254 end: 255 found = csr_nonscan_active_ll_remove_entry(mac, entry, 256 LL_ACCESS_LOCK); 257 if (found) 258 /* Now put this command back on the available command list */ 259 csr_release_command(mac, command); 260 261 return QDF_STATUS_SUCCESS; 262 } 263 264 /** 265 * sme_process_hw_mode_trans_ind() - Process HW mode transition indication 266 * @mac: Global MAC pointer 267 * @msg: HW mode transition response 268 * 269 * Processes the HW mode transition indication and invoke the HDD callback 270 * to process further 271 */ sme_process_hw_mode_trans_ind(struct mac_context * mac,uint8_t * msg)272 static QDF_STATUS sme_process_hw_mode_trans_ind(struct mac_context *mac, 273 uint8_t *msg) 274 { 275 struct cm_hw_mode_trans_ind *param; 276 277 param = (struct cm_hw_mode_trans_ind *)msg; 278 if (!param) { 279 sme_err("HW mode trans ind param is NULL"); 280 return QDF_STATUS_E_FAILURE; 281 } 282 283 policy_mgr_hw_mode_transition_cb(param->old_hw_mode_index, 284 param->new_hw_mode_index, 285 param->num_vdev_mac_entries, 286 param->vdev_mac_map, param->num_freq_map, param->mac_freq_map, 287 mac->psoc); 288 289 return QDF_STATUS_SUCCESS; 290 } 291 292 /** 293 * free_sme_cmds() - This function frees memory allocated for SME commands 294 * @mac_ctx: Pointer to Global MAC structure 295 * 296 * This function frees memory allocated for SME commands 297 * 298 * @Return: void 299 */ free_sme_cmds(struct mac_context * mac_ctx)300 static void free_sme_cmds(struct mac_context *mac_ctx) 301 { 302 uint32_t idx; 303 304 if (!mac_ctx->sme.sme_cmd_buf_addr) 305 return; 306 307 for (idx = 0; idx < mac_ctx->sme.sme_cmd_count; idx++) 308 qdf_mem_free(mac_ctx->sme.sme_cmd_buf_addr[idx]); 309 310 qdf_mem_free(mac_ctx->sme.sme_cmd_buf_addr); 311 mac_ctx->sme.sme_cmd_buf_addr = NULL; 312 } 313 init_sme_cmd_list(struct mac_context * mac)314 static QDF_STATUS init_sme_cmd_list(struct mac_context *mac) 315 { 316 QDF_STATUS status; 317 tSmeCmd *cmd; 318 uint32_t cmd_idx; 319 uint32_t sme_cmd_ptr_ary_sz; 320 321 mac->sme.sme_cmd_count = SME_TOTAL_COMMAND; 322 323 status = csr_ll_open(&mac->sme.sme_cmd_freelist); 324 if (!QDF_IS_STATUS_SUCCESS(status)) 325 goto end; 326 327 /* following pointer contains array of pointers for tSmeCmd* */ 328 sme_cmd_ptr_ary_sz = sizeof(void *) * mac->sme.sme_cmd_count; 329 mac->sme.sme_cmd_buf_addr = qdf_mem_malloc(sme_cmd_ptr_ary_sz); 330 if (!mac->sme.sme_cmd_buf_addr) { 331 status = QDF_STATUS_E_NOMEM; 332 goto end; 333 } 334 335 status = QDF_STATUS_SUCCESS; 336 for (cmd_idx = 0; cmd_idx < mac->sme.sme_cmd_count; cmd_idx++) { 337 /* 338 * Since total size of all commands together can be huge chunk 339 * of memory, allocate SME cmd individually. These SME CMDs are 340 * moved between pending and active queues. And these freeing of 341 * these queues just manipulates the list but does not actually 342 * frees SME CMD pointers. Hence store each SME CMD address in 343 * the array, sme.sme_cmd_buf_addr. This will later facilitate 344 * freeing up of all SME CMDs with just a for loop. 345 */ 346 cmd = qdf_mem_malloc(sizeof(*cmd)); 347 if (!cmd) { 348 status = QDF_STATUS_E_NOMEM; 349 free_sme_cmds(mac); 350 goto end; 351 } 352 mac->sme.sme_cmd_buf_addr[cmd_idx] = cmd; 353 csr_ll_insert_tail(&mac->sme.sme_cmd_freelist, 354 &cmd->Link, LL_ACCESS_LOCK); 355 } 356 357 end: 358 if (!QDF_IS_STATUS_SUCCESS(status)) 359 sme_err("Failed to initialize sme command list: %d", status); 360 361 return status; 362 } 363 sme_release_command(struct mac_context * mac_ctx,tSmeCmd * sme_cmd)364 void sme_release_command(struct mac_context *mac_ctx, tSmeCmd *sme_cmd) 365 { 366 sme_cmd->command = eSmeNoCommand; 367 csr_ll_insert_tail(&mac_ctx->sme.sme_cmd_freelist, &sme_cmd->Link, 368 LL_ACCESS_LOCK); 369 } 370 free_sme_cmd_list(struct mac_context * mac)371 static QDF_STATUS free_sme_cmd_list(struct mac_context *mac) 372 { 373 QDF_STATUS status = QDF_STATUS_SUCCESS; 374 375 csr_ll_close(&mac->sme.sme_cmd_freelist); 376 377 status = sme_acquire_global_lock(&mac->sme); 378 if (status != QDF_STATUS_SUCCESS) 379 goto done; 380 381 free_sme_cmds(mac); 382 383 status = sme_release_global_lock(&mac->sme); 384 if (status != QDF_STATUS_SUCCESS) 385 sme_err("Failed to release the lock status: %d", status); 386 done: 387 return status; 388 } 389 dump_csr_command_info(struct mac_context * mac,tSmeCmd * pCmd)390 static void dump_csr_command_info(struct mac_context *mac, tSmeCmd *pCmd) 391 { 392 switch (pCmd->command) { 393 case eSmeCommandRoam: 394 sme_debug("roam command reason is %d", 395 pCmd->u.roamCmd.roamReason); 396 break; 397 398 case eSmeCommandWmStatusChange: 399 sme_debug("WMStatusChange command type is %d", 400 pCmd->u.wmStatusChangeCmd.Type); 401 break; 402 403 default: 404 sme_debug("default: Unhandled command %d", 405 pCmd->command); 406 break; 407 } 408 } 409 sme_get_command_buffer(struct mac_context * mac)410 tSmeCmd *sme_get_command_buffer(struct mac_context *mac) 411 { 412 tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL; 413 tListElem *pEntry; 414 static int sme_command_queue_full; 415 416 pEntry = csr_ll_remove_head(&mac->sme.sme_cmd_freelist, LL_ACCESS_LOCK); 417 418 /* If we can get another MS Msg buffer, then we are ok. Just 419 * link the entry onto the linked list. (We are using the 420 * linked list to keep track of the message buffers). 421 */ 422 if (pEntry) { 423 pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); 424 /* reset when free list is available */ 425 sme_command_queue_full = 0; 426 } else { 427 int idx = 1; 428 429 /* Cannot change pRetCmd here since it needs to return later. */ 430 pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 431 if (pEntry) 432 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); 433 434 sme_err("Out of command buffer.... command (0x%X) stuck", 435 (pTempCmd) ? pTempCmd->command : eSmeNoCommand); 436 if (pTempCmd) { 437 if (eSmeCsrCommandMask & pTempCmd->command) 438 /* CSR command is stuck. See what the reason 439 * code is for that command 440 */ 441 dump_csr_command_info(mac, pTempCmd); 442 } /* if(pTempCmd) */ 443 444 /* dump what is in the pending queue */ 445 pEntry = 446 csr_nonscan_pending_ll_peek_head(mac, 447 LL_ACCESS_NOLOCK); 448 while (pEntry && !sme_command_queue_full) { 449 pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); 450 /* Print only 1st five commands from pending queue. */ 451 if (idx <= 5) 452 sme_err("Out of command buffer.... SME pending command #%d (0x%X)", 453 idx, pTempCmd->command); 454 idx++; 455 if (eSmeCsrCommandMask & pTempCmd->command) 456 /* CSR command is stuck. See what the reason 457 * code is for that command 458 */ 459 dump_csr_command_info(mac, pTempCmd); 460 pEntry = csr_nonscan_pending_ll_next(mac, pEntry, 461 LL_ACCESS_NOLOCK); 462 } 463 464 if (mac->mlme_cfg->gen.fatal_event_trigger) 465 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 466 WLAN_LOG_INDICATOR_HOST_DRIVER, 467 WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, 468 false, 469 mac->mlme_cfg->gen.self_recovery); 470 else 471 cds_trigger_recovery(QDF_GET_MSG_BUFF_FAILURE); 472 } 473 474 /* memset to zero */ 475 if (pRetCmd) { 476 qdf_mem_zero((uint8_t *)&pRetCmd->command, 477 sizeof(pRetCmd->command)); 478 qdf_mem_zero((uint8_t *)&pRetCmd->vdev_id, 479 sizeof(pRetCmd->vdev_id)); 480 qdf_mem_zero((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u)); 481 } 482 483 return pRetCmd; 484 } 485 486 /** 487 * sme_ser_handle_active_cmd() - handle command activation callback from 488 * new serialization module 489 * @cmd: pointer to new serialization command 490 * 491 * This API is to handle command activation callback from new serialization 492 * callback 493 * 494 * Return: QDF_STATUS_SUCCESS 495 */ 496 static sme_ser_handle_active_cmd(struct wlan_serialization_command * cmd)497 QDF_STATUS sme_ser_handle_active_cmd(struct wlan_serialization_command *cmd) 498 { 499 tSmeCmd *sme_cmd; 500 mac_handle_t mac_handle; 501 struct mac_context *mac_ctx; 502 QDF_STATUS status = QDF_STATUS_SUCCESS; 503 bool do_continue; 504 505 if (!cmd) { 506 sme_err("No serialization command found"); 507 return QDF_STATUS_E_FAILURE; 508 } 509 510 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 511 if (mac_handle) 512 mac_ctx = MAC_CONTEXT(mac_handle); 513 else 514 return QDF_STATUS_E_FAILURE; 515 516 sme_cmd = cmd->umac_cmd; 517 if (!sme_cmd) { 518 sme_err("No SME command found"); 519 return QDF_STATUS_E_FAILURE; 520 } 521 522 switch (sme_cmd->command) { 523 case eSmeCommandRoam: 524 status = csr_roam_process_command(mac_ctx, sme_cmd); 525 break; 526 case eSmeCommandWmStatusChange: 527 csr_roam_process_wm_status_change_command(mac_ctx, 528 sme_cmd); 529 break; 530 531 case eSmeCommandAddTs: 532 case eSmeCommandDelTs: 533 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 534 do_continue = qos_process_command(mac_ctx, sme_cmd); 535 if (do_continue) 536 status = QDF_STATUS_E_FAILURE; 537 #endif 538 break; 539 case e_sme_command_set_hw_mode: 540 csr_process_set_hw_mode(mac_ctx, sme_cmd); 541 break; 542 case e_sme_command_nss_update: 543 csr_process_nss_update_req(mac_ctx, sme_cmd); 544 break; 545 case e_sme_command_set_dual_mac_config: 546 csr_process_set_dual_mac_config(mac_ctx, sme_cmd); 547 break; 548 case e_sme_command_set_antenna_mode: 549 csr_process_set_antenna_mode(mac_ctx, sme_cmd); 550 break; 551 case e_sme_command_sap_ch_width_update: 552 csr_process_sap_ch_width_update(mac_ctx, sme_cmd); 553 break; 554 default: 555 /* something is wrong */ 556 sme_err("unknown command %d", sme_cmd->command); 557 status = QDF_STATUS_E_FAILURE; 558 break; 559 } 560 return status; 561 } 562 sme_dump_peer_disconnect_timeout_info(tSmeCmd * sme_cmd)563 static void sme_dump_peer_disconnect_timeout_info(tSmeCmd *sme_cmd) 564 { 565 struct wmstatus_changecmd *wms_cmd; 566 struct qdf_mac_addr peer_macaddr = QDF_MAC_ADDR_ZERO_INIT; 567 struct qdf_mac_addr peer_mld_addr = QDF_MAC_ADDR_ZERO_INIT; 568 char mld_log_str[MAC_ADDR_DUMP_LEN] = {0}; 569 570 if (sme_cmd->command == eSmeCommandRoam && 571 (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta || 572 sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta)) { 573 qdf_mem_copy(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac, 574 QDF_MAC_ADDR_SIZE); 575 if (!qdf_is_macaddr_zero(&sme_cmd->u.roamCmd.peer_mld_addr)) 576 qdf_copy_macaddr(&peer_mld_addr, 577 &sme_cmd->u.roamCmd.peer_mld_addr); 578 } else if (sme_cmd->command == eSmeCommandWmStatusChange) { 579 wms_cmd = &sme_cmd->u.wmStatusChangeCmd; 580 if (wms_cmd->Type == eCsrDisassociated) { 581 qdf_copy_macaddr( 582 &peer_macaddr, 583 &wms_cmd->u.DisassocIndMsg.peer_macaddr); 584 if (!qdf_is_macaddr_zero( 585 &wms_cmd->u.DisassocIndMsg.peer_mld_addr)) 586 qdf_copy_macaddr( 587 &peer_mld_addr, 588 &wms_cmd->u.DisassocIndMsg.peer_mld_addr); 589 } else if (wms_cmd->Type == eCsrDeauthenticated) { 590 qdf_copy_macaddr( 591 &peer_macaddr, 592 &wms_cmd->u.DeauthIndMsg.peer_macaddr); 593 if (!qdf_is_macaddr_zero( 594 &wms_cmd->u.DeauthIndMsg.peer_mld_addr)) 595 qdf_copy_macaddr( 596 &peer_mld_addr, 597 &wms_cmd->u.DeauthIndMsg.peer_mld_addr); 598 } 599 } 600 601 if (!qdf_is_macaddr_zero(&peer_mld_addr)) 602 qdf_scnprintf(mld_log_str, MAC_ADDR_DUMP_LEN, 603 " mld: " QDF_MAC_ADDR_FMT, 604 QDF_MAC_ADDR_REF(peer_mld_addr.bytes)); 605 606 if (!qdf_is_macaddr_zero(&peer_macaddr)) 607 sme_err("vdev %d cmd %d timeout for peer " QDF_MAC_ADDR_FMT "%s", 608 sme_cmd->vdev_id, sme_cmd->command, 609 QDF_MAC_ADDR_REF(peer_macaddr.bytes), mld_log_str); 610 611 } 612 sme_ser_cmd_callback(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)613 QDF_STATUS sme_ser_cmd_callback(struct wlan_serialization_command *cmd, 614 enum wlan_serialization_cb_reason reason) 615 { 616 mac_handle_t mac_handle; 617 struct mac_context *mac_ctx; 618 QDF_STATUS status = QDF_STATUS_SUCCESS; 619 tSmeCmd *sme_cmd; 620 621 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 622 if (mac_handle) 623 mac_ctx = MAC_CONTEXT(mac_handle); 624 else 625 return QDF_STATUS_E_FAILURE; 626 627 /* 628 * Do not acquire lock here as sme global lock is already acquired in 629 * caller or MC thread context 630 */ 631 if (!cmd) { 632 sme_err("serialization command is null"); 633 return QDF_STATUS_E_FAILURE; 634 } 635 636 switch (reason) { 637 case WLAN_SER_CB_ACTIVATE_CMD: 638 status = sme_ser_handle_active_cmd(cmd); 639 break; 640 case WLAN_SER_CB_CANCEL_CMD: 641 if (cmd->cmd_type == WLAN_SER_CMD_SET_HW_MODE) 642 policy_mgr_reset_hw_mode_change(mac_ctx->psoc); 643 break; 644 case WLAN_SER_CB_RELEASE_MEM_CMD: 645 if (cmd->vdev) 646 wlan_objmgr_vdev_release_ref(cmd->vdev, 647 WLAN_LEGACY_SME_ID); 648 sme_cmd = cmd->umac_cmd; 649 csr_release_command_buffer(mac_ctx, sme_cmd); 650 break; 651 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 652 sme_cmd = cmd->umac_cmd; 653 if (sme_cmd && (sme_cmd->command == eSmeCommandRoam || 654 sme_cmd->command == eSmeCommandWmStatusChange)) { 655 sme_dump_peer_disconnect_timeout_info(sme_cmd); 656 qdf_trigger_self_recovery(mac_ctx->psoc, 657 QDF_ACTIVE_LIST_TIMEOUT); 658 } 659 660 if (cmd->cmd_type == WLAN_SER_CMD_SET_HW_MODE) 661 policy_mgr_reset_hw_mode_change(mac_ctx->psoc); 662 break; 663 default: 664 sme_debug("unknown reason code"); 665 return QDF_STATUS_E_FAILURE; 666 } 667 return status; 668 } 669 670 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 671 /** 672 * sme_get_sessionid_from_activelist() - gets vdev_id 673 * @mac: mac context 674 * 675 * This function is used to get session id from sme command 676 * active list 677 * 678 * Return: returns vdev_id 679 */ sme_get_sessionid_from_activelist(struct mac_context * mac)680 static uint32_t sme_get_sessionid_from_activelist(struct mac_context *mac) 681 { 682 tListElem *entry; 683 tSmeCmd *command; 684 uint32_t vdev_id = WLAN_UMAC_VDEV_ID_MAX; 685 686 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 687 if (entry) { 688 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 689 vdev_id = command->vdev_id; 690 } 691 692 return vdev_id; 693 } 694 695 /** 696 * sme_state_info_dump() - prints state information of sme layer 697 * @buf: buffer pointer 698 * @size: size of buffer to be filled 699 * 700 * This function is used to dump state information of sme layer 701 * 702 * Return: None 703 */ sme_state_info_dump(char ** buf_ptr,uint16_t * size)704 static void sme_state_info_dump(char **buf_ptr, uint16_t *size) 705 { 706 uint8_t vdev_id, active_session_id; 707 mac_handle_t mac_handle; 708 struct mac_context *mac; 709 uint16_t len = 0; 710 char *buf = *buf_ptr; 711 enum QDF_OPMODE op_mode; 712 713 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 714 if (!mac_handle) { 715 return; 716 } 717 718 mac = MAC_CONTEXT(mac_handle); 719 720 active_session_id = sme_get_sessionid_from_activelist(mac); 721 if (active_session_id != WLAN_UMAC_VDEV_ID_MAX) { 722 len += qdf_scnprintf(buf + len, *size - len, 723 "\n active command sessionid %d", active_session_id); 724 } 725 726 for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) { 727 if (CSR_IS_SESSION_VALID(mac, vdev_id)) { 728 op_mode = wlan_get_opmode_from_vdev_id(mac->pdev, 729 vdev_id); 730 if (op_mode != QDF_STA_MODE && 731 op_mode != QDF_P2P_CLIENT_MODE) 732 continue; 733 if (cm_is_vdevid_connected(mac->pdev, vdev_id)) { 734 len += qdf_scnprintf(buf + len, *size - len, 735 "\n RoamState: %d", mac->roam.curState[vdev_id]); 736 len += qdf_scnprintf(buf + len, *size - len, 737 "\n RoamSubState: %d", mac->roam.curSubState[vdev_id]); 738 } 739 } 740 } 741 742 *size -= len; 743 *buf_ptr += len; 744 } 745 746 /** 747 * sme_register_debug_callback() - registration function sme layer 748 * to print sme state information 749 * 750 * Return: None 751 */ sme_register_debug_callback(void)752 static void sme_register_debug_callback(void) 753 { 754 qdf_register_debug_callback(QDF_MODULE_ID_SME, &sme_state_info_dump); 755 } 756 #else /* WLAN_FEATURE_MEMDUMP_ENABLE */ sme_register_debug_callback(void)757 static void sme_register_debug_callback(void) 758 { 759 } 760 #endif /* WLAN_FEATURE_MEMDUMP_ENABLE */ 761 762 #ifdef WLAN_POWER_DEBUG sme_power_debug_stats_cb(struct mac_context * mac,struct power_stats_response * response)763 static void sme_power_debug_stats_cb(struct mac_context *mac, 764 struct power_stats_response *response) 765 { 766 QDF_STATUS status = QDF_STATUS_SUCCESS; 767 768 status = sme_acquire_global_lock(&mac->sme); 769 if (QDF_IS_STATUS_SUCCESS(status)) { 770 if (mac->sme.power_stats_resp_callback) 771 mac->sme.power_stats_resp_callback( 772 response, 773 mac->sme.power_debug_stats_context); 774 else 775 sme_err("Null hdd cb"); 776 mac->sme.power_stats_resp_callback = NULL; 777 mac->sme.power_debug_stats_context = NULL; 778 sme_release_global_lock(&mac->sme); 779 } 780 } 781 sme_register_power_debug_stats_cb(struct mac_context * mac)782 static void sme_register_power_debug_stats_cb(struct mac_context *mac) 783 { 784 QDF_STATUS status = QDF_STATUS_SUCCESS; 785 786 status = sme_acquire_global_lock(&mac->sme); 787 788 if (QDF_IS_STATUS_SUCCESS(status)) { 789 mac->sme.sme_power_debug_stats_callback = 790 sme_power_debug_stats_cb; 791 sme_release_global_lock(&mac->sme); 792 } 793 } 794 sme_unregister_power_debug_stats_cb(struct mac_context * mac)795 static void sme_unregister_power_debug_stats_cb(struct mac_context *mac) 796 { 797 QDF_STATUS status = QDF_STATUS_SUCCESS; 798 799 status = sme_acquire_global_lock(&mac->sme); 800 if (QDF_IS_STATUS_SUCCESS(status)) { 801 mac->sme.sme_power_debug_stats_callback = NULL; 802 sme_release_global_lock(&mac->sme); 803 } 804 } 805 #else sme_register_power_debug_stats_cb(struct mac_context * mac)806 static inline void sme_register_power_debug_stats_cb(struct mac_context *mac) 807 { 808 } 809 sme_unregister_power_debug_stats_cb(struct mac_context * mac)810 static inline void sme_unregister_power_debug_stats_cb(struct mac_context *mac) 811 { 812 } 813 #endif 814 815 static void sme_register_vdev_delete_callback(struct mac_context * mac)816 sme_register_vdev_delete_callback(struct mac_context *mac) 817 { 818 mac->sme.sme_vdev_del_cb = sme_vdev_delete; 819 } 820 821 /* Global APIs */ 822 823 /** 824 * sme_open() - Initialize all SME modules and put them at idle state 825 * @mac_handle: The handle returned by mac_open 826 * 827 * The function initializes each module inside SME, PMC, CSR, etc. Upon 828 * successfully return, all modules are at idle state ready to start. 829 * smeOpen must be called before any other SME APIs can be involved. 830 * smeOpen must be called after mac_open. 831 * 832 * Return: QDF_STATUS_SUCCESS - SME is successfully initialized. 833 * Other status means SME is failed to be initialized 834 */ sme_open(mac_handle_t mac_handle)835 QDF_STATUS sme_open(mac_handle_t mac_handle) 836 { 837 QDF_STATUS status = QDF_STATUS_E_FAILURE; 838 struct mac_context *mac = MAC_CONTEXT(mac_handle); 839 840 mac->sme.state = SME_STATE_STOP; 841 if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( 842 &mac->sme.sme_global_lock))) { 843 sme_err("Init lock failed"); 844 return QDF_STATUS_E_FAILURE; 845 } 846 status = csr_open(mac); 847 if (!QDF_IS_STATUS_SUCCESS(status)) { 848 sme_err("csr_open failed, status: %d", status); 849 return status; 850 } 851 852 status = sme_ps_open(mac_handle); 853 if (!QDF_IS_STATUS_SUCCESS(status)) { 854 sme_err("sme_ps_open failed with status: %d", status); 855 return status; 856 } 857 858 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 859 status = sme_qos_open(mac); 860 if (!QDF_IS_STATUS_SUCCESS(status)) { 861 sme_err("Qos open, status: %d", status); 862 return status; 863 } 864 #endif 865 status = init_sme_cmd_list(mac); 866 if (!QDF_IS_STATUS_SUCCESS(status)) 867 return status; 868 869 status = rrm_open(mac); 870 if (!QDF_IS_STATUS_SUCCESS(status)) { 871 sme_err("rrm_open failed, status: %d", status); 872 return status; 873 } 874 sme_trace_init(mac); 875 sme_register_debug_callback(); 876 sme_register_power_debug_stats_cb(mac); 877 sme_register_vdev_delete_callback(mac); 878 879 return status; 880 } 881 882 /* 883 * sme_init_chan_list, triggers channel setup based on country code. 884 */ sme_init_chan_list(mac_handle_t mac_handle,enum country_src cc_src)885 QDF_STATUS sme_init_chan_list(mac_handle_t mac_handle, enum country_src cc_src) 886 { 887 struct mac_context *pmac = MAC_CONTEXT(mac_handle); 888 889 if ((cc_src == SOURCE_USERSPACE) && 890 (pmac->mlme_cfg->sap_cfg.country_code_priority)) { 891 pmac->mlme_cfg->gen.enabled_11d = false; 892 } 893 894 return csr_init_chan_list(pmac); 895 } 896 897 /* 898 * sme_set11dinfo() - Set the 11d information about valid channels 899 * and there power using information from nvRAM 900 * This function is called only for AP. 901 * 902 * This is a synchronous call 903 * 904 * mac_handle - The handle returned by mac_open. 905 * pSmeConfigParams - a pointer to a caller allocated object of 906 * struct sme_config_params. 907 * 908 * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully. 909 * 910 * Other status means SME is failed to update the config parameters. 911 */ 912 sme_set11dinfo(mac_handle_t mac_handle,struct sme_config_params * pSmeConfigParams)913 QDF_STATUS sme_set11dinfo(mac_handle_t mac_handle, 914 struct sme_config_params *pSmeConfigParams) 915 { 916 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 917 QDF_STATUS status = QDF_STATUS_E_FAILURE; 918 919 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 920 TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0)); 921 if (!pSmeConfigParams) { 922 sme_err("SME config params empty"); 923 return status; 924 } 925 926 status = csr_set_channels(mac_ctx, &pSmeConfigParams->csr_config); 927 if (!QDF_IS_STATUS_SUCCESS(status)) 928 sme_err("csr_set_channels failed with status: %d", status); 929 930 return status; 931 } 932 933 /** 934 * sme_update_fine_time_measurement_capab() - Update the FTM capabitlies from 935 * incoming val 936 * @mac_handle: Opaque handle to the global MAC context 937 * @val: New FTM capability value 938 * 939 * Return: None 940 */ sme_update_fine_time_measurement_capab(mac_handle_t mac_handle,uint8_t session_id,uint32_t val)941 void sme_update_fine_time_measurement_capab(mac_handle_t mac_handle, 942 uint8_t session_id, 943 uint32_t val) 944 { 945 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 946 QDF_STATUS status; 947 948 ucfg_wifi_pos_set_ftm_cap(mac_ctx->psoc, val); 949 950 if (!val) { 951 mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0; 952 ((tpRRMCaps)mac_ctx->rrm.rrmConfig. 953 rm_capability)->fine_time_meas_rpt = 0; 954 } else { 955 mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1; 956 ((tpRRMCaps)mac_ctx->rrm.rrmConfig. 957 rm_capability)->fine_time_meas_rpt = 1; 958 } 959 960 /* Inform this RRM IE change to FW */ 961 status = sme_acquire_global_lock(&mac_ctx->sme); 962 if (QDF_IS_STATUS_SUCCESS(status)) { 963 wlan_roam_update_cfg(mac_ctx->psoc, session_id, 964 REASON_CONNECT_IES_CHANGED); 965 sme_release_global_lock(&mac_ctx->sme); 966 } 967 } 968 969 /* 970 * sme_update_config() - Change configurations for all SME modules 971 * The function updates some configuration for modules in SME, CSR, etc 972 * during SMEs close open sequence. 973 * Modules inside SME apply the new configuration at the next transaction. 974 * This is a synchronous call 975 * 976 * mac_handle - The handle returned by mac_open. 977 * pSmeConfigParams - a pointer to a caller allocated object of 978 * struct sme_config_params. 979 * Return QDF_STATUS_SUCCESS - SME update the config parameters successfully. 980 * Other status means SME is failed to update the config parameters. 981 */ sme_update_config(mac_handle_t mac_handle,struct sme_config_params * pSmeConfigParams)982 QDF_STATUS sme_update_config(mac_handle_t mac_handle, 983 struct sme_config_params *pSmeConfigParams) 984 { 985 QDF_STATUS status = QDF_STATUS_E_FAILURE; 986 struct mac_context *mac = MAC_CONTEXT(mac_handle); 987 988 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 989 TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, 990 0)); 991 if (!pSmeConfigParams) { 992 sme_err("SME config params empty"); 993 return status; 994 } 995 status = sme_acquire_global_lock(&mac->sme); 996 if (QDF_IS_STATUS_ERROR(status)) { 997 sme_err("SME lock error %d", status); 998 return status; 999 } 1000 1001 status = csr_change_default_config_param(mac, &pSmeConfigParams-> 1002 csr_config); 1003 if (!QDF_IS_STATUS_SUCCESS(status)) 1004 sme_err("csr_change_default_config_param failed status: %d", 1005 status); 1006 1007 /* For SOC, CFG is set before start We don't want to apply global CFG 1008 * in connect state because that may cause some side affect 1009 */ 1010 if (csr_is_all_session_disconnected(mac)) 1011 csr_set_global_cfgs(mac); 1012 1013 sme_release_global_lock(&mac->sme); 1014 1015 return QDF_STATUS_SUCCESS; 1016 } 1017 sme_update_roam_params(mac_handle_t mac_handle,uint8_t vdev_id,struct rso_config_params * src_rso_config,struct rso_user_config * src_rso_usr_cfg,int update_param)1018 QDF_STATUS sme_update_roam_params(mac_handle_t mac_handle, 1019 uint8_t vdev_id, 1020 struct rso_config_params *src_rso_config, 1021 struct rso_user_config *src_rso_usr_cfg, 1022 int update_param) 1023 { 1024 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 1025 QDF_STATUS status; 1026 uint8_t i; 1027 struct wlan_mlme_psoc_ext_obj *mlme_obj; 1028 struct rso_config_params *dst_rso_usr_cfg; 1029 struct rso_user_config *rso_usr_cfg; 1030 struct wlan_objmgr_vdev *vdev; 1031 1032 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 1033 if (!mlme_obj) 1034 return QDF_STATUS_E_FAILURE; 1035 1036 dst_rso_usr_cfg = &mlme_obj->cfg.lfr.rso_user_config; 1037 1038 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 1039 WLAN_LEGACY_SME_ID); 1040 if (!vdev) 1041 return QDF_STATUS_E_FAILURE; 1042 1043 rso_usr_cfg = wlan_cm_get_rso_user_config(vdev); 1044 1045 if (!rso_usr_cfg) { 1046 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1047 return QDF_STATUS_E_FAILURE; 1048 } 1049 1050 switch (update_param) { 1051 case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED: 1052 mac_ctx->mlme_cfg->lfr.rssi_boost_threshold_5g = 1053 src_rso_config->raise_rssi_thresh_5g; 1054 mac_ctx->mlme_cfg->lfr.rssi_penalize_threshold_5g = 1055 src_rso_config->drop_rssi_thresh_5g; 1056 mac_ctx->mlme_cfg->lfr.rssi_boost_factor_5g = 1057 src_rso_config->raise_factor_5g; 1058 mac_ctx->mlme_cfg->lfr.rssi_penalize_factor_5g = 1059 src_rso_config->drop_factor_5g; 1060 mac_ctx->mlme_cfg->lfr.max_rssi_boost_5g = 1061 src_rso_config->max_raise_rssi_5g; 1062 dst_rso_usr_cfg->alert_rssi_threshold = 1063 src_rso_config->alert_rssi_threshold; 1064 dst_rso_usr_cfg->rssi_diff = src_rso_config->rssi_diff; 1065 mac_ctx->mlme_cfg->lfr.enable_5g_band_pref = true; 1066 break; 1067 case REASON_ROAM_SET_SSID_ALLOWED: 1068 qdf_mem_zero(&rso_usr_cfg->ssid_allowed_list, 1069 sizeof(struct wlan_ssid) * MAX_SSID_ALLOWED_LIST); 1070 rso_usr_cfg->num_ssid_allowed_list = 1071 src_rso_usr_cfg->num_ssid_allowed_list; 1072 for (i = 0; i < rso_usr_cfg->num_ssid_allowed_list; i++) { 1073 rso_usr_cfg->ssid_allowed_list[i].length = 1074 src_rso_usr_cfg->ssid_allowed_list[i].length; 1075 qdf_mem_copy(rso_usr_cfg->ssid_allowed_list[i].ssid, 1076 src_rso_usr_cfg->ssid_allowed_list[i].ssid, 1077 rso_usr_cfg->ssid_allowed_list[i].length); 1078 } 1079 break; 1080 case REASON_ROAM_SET_FAVORED_BSSID: 1081 qdf_mem_zero(&dst_rso_usr_cfg->bssid_favored, 1082 sizeof(struct qdf_mac_addr) * MAX_BSSID_FAVORED); 1083 dst_rso_usr_cfg->num_bssid_favored = 1084 src_rso_config->num_bssid_favored; 1085 for (i = 0; i < dst_rso_usr_cfg->num_bssid_favored; i++) { 1086 qdf_copy_macaddr(&dst_rso_usr_cfg->bssid_favored[i], 1087 &src_rso_config->bssid_favored[i]); 1088 dst_rso_usr_cfg->bssid_favored_factor[i] = 1089 src_rso_config->bssid_favored_factor[i]; 1090 } 1091 break; 1092 case REASON_ROAM_GOOD_RSSI_CHANGED: 1093 dst_rso_usr_cfg->good_rssi_roam = 1094 src_rso_config->good_rssi_roam; 1095 break; 1096 default: 1097 break; 1098 } 1099 1100 status = sme_acquire_global_lock(&mac_ctx->sme); 1101 if (QDF_IS_STATUS_SUCCESS(status)) { 1102 wlan_roam_update_cfg(mac_ctx->psoc, vdev_id, update_param); 1103 sme_release_global_lock(&mac_ctx->sme); 1104 } 1105 1106 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 1107 return 0; 1108 } 1109 1110 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT 1111 1112 /** 1113 * sme_process_ready_to_ext_wow() - inform ready to ExtWoW indication. 1114 * @mac: Global MAC context 1115 * @indication: ready to Ext WoW indication from lower layer 1116 * 1117 * On getting ready to Ext WoW indication, this function calls callback 1118 * registered (HDD callback) with SME to inform ready to ExtWoW indication. 1119 * 1120 * Return: None 1121 */ sme_process_ready_to_ext_wow(struct mac_context * mac,tpSirReadyToExtWoWInd indication)1122 static void sme_process_ready_to_ext_wow(struct mac_context *mac, 1123 tpSirReadyToExtWoWInd indication) 1124 { 1125 if (!mac) { 1126 sme_err("mac is null"); 1127 return; 1128 } 1129 1130 if (mac->readyToExtWoWCallback) { 1131 mac->readyToExtWoWCallback(mac->readyToExtWoWContext, 1132 indication->status); 1133 mac->readyToExtWoWCallback = NULL; 1134 mac->readyToExtWoWContext = NULL; 1135 } 1136 1137 } 1138 #endif 1139 1140 /* 1141 * sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform 1142 * that the NIC is ready tio run. 1143 * The function is called by HDD at the end of initialization stage so PE/HAL 1144 * can enable the NIC to running state. 1145 * This is a synchronous call 1146 * 1147 * @mac_handle - The handle returned by mac_open. 1148 * Return QDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE 1149 * successfully. 1150 * Other status means SME failed to send the message to PE. 1151 */ sme_hdd_ready_ind(mac_handle_t mac_handle)1152 QDF_STATUS sme_hdd_ready_ind(mac_handle_t mac_handle) 1153 { 1154 struct sme_ready_req *msg; 1155 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1156 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1157 1158 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 1159 TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0)); 1160 do { 1161 1162 msg = qdf_mem_malloc(sizeof(*msg)); 1163 if (!msg) 1164 return QDF_STATUS_E_NOMEM; 1165 1166 msg->messageType = eWNI_SME_SYS_READY_IND; 1167 msg->length = sizeof(*msg); 1168 msg->sme_msg_cb = sme_process_msg_callback; 1169 msg->stop_roaming_cb = sme_stop_roaming; 1170 msg->csr_roam_auth_event_handle_cb = 1171 csr_roam_auth_offload_callback; 1172 status = u_mac_post_ctrl_msg(mac_handle, (tSirMbMsg *)msg); 1173 if (QDF_IS_STATUS_ERROR(status)) { 1174 sme_err("u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND"); 1175 break; 1176 } 1177 1178 status = csr_ready(mac); 1179 if (QDF_IS_STATUS_ERROR(status)) { 1180 sme_err("csr_ready failed with status: %d", status); 1181 break; 1182 } 1183 1184 mac->sme.state = SME_STATE_READY; 1185 } while (0); 1186 1187 return status; 1188 } 1189 1190 #ifdef WLAN_BCN_RECV_FEATURE 1191 QDF_STATUS sme_register_bcn_report_pe_cb(mac_handle_t mac_handle,beacon_report_cb cb)1192 sme_register_bcn_report_pe_cb(mac_handle_t mac_handle, beacon_report_cb cb) 1193 { 1194 QDF_STATUS status; 1195 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1196 1197 if (!mac) { 1198 sme_err("Invalid mac context"); 1199 return QDF_STATUS_E_INVAL; 1200 } 1201 1202 status = sme_acquire_global_lock(&mac->sme); 1203 if (QDF_IS_STATUS_SUCCESS(status)) { 1204 mac_register_bcn_report_send_cb(mac, cb); 1205 sme_release_global_lock(&mac->sme); 1206 } 1207 1208 return status; 1209 } 1210 #endif 1211 1212 #ifdef WLAN_CONV_SPECTRAL_ENABLE sme_register_spectral_cb(struct mac_context * mac_ctx)1213 static QDF_STATUS sme_register_spectral_cb(struct mac_context *mac_ctx) 1214 { 1215 struct spectral_legacy_cbacks spectral_cb = {0}; 1216 QDF_STATUS status; 1217 1218 spectral_cb.vdev_get_chan_freq = sme_get_oper_chan_freq; 1219 spectral_cb.vdev_get_ch_width = sme_get_oper_ch_width; 1220 spectral_cb.vdev_get_sec20chan_freq_mhz = sme_get_sec20chan_freq_mhz; 1221 status = spectral_register_legacy_cb(mac_ctx->psoc, &spectral_cb); 1222 1223 return status; 1224 } 1225 #else sme_register_spectral_cb(struct mac_context * mac_ctx)1226 static QDF_STATUS sme_register_spectral_cb(struct mac_context *mac_ctx) 1227 { 1228 return QDF_STATUS_SUCCESS; 1229 } 1230 #endif 1231 /* 1232 * sme_start() - Put all SME modules at ready state. 1233 * The function starts each module in SME, PMC, CSR, etc. . Upon 1234 * successfully return, all modules are ready to run. 1235 * This is a synchronous call 1236 * 1237 * mac_handle - The handle returned by mac_open. 1238 * Return QDF_STATUS_SUCCESS - SME is ready. 1239 * Other status means SME is failed to start 1240 */ sme_start(mac_handle_t mac_handle)1241 QDF_STATUS sme_start(mac_handle_t mac_handle) 1242 { 1243 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1244 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1245 struct policy_mgr_sme_cbacks sme_cbacks; 1246 1247 do { 1248 status = csr_start(mac); 1249 if (!QDF_IS_STATUS_SUCCESS(status)) { 1250 sme_err("csr_start failed status: %d", status); 1251 break; 1252 } 1253 sme_cbacks.sme_get_nss_for_vdev = sme_get_vdev_type_nss; 1254 sme_cbacks.sme_nss_update_request = sme_nss_update_request; 1255 sme_cbacks.sme_pdev_set_hw_mode = sme_pdev_set_hw_mode; 1256 sme_cbacks.sme_soc_set_dual_mac_config = 1257 sme_soc_set_dual_mac_config; 1258 sme_cbacks.sme_change_mcc_beacon_interval = 1259 sme_change_mcc_beacon_interval; 1260 sme_cbacks.sme_rso_start_cb = sme_start_roaming; 1261 sme_cbacks.sme_rso_stop_cb = sme_stop_roaming; 1262 sme_cbacks.sme_change_sap_csa_count = sme_change_sap_csa_count; 1263 sme_cbacks.sme_sap_update_ch_width = sme_sap_update_ch_width; 1264 status = policy_mgr_register_sme_cb(mac->psoc, &sme_cbacks); 1265 if (!QDF_IS_STATUS_SUCCESS(status)) { 1266 sme_err("Failed to register sme cb with Policy Manager: %d", 1267 status); 1268 break; 1269 } 1270 sme_register_spectral_cb(mac); 1271 mac->sme.state = SME_STATE_START; 1272 1273 /* START RRM */ 1274 status = rrm_start(mac); 1275 if (!QDF_IS_STATUS_SUCCESS(status)) { 1276 sme_err("Failed to start RRM"); 1277 break; 1278 } 1279 } while (0); 1280 return status; 1281 } 1282 dfs_msg_processor(struct mac_context * mac,struct scheduler_msg * msg)1283 static QDF_STATUS dfs_msg_processor(struct mac_context *mac, 1284 struct scheduler_msg *msg) 1285 { 1286 QDF_STATUS status = QDF_STATUS_SUCCESS; 1287 struct csr_roam_info *roam_info; 1288 tSirSmeCSAIeTxCompleteRsp *csa_ie_tx_complete_rsp; 1289 uint32_t session_id = 0; 1290 eRoamCmdStatus roam_status; 1291 eCsrRoamResult roam_result; 1292 1293 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 1294 if (!roam_info) 1295 return QDF_STATUS_E_NOMEM; 1296 1297 switch (msg->type) { 1298 case eWNI_SME_DFS_RADAR_FOUND: 1299 { 1300 session_id = policy_mgr_get_dfs_beaconing_session_id(mac->psoc); 1301 if (!CSR_IS_SESSION_VALID(mac, session_id)) { 1302 sme_err("Invalid vdev %d", session_id); 1303 qdf_mem_free(roam_info); 1304 return QDF_STATUS_E_FAILURE; 1305 } 1306 roam_status = eCSR_ROAM_DFS_RADAR_IND; 1307 roam_result = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND; 1308 sme_debug("sapdfs: Radar indication event occurred"); 1309 break; 1310 } 1311 case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: 1312 { 1313 csa_ie_tx_complete_rsp = 1314 (tSirSmeCSAIeTxCompleteRsp *) msg->bodyptr; 1315 if (!csa_ie_tx_complete_rsp) { 1316 sme_err("eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND null msg"); 1317 qdf_mem_free(roam_info); 1318 return QDF_STATUS_E_FAILURE; 1319 } 1320 session_id = csa_ie_tx_complete_rsp->sessionId; 1321 roam_status = eCSR_ROAM_DFS_CHAN_SW_NOTIFY; 1322 roam_result = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS; 1323 break; 1324 } 1325 case eWNI_SME_DFS_CAC_COMPLETE: 1326 { 1327 session_id = msg->bodyval; 1328 roam_status = eCSR_ROAM_CAC_COMPLETE_IND; 1329 roam_result = eCSR_ROAM_RESULT_CAC_END_IND; 1330 sme_debug("sapdfs: Received eWNI_SME_DFS_CAC_COMPLETE vdev %d", 1331 session_id); 1332 break; 1333 } 1334 case eWNI_SME_CSA_RESTART_RSP: 1335 { 1336 session_id = msg->bodyval; 1337 roam_status = 0; 1338 roam_result = eCSR_ROAM_RESULT_CSA_RESTART_RSP; 1339 sme_debug("sapdfs: Received eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_REQ vdev %d", 1340 session_id); 1341 break; 1342 } 1343 default: 1344 { 1345 sme_err("Invalid DFS message: 0x%x", msg->type); 1346 qdf_mem_free(roam_info); 1347 status = QDF_STATUS_E_FAILURE; 1348 return status; 1349 } 1350 } 1351 1352 /* Indicate Radar Event to SAP */ 1353 csr_roam_call_callback(mac, session_id, roam_info, 1354 roam_status, roam_result); 1355 qdf_mem_free(roam_info); 1356 return status; 1357 } 1358 1359 /* 1360 * Handle the unprotected management frame indication from LIM and 1361 * forward it to HDD. 1362 */ 1363 static QDF_STATUS sme_unprotected_mgmt_frm_ind(struct mac_context * mac,tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)1364 sme_unprotected_mgmt_frm_ind(struct mac_context *mac, 1365 tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm) 1366 { 1367 QDF_STATUS status = QDF_STATUS_SUCCESS; 1368 struct csr_roam_info *roam_info; 1369 uint32_t SessionId = pSmeMgmtFrm->sessionId; 1370 1371 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 1372 if (!roam_info) 1373 return QDF_STATUS_E_NOMEM; 1374 1375 roam_info->nFrameLength = pSmeMgmtFrm->frameLen; 1376 roam_info->pbFrames = pSmeMgmtFrm->frameBuf; 1377 roam_info->frameType = pSmeMgmtFrm->frameType; 1378 1379 /* forward the mgmt frame to HDD */ 1380 csr_roam_call_callback(mac, SessionId, roam_info, 1381 eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0); 1382 1383 qdf_mem_free(roam_info); 1384 1385 return status; 1386 } 1387 sme_update_new_channel_event(mac_handle_t mac_handle,uint8_t session_id)1388 QDF_STATUS sme_update_new_channel_event(mac_handle_t mac_handle, 1389 uint8_t session_id) 1390 { 1391 QDF_STATUS status = QDF_STATUS_SUCCESS; 1392 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1393 struct csr_roam_info *roamInfo; 1394 eRoamCmdStatus roamStatus; 1395 eCsrRoamResult roamResult; 1396 1397 roamInfo = qdf_mem_malloc(sizeof(*roamInfo)); 1398 if (!roamInfo) 1399 return QDF_STATUS_E_FAILURE; 1400 1401 roamStatus = eCSR_ROAM_CHANNEL_COMPLETE_IND; 1402 roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND; 1403 sme_debug("sapdfs: Updated new channel event"); 1404 1405 /* Indicate channel Event to SAP */ 1406 csr_roam_call_callback(mac, session_id, roamInfo, 1407 roamStatus, roamResult); 1408 1409 qdf_mem_free(roamInfo); 1410 return status; 1411 } 1412 1413 1414 /** 1415 * sme_extended_change_channel_ind()- function to indicate ECSA 1416 * action frame is received in lim to SAP 1417 * @mac_ctx: pointer to global mac structure 1418 * @msg_buf: contain new channel and session id. 1419 * 1420 * This function is called to post ECSA action frame 1421 * receive event to SAP. 1422 * 1423 * Return: success if msg indicated to SAP else return failure 1424 */ sme_extended_change_channel_ind(struct mac_context * mac_ctx,void * msg_buf)1425 static QDF_STATUS sme_extended_change_channel_ind(struct mac_context *mac_ctx, 1426 void *msg_buf) 1427 { 1428 struct sir_sme_ext_cng_chan_ind *ext_chan_ind; 1429 QDF_STATUS status = QDF_STATUS_SUCCESS; 1430 uint32_t session_id = 0; 1431 struct csr_roam_info *roam_info; 1432 eRoamCmdStatus roam_status; 1433 eCsrRoamResult roam_result; 1434 1435 ext_chan_ind = msg_buf; 1436 if (!ext_chan_ind) { 1437 sme_err("ext_chan_ind is NULL"); 1438 return QDF_STATUS_E_FAILURE; 1439 } 1440 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 1441 if (!roam_info) 1442 return QDF_STATUS_E_NOMEM; 1443 1444 session_id = ext_chan_ind->session_id; 1445 roam_info->target_chan_freq = ext_chan_ind->new_chan_freq; 1446 roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND; 1447 roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND; 1448 sme_debug("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]", 1449 session_id); 1450 1451 /* Indicate Ext Channel Change event to SAP */ 1452 csr_roam_call_callback(mac_ctx, session_id, roam_info, 1453 roam_status, roam_result); 1454 qdf_mem_free(roam_info); 1455 return status; 1456 } 1457 1458 #ifdef FEATURE_WLAN_ESE 1459 /** 1460 * sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime 1461 * @mac_handle: Opaque handle to the global MAC context 1462 * @sessionId: session id 1463 * @isEseIniFeatureEnabled: ese ini enabled 1464 * 1465 * It is used at in the REG_DYNAMIC_VARIABLE macro definition of 1466 * isEseIniFeatureEnabled. This is a synchronous call 1467 * 1468 * Return: QDF_STATUS enumeration 1469 */ sme_update_is_ese_feature_enabled(mac_handle_t mac_handle,uint8_t sessionId,const bool isEseIniFeatureEnabled)1470 QDF_STATUS sme_update_is_ese_feature_enabled(mac_handle_t mac_handle, 1471 uint8_t sessionId, const bool isEseIniFeatureEnabled) 1472 { 1473 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1474 QDF_STATUS status; 1475 1476 if (mac->mlme_cfg->lfr.ese_enabled == 1477 isEseIniFeatureEnabled) { 1478 sme_debug("ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", 1479 mac->mlme_cfg->lfr.ese_enabled, isEseIniFeatureEnabled); 1480 return QDF_STATUS_SUCCESS; 1481 } 1482 1483 sme_debug("vdev %d EseEnabled is changed from %d to %d", sessionId, 1484 mac->mlme_cfg->lfr.ese_enabled, isEseIniFeatureEnabled); 1485 mac->mlme_cfg->lfr.ese_enabled = isEseIniFeatureEnabled; 1486 mlme_set_supplicant_disabled_roaming(mac->psoc, sessionId, 1487 !isEseIniFeatureEnabled); 1488 if (isEseIniFeatureEnabled) 1489 wlan_cm_roam_state_change(mac->pdev, sessionId, 1490 WLAN_ROAM_RSO_ENABLED, 1491 REASON_CONNECT); 1492 else 1493 wlan_cm_roam_state_change(mac->pdev, sessionId, 1494 WLAN_ROAM_RSO_STOPPED, 1495 REASON_SUPPLICANT_DISABLED_ROAMING); 1496 1497 if (true == isEseIniFeatureEnabled) 1498 mac->mlme_cfg->lfr.fast_transition_enabled = true; 1499 1500 if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) { 1501 status = sme_acquire_global_lock(&mac->sme); 1502 if (QDF_IS_STATUS_SUCCESS(status)) { 1503 wlan_roam_update_cfg(mac->psoc, sessionId, 1504 REASON_ESE_INI_CFG_CHANGED); 1505 sme_release_global_lock(&mac->sme); 1506 } else { 1507 return status; 1508 } 1509 } 1510 return QDF_STATUS_SUCCESS; 1511 } 1512 sme_set_plm_request(mac_handle_t mac_handle,struct plm_req_params * req)1513 QDF_STATUS sme_set_plm_request(mac_handle_t mac_handle, 1514 struct plm_req_params *req) 1515 { 1516 QDF_STATUS status; 1517 bool ret = false; 1518 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1519 uint32_t ch_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; 1520 uint8_t count, valid_count = 0; 1521 struct scheduler_msg msg = {0}; 1522 struct csr_roam_session *session; 1523 struct plm_req_params *body; 1524 uint32_t ch_freq; 1525 1526 if (!req) 1527 return QDF_STATUS_E_FAILURE; 1528 1529 status = sme_acquire_global_lock(&mac->sme); 1530 if (!QDF_IS_STATUS_SUCCESS(status)) 1531 return status; 1532 1533 session = CSR_GET_SESSION(mac, req->vdev_id); 1534 if (!session) { 1535 sme_err("session for vdev %d not found", req->vdev_id); 1536 sme_release_global_lock(&mac->sme); 1537 return QDF_STATUS_E_FAILURE; 1538 } 1539 1540 if (!session->sessionActive) { 1541 sme_err("Invalid vdev %d", req->vdev_id); 1542 sme_release_global_lock(&mac->sme); 1543 return QDF_STATUS_E_FAILURE; 1544 } 1545 1546 /* per contract must make a copy of the params when messaging */ 1547 body = qdf_mem_malloc(sizeof(*body)); 1548 1549 if (!body) { 1550 sme_release_global_lock(&mac->sme); 1551 return QDF_STATUS_E_NOMEM; 1552 } 1553 1554 *body = *req; 1555 1556 if (!body->enable) 1557 goto send_plm_start; 1558 /* validating channel numbers */ 1559 for (count = 0; count < body->plm_num_ch; count++) { 1560 ch_freq = body->plm_ch_freq_list[count]; 1561 ret = csr_is_supported_channel(mac, ch_freq); 1562 if (!ret) { 1563 /* Not supported, ignore the channel */ 1564 sme_debug("Unsupported freq %d ignored for PLM", 1565 ch_freq); 1566 continue; 1567 } 1568 1569 if (ch_freq > 2477) { 1570 enum channel_state state = 1571 wlan_reg_get_channel_state_for_pwrmode( 1572 mac->pdev, ch_freq, 1573 REG_CURRENT_PWR_MODE); 1574 1575 if (state == CHANNEL_STATE_DFS) { 1576 /* DFS channel is provided, no PLM bursts can be 1577 * transmitted. Ignoring these channels. 1578 */ 1579 sme_debug("DFS channel %d ignored for PLM", 1580 ch_freq); 1581 continue; 1582 } 1583 } 1584 ch_freq_list[valid_count++] = ch_freq; 1585 } /* End of for () */ 1586 1587 /* Copying back the valid channel list to plm struct */ 1588 qdf_mem_zero(body->plm_ch_freq_list, body->plm_num_ch); 1589 if (valid_count) 1590 qdf_mem_copy(body->plm_ch_freq_list, ch_freq_list, valid_count); 1591 /* All are invalid channels, FW need to send the PLM 1592 * report with "incapable" bit set. 1593 */ 1594 body->plm_num_ch = valid_count; 1595 1596 send_plm_start: 1597 /* PLM START */ 1598 msg.type = WMA_SET_PLM_REQ; 1599 msg.reserved = 0; 1600 msg.bodyptr = body; 1601 1602 if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME, 1603 QDF_MODULE_ID_WMA, 1604 QDF_MODULE_ID_WMA, 1605 &msg))) { 1606 sme_err("Not able to post WMA_SET_PLM_REQ to WMA"); 1607 sme_release_global_lock(&mac->sme); 1608 qdf_mem_free(body); 1609 return QDF_STATUS_E_FAILURE; 1610 } 1611 1612 sme_release_global_lock(&mac->sme); 1613 return QDF_STATUS_SUCCESS; 1614 } 1615 1616 /** 1617 * sme_tsm_ie_ind() - sme tsm ie indication 1618 * @mac: Global mac context 1619 * @pSmeTsmIeInd: Pointer to tsm ie indication 1620 * 1621 * Handle the tsm ie indication from LIM and forward it to HDD. 1622 * 1623 * Return: QDF_STATUS enumeration 1624 */ sme_tsm_ie_ind(struct mac_context * mac,struct tsm_ie_ind * pSmeTsmIeInd)1625 static QDF_STATUS sme_tsm_ie_ind(struct mac_context *mac, 1626 struct tsm_ie_ind *pSmeTsmIeInd) 1627 { 1628 QDF_STATUS status = QDF_STATUS_SUCCESS; 1629 struct csr_roam_info *roam_info; 1630 uint32_t SessionId = pSmeTsmIeInd->sessionId; 1631 1632 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 1633 if (!roam_info) 1634 return QDF_STATUS_E_NOMEM; 1635 1636 roam_info->tsm_ie.tsid = pSmeTsmIeInd->tsm_ie.tsid; 1637 roam_info->tsm_ie.state = pSmeTsmIeInd->tsm_ie.state; 1638 roam_info->tsm_ie.msmt_interval = pSmeTsmIeInd->tsm_ie.msmt_interval; 1639 /* forward the tsm ie information to HDD */ 1640 csr_roam_call_callback(mac, SessionId, roam_info, 1641 eCSR_ROAM_TSM_IE_IND, 0); 1642 qdf_mem_free(roam_info); 1643 return status; 1644 } 1645 1646 /** 1647 * sme_set_ese_beacon_request() - set ese beacon request 1648 * @mac_handle: Opaque handle to the global MAC context 1649 * @sessionId: session id 1650 * @in_req: Ese beacon report request 1651 * 1652 * function to set ESE beacon request parameters 1653 * 1654 * Return: QDF_STATUS enumeration 1655 */ sme_set_ese_beacon_request(mac_handle_t mac_handle,const uint8_t sessionId,const tCsrEseBeaconReq * in_req)1656 QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle, 1657 const uint8_t sessionId, 1658 const tCsrEseBeaconReq *in_req) 1659 { 1660 QDF_STATUS status; 1661 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1662 tpSirBeaconReportReqInd sme_bcn_rpt_req = NULL; 1663 const tCsrEseBeaconReqParams *bcn_req = NULL; 1664 uint8_t counter = 0; 1665 tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext[0]; 1666 1667 if (sme_rrm_ctx->eseBcnReqInProgress == true) { 1668 sme_err("A Beacon Report Req is already in progress"); 1669 return QDF_STATUS_E_RESOURCES; 1670 } 1671 1672 /* Store the info in RRM context */ 1673 qdf_mem_copy(&sme_rrm_ctx->eseBcnReqInfo, in_req, 1674 sizeof(tCsrEseBeaconReq)); 1675 1676 /* Prepare the request to send to SME. */ 1677 sme_bcn_rpt_req = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); 1678 if (!sme_bcn_rpt_req) 1679 return QDF_STATUS_E_NOMEM; 1680 1681 sme_rrm_ctx->eseBcnReqInProgress = true; 1682 1683 sme_debug("Sending Beacon Report Req to SME"); 1684 1685 sme_bcn_rpt_req->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; 1686 sme_bcn_rpt_req->length = sizeof(tSirBeaconReportReqInd); 1687 wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId, 1688 (struct qdf_mac_addr *)&sme_bcn_rpt_req->bssId); 1689 sme_bcn_rpt_req->channel_info.chan_num = 255; 1690 sme_bcn_rpt_req->channel_list.num_channels = in_req->numBcnReqIe; 1691 sme_bcn_rpt_req->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; 1692 sme_bcn_rpt_req->measurement_idx = 0; 1693 1694 for (counter = 0; counter < in_req->numBcnReqIe; counter++) { 1695 bcn_req = &in_req->bcnReq[counter]; 1696 sme_bcn_rpt_req->fMeasurementtype[counter] = 1697 bcn_req->scanMode; 1698 sme_bcn_rpt_req->measurementDuration[counter] = 1699 SYS_TU_TO_MS(bcn_req->measurementDuration); 1700 sme_bcn_rpt_req->channel_list.chan_freq_lst[counter] = 1701 bcn_req->ch_freq; 1702 } 1703 1704 status = sme_rrm_process_beacon_report_req_ind(mac, sme_bcn_rpt_req); 1705 1706 if (status != QDF_STATUS_SUCCESS) 1707 sme_rrm_ctx->eseBcnReqInProgress = false; 1708 1709 qdf_mem_free(sme_bcn_rpt_req); 1710 1711 return status; 1712 } 1713 1714 /** 1715 * sme_get_tsm_stats() - SME get tsm stats 1716 * @mac_handle: Opaque handle to the global MAC context 1717 * @callback: SME sends back the requested stats using the callback 1718 * @staId: The station ID for which the stats is requested for 1719 * @bssId: bssid 1720 * @pContext: user context to be passed back along with the callback 1721 * @tid: Traffic id 1722 * 1723 * API register a callback to get TSM Stats. 1724 * 1725 * Return: QDF_STATUS enumeration 1726 */ sme_get_tsm_stats(mac_handle_t mac_handle,tCsrTsmStatsCallback callback,struct qdf_mac_addr bssId,void * pContext,uint8_t tid)1727 QDF_STATUS sme_get_tsm_stats(mac_handle_t mac_handle, 1728 tCsrTsmStatsCallback callback, 1729 struct qdf_mac_addr bssId, 1730 void *pContext, uint8_t tid) 1731 { 1732 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1733 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1734 1735 status = sme_acquire_global_lock(&mac->sme); 1736 if (QDF_IS_STATUS_SUCCESS(status)) { 1737 status = csr_get_tsm_stats(mac, callback, 1738 bssId, pContext, 1739 tid); 1740 sme_release_global_lock(&mac->sme); 1741 } 1742 return status; 1743 } 1744 #endif /* FEATURE_WLAN_ESE */ 1745 1746 #ifdef WLAN_FEATURE_ROAM_OFFLOAD sme_get_roam_scan_ch(mac_handle_t mac_handle,uint8_t vdev_id,void * pcontext)1747 QDF_STATUS sme_get_roam_scan_ch(mac_handle_t mac_handle, 1748 uint8_t vdev_id, void *pcontext) 1749 { 1750 struct scheduler_msg msg = {0}; 1751 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1752 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1753 1754 status = sme_acquire_global_lock(&mac->sme); 1755 if (QDF_IS_STATUS_ERROR(status)) 1756 return QDF_STATUS_E_FAILURE; 1757 1758 msg.type = WMA_ROAM_SCAN_CH_REQ; 1759 msg.bodyval = vdev_id; 1760 mac->sme.roam_scan_ch_get_context = pcontext; 1761 1762 if (scheduler_post_message(QDF_MODULE_ID_SME, 1763 QDF_MODULE_ID_WMA, 1764 QDF_MODULE_ID_WMA, 1765 &msg)) { 1766 sme_err("Posting message %d failed", 1767 WMA_ROAM_SCAN_CH_REQ); 1768 mac->sme.roam_scan_ch_get_context = NULL; 1769 sme_release_global_lock(&mac->sme); 1770 return QDF_STATUS_E_FAILURE; 1771 } 1772 1773 sme_release_global_lock(&mac->sme); 1774 return QDF_STATUS_SUCCESS; 1775 } 1776 #endif 1777 1778 /** 1779 * sme_process_dual_mac_config_resp() - Process set Dual mac config response 1780 * @mac: Global MAC pointer 1781 * @msg: Dual mac config response 1782 * 1783 * Processes the dual mac configuration response and invokes the HDD callback 1784 * to process further 1785 */ sme_process_dual_mac_config_resp(struct mac_context * mac,uint8_t * msg)1786 static QDF_STATUS sme_process_dual_mac_config_resp(struct mac_context *mac, 1787 uint8_t *msg) 1788 { 1789 tListElem *entry = NULL; 1790 tSmeCmd *command = NULL; 1791 bool found; 1792 dual_mac_cb callback = NULL; 1793 struct sir_dual_mac_config_resp *param; 1794 1795 param = (struct sir_dual_mac_config_resp *)msg; 1796 if (!param) { 1797 sme_err("Dual mac config resp param is NULL"); 1798 /* Not returning. Need to check if active command list 1799 * needs to be freed 1800 */ 1801 } 1802 1803 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 1804 if (!entry) { 1805 sme_err("No cmd found in active list"); 1806 return QDF_STATUS_E_FAILURE; 1807 } 1808 1809 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 1810 if (!command) { 1811 sme_err("Base address is NULL"); 1812 return QDF_STATUS_E_FAILURE; 1813 } 1814 1815 if (e_sme_command_set_dual_mac_config != command->command) { 1816 sme_err("Command mismatch!"); 1817 return QDF_STATUS_E_FAILURE; 1818 } 1819 1820 callback = command->u.set_dual_mac_cmd.set_dual_mac_cb; 1821 if (callback) { 1822 if (!param) { 1823 sme_err("Callback failed-Dual mac config is NULL"); 1824 } else { 1825 sme_debug("Calling HDD callback for Dual mac config"); 1826 callback(param->status, 1827 command->u.set_dual_mac_cmd.scan_config, 1828 command->u.set_dual_mac_cmd.fw_mode_config); 1829 } 1830 } else { 1831 sme_err("Callback does not exist"); 1832 } 1833 1834 found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK); 1835 if (found) 1836 /* Now put this command back on the available command list */ 1837 csr_release_command(mac, command); 1838 1839 return QDF_STATUS_SUCCESS; 1840 } 1841 1842 #ifdef WLAN_FEATURE_ROAM_OFFLOAD sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle,sme_get_raom_scan_ch_callback cb)1843 QDF_STATUS sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle, 1844 sme_get_raom_scan_ch_callback cb) 1845 { 1846 QDF_STATUS qdf_status; 1847 struct mac_context *mac = MAC_CONTEXT(mac_handle); 1848 1849 qdf_status = sme_acquire_global_lock(&mac->sme); 1850 if (QDF_IS_STATUS_ERROR(qdf_status)) 1851 return qdf_status; 1852 1853 mac->sme.roam_scan_ch_callback = cb; 1854 sme_release_global_lock(&mac->sme); 1855 1856 return qdf_status; 1857 } 1858 1859 /** 1860 * sme_process_roam_scan_ch_list_resp() - Process get roam scan ch list 1861 * response 1862 * @mac: Global MAC pointer 1863 * @msgbuf: pointer to roam scan ch list response 1864 * 1865 * This function checks the roam scan chan list message is for command 1866 * response or a async event and accordingly data is given to user space. 1867 * callback to process further 1868 */ 1869 static void sme_process_roam_scan_ch_list_resp(struct mac_context * mac,struct roam_scan_ch_resp * roam_ch)1870 sme_process_roam_scan_ch_list_resp(struct mac_context *mac, 1871 struct roam_scan_ch_resp *roam_ch) 1872 { 1873 sme_get_raom_scan_ch_callback callback = 1874 mac->sme.roam_scan_ch_callback; 1875 1876 if (!roam_ch) 1877 return; 1878 1879 if (callback) 1880 callback(mac->hdd_handle, roam_ch, 1881 mac->sme.roam_scan_ch_get_context); 1882 } 1883 #else 1884 static void sme_process_roam_scan_ch_list_resp(tpAniSirGlobal mac,struct roam_scan_ch_resp * roam_ch)1885 sme_process_roam_scan_ch_list_resp(tpAniSirGlobal mac, 1886 struct roam_scan_ch_resp *roam_ch) 1887 { 1888 } 1889 #endif 1890 1891 /** 1892 * sme_process_antenna_mode_resp() - Process set antenna mode 1893 * response 1894 * @mac: Global MAC pointer 1895 * @msg: antenna mode response 1896 * 1897 * Processes the antenna mode response and invokes the HDD 1898 * callback to process further 1899 */ sme_process_antenna_mode_resp(struct mac_context * mac,uint8_t * msg)1900 static QDF_STATUS sme_process_antenna_mode_resp(struct mac_context *mac, 1901 uint8_t *msg) 1902 { 1903 tListElem *entry; 1904 tSmeCmd *command; 1905 bool found; 1906 void *context = NULL; 1907 antenna_mode_cb callback; 1908 struct sir_antenna_mode_resp *param; 1909 1910 param = (struct sir_antenna_mode_resp *)msg; 1911 if (!param) 1912 sme_err("set antenna mode resp is NULL"); 1913 /* Not returning. Need to check if active command list 1914 * needs to be freed 1915 */ 1916 1917 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 1918 if (!entry) { 1919 sme_err("No cmd found in active list"); 1920 return QDF_STATUS_E_FAILURE; 1921 } 1922 1923 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 1924 if (!command) { 1925 sme_err("Base address is NULL"); 1926 return QDF_STATUS_E_FAILURE; 1927 } 1928 1929 if (e_sme_command_set_antenna_mode != command->command) { 1930 sme_err("Command mismatch!"); 1931 return QDF_STATUS_E_FAILURE; 1932 } 1933 1934 context = command->u.set_antenna_mode_cmd.set_antenna_mode_ctx; 1935 callback = command->u.set_antenna_mode_cmd.set_antenna_mode_resp; 1936 if (callback) { 1937 if (!param) 1938 sme_err("Set antenna mode call back is NULL"); 1939 else 1940 callback(param->status, context); 1941 } else { 1942 sme_err("Callback does not exist"); 1943 } 1944 1945 found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK); 1946 if (found) 1947 /* Now put this command back on the available command list */ 1948 csr_release_command(mac, command); 1949 1950 return QDF_STATUS_SUCCESS; 1951 } 1952 1953 #ifdef WLAN_SUPPORT_TWT 1954 /** 1955 * sme_sap_twt_is_command_in_progress() - Based on the input peer mac address 1956 * invoke the appropriate function to check if the given command is in progress 1957 * @psoc: Pointer to psoc object 1958 * @vdev_id: Vdev id 1959 * @peer_mac: Peer MAC address 1960 * @dialog_id: Dialog id 1961 * @cmd: command 1962 * 1963 * If the input @peer_mac is a broadcast MAC address then the expectation is 1964 * to iterate through the list of all peers and check for any given @dialog_id 1965 * if the command @cmd is in progress. 1966 * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always 1967 * be TWT_ALL_SESSIONS_DIALOG_ID. 1968 * For ex: If TWT teardown command is issued on a particular @dialog_id and 1969 * non-broadcast peer mac and FW response is not yet received then for that 1970 * particular @dialog_id and @peer_mac, TWT teardown is the active command, 1971 * then if the driver receives another TWT teardown request with broadcast 1972 * peer mac, then API mlme_twt_any_peer_cmd_in_progress() shall iterate 1973 * through the list of all peers and returns command in progress as true. 1974 * 1975 * If the input @peer_mac is a non-broadcast MAC address then 1976 * mlme_sap_twt_peer_is_cmd_in_progress() shall check only for that 1977 * particular @peer_mac and @dialog_id. 1978 * 1979 * Return: true if command is in progress, false otherwise 1980 */ 1981 static bool sme_sap_twt_is_command_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)1982 sme_sap_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc, 1983 uint8_t vdev_id, 1984 struct qdf_mac_addr *peer_mac, 1985 uint8_t dialog_id, 1986 enum wlan_twt_commands cmd) 1987 { 1988 if (qdf_is_macaddr_broadcast(peer_mac)) { 1989 return mlme_twt_any_peer_cmd_in_progress(psoc, vdev_id, 1990 dialog_id, cmd); 1991 } else { 1992 return mlme_sap_twt_peer_is_cmd_in_progress(psoc, peer_mac, 1993 dialog_id, cmd); 1994 } 1995 } 1996 1997 /** 1998 * sme_sap_add_twt_session() - Based on the input peer mac address 1999 * invoke the appropriate function to add dialog_id to the TWT session context 2000 * @psoc: Pointer to psoc object 2001 * @vdev_id: Vdev id 2002 * @peer_mac: Peer MAC address 2003 * @dialog_id: Dialog id 2004 * 2005 * If the input @peer_mac is a broadcast MAC address then there is nothing 2006 * to do, because the initialized structure is already in the expected format 2007 * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always 2008 * be TWT_ALL_SESSIONS_DIALOG_ID. 2009 * 2010 * If the input @peer_mac is a non-broadcast MAC address then 2011 * mlme_add_twt_session() shall add the @dialog_id to the @peer_mac 2012 * TWT session context. 2013 * 2014 * Return: None 2015 */ 2016 static void sme_sap_add_twt_session(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)2017 sme_sap_add_twt_session(struct wlan_objmgr_psoc *psoc, 2018 uint8_t vdev_id, 2019 struct qdf_mac_addr *peer_mac, 2020 uint8_t dialog_id) 2021 { 2022 if (!qdf_is_macaddr_broadcast(peer_mac)) 2023 mlme_add_twt_session(psoc, peer_mac, dialog_id); 2024 } 2025 2026 /** 2027 * sme_sap_set_twt_command_in_progress() - Based on the input peer mac address 2028 * invoke the appropriate function to set the command is in progress 2029 * @psoc: Pointer to psoc object 2030 * @vdev_id: Vdev id 2031 * @peer_mac: Peer MAC address 2032 * @dialog_id: Dialog id 2033 * @cmd: command 2034 * 2035 * If the input @peer_mac is a broadcast MAC address then the expectation is 2036 * to iterate through the list of all peers and set the active command to @cmd 2037 * for the given @dialog_id 2038 * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always 2039 * be TWT_ALL_SESSIONS_DIALOG_ID. 2040 * For ex: If TWT teardown command is issued on broadcast @peer_mac, then 2041 * it is same as issuing TWT teardown for all the peers (all TWT sessions). 2042 * Invoking mlme_sap_set_twt_all_peers_cmd_in_progress() shall iterate through 2043 * all the peers and set the active command to @cmd. 2044 * 2045 * If the input @peer_mac is a non-broadcast MAC address then 2046 * mlme_set_twt_command_in_progress() shall set the active command to @cmd 2047 * only for that particular @peer_mac and @dialog_id. 2048 * 2049 * Return: QDF_STATUS 2050 */ 2051 static QDF_STATUS sme_sap_set_twt_command_in_progress(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id,enum wlan_twt_commands cmd)2052 sme_sap_set_twt_command_in_progress(struct wlan_objmgr_psoc *psoc, 2053 uint8_t vdev_id, 2054 struct qdf_mac_addr *peer_mac, 2055 uint8_t dialog_id, 2056 enum wlan_twt_commands cmd) 2057 { 2058 if (qdf_is_macaddr_broadcast(peer_mac)) { 2059 return mlme_sap_set_twt_all_peers_cmd_in_progress(psoc, 2060 vdev_id, 2061 dialog_id, 2062 cmd); 2063 } else { 2064 return mlme_set_twt_command_in_progress(psoc, peer_mac, 2065 dialog_id, cmd); 2066 } 2067 } 2068 2069 /** 2070 * sme_sap_init_twt_context() - Based on the input peer mac address 2071 * invoke the appropriate function to initialize the TWT session context 2072 * @psoc: Pointer to psoc object 2073 * @vdev_id: Vdev id 2074 * @peer_mac: Peer MAC address 2075 * @dialog_id: Dialog id 2076 * 2077 * If the input @peer_mac is a broadcast MAC address then the expectation is 2078 * to iterate through the list of all peers and initialize the TWT session 2079 * context 2080 * Note: If @peer_mac is broadcast MAC address then @dialog_id shall always 2081 * be TWT_ALL_SESSIONS_DIALOG_ID. 2082 * For ex: If TWT teardown command is issued on broadcast @peer_mac, then 2083 * it is same as issuing TWT teardown for all the peers (all TWT sessions). 2084 * Then active command for all the peers is set to @WLAN_TWT_TERMINATE. 2085 * Upon receiving the TWT teardown WMI event, mlme_init_all_peers_twt_context() 2086 * shall iterate through the list of all peers and initializes the TWT session 2087 * context back to its initial state. 2088 * 2089 * If the input @peer_mac is a non-broadcast MAC address then 2090 * mlme_init_twt_context() shall initialize the TWT session context 2091 * only for that particular @peer_mac and @dialog_id. 2092 * 2093 * Return: QDF_STATUS 2094 */ 2095 static QDF_STATUS sme_sap_init_twt_context(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint8_t dialog_id)2096 sme_sap_init_twt_context(struct wlan_objmgr_psoc *psoc, 2097 uint8_t vdev_id, 2098 struct qdf_mac_addr *peer_mac, 2099 uint8_t dialog_id) 2100 { 2101 if (qdf_is_macaddr_broadcast(peer_mac)) { 2102 return mlme_init_all_peers_twt_context(psoc, vdev_id, 2103 dialog_id); 2104 } else { 2105 return mlme_init_twt_context(psoc, peer_mac, dialog_id); 2106 } 2107 } 2108 2109 /** 2110 * sme_process_twt_add_renego_failure() - Process TWT re-negotiation failure 2111 * 2112 * @mac: Global MAC pointer 2113 * @add_dialog_event: pointer to event buf containing twt response parameters 2114 * 2115 * Return: None 2116 */ 2117 static void sme_process_twt_add_renego_failure(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2118 sme_process_twt_add_renego_failure(struct mac_context *mac, 2119 struct wma_twt_add_dialog_complete_event *add_dialog_event) 2120 { 2121 twt_add_dialog_cb callback; 2122 2123 /* Reset the active TWT command to none */ 2124 mlme_set_twt_command_in_progress( 2125 mac->psoc, 2126 (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, 2127 add_dialog_event->params.dialog_id, WLAN_TWT_NONE); 2128 2129 callback = mac->sme.twt_add_dialog_cb; 2130 if (callback) 2131 callback(mac->psoc, add_dialog_event, true); 2132 } 2133 2134 /** 2135 * sme_process_twt_add_initial_nego() - Process initial TWT setup or 2136 * re-negotiation successful setup 2137 * @mac: Global MAC pointer 2138 * @add_dialog_event: pointer to event buf containing twt response parameters 2139 * 2140 * Return: None 2141 */ 2142 static void sme_process_twt_add_initial_nego(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2143 sme_process_twt_add_initial_nego(struct mac_context *mac, 2144 struct wma_twt_add_dialog_complete_event *add_dialog_event) 2145 { 2146 twt_add_dialog_cb callback; 2147 2148 callback = mac->sme.twt_add_dialog_cb; 2149 if (callback) 2150 callback(mac->psoc, add_dialog_event, false); 2151 2152 /* Reset the active TWT command to none */ 2153 mlme_set_twt_command_in_progress( 2154 mac->psoc, 2155 (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, 2156 add_dialog_event->params.dialog_id, WLAN_TWT_NONE); 2157 2158 if (add_dialog_event->params.status) { 2159 /* Clear the stored TWT dialog ID as TWT setup failed */ 2160 ucfg_mlme_init_twt_context(mac->psoc, (struct qdf_mac_addr *) 2161 add_dialog_event->params.peer_macaddr, 2162 add_dialog_event->params.dialog_id); 2163 return; 2164 } 2165 2166 ucfg_mlme_set_twt_setup_done(mac->psoc, (struct qdf_mac_addr *) 2167 add_dialog_event->params.peer_macaddr, 2168 add_dialog_event->params.dialog_id, true); 2169 2170 ucfg_mlme_set_twt_session_state( 2171 mac->psoc, 2172 (struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr, 2173 add_dialog_event->params.dialog_id, 2174 WLAN_TWT_SETUP_STATE_ACTIVE); 2175 } 2176 2177 /** 2178 * sme_process_twt_add_dialog_event() - Process twt add dialog event 2179 * response from firmware 2180 * @mac: Global MAC pointer 2181 * @add_dialog_event: pointer to event buf containing twt response parameters 2182 * 2183 * Return: None 2184 */ 2185 static void sme_process_twt_add_dialog_event(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2186 sme_process_twt_add_dialog_event(struct mac_context *mac, 2187 struct wma_twt_add_dialog_complete_event 2188 *add_dialog_event) 2189 { 2190 bool is_evt_allowed; 2191 bool setup_done; 2192 enum WMI_HOST_ADD_TWT_STATUS status = add_dialog_event->params.status; 2193 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 2194 enum QDF_OPMODE opmode; 2195 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2196 twt_add_dialog_cb callback; 2197 2198 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, 2199 add_dialog_event->params.vdev_id); 2200 2201 qdf_status = sme_acquire_global_lock(&mac->sme); 2202 if (QDF_IS_STATUS_ERROR(qdf_status)) 2203 return; 2204 2205 switch (opmode) { 2206 case QDF_SAP_MODE: 2207 callback = mac->sme.twt_add_dialog_cb; 2208 if (callback) 2209 callback(mac->psoc, add_dialog_event, false); 2210 break; 2211 case QDF_STA_MODE: 2212 is_evt_allowed = mlme_twt_is_command_in_progress( 2213 mac->psoc, (struct qdf_mac_addr *) 2214 add_dialog_event->params.peer_macaddr, 2215 add_dialog_event->params.dialog_id, 2216 WLAN_TWT_SETUP, &active_cmd); 2217 2218 if (!is_evt_allowed) { 2219 sme_debug("Drop TWT add dialog event for dialog_id:%d status:%d active_cmd:%d", 2220 add_dialog_event->params.dialog_id, status, 2221 active_cmd); 2222 sme_release_global_lock(&mac->sme); 2223 return; 2224 } 2225 2226 setup_done = ucfg_mlme_is_twt_setup_done( 2227 mac->psoc, (struct qdf_mac_addr *) 2228 add_dialog_event->params.peer_macaddr, 2229 add_dialog_event->params.dialog_id); 2230 sme_debug("setup_done:%d status:%d", setup_done, status); 2231 2232 if (setup_done && status) { 2233 /*This is re-negotiation failure case */ 2234 sme_process_twt_add_renego_failure(mac, 2235 add_dialog_event); 2236 } else { 2237 sme_process_twt_add_initial_nego(mac, 2238 add_dialog_event); 2239 } 2240 break; 2241 default: 2242 sme_debug("TWT Setup is not supported on %s", 2243 qdf_opmode_str(opmode)); 2244 } 2245 2246 sme_release_global_lock(&mac->sme); 2247 return; 2248 } 2249 2250 static bool sme_is_twt_teardown_failed(enum WMI_HOST_DEL_TWT_STATUS teardown_status)2251 sme_is_twt_teardown_failed(enum WMI_HOST_DEL_TWT_STATUS teardown_status) 2252 { 2253 switch (teardown_status) { 2254 case WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_NOT_EXIST: 2255 case WMI_HOST_DEL_TWT_STATUS_INVALID_PARAM: 2256 case WMI_HOST_DEL_TWT_STATUS_DIALOG_ID_BUSY: 2257 case WMI_HOST_DEL_TWT_STATUS_NO_RESOURCE: 2258 case WMI_HOST_DEL_TWT_STATUS_NO_ACK: 2259 case WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR: 2260 return true; 2261 default: 2262 return false; 2263 } 2264 2265 return false; 2266 } 2267 2268 static void sme_process_sta_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2269 sme_process_sta_twt_del_dialog_event( 2270 struct mac_context *mac, 2271 struct wmi_twt_del_dialog_complete_event_param *param) 2272 { 2273 twt_del_dialog_cb callback; 2274 bool is_evt_allowed, usr_cfg_ps_enable; 2275 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 2276 2277 is_evt_allowed = mlme_twt_is_command_in_progress( 2278 mac->psoc, (struct qdf_mac_addr *) 2279 param->peer_macaddr, param->dialog_id, 2280 WLAN_TWT_TERMINATE, &active_cmd); 2281 2282 if (!is_evt_allowed && 2283 param->dialog_id != TWT_ALL_SESSIONS_DIALOG_ID && 2284 param->status != WMI_HOST_DEL_TWT_STATUS_ROAMING && 2285 param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN && 2286 param->status != WMI_HOST_DEL_TWT_STATUS_CONCURRENCY) { 2287 sme_debug("Drop TWT Del dialog event for dialog_id:%d status:%d active_cmd:%d", 2288 param->dialog_id, param->status, active_cmd); 2289 2290 return; 2291 } 2292 2293 usr_cfg_ps_enable = mlme_get_user_ps(mac->psoc, param->vdev_id); 2294 if (!usr_cfg_ps_enable && 2295 param->status == WMI_HOST_DEL_TWT_STATUS_OK) 2296 param->status = WMI_HOST_DEL_TWT_STATUS_PS_DISABLE_TEARDOWN; 2297 2298 callback = mac->sme.twt_del_dialog_cb; 2299 if (callback) 2300 callback(mac->psoc, param); 2301 2302 if (param->status == WMI_HOST_DEL_TWT_STATUS_ROAMING || 2303 param->status == WMI_HOST_DEL_TWT_STATUS_CONCURRENCY) 2304 mlme_twt_set_wait_for_notify(mac->psoc, param->vdev_id, true); 2305 2306 /* Reset the active TWT command to none */ 2307 mlme_set_twt_command_in_progress(mac->psoc, (struct qdf_mac_addr *) 2308 param->peer_macaddr, param->dialog_id, 2309 WLAN_TWT_NONE); 2310 2311 if (sme_is_twt_teardown_failed(param->status)) 2312 return; 2313 2314 ucfg_mlme_set_twt_setup_done(mac->psoc, (struct qdf_mac_addr *) 2315 param->peer_macaddr, param->dialog_id, 2316 false); 2317 2318 ucfg_mlme_set_twt_session_state(mac->psoc, (struct qdf_mac_addr *) 2319 param->peer_macaddr, param->dialog_id, 2320 WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED); 2321 2322 mlme_init_twt_context(mac->psoc, (struct qdf_mac_addr *) 2323 param->peer_macaddr, param->dialog_id); 2324 } 2325 2326 /** 2327 * sme_process_twt_del_dialog_event() - Process twt del dialog event 2328 * response from firmware 2329 * @mac: Global MAC pointer 2330 * @param: pointer to wmi_twt_del_dialog_complete_event_param buffer 2331 * 2332 * Return: None 2333 */ 2334 static void sme_process_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2335 sme_process_twt_del_dialog_event( 2336 struct mac_context *mac, 2337 struct wmi_twt_del_dialog_complete_event_param *param) 2338 { 2339 twt_del_dialog_cb callback; 2340 enum QDF_OPMODE opmode; 2341 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2342 2343 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id); 2344 2345 qdf_status = sme_acquire_global_lock(&mac->sme); 2346 if (QDF_IS_STATUS_ERROR(qdf_status)) 2347 return; 2348 2349 switch (opmode) { 2350 case QDF_SAP_MODE: 2351 callback = mac->sme.twt_del_dialog_cb; 2352 if (callback) 2353 callback(mac->psoc, param); 2354 2355 /* 2356 * If this is an unsolicited TWT del event initiated from the 2357 * peer, then no need to clear the active command in progress 2358 */ 2359 if (param->status != 2360 WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN) { 2361 /* Reset the active TWT command to none */ 2362 sme_sap_set_twt_command_in_progress(mac->psoc, 2363 param->vdev_id, 2364 (struct qdf_mac_addr *)param->peer_macaddr, 2365 param->dialog_id, WLAN_TWT_NONE); 2366 sme_sap_init_twt_context(mac->psoc, param->vdev_id, 2367 (struct qdf_mac_addr *) 2368 param->peer_macaddr, param->dialog_id); 2369 } 2370 break; 2371 case QDF_STA_MODE: 2372 sme_process_sta_twt_del_dialog_event(mac, param); 2373 break; 2374 default: 2375 sme_debug("TWT Teardown is not supported on %s", 2376 qdf_opmode_str(opmode)); 2377 } 2378 2379 sme_release_global_lock(&mac->sme); 2380 return; 2381 } 2382 2383 /** 2384 * sme_process_twt_pause_dialog_event() - Process twt pause dialog event 2385 * response from firmware 2386 * @mac: Global MAC pointer 2387 * @param: pointer to wmi_twt_pause_dialog_complete_event_param buffer 2388 * 2389 * Return: None 2390 */ 2391 static void sme_process_twt_pause_dialog_event(struct mac_context * mac,struct wmi_twt_pause_dialog_complete_event_param * param)2392 sme_process_twt_pause_dialog_event( 2393 struct mac_context *mac, 2394 struct wmi_twt_pause_dialog_complete_event_param *param) 2395 { 2396 twt_pause_dialog_cb callback; 2397 enum QDF_OPMODE opmode; 2398 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2399 2400 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id); 2401 2402 qdf_status = sme_acquire_global_lock(&mac->sme); 2403 if (QDF_IS_STATUS_ERROR(qdf_status)) 2404 return; 2405 2406 switch (opmode) { 2407 case QDF_SAP_MODE: 2408 callback = mac->sme.twt_pause_dialog_cb; 2409 if (callback) 2410 callback(mac->psoc, param); 2411 break; 2412 case QDF_STA_MODE: 2413 callback = mac->sme.twt_pause_dialog_cb; 2414 if (callback) 2415 callback(mac->psoc, param); 2416 2417 ucfg_mlme_set_twt_session_state( 2418 mac->psoc, (struct qdf_mac_addr *) 2419 param->peer_macaddr, param->dialog_id, 2420 WLAN_TWT_SETUP_STATE_SUSPEND); 2421 2422 /*Reset the active TWT command to none */ 2423 mlme_set_twt_command_in_progress( 2424 mac->psoc, (struct qdf_mac_addr *) 2425 param->peer_macaddr, param->dialog_id, 2426 WLAN_TWT_NONE); 2427 break; 2428 default: 2429 sme_debug("TWT Pause is not supported on %s", 2430 qdf_opmode_str(opmode)); 2431 } 2432 2433 sme_release_global_lock(&mac->sme); 2434 return; 2435 } 2436 2437 /** 2438 * sme_process_twt_nudge_dialog_event() - Process twt nudge dialog event 2439 * response from firmware 2440 * @mac: Global MAC pointer 2441 * @param: pointer to wmi_twt_nudge_dialog_complete_event_param buffer 2442 * 2443 * Return: None 2444 */ 2445 static void sme_process_twt_nudge_dialog_event(struct mac_context * mac,struct wmi_twt_nudge_dialog_complete_event_param * param)2446 sme_process_twt_nudge_dialog_event(struct mac_context *mac, 2447 struct wmi_twt_nudge_dialog_complete_event_param *param) 2448 { 2449 twt_nudge_dialog_cb callback; 2450 bool is_evt_allowed; 2451 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 2452 enum QDF_OPMODE opmode; 2453 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2454 2455 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id); 2456 2457 qdf_status = sme_acquire_global_lock(&mac->sme); 2458 if (QDF_IS_STATUS_ERROR(qdf_status)) 2459 return; 2460 2461 switch (opmode) { 2462 case QDF_SAP_MODE: 2463 callback = mac->sme.twt_nudge_dialog_cb; 2464 if (callback) 2465 callback(mac->psoc, param); 2466 break; 2467 case QDF_STA_MODE: 2468 is_evt_allowed = mlme_twt_is_command_in_progress( 2469 mac->psoc, (struct qdf_mac_addr *) 2470 param->peer_macaddr, param->dialog_id, 2471 WLAN_TWT_NUDGE, &active_cmd); 2472 if (!is_evt_allowed && 2473 param->dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) { 2474 sme_debug("Nudge event dropped active_cmd:%d", 2475 active_cmd); 2476 goto fail; 2477 } 2478 2479 callback = mac->sme.twt_nudge_dialog_cb; 2480 if (callback) 2481 callback(mac->psoc, param); 2482 /* Reset the active TWT command to none */ 2483 mlme_set_twt_command_in_progress( 2484 mac->psoc, (struct qdf_mac_addr *) 2485 param->peer_macaddr, param->dialog_id, 2486 WLAN_TWT_NONE); 2487 break; 2488 default: 2489 sme_debug("TWT Nudge is not supported on %s", 2490 qdf_opmode_str(opmode)); 2491 } 2492 2493 fail: 2494 sme_release_global_lock(&mac->sme); 2495 return; 2496 } 2497 2498 /** 2499 * sme_process_twt_resume_dialog_event() - Process twt resume dialog event 2500 * response from firmware 2501 * @mac: Global MAC pointer 2502 * @param: pointer to wmi_twt_resume_dialog_complete_event_param buffer 2503 * 2504 * Return: None 2505 */ 2506 static void sme_process_twt_resume_dialog_event(struct mac_context * mac,struct wmi_twt_resume_dialog_complete_event_param * param)2507 sme_process_twt_resume_dialog_event( 2508 struct mac_context *mac, 2509 struct wmi_twt_resume_dialog_complete_event_param *param) 2510 { 2511 twt_resume_dialog_cb callback; 2512 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; 2513 enum QDF_OPMODE opmode; 2514 2515 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, param->vdev_id); 2516 2517 qdf_status = sme_acquire_global_lock(&mac->sme); 2518 if (QDF_IS_STATUS_ERROR(qdf_status)) 2519 return; 2520 2521 switch (opmode) { 2522 case QDF_SAP_MODE: 2523 callback = mac->sme.twt_resume_dialog_cb; 2524 if (callback) 2525 callback(mac->psoc, param); 2526 break; 2527 case QDF_STA_MODE: 2528 callback = mac->sme.twt_resume_dialog_cb; 2529 if (callback) 2530 callback(mac->psoc, param); 2531 2532 ucfg_mlme_set_twt_session_state( 2533 mac->psoc, (struct qdf_mac_addr *) 2534 param->peer_macaddr, param->dialog_id, 2535 WLAN_TWT_SETUP_STATE_ACTIVE); 2536 2537 /* Reset the active TWT command to none */ 2538 mlme_set_twt_command_in_progress( 2539 mac->psoc, (struct qdf_mac_addr *) 2540 param->peer_macaddr, param->dialog_id, 2541 WLAN_TWT_NONE); 2542 break; 2543 default: 2544 sme_debug("TWT Resume is not supported on %s", 2545 qdf_opmode_str(opmode)); 2546 } 2547 2548 sme_release_global_lock(&mac->sme); 2549 return; 2550 } 2551 2552 /** 2553 * sme_process_twt_notify_event() - Process twt ready for setup notification 2554 * event from firmware 2555 * @mac: Global MAC pointer 2556 * @twt_notify_event: pointer to event buf containing twt notify parameters 2557 * 2558 * Return: None 2559 */ 2560 static void sme_process_twt_notify_event(struct mac_context * mac,struct wmi_twt_notify_event_param * notify_event)2561 sme_process_twt_notify_event(struct mac_context *mac, 2562 struct wmi_twt_notify_event_param *notify_event) 2563 { 2564 twt_notify_cb callback; 2565 2566 mlme_twt_set_wait_for_notify(mac->psoc, notify_event->vdev_id, false); 2567 callback = mac->sme.twt_notify_cb; 2568 if (callback) 2569 callback(mac->psoc, notify_event); 2570 } 2571 2572 /** 2573 * sme_twt_update_beacon_template() - API to send beacon update to fw 2574 * @mac: Global MAC pointer 2575 * 2576 * Return: None 2577 */ sme_twt_update_beacon_template(mac_handle_t mac_handle)2578 void sme_twt_update_beacon_template(mac_handle_t mac_handle) 2579 { 2580 struct mac_context *mac = MAC_CONTEXT(mac_handle); 2581 2582 csr_update_beacon(mac); 2583 } 2584 2585 #else 2586 static void sme_process_twt_add_dialog_event(struct mac_context * mac,struct wma_twt_add_dialog_complete_event * add_dialog_event)2587 sme_process_twt_add_dialog_event(struct mac_context *mac, 2588 struct wma_twt_add_dialog_complete_event *add_dialog_event) 2589 { 2590 } 2591 2592 static void sme_process_twt_del_dialog_event(struct mac_context * mac,struct wmi_twt_del_dialog_complete_event_param * param)2593 sme_process_twt_del_dialog_event( 2594 struct mac_context *mac, 2595 struct wmi_twt_del_dialog_complete_event_param *param) 2596 { 2597 } 2598 2599 static void sme_process_twt_pause_dialog_event(struct mac_context * mac,struct wmi_twt_pause_dialog_complete_event_param * param)2600 sme_process_twt_pause_dialog_event(struct mac_context *mac, 2601 struct wmi_twt_pause_dialog_complete_event_param *param) 2602 { 2603 } 2604 2605 static void sme_process_twt_resume_dialog_event(struct mac_context * mac,struct wmi_twt_resume_dialog_complete_event_param * param)2606 sme_process_twt_resume_dialog_event(struct mac_context *mac, 2607 struct wmi_twt_resume_dialog_complete_event_param *param) 2608 { 2609 } 2610 2611 static void sme_process_twt_nudge_dialog_event(struct mac_context * mac,struct wmi_twt_nudge_dialog_complete_event_param * param)2612 sme_process_twt_nudge_dialog_event(struct mac_context *mac, 2613 struct wmi_twt_nudge_dialog_complete_event_param *param) 2614 { 2615 } 2616 2617 static void sme_process_twt_notify_event(struct mac_context * mac,struct wmi_twt_notify_event_param * notify_event)2618 sme_process_twt_notify_event(struct mac_context *mac, 2619 struct wmi_twt_notify_event_param *notify_event) 2620 { 2621 } 2622 #endif 2623 sme_link_lost_ind(struct mac_context * mac,struct sir_lost_link_info * ind)2624 static void sme_link_lost_ind(struct mac_context *mac, 2625 struct sir_lost_link_info *ind) 2626 { 2627 struct cm_roam_values_copy src_cfg = {}; 2628 2629 if (ind) { 2630 src_cfg.int_value = ind->rssi; 2631 wlan_cm_roam_cfg_set_value(mac->psoc, ind->vdev_id, 2632 LOST_LINK_RSSI, &src_cfg); 2633 } 2634 if (mac->sme.lost_link_info_cb) 2635 mac->sme.lost_link_info_cb(mac->hdd_handle, ind); 2636 } 2637 2638 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE sme_indicate_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2639 static void sme_indicate_chan_info_event(struct mac_context *mac, 2640 struct channel_status *chan_stats, 2641 uint8_t vdev_id) 2642 { 2643 struct csr_roam_info *roam_info; 2644 struct wlan_objmgr_vdev *vdev; 2645 eRoamCmdStatus roam_status; 2646 eCsrRoamResult roam_result; 2647 enum QDF_OPMODE mode; 2648 2649 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 2650 WLAN_LEGACY_SME_ID); 2651 if (!vdev) { 2652 sme_err("vdev not found for vdev %d", vdev_id); 2653 return; 2654 } 2655 2656 mode = wlan_vdev_mlme_get_opmode(vdev); 2657 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 2658 2659 if (mode != QDF_SAP_MODE) 2660 return; 2661 2662 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 2663 if (!roam_info) 2664 return; 2665 2666 roam_info->chan_info_freq = chan_stats->channel_freq; 2667 roam_status = eCSR_ROAM_CHANNEL_INFO_EVENT_IND; 2668 roam_result = eCSR_ROAM_RESULT_NONE; 2669 2670 /* Indicate channel info event to SAP */ 2671 csr_roam_call_callback(mac, vdev_id, roam_info, 2672 roam_status, roam_result); 2673 2674 qdf_mem_free(roam_info); 2675 } 2676 #else sme_indicate_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2677 static void sme_indicate_chan_info_event(struct mac_context *mac, 2678 struct channel_status *chan_stats, 2679 uint8_t vdev_id) 2680 { 2681 } 2682 #endif 2683 sme_process_chan_info_event(struct mac_context * mac,struct channel_status * chan_stats,uint8_t vdev_id)2684 static void sme_process_chan_info_event(struct mac_context *mac, 2685 struct channel_status *chan_stats, 2686 uint8_t vdev_id) 2687 { 2688 if (!chan_stats) { 2689 sme_err("Chan info report is NULL\n"); 2690 return; 2691 } 2692 2693 wlan_cp_stats_update_chan_info(mac->psoc, chan_stats, vdev_id); 2694 2695 sme_indicate_chan_info_event(mac, chan_stats, vdev_id); 2696 } 2697 2698 /** 2699 * sme_process_sap_ch_width_update_rsp() - Process ch_width update response 2700 * @mac: Global MAC pointer 2701 * @msg: ch_width update response 2702 * 2703 * Processes the ch_width update response and invokes the HDD 2704 * callback to process further 2705 */ 2706 static QDF_STATUS sme_process_sap_ch_width_update_rsp(struct mac_context * mac,uint8_t * msg)2707 sme_process_sap_ch_width_update_rsp(struct mac_context *mac, uint8_t *msg) 2708 { 2709 tListElem *entry = NULL; 2710 tSmeCmd *command = NULL; 2711 bool found; 2712 struct sir_bcn_update_rsp *param; 2713 enum policy_mgr_conn_update_reason reason; 2714 uint32_t request_id; 2715 uint8_t vdev_id; 2716 QDF_STATUS status = QDF_STATUS_E_NOMEM; 2717 2718 param = (struct sir_bcn_update_rsp *)msg; 2719 if (!param) 2720 sme_err("ch_width update resp param is NULL"); 2721 /* Not returning. Need to check if active command list 2722 * needs to be freed 2723 */ 2724 2725 if (param && param->reason != REASON_CH_WIDTH_UPDATE) { 2726 sme_err("reason not ch_width update"); 2727 return QDF_STATUS_E_INVAL; 2728 } 2729 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 2730 if (!entry) { 2731 sme_err("No cmd found in active list"); 2732 return QDF_STATUS_E_FAILURE; 2733 } 2734 2735 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 2736 if (!command) { 2737 sme_err("Base address is NULL"); 2738 return QDF_STATUS_E_FAILURE; 2739 } 2740 2741 if (e_sme_command_sap_ch_width_update != command->command) { 2742 sme_err("Command mismatch!"); 2743 return QDF_STATUS_E_FAILURE; 2744 } 2745 reason = command->u.bw_update_cmd.reason; 2746 request_id = command->u.bw_update_cmd.request_id; 2747 vdev_id = command->u.bw_update_cmd.conc_vdev_id; 2748 if (param) 2749 status = param->status; 2750 sme_debug("vdev %d reason %d status %d cm_id 0x%x", 2751 vdev_id, reason, status, request_id); 2752 2753 if (reason == POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA) { 2754 sme_debug("Continue channel switch for STA on vdev %d", 2755 vdev_id); 2756 csr_sta_continue_csa(mac, vdev_id); 2757 } else if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT) { 2758 sme_debug("Continue connect/reassoc on vdev %d reason %d status %d cm_id 0x%x", 2759 vdev_id, reason, status, request_id); 2760 wlan_cm_handle_hw_mode_change_resp(mac->pdev, vdev_id, 2761 request_id, status); 2762 } 2763 2764 policy_mgr_set_connection_update(mac->psoc); 2765 2766 found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK); 2767 if (found) { 2768 /* Now put this command back on the available command list */ 2769 csr_release_command(mac, command); 2770 } 2771 2772 return QDF_STATUS_SUCCESS; 2773 } 2774 sme_process_msg(struct mac_context * mac,struct scheduler_msg * pMsg)2775 QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) 2776 { 2777 QDF_STATUS status = QDF_STATUS_E_FAILURE; 2778 2779 if (!pMsg) { 2780 sme_err("Empty message for SME"); 2781 return status; 2782 } 2783 status = sme_acquire_global_lock(&mac->sme); 2784 if (!QDF_IS_STATUS_SUCCESS(status)) { 2785 if (pMsg->bodyptr) 2786 qdf_mem_free(pMsg->bodyptr); 2787 return status; 2788 } 2789 if (!SME_IS_START(mac)) { 2790 sme_debug("message type %d in stop state ignored", pMsg->type); 2791 if (pMsg->bodyptr) 2792 qdf_mem_free(pMsg->bodyptr); 2793 goto release_lock; 2794 } 2795 switch (pMsg->type) { 2796 case eWNI_SME_ADDTS_RSP: 2797 case eWNI_SME_DELTS_RSP: 2798 case eWNI_SME_DELTS_IND: 2799 case eWNI_SME_FT_AGGR_QOS_RSP: 2800 /* QoS */ 2801 if (pMsg->bodyptr) { 2802 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 2803 status = sme_qos_msg_processor(mac, pMsg->type, 2804 pMsg->bodyptr); 2805 qdf_mem_free(pMsg->bodyptr); 2806 #endif 2807 } else { 2808 sme_err("Empty message for: %d", pMsg->type); 2809 } 2810 break; 2811 case eWNI_SME_NEIGHBOR_REPORT_IND: 2812 case eWNI_SME_BEACON_REPORT_REQ_IND: 2813 case eWNI_SME_CHAN_LOAD_REQ_IND: 2814 if (pMsg->bodyptr) { 2815 status = sme_rrm_msg_processor(mac, pMsg->type, 2816 pMsg->bodyptr); 2817 qdf_mem_free(pMsg->bodyptr); 2818 } else { 2819 sme_err("Empty message for: %d", pMsg->type); 2820 } 2821 break; 2822 case eWNI_SME_VDEV_DELETE_RSP: 2823 if (pMsg->bodyptr) 2824 sme_vdev_self_peer_delete_resp(pMsg->bodyptr); 2825 else 2826 sme_err("Empty message for: %d", pMsg->type); 2827 break; 2828 case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE: 2829 if (pMsg->bodyptr) { 2830 status = sme_handle_generic_change_country_code( 2831 (void *)mac, pMsg->bodyptr); 2832 qdf_mem_free(pMsg->bodyptr); 2833 } else { 2834 sme_err("Empty message for: %d", pMsg->type); 2835 } 2836 break; 2837 case eWNI_SME_UNPROT_MGMT_FRM_IND: 2838 if (pMsg->bodyptr) { 2839 sme_unprotected_mgmt_frm_ind(mac, pMsg->bodyptr); 2840 qdf_mem_free(pMsg->bodyptr); 2841 } else { 2842 sme_err("Empty message for: %d", pMsg->type); 2843 } 2844 break; 2845 #ifdef FEATURE_WLAN_ESE 2846 case eWNI_SME_TSM_IE_IND: 2847 if (pMsg->bodyptr) { 2848 sme_tsm_ie_ind(mac, pMsg->bodyptr); 2849 qdf_mem_free(pMsg->bodyptr); 2850 } else { 2851 sme_err("Empty message for: %d", pMsg->type); 2852 } 2853 break; 2854 #endif /* FEATURE_WLAN_ESE */ 2855 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT 2856 case eWNI_SME_READY_TO_EXTWOW_IND: 2857 if (pMsg->bodyptr) { 2858 sme_process_ready_to_ext_wow(mac, pMsg->bodyptr); 2859 qdf_mem_free(pMsg->bodyptr); 2860 } else { 2861 sme_err("Empty message for: %d", pMsg->type); 2862 } 2863 break; 2864 #endif 2865 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN 2866 case eWNI_SME_AUTO_SHUTDOWN_IND: 2867 if (mac->sme.auto_shutdown_cb) { 2868 sme_debug("Auto shutdown notification"); 2869 mac->sme.auto_shutdown_cb(); 2870 } 2871 break; 2872 #endif 2873 case eWNI_SME_DFS_RADAR_FOUND: 2874 case eWNI_SME_DFS_CAC_COMPLETE: 2875 case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: 2876 case eWNI_SME_CSA_RESTART_RSP: 2877 status = dfs_msg_processor(mac, pMsg); 2878 qdf_mem_free(pMsg->bodyptr); 2879 break; 2880 case eWNI_SME_CHANNEL_CHANGE_RSP: 2881 if (pMsg->bodyptr) { 2882 status = sme_process_channel_change_resp(mac, 2883 pMsg->type, 2884 pMsg->bodyptr); 2885 qdf_mem_free(pMsg->bodyptr); 2886 } else { 2887 sme_err("Empty message for: %d", pMsg->type); 2888 } 2889 break; 2890 case eWNI_SME_STATS_EXT_EVENT: 2891 status = sme_stats_ext_event(mac, pMsg->bodyptr); 2892 qdf_mem_free(pMsg->bodyptr); 2893 break; 2894 case eWNI_SME_FW_STATUS_IND: 2895 status = sme_fw_state_resp(mac); 2896 break; 2897 case eWNI_SME_TSF_EVENT: 2898 if (mac->sme.get_tsf_cb) { 2899 mac->sme.get_tsf_cb(mac->sme.get_tsf_cxt, 2900 (struct stsf *)pMsg->bodyptr); 2901 } 2902 if (pMsg->bodyptr) 2903 qdf_mem_free(pMsg->bodyptr); 2904 break; 2905 case eWNI_SME_LINK_STATUS_IND: 2906 { 2907 tAniGetLinkStatus *pLinkStatus = 2908 (tAniGetLinkStatus *) pMsg->bodyptr; 2909 if (pLinkStatus) { 2910 if (mac->sme.link_status_callback) 2911 mac->sme.link_status_callback( 2912 pLinkStatus->linkStatus, 2913 mac->sme.link_status_context); 2914 2915 mac->sme.link_status_callback = NULL; 2916 mac->sme.link_status_context = NULL; 2917 qdf_mem_free(pLinkStatus); 2918 } 2919 break; 2920 } 2921 case eWNI_SME_MSG_GET_TEMPERATURE_IND: 2922 if (mac->sme.temperature_cb) 2923 mac->sme.temperature_cb(pMsg->bodyval, 2924 mac->sme.temperature_cb_context); 2925 break; 2926 case eWNI_SME_SNR_IND: 2927 { 2928 tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr; 2929 2930 if (pSnrReq) { 2931 if (pSnrReq->snrCallback) { 2932 ((tCsrSnrCallback) 2933 (pSnrReq->snrCallback))(pSnrReq->snr, 2934 pSnrReq->pDevContext); 2935 } 2936 qdf_mem_free(pSnrReq); 2937 } 2938 break; 2939 } 2940 #ifdef FEATURE_WLAN_EXTSCAN 2941 case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND: 2942 if (mac->sme.ext_scan_ind_cb) 2943 mac->sme.ext_scan_ind_cb(mac->hdd_handle, 2944 eSIR_EXTSCAN_FULL_SCAN_RESULT_IND, 2945 pMsg->bodyptr); 2946 else 2947 sme_err("callback not registered to process: %d", 2948 pMsg->type); 2949 2950 qdf_mem_free(pMsg->bodyptr); 2951 break; 2952 case eWNI_SME_EPNO_NETWORK_FOUND_IND: 2953 if (mac->sme.ext_scan_ind_cb) 2954 mac->sme.ext_scan_ind_cb(mac->hdd_handle, 2955 eSIR_EPNO_NETWORK_FOUND_IND, 2956 pMsg->bodyptr); 2957 else 2958 sme_err("callback not registered to process: %d", 2959 pMsg->type); 2960 2961 qdf_mem_free(pMsg->bodyptr); 2962 break; 2963 #endif 2964 case eWNI_SME_SET_HW_MODE_RESP: 2965 if (pMsg->bodyptr) { 2966 status = sme_process_set_hw_mode_resp(mac, 2967 pMsg->bodyptr); 2968 qdf_mem_free(pMsg->bodyptr); 2969 } else { 2970 sme_err("Empty message for: %d", pMsg->type); 2971 } 2972 break; 2973 case eWNI_SME_HW_MODE_TRANS_IND: 2974 if (pMsg->bodyptr) { 2975 status = sme_process_hw_mode_trans_ind(mac, 2976 pMsg->bodyptr); 2977 qdf_mem_free(pMsg->bodyptr); 2978 } else { 2979 sme_err("Empty message for: %d", pMsg->type); 2980 } 2981 break; 2982 case eWNI_SME_NSS_UPDATE_RSP: 2983 if (pMsg->bodyptr) { 2984 status = sme_process_nss_update_resp(mac, 2985 pMsg->bodyptr); 2986 qdf_mem_free(pMsg->bodyptr); 2987 } else { 2988 sme_err("Empty message for: %d", pMsg->type); 2989 } 2990 break; 2991 case eWNI_SME_SET_DUAL_MAC_CFG_RESP: 2992 if (pMsg->bodyptr) { 2993 status = sme_process_dual_mac_config_resp(mac, 2994 pMsg->bodyptr); 2995 qdf_mem_free(pMsg->bodyptr); 2996 } else { 2997 sme_err("Empty message for: %d", pMsg->type); 2998 } 2999 break; 3000 case eWNI_SME_SET_THERMAL_LEVEL_IND: 3001 if (mac->sme.set_thermal_level_cb) 3002 mac->sme.set_thermal_level_cb(mac->hdd_handle, 3003 pMsg->bodyval); 3004 break; 3005 case eWNI_SME_EXT_CHANGE_CHANNEL_IND: 3006 status = sme_extended_change_channel_ind(mac, pMsg->bodyptr); 3007 qdf_mem_free(pMsg->bodyptr); 3008 break; 3009 case eWNI_SME_SET_ANTENNA_MODE_RESP: 3010 if (pMsg->bodyptr) { 3011 status = sme_process_antenna_mode_resp(mac, 3012 pMsg->bodyptr); 3013 qdf_mem_free(pMsg->bodyptr); 3014 } else { 3015 sme_err("Empty message for: %d", pMsg->type); 3016 } 3017 break; 3018 case eWNI_SME_LOST_LINK_INFO_IND: 3019 sme_link_lost_ind(mac, pMsg->bodyptr); 3020 qdf_mem_free(pMsg->bodyptr); 3021 break; 3022 case eWNI_SME_RSO_CMD_STATUS_IND: 3023 if (mac->sme.rso_cmd_status_cb) 3024 mac->sme.rso_cmd_status_cb(mac->hdd_handle, 3025 pMsg->bodyptr); 3026 qdf_mem_free(pMsg->bodyptr); 3027 break; 3028 case eWMI_SME_LL_STATS_IND: 3029 if (mac->sme.link_layer_stats_ext_cb) 3030 mac->sme.link_layer_stats_ext_cb(mac->hdd_handle, 3031 pMsg->bodyptr); 3032 qdf_mem_free(pMsg->bodyptr); 3033 break; 3034 case eWNI_SME_BT_ACTIVITY_INFO_IND: 3035 if (mac->sme.bt_activity_info_cb) 3036 mac->sme.bt_activity_info_cb(mac->hdd_handle, 3037 pMsg->bodyval); 3038 break; 3039 case eWNI_SME_HIDDEN_SSID_RESTART_RSP: 3040 if (mac->sme.hidden_ssid_cb) 3041 mac->sme.hidden_ssid_cb(mac->hdd_handle, pMsg->bodyval); 3042 else 3043 sme_err("callback is NULL"); 3044 break; 3045 case eWNI_SME_ANTENNA_ISOLATION_RSP: 3046 if (pMsg->bodyptr) { 3047 if (mac->sme.get_isolation_cb) 3048 mac->sme.get_isolation_cb( 3049 (struct sir_isolation_resp *)pMsg->bodyptr, 3050 mac->sme.get_isolation_cb_context); 3051 qdf_mem_free(pMsg->bodyptr); 3052 } else { 3053 sme_err("Empty message for: %d", pMsg->type); 3054 } 3055 break; 3056 case eWNI_SME_GET_ROAM_SCAN_CH_LIST_EVENT: 3057 sme_process_roam_scan_ch_list_resp(mac, pMsg->bodyptr); 3058 qdf_mem_free(pMsg->bodyptr); 3059 break; 3060 case eWNI_SME_MONITOR_MODE_VDEV_UP: 3061 status = sme_process_monitor_mode_vdev_up_evt(pMsg->bodyval); 3062 break; 3063 case eWNI_SME_TWT_ADD_DIALOG_EVENT: 3064 sme_process_twt_add_dialog_event(mac, pMsg->bodyptr); 3065 qdf_mem_free(pMsg->bodyptr); 3066 break; 3067 case eWNI_SME_TWT_DEL_DIALOG_EVENT: 3068 sme_process_twt_del_dialog_event(mac, pMsg->bodyptr); 3069 qdf_mem_free(pMsg->bodyptr); 3070 break; 3071 case eWNI_SME_TWT_PAUSE_DIALOG_EVENT: 3072 sme_process_twt_pause_dialog_event(mac, pMsg->bodyptr); 3073 qdf_mem_free(pMsg->bodyptr); 3074 break; 3075 case eWNI_SME_TWT_RESUME_DIALOG_EVENT: 3076 sme_process_twt_resume_dialog_event(mac, pMsg->bodyptr); 3077 qdf_mem_free(pMsg->bodyptr); 3078 break; 3079 case eWNI_SME_TWT_NUDGE_DIALOG_EVENT: 3080 sme_process_twt_nudge_dialog_event(mac, pMsg->bodyptr); 3081 qdf_mem_free(pMsg->bodyptr); 3082 break; 3083 case eWNI_SME_TWT_NOTIFY_EVENT: 3084 sme_process_twt_notify_event(mac, pMsg->bodyptr); 3085 qdf_mem_free(pMsg->bodyptr); 3086 break; 3087 case eWNI_SME_START_BSS_RSP: 3088 csr_roam_roaming_state_start_bss_rsp_processor(mac, 3089 pMsg->bodyptr); 3090 qdf_mem_free(pMsg->bodyptr); 3091 break; 3092 case eWNI_SME_STOP_BSS_RSP: 3093 csr_roam_roaming_state_stop_bss_rsp_processor(mac, 3094 pMsg->bodyptr); 3095 qdf_mem_free(pMsg->bodyptr); 3096 break; 3097 case eWNI_SME_CHAN_INFO_EVENT: 3098 sme_process_chan_info_event(mac, pMsg->bodyptr, pMsg->bodyval); 3099 qdf_mem_free(pMsg->bodyptr); 3100 break; 3101 case eWNI_SME_SAP_CH_WIDTH_UPDATE_RSP: 3102 status = sme_process_sap_ch_width_update_rsp(mac, 3103 pMsg->bodyptr); 3104 qdf_mem_free(pMsg->bodyptr); 3105 break; 3106 default: 3107 3108 if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN) 3109 && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) { 3110 /* CSR */ 3111 if (pMsg->bodyptr) { 3112 status = csr_msg_processor(mac, pMsg->bodyptr); 3113 qdf_mem_free(pMsg->bodyptr); 3114 } else 3115 sme_err("Empty message for: %d", pMsg->type); 3116 } else { 3117 sme_warn("Unknown message type: %d", pMsg->type); 3118 if (pMsg->bodyptr) 3119 qdf_mem_free(pMsg->bodyptr); 3120 } 3121 } /* switch */ 3122 release_lock: 3123 sme_release_global_lock(&mac->sme); 3124 return status; 3125 } 3126 sme_mc_process_handler(struct scheduler_msg * msg)3127 QDF_STATUS sme_mc_process_handler(struct scheduler_msg *msg) 3128 { 3129 struct mac_context *mac_ctx = cds_get_context(QDF_MODULE_ID_SME); 3130 3131 if (!mac_ctx) { 3132 QDF_ASSERT(0); 3133 return QDF_STATUS_E_FAILURE; 3134 } 3135 3136 return sme_process_msg(mac_ctx, msg); 3137 } 3138 3139 /** 3140 * sme_process_nss_update_resp() - Process nss update response 3141 * @mac: Global MAC pointer 3142 * @msg: nss update response 3143 * 3144 * Processes the nss update response and invokes the HDD 3145 * callback to process further 3146 */ sme_process_nss_update_resp(struct mac_context * mac,uint8_t * msg)3147 static QDF_STATUS sme_process_nss_update_resp(struct mac_context *mac, uint8_t *msg) 3148 { 3149 tListElem *entry = NULL; 3150 tSmeCmd *command = NULL; 3151 bool found; 3152 policy_mgr_nss_update_cback callback = NULL; 3153 struct sir_bcn_update_rsp *param; 3154 3155 param = (struct sir_bcn_update_rsp *)msg; 3156 if (!param) 3157 sme_err("nss update resp param is NULL"); 3158 /* Not returning. Need to check if active command list 3159 * needs to be freed 3160 */ 3161 3162 if (param && param->reason != REASON_NSS_UPDATE) { 3163 sme_err("reason not NSS update"); 3164 return QDF_STATUS_E_INVAL; 3165 } 3166 entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); 3167 if (!entry) { 3168 sme_err("No cmd found in active list"); 3169 return QDF_STATUS_E_FAILURE; 3170 } 3171 3172 command = GET_BASE_ADDR(entry, tSmeCmd, Link); 3173 if (!command) { 3174 sme_err("Base address is NULL"); 3175 return QDF_STATUS_E_FAILURE; 3176 } 3177 3178 if (e_sme_command_nss_update != command->command) { 3179 sme_err("Command mismatch!"); 3180 return QDF_STATUS_E_FAILURE; 3181 } 3182 3183 callback = command->u.nss_update_cmd.nss_update_cb; 3184 if (callback) { 3185 if (!param) 3186 sme_err("Callback failed since nss update params is NULL"); 3187 else 3188 callback(command->u.nss_update_cmd.context, 3189 param->status, 3190 param->vdev_id, 3191 command->u.nss_update_cmd.next_action, 3192 command->u.nss_update_cmd.reason, 3193 command->u.nss_update_cmd.original_vdev_id, 3194 command->u.nss_update_cmd.request_id); 3195 } else { 3196 sme_err("Callback does not exist"); 3197 } 3198 3199 found = csr_nonscan_active_ll_remove_entry(mac, entry, LL_ACCESS_LOCK); 3200 if (found) { 3201 /* Now put this command back on the available command list */ 3202 csr_release_command(mac, command); 3203 } 3204 3205 return QDF_STATUS_SUCCESS; 3206 } 3207 sme_stop(mac_handle_t mac_handle)3208 QDF_STATUS sme_stop(mac_handle_t mac_handle) 3209 { 3210 QDF_STATUS status; 3211 QDF_STATUS ret_status = QDF_STATUS_SUCCESS; 3212 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3213 3214 status = rrm_stop(mac); 3215 if (QDF_IS_STATUS_ERROR(status)) { 3216 ret_status = status; 3217 sme_err("rrm_stop failed with status: %d", status); 3218 } 3219 3220 status = csr_stop(mac); 3221 if (QDF_IS_STATUS_ERROR(status)) { 3222 ret_status = status; 3223 sme_err("csr_stop failed with status: %d", status); 3224 } 3225 3226 mac->sme.state = SME_STATE_STOP; 3227 3228 return ret_status; 3229 } 3230 3231 /* 3232 * sme_close() - Release all SME modules and their resources. 3233 * The function release each module in SME, PMC, CSR, etc. . Upon 3234 * return, all modules are at closed state. 3235 * 3236 * No SME APIs can be involved after smeClose except smeOpen. 3237 * smeClose must be called before mac_close. 3238 * This is a synchronous call 3239 * 3240 * mac_handle - The handle returned by mac_open 3241 * Return QDF_STATUS_SUCCESS - SME is successfully close. 3242 * 3243 * Other status means SME is failed to be closed but caller still cannot 3244 * call any other SME functions except smeOpen. 3245 */ sme_close(mac_handle_t mac_handle)3246 QDF_STATUS sme_close(mac_handle_t mac_handle) 3247 { 3248 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3249 QDF_STATUS fail_status = QDF_STATUS_SUCCESS; 3250 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3251 3252 if (!mac) 3253 return QDF_STATUS_E_FAILURE; 3254 3255 sme_unregister_power_debug_stats_cb(mac); 3256 3257 status = csr_close(mac); 3258 if (!QDF_IS_STATUS_SUCCESS(status)) { 3259 sme_err("csr_close failed with status: %d", status); 3260 fail_status = status; 3261 } 3262 #ifndef WLAN_MDM_CODE_REDUCTION_OPT 3263 status = sme_qos_close(mac); 3264 if (!QDF_IS_STATUS_SUCCESS(status)) { 3265 sme_err("Qos close failed with status: %d", status); 3266 fail_status = status; 3267 } 3268 #endif 3269 status = sme_ps_close(mac_handle); 3270 if (!QDF_IS_STATUS_SUCCESS(status)) { 3271 sme_err("sme_ps_close failed status: %d", status); 3272 fail_status = status; 3273 } 3274 3275 status = rrm_close(mac); 3276 if (!QDF_IS_STATUS_SUCCESS(status)) { 3277 sme_err("RRM close failed with status: %d", status); 3278 fail_status = status; 3279 } 3280 3281 free_sme_cmd_list(mac); 3282 3283 status = qdf_mutex_destroy(&mac->sme.sme_global_lock); 3284 if (!QDF_IS_STATUS_SUCCESS(status)) 3285 fail_status = QDF_STATUS_E_FAILURE; 3286 3287 mac->sme.state = SME_STATE_STOP; 3288 3289 return fail_status; 3290 } 3291 sme_get_phy_mode(mac_handle_t mac_handle)3292 eCsrPhyMode sme_get_phy_mode(mac_handle_t mac_handle) 3293 { 3294 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3295 3296 return mac->roam.configParam.phyMode; 3297 } 3298 sme_get_network_params(struct mac_context * mac,struct bss_dot11_config * dot11_cfg)3299 QDF_STATUS sme_get_network_params(struct mac_context *mac, 3300 struct bss_dot11_config *dot11_cfg) 3301 { 3302 enum csr_cfgdot11mode dot11_mode; 3303 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3304 bool chan_switch_hostapd_rate_enabled = true; 3305 uint8_t mcc_to_scc_switch = 0; 3306 enum QDF_OPMODE opmode; 3307 3308 if (!mac) 3309 return status; 3310 3311 status = sme_acquire_global_lock(&mac->sme); 3312 if (QDF_IS_STATUS_ERROR(status)) 3313 return status; 3314 3315 ucfg_mlme_get_sap_chan_switch_rate_enabled(mac->psoc, 3316 &chan_switch_hostapd_rate_enabled); 3317 ucfg_policy_mgr_get_mcc_scc_switch(mac->psoc, 3318 &mcc_to_scc_switch); 3319 3320 if (mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) 3321 chan_switch_hostapd_rate_enabled = false; 3322 3323 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, 3324 dot11_cfg->vdev_id); 3325 dot11_mode = 3326 csr_roam_get_phy_mode_band_for_bss(mac, dot11_cfg); 3327 3328 dot11_cfg->dot11_mode = 3329 csr_translate_to_wni_cfg_dot11_mode(mac, dot11_mode); 3330 3331 dot11_cfg->nw_type = 3332 csr_convert_mode_to_nw_type(dot11_mode, dot11_cfg->p_band); 3333 3334 /* If INI is enabled, use the rates from hostapd */ 3335 if (!cds_is_sub_20_mhz_enabled() && chan_switch_hostapd_rate_enabled && 3336 (dot11_cfg->opr_rates.numRates || dot11_cfg->ext_rates.numRates)) { 3337 sme_err("Use the rates from the hostapd"); 3338 } else { /* Populate new rates */ 3339 dot11_cfg->ext_rates.numRates = 0; 3340 dot11_cfg->opr_rates.numRates = 0; 3341 3342 switch (dot11_cfg->nw_type) { 3343 case eSIR_11A_NW_TYPE: 3344 wlan_populate_basic_rates(&dot11_cfg->opr_rates, 3345 true, true); 3346 break; 3347 case eSIR_11B_NW_TYPE: 3348 wlan_populate_basic_rates(&dot11_cfg->opr_rates, 3349 false, true); 3350 break; 3351 case eSIR_11G_NW_TYPE: 3352 if ((opmode == QDF_P2P_CLIENT_MODE) || 3353 (opmode == QDF_P2P_GO_MODE) || 3354 (dot11_mode == eCSR_CFG_DOT11_MODE_11G_ONLY)) { 3355 wlan_populate_basic_rates(&dot11_cfg->opr_rates, 3356 true, true); 3357 } else { 3358 wlan_populate_basic_rates(&dot11_cfg->opr_rates, 3359 false, true); 3360 wlan_populate_basic_rates(&dot11_cfg->ext_rates, 3361 true, false); 3362 } 3363 break; 3364 default: 3365 sme_release_global_lock(&mac->sme); 3366 sme_err("Unknown network type %d", dot11_cfg->nw_type); 3367 return QDF_STATUS_E_FAILURE; 3368 } 3369 } 3370 3371 sme_release_global_lock(&mac->sme); 3372 return QDF_STATUS_SUCCESS; 3373 } 3374 sme_start_bss(mac_handle_t mac_handle,uint8_t vdev_id,struct start_bss_config * bss_config)3375 QDF_STATUS sme_start_bss(mac_handle_t mac_handle, uint8_t vdev_id, 3376 struct start_bss_config *bss_config) 3377 { 3378 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3379 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3380 3381 if (!mac) 3382 return QDF_STATUS_E_FAILURE; 3383 3384 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 3385 TRACE_CODE_SME_RX_HDD_MSG_CONNECT, vdev_id, 0)); 3386 3387 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) { 3388 sme_err("Invalid sessionID: %d", vdev_id); 3389 return QDF_STATUS_E_INVAL; 3390 } 3391 3392 status = sme_acquire_global_lock(&mac->sme); 3393 if (QDF_IS_STATUS_ERROR(status)) 3394 return status; 3395 3396 status = csr_bss_start(mac, vdev_id, bss_config); 3397 sme_release_global_lock(&mac->sme); 3398 3399 return status; 3400 } 3401 3402 /* 3403 * sme_set_phy_mode() - 3404 * Changes the PhyMode. 3405 * 3406 * mac_handle - The handle returned by mac_open. 3407 * phyMode new phyMode which is to set 3408 * Return QDF_STATUS SUCCESS. 3409 */ sme_set_phy_mode(mac_handle_t mac_handle,eCsrPhyMode phyMode)3410 QDF_STATUS sme_set_phy_mode(mac_handle_t mac_handle, eCsrPhyMode phyMode) 3411 { 3412 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3413 3414 mac->roam.configParam.phyMode = phyMode; 3415 mac->roam.configParam.uCfgDot11Mode = 3416 csr_get_cfg_dot11_mode_from_csr_phy_mode(false, 3417 mac->roam.configParam.phyMode); 3418 3419 return QDF_STATUS_SUCCESS; 3420 } 3421 3422 /* 3423 * sme_get_11b_data_duration() - 3424 * returns 11b data duration via channel freq. 3425 * 3426 * mac_handle - The handle returned by mac_open. 3427 * chan_freq - channel frequency 3428 * 3429 * Return - 11b data duration on success else 0 3430 */ sme_get_11b_data_duration(mac_handle_t mac_handle,uint32_t chan_freq)3431 uint32_t sme_get_11b_data_duration(mac_handle_t mac_handle, uint32_t chan_freq) 3432 { 3433 uint32_t rx_11b_data_duration = 0; 3434 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3435 struct channel_status *chan_status = 3436 ucfg_mc_cp_stats_get_channel_status(mac->pdev, chan_freq); 3437 3438 if (chan_status) 3439 rx_11b_data_duration = chan_status->rx_11b_mode_data_duration; 3440 3441 return rx_11b_data_duration; 3442 } 3443 sme_roam_ndi_stop(mac_handle_t mac_handle,uint8_t vdev_id)3444 QDF_STATUS sme_roam_ndi_stop(mac_handle_t mac_handle, uint8_t vdev_id) 3445 { 3446 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3447 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 3448 3449 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 3450 TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, vdev_id, 3451 0)); 3452 3453 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 3454 sme_debug("Invalid sessionID: %d", vdev_id); 3455 return QDF_STATUS_E_INVAL; 3456 } 3457 3458 status = sme_acquire_global_lock(&mac_ctx->sme); 3459 if (QDF_IS_STATUS_ERROR(status)) 3460 return status; 3461 3462 status = csr_roam_ndi_stop(mac_ctx, vdev_id); 3463 sme_release_global_lock(&mac_ctx->sme); 3464 3465 return status; 3466 } 3467 3468 /* sme_dhcp_done_ind() - send dhcp done ind 3469 * @mac_handle: Opaque handle to the global MAC context 3470 * @session_id: session id 3471 * 3472 * Return: void. 3473 */ sme_dhcp_done_ind(mac_handle_t mac_handle,uint8_t session_id)3474 void sme_dhcp_done_ind(mac_handle_t mac_handle, uint8_t session_id) 3475 { 3476 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 3477 struct csr_roam_session *session; 3478 3479 if (!mac_ctx) 3480 return; 3481 3482 session = CSR_GET_SESSION(mac_ctx, session_id); 3483 if (!session) { 3484 sme_err("Session: %d not found", session_id); 3485 return; 3486 } 3487 session->dhcp_done = true; 3488 } 3489 sme_roam_stop_bss(mac_handle_t mac_handle,uint8_t vdev_id)3490 QDF_STATUS sme_roam_stop_bss(mac_handle_t mac_handle, uint8_t vdev_id) 3491 { 3492 QDF_STATUS status; 3493 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3494 3495 status = sme_acquire_global_lock(&mac->sme); 3496 if (QDF_IS_STATUS_ERROR(status)) 3497 return status; 3498 3499 status = csr_roam_issue_stop_bss_cmd(mac, vdev_id, 3500 eCSR_BSS_TYPE_INFRA_AP); 3501 sme_release_global_lock(&mac->sme); 3502 3503 return status; 3504 } 3505 3506 /** 3507 * sme_roam_disconnect_sta() - disassociate a station 3508 * @mac_handle: Global structure 3509 * @sessionId: SessionId of SoftAP 3510 * @p_del_sta_params: Pointer to parameters of the station to disassoc 3511 * 3512 * To disassociate a station. This is an asynchronous API. 3513 * 3514 * Return: QDF_STATUS_SUCCESS on success.Roam callback will 3515 * be called to indicate actual result. 3516 */ sme_roam_disconnect_sta(mac_handle_t mac_handle,uint8_t sessionId,struct csr_del_sta_params * p_del_sta_params)3517 QDF_STATUS sme_roam_disconnect_sta(mac_handle_t mac_handle, uint8_t sessionId, 3518 struct csr_del_sta_params *p_del_sta_params) 3519 { 3520 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3521 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3522 3523 if (!mac) { 3524 QDF_ASSERT(0); 3525 return status; 3526 } 3527 3528 status = sme_acquire_global_lock(&mac->sme); 3529 if (QDF_IS_STATUS_SUCCESS(status)) { 3530 if (CSR_IS_SESSION_VALID(mac, sessionId)) 3531 status = csr_roam_issue_disassociate_sta_cmd(mac, 3532 sessionId, p_del_sta_params); 3533 else 3534 status = QDF_STATUS_E_INVAL; 3535 sme_release_global_lock(&mac->sme); 3536 } 3537 3538 return status; 3539 } 3540 3541 /** 3542 * sme_roam_deauth_sta() - deauthenticate a station 3543 * @mac_handle: Global structure 3544 * @sessionId: SessionId of SoftAP 3545 * @pDelStaParams: Pointer to parameters of the station to deauthenticate 3546 * 3547 * To disassociate a station. This is an asynchronous API. 3548 * 3549 * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS error 3550 * code on error. Roam callback will be called to indicate actual 3551 * result 3552 */ sme_roam_deauth_sta(mac_handle_t mac_handle,uint8_t sessionId,struct csr_del_sta_params * pDelStaParams)3553 QDF_STATUS sme_roam_deauth_sta(mac_handle_t mac_handle, uint8_t sessionId, 3554 struct csr_del_sta_params *pDelStaParams) 3555 { 3556 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3557 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3558 3559 if (!mac) { 3560 QDF_ASSERT(0); 3561 return status; 3562 } 3563 3564 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 3565 TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA, 3566 sessionId, pDelStaParams->reason_code)); 3567 status = sme_acquire_global_lock(&mac->sme); 3568 if (QDF_IS_STATUS_SUCCESS(status)) { 3569 if (CSR_IS_SESSION_VALID(mac, sessionId)) 3570 status = 3571 csr_roam_issue_deauth_sta_cmd(mac, sessionId, 3572 pDelStaParams); 3573 else 3574 status = QDF_STATUS_E_INVAL; 3575 sme_release_global_lock(&mac->sme); 3576 } 3577 3578 return status; 3579 } 3580 3581 #ifdef WLAN_FEATURE_ROAM_OFFLOAD sme_get_pmk_info(mac_handle_t mac_handle,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache)3582 void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id, 3583 struct wlan_crypto_pmksa *pmk_cache) 3584 { 3585 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 3586 QDF_STATUS status = sme_acquire_global_lock(&mac_ctx->sme); 3587 3588 if (QDF_IS_STATUS_SUCCESS(status)) { 3589 if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) 3590 csr_get_pmk_info(mac_ctx, session_id, pmk_cache); 3591 sme_release_global_lock(&mac_ctx->sme); 3592 } 3593 } 3594 #endif 3595 3596 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 3597 /* 3598 * sme_roam_set_psk_pmk() - a wrapper function to request CSR to save PSK/PMK 3599 * This is a synchronous call. 3600 * @mac_handle: Global structure 3601 * @vdev_id: vdev id 3602 * @pmksa : PMK entry 3603 * @update_to_fw: True - send RSO update to firmware after updating 3604 * session->psk_pmk. 3605 * False - Copy the pmk to session->psk_pmk and return 3606 * 3607 * Return: QDF_STATUS - status whether PSK/PMK is set or not 3608 */ sme_roam_set_psk_pmk(mac_handle_t mac_handle,struct wlan_crypto_pmksa * pmksa,uint8_t vdev_id,bool update_to_fw)3609 QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, 3610 struct wlan_crypto_pmksa *pmksa, 3611 uint8_t vdev_id, bool update_to_fw) 3612 { 3613 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3614 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3615 3616 status = sme_acquire_global_lock(&mac->sme); 3617 if (QDF_IS_STATUS_SUCCESS(status)) { 3618 if (CSR_IS_SESSION_VALID(mac, vdev_id)) 3619 status = csr_roam_set_psk_pmk(mac, pmksa, vdev_id, 3620 update_to_fw); 3621 else 3622 status = QDF_STATUS_E_INVAL; 3623 sme_release_global_lock(&mac->sme); 3624 } 3625 return status; 3626 } 3627 sme_set_pmk_cache_ft(mac_handle_t mac_handle,uint8_t vdev_id,struct wlan_crypto_pmksa * pmk_cache)3628 QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t vdev_id, 3629 struct wlan_crypto_pmksa *pmk_cache) 3630 { 3631 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3632 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3633 3634 status = sme_acquire_global_lock(&mac->sme); 3635 if (QDF_IS_STATUS_SUCCESS(status)) { 3636 status = csr_set_pmk_cache_ft(mac, vdev_id, pmk_cache); 3637 sme_release_global_lock(&mac->sme); 3638 } 3639 return status; 3640 } 3641 #endif 3642 3643 /* 3644 * sme_get_config_param() - 3645 * A wrapper function that HDD calls to get the global settings 3646 * currently maintained by CSR. 3647 * This is a synchronous call. 3648 * 3649 * pParam - caller allocated memory 3650 * Return QDF_STATUS 3651 */ sme_get_config_param(mac_handle_t mac_handle,struct sme_config_params * pParam)3652 QDF_STATUS sme_get_config_param(mac_handle_t mac_handle, 3653 struct sme_config_params *pParam) 3654 { 3655 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3656 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3657 3658 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 3659 TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0)); 3660 status = sme_acquire_global_lock(&mac->sme); 3661 if (QDF_IS_STATUS_SUCCESS(status)) { 3662 status = csr_get_config_param(mac, &pParam->csr_config); 3663 if (status != QDF_STATUS_SUCCESS) { 3664 sme_err("csr_get_config_param failed"); 3665 sme_release_global_lock(&mac->sme); 3666 return status; 3667 } 3668 sme_release_global_lock(&mac->sme); 3669 } 3670 3671 return status; 3672 } 3673 sme_get_vht_ch_width(void)3674 uint32_t sme_get_vht_ch_width(void) 3675 { 3676 return wma_get_vht_ch_width(); 3677 } 3678 3679 #ifdef WLAN_FEATURE_11BE sme_get_eht_ch_width(void)3680 uint32_t sme_get_eht_ch_width(void) 3681 { 3682 return wma_get_eht_ch_width(); 3683 } 3684 #endif 3685 3686 #ifdef FEATURE_OEM_DATA_SUPPORT 3687 /** 3688 * sme_register_oem_data_rsp_callback() - Register a routine of 3689 * type send_oem_data_rsp_msg 3690 * @mac_handle: Handle returned by mac_open. 3691 * @callback: Callback to send response 3692 * to oem application. 3693 * 3694 * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg 3695 * callback function. 3696 * 3697 * Return: QDF_STATUS. 3698 */ sme_register_oem_data_rsp_callback(mac_handle_t mac_handle,sme_send_oem_data_rsp_msg callback)3699 QDF_STATUS sme_register_oem_data_rsp_callback(mac_handle_t mac_handle, 3700 sme_send_oem_data_rsp_msg callback) 3701 { 3702 QDF_STATUS status = QDF_STATUS_SUCCESS; 3703 struct mac_context *pmac = MAC_CONTEXT(mac_handle); 3704 3705 pmac->sme.oem_data_rsp_callback = callback; 3706 3707 return status; 3708 3709 } 3710 3711 /** 3712 * sme_deregister_oem_data_rsp_callback() - De-register OEM datarsp callback 3713 * @mac_handle: Handler return by mac_open 3714 * This function De-registers the OEM data response callback to SME 3715 * 3716 * Return: None 3717 */ sme_deregister_oem_data_rsp_callback(mac_handle_t mac_handle)3718 void sme_deregister_oem_data_rsp_callback(mac_handle_t mac_handle) 3719 { 3720 struct mac_context *pmac; 3721 3722 if (!mac_handle) { 3723 sme_err("mac_handle is not valid"); 3724 return; 3725 } 3726 pmac = MAC_CONTEXT(mac_handle); 3727 3728 pmac->sme.oem_data_rsp_callback = NULL; 3729 } 3730 3731 /** 3732 * sme_oem_update_capability() - update UMAC's oem related capability. 3733 * @mac_handle: Handle returned by mac_open 3734 * @oem_cap: pointer to oem_capability 3735 * 3736 * This function updates OEM capability to UMAC. Currently RTT 3737 * related capabilities are updated. More capabilities can be 3738 * added in future. 3739 * 3740 * Return: QDF_STATUS 3741 */ sme_oem_update_capability(mac_handle_t mac_handle,struct sme_oem_capability * cap)3742 QDF_STATUS sme_oem_update_capability(mac_handle_t mac_handle, 3743 struct sme_oem_capability *cap) 3744 { 3745 QDF_STATUS status = QDF_STATUS_SUCCESS; 3746 struct mac_context *pmac = MAC_CONTEXT(mac_handle); 3747 uint8_t *bytes; 3748 3749 bytes = pmac->rrm.rrmConfig.rm_capability; 3750 3751 if (cap->ftm_rr) 3752 bytes[4] |= RM_CAP_FTM_RANGE_REPORT; 3753 if (cap->lci_capability) 3754 bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT; 3755 3756 return status; 3757 } 3758 3759 /** 3760 * sme_oem_get_capability() - get oem capability 3761 * @mac_handle: Handle returned by mac_open 3762 * @oem_cap: pointer to oem_capability 3763 * 3764 * This function is used to get the OEM capability from UMAC. 3765 * Currently RTT related capabilities are received. More 3766 * capabilities can be added in future. 3767 * 3768 * Return: QDF_STATUS 3769 */ sme_oem_get_capability(mac_handle_t mac_handle,struct sme_oem_capability * cap)3770 QDF_STATUS sme_oem_get_capability(mac_handle_t mac_handle, 3771 struct sme_oem_capability *cap) 3772 { 3773 QDF_STATUS status = QDF_STATUS_SUCCESS; 3774 struct mac_context *pmac = MAC_CONTEXT(mac_handle); 3775 uint8_t *bytes; 3776 3777 bytes = pmac->rrm.rrmConfig.rm_capability; 3778 3779 cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT; 3780 cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT; 3781 3782 return status; 3783 } 3784 #endif 3785 3786 /* 3787 * sme_get_snr() - 3788 * A wrapper function that client calls to register a callback to get SNR 3789 * 3790 * callback - SME sends back the requested stats using the callback 3791 * staId - The station ID for which the stats is requested for 3792 * pContext - user context to be passed back along with the callback 3793 * p_cds_context - cds context 3794 * \return QDF_STATUS 3795 */ sme_get_snr(mac_handle_t mac_handle,tCsrSnrCallback callback,struct qdf_mac_addr bssId,void * pContext)3796 QDF_STATUS sme_get_snr(mac_handle_t mac_handle, 3797 tCsrSnrCallback callback, 3798 struct qdf_mac_addr bssId, void *pContext) 3799 { 3800 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3801 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3802 3803 status = sme_acquire_global_lock(&mac->sme); 3804 if (QDF_IS_STATUS_SUCCESS(status)) { 3805 status = csr_get_snr(mac, callback, bssId, pContext); 3806 sme_release_global_lock(&mac->sme); 3807 } 3808 return status; 3809 } 3810 sme_get_link_status(mac_handle_t mac_handle,csr_link_status_callback callback,void * context,uint8_t session_id)3811 QDF_STATUS sme_get_link_status(mac_handle_t mac_handle, 3812 csr_link_status_callback callback, 3813 void *context, uint8_t session_id) 3814 { 3815 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3816 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3817 tAniGetLinkStatus *msg; 3818 struct scheduler_msg message = {0}; 3819 3820 status = sme_acquire_global_lock(&mac->sme); 3821 if (QDF_IS_STATUS_SUCCESS(status)) { 3822 msg = qdf_mem_malloc(sizeof(*msg)); 3823 if (!msg) { 3824 sme_release_global_lock(&mac->sme); 3825 return QDF_STATUS_E_NOMEM; 3826 } 3827 3828 msg->msgType = WMA_LINK_STATUS_GET_REQ; 3829 msg->msgLen = sizeof(*msg); 3830 msg->sessionId = session_id; 3831 mac->sme.link_status_context = context; 3832 mac->sme.link_status_callback = callback; 3833 3834 message.type = WMA_LINK_STATUS_GET_REQ; 3835 message.bodyptr = msg; 3836 message.reserved = 0; 3837 3838 status = scheduler_post_message(QDF_MODULE_ID_SME, 3839 QDF_MODULE_ID_WMA, 3840 QDF_MODULE_ID_WMA, &message); 3841 if (QDF_IS_STATUS_ERROR(status)) { 3842 sme_err("post msg failed, %d", status); 3843 qdf_mem_free(msg); 3844 mac->sme.link_status_context = NULL; 3845 mac->sme.link_status_callback = NULL; 3846 } 3847 3848 sme_release_global_lock(&mac->sme); 3849 } 3850 3851 return status; 3852 } 3853 3854 /* 3855 * sme_generic_change_country_code() - 3856 * Change Country code from upperlayer during WLAN driver operation. 3857 * This is a synchronous API. 3858 * 3859 * mac_handle - The handle returned by mac_open. 3860 * pCountry New Country Code String 3861 * reg_domain regulatory domain 3862 * Return QDF_STATUS SUCCESS. 3863 * FAILURE or RESOURCES The API finished and failed. 3864 */ sme_generic_change_country_code(mac_handle_t mac_handle,uint8_t * pCountry)3865 QDF_STATUS sme_generic_change_country_code(mac_handle_t mac_handle, 3866 uint8_t *pCountry) 3867 { 3868 QDF_STATUS status = QDF_STATUS_E_FAILURE; 3869 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3870 struct scheduler_msg msg = {0}; 3871 tAniGenericChangeCountryCodeReq *pMsg; 3872 3873 if (!mac) { 3874 sme_err("mac is null"); 3875 return status; 3876 } 3877 3878 status = sme_acquire_global_lock(&mac->sme); 3879 if (QDF_IS_STATUS_SUCCESS(status)) { 3880 pMsg = qdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq)); 3881 if (!pMsg) { 3882 sme_release_global_lock(&mac->sme); 3883 return QDF_STATUS_E_NOMEM; 3884 } 3885 3886 pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; 3887 pMsg->msgLen = 3888 (uint16_t) sizeof(tAniGenericChangeCountryCodeReq); 3889 qdf_mem_copy(pMsg->countryCode, pCountry, 2); 3890 pMsg->countryCode[2] = ' '; 3891 3892 msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; 3893 msg.bodyptr = pMsg; 3894 msg.reserved = 0; 3895 3896 if (QDF_STATUS_SUCCESS != 3897 scheduler_post_message(QDF_MODULE_ID_SME, 3898 QDF_MODULE_ID_SME, 3899 QDF_MODULE_ID_SME, &msg)) { 3900 qdf_mem_free(pMsg); 3901 status = QDF_STATUS_E_FAILURE; 3902 } 3903 sme_release_global_lock(&mac->sme); 3904 } 3905 3906 return status; 3907 } 3908 3909 /* 3910 * sme_dhcp_start_ind() - 3911 * API to signal the FW about the DHCP Start event. 3912 * 3913 * mac_handle: Opaque handle to the global MAC context. 3914 * device_mode - mode(AP,SAP etc) of the device. 3915 * macAddr - MAC address of the adapter. 3916 * sessionId - session ID. 3917 * Return QDF_STATUS SUCCESS. 3918 * FAILURE or RESOURCES The API finished and failed. 3919 */ sme_dhcp_start_ind(mac_handle_t mac_handle,uint8_t device_mode,uint8_t * macAddr,uint8_t sessionId)3920 QDF_STATUS sme_dhcp_start_ind(mac_handle_t mac_handle, 3921 uint8_t device_mode, 3922 uint8_t *macAddr, uint8_t sessionId) 3923 { 3924 QDF_STATUS status; 3925 QDF_STATUS qdf_status; 3926 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3927 struct scheduler_msg message = {0}; 3928 tAniDHCPInd *pMsg; 3929 struct csr_roam_session *pSession; 3930 3931 status = sme_acquire_global_lock(&mac->sme); 3932 if (QDF_STATUS_SUCCESS == status) { 3933 pSession = CSR_GET_SESSION(mac, sessionId); 3934 3935 if (!pSession) { 3936 sme_err("Session: %d not found", sessionId); 3937 sme_release_global_lock(&mac->sme); 3938 return QDF_STATUS_E_FAILURE; 3939 } 3940 pSession->dhcp_done = false; 3941 3942 pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd)); 3943 if (!pMsg) { 3944 sme_release_global_lock(&mac->sme); 3945 return QDF_STATUS_E_NOMEM; 3946 } 3947 pMsg->msgType = WMA_DHCP_START_IND; 3948 pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd); 3949 pMsg->device_mode = device_mode; 3950 qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr, 3951 QDF_MAC_ADDR_SIZE); 3952 wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId, 3953 &pMsg->peerMacAddr); 3954 3955 message.type = WMA_DHCP_START_IND; 3956 message.bodyptr = pMsg; 3957 message.reserved = 0; 3958 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 3959 sessionId, message.type)); 3960 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 3961 QDF_MODULE_ID_WMA, 3962 QDF_MODULE_ID_WMA, 3963 &message); 3964 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 3965 sme_err("Post DHCP Start MSG fail"); 3966 qdf_mem_free(pMsg); 3967 status = QDF_STATUS_E_FAILURE; 3968 } 3969 sme_release_global_lock(&mac->sme); 3970 } 3971 return status; 3972 } 3973 3974 /* 3975 * sme_dhcp_stop_ind() - 3976 * API to signal the FW about the DHCP complete event. 3977 * 3978 * mac_handle: Opaque handle to the global MAC context. 3979 * device_mode - mode(AP, SAP etc) of the device. 3980 * macAddr - MAC address of the adapter. 3981 * sessionId - session ID. 3982 * Return QDF_STATUS SUCCESS. 3983 * FAILURE or RESOURCES The API finished and failed. 3984 */ sme_dhcp_stop_ind(mac_handle_t mac_handle,uint8_t device_mode,uint8_t * macAddr,uint8_t sessionId)3985 QDF_STATUS sme_dhcp_stop_ind(mac_handle_t mac_handle, 3986 uint8_t device_mode, 3987 uint8_t *macAddr, uint8_t sessionId) 3988 { 3989 QDF_STATUS status; 3990 QDF_STATUS qdf_status; 3991 struct mac_context *mac = MAC_CONTEXT(mac_handle); 3992 struct scheduler_msg message = {0}; 3993 tAniDHCPInd *pMsg; 3994 struct csr_roam_session *pSession; 3995 3996 status = sme_acquire_global_lock(&mac->sme); 3997 if (QDF_STATUS_SUCCESS == status) { 3998 pSession = CSR_GET_SESSION(mac, sessionId); 3999 4000 if (!pSession) { 4001 sme_err("Session: %d not found", sessionId); 4002 sme_release_global_lock(&mac->sme); 4003 return QDF_STATUS_E_FAILURE; 4004 } 4005 pSession->dhcp_done = true; 4006 4007 pMsg = qdf_mem_malloc(sizeof(tAniDHCPInd)); 4008 if (!pMsg) { 4009 sme_release_global_lock(&mac->sme); 4010 return QDF_STATUS_E_NOMEM; 4011 } 4012 4013 pMsg->msgType = WMA_DHCP_STOP_IND; 4014 pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd); 4015 pMsg->device_mode = device_mode; 4016 qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr, 4017 QDF_MAC_ADDR_SIZE); 4018 4019 wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId, 4020 &pMsg->peerMacAddr); 4021 4022 message.type = WMA_DHCP_STOP_IND; 4023 message.bodyptr = pMsg; 4024 message.reserved = 0; 4025 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 4026 sessionId, message.type)); 4027 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 4028 QDF_MODULE_ID_WMA, 4029 QDF_MODULE_ID_WMA, 4030 &message); 4031 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 4032 sme_err("Post DHCP Stop MSG fail"); 4033 qdf_mem_free(pMsg); 4034 status = QDF_STATUS_E_FAILURE; 4035 } 4036 4037 sme_release_global_lock(&mac->sme); 4038 } 4039 return status; 4040 } 4041 4042 /* 4043 * sme_neighbor_report_request() - 4044 * API to request neighbor report. 4045 * 4046 * mac_handle - The handle returned by mac_open. 4047 * pRrmNeighborReq - Pointer to a caller allocated object of type 4048 * tRrmNeighborReq. Caller owns the memory and is 4049 * responsible for freeing it. 4050 * Return QDF_STATUS 4051 * QDF_STATUS_E_FAILURE - failure 4052 * QDF_STATUS_SUCCESS success 4053 */ sme_neighbor_report_request(mac_handle_t mac_handle,uint8_t sessionId,tpRrmNeighborReq pRrmNeighborReq,tpRrmNeighborRspCallbackInfo callbackInfo)4054 QDF_STATUS sme_neighbor_report_request( 4055 mac_handle_t mac_handle, 4056 uint8_t sessionId, 4057 tpRrmNeighborReq pRrmNeighborReq, 4058 tpRrmNeighborRspCallbackInfo callbackInfo) 4059 { 4060 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4061 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4062 4063 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 4064 TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION, 4065 0)); 4066 4067 if (pRrmNeighborReq->neighbor_report_offload) { 4068 status = csr_invoke_neighbor_report_request(sessionId, 4069 pRrmNeighborReq, 4070 false); 4071 return status; 4072 } 4073 4074 if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) { 4075 status = 4076 sme_rrm_neighbor_report_request(mac, sessionId, 4077 pRrmNeighborReq, callbackInfo); 4078 sme_release_global_lock(&mac->sme); 4079 } 4080 4081 return status; 4082 } 4083 4084 void sme_register_pagefault_cb(mac_handle_t mac_handle,QDF_STATUS (* hdd_pagefault_action_cb)(void * buf,uint32_t data))4085 sme_register_pagefault_cb(mac_handle_t mac_handle, 4086 QDF_STATUS (*hdd_pagefault_action_cb)(void *buf, 4087 uint32_t data)) 4088 { 4089 QDF_STATUS status; 4090 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4091 4092 SME_ENTER(); 4093 4094 status = sme_acquire_global_lock(&mac->sme); 4095 if (QDF_IS_STATUS_SUCCESS(status)) { 4096 mac->sme.pagefault_action_cb = hdd_pagefault_action_cb; 4097 sme_release_global_lock(&mac->sme); 4098 } 4099 4100 SME_EXIT(); 4101 } 4102 sme_deregister_ssr_on_pagefault_cb(mac_handle_t mac_handle)4103 void sme_deregister_ssr_on_pagefault_cb(mac_handle_t mac_handle) 4104 { 4105 QDF_STATUS status; 4106 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4107 4108 SME_ENTER(); 4109 4110 status = sme_acquire_global_lock(&mac->sme); 4111 if (QDF_IS_STATUS_SUCCESS(status)) { 4112 mac->sme.pagefault_action_cb = NULL; 4113 sme_release_global_lock(&mac->sme); 4114 } 4115 4116 SME_EXIT(); 4117 } 4118 4119 #ifdef FEATURE_OEM_DATA_SUPPORT sme_oem_req_cmd(mac_handle_t mac_handle,struct oem_data_req * oem_req)4120 QDF_STATUS sme_oem_req_cmd(mac_handle_t mac_handle, 4121 struct oem_data_req *oem_req) 4122 { 4123 QDF_STATUS status = QDF_STATUS_SUCCESS; 4124 struct oem_data_req *oem_data_req; 4125 void *wma_handle; 4126 4127 SME_ENTER(); 4128 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 4129 if (!wma_handle) 4130 return QDF_STATUS_E_FAILURE; 4131 4132 oem_data_req = qdf_mem_malloc(sizeof(*oem_data_req)); 4133 if (!oem_data_req) 4134 return QDF_STATUS_E_NOMEM; 4135 4136 oem_data_req->data_len = oem_req->data_len; 4137 oem_data_req->data = qdf_mem_malloc(oem_data_req->data_len); 4138 if (!oem_data_req->data) { 4139 qdf_mem_free(oem_data_req); 4140 return QDF_STATUS_E_NOMEM; 4141 } 4142 4143 qdf_mem_copy(oem_data_req->data, oem_req->data, 4144 oem_data_req->data_len); 4145 4146 status = wma_start_oem_req_cmd(wma_handle, oem_data_req); 4147 4148 if (!QDF_IS_STATUS_SUCCESS(status)) 4149 sme_err("Post oem data request msg fail"); 4150 else 4151 sme_debug("OEM request(length: %d) sent to WMA", 4152 oem_data_req->data_len); 4153 4154 if (oem_data_req->data_len) 4155 qdf_mem_free(oem_data_req->data); 4156 qdf_mem_free(oem_data_req); 4157 4158 SME_EXIT(); 4159 return status; 4160 } 4161 #endif /*FEATURE_OEM_DATA_SUPPORT */ 4162 4163 #ifdef FEATURE_OEM_DATA sme_oem_data_cmd(mac_handle_t mac_handle,void (* oem_data_event_handler_cb)(const struct oem_data * oem_event_data,uint8_t vdev_id),struct oem_data * oem_data,uint8_t vdev_id)4164 QDF_STATUS sme_oem_data_cmd(mac_handle_t mac_handle, 4165 void (*oem_data_event_handler_cb) 4166 (const struct oem_data *oem_event_data, 4167 uint8_t vdev_id), 4168 struct oem_data *oem_data, 4169 uint8_t vdev_id) 4170 { 4171 QDF_STATUS status; 4172 void *wma_handle; 4173 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4174 4175 SME_ENTER(); 4176 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 4177 if (!wma_handle) 4178 return QDF_STATUS_E_FAILURE; 4179 4180 status = sme_acquire_global_lock(&mac->sme); 4181 if (QDF_IS_STATUS_SUCCESS(status)) { 4182 mac->sme.oem_data_event_handler_cb = oem_data_event_handler_cb; 4183 mac->sme.oem_data_vdev_id = vdev_id; 4184 sme_release_global_lock(&mac->sme); 4185 } 4186 status = wma_start_oem_data_cmd(wma_handle, oem_data); 4187 if (!QDF_IS_STATUS_SUCCESS(status)) 4188 sme_err("fail to call wma_start_oem_data_cmd."); 4189 4190 SME_EXIT(); 4191 return status; 4192 } 4193 sme_oem_event_deinit(mac_handle_t mac_handle)4194 void sme_oem_event_deinit(mac_handle_t mac_handle) 4195 { 4196 QDF_STATUS status; 4197 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4198 4199 SME_ENTER(); 4200 4201 status = sme_acquire_global_lock(&mac->sme); 4202 if (QDF_IS_STATUS_SUCCESS(status)) { 4203 mac->sme.oem_data_event_handler_cb = NULL; 4204 mac->sme.oem_data_vdev_id = WMA_INVALID_VDEV_ID; 4205 sme_release_global_lock(&mac->sme); 4206 } 4207 4208 SME_EXIT(); 4209 } 4210 sme_async_oem_event_init(mac_handle_t mac_handle,void (* oem_data_async_event_handler_cb)(const struct oem_data * oem_event_data))4211 void sme_async_oem_event_init(mac_handle_t mac_handle, 4212 void (*oem_data_async_event_handler_cb) 4213 (const struct oem_data *oem_event_data)) 4214 { 4215 QDF_STATUS status; 4216 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4217 4218 SME_ENTER(); 4219 4220 status = sme_acquire_global_lock(&mac->sme); 4221 if (QDF_IS_STATUS_SUCCESS(status)) { 4222 mac->sme.oem_data_async_event_handler_cb = 4223 oem_data_async_event_handler_cb; 4224 sme_release_global_lock(&mac->sme); 4225 } 4226 4227 SME_EXIT(); 4228 } 4229 sme_async_oem_event_deinit(mac_handle_t mac_handle)4230 void sme_async_oem_event_deinit(mac_handle_t mac_handle) 4231 { 4232 QDF_STATUS status; 4233 struct mac_context *mac = MAC_CONTEXT(mac_handle); 4234 4235 SME_ENTER(); 4236 4237 status = sme_acquire_global_lock(&mac->sme); 4238 if (QDF_IS_STATUS_SUCCESS(status)) { 4239 mac->sme.oem_data_async_event_handler_cb = NULL; 4240 sme_release_global_lock(&mac->sme); 4241 } 4242 4243 SME_EXIT(); 4244 } 4245 #endif 4246 4247 #define STA_NSS_CHAINS_SHIFT 0 4248 #define SAP_NSS_CHAINS_SHIFT 3 4249 #define P2P_GO_NSS_CHAINS_SHIFT 6 4250 #define P2P_CLI_CHAINS_SHIFT 9 4251 #define TDLS_NSS_CHAINS_SHIFT 12 4252 #define IBSS_NSS_CHAINS_SHIFT 15 4253 #define P2P_DEV_NSS_CHAINS_SHIFT 18 4254 #define OCB_NSS_CHAINS_SHIFT 21 4255 #define NAN_NSS_CHAIN_SHIFT 24 4256 #define NSS_CHAIN_MASK 0x7 4257 #define GET_VDEV_NSS_CHAIN(x, y) (((x) >> (y)) & NSS_CHAIN_MASK) 4258 sme_get_nss_chain_shift(enum QDF_OPMODE device_mode)4259 static uint8_t sme_get_nss_chain_shift(enum QDF_OPMODE device_mode) 4260 { 4261 switch (device_mode) { 4262 case QDF_STA_MODE: 4263 return STA_NSS_CHAINS_SHIFT; 4264 case QDF_SAP_MODE: 4265 return SAP_NSS_CHAINS_SHIFT; 4266 case QDF_P2P_GO_MODE: 4267 return P2P_GO_NSS_CHAINS_SHIFT; 4268 case QDF_P2P_CLIENT_MODE: 4269 return P2P_CLI_CHAINS_SHIFT; 4270 case QDF_IBSS_MODE: 4271 return IBSS_NSS_CHAINS_SHIFT; 4272 case QDF_P2P_DEVICE_MODE: 4273 return P2P_DEV_NSS_CHAINS_SHIFT; 4274 case QDF_OCB_MODE: 4275 return OCB_NSS_CHAINS_SHIFT; 4276 case QDF_TDLS_MODE: 4277 return TDLS_NSS_CHAINS_SHIFT; 4278 4279 default: 4280 sme_err("Device mode %d invalid", device_mode); 4281 return STA_NSS_CHAINS_SHIFT; 4282 } 4283 } 4284 4285 static void sme_check_nss_chain_ini_param(struct wlan_mlme_nss_chains * vdev_ini_cfg,uint8_t rf_chains_supported,enum nss_chains_band_info band)4286 sme_check_nss_chain_ini_param(struct wlan_mlme_nss_chains *vdev_ini_cfg, 4287 uint8_t rf_chains_supported, 4288 enum nss_chains_band_info band) 4289 { 4290 vdev_ini_cfg->rx_nss[band] = QDF_MIN(vdev_ini_cfg->rx_nss[band], 4291 rf_chains_supported); 4292 vdev_ini_cfg->tx_nss[band] = QDF_MIN(vdev_ini_cfg->tx_nss[band], 4293 rf_chains_supported); 4294 } 4295 4296 static void sme_fill_nss_chain_params(struct mac_context * mac_ctx,struct wlan_mlme_nss_chains * vdev_ini_cfg,enum QDF_OPMODE device_mode,enum nss_chains_band_info band,uint8_t rf_chains_supported)4297 sme_fill_nss_chain_params(struct mac_context *mac_ctx, 4298 struct wlan_mlme_nss_chains *vdev_ini_cfg, 4299 enum QDF_OPMODE device_mode, 4300 enum nss_chains_band_info band, 4301 uint8_t rf_chains_supported) 4302 { 4303 uint8_t nss_chain_shift; 4304 uint8_t max_supported_nss; 4305 enum coex_btc_chain_mode btc_chain_mode; 4306 struct wlan_mlme_nss_chains *nss_chains_ini_cfg = 4307 &mac_ctx->mlme_cfg->nss_chains_ini_cfg; 4308 QDF_STATUS status; 4309 4310 nss_chain_shift = sme_get_nss_chain_shift(device_mode); 4311 max_supported_nss = mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2 ? 4312 MAX_VDEV_NSS : 1; 4313 4314 /* 4315 * If target supports Antenna sharing, set NSS to 1 for 2.4GHz band for 4316 * NDI vdev. 4317 */ 4318 if (device_mode == QDF_NDI_MODE && mac_ctx->mlme_cfg->gen.as_enabled && 4319 band == NSS_CHAINS_BAND_2GHZ) 4320 max_supported_nss = NSS_1x1_MODE; 4321 4322 status = ucfg_coex_psoc_get_btc_chain_mode(mac_ctx->psoc, 4323 &btc_chain_mode); 4324 if (QDF_IS_STATUS_ERROR(status)) { 4325 sme_err("Failed to get BT coex chain mode"); 4326 btc_chain_mode = WLAN_COEX_BTC_CHAIN_MODE_UNSETTLED; 4327 } 4328 4329 if (band == NSS_CHAINS_BAND_2GHZ && 4330 (btc_chain_mode == WLAN_COEX_BTC_CHAIN_MODE_FDD || 4331 btc_chain_mode == WLAN_COEX_BTC_CHAIN_MODE_HYBRID)) 4332 max_supported_nss = NSS_1x1_MODE; 4333 4334 /* If the fw doesn't support two chains, num rf chains can max be 1 */ 4335 vdev_ini_cfg->num_rx_chains[band] = 4336 QDF_MIN(GET_VDEV_NSS_CHAIN( 4337 nss_chains_ini_cfg->num_rx_chains[band], 4338 nss_chain_shift), rf_chains_supported); 4339 4340 vdev_ini_cfg->num_tx_chains[band] = 4341 QDF_MIN(GET_VDEV_NSS_CHAIN( 4342 nss_chains_ini_cfg->num_tx_chains[band], 4343 nss_chain_shift), rf_chains_supported); 4344 4345 /* If 2x2 mode is disabled, then max rx, tx nss can be 1 */ 4346 vdev_ini_cfg->rx_nss[band] = 4347 QDF_MIN(GET_VDEV_NSS_CHAIN( 4348 nss_chains_ini_cfg->rx_nss[band], 4349 nss_chain_shift), max_supported_nss); 4350 4351 vdev_ini_cfg->tx_nss[band] = 4352 QDF_MIN(GET_VDEV_NSS_CHAIN( 4353 nss_chains_ini_cfg->tx_nss[band], 4354 nss_chain_shift), max_supported_nss); 4355 4356 vdev_ini_cfg->num_tx_chains_11a = 4357 QDF_MIN(GET_VDEV_NSS_CHAIN( 4358 nss_chains_ini_cfg->num_tx_chains_11a, 4359 nss_chain_shift), rf_chains_supported); 4360 4361 /* If the fw doesn't support two chains, num rf chains can max be 1 */ 4362 vdev_ini_cfg->num_tx_chains_11b = 4363 QDF_MIN(GET_VDEV_NSS_CHAIN( 4364 nss_chains_ini_cfg->num_tx_chains_11b, 4365 nss_chain_shift), rf_chains_supported); 4366 4367 vdev_ini_cfg->num_tx_chains_11g = 4368 QDF_MIN(GET_VDEV_NSS_CHAIN( 4369 nss_chains_ini_cfg->num_tx_chains_11g, 4370 nss_chain_shift), rf_chains_supported); 4371 4372 vdev_ini_cfg->disable_rx_mrc[band] = 4373 nss_chains_ini_cfg->disable_rx_mrc[band]; 4374 4375 vdev_ini_cfg->disable_tx_mrc[band] = 4376 nss_chains_ini_cfg->disable_tx_mrc[band]; 4377 /* 4378 * Check whether the rx/tx nss is greater than the number of rf chains 4379 * supported by FW, if so downgrade the nss to the number of chains 4380 * supported, as higher nss cannot be supported with less chains. 4381 */ 4382 sme_check_nss_chain_ini_param(vdev_ini_cfg, rf_chains_supported, 4383 band); 4384 4385 } 4386 sme_populate_nss_chain_params(mac_handle_t mac_handle,struct wlan_mlme_nss_chains * vdev_ini_cfg,enum QDF_OPMODE device_mode,uint8_t rf_chains_supported)4387 void sme_populate_nss_chain_params(mac_handle_t mac_handle, 4388 struct wlan_mlme_nss_chains *vdev_ini_cfg, 4389 enum QDF_OPMODE device_mode, 4390 uint8_t rf_chains_supported) 4391 { 4392 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4393 enum nss_chains_band_info band; 4394 4395 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) 4396 sme_fill_nss_chain_params(mac_ctx, vdev_ini_cfg, 4397 device_mode, band, 4398 rf_chains_supported); 4399 } 4400 4401 void sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev * vdev,struct wlan_mlme_nss_chains * vdev_ini_cfg)4402 sme_store_nss_chains_cfg_in_vdev(struct wlan_objmgr_vdev *vdev, 4403 struct wlan_mlme_nss_chains *vdev_ini_cfg) 4404 { 4405 struct wlan_mlme_nss_chains *ini_cfg; 4406 struct wlan_mlme_nss_chains *dynamic_cfg; 4407 4408 if (!vdev) { 4409 sme_err("Invalid vdev"); 4410 return; 4411 } 4412 4413 ini_cfg = mlme_get_ini_vdev_config(vdev); 4414 dynamic_cfg = mlme_get_dynamic_vdev_config(vdev); 4415 4416 if (!ini_cfg || !dynamic_cfg) { 4417 sme_err("Nss chains ini/dynamic config NULL vdev_id %d", 4418 vdev->vdev_objmgr.vdev_id); 4419 return; 4420 } 4421 4422 *ini_cfg = *vdev_ini_cfg; 4423 *dynamic_cfg = *vdev_ini_cfg; 4424 } 4425 4426 static void sme_populate_user_config(struct wlan_mlme_nss_chains * dynamic_cfg,struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * ini_cfg,enum nss_chains_band_info band)4427 sme_populate_user_config(struct wlan_mlme_nss_chains *dynamic_cfg, 4428 struct wlan_mlme_nss_chains *user_cfg, 4429 struct wlan_mlme_nss_chains *ini_cfg, 4430 enum nss_chains_band_info band) 4431 { 4432 if (!user_cfg->num_rx_chains[band]) 4433 user_cfg->num_rx_chains[band] = 4434 dynamic_cfg->num_rx_chains[band]; 4435 4436 if (!user_cfg->num_tx_chains[band]) 4437 user_cfg->num_tx_chains[band] = 4438 dynamic_cfg->num_tx_chains[band]; 4439 4440 if (!user_cfg->rx_nss[band]) 4441 user_cfg->rx_nss[band] = 4442 dynamic_cfg->rx_nss[band]; 4443 4444 if (!user_cfg->tx_nss[band]) 4445 user_cfg->tx_nss[band] = 4446 dynamic_cfg->tx_nss[band]; 4447 4448 if (!user_cfg->num_tx_chains_11a) { 4449 user_cfg->num_tx_chains_11a = 4450 QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ], 4451 ini_cfg->num_tx_chains_11a); 4452 } 4453 4454 if (!user_cfg->num_tx_chains_11b) { 4455 user_cfg->num_tx_chains_11b = 4456 QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ], 4457 ini_cfg->num_tx_chains_11b); 4458 } 4459 4460 if (!user_cfg->num_tx_chains_11g) { 4461 user_cfg->num_tx_chains_11g = 4462 QDF_MIN(user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ], 4463 ini_cfg->num_tx_chains_11g); 4464 } 4465 4466 if (!user_cfg->disable_rx_mrc[band]) 4467 user_cfg->disable_rx_mrc[band] = 4468 dynamic_cfg->disable_rx_mrc[band]; 4469 4470 if (!user_cfg->disable_tx_mrc[band]) 4471 user_cfg->disable_tx_mrc[band] = 4472 dynamic_cfg->disable_tx_mrc[band]; 4473 } 4474 4475 static QDF_STATUS sme_validate_from_ini_config(struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * ini_cfg,enum nss_chains_band_info band)4476 sme_validate_from_ini_config(struct wlan_mlme_nss_chains *user_cfg, 4477 struct wlan_mlme_nss_chains *ini_cfg, 4478 enum nss_chains_band_info band) 4479 { 4480 if (user_cfg->num_rx_chains[band] > 4481 ini_cfg->num_rx_chains[band]) 4482 return QDF_STATUS_E_FAILURE; 4483 4484 if (user_cfg->num_tx_chains[band] > 4485 ini_cfg->num_tx_chains[band]) 4486 return QDF_STATUS_E_FAILURE; 4487 4488 if (user_cfg->rx_nss[band] > 4489 ini_cfg->rx_nss[band]) 4490 return QDF_STATUS_E_FAILURE; 4491 4492 if (user_cfg->tx_nss[band] > 4493 ini_cfg->tx_nss[band]) 4494 return QDF_STATUS_E_FAILURE; 4495 4496 if (user_cfg->num_tx_chains_11a > 4497 ini_cfg->num_tx_chains_11a) 4498 return QDF_STATUS_E_FAILURE; 4499 4500 if (user_cfg->num_tx_chains_11b > 4501 ini_cfg->num_tx_chains_11b) 4502 return QDF_STATUS_E_FAILURE; 4503 4504 if (user_cfg->num_tx_chains_11g > 4505 ini_cfg->num_tx_chains_11g) 4506 return QDF_STATUS_E_FAILURE; 4507 4508 return QDF_STATUS_SUCCESS; 4509 } 4510 4511 static QDF_STATUS sme_validate_user_nss_chain_params(struct wlan_mlme_nss_chains * user_cfg,enum nss_chains_band_info band)4512 sme_validate_user_nss_chain_params( 4513 struct wlan_mlme_nss_chains *user_cfg, 4514 enum nss_chains_band_info band) 4515 { 4516 /* Reject as 2x1 modes are not supported in chains yet */ 4517 4518 if (user_cfg->num_tx_chains[band] > 4519 user_cfg->num_rx_chains[band]) 4520 return QDF_STATUS_E_FAILURE; 4521 4522 /* Also if mode is 2x2, we cant have chains as 1x1, or 1x2, or 2x1 */ 4523 4524 if (user_cfg->tx_nss[band] > 4525 user_cfg->num_tx_chains[band]) 4526 user_cfg->num_tx_chains[band] = 4527 user_cfg->tx_nss[band]; 4528 4529 if (user_cfg->rx_nss[band] > 4530 user_cfg->num_rx_chains[band]) 4531 user_cfg->num_rx_chains[band] = 4532 user_cfg->rx_nss[band]; 4533 4534 /* 4535 * It may happen that already chains are in 1x1 mode and nss too 4536 * is in 1x1 mode, but the tx 11a/b/g chains in user config comes 4537 * as 2x1, or 1x2 which cannot support respective mode, as tx chains 4538 * for respective band have max of 1x1 only, so these cannot exceed 4539 * respective band num tx chains. 4540 */ 4541 4542 if (user_cfg->num_tx_chains_11a > 4543 user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]) 4544 user_cfg->num_tx_chains_11a = 4545 user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]; 4546 4547 if (user_cfg->num_tx_chains_11b > 4548 user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]) 4549 user_cfg->num_tx_chains_11b = 4550 user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 4551 4552 if (user_cfg->num_tx_chains_11g > 4553 user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]) 4554 user_cfg->num_tx_chains_11g = 4555 user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ]; 4556 4557 return QDF_STATUS_SUCCESS; 4558 } 4559 4560 static QDF_STATUS sme_validate_nss_chains_config(struct wlan_objmgr_vdev * vdev,struct wlan_mlme_nss_chains * user_cfg,struct wlan_mlme_nss_chains * dynamic_cfg)4561 sme_validate_nss_chains_config(struct wlan_objmgr_vdev *vdev, 4562 struct wlan_mlme_nss_chains *user_cfg, 4563 struct wlan_mlme_nss_chains *dynamic_cfg) 4564 { 4565 enum nss_chains_band_info band; 4566 struct wlan_mlme_nss_chains *ini_cfg; 4567 QDF_STATUS status; 4568 4569 ini_cfg = mlme_get_ini_vdev_config(vdev); 4570 if (!ini_cfg) { 4571 sme_err("nss chain ini config NULL"); 4572 return QDF_STATUS_E_FAILURE; 4573 } 4574 4575 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) { 4576 sme_populate_user_config(dynamic_cfg, 4577 user_cfg, ini_cfg, band); 4578 status = sme_validate_from_ini_config(user_cfg, 4579 ini_cfg, 4580 band); 4581 if (QDF_IS_STATUS_ERROR(status)) { 4582 sme_err("Validation from ini config failed"); 4583 return QDF_STATUS_E_FAILURE; 4584 } 4585 status = sme_validate_user_nss_chain_params(user_cfg, 4586 band); 4587 if (QDF_IS_STATUS_ERROR(status)) { 4588 sme_err("User cfg validation failed"); 4589 return QDF_STATUS_E_FAILURE; 4590 } 4591 } 4592 4593 return QDF_STATUS_SUCCESS; 4594 } 4595 4596 static bool sme_is_nss_update_allowed(struct wlan_mlme_chain_cfg chain_cfg,uint8_t rx_nss,uint8_t tx_nss,enum nss_chains_band_info band)4597 sme_is_nss_update_allowed(struct wlan_mlme_chain_cfg chain_cfg, 4598 uint8_t rx_nss, uint8_t tx_nss, 4599 enum nss_chains_band_info band) 4600 { 4601 switch (band) { 4602 case NSS_CHAINS_BAND_2GHZ: 4603 if (rx_nss > chain_cfg.max_rx_chains_2g) 4604 return false; 4605 if (tx_nss > chain_cfg.max_tx_chains_2g) 4606 return false; 4607 break; 4608 case NSS_CHAINS_BAND_5GHZ: 4609 if (rx_nss > chain_cfg.max_rx_chains_5g) 4610 return false; 4611 if (tx_nss > chain_cfg.max_tx_chains_5g) 4612 return false; 4613 break; 4614 default: 4615 sme_err("Unknown Band nss change not allowed"); 4616 return false; 4617 } 4618 return true; 4619 } 4620 sme_modify_chains_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_chains,uint8_t tx_chains,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4621 static void sme_modify_chains_in_mlme_cfg(mac_handle_t mac_handle, 4622 uint8_t rx_chains, 4623 uint8_t tx_chains, 4624 enum QDF_OPMODE vdev_op_mode, 4625 enum nss_chains_band_info band) 4626 { 4627 uint8_t nss_shift; 4628 uint32_t nss_mask = 0x7; 4629 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4630 4631 nss_shift = sme_get_nss_chain_shift(vdev_op_mode); 4632 4633 mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] &= 4634 ~(nss_mask << nss_shift); 4635 mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_rx_chains[band] |= 4636 (rx_chains << nss_shift); 4637 mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] &= 4638 ~(nss_mask << nss_shift); 4639 mac_ctx->mlme_cfg->nss_chains_ini_cfg.num_tx_chains[band] |= 4640 (tx_chains << nss_shift); 4641 sme_debug("rx chains %d tx chains %d changed for vdev mode %d for band %d", 4642 rx_chains, tx_chains, vdev_op_mode, band); 4643 } 4644 4645 static void sme_modify_nss_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_nss,uint8_t tx_nss,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4646 sme_modify_nss_in_mlme_cfg(mac_handle_t mac_handle, 4647 uint8_t rx_nss, uint8_t tx_nss, 4648 enum QDF_OPMODE vdev_op_mode, 4649 enum nss_chains_band_info band) 4650 { 4651 uint8_t nss_shift; 4652 uint32_t nss_mask = 0x7; 4653 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4654 4655 if (!sme_is_nss_update_allowed(mac_ctx->fw_chain_cfg, rx_nss, tx_nss, 4656 band)) { 4657 sme_debug("Nss modification failed, fw doesn't support this nss %d", 4658 rx_nss); 4659 return; 4660 } 4661 4662 nss_shift = sme_get_nss_chain_shift(vdev_op_mode); 4663 4664 mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] &= 4665 ~(nss_mask << nss_shift); 4666 mac_ctx->mlme_cfg->nss_chains_ini_cfg.rx_nss[band] |= 4667 (rx_nss << nss_shift); 4668 mac_ctx->mlme_cfg->nss_chains_ini_cfg.tx_nss[band] &= 4669 ~(nss_mask << nss_shift); 4670 mac_ctx->mlme_cfg->nss_chains_ini_cfg.tx_nss[band] |= 4671 (tx_nss << nss_shift); 4672 sme_debug("rx nss %d tx nss %d changed for vdev mode %d for band %d", 4673 rx_nss, tx_nss, vdev_op_mode, band); 4674 } 4675 4676 void sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4677 sme_modify_nss_chains_tgt_cfg(mac_handle_t mac_handle, 4678 enum QDF_OPMODE vdev_op_mode, 4679 enum nss_chains_band_info band) 4680 { 4681 uint8_t ini_rx_nss; 4682 uint8_t ini_tx_nss; 4683 uint8_t max_supported_rx_nss = MAX_VDEV_NSS; 4684 uint8_t max_supported_tx_nss = MAX_VDEV_NSS; 4685 uint8_t ini_rx_chains; 4686 uint8_t ini_tx_chains; 4687 uint8_t max_supported_rx_chains = MAX_VDEV_CHAINS; 4688 uint8_t max_supported_tx_chains = MAX_VDEV_CHAINS; 4689 4690 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4691 struct wlan_mlme_nss_chains *nss_chains_ini_cfg = 4692 &mac_ctx->mlme_cfg->nss_chains_ini_cfg; 4693 uint8_t nss_shift = sme_get_nss_chain_shift(vdev_op_mode); 4694 struct wlan_mlme_chain_cfg chain_cfg = mac_ctx->fw_chain_cfg; 4695 4696 ini_rx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->rx_nss[band], 4697 nss_shift); 4698 ini_tx_nss = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg->tx_nss[band], 4699 nss_shift); 4700 4701 if (band == NSS_CHAINS_BAND_2GHZ) { 4702 max_supported_rx_nss = chain_cfg.max_rx_chains_2g; 4703 max_supported_tx_nss = chain_cfg.max_tx_chains_2g; 4704 } else if (band == NSS_CHAINS_BAND_5GHZ) { 4705 max_supported_rx_nss = chain_cfg.max_rx_chains_5g; 4706 max_supported_tx_nss = chain_cfg.max_tx_chains_5g; 4707 } 4708 4709 max_supported_rx_nss = QDF_MIN(ini_rx_nss, max_supported_rx_nss); 4710 if (!max_supported_rx_nss) 4711 return; 4712 4713 max_supported_tx_nss = QDF_MIN(ini_tx_nss, max_supported_tx_nss); 4714 if (!max_supported_tx_nss) 4715 return; 4716 4717 ini_rx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg-> 4718 num_rx_chains[band], 4719 nss_shift); 4720 ini_tx_chains = GET_VDEV_NSS_CHAIN(nss_chains_ini_cfg-> 4721 num_tx_chains[band], 4722 nss_shift); 4723 4724 if (band == NSS_CHAINS_BAND_2GHZ) { 4725 max_supported_rx_chains = chain_cfg.max_rx_chains_2g; 4726 max_supported_tx_chains = chain_cfg.max_tx_chains_2g; 4727 } else if (band == NSS_CHAINS_BAND_5GHZ) { 4728 max_supported_rx_chains = chain_cfg.max_rx_chains_5g; 4729 max_supported_tx_chains = chain_cfg.max_tx_chains_5g; 4730 } 4731 4732 max_supported_rx_chains = QDF_MIN(ini_rx_chains, 4733 max_supported_rx_chains); 4734 if (!max_supported_rx_chains) 4735 return; 4736 4737 max_supported_tx_chains = QDF_MIN(ini_tx_chains, 4738 max_supported_tx_chains); 4739 if (!max_supported_tx_chains) 4740 return; 4741 4742 sme_modify_chains_in_mlme_cfg(mac_handle, max_supported_rx_chains, 4743 max_supported_tx_chains, vdev_op_mode, 4744 band); 4745 sme_modify_nss_in_mlme_cfg(mac_handle, max_supported_rx_nss, 4746 max_supported_tx_nss, vdev_op_mode, band); 4747 } 4748 4749 void sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle,uint8_t rx_nss,uint8_t tx_nss,enum QDF_OPMODE vdev_op_mode,enum nss_chains_band_info band)4750 sme_update_nss_in_mlme_cfg(mac_handle_t mac_handle, 4751 uint8_t rx_nss, uint8_t tx_nss, 4752 enum QDF_OPMODE vdev_op_mode, 4753 enum nss_chains_band_info band) 4754 { 4755 /* 4756 * If device mode is P2P-DEVICE, then we want P2P to come in that 4757 * particular nss, then we should change the nss of P@P-CLI, and GO 4758 * and we are unaware that for what will be the device mode after 4759 * negotiation yet. 4760 */ 4761 4762 if (vdev_op_mode == QDF_P2P_DEVICE_MODE || 4763 vdev_op_mode == QDF_P2P_CLIENT_MODE || 4764 vdev_op_mode == QDF_P2P_GO_MODE) { 4765 sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss, 4766 QDF_P2P_CLIENT_MODE, band); 4767 sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss, 4768 QDF_P2P_GO_MODE, band); 4769 sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss, 4770 QDF_P2P_DEVICE_MODE, band); 4771 } else 4772 sme_modify_nss_in_mlme_cfg(mac_handle, rx_nss, tx_nss, 4773 vdev_op_mode, band); 4774 } 4775 sme_dump_nss_cfg(struct wlan_mlme_nss_chains * user_cfg)4776 static void sme_dump_nss_cfg(struct wlan_mlme_nss_chains *user_cfg) 4777 { 4778 sme_debug("num_tx_chains 2g %d 5g %d", 4779 user_cfg->num_tx_chains[NSS_CHAINS_BAND_2GHZ], 4780 user_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ]); 4781 4782 sme_debug("num_rx_chains 2g %d 5g %d", 4783 user_cfg->num_rx_chains[NSS_CHAINS_BAND_2GHZ], 4784 user_cfg->num_rx_chains[NSS_CHAINS_BAND_5GHZ]); 4785 4786 sme_debug("tx_nss 2g %d 5g %d", 4787 user_cfg->tx_nss[NSS_CHAINS_BAND_2GHZ], 4788 user_cfg->tx_nss[NSS_CHAINS_BAND_5GHZ]); 4789 sme_debug("rx_nss 2g %d 5g %d", 4790 user_cfg->rx_nss[NSS_CHAINS_BAND_2GHZ], 4791 user_cfg->rx_nss[NSS_CHAINS_BAND_5GHZ]); 4792 sme_debug("num_tx_chains_11b %d", 4793 user_cfg->num_tx_chains_11b); 4794 sme_debug("num_tx_chains_11g %d", 4795 user_cfg->num_tx_chains_11g); 4796 sme_debug("num_tx_chains_11a %d", 4797 user_cfg->num_tx_chains_11a); 4798 } 4799 4800 QDF_STATUS sme_nss_chains_update(mac_handle_t mac_handle,struct wlan_mlme_nss_chains * user_cfg,uint8_t vdev_id)4801 sme_nss_chains_update(mac_handle_t mac_handle, 4802 struct wlan_mlme_nss_chains *user_cfg, 4803 uint8_t vdev_id) 4804 { 4805 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4806 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4807 struct wlan_mlme_nss_chains *dynamic_cfg; 4808 struct wlan_objmgr_vdev *vdev = 4809 wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 4810 vdev_id, 4811 WLAN_LEGACY_SME_ID); 4812 uint8_t ll_lt_sap_vdev_id; 4813 4814 if (!vdev) { 4815 sme_err("Got NULL vdev obj, returning"); 4816 return QDF_STATUS_E_FAILURE; 4817 } 4818 4819 ll_lt_sap_vdev_id = 4820 wlan_policy_mgr_get_ll_lt_sap_vdev_id(mac_ctx->psoc); 4821 if (ll_lt_sap_vdev_id != WLAN_INVALID_VDEV_ID) { 4822 sme_info_rl("LL_LT_SAP vdev %d present, chainmask config not allowed", 4823 ll_lt_sap_vdev_id); 4824 goto release_ref; 4825 } 4826 4827 if (QDF_STATUS_SUCCESS == wlan_is_tdls_session_present(vdev)) { 4828 sme_debug("TDLS session exists"); 4829 status = QDF_STATUS_E_FAILURE; 4830 goto release_ref; 4831 } 4832 4833 status = sme_acquire_global_lock(&mac_ctx->sme); 4834 if (QDF_IS_STATUS_ERROR(status)) 4835 goto release_ref; 4836 4837 dynamic_cfg = mlme_get_dynamic_vdev_config(vdev); 4838 if (!dynamic_cfg) { 4839 sme_err("nss chain dynamic config NULL"); 4840 status = QDF_STATUS_E_FAILURE; 4841 goto release_lock; 4842 } 4843 4844 status = sme_validate_nss_chains_config(vdev, user_cfg, 4845 dynamic_cfg); 4846 sme_debug("dynamic_cfg"); 4847 sme_dump_nss_cfg(dynamic_cfg); 4848 sme_debug("user_cfg"); 4849 sme_dump_nss_cfg(user_cfg); 4850 4851 if (QDF_IS_STATUS_ERROR(status)) 4852 goto release_lock; 4853 4854 if (!qdf_mem_cmp(dynamic_cfg, user_cfg, 4855 sizeof(struct wlan_mlme_nss_chains))) { 4856 sme_debug("current config same as user config"); 4857 status = QDF_STATUS_SUCCESS; 4858 goto release_lock; 4859 } 4860 sme_debug("User params verified, sending to fw vdev id %d", vdev_id); 4861 4862 status = wma_vdev_nss_chain_params_send(vdev->vdev_objmgr.vdev_id, 4863 user_cfg); 4864 if (QDF_IS_STATUS_ERROR(status)) { 4865 sme_err("params sent failed to fw vdev id %d", vdev_id); 4866 goto release_lock; 4867 } 4868 4869 *dynamic_cfg = *user_cfg; 4870 4871 release_lock: 4872 sme_release_global_lock(&mac_ctx->sme); 4873 4874 release_ref: 4875 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 4876 return status; 4877 } 4878 4879 #ifdef WLAN_FEATURE_11AX sme_update_bfer_he_cap(struct wma_tgt_cfg * cfg)4880 static void sme_update_bfer_he_cap(struct wma_tgt_cfg *cfg) 4881 { 4882 cfg->he_cap_5g.su_beamformer = 0; 4883 } 4884 #else sme_update_bfer_he_cap(struct wma_tgt_cfg * cfg)4885 static void sme_update_bfer_he_cap(struct wma_tgt_cfg *cfg) 4886 { 4887 } 4888 #endif 4889 4890 #ifdef WLAN_FEATURE_11BE sme_update_bfer_eht_cap(struct wma_tgt_cfg * cfg)4891 static void sme_update_bfer_eht_cap(struct wma_tgt_cfg *cfg) 4892 { 4893 cfg->eht_cap_5g.su_beamformer = 0; 4894 } 4895 #else sme_update_bfer_eht_cap(struct wma_tgt_cfg * cfg)4896 static void sme_update_bfer_eht_cap(struct wma_tgt_cfg *cfg) 4897 { 4898 } 4899 #endif 4900 sme_update_bfer_caps_as_per_nss_chains(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg)4901 void sme_update_bfer_caps_as_per_nss_chains(mac_handle_t mac_handle, 4902 struct wma_tgt_cfg *cfg) 4903 { 4904 uint8_t max_supported_tx_chains = MAX_VDEV_CHAINS; 4905 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4906 struct wlan_mlme_nss_chains *nss_chains_ini_cfg = 4907 &mac_ctx->mlme_cfg->nss_chains_ini_cfg; 4908 uint8_t ini_tx_chains; 4909 4910 ini_tx_chains = GET_VDEV_NSS_CHAIN( 4911 nss_chains_ini_cfg->num_tx_chains[NSS_CHAINS_BAND_5GHZ], 4912 SAP_NSS_CHAINS_SHIFT); 4913 4914 max_supported_tx_chains = 4915 mac_ctx->fw_chain_cfg.max_tx_chains_5g; 4916 4917 max_supported_tx_chains = QDF_MIN(ini_tx_chains, 4918 max_supported_tx_chains); 4919 if (!max_supported_tx_chains) 4920 return; 4921 4922 if (max_supported_tx_chains == 1) { 4923 sme_debug("ini support %d and firmware support %d", 4924 ini_tx_chains, 4925 mac_ctx->fw_chain_cfg.max_tx_chains_5g); 4926 if (mac_ctx->fw_chain_cfg.max_tx_chains_5g == 1) { 4927 cfg->vht_cap.vht_su_bformer = 0; 4928 sme_update_bfer_he_cap(cfg); 4929 sme_update_bfer_eht_cap(cfg); 4930 } 4931 mac_ctx->mlme_cfg->vht_caps.vht_cap_info.su_bformer = 0; 4932 mac_ctx->mlme_cfg->vht_caps.vht_cap_info.num_soundingdim = 0; 4933 mac_ctx->mlme_cfg->vht_caps.vht_cap_info.mu_bformer = 0; 4934 } 4935 } 4936 sme_vdev_post_vdev_create_setup(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)4937 QDF_STATUS sme_vdev_post_vdev_create_setup(mac_handle_t mac_handle, 4938 struct wlan_objmgr_vdev *vdev) 4939 { 4940 struct vdev_mlme_obj *vdev_mlme; 4941 QDF_STATUS status = QDF_STATUS_E_INVAL; 4942 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4943 uint8_t vdev_id; 4944 4945 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 4946 if (!vdev_mlme) { 4947 sme_err("Failed to get vdev mlme obj!"); 4948 QDF_BUG(0); 4949 return status; 4950 } 4951 4952 vdev_id = wlan_vdev_get_id(vdev); 4953 status = wma_post_vdev_create_setup(vdev); 4954 if (QDF_IS_STATUS_ERROR(status)) { 4955 sme_err("Failed to setup wma for vdev: %d", vdev_id); 4956 return status; 4957 } 4958 4959 status = csr_setup_vdev_session(vdev_mlme); 4960 if (QDF_IS_STATUS_ERROR(status)) { 4961 sme_err("Failed to setup CSR layer for vdev: %d", vdev_id); 4962 goto cleanup_wma; 4963 } 4964 4965 wlan_vdev_set_dot11mode(mac_ctx->mlme_cfg, vdev->vdev_mlme.vdev_opmode, 4966 vdev_mlme); 4967 4968 status = mlme_vdev_self_peer_create(vdev); 4969 if (QDF_IS_STATUS_ERROR(status)) { 4970 sme_err("Failed to create vdev selfpeer for vdev:%d", vdev_id); 4971 goto csr_cleanup_vdev_session; 4972 } 4973 4974 return status; 4975 4976 csr_cleanup_vdev_session: 4977 csr_cleanup_vdev_session(mac_ctx, vdev_id); 4978 cleanup_wma: 4979 wma_cleanup_vdev(vdev); 4980 return status; 4981 } 4982 sme_vdev_set_data_tx_callback(struct wlan_objmgr_vdev * vdev)4983 QDF_STATUS sme_vdev_set_data_tx_callback(struct wlan_objmgr_vdev *vdev) 4984 { 4985 return wma_vdev_set_data_tx_callback(vdev); 4986 } 4987 4988 struct wlan_objmgr_vdev sme_vdev_create(mac_handle_t mac_handle,struct wlan_vdev_create_params * vdev_params)4989 *sme_vdev_create(mac_handle_t mac_handle, 4990 struct wlan_vdev_create_params *vdev_params) 4991 { 4992 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 4993 struct wlan_objmgr_vdev *vdev; 4994 4995 sme_debug("addr:"QDF_MAC_ADDR_FMT" opmode:%d", 4996 QDF_MAC_ADDR_REF(vdev_params->macaddr), 4997 vdev_params->opmode); 4998 4999 vdev = wlan_objmgr_vdev_obj_create(mac_ctx->pdev, vdev_params); 5000 if (!vdev) { 5001 sme_err("Failed to create vdev object"); 5002 return NULL; 5003 } 5004 5005 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_LEGACY_SME_ID) != 5006 QDF_STATUS_SUCCESS) { 5007 wlan_objmgr_vdev_obj_delete(vdev); 5008 return NULL; 5009 } 5010 5011 cm_utf_attach(vdev); 5012 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5013 TRACE_CODE_SME_RX_HDD_OPEN_SESSION, 5014 wlan_vdev_get_id(vdev), 0)); 5015 5016 return vdev; 5017 } 5018 sme_vdev_del_resp(uint8_t vdev_id)5019 void sme_vdev_del_resp(uint8_t vdev_id) 5020 { 5021 mac_handle_t mac_handle; 5022 struct mac_context *mac; 5023 5024 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 5025 if (!mac_handle) { 5026 QDF_ASSERT(0); 5027 return; 5028 } 5029 5030 mac = MAC_CONTEXT(mac_handle); 5031 csr_cleanup_vdev_session(mac, vdev_id); 5032 5033 if (mac->session_close_cb) 5034 mac->session_close_cb(vdev_id); 5035 } 5036 sme_vdev_self_peer_delete_resp(struct del_vdev_params * del_vdev_req)5037 QDF_STATUS sme_vdev_self_peer_delete_resp(struct del_vdev_params *del_vdev_req) 5038 { 5039 struct wlan_objmgr_vdev *vdev; 5040 QDF_STATUS status; 5041 5042 vdev = del_vdev_req->vdev; 5043 if (!vdev) { 5044 qdf_mem_free(del_vdev_req); 5045 return QDF_STATUS_E_INVAL; 5046 } 5047 5048 if (vdev->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) { 5049 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5050 wma_debug("vdev delete"); 5051 } else { 5052 wlan_vdev_mlme_notify_set_mac_addr_response(vdev, 5053 del_vdev_req->status); 5054 wma_debug("mac update"); 5055 } 5056 5057 status = del_vdev_req->status; 5058 qdf_mem_free(del_vdev_req); 5059 return status; 5060 } 5061 sme_vdev_delete(mac_handle_t mac_handle,struct wlan_objmgr_vdev * vdev)5062 QDF_STATUS sme_vdev_delete(mac_handle_t mac_handle, 5063 struct wlan_objmgr_vdev *vdev) 5064 { 5065 QDF_STATUS status; 5066 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5067 uint8_t *self_peer_macaddr, vdev_id = wlan_vdev_get_id(vdev); 5068 struct scheduler_msg self_peer_delete_msg = {0}; 5069 struct del_vdev_params *del_self_peer; 5070 bool is_pasn_peer_delete_all_required; 5071 5072 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5073 TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, vdev_id, 0)); 5074 5075 is_pasn_peer_delete_all_required = 5076 wlan_wifi_pos_pasn_peer_delete_all(mac->psoc, vdev_id); 5077 if (is_pasn_peer_delete_all_required) { 5078 sme_info("Resume vdev delete after pasn peers deletion"); 5079 return QDF_STATUS_SUCCESS; 5080 } 5081 5082 status = sme_acquire_global_lock(&mac->sme); 5083 5084 if (QDF_IS_STATUS_SUCCESS(status)) { 5085 status = csr_prepare_vdev_delete(mac, vdev); 5086 sme_release_global_lock(&mac->sme); 5087 } 5088 5089 /* 5090 * While this vdev delete is invoked we will still have following 5091 * references held: 5092 * WLAN_LEGACY_WMA_ID -- 1 5093 * WLAN_LEGACY_SME_ID -- 1 5094 * WLAN_OBJMGR_ID -- 2 5095 * Following message will release the self and delete the self peer 5096 * and release the wma references so the objmgr and wma_legacy will be 5097 * released because of this. 5098 * 5099 * In the message callback the legacy_sme reference will be released 5100 * resulting in the last reference of vdev object and sending the 5101 * vdev_delete to firmware. 5102 */ 5103 status = wlan_objmgr_vdev_obj_delete(vdev); 5104 if (QDF_IS_STATUS_ERROR(status)) { 5105 sme_nofl_err("Failed to mark vdev as logical delete %d", 5106 status); 5107 return status; 5108 } 5109 5110 cm_utf_detach(vdev); 5111 5112 del_self_peer = qdf_mem_malloc(sizeof(*del_self_peer)); 5113 if (!del_self_peer) 5114 return QDF_STATUS_E_NOMEM; 5115 5116 self_peer_macaddr = wlan_vdev_mlme_get_mldaddr(vdev); 5117 if (qdf_is_macaddr_zero((struct qdf_mac_addr *)self_peer_macaddr)) 5118 self_peer_macaddr = wlan_vdev_mlme_get_macaddr(vdev); 5119 5120 del_self_peer->vdev = vdev; 5121 del_self_peer->vdev_id = wlan_vdev_get_id(vdev); 5122 qdf_mem_copy(del_self_peer->self_mac_addr, self_peer_macaddr, 5123 sizeof(tSirMacAddr)); 5124 5125 self_peer_delete_msg.bodyptr = del_self_peer; 5126 self_peer_delete_msg.callback = mlme_vdev_self_peer_delete; 5127 status = scheduler_post_message(QDF_MODULE_ID_SME, 5128 QDF_MODULE_ID_MLME, 5129 QDF_MODULE_ID_TARGET_IF, 5130 &self_peer_delete_msg); 5131 5132 if (QDF_IS_STATUS_ERROR(status)) { 5133 sme_err("Failed to post vdev selfpeer for vdev:%d", vdev_id); 5134 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5135 qdf_mem_free(del_self_peer); 5136 } 5137 5138 return status; 5139 } 5140 sme_cleanup_session(mac_handle_t mac_handle,uint8_t vdev_id)5141 void sme_cleanup_session(mac_handle_t mac_handle, uint8_t vdev_id) 5142 { 5143 QDF_STATUS status; 5144 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5145 5146 status = sme_acquire_global_lock(&mac->sme); 5147 if (QDF_IS_STATUS_ERROR(status)) 5148 return; 5149 csr_cleanup_vdev_session(mac, vdev_id); 5150 sme_release_global_lock(&mac->sme); 5151 } 5152 5153 /* 5154 * sme_change_mcc_beacon_interval() - 5155 * To update P2P-GO beaconInterval. This function should be called after 5156 * disassociating all the station is done 5157 * This is an asynchronous API. 5158 * 5159 * @sessionId: Session Identifier 5160 * Return QDF_STATUS SUCCESS 5161 * FAILURE or RESOURCES 5162 * The API finished and failed. 5163 */ sme_change_mcc_beacon_interval(uint8_t sessionId)5164 QDF_STATUS sme_change_mcc_beacon_interval(uint8_t sessionId) 5165 { 5166 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5167 struct mac_context *mac_ctx = sme_get_mac_context(); 5168 5169 if (!mac_ctx) { 5170 sme_err("mac_ctx is NULL"); 5171 return status; 5172 } 5173 status = sme_acquire_global_lock(&mac_ctx->sme); 5174 if (QDF_IS_STATUS_SUCCESS(status)) { 5175 status = csr_send_chng_mcc_beacon_interval(mac_ctx, 5176 sessionId); 5177 sme_release_global_lock(&mac_ctx->sme); 5178 } 5179 return status; 5180 } 5181 sme_change_sap_csa_count(uint8_t count)5182 QDF_STATUS sme_change_sap_csa_count(uint8_t count) 5183 { 5184 struct mac_context *mac_ctx = sme_get_mac_context(); 5185 5186 if (!mac_ctx) { 5187 sme_err("mac_ctx is NULL"); 5188 return QDF_STATUS_E_FAILURE; 5189 } 5190 mac_ctx->sap.one_time_csa_count = count; 5191 5192 return QDF_STATUS_SUCCESS; 5193 } 5194 5195 /** 5196 * sme_set_host_offload(): API to set the host offload feature. 5197 * @mac_handle: The handle returned by mac_open. 5198 * @sessionId: Session Identifier 5199 * @request: Pointer to the offload request. 5200 * 5201 * Return QDF_STATUS 5202 */ sme_set_host_offload(mac_handle_t mac_handle,uint8_t sessionId,struct sir_host_offload_req * request)5203 QDF_STATUS sme_set_host_offload(mac_handle_t mac_handle, uint8_t sessionId, 5204 struct sir_host_offload_req *request) 5205 { 5206 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5207 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5208 5209 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5210 TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0)); 5211 status = sme_acquire_global_lock(&mac->sme); 5212 if (QDF_IS_STATUS_SUCCESS(status)) { 5213 #ifdef WLAN_NS_OFFLOAD 5214 if (SIR_IPV6_NS_OFFLOAD == request->offloadType) { 5215 status = sme_set_ps_ns_offload(mac_handle, request, 5216 sessionId); 5217 } else 5218 #endif /* WLAN_NS_OFFLOAD */ 5219 { 5220 status = sme_set_ps_host_offload(mac_handle, request, 5221 sessionId); 5222 } 5223 sme_release_global_lock(&mac->sme); 5224 } 5225 5226 return status; 5227 } 5228 5229 /* 5230 * sme_set_keep_alive() - 5231 * API to set the Keep Alive feature. 5232 * 5233 * mac_handle - The handle returned by mac_open. 5234 * request - Pointer to the Keep Alive request. 5235 * Return QDF_STATUS 5236 */ sme_set_keep_alive(mac_handle_t mac_handle,uint8_t session_id,struct keep_alive_req * request)5237 QDF_STATUS sme_set_keep_alive(mac_handle_t mac_handle, uint8_t session_id, 5238 struct keep_alive_req *request) 5239 { 5240 struct keep_alive_req *request_buf; 5241 struct scheduler_msg msg = {0}; 5242 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5243 5244 if (!CSR_IS_SESSION_VALID(mac, session_id)) { 5245 sme_err("invalid vdev %d", session_id); 5246 return QDF_STATUS_E_INVAL; 5247 } 5248 5249 request_buf = qdf_mem_malloc(sizeof(*request_buf)); 5250 if (!request_buf) 5251 return QDF_STATUS_E_NOMEM; 5252 5253 wlan_mlme_get_bssid_vdev_id(mac->pdev, session_id, 5254 &request->bssid); 5255 qdf_mem_copy(request_buf, request, sizeof(*request_buf)); 5256 5257 sme_debug("vdev %d buff TP %d input TP %d ", session_id, 5258 request_buf->timePeriod, request->timePeriod); 5259 request_buf->sessionId = session_id; 5260 5261 msg.type = WMA_SET_KEEP_ALIVE; 5262 msg.reserved = 0; 5263 msg.bodyptr = request_buf; 5264 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 5265 session_id, msg.type)); 5266 if (QDF_STATUS_SUCCESS != 5267 scheduler_post_message(QDF_MODULE_ID_SME, 5268 QDF_MODULE_ID_WMA, 5269 QDF_MODULE_ID_WMA, &msg)) { 5270 sme_err("Not able to post WMA_SET_KEEP_ALIVE message to WMA"); 5271 qdf_mem_free(request_buf); 5272 return QDF_STATUS_E_FAILURE; 5273 } 5274 5275 return QDF_STATUS_SUCCESS; 5276 } 5277 5278 /* 5279 * sme_get_operation_channel() - 5280 * API to get current channel on which STA is parked his function gives 5281 * channel information only of infra station 5282 * 5283 * mac_handle, pointer to memory location and sessionId 5284 * Returns QDF_STATUS_SUCCESS 5285 * QDF_STATUS_E_FAILURE 5286 */ sme_get_operation_channel(mac_handle_t mac_handle,uint32_t * chan_freq,uint8_t sessionId)5287 QDF_STATUS sme_get_operation_channel(mac_handle_t mac_handle, 5288 uint32_t *chan_freq, 5289 uint8_t sessionId) 5290 { 5291 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5292 5293 if (CSR_IS_SESSION_VALID(mac, sessionId)) { 5294 *chan_freq = wlan_get_operation_chan_freq_vdev_id(mac->pdev, 5295 sessionId); 5296 return QDF_STATUS_SUCCESS; 5297 } 5298 5299 return QDF_STATUS_E_FAILURE; 5300 } /* sme_get_operation_channel ends here */ 5301 5302 /** 5303 * sme_register_mgmt_frame_ind_callback() - Register a callback for 5304 * management frame indication to PE. 5305 * 5306 * @mac_handle: Opaque handle to the global MAC context 5307 * @callback: callback pointer to be registered 5308 * 5309 * This function is used to register a callback for management 5310 * frame indication to PE. 5311 * 5312 * Return: Success if msg is posted to PE else Failure. 5313 */ sme_register_mgmt_frame_ind_callback(mac_handle_t mac_handle,sir_mgmt_frame_ind_callback callback)5314 QDF_STATUS sme_register_mgmt_frame_ind_callback(mac_handle_t mac_handle, 5315 sir_mgmt_frame_ind_callback callback) 5316 { 5317 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 5318 struct sir_sme_mgmt_frame_cb_req *msg; 5319 QDF_STATUS status = QDF_STATUS_SUCCESS; 5320 5321 if (QDF_STATUS_SUCCESS == 5322 sme_acquire_global_lock(&mac_ctx->sme)) { 5323 msg = qdf_mem_malloc(sizeof(*msg)); 5324 if (!msg) { 5325 sme_release_global_lock(&mac_ctx->sme); 5326 return QDF_STATUS_E_NOMEM; 5327 } 5328 msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB; 5329 msg->length = sizeof(*msg); 5330 5331 msg->callback = callback; 5332 status = umac_send_mb_message_to_mac(msg); 5333 sme_release_global_lock(&mac_ctx->sme); 5334 return status; 5335 } 5336 return QDF_STATUS_E_FAILURE; 5337 } 5338 5339 /* 5340 * sme_RegisterMgtFrame() - 5341 * To register management frame of specified type and subtype. 5342 * 5343 * frameType - type of the frame that needs to be passed to HDD. 5344 * matchData - data which needs to be matched before passing frame 5345 * to HDD. 5346 * matchDataLen - Length of matched data. 5347 * Return QDF_STATUS 5348 */ sme_register_mgmt_frame(mac_handle_t mac_handle,uint8_t sessionId,uint16_t frameType,uint8_t * matchData,uint16_t matchLen)5349 QDF_STATUS sme_register_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId, 5350 uint16_t frameType, uint8_t *matchData, 5351 uint16_t matchLen) 5352 { 5353 QDF_STATUS status = QDF_STATUS_SUCCESS; 5354 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5355 5356 status = sme_acquire_global_lock(&mac->sme); 5357 if (QDF_IS_STATUS_SUCCESS(status)) { 5358 struct register_mgmt_frame *pMsg; 5359 uint16_t len; 5360 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, 5361 sessionId); 5362 5363 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) { 5364 sme_err("Session %d not found", sessionId); 5365 sme_release_global_lock(&mac->sme); 5366 return QDF_STATUS_E_FAILURE; 5367 } 5368 5369 if (!CSR_IS_SESSION_ANY(sessionId) && 5370 !pSession->sessionActive) { 5371 sme_err("Invalid Sessionid"); 5372 sme_release_global_lock(&mac->sme); 5373 return QDF_STATUS_E_FAILURE; 5374 } 5375 5376 len = sizeof(*pMsg) + matchLen; 5377 5378 pMsg = qdf_mem_malloc(len); 5379 if (!pMsg) 5380 status = QDF_STATUS_E_NOMEM; 5381 else { 5382 pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; 5383 pMsg->length = len; 5384 pMsg->sessionId = sessionId; 5385 pMsg->registerFrame = true; 5386 pMsg->frameType = frameType; 5387 pMsg->matchLen = matchLen; 5388 qdf_mem_copy(pMsg->matchData, matchData, matchLen); 5389 status = umac_send_mb_message_to_mac(pMsg); 5390 } 5391 sme_release_global_lock(&mac->sme); 5392 } 5393 return status; 5394 } 5395 5396 /* 5397 * sme_DeregisterMgtFrame() - 5398 * To De-register management frame of specified type and subtype. 5399 * 5400 * frameType - type of the frame that needs to be passed to HDD. 5401 * matchData - data which needs to be matched before passing frame 5402 * to HDD. 5403 * matchDataLen - Length of matched data. 5404 * Return QDF_STATUS 5405 */ sme_deregister_mgmt_frame(mac_handle_t mac_handle,uint8_t sessionId,uint16_t frameType,uint8_t * matchData,uint16_t matchLen)5406 QDF_STATUS sme_deregister_mgmt_frame(mac_handle_t mac_handle, uint8_t sessionId, 5407 uint16_t frameType, uint8_t *matchData, 5408 uint16_t matchLen) 5409 { 5410 QDF_STATUS status = QDF_STATUS_SUCCESS; 5411 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5412 5413 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5414 TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId, 5415 0)); 5416 status = sme_acquire_global_lock(&mac->sme); 5417 if (QDF_IS_STATUS_SUCCESS(status)) { 5418 struct register_mgmt_frame *pMsg; 5419 uint16_t len; 5420 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, 5421 sessionId); 5422 5423 if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) { 5424 sme_err("Session %d not found", sessionId); 5425 sme_release_global_lock(&mac->sme); 5426 return QDF_STATUS_E_FAILURE; 5427 } 5428 5429 if (!CSR_IS_SESSION_ANY(sessionId) && 5430 !pSession->sessionActive) { 5431 sme_err("Invalid Sessionid"); 5432 sme_release_global_lock(&mac->sme); 5433 return QDF_STATUS_E_FAILURE; 5434 } 5435 5436 len = sizeof(*pMsg) + matchLen; 5437 5438 pMsg = qdf_mem_malloc(len); 5439 if (!pMsg) 5440 status = QDF_STATUS_E_NOMEM; 5441 else { 5442 pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; 5443 pMsg->length = len; 5444 pMsg->registerFrame = false; 5445 pMsg->frameType = frameType; 5446 pMsg->matchLen = matchLen; 5447 qdf_mem_copy(pMsg->matchData, matchData, matchLen); 5448 status = umac_send_mb_message_to_mac(pMsg); 5449 } 5450 sme_release_global_lock(&mac->sme); 5451 } 5452 return status; 5453 } 5454 5455 /** 5456 * sme_prepare_mgmt_tx() - Prepares mgmt frame 5457 * @mac_handle: The handle returned by mac_open 5458 * @vdev_id: vdev id 5459 * @buf: pointer to frame 5460 * @len: frame length 5461 * 5462 * Return: QDF_STATUS 5463 */ sme_prepare_mgmt_tx(mac_handle_t mac_handle,uint8_t vdev_id,const uint8_t * buf,uint32_t len)5464 static QDF_STATUS sme_prepare_mgmt_tx(mac_handle_t mac_handle, 5465 uint8_t vdev_id, 5466 const uint8_t *buf, uint32_t len) 5467 { 5468 QDF_STATUS status = QDF_STATUS_SUCCESS; 5469 struct sir_mgmt_msg *msg; 5470 uint16_t msg_len; 5471 struct scheduler_msg sch_msg = {0}; 5472 5473 sme_debug("prepares auth frame"); 5474 5475 msg_len = sizeof(*msg) + len; 5476 msg = qdf_mem_malloc(msg_len); 5477 if (!msg) { 5478 status = QDF_STATUS_E_NOMEM; 5479 } else { 5480 msg->type = eWNI_SME_SEND_MGMT_FRAME_TX; 5481 msg->msg_len = msg_len; 5482 msg->vdev_id = vdev_id; 5483 msg->data = (uint8_t *)msg + sizeof(*msg); 5484 qdf_mem_copy(msg->data, buf, len); 5485 5486 sch_msg.type = eWNI_SME_SEND_MGMT_FRAME_TX; 5487 sch_msg.bodyptr = msg; 5488 status = scheduler_post_message(QDF_MODULE_ID_SME, 5489 QDF_MODULE_ID_PE, 5490 QDF_MODULE_ID_PE, &sch_msg); 5491 } 5492 return status; 5493 } 5494 sme_send_mgmt_tx(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * buf,uint32_t len)5495 QDF_STATUS sme_send_mgmt_tx(mac_handle_t mac_handle, uint8_t session_id, 5496 const uint8_t *buf, uint32_t len) 5497 { 5498 QDF_STATUS status = QDF_STATUS_SUCCESS; 5499 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5500 5501 status = sme_acquire_global_lock(&mac->sme); 5502 if (QDF_IS_STATUS_SUCCESS(status)) { 5503 status = sme_prepare_mgmt_tx(mac_handle, session_id, buf, len); 5504 sme_release_global_lock(&mac->sme); 5505 } 5506 5507 return status; 5508 } 5509 5510 #ifdef WLAN_FEATURE_EXTWOW_SUPPORT 5511 /** 5512 * sme_configure_ext_wow() - configure Extr WoW 5513 * @mac_handle - The handle returned by mac_open. 5514 * @wlanExtParams - Depicts the wlan Ext params. 5515 * @callback - ext_wow callback to be registered. 5516 * @callback_context - ext_wow callback context 5517 * 5518 * SME will pass this request to lower mac to configure Extr WoW 5519 * Return: QDF_STATUS 5520 */ sme_configure_ext_wow(mac_handle_t mac_handle,tpSirExtWoWParams wlanExtParams,csr_readyToExtWoWCallback callback,void * callback_context)5521 QDF_STATUS sme_configure_ext_wow(mac_handle_t mac_handle, 5522 tpSirExtWoWParams wlanExtParams, 5523 csr_readyToExtWoWCallback callback, 5524 void *callback_context) 5525 { 5526 QDF_STATUS status = QDF_STATUS_SUCCESS; 5527 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 5528 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5529 struct scheduler_msg message = {0}; 5530 tpSirExtWoWParams MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); 5531 5532 if (!MsgPtr) 5533 return QDF_STATUS_E_NOMEM; 5534 5535 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5536 TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0)); 5537 5538 mac->readyToExtWoWCallback = callback; 5539 mac->readyToExtWoWContext = callback_context; 5540 5541 status = sme_acquire_global_lock(&mac->sme); 5542 if (QDF_IS_STATUS_SUCCESS(status)) { 5543 5544 /* serialize the req through MC thread */ 5545 qdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr)); 5546 message.bodyptr = MsgPtr; 5547 message.type = WMA_WLAN_EXT_WOW; 5548 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 5549 QDF_MODULE_ID_WMA, 5550 QDF_MODULE_ID_WMA, 5551 &message); 5552 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5553 mac->readyToExtWoWCallback = NULL; 5554 mac->readyToExtWoWContext = NULL; 5555 qdf_mem_free(MsgPtr); 5556 status = QDF_STATUS_E_FAILURE; 5557 } 5558 sme_release_global_lock(&mac->sme); 5559 } else { 5560 mac->readyToExtWoWCallback = NULL; 5561 mac->readyToExtWoWContext = NULL; 5562 qdf_mem_free(MsgPtr); 5563 } 5564 5565 return status; 5566 } 5567 5568 /* 5569 * sme_configure_app_type1_params() - 5570 * SME will pass this request to lower mac to configure Indoor WoW parameters. 5571 * 5572 * mac_handle - The handle returned by mac_open. 5573 * wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params 5574 * Return QDF_STATUS 5575 */ sme_configure_app_type1_params(mac_handle_t mac_handle,tpSirAppType1Params wlanAppType1Params)5576 QDF_STATUS sme_configure_app_type1_params(mac_handle_t mac_handle, 5577 tpSirAppType1Params wlanAppType1Params) 5578 { 5579 QDF_STATUS status = QDF_STATUS_SUCCESS; 5580 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 5581 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5582 struct scheduler_msg message = {0}; 5583 tpSirAppType1Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); 5584 5585 if (!MsgPtr) 5586 return QDF_STATUS_E_NOMEM; 5587 5588 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5589 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION, 5590 0)); 5591 5592 status = sme_acquire_global_lock(&mac->sme); 5593 if (QDF_IS_STATUS_SUCCESS(status)) { 5594 /* serialize the req through MC thread */ 5595 qdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr)); 5596 message.bodyptr = MsgPtr; 5597 message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS; 5598 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 5599 QDF_MODULE_ID_WMA, 5600 QDF_MODULE_ID_WMA, 5601 &message); 5602 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5603 qdf_mem_free(MsgPtr); 5604 status = QDF_STATUS_E_FAILURE; 5605 } 5606 sme_release_global_lock(&mac->sme); 5607 } else { 5608 qdf_mem_free(MsgPtr); 5609 } 5610 5611 return status; 5612 } 5613 5614 /* 5615 * sme_configure_app_type2_params() - 5616 * SME will pass this request to lower mac to configure Indoor WoW parameters. 5617 * 5618 * mac_handle - The handle returned by mac_open. 5619 * wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params 5620 * Return QDF_STATUS 5621 */ sme_configure_app_type2_params(mac_handle_t mac_handle,tpSirAppType2Params wlanAppType2Params)5622 QDF_STATUS sme_configure_app_type2_params(mac_handle_t mac_handle, 5623 tpSirAppType2Params wlanAppType2Params) 5624 { 5625 QDF_STATUS status = QDF_STATUS_SUCCESS; 5626 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 5627 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5628 struct scheduler_msg message = {0}; 5629 tpSirAppType2Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); 5630 5631 if (!MsgPtr) 5632 return QDF_STATUS_E_NOMEM; 5633 5634 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 5635 TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION, 5636 0)); 5637 5638 status = sme_acquire_global_lock(&mac->sme); 5639 if (QDF_IS_STATUS_SUCCESS(status)) { 5640 /* serialize the req through MC thread */ 5641 qdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr)); 5642 message.bodyptr = MsgPtr; 5643 message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS; 5644 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 5645 QDF_MODULE_ID_WMA, 5646 QDF_MODULE_ID_WMA, 5647 &message); 5648 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 5649 qdf_mem_free(MsgPtr); 5650 status = QDF_STATUS_E_FAILURE; 5651 } 5652 sme_release_global_lock(&mac->sme); 5653 } else { 5654 qdf_mem_free(MsgPtr); 5655 } 5656 5657 return status; 5658 } 5659 #endif 5660 sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle,uint8_t vdev_id_to_skip)5661 uint32_t sme_get_beaconing_concurrent_operation_channel(mac_handle_t mac_handle, 5662 uint8_t vdev_id_to_skip) 5663 { 5664 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5665 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5666 uint32_t chan_freq = 0; 5667 5668 status = sme_acquire_global_lock(&mac->sme); 5669 if (QDF_IS_STATUS_SUCCESS(status)) { 5670 5671 chan_freq = csr_get_beaconing_concurrent_channel(mac, 5672 vdev_id_to_skip); 5673 sme_debug("Other Concurrent Chan_freq: %d skipped vdev_id %d", 5674 chan_freq, vdev_id_to_skip); 5675 sme_release_global_lock(&mac->sme); 5676 } 5677 5678 return chan_freq; 5679 } 5680 5681 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH sme_check_concurrent_channel_overlap(mac_handle_t mac_handle,uint16_t sap_ch_freq,eCsrPhyMode sapPhyMode,uint8_t cc_switch_mode,uint8_t vdev_id)5682 uint16_t sme_check_concurrent_channel_overlap(mac_handle_t mac_handle, 5683 uint16_t sap_ch_freq, 5684 eCsrPhyMode sapPhyMode, 5685 uint8_t cc_switch_mode, 5686 uint8_t vdev_id) 5687 { 5688 QDF_STATUS status = QDF_STATUS_E_FAILURE; 5689 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5690 uint16_t intf_ch_freq = 0; 5691 5692 status = sme_acquire_global_lock(&mac->sme); 5693 if (QDF_IS_STATUS_SUCCESS(status)) { 5694 intf_ch_freq = csr_check_concurrent_channel_overlap( 5695 mac, sap_ch_freq, sapPhyMode, cc_switch_mode, vdev_id); 5696 sme_release_global_lock(&mac->sme); 5697 } 5698 5699 return intf_ch_freq; 5700 } 5701 #endif 5702 5703 /** 5704 * sme_set_tsfcb() - Set callback for TSF capture 5705 * @mac_handle: Handler return by mac_open 5706 * @cb_fn: Callback function pointer 5707 * @db_ctx: Callback data 5708 * 5709 * Return: QDF_STATUS 5710 */ sme_set_tsfcb(mac_handle_t mac_handle,int (* cb_fn)(void * cb_ctx,struct stsf * ptsf),void * cb_ctx)5711 QDF_STATUS sme_set_tsfcb(mac_handle_t mac_handle, 5712 int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx) 5713 { 5714 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5715 QDF_STATUS status; 5716 5717 status = sme_acquire_global_lock(&mac->sme); 5718 if (QDF_IS_STATUS_SUCCESS(status)) { 5719 mac->sme.get_tsf_cb = cb_fn; 5720 mac->sme.get_tsf_cxt = cb_ctx; 5721 sme_release_global_lock(&mac->sme); 5722 } 5723 return status; 5724 } 5725 5726 /** 5727 * sme_reset_tsfcb() - Reset callback for TSF capture 5728 * @mac_handle: Handler return by mac_open 5729 * 5730 * This function reset the tsf capture callback to SME 5731 * 5732 * Return: QDF_STATUS 5733 */ sme_reset_tsfcb(mac_handle_t mac_handle)5734 QDF_STATUS sme_reset_tsfcb(mac_handle_t mac_handle) 5735 { 5736 struct mac_context *mac; 5737 QDF_STATUS status; 5738 5739 if (!mac_handle) { 5740 sme_err("mac_handle is not valid"); 5741 return QDF_STATUS_E_INVAL; 5742 } 5743 mac = MAC_CONTEXT(mac_handle); 5744 5745 status = sme_acquire_global_lock(&mac->sme); 5746 if (QDF_IS_STATUS_SUCCESS(status)) { 5747 mac->sme.get_tsf_cb = NULL; 5748 mac->sme.get_tsf_cxt = NULL; 5749 sme_release_global_lock(&mac->sme); 5750 } 5751 return status; 5752 } 5753 5754 #if defined(WLAN_FEATURE_TSF) && !defined(WLAN_FEATURE_TSF_PLUS_NOIRQ) 5755 /* 5756 * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tsf 5757 * @mac_handle: Handler return by mac_open 5758 * @pinvalue: gpio pin id 5759 * 5760 * Return: QDF_STATUS 5761 */ sme_set_tsf_gpio(mac_handle_t mac_handle,uint32_t pinvalue)5762 QDF_STATUS sme_set_tsf_gpio(mac_handle_t mac_handle, uint32_t pinvalue) 5763 { 5764 QDF_STATUS status; 5765 struct scheduler_msg tsf_msg = {0}; 5766 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5767 5768 status = sme_acquire_global_lock(&mac->sme); 5769 if (QDF_IS_STATUS_SUCCESS(status)) { 5770 tsf_msg.type = WMA_TSF_GPIO_PIN; 5771 tsf_msg.reserved = 0; 5772 tsf_msg.bodyval = pinvalue; 5773 5774 status = scheduler_post_message(QDF_MODULE_ID_SME, 5775 QDF_MODULE_ID_WMA, 5776 QDF_MODULE_ID_WMA, &tsf_msg); 5777 if (!QDF_IS_STATUS_SUCCESS(status)) { 5778 sme_err("Unable to post WMA_TSF_GPIO_PIN"); 5779 status = QDF_STATUS_E_FAILURE; 5780 } 5781 sme_release_global_lock(&mac->sme); 5782 } 5783 return status; 5784 } 5785 #endif 5786 sme_get_cfg_valid_channels(uint32_t * valid_ch_freq,uint32_t * len)5787 QDF_STATUS sme_get_cfg_valid_channels(uint32_t *valid_ch_freq, uint32_t *len) 5788 { 5789 QDF_STATUS status; 5790 struct mac_context *mac_ctx = sme_get_mac_context(); 5791 uint32_t *valid_ch_freq_list; 5792 uint32_t i; 5793 5794 if (!mac_ctx) { 5795 sme_err("Invalid MAC context"); 5796 return QDF_STATUS_E_FAILURE; 5797 } 5798 5799 valid_ch_freq_list = qdf_mem_malloc(CFG_VALID_CHANNEL_LIST_LEN * 5800 sizeof(uint32_t)); 5801 if (!valid_ch_freq_list) 5802 return QDF_STATUS_E_NOMEM; 5803 5804 status = csr_get_cfg_valid_channels(mac_ctx, valid_ch_freq_list, len); 5805 5806 for (i = 0; i < *len; i++) 5807 valid_ch_freq[i] = valid_ch_freq_list[i]; 5808 5809 qdf_mem_free(valid_ch_freq_list); 5810 5811 return status; 5812 } 5813 5814 /** 5815 * sme_handle_generic_change_country_code() - handles country ch req 5816 * @mac_ctx: mac global context 5817 * @msg: request msg packet 5818 * 5819 * If Supplicant country code is priority than 11d is disabled. 5820 * If 11D is enabled, we update the country code after every scan. 5821 * Hence when Supplicant country code is priority, we don't need 11D info. 5822 * Country code from Supplicant is set as current country code. 5823 * 5824 * Return: status of operation 5825 */ 5826 static QDF_STATUS sme_handle_generic_change_country_code(struct mac_context * mac_ctx,void * msg_buf)5827 sme_handle_generic_change_country_code(struct mac_context *mac_ctx, 5828 void *msg_buf) 5829 { 5830 QDF_STATUS status = QDF_STATUS_SUCCESS; 5831 5832 /* get the channels based on new cc */ 5833 status = csr_get_channel_and_power_list(mac_ctx); 5834 5835 if (status != QDF_STATUS_SUCCESS) { 5836 sme_err("fail to get Channels"); 5837 return status; 5838 } 5839 5840 /* reset info based on new cc, and we are done */ 5841 csr_apply_channel_power_info_wrapper(mac_ctx); 5842 csr_update_beacon(mac_ctx); 5843 5844 csr_scan_filter_results(mac_ctx); 5845 5846 return QDF_STATUS_SUCCESS; 5847 } 5848 sme_update_channel_list(mac_handle_t mac_handle)5849 QDF_STATUS sme_update_channel_list(mac_handle_t mac_handle) 5850 { 5851 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 5852 QDF_STATUS status; 5853 5854 status = sme_acquire_global_lock(&mac_ctx->sme); 5855 if (QDF_IS_STATUS_SUCCESS(status)) { 5856 /* Update umac channel (enable/disable) from cds channels */ 5857 status = csr_get_channel_and_power_list(mac_ctx); 5858 if (status != QDF_STATUS_SUCCESS) { 5859 sme_err("fail to get Channels"); 5860 sme_release_global_lock(&mac_ctx->sme); 5861 return status; 5862 } 5863 5864 csr_apply_channel_power_info_wrapper(mac_ctx); 5865 csr_scan_filter_results(mac_ctx); 5866 sme_release_global_lock(&mac_ctx->sme); 5867 /* release the sme lock before we call cm disconnect */ 5868 sme_disconnect_connected_sessions(mac_ctx, 5869 REASON_OPER_CHANNEL_USER_DISABLED); 5870 } 5871 5872 return status; 5873 } 5874 5875 /** 5876 * sme_search_in_base_ch_freq_lst() - is given ch_freq in base ch freq 5877 * @mac_ctx: mac global context 5878 * @chan_freq: current channel freq 5879 * 5880 * Return: true if given ch_freq is in base ch freq 5881 */ sme_search_in_base_ch_freq_lst(struct mac_context * mac_ctx,uint32_t chan_freq)5882 static bool sme_search_in_base_ch_freq_lst( 5883 struct mac_context *mac_ctx, uint32_t chan_freq) 5884 { 5885 uint8_t i; 5886 struct csr_channel *ch_lst_info; 5887 5888 ch_lst_info = &mac_ctx->scan.base_channels; 5889 for (i = 0; i < ch_lst_info->numChannels; i++) { 5890 if (ch_lst_info->channel_freq_list[i] == chan_freq) 5891 return true; 5892 } 5893 5894 return false; 5895 } 5896 5897 /** 5898 * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session 5899 * if channel is not supported 5900 * @mac_ctx: mac global context 5901 * @reason: Mac Disconnect reason code as per @enum wlan_reason_code 5902 * 5903 * If new country code does not support the channel on which STA/P2P client 5904 * is connected, it sends the disconnect to the AP/P2P GO 5905 * 5906 * Return: void 5907 */ sme_disconnect_connected_sessions(struct mac_context * mac_ctx,enum wlan_reason_code reason)5908 static void sme_disconnect_connected_sessions(struct mac_context *mac_ctx, 5909 enum wlan_reason_code reason) 5910 { 5911 uint8_t vdev_id, found = false; 5912 qdf_freq_t chan_freq; 5913 enum QDF_OPMODE op_mode; 5914 struct wlan_objmgr_vdev *vdev; 5915 5916 for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) { 5917 op_mode = wlan_get_opmode_from_vdev_id(mac_ctx->pdev, vdev_id); 5918 /* check only for STA and CLI */ 5919 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 5920 continue; 5921 5922 chan_freq = 5923 wlan_get_operation_chan_freq_vdev_id(mac_ctx->pdev, 5924 vdev_id); 5925 if (!chan_freq) 5926 continue; 5927 found = false; 5928 sme_debug("Current Operating channel : %d, vdev_id :%d", 5929 chan_freq, vdev_id); 5930 found = sme_search_in_base_ch_freq_lst(mac_ctx, chan_freq); 5931 if (!found) { 5932 sme_debug("Disconnect Session: %d", vdev_id); 5933 /* do not call cm disconnect while holding Sme lock */ 5934 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 5935 mac_ctx->psoc, 5936 vdev_id, 5937 WLAN_LEGACY_SME_ID); 5938 if (!vdev) { 5939 sme_err("vdev object is NULL for vdev_id %d", 5940 vdev_id); 5941 return; 5942 } 5943 mlo_disconnect(vdev, CM_MLME_DISCONNECT, reason, NULL); 5944 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 5945 } 5946 } 5947 } 5948 5949 #ifdef WLAN_FEATURE_PACKET_FILTERING sme_8023_multicast_list(mac_handle_t mac_handle,uint8_t sessionId,tpSirRcvFltMcAddrList pMulticastAddrs)5950 QDF_STATUS sme_8023_multicast_list(mac_handle_t mac_handle, uint8_t sessionId, 5951 tpSirRcvFltMcAddrList pMulticastAddrs) 5952 { 5953 tpSirRcvFltMcAddrList request_buf; 5954 struct scheduler_msg msg = {0}; 5955 struct mac_context *mac = MAC_CONTEXT(mac_handle); 5956 struct csr_roam_session *pSession = NULL; 5957 5958 sme_debug("ulMulticastAddrCnt: %d, multicastAddr[0]: %pK", 5959 pMulticastAddrs->ulMulticastAddrCnt, 5960 pMulticastAddrs->multicastAddr[0].bytes); 5961 5962 /* Find the connected Infra / P2P_client connected session */ 5963 pSession = CSR_GET_SESSION(mac, sessionId); 5964 if (!CSR_IS_SESSION_VALID(mac, sessionId) || 5965 (!cm_is_vdevid_connected(mac->pdev, sessionId) && 5966 !csr_is_ndi_started(mac, sessionId))) { 5967 sme_err("Unable to find the vdev %d", sessionId); 5968 return QDF_STATUS_E_FAILURE; 5969 } 5970 5971 request_buf = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList)); 5972 if (!request_buf) 5973 return QDF_STATUS_E_NOMEM; 5974 5975 if (!cm_is_vdevid_connected(mac->pdev, sessionId) && 5976 !csr_is_ndi_started(mac, sessionId)) { 5977 sme_err("Request ignored, session %d is not connected or started", 5978 sessionId); 5979 qdf_mem_free(request_buf); 5980 return QDF_STATUS_E_FAILURE; 5981 } 5982 5983 qdf_mem_copy(request_buf, pMulticastAddrs, 5984 sizeof(tSirRcvFltMcAddrList)); 5985 5986 wlan_mlme_get_mac_vdev_id(mac->pdev, sessionId, 5987 &request_buf->self_macaddr); 5988 wlan_mlme_get_bssid_vdev_id(mac->pdev, sessionId, &request_buf->bssid); 5989 5990 msg.type = WMA_8023_MULTICAST_LIST_REQ; 5991 msg.reserved = 0; 5992 msg.bodyptr = request_buf; 5993 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 5994 sessionId, msg.type)); 5995 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 5996 QDF_MODULE_ID_WMA, 5997 QDF_MODULE_ID_WMA, 5998 &msg)) { 5999 sme_err("Not able to post WMA_8023_MULTICAST_LIST message to WMA"); 6000 qdf_mem_free(request_buf); 6001 return QDF_STATUS_E_FAILURE; 6002 } 6003 6004 return QDF_STATUS_SUCCESS; 6005 } 6006 #endif /* WLAN_FEATURE_PACKET_FILTERING */ 6007 sme_is_channel_valid(mac_handle_t mac_handle,uint32_t chan_freq)6008 bool sme_is_channel_valid(mac_handle_t mac_handle, uint32_t chan_freq) 6009 { 6010 QDF_STATUS status = QDF_STATUS_E_FAILURE; 6011 bool valid = false; 6012 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6013 6014 status = sme_acquire_global_lock(&mac->sme); 6015 if (QDF_IS_STATUS_SUCCESS(status)) { 6016 6017 valid = wlan_roam_is_channel_valid(&mac->mlme_cfg->reg, 6018 chan_freq); 6019 6020 sme_release_global_lock(&mac->sme); 6021 } 6022 6023 return valid; 6024 } 6025 6026 /* 6027 * sme_set_max_tx_power_per_band() - 6028 * Set the Maximum Transmit Power specific to band dynamically. 6029 * Note: this setting will not persist over reboots. 6030 * 6031 * band 6032 * power to set in dB 6033 * Return QDF_STATUS 6034 */ sme_set_max_tx_power_per_band(enum band_info band,int8_t dB)6035 QDF_STATUS sme_set_max_tx_power_per_band(enum band_info band, int8_t dB) 6036 { 6037 struct scheduler_msg msg = {0}; 6038 tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL; 6039 6040 pMaxTxPowerPerBandParams = 6041 qdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams)); 6042 if (!pMaxTxPowerPerBandParams) 6043 return QDF_STATUS_E_NOMEM; 6044 6045 pMaxTxPowerPerBandParams->power = dB; 6046 pMaxTxPowerPerBandParams->bandInfo = band; 6047 6048 msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ; 6049 msg.reserved = 0; 6050 msg.bodyptr = pMaxTxPowerPerBandParams; 6051 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 6052 NO_SESSION, msg.type)); 6053 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6054 QDF_MODULE_ID_WMA, 6055 QDF_MODULE_ID_WMA, 6056 &msg)) { 6057 sme_err("Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ"); 6058 qdf_mem_free(pMaxTxPowerPerBandParams); 6059 return QDF_STATUS_E_FAILURE; 6060 } 6061 6062 return QDF_STATUS_SUCCESS; 6063 } 6064 6065 /* 6066 * sme_set_max_tx_power() - 6067 * Set the Maximum Transmit Power dynamically. Note: this setting will 6068 * not persist over reboots. 6069 * 6070 * mac_handle 6071 * pBssid BSSID to set the power cap for 6072 * pBssid pSelfMacAddress self MAC Address 6073 * pBssid power to set in dB 6074 * Return QDF_STATUS 6075 */ sme_set_max_tx_power(mac_handle_t mac_handle,struct qdf_mac_addr pBssid,struct qdf_mac_addr pSelfMacAddress,int8_t dB)6076 QDF_STATUS sme_set_max_tx_power(mac_handle_t mac_handle, 6077 struct qdf_mac_addr pBssid, 6078 struct qdf_mac_addr pSelfMacAddress, int8_t dB) 6079 { 6080 struct scheduler_msg msg = {0}; 6081 tpMaxTxPowerParams pMaxTxParams = NULL; 6082 6083 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 6084 TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0)); 6085 pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams)); 6086 if (!pMaxTxParams) 6087 return QDF_STATUS_E_NOMEM; 6088 6089 qdf_copy_macaddr(&pMaxTxParams->bssId, &pBssid); 6090 qdf_copy_macaddr(&pMaxTxParams->selfStaMacAddr, &pSelfMacAddress); 6091 pMaxTxParams->power = dB; 6092 6093 msg.type = WMA_SET_MAX_TX_POWER_REQ; 6094 msg.reserved = 0; 6095 msg.bodyptr = pMaxTxParams; 6096 6097 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6098 QDF_MODULE_ID_WMA, 6099 QDF_MODULE_ID_WMA, 6100 &msg)) { 6101 sme_err("Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA"); 6102 qdf_mem_free(pMaxTxParams); 6103 return QDF_STATUS_E_FAILURE; 6104 } 6105 6106 return QDF_STATUS_SUCCESS; 6107 } 6108 sme_set_listen_interval(mac_handle_t mac_handle,uint8_t vdev_id)6109 void sme_set_listen_interval(mac_handle_t mac_handle, uint8_t vdev_id) 6110 { 6111 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6112 struct pe_session *session = NULL; 6113 uint8_t val = 0; 6114 6115 session = pe_find_session_by_vdev_id(mac, vdev_id); 6116 if (!session) { 6117 sme_err("Session lookup fails for vdev %d", vdev_id); 6118 return; 6119 } 6120 6121 val = session->dtimPeriod; 6122 pe_debug("Listen interval: %d vdev id: %d", val, vdev_id); 6123 wma_vdev_set_listen_interval(vdev_id, val); 6124 } 6125 6126 /* 6127 * sme_set_custom_mac_addr() - 6128 * Set the customer Mac Address. 6129 * 6130 * customMacAddr customer MAC Address 6131 * Return QDF_STATUS 6132 */ sme_set_custom_mac_addr(tSirMacAddr customMacAddr)6133 QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr) 6134 { 6135 struct scheduler_msg msg = {0}; 6136 tSirMacAddr *pBaseMacAddr; 6137 6138 pBaseMacAddr = qdf_mem_malloc(sizeof(tSirMacAddr)); 6139 if (!pBaseMacAddr) 6140 return QDF_STATUS_E_NOMEM; 6141 6142 qdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr)); 6143 6144 msg.type = SIR_HAL_SET_BASE_MACADDR_IND; 6145 msg.reserved = 0; 6146 msg.bodyptr = pBaseMacAddr; 6147 6148 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6149 QDF_MODULE_ID_WMA, 6150 QDF_MODULE_ID_WMA, 6151 &msg)) { 6152 sme_err("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA"); 6153 qdf_mem_free(pBaseMacAddr); 6154 return QDF_STATUS_E_FAILURE; 6155 } 6156 6157 return QDF_STATUS_SUCCESS; 6158 } 6159 6160 /* 6161 * sme_set_tx_power() - 6162 * Set Transmit Power dynamically. 6163 * 6164 * mac_handle 6165 * sessionId Target Session ID 6166 * BSSID 6167 * dev_mode dev_mode such as station, P2PGO, SAP 6168 * dBm power to set 6169 * Return QDF_STATUS 6170 */ sme_set_tx_power(mac_handle_t mac_handle,uint8_t sessionId,struct qdf_mac_addr pBSSId,enum QDF_OPMODE dev_mode,int dBm)6171 QDF_STATUS sme_set_tx_power(mac_handle_t mac_handle, uint8_t sessionId, 6172 struct qdf_mac_addr pBSSId, 6173 enum QDF_OPMODE dev_mode, int dBm) 6174 { 6175 struct scheduler_msg msg = {0}; 6176 tpMaxTxPowerParams pTxParams = NULL; 6177 int8_t power = (int8_t) dBm; 6178 6179 MTRACE(qdf_trace(QDF_MODULE_ID_SME, 6180 TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0)); 6181 6182 /* make sure there is no overflow */ 6183 if ((int)power != dBm) { 6184 sme_err("error, invalid power = %d", dBm); 6185 return QDF_STATUS_E_FAILURE; 6186 } 6187 6188 pTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams)); 6189 if (!pTxParams) 6190 return QDF_STATUS_E_NOMEM; 6191 6192 qdf_copy_macaddr(&pTxParams->bssId, &pBSSId); 6193 pTxParams->power = power; /* unit is dBm */ 6194 pTxParams->dev_mode = dev_mode; 6195 msg.type = WMA_SET_TX_POWER_REQ; 6196 msg.reserved = 0; 6197 msg.bodyptr = pTxParams; 6198 6199 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 6200 QDF_MODULE_ID_WMA, 6201 QDF_MODULE_ID_WMA, 6202 &msg)) { 6203 qdf_mem_free(pTxParams); 6204 return QDF_STATUS_E_FAILURE; 6205 } 6206 6207 return QDF_STATUS_SUCCESS; 6208 } 6209 sme_set_check_assoc_disallowed(mac_handle_t mac_handle,bool check_assoc_disallowed)6210 QDF_STATUS sme_set_check_assoc_disallowed(mac_handle_t mac_handle, 6211 bool check_assoc_disallowed) 6212 { 6213 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6214 QDF_STATUS status; 6215 6216 status = sme_acquire_global_lock(&mac->sme); 6217 if (QDF_IS_STATUS_ERROR(status)) { 6218 sme_err("Failed to acquire sme lock; status: %d", status); 6219 return status; 6220 } 6221 wlan_cm_set_check_assoc_disallowed(mac->psoc, check_assoc_disallowed); 6222 sme_release_global_lock(&mac->sme); 6223 6224 return QDF_STATUS_SUCCESS; 6225 } 6226 sme_update_session_param(mac_handle_t mac_handle,uint8_t session_id,uint32_t param_type,uint32_t param_val)6227 QDF_STATUS sme_update_session_param(mac_handle_t mac_handle, uint8_t session_id, 6228 uint32_t param_type, uint32_t param_val) 6229 { 6230 QDF_STATUS status = QDF_STATUS_SUCCESS; 6231 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 6232 uint16_t len; 6233 6234 status = sme_acquire_global_lock(&mac_ctx->sme); 6235 if (QDF_IS_STATUS_SUCCESS(status)) { 6236 struct sir_update_session_param *msg; 6237 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, 6238 session_id); 6239 6240 if (!session) { 6241 sme_err("Session: %d not found", session_id); 6242 sme_release_global_lock(&mac_ctx->sme); 6243 return status; 6244 } 6245 6246 if (!session->sessionActive) 6247 QDF_ASSERT(0); 6248 6249 len = sizeof(*msg); 6250 msg = qdf_mem_malloc(len); 6251 if (!msg) 6252 status = QDF_STATUS_E_NOMEM; 6253 else { 6254 msg->message_type = eWNI_SME_SESSION_UPDATE_PARAM; 6255 msg->length = len; 6256 msg->vdev_id = session_id; 6257 msg->param_type = param_type; 6258 msg->param_val = param_val; 6259 status = umac_send_mb_message_to_mac(msg); 6260 } 6261 sme_release_global_lock(&mac_ctx->sme); 6262 } 6263 return status; 6264 } 6265 sme_update_roam_scan_n_probes(mac_handle_t mac_handle,uint8_t vdev_id,const uint8_t probes)6266 QDF_STATUS sme_update_roam_scan_n_probes(mac_handle_t mac_handle, 6267 uint8_t vdev_id, 6268 const uint8_t probes) 6269 { 6270 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6271 struct cm_roam_values_copy src_config = {}; 6272 6273 src_config.uint_value = probes; 6274 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 6275 SCAN_N_PROBE, 6276 &src_config); 6277 } 6278 6279 QDF_STATUS sme_update_roam_scan_home_away_time(mac_handle_t mac_handle,uint8_t vdev_id,const uint16_t roam_scan_home_away_time,const bool send_offload_cmd)6280 sme_update_roam_scan_home_away_time(mac_handle_t mac_handle, uint8_t vdev_id, 6281 const uint16_t roam_scan_home_away_time, 6282 const bool send_offload_cmd) 6283 { 6284 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6285 struct cm_roam_values_copy src_config = {}; 6286 6287 src_config.bool_value = send_offload_cmd; 6288 src_config.uint_value = roam_scan_home_away_time; 6289 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 6290 SCAN_HOME_AWAY, &src_config); 6291 } 6292 6293 /** 6294 * sme_ext_change_freq()- function to post send ECSA 6295 * action frame to csr. 6296 * @mac_handle: Opaque handle to the global MAC context 6297 * @channel freq: new channel freq to switch 6298 * @session_id: senssion it should be sent on. 6299 * 6300 * This function is called to post ECSA frame to csr. 6301 * 6302 * Return: success if msg is sent else return failure 6303 */ sme_ext_change_freq(mac_handle_t mac_handle,qdf_freq_t ch_freq,uint8_t session_id)6304 QDF_STATUS sme_ext_change_freq(mac_handle_t mac_handle, qdf_freq_t ch_freq, 6305 uint8_t session_id) 6306 { 6307 QDF_STATUS status = QDF_STATUS_SUCCESS; 6308 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 6309 uint8_t channel_state; 6310 6311 sme_err("Set Channel freq: %d", ch_freq); 6312 6313 channel_state = wlan_reg_get_channel_state_for_pwrmode( 6314 mac_ctx->pdev, 6315 ch_freq, 6316 REG_CURRENT_PWR_MODE); 6317 6318 if (CHANNEL_STATE_DISABLE == channel_state) { 6319 sme_err("Invalid channel freq: %d", ch_freq); 6320 return QDF_STATUS_E_INVAL; 6321 } 6322 6323 status = sme_acquire_global_lock(&mac_ctx->sme); 6324 6325 if (QDF_STATUS_SUCCESS == status) { 6326 /* update the channel list to the firmware */ 6327 status = csr_send_ext_change_freq(mac_ctx, 6328 ch_freq, session_id); 6329 sme_release_global_lock(&mac_ctx->sme); 6330 } 6331 6332 return status; 6333 } 6334 sme_get_roam_scan_n_probes(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * roam_scan_n_probes)6335 QDF_STATUS sme_get_roam_scan_n_probes(mac_handle_t mac_handle, uint8_t vdev_id, 6336 uint8_t *roam_scan_n_probes) 6337 { 6338 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6339 struct cm_roam_values_copy temp; 6340 6341 wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id, SCAN_N_PROBE, &temp); 6342 *roam_scan_n_probes = temp.uint_value; 6343 6344 return QDF_STATUS_SUCCESS; 6345 } 6346 sme_update_roam_rssi_diff(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t roam_rssi_diff)6347 QDF_STATUS sme_update_roam_rssi_diff(mac_handle_t mac_handle, uint8_t vdev_id, 6348 uint8_t roam_rssi_diff) 6349 { 6350 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6351 struct cm_roam_values_copy src_config = {}; 6352 6353 src_config.uint_value = roam_rssi_diff; 6354 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 6355 ROAM_RSSI_DIFF, &src_config); 6356 } 6357 sme_send_rso_connect_params(mac_handle_t mac_handle,uint8_t vdev_id)6358 QDF_STATUS sme_send_rso_connect_params(mac_handle_t mac_handle, 6359 uint8_t vdev_id) 6360 { 6361 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6362 QDF_STATUS status = QDF_STATUS_SUCCESS; 6363 6364 if (vdev_id >= WLAN_MAX_VDEVS) { 6365 sme_err("Invalid sme vdev id: %d", vdev_id); 6366 return QDF_STATUS_E_INVAL; 6367 } 6368 6369 if (!mac->mlme_cfg->lfr.lfr_enabled) { 6370 sme_debug("lfr enabled %d", mac->mlme_cfg->lfr.lfr_enabled); 6371 return QDF_STATUS_E_PERM; 6372 } 6373 6374 if (wlan_is_roam_offload_enabled(mac->mlme_cfg->lfr)) { 6375 status = sme_acquire_global_lock(&mac->sme); 6376 if (QDF_IS_STATUS_SUCCESS(status)) { 6377 sme_debug("Updating fils config to fw"); 6378 wlan_roam_update_cfg(mac->psoc, vdev_id, 6379 REASON_FILS_PARAMS_CHANGED); 6380 sme_release_global_lock(&mac->sme); 6381 } else { 6382 sme_err("Failed to acquire SME lock"); 6383 } 6384 } else { 6385 sme_debug("LFR3 not enabled"); 6386 return QDF_STATUS_E_INVAL; 6387 } 6388 6389 return status; 6390 } 6391 6392 #ifdef WLAN_FEATURE_FILS_SK sme_send_hlp_ie_info(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t if_addr)6393 void sme_send_hlp_ie_info(mac_handle_t mac_handle, uint8_t vdev_id, 6394 uint32_t if_addr) 6395 { 6396 int i; 6397 struct scheduler_msg msg; 6398 QDF_STATUS status; 6399 struct hlp_params *params; 6400 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6401 struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); 6402 struct mlme_legacy_priv *mlme_priv; 6403 struct wlan_objmgr_vdev *vdev; 6404 6405 if (!session) { 6406 sme_err("session NULL"); 6407 return; 6408 } 6409 6410 if (!mac->mlme_cfg->lfr.lfr_enabled) { 6411 sme_debug("Fast roam is disabled"); 6412 return; 6413 } 6414 if (!csr_is_conn_state_connected(mac, vdev_id)) { 6415 sme_debug("vdev not connected"); 6416 return; 6417 } 6418 6419 params = qdf_mem_malloc(sizeof(*params)); 6420 if (!params) 6421 return; 6422 6423 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 6424 WLAN_MLME_NB_ID); 6425 if (!vdev) { 6426 mlme_err("vdev object is NULL for vdev_id %d", vdev_id); 6427 qdf_mem_free(params); 6428 return; 6429 } 6430 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 6431 if (!mlme_priv) { 6432 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 6433 qdf_mem_free(params); 6434 return; 6435 } 6436 if ((mlme_priv->connect_info.hlp_ie_len + 6437 QDF_IPV4_ADDR_SIZE) > FILS_MAX_HLP_DATA_LEN) { 6438 sme_err("HLP IE len exceeds %d", 6439 mlme_priv->connect_info.hlp_ie_len); 6440 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 6441 qdf_mem_free(params); 6442 return; 6443 } 6444 6445 params->vdev_id = vdev_id; 6446 params->hlp_ie_len = 6447 mlme_priv->connect_info.hlp_ie_len + QDF_IPV4_ADDR_SIZE; 6448 6449 for (i = 0; i < QDF_IPV4_ADDR_SIZE; i++) 6450 params->hlp_ie[i] = (if_addr >> (i * 8)) & 0xFF; 6451 6452 qdf_mem_copy(params->hlp_ie + QDF_IPV4_ADDR_SIZE, 6453 mlme_priv->connect_info.hlp_ie, 6454 mlme_priv->connect_info.hlp_ie_len); 6455 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 6456 6457 msg.type = SIR_HAL_HLP_IE_INFO; 6458 msg.reserved = 0; 6459 msg.bodyptr = params; 6460 status = sme_acquire_global_lock(&mac->sme); 6461 if (status != QDF_STATUS_SUCCESS) { 6462 sme_err("sme lock acquire fails"); 6463 qdf_mem_free(params); 6464 return; 6465 } 6466 6467 if (!QDF_IS_STATUS_SUCCESS 6468 (scheduler_post_message(QDF_MODULE_ID_SME, 6469 QDF_MODULE_ID_WMA, 6470 QDF_MODULE_ID_WMA, &msg))) { 6471 sme_err("Not able to post WMA_HLP_IE_INFO message to HAL"); 6472 sme_release_global_lock(&mac->sme); 6473 qdf_mem_free(params); 6474 return; 6475 } 6476 6477 sme_release_global_lock(&mac->sme); 6478 } 6479 6480 #else sme_send_hlp_ie_info(mac_handle_t mac_handle,uint8_t vdev_id,struct csr_roam_profile * profile,uint32_t if_addr)6481 inline void sme_send_hlp_ie_info(mac_handle_t mac_handle, uint8_t vdev_id, 6482 struct csr_roam_profile *profile, uint32_t if_addr) 6483 {} 6484 #endif 6485 6486 /* 6487 * sme_update_wes_mode() - 6488 * Update WES Mode 6489 * This function is called through dynamic setConfig callback function 6490 * to configure isWESModeEnabled 6491 * 6492 * mac_handle: Opaque handle to the global MAC context 6493 * isWESModeEnabled - WES mode 6494 * sessionId - Session Identifier 6495 * Return QDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully. 6496 * Other status means SME is failed to update isWESModeEnabled. 6497 */ 6498 sme_update_wes_mode(mac_handle_t mac_handle,bool isWESModeEnabled,uint8_t sessionId)6499 QDF_STATUS sme_update_wes_mode(mac_handle_t mac_handle, bool isWESModeEnabled, 6500 uint8_t sessionId) 6501 { 6502 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6503 QDF_STATUS status = QDF_STATUS_SUCCESS; 6504 6505 if (sessionId >= WLAN_MAX_VDEVS) { 6506 sme_err("Invalid vdev %d", sessionId); 6507 return QDF_STATUS_E_INVAL; 6508 } 6509 6510 status = sme_acquire_global_lock(&mac->sme); 6511 if (QDF_IS_STATUS_SUCCESS(status)) { 6512 sme_debug("LFR runtime successfully set WES Mode to %d - old value is %d", 6513 isWESModeEnabled, 6514 mac->mlme_cfg->lfr.wes_mode_enabled); 6515 mac->mlme_cfg->lfr.wes_mode_enabled = isWESModeEnabled; 6516 sme_release_global_lock(&mac->sme); 6517 } 6518 6519 return status; 6520 } 6521 6522 /* 6523 * sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR 6524 * support at runtime 6525 * It is used at in the REG_DYNAMIC_VARIABLE macro definition of 6526 * isFastRoamIniFeatureEnabled. 6527 * This is a synchronous call 6528 * 6529 * mac_handle - The handle returned by mac_open. 6530 * sessionId - Session Identifier 6531 * Return QDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config 6532 * successfully. 6533 * Other status means SME is failed to update isFastRoamIniFeatureEnabled. 6534 */ sme_update_is_fast_roam_ini_feature_enabled(mac_handle_t mac_handle,uint8_t sessionId,const bool isFastRoamIniFeatureEnabled)6535 QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled(mac_handle_t mac_handle, 6536 uint8_t sessionId, const bool isFastRoamIniFeatureEnabled) 6537 { 6538 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6539 6540 if (mac->mlme_cfg->lfr.lfr_enabled == 6541 isFastRoamIniFeatureEnabled) { 6542 sme_debug("FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", 6543 mac->mlme_cfg->lfr.lfr_enabled, 6544 isFastRoamIniFeatureEnabled); 6545 return QDF_STATUS_SUCCESS; 6546 } 6547 6548 sme_debug("FastRoamEnabled is changed from %d to %d", 6549 mac->mlme_cfg->lfr.lfr_enabled, 6550 isFastRoamIniFeatureEnabled); 6551 mac->mlme_cfg->lfr.lfr_enabled = isFastRoamIniFeatureEnabled; 6552 mlme_set_supplicant_disabled_roaming(mac->psoc, sessionId, 6553 !isFastRoamIniFeatureEnabled); 6554 if (isFastRoamIniFeatureEnabled) 6555 wlan_cm_roam_state_change(mac->pdev, sessionId, 6556 WLAN_ROAM_RSO_ENABLED, 6557 REASON_CONNECT); 6558 else 6559 wlan_cm_roam_state_change(mac->pdev, sessionId, 6560 WLAN_ROAM_RSO_STOPPED, 6561 REASON_SUPPLICANT_DISABLED_ROAMING); 6562 6563 return QDF_STATUS_SUCCESS; 6564 } 6565 6566 #ifdef FEATURE_WLAN_ESE sme_add_key_krk(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * key,const int key_len)6567 int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id, 6568 const uint8_t *key, const int key_len) 6569 { 6570 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 6571 struct wlan_objmgr_vdev *vdev; 6572 struct rso_config *rso_cfg; 6573 6574 if (key_len < WMI_KRK_KEY_LEN) { 6575 sme_warn("Invalid KRK keylength [= %d]", key_len); 6576 return -EINVAL; 6577 } 6578 6579 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 6580 sme_err("incorrect session/vdev ID"); 6581 return -EINVAL; 6582 } 6583 6584 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, session_id, 6585 WLAN_LEGACY_SME_ID); 6586 if (!vdev) { 6587 sme_err("vdev object is NULL for vdev %d", session_id); 6588 return QDF_STATUS_E_INVAL; 6589 } 6590 rso_cfg = wlan_cm_get_rso_config(vdev); 6591 if (!rso_cfg) { 6592 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6593 return QDF_STATUS_E_INVAL; 6594 } 6595 6596 qdf_mem_copy(rso_cfg->krk, key, WMI_KRK_KEY_LEN); 6597 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6598 6599 return 0; 6600 } 6601 #endif 6602 6603 #if defined(FEATURE_WLAN_ESE) && defined(WLAN_FEATURE_ROAM_OFFLOAD) sme_add_key_btk(mac_handle_t mac_handle,uint8_t session_id,const uint8_t * key,const int key_len)6604 int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id, 6605 const uint8_t *key, const int key_len) 6606 { 6607 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 6608 struct wlan_objmgr_vdev *vdev; 6609 struct rso_config *rso_cfg; 6610 6611 if (key_len < WMI_BTK_KEY_LEN) { 6612 sme_warn("Invalid BTK keylength [= %d]", key_len); 6613 return -EINVAL; 6614 } 6615 6616 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 6617 sme_err("incorrect session/vdev ID"); 6618 return -EINVAL; 6619 } 6620 6621 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, session_id, 6622 WLAN_LEGACY_SME_ID); 6623 if (!vdev) { 6624 sme_err("vdev object is NULL for vdev %d", session_id); 6625 return QDF_STATUS_E_INVAL; 6626 } 6627 rso_cfg = wlan_cm_get_rso_config(vdev); 6628 if (!rso_cfg) { 6629 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6630 return QDF_STATUS_E_INVAL; 6631 } 6632 6633 qdf_mem_copy(rso_cfg->btk, key, WMI_BTK_KEY_LEN); 6634 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 6635 /* 6636 * KRK and BTK are updated by upper layer back to back. Send 6637 * updated KRK and BTK together to FW here. 6638 */ 6639 wlan_roam_update_cfg(mac_ctx->psoc, session_id, 6640 REASON_ROAM_PSK_PMK_CHANGED); 6641 6642 return 0; 6643 } 6644 #endif 6645 sme_stop_roaming(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t reason,enum wlan_cm_rso_control_requestor requestor)6646 QDF_STATUS sme_stop_roaming(mac_handle_t mac_handle, uint8_t vdev_id, 6647 uint8_t reason, 6648 enum wlan_cm_rso_control_requestor requestor) 6649 { 6650 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6651 struct csr_roam_session *session; 6652 6653 session = CSR_GET_SESSION(mac, vdev_id); 6654 if (!session) { 6655 sme_err("ROAM: incorrect vdev ID %d", vdev_id); 6656 return QDF_STATUS_E_FAILURE; 6657 } 6658 6659 return wlan_cm_disable_rso(mac->pdev, vdev_id, requestor, reason); 6660 } 6661 sme_start_roaming(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t reason,enum wlan_cm_rso_control_requestor requestor)6662 QDF_STATUS sme_start_roaming(mac_handle_t mac_handle, uint8_t vdev_id, 6663 uint8_t reason, 6664 enum wlan_cm_rso_control_requestor requestor) 6665 { 6666 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6667 6668 return wlan_cm_enable_rso(mac->pdev, vdev_id, requestor, reason); 6669 } 6670 sme_roaming_in_progress(mac_handle_t mac_handle,uint8_t vdev_id)6671 bool sme_roaming_in_progress(mac_handle_t mac_handle, uint8_t vdev_id) 6672 { 6673 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6674 struct csr_roam_session *session; 6675 6676 session = CSR_GET_SESSION(mac, vdev_id); 6677 if (!session) { 6678 sme_err("ROAM: incorrect vdev ID %d", vdev_id); 6679 return false; 6680 } 6681 6682 return wlan_cm_roaming_in_progress(mac->pdev, vdev_id); 6683 } 6684 6685 /* 6686 * sme_set_roam_opportunistic_scan_threshold_diff() - 6687 * Update Opportunistic Scan threshold diff 6688 * This function is called through dynamic setConfig callback function 6689 * to configure nOpportunisticThresholdDiff 6690 * 6691 * mac_handle: Opaque handle to the global MAC context 6692 * sessionId - Session Identifier 6693 * nOpportunisticThresholdDiff - Opportunistic Scan threshold diff 6694 * Return QDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config 6695 * successfully. 6696 * else SME is failed to update nOpportunisticThresholdDiff. 6697 */ sme_set_roam_opportunistic_scan_threshold_diff(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nOpportunisticThresholdDiff)6698 QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff( 6699 mac_handle_t mac_handle, 6700 uint8_t sessionId, 6701 const uint8_t nOpportunisticThresholdDiff) 6702 { 6703 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6704 QDF_STATUS status = QDF_STATUS_SUCCESS; 6705 6706 status = sme_acquire_global_lock(&mac->sme); 6707 if (QDF_IS_STATUS_SUCCESS(status)) { 6708 status = cm_neighbor_roam_update_config(mac->pdev, sessionId, 6709 nOpportunisticThresholdDiff, 6710 REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED); 6711 if (QDF_IS_STATUS_SUCCESS(status)) { 6712 mac->mlme_cfg->lfr.opportunistic_scan_threshold_diff = 6713 nOpportunisticThresholdDiff; 6714 } 6715 sme_release_global_lock(&mac->sme); 6716 } 6717 return status; 6718 } 6719 6720 /* 6721 * sme_set_roam_rescan_rssi_diff() - Update roam rescan rssi diff 6722 * This function is called through dynamic setConfig callback function 6723 * to configure nRoamRescanRssiDiff 6724 * 6725 * mac_handle: Opaque handle to the global MAC context 6726 * sessionId - Session Identifier 6727 * nRoamRescanRssiDiff - roam rescan rssi diff 6728 * Return QDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config 6729 * successfully. 6730 * else SME is failed to update nRoamRescanRssiDiff. 6731 */ sme_set_roam_rescan_rssi_diff(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamRescanRssiDiff)6732 QDF_STATUS sme_set_roam_rescan_rssi_diff(mac_handle_t mac_handle, 6733 uint8_t sessionId, 6734 const uint8_t nRoamRescanRssiDiff) 6735 { 6736 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6737 QDF_STATUS status = QDF_STATUS_SUCCESS; 6738 6739 status = sme_acquire_global_lock(&mac->sme); 6740 if (QDF_IS_STATUS_SUCCESS(status)) { 6741 status = cm_neighbor_roam_update_config(mac->pdev, sessionId, 6742 nRoamRescanRssiDiff, 6743 REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED); 6744 if (QDF_IS_STATUS_SUCCESS(status)) 6745 mac->mlme_cfg->lfr.roam_rescan_rssi_diff = 6746 nRoamRescanRssiDiff; 6747 6748 sme_release_global_lock(&mac->sme); 6749 } 6750 return status; 6751 } 6752 6753 /* 6754 * sme_set_roam_bmiss_first_bcnt() - 6755 * Update Roam count for first beacon miss 6756 * This function is called through dynamic setConfig callback function 6757 * to configure nRoamBmissFirstBcnt 6758 * mac_handle: Opaque handle to the global MAC context 6759 * sessionId - Session Identifier 6760 * nRoamBmissFirstBcnt - Roam first bmiss count 6761 * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt 6762 * successfully. 6763 * else SME is failed to update nRoamBmissFirstBcnt 6764 */ sme_set_roam_bmiss_first_bcnt(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamBmissFirstBcnt)6765 QDF_STATUS sme_set_roam_bmiss_first_bcnt(mac_handle_t mac_handle, 6766 uint8_t sessionId, 6767 const uint8_t nRoamBmissFirstBcnt) 6768 { 6769 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6770 QDF_STATUS status = QDF_STATUS_SUCCESS; 6771 6772 status = sme_acquire_global_lock(&mac->sme); 6773 if (QDF_IS_STATUS_SUCCESS(status)) { 6774 status = cm_neighbor_roam_update_config(mac->pdev, sessionId, 6775 nRoamBmissFirstBcnt, 6776 REASON_ROAM_BMISS_FIRST_BCNT_CHANGED); 6777 if (QDF_IS_STATUS_SUCCESS(status)) { 6778 mac->mlme_cfg->lfr.roam_bmiss_first_bcnt = 6779 nRoamBmissFirstBcnt; 6780 } 6781 sme_release_global_lock(&mac->sme); 6782 } 6783 return status; 6784 } 6785 6786 /* 6787 * sme_set_roam_bmiss_final_bcnt() - 6788 * Update Roam count for final beacon miss 6789 * This function is called through dynamic setConfig callback function 6790 * to configure nRoamBmissFinalBcnt 6791 * mac_handle: Opaque handle to the global MAC context 6792 * sessionId - Session Identifier 6793 * nRoamBmissFinalBcnt - Roam final bmiss count 6794 * Return QDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt 6795 * successfully. 6796 * else SME is failed to update nRoamBmissFinalBcnt 6797 */ sme_set_roam_bmiss_final_bcnt(mac_handle_t mac_handle,uint8_t sessionId,const uint8_t nRoamBmissFinalBcnt)6798 QDF_STATUS sme_set_roam_bmiss_final_bcnt(mac_handle_t mac_handle, 6799 uint8_t sessionId, 6800 const uint8_t nRoamBmissFinalBcnt) 6801 { 6802 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6803 QDF_STATUS status = QDF_STATUS_SUCCESS; 6804 6805 status = sme_acquire_global_lock(&mac->sme); 6806 if (QDF_IS_STATUS_SUCCESS(status)) { 6807 status = cm_neighbor_roam_update_config(mac->pdev, sessionId, 6808 nRoamBmissFinalBcnt, 6809 REASON_ROAM_BMISS_FINAL_BCNT_CHANGED); 6810 if (QDF_IS_STATUS_SUCCESS(status)) { 6811 mac->mlme_cfg->lfr.roam_bmiss_final_bcnt = 6812 nRoamBmissFinalBcnt; 6813 } 6814 sme_release_global_lock(&mac->sme); 6815 } 6816 return status; 6817 } 6818 6819 QDF_STATUS sme_set_neighbor_lookup_rssi_threshold(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t neighbor_lookup_rssi_threshold)6820 sme_set_neighbor_lookup_rssi_threshold(mac_handle_t mac_handle, 6821 uint8_t vdev_id, 6822 uint8_t neighbor_lookup_rssi_threshold) 6823 { 6824 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6825 QDF_STATUS status; 6826 6827 if (vdev_id >= WLAN_MAX_VDEVS) { 6828 sme_err("Invalid vdev_id: %u", vdev_id); 6829 return QDF_STATUS_E_INVAL; 6830 } 6831 6832 status = sme_acquire_global_lock(&mac->sme); 6833 if (QDF_IS_STATUS_ERROR(status)) 6834 return status; 6835 cm_neighbor_roam_update_config(mac->pdev, vdev_id, 6836 neighbor_lookup_rssi_threshold, 6837 REASON_LOOKUP_THRESH_CHANGED); 6838 sme_release_global_lock(&mac->sme); 6839 return status; 6840 } 6841 6842 /* 6843 * sme_set_neighbor_scan_refresh_period() - set neighbor scan results 6844 * refresh period 6845 * This is a synchronous call 6846 * 6847 * mac_handle - The handle returned by mac_open. 6848 * sessionId - Session Identifier 6849 * Return QDF_STATUS_SUCCESS - SME update config successful. 6850 * Other status means SME is failed to update 6851 */ sme_set_neighbor_scan_refresh_period(mac_handle_t mac_handle,uint8_t sessionId,uint16_t neighborScanResultsRefreshPeriod)6852 QDF_STATUS sme_set_neighbor_scan_refresh_period(mac_handle_t mac_handle, 6853 uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod) 6854 { 6855 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6856 struct cm_roam_values_copy src_config = {}; 6857 6858 src_config.uint_value = neighborScanResultsRefreshPeriod; 6859 return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId, 6860 NEIGHBOUR_SCAN_REFRESH_PERIOD, 6861 &src_config); 6862 } 6863 6864 /* 6865 * sme_update_empty_scan_refresh_period 6866 * Update empty_scan_refresh_period 6867 * This function is called through dynamic setConfig callback function 6868 * to configure empty_scan_refresh_period 6869 * Usage: adb shell iwpriv wlan0 setConfig 6870 * empty_scan_refresh_period=[0 .. 60] 6871 * 6872 * mac_handle: Opaque handle to the global MAC context 6873 * sessionId - Session Identifier 6874 * empty_scan_refresh_period - scan period following empty scan results. 6875 * Return Success or failure 6876 */ 6877 sme_update_empty_scan_refresh_period(mac_handle_t mac_handle,uint8_t sessionId,uint16_t empty_scan_refresh_period)6878 QDF_STATUS sme_update_empty_scan_refresh_period(mac_handle_t mac_handle, 6879 uint8_t sessionId, uint16_t 6880 empty_scan_refresh_period) 6881 { 6882 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6883 struct cm_roam_values_copy src_config = {}; 6884 6885 src_config.uint_value = empty_scan_refresh_period; 6886 return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId, 6887 EMPTY_SCAN_REFRESH_PERIOD, 6888 &src_config); 6889 } 6890 sme_update_full_roam_scan_period(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t full_roam_scan_period)6891 QDF_STATUS sme_update_full_roam_scan_period(mac_handle_t mac_handle, 6892 uint8_t vdev_id, 6893 uint32_t full_roam_scan_period) 6894 { 6895 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6896 struct cm_roam_values_copy src_config = {}; 6897 6898 src_config.uint_value = full_roam_scan_period; 6899 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 6900 FULL_ROAM_SCAN_PERIOD, &src_config); 6901 } 6902 6903 QDF_STATUS sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle,uint8_t vdev_id,bool enable_scoring_for_roam)6904 sme_modify_roam_cand_sel_criteria(mac_handle_t mac_handle, 6905 uint8_t vdev_id, 6906 bool enable_scoring_for_roam) 6907 { 6908 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6909 struct cm_roam_values_copy src_config = {}; 6910 6911 src_config.bool_value = enable_scoring_for_roam; 6912 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 6913 ENABLE_SCORING_FOR_ROAM, &src_config); 6914 } 6915 sme_roam_control_restore_default_config(mac_handle_t mac_handle,uint8_t vdev_id)6916 QDF_STATUS sme_roam_control_restore_default_config(mac_handle_t mac_handle, 6917 uint8_t vdev_id) 6918 { 6919 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6920 6921 if (vdev_id >= WLAN_MAX_VDEVS) { 6922 sme_err("Invalid vdev_id: %d", vdev_id); 6923 return QDF_STATUS_E_INVAL; 6924 } 6925 6926 return cm_roam_control_restore_default_config(mac->pdev, vdev_id); 6927 } 6928 6929 /* 6930 * sme_set_neighbor_scan_min_chan_time() - 6931 * Update nNeighborScanMinChanTime 6932 * This function is called through dynamic setConfig callback function 6933 * to configure gNeighborScanChannelMinTime 6934 * Usage: adb shell iwpriv wlan0 setConfig 6935 * gNeighborScanChannelMinTime=[0 .. 60] 6936 * 6937 * mac_handle: Opaque handle to the global MAC context 6938 * nNeighborScanMinChanTime - Channel minimum dwell time 6939 * sessionId - Session Identifier 6940 * Return Success or failure 6941 */ sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle,const uint16_t nNeighborScanMinChanTime,uint8_t sessionId)6942 QDF_STATUS sme_set_neighbor_scan_min_chan_time(mac_handle_t mac_handle, 6943 const uint16_t 6944 nNeighborScanMinChanTime, 6945 uint8_t sessionId) 6946 { 6947 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6948 struct cm_roam_values_copy src_config = {}; 6949 6950 src_config.uint_value = nNeighborScanMinChanTime; 6951 return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId, 6952 SCAN_MIN_CHAN_TIME, &src_config); 6953 } 6954 6955 /* 6956 * sme_set_neighbor_scan_max_chan_time() - 6957 * Update nNeighborScanMaxChanTime 6958 * This function is called through dynamic setConfig callback function 6959 * to configure gNeighborScanChannelMaxTime 6960 * Usage: adb shell iwpriv wlan0 setConfig 6961 * gNeighborScanChannelMaxTime=[0 .. 60] 6962 * 6963 * mac_handle: Opaque handle to the global MAC context 6964 * sessionId - Session Identifier 6965 * nNeighborScanMinChanTime - Channel maximum dwell time 6966 * Return Success or failure 6967 */ sme_set_neighbor_scan_max_chan_time(mac_handle_t mac_handle,uint8_t sessionId,const uint16_t nNeighborScanMaxChanTime)6968 QDF_STATUS sme_set_neighbor_scan_max_chan_time(mac_handle_t mac_handle, 6969 uint8_t sessionId, 6970 const uint16_t 6971 nNeighborScanMaxChanTime) 6972 { 6973 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6974 struct cm_roam_values_copy src_config = {}; 6975 6976 src_config.uint_value = nNeighborScanMaxChanTime; 6977 return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId, 6978 SCAN_MAX_CHAN_TIME, &src_config); 6979 } 6980 6981 /* 6982 * sme_get_current_roam_state() - 6983 * get current roam state 6984 * 6985 * mac_handle - The handle returned by mac_open. 6986 * sessionId - Session Identifier 6987 * Return uint32_t - current roam state 6988 */ sme_get_current_roam_state(mac_handle_t mac_handle,uint8_t sessionId)6989 uint32_t sme_get_current_roam_state(mac_handle_t mac_handle, uint8_t sessionId) 6990 { 6991 struct mac_context *mac = MAC_CONTEXT(mac_handle); 6992 6993 return mac->roam.curState[sessionId]; 6994 } 6995 6996 /* 6997 * sme_get_current_roam_sub_state() - 6998 * \brief get neighbor roam sub state 6999 * 7000 * mac_handle - The handle returned by mac_open. 7001 * sessionId - Session Identifier 7002 * Return uint32_t - current roam sub state 7003 */ sme_get_current_roam_sub_state(mac_handle_t mac_handle,uint8_t sessionId)7004 uint32_t sme_get_current_roam_sub_state(mac_handle_t mac_handle, 7005 uint8_t sessionId) 7006 { 7007 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7008 7009 return mac->roam.curSubState[sessionId]; 7010 } 7011 7012 /* 7013 * sme_get_lim_sme_state() - 7014 * get Lim Sme state 7015 * 7016 * mac_handle - The handle returned by mac_open. 7017 * Return uint32_t - Lim Sme state 7018 */ sme_get_lim_sme_state(mac_handle_t mac_handle)7019 uint32_t sme_get_lim_sme_state(mac_handle_t mac_handle) 7020 { 7021 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7022 7023 return mac->lim.gLimSmeState; 7024 } 7025 7026 /* 7027 * sme_get_lim_mlm_state() - 7028 * get Lim Mlm state 7029 * 7030 * mac_handle - The handle returned by mac_open. 7031 * Return uint32_t - Lim Mlm state 7032 */ sme_get_lim_mlm_state(mac_handle_t mac_handle)7033 uint32_t sme_get_lim_mlm_state(mac_handle_t mac_handle) 7034 { 7035 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7036 7037 return mac->lim.gLimMlmState; 7038 } 7039 7040 /* 7041 * sme_is_lim_session_valid() - 7042 * is Lim session valid 7043 * 7044 * mac_handle - The handle returned by mac_open. 7045 * sessionId - Session Identifier 7046 * Return bool - true or false 7047 */ sme_is_lim_session_valid(mac_handle_t mac_handle,uint8_t sessionId)7048 bool sme_is_lim_session_valid(mac_handle_t mac_handle, uint8_t sessionId) 7049 { 7050 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7051 7052 if (sessionId > mac->lim.maxBssId) 7053 return false; 7054 7055 return mac->lim.gpSession[sessionId].valid; 7056 } 7057 7058 /* 7059 * sme_get_lim_sme_session_state() - 7060 * get Lim Sme session state 7061 * 7062 * mac_handle - The handle returned by mac_open. 7063 * sessionId - Session Identifier 7064 * Return uint32_t - Lim Sme session state 7065 */ sme_get_lim_sme_session_state(mac_handle_t mac_handle,uint8_t sessionId)7066 uint32_t sme_get_lim_sme_session_state(mac_handle_t mac_handle, 7067 uint8_t sessionId) 7068 { 7069 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7070 7071 return mac->lim.gpSession[sessionId].limSmeState; 7072 } 7073 7074 /* 7075 * sme_get_lim_mlm_session_state() - 7076 * \brief get Lim Mlm session state 7077 * 7078 * mac_handle - The handle returned by mac_open. 7079 * sessionId - Session Identifier 7080 * Return uint32_t - Lim Mlm session state 7081 */ sme_get_lim_mlm_session_state(mac_handle_t mac_handle,uint8_t sessionId)7082 uint32_t sme_get_lim_mlm_session_state(mac_handle_t mac_handle, 7083 uint8_t sessionId) 7084 { 7085 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7086 7087 return mac->lim.gpSession[sessionId].limMlmState; 7088 } 7089 7090 /* 7091 * sme_set_neighbor_scan_period() - 7092 * Update nNeighborScanPeriod 7093 * This function is called through dynamic setConfig callback function 7094 * to configure nNeighborScanPeriod 7095 * Usage: adb shell iwpriv wlan0 setConfig 7096 * nNeighborScanPeriod=[0 .. 1000] 7097 * 7098 * mac_handle: Opaque handle to the global MAC context 7099 * sessionId - Session Identifier 7100 * nNeighborScanPeriod - neighbor scan period 7101 * Return Success or failure 7102 */ sme_set_neighbor_scan_period(mac_handle_t mac_handle,uint8_t sessionId,const uint16_t nNeighborScanPeriod)7103 QDF_STATUS sme_set_neighbor_scan_period(mac_handle_t mac_handle, 7104 uint8_t sessionId, 7105 const uint16_t nNeighborScanPeriod) 7106 { 7107 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7108 struct cm_roam_values_copy src_config = {}; 7109 7110 src_config.uint_value = nNeighborScanPeriod; 7111 return wlan_cm_roam_cfg_set_value(mac->psoc, sessionId, 7112 NEIGHBOR_SCAN_PERIOD, 7113 &src_config); 7114 } 7115 sme_validate_freq_list(mac_handle_t mac_handle,uint32_t * freq_list,uint8_t num_channels)7116 static bool sme_validate_freq_list(mac_handle_t mac_handle, 7117 uint32_t *freq_list, 7118 uint8_t num_channels) 7119 { 7120 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 7121 uint8_t i = 0, j; 7122 bool found; 7123 struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels; 7124 7125 if (!freq_list || !num_channels) { 7126 sme_err("Freq list empty %pK or num_channels is 0", freq_list); 7127 return false; 7128 } 7129 7130 while (i < num_channels) { 7131 found = false; 7132 for (j = 0; j < ch_lst_info->numChannels; j++) { 7133 if (ch_lst_info->channel_freq_list[j] == freq_list[i]) { 7134 found = true; 7135 break; 7136 } 7137 } 7138 7139 if (!found) { 7140 sme_debug("Invalid frequency %u", freq_list[i]); 7141 return false; 7142 } 7143 7144 i++; 7145 } 7146 7147 return true; 7148 } 7149 7150 QDF_STATUS sme_update_roam_scan_freq_list(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t * freq_list,uint8_t num_chan,uint32_t freq_list_type)7151 sme_update_roam_scan_freq_list(mac_handle_t mac_handle, uint8_t vdev_id, 7152 uint32_t *freq_list, uint8_t num_chan, 7153 uint32_t freq_list_type) 7154 { 7155 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7156 struct cm_roam_values_copy src_config = {}; 7157 7158 if (!sme_validate_freq_list(mac_handle, freq_list, num_chan)) { 7159 sme_err("List contains invalid channel(s)"); 7160 return QDF_STATUS_E_INVAL; 7161 } 7162 7163 /* 7164 * NCHO Frequency configurations: 7165 * If ADDROAMSCANFREQUENCIES command is given, then freq_list_type is 7166 * QCA_PREFERRED_SCAN_FREQ_LIST. 7167 * If SETROAMSCANFREQUENCIES command is given, then freq_list_type is 7168 * QCA_SPECIFIC_SCAN_FREQ_LIST. 7169 * 7170 * If new channels are configured with type as STATIC(specific freq 7171 * list): 7172 * - FW clears both static & dynamic list. 7173 * - FW adds new channels to static & dynamic lists(both list contains 7174 * only new channels) 7175 * 7176 * If Host configures new channels with type as DYNAMIC(preferred freq 7177 * list): 7178 * - FW clears the static list and adds new channels(Static list 7179 * contains only new channels) 7180 * - FW will not clear dynamic list. New channels will be 7181 * appended(Dynamic list contains old+new channels) 7182 */ 7183 7184 src_config.chan_info.freq_list = freq_list; 7185 src_config.chan_info.num_chan = num_chan; 7186 if (freq_list_type == QCA_PREFERRED_SCAN_FREQ_LIST) 7187 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 7188 ROAM_PREFERRED_CHAN, 7189 &src_config); 7190 else 7191 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 7192 ROAM_SPECIFIC_CHAN, 7193 &src_config); 7194 } 7195 7196 /** 7197 * sme_get_roam_scan_channel_list() - To get roam scan channel list 7198 * @mac_handle: Opaque handle to the global MAC context 7199 * @freq_list: Output channel freq list 7200 * @pNumChannels: Output number of channels 7201 * @sessionId: Session Identifier 7202 * 7203 * To get roam scan channel list This is a synchronous call 7204 * 7205 * Return: QDF_STATUS 7206 */ sme_get_roam_scan_channel_list(mac_handle_t mac_handle,uint32_t * freq_list,uint8_t * pNumChannels,uint8_t sessionId)7207 QDF_STATUS sme_get_roam_scan_channel_list(mac_handle_t mac_handle, 7208 uint32_t *freq_list, uint8_t *pNumChannels, 7209 uint8_t sessionId) 7210 { 7211 int i = 0, chan_cnt = 0; 7212 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7213 QDF_STATUS status = QDF_STATUS_SUCCESS; 7214 struct rso_chan_info *chan_info; 7215 struct wlan_objmgr_vdev *vdev; 7216 struct rso_config *rso_cfg; 7217 struct rso_cfg_params *cfg_params; 7218 7219 if (sessionId >= WLAN_MAX_VDEVS) { 7220 sme_err("Invalid sme vdev %d", sessionId); 7221 return QDF_STATUS_E_INVAL; 7222 } 7223 7224 status = sme_acquire_global_lock(&mac->sme); 7225 if (!QDF_IS_STATUS_SUCCESS(status)) 7226 return status; 7227 7228 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac->pdev, sessionId, 7229 WLAN_LEGACY_SME_ID); 7230 if (!vdev) { 7231 sme_err("vdev object is NULL for vdev %d", sessionId); 7232 sme_release_global_lock(&mac->sme); 7233 return QDF_STATUS_E_INVAL; 7234 } 7235 rso_cfg = wlan_cm_get_rso_config(vdev); 7236 if (!rso_cfg) { 7237 sme_release_global_lock(&mac->sme); 7238 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7239 return QDF_STATUS_E_INVAL; 7240 } 7241 cfg_params = &rso_cfg->cfg_param; 7242 chan_info = &cfg_params->specific_chan_info; 7243 if (chan_info->num_chan) { 7244 *pNumChannels = chan_info->num_chan; 7245 for (i = 0; i < (*pNumChannels) && 7246 i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) 7247 freq_list[i] = chan_info->freq_list[i]; 7248 7249 *pNumChannels = i; 7250 } else { 7251 chan_info = &cfg_params->pref_chan_info; 7252 *pNumChannels = chan_info->num_chan; 7253 if (chan_info->num_chan) { 7254 for (chan_cnt = 0; chan_cnt < (*pNumChannels) && 7255 chan_cnt < WNI_CFG_VALID_CHANNEL_LIST_LEN; 7256 chan_cnt++) 7257 freq_list[chan_cnt] = 7258 chan_info->freq_list[chan_cnt]; 7259 } 7260 7261 if (rso_cfg->occupied_chan_lst.num_chan) { 7262 for (i = 0; i < rso_cfg->occupied_chan_lst.num_chan && 7263 chan_cnt < CFG_VALID_CHANNEL_LIST_LEN; i++) 7264 freq_list[chan_cnt++] = 7265 rso_cfg->occupied_chan_lst.freq_list[i]; 7266 } 7267 7268 *pNumChannels = chan_cnt; 7269 if (!(chan_info->num_chan || 7270 rso_cfg->occupied_chan_lst.num_chan)) { 7271 sme_info("Roam Scan channel list is NOT yet initialized"); 7272 *pNumChannels = 0; 7273 status = QDF_STATUS_E_INVAL; 7274 } 7275 } 7276 7277 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7278 sme_release_global_lock(&mac->sme); 7279 return status; 7280 } 7281 7282 /** 7283 * sme_is_feature_supported_by_fw() - check if feature is supported by FW 7284 * @feature: enum value of requested feature. 7285 * 7286 * Return: 1 if supported; 0 otherwise 7287 */ sme_is_feature_supported_by_fw(enum cap_bitmap feature)7288 bool sme_is_feature_supported_by_fw(enum cap_bitmap feature) 7289 { 7290 return IS_FEATURE_SUPPORTED_BY_FW(feature); 7291 } 7292 sme_get_link_speed(mac_handle_t mac_handle,struct link_speed_info * req,void * context,sme_link_speed_cb cb)7293 QDF_STATUS sme_get_link_speed(mac_handle_t mac_handle, 7294 struct link_speed_info *req, 7295 void *context, 7296 sme_link_speed_cb cb) 7297 { 7298 QDF_STATUS status; 7299 struct mac_context *mac; 7300 void *wma_handle; 7301 7302 if (!mac_handle || !cb || !req) { 7303 sme_err("Invalid parameter"); 7304 return QDF_STATUS_E_FAILURE; 7305 } 7306 7307 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 7308 if (!wma_handle) 7309 return QDF_STATUS_E_FAILURE; 7310 7311 mac = MAC_CONTEXT(mac_handle); 7312 status = sme_acquire_global_lock(&mac->sme); 7313 if (QDF_STATUS_SUCCESS != status) { 7314 sme_err("Failed to acquire global lock"); 7315 return QDF_STATUS_E_FAILURE; 7316 } 7317 7318 mac->sme.link_speed_context = context; 7319 mac->sme.link_speed_cb = cb; 7320 status = wma_get_link_speed(wma_handle, req); 7321 sme_release_global_lock(&mac->sme); 7322 return status; 7323 } 7324 sme_get_isolation(mac_handle_t mac_handle,void * context,sme_get_isolation_cb callbackfn)7325 QDF_STATUS sme_get_isolation(mac_handle_t mac_handle, void *context, 7326 sme_get_isolation_cb callbackfn) 7327 { 7328 QDF_STATUS status; 7329 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7330 struct scheduler_msg message = {0}; 7331 7332 if (!callbackfn) { 7333 sme_err("Indication Call back is NULL"); 7334 return QDF_STATUS_E_FAILURE; 7335 } 7336 status = sme_acquire_global_lock(&mac->sme); 7337 if (QDF_IS_STATUS_ERROR(status)) 7338 return status; 7339 mac->sme.get_isolation_cb = callbackfn; 7340 mac->sme.get_isolation_cb_context = context; 7341 message.bodyptr = NULL; 7342 message.type = WMA_GET_ISOLATION; 7343 status = scheduler_post_message(QDF_MODULE_ID_SME, 7344 QDF_MODULE_ID_WMA, 7345 QDF_MODULE_ID_WMA, 7346 &message); 7347 if (!QDF_IS_STATUS_SUCCESS(status)) { 7348 sme_err("failed to post WMA_GET_ISOLATION"); 7349 status = QDF_STATUS_E_FAILURE; 7350 } 7351 sme_release_global_lock(&mac->sme); 7352 return status; 7353 } 7354 7355 /*convert the ini value to the ENUM used in csr and MAC for CB state*/ sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value)7356 ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value) 7357 { 7358 return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value); 7359 } 7360 7361 /** 7362 * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern 7363 * @mac_handle: Opaque handle to the global MAC context 7364 * @addPeriodicTxPtrnParams: request message 7365 * 7366 * Return: QDF_STATUS enumeration 7367 */ 7368 QDF_STATUS sme_add_periodic_tx_ptrn(mac_handle_t mac_handle,struct sSirAddPeriodicTxPtrn * addPeriodicTxPtrnParams)7369 sme_add_periodic_tx_ptrn(mac_handle_t mac_handle, 7370 struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams) 7371 { 7372 QDF_STATUS status = QDF_STATUS_SUCCESS; 7373 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7374 struct sSirAddPeriodicTxPtrn *req_msg; 7375 struct scheduler_msg msg = {0}; 7376 7377 SME_ENTER(); 7378 7379 req_msg = qdf_mem_malloc(sizeof(*req_msg)); 7380 if (!req_msg) 7381 return QDF_STATUS_E_NOMEM; 7382 7383 *req_msg = *addPeriodicTxPtrnParams; 7384 7385 status = sme_acquire_global_lock(&mac->sme); 7386 if (!QDF_IS_STATUS_SUCCESS(status)) { 7387 sme_err("sme_acquire_global_lock failed!(status=%d)", 7388 status); 7389 qdf_mem_free(req_msg); 7390 return status; 7391 } 7392 7393 /* Serialize the req through MC thread */ 7394 msg.bodyptr = req_msg; 7395 msg.type = WMA_ADD_PERIODIC_TX_PTRN_IND; 7396 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 7397 NO_SESSION, msg.type)); 7398 status = scheduler_post_message(QDF_MODULE_ID_SME, 7399 QDF_MODULE_ID_WMA, 7400 QDF_MODULE_ID_WMA, &msg); 7401 if (!QDF_IS_STATUS_SUCCESS(status)) { 7402 sme_err("scheduler_post_msg failed!(err=%d)", 7403 status); 7404 qdf_mem_free(req_msg); 7405 } 7406 sme_release_global_lock(&mac->sme); 7407 return status; 7408 } 7409 7410 /** 7411 * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern 7412 * @mac_handle: Opaque handle to the global MAC context 7413 * @delPeriodicTxPtrnParams: request message 7414 * 7415 * Return: QDF_STATUS enumeration 7416 */ 7417 QDF_STATUS sme_del_periodic_tx_ptrn(mac_handle_t mac_handle,struct sSirDelPeriodicTxPtrn * delPeriodicTxPtrnParams)7418 sme_del_periodic_tx_ptrn(mac_handle_t mac_handle, 7419 struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams) 7420 { 7421 QDF_STATUS status = QDF_STATUS_SUCCESS; 7422 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7423 struct sSirDelPeriodicTxPtrn *req_msg; 7424 struct scheduler_msg msg = {0}; 7425 7426 SME_ENTER(); 7427 7428 req_msg = qdf_mem_malloc(sizeof(*req_msg)); 7429 if (!req_msg) 7430 return QDF_STATUS_E_NOMEM; 7431 7432 *req_msg = *delPeriodicTxPtrnParams; 7433 7434 status = sme_acquire_global_lock(&mac->sme); 7435 if (!QDF_IS_STATUS_SUCCESS(status)) { 7436 sme_err("sme_acquire_global_lock failed!(status=%d)", 7437 status); 7438 qdf_mem_free(req_msg); 7439 return status; 7440 } 7441 7442 /* Serialize the req through MC thread */ 7443 msg.bodyptr = req_msg; 7444 msg.type = WMA_DEL_PERIODIC_TX_PTRN_IND; 7445 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 7446 NO_SESSION, msg.type)); 7447 status = scheduler_post_message(QDF_MODULE_ID_SME, 7448 QDF_MODULE_ID_WMA, 7449 QDF_MODULE_ID_WMA, &msg); 7450 if (!QDF_IS_STATUS_SUCCESS(status)) { 7451 sme_err("scheduler_post_msg failed!(err=%d)", 7452 status); 7453 qdf_mem_free(req_msg); 7454 } 7455 sme_release_global_lock(&mac->sme); 7456 return status; 7457 } 7458 7459 #ifdef MULTI_CLIENT_LL_SUPPORT sme_multi_client_ll_rsp_register_callback(mac_handle_t mac_handle,void (* latency_level_event_handler_cb)(const struct latency_level_data * event_data,uint8_t vdev_id))7460 QDF_STATUS sme_multi_client_ll_rsp_register_callback(mac_handle_t mac_handle, 7461 void (*latency_level_event_handler_cb) 7462 (const struct latency_level_data *event_data, 7463 uint8_t vdev_id)) 7464 { 7465 QDF_STATUS status = QDF_STATUS_SUCCESS; 7466 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7467 7468 status = sme_acquire_global_lock(&mac->sme); 7469 if (QDF_IS_STATUS_SUCCESS(status)) { 7470 mac->sme.latency_level_event_handler_cb = 7471 latency_level_event_handler_cb; 7472 sme_release_global_lock(&mac->sme); 7473 } 7474 7475 return status; 7476 } 7477 sme_multi_client_ll_rsp_deregister_callback(mac_handle_t mac_handle)7478 void sme_multi_client_ll_rsp_deregister_callback(mac_handle_t mac_handle) 7479 { 7480 sme_multi_client_ll_rsp_register_callback(mac_handle, NULL); 7481 } 7482 7483 /** 7484 * sme_fill_multi_client_info() - Fill multi client info 7485 * @param:latency leevel param 7486 * @client_id_bitmap: bitmap for host clients 7487 * @force_reset: force reset bit to clear latency level for all clients 7488 * 7489 * Return: none 7490 */ 7491 static void sme_fill_multi_client_info(struct wlm_latency_level_param * params,uint32_t client_id_bitmap,bool force_reset)7492 sme_fill_multi_client_info(struct wlm_latency_level_param *params, 7493 uint32_t client_id_bitmap, bool force_reset) 7494 { 7495 params->client_id_bitmask = client_id_bitmap; 7496 params->force_reset = force_reset; 7497 } 7498 #else 7499 static inline void sme_fill_multi_client_info(struct wlm_latency_level_param * params,uint32_t client_id_bitmap,bool force_reset)7500 sme_fill_multi_client_info(struct wlm_latency_level_param *params, 7501 uint32_t client_id_bitmap, bool force_reset) 7502 { 7503 } 7504 #endif 7505 sme_set_wlm_latency_level(mac_handle_t mac_handle,uint16_t session_id,uint16_t latency_level,uint32_t client_id_bitmap,bool force_reset)7506 QDF_STATUS sme_set_wlm_latency_level(mac_handle_t mac_handle, 7507 uint16_t session_id, uint16_t latency_level, 7508 uint32_t client_id_bitmap, 7509 bool force_reset) 7510 { 7511 QDF_STATUS status; 7512 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 7513 struct wlm_latency_level_param params; 7514 void *wma = cds_get_context(QDF_MODULE_ID_WMA); 7515 7516 SME_ENTER(); 7517 7518 if (!wma) 7519 return QDF_STATUS_E_FAILURE; 7520 7521 if (!mac_ctx->mlme_cfg->wlm_config.latency_enable) { 7522 sme_err("WLM latency level setting is disabled"); 7523 return QDF_STATUS_E_FAILURE; 7524 } 7525 if (!wma) { 7526 sme_err("wma is NULL"); 7527 return QDF_STATUS_E_FAILURE; 7528 } 7529 7530 if (session_id == WLAN_INVALID_LINK_ID) { 7531 sme_err("Invalid vdev_id[%u]", session_id); 7532 return QDF_STATUS_E_FAILURE; 7533 } 7534 7535 params.wlm_latency_level = latency_level; 7536 params.wlm_latency_flags = 7537 mac_ctx->mlme_cfg->wlm_config.latency_flags[latency_level]; 7538 params.vdev_id = session_id; 7539 sme_fill_multi_client_info(¶ms, client_id_bitmap, force_reset); 7540 7541 status = wma_set_wlm_latency_level(wma, ¶ms); 7542 7543 return status; 7544 } 7545 sme_get_command_q_status(mac_handle_t mac_handle)7546 void sme_get_command_q_status(mac_handle_t mac_handle) 7547 { 7548 tSmeCmd *pTempCmd = NULL; 7549 struct mac_context *mac; 7550 struct wlan_serialization_command *cmd; 7551 7552 if (!mac_handle) 7553 return; 7554 7555 mac = MAC_CONTEXT(mac_handle); 7556 7557 sme_debug("smeCmdPendingList has %d commands", 7558 wlan_serialization_get_pending_list_count(mac->psoc, false)); 7559 cmd = wlan_serialization_peek_head_active_cmd_using_psoc(mac->psoc, 7560 false); 7561 if (cmd) 7562 sme_debug("Active commaned is %d cmd id %d source %d", 7563 cmd->cmd_type, cmd->cmd_id, cmd->source); 7564 if (!cmd || cmd->source != WLAN_UMAC_COMP_MLME) 7565 return; 7566 7567 pTempCmd = cmd->umac_cmd; 7568 if (pTempCmd) { 7569 if (eSmeCsrCommandMask & pTempCmd->command) 7570 /* CSR command is stuck. See what the reason code is 7571 * for that command 7572 */ 7573 dump_csr_command_info(mac, pTempCmd); 7574 } 7575 } 7576 7577 #ifdef WLAN_FEATURE_DSRC 7578 /** 7579 * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer 7580 * @mac_handle: Opaque handle to the global MAC context 7581 * @self_addr: the self MAC address 7582 * @buf: the buffer that will contain the frame 7583 * @timestamp_offset: return for the offset of the timestamp field 7584 * @time_value_offset: return for the time_value field in the TA IE 7585 * 7586 * Return: the length of the buffer on success and error code on failure. 7587 */ sme_ocb_gen_timing_advert_frame(mac_handle_t mac_handle,tSirMacAddr self_addr,uint8_t ** buf,uint32_t * timestamp_offset,uint32_t * time_value_offset)7588 int sme_ocb_gen_timing_advert_frame(mac_handle_t mac_handle, 7589 tSirMacAddr self_addr, uint8_t **buf, 7590 uint32_t *timestamp_offset, 7591 uint32_t *time_value_offset) 7592 { 7593 int template_length; 7594 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 7595 7596 template_length = sch_gen_timing_advert_frame(mac_ctx, self_addr, buf, 7597 timestamp_offset, 7598 time_value_offset); 7599 return template_length; 7600 } 7601 #endif 7602 sme_notify_modem_power_state(mac_handle_t mac_handle,uint32_t value)7603 QDF_STATUS sme_notify_modem_power_state(mac_handle_t mac_handle, uint32_t value) 7604 { 7605 struct scheduler_msg msg = {0}; 7606 tpSirModemPowerStateInd request_buf; 7607 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7608 7609 if (!mac) 7610 return QDF_STATUS_E_FAILURE; 7611 7612 request_buf = qdf_mem_malloc(sizeof(tSirModemPowerStateInd)); 7613 if (!request_buf) 7614 return QDF_STATUS_E_NOMEM; 7615 7616 request_buf->param = value; 7617 7618 msg.type = WMA_MODEM_POWER_STATE_IND; 7619 msg.reserved = 0; 7620 msg.bodyptr = request_buf; 7621 if (!QDF_IS_STATUS_SUCCESS 7622 (scheduler_post_message(QDF_MODULE_ID_SME, 7623 QDF_MODULE_ID_WMA, 7624 QDF_MODULE_ID_WMA, &msg))) { 7625 sme_err("Not able to post WMA_MODEM_POWER_STATE_IND message to WMA"); 7626 qdf_mem_free(request_buf); 7627 return QDF_STATUS_E_FAILURE; 7628 } 7629 7630 return QDF_STATUS_SUCCESS; 7631 } 7632 7633 #ifdef QCA_HT_2040_COEX sme_notify_ht2040_mode(mac_handle_t mac_handle,struct qdf_mac_addr macAddrSTA,uint8_t sessionId,uint8_t channel_type)7634 QDF_STATUS sme_notify_ht2040_mode(mac_handle_t mac_handle, 7635 struct qdf_mac_addr macAddrSTA, 7636 uint8_t sessionId, 7637 uint8_t channel_type) 7638 { 7639 struct scheduler_msg msg = {0}; 7640 tUpdateVHTOpMode *pHtOpMode = NULL; 7641 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7642 7643 if (!mac) 7644 return QDF_STATUS_E_FAILURE; 7645 7646 pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode)); 7647 if (!pHtOpMode) 7648 return QDF_STATUS_E_NOMEM; 7649 7650 switch (channel_type) { 7651 case eHT_CHAN_HT20: 7652 pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ; 7653 break; 7654 7655 case eHT_CHAN_HT40MINUS: 7656 case eHT_CHAN_HT40PLUS: 7657 pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ; 7658 break; 7659 7660 default: 7661 sme_err("Invalid OP mode %d", channel_type); 7662 qdf_mem_free(pHtOpMode); 7663 return QDF_STATUS_E_FAILURE; 7664 } 7665 7666 qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes, 7667 sizeof(tSirMacAddr)); 7668 pHtOpMode->smesessionId = sessionId; 7669 7670 msg.type = WMA_UPDATE_OP_MODE; 7671 msg.reserved = 0; 7672 msg.bodyptr = pHtOpMode; 7673 if (QDF_IS_STATUS_ERROR 7674 (scheduler_post_message(QDF_MODULE_ID_SME, 7675 QDF_MODULE_ID_WMA, 7676 QDF_MODULE_ID_WMA, &msg))) { 7677 sme_err("Not able to post WMA_UPDATE_OP_MODE message to WMA"); 7678 qdf_mem_free(pHtOpMode); 7679 return QDF_STATUS_E_FAILURE; 7680 } 7681 7682 sme_debug("vdev %d OP mode: %d", sessionId, pHtOpMode->opMode); 7683 7684 return QDF_STATUS_SUCCESS; 7685 } 7686 7687 /* 7688 * sme_set_ht2040_mode() - 7689 * To update HT Operation beacon IE. 7690 * 7691 * Return QDF_STATUS SUCCESS 7692 * FAILURE or RESOURCES 7693 * The API finished and failed. 7694 */ sme_set_ht2040_mode(mac_handle_t mac_handle,uint8_t sessionId,uint8_t channel_type,bool obssEnabled)7695 QDF_STATUS sme_set_ht2040_mode(mac_handle_t mac_handle, uint8_t sessionId, 7696 uint8_t channel_type, bool obssEnabled) 7697 { 7698 QDF_STATUS status = QDF_STATUS_E_FAILURE; 7699 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7700 ePhyChanBondState cb_mode; 7701 struct csr_roam_session *session = CSR_GET_SESSION(mac, sessionId); 7702 7703 if (!CSR_IS_SESSION_VALID(mac, sessionId)) { 7704 sme_err("Session not valid for session id %d", sessionId); 7705 return QDF_STATUS_E_INVAL; 7706 } 7707 session = CSR_GET_SESSION(mac, sessionId); 7708 sme_debug("Update HT operation beacon IE, channel_type=%d cur cbmode %d", 7709 channel_type, session->cb_mode); 7710 7711 switch (channel_type) { 7712 case eHT_CHAN_HT20: 7713 if (!session->cb_mode) 7714 return QDF_STATUS_SUCCESS; 7715 cb_mode = PHY_SINGLE_CHANNEL_CENTERED; 7716 break; 7717 case eHT_CHAN_HT40MINUS: 7718 if (session->cb_mode) 7719 return QDF_STATUS_SUCCESS; 7720 cb_mode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; 7721 break; 7722 case eHT_CHAN_HT40PLUS: 7723 if (session->cb_mode) 7724 return QDF_STATUS_SUCCESS; 7725 cb_mode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; 7726 break; 7727 default: 7728 sme_err("Error!!! Invalid HT20/40 mode !"); 7729 return QDF_STATUS_E_FAILURE; 7730 } 7731 session->cb_mode = cb_mode; 7732 status = sme_acquire_global_lock(&mac->sme); 7733 if (QDF_IS_STATUS_SUCCESS(status)) { 7734 status = csr_set_ht2040_mode(mac, sessionId, 7735 cb_mode, obssEnabled); 7736 sme_release_global_lock(&mac->sme); 7737 } 7738 return status; 7739 } 7740 sme_get_ht2040_mode(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelType * channel_type)7741 QDF_STATUS sme_get_ht2040_mode(mac_handle_t mac_handle, uint8_t vdev_id, 7742 enum eSirMacHTChannelType *channel_type) 7743 { 7744 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7745 struct csr_roam_session *session; 7746 7747 if (!CSR_IS_SESSION_VALID(mac, vdev_id)) { 7748 sme_err("Session not valid for session id %d", vdev_id); 7749 return QDF_STATUS_E_INVAL; 7750 } 7751 session = CSR_GET_SESSION(mac, vdev_id); 7752 sme_debug("Get HT operation beacon IE, channel_type=%d cur cbmode %d", 7753 *channel_type, session->cb_mode); 7754 7755 switch (session->cb_mode) { 7756 case PHY_SINGLE_CHANNEL_CENTERED: 7757 *channel_type = eHT_CHAN_HT20; 7758 break; 7759 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: 7760 *channel_type = eHT_CHAN_HT40MINUS; 7761 break; 7762 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: 7763 *channel_type = eHT_CHAN_HT40PLUS; 7764 break; 7765 default: 7766 sme_err("Error!!! Invalid HT20/40 mode !"); 7767 return QDF_STATUS_E_FAILURE; 7768 } 7769 7770 return QDF_STATUS_SUCCESS; 7771 } 7772 7773 #endif 7774 7775 /* 7776 * SME API to enable/disable idle mode powersave 7777 * This should be called only if powersave offload 7778 * is enabled 7779 */ sme_set_idle_powersave_config(bool value)7780 QDF_STATUS sme_set_idle_powersave_config(bool value) 7781 { 7782 void *wmaContext = cds_get_context(QDF_MODULE_ID_WMA); 7783 7784 if (!wmaContext) 7785 return QDF_STATUS_E_FAILURE; 7786 7787 if (QDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value)) 7788 return QDF_STATUS_E_FAILURE; 7789 7790 return QDF_STATUS_SUCCESS; 7791 } 7792 sme_get_ht_config(mac_handle_t mac_handle,uint8_t vdev_id,uint16_t ht_capab)7793 int16_t sme_get_ht_config(mac_handle_t mac_handle, uint8_t vdev_id, 7794 uint16_t ht_capab) 7795 { 7796 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7797 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); 7798 struct wlan_objmgr_vdev *vdev; 7799 struct vdev_mlme_obj *vdev_mlme; 7800 struct wlan_ht_config ht_cap_info; 7801 7802 if (!pSession) { 7803 sme_err("pSession is NULL"); 7804 return -EIO; 7805 } 7806 7807 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 7808 WLAN_LEGACY_SME_ID); 7809 if (!vdev) 7810 return -EIO; 7811 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 7812 if (!vdev_mlme) { 7813 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7814 return -EIO; 7815 } 7816 ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps; 7817 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7818 switch (ht_capab) { 7819 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: 7820 return ht_cap_info.ht_caps.adv_coding_cap; 7821 case WNI_CFG_HT_CAP_INFO_TX_STBC: 7822 return ht_cap_info.ht_caps.tx_stbc; 7823 case WNI_CFG_HT_CAP_INFO_RX_STBC: 7824 return ht_cap_info.ht_caps.rx_stbc; 7825 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: 7826 return ht_cap_info.ht_caps.short_gi_20_mhz; 7827 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: 7828 return ht_cap_info.ht_caps.short_gi_40_mhz; 7829 default: 7830 sme_err("invalid ht capability"); 7831 return -EIO; 7832 } 7833 } 7834 7835 /** 7836 * sme_validate_peer_ampdu_cfg() - Function to validate peer A-MPDU configure 7837 * @peer: peer object 7838 * @cfg: peer A-MPDU configure value 7839 * 7840 * Return: true if success, otherwise false 7841 */ sme_validate_peer_ampdu_cfg(struct wlan_objmgr_peer * peer,uint16_t cfg)7842 static bool sme_validate_peer_ampdu_cfg(struct wlan_objmgr_peer *peer, 7843 uint16_t cfg) 7844 { 7845 if (!cfg) { 7846 sme_debug("peer ampdu count 0"); 7847 return false; 7848 } 7849 7850 if (wlan_peer_get_peer_type(peer) == WLAN_PEER_SELF) { 7851 sme_debug("self peer"); 7852 return false; 7853 } 7854 7855 return true; 7856 } 7857 sme_set_peer_ampdu(mac_handle_t mac_handle,uint8_t vdev_id,struct qdf_mac_addr * peer_mac,uint16_t cfg)7858 int sme_set_peer_ampdu(mac_handle_t mac_handle, uint8_t vdev_id, 7859 struct qdf_mac_addr *peer_mac, uint16_t cfg) 7860 { 7861 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 7862 struct wlan_objmgr_vdev *vdev; 7863 QDF_STATUS status; 7864 struct wlan_objmgr_peer *peer_obj; 7865 7866 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 7867 vdev_id, 7868 WLAN_LEGACY_SME_ID); 7869 if (!vdev) { 7870 sme_err("vdev null"); 7871 return -EINVAL; 7872 } 7873 7874 status = wlan_vdev_is_up(vdev); 7875 if (QDF_IS_STATUS_ERROR(status)) { 7876 sme_debug("vdev id %d not up", vdev_id); 7877 goto release_vdev_ref; 7878 } 7879 peer_obj = wlan_objmgr_vdev_find_peer_by_mac(vdev, 7880 peer_mac->bytes, 7881 WLAN_LEGACY_SME_ID); 7882 if (!peer_obj) { 7883 sme_debug("vdev id %d peer not found "QDF_MAC_ADDR_FMT, 7884 vdev_id, 7885 QDF_MAC_ADDR_REF(peer_mac->bytes)); 7886 status = QDF_STATUS_E_FAILURE; 7887 goto release_vdev_ref; 7888 } 7889 7890 if (!sme_validate_peer_ampdu_cfg(peer_obj, cfg)) { 7891 status = QDF_STATUS_E_INVAL; 7892 goto release_peer_ref; 7893 } 7894 status = sme_set_peer_param(peer_mac->bytes, 7895 WMI_HOST_PEER_AMPDU, 7896 cfg, 7897 vdev_id); 7898 release_peer_ref: 7899 wlan_objmgr_peer_release_ref(peer_obj, WLAN_LEGACY_SME_ID); 7900 release_vdev_ref: 7901 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7902 return qdf_status_to_os_return(status); 7903 } 7904 sme_update_ht_config(mac_handle_t mac_handle,uint8_t vdev_id,uint16_t htCapab,int value)7905 int sme_update_ht_config(mac_handle_t mac_handle, uint8_t vdev_id, 7906 uint16_t htCapab, int value) 7907 { 7908 struct mac_context *mac = MAC_CONTEXT(mac_handle); 7909 struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); 7910 struct wlan_ht_config ht_cap_info; 7911 struct wlan_objmgr_vdev *vdev; 7912 struct vdev_mlme_obj *vdev_mlme; 7913 7914 if (!pSession) { 7915 sme_err("pSession is NULL"); 7916 return -EIO; 7917 } 7918 7919 if (QDF_STATUS_SUCCESS != wma_set_htconfig(vdev_id, htCapab, value)) { 7920 sme_err("Failed to set ht capability in target"); 7921 return -EIO; 7922 } 7923 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 7924 WLAN_LEGACY_SME_ID); 7925 if (!vdev) 7926 return -EIO; 7927 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 7928 if (!vdev_mlme) { 7929 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7930 return -EIO; 7931 } 7932 ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps; 7933 7934 switch (htCapab) { 7935 case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: 7936 ht_cap_info.ht_caps.adv_coding_cap = value; 7937 break; 7938 case WNI_CFG_HT_CAP_INFO_TX_STBC: 7939 ht_cap_info.ht_caps.tx_stbc = value; 7940 break; 7941 case WNI_CFG_HT_CAP_INFO_RX_STBC: 7942 ht_cap_info.ht_caps.rx_stbc = value; 7943 break; 7944 case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: 7945 value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */ 7946 ht_cap_info.ht_caps.short_gi_20_mhz = value; 7947 break; 7948 case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: 7949 value = value ? 1 : 0; /* HT SGI can be only 1 or 0 */ 7950 ht_cap_info.ht_caps.short_gi_40_mhz = value; 7951 break; 7952 } 7953 vdev_mlme->proto.ht_info.ht_caps = ht_cap_info.caps; 7954 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 7955 7956 csr_roam_update_config(mac, vdev_id, htCapab, value); 7957 return 0; 7958 } 7959 sme_set_addba_accept(mac_handle_t mac_handle,uint8_t session_id,int value)7960 int sme_set_addba_accept(mac_handle_t mac_handle, uint8_t session_id, int value) 7961 { 7962 struct sme_addba_accept *addba_accept; 7963 struct scheduler_msg msg = {0}; 7964 QDF_STATUS status; 7965 7966 addba_accept = qdf_mem_malloc(sizeof(*addba_accept)); 7967 if (!addba_accept) 7968 return -EIO; 7969 7970 addba_accept->session_id = session_id; 7971 addba_accept->addba_accept = value; 7972 qdf_mem_zero(&msg, sizeof(msg)); 7973 msg.type = eWNI_SME_SET_ADDBA_ACCEPT; 7974 msg.reserved = 0; 7975 msg.bodyptr = addba_accept; 7976 status = scheduler_post_message(QDF_MODULE_ID_SME, 7977 QDF_MODULE_ID_PE, 7978 QDF_MODULE_ID_PE, &msg); 7979 if (status != QDF_STATUS_SUCCESS) { 7980 sme_err("Not able to post addba reject"); 7981 qdf_mem_free(addba_accept); 7982 return -EIO; 7983 } 7984 return 0; 7985 } 7986 sme_set_ba_buff_size(mac_handle_t mac_handle,uint8_t session_id,uint16_t buff_size)7987 int sme_set_ba_buff_size(mac_handle_t mac_handle, uint8_t session_id, 7988 uint16_t buff_size) 7989 { 7990 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 7991 if (!buff_size) { 7992 sme_err("invalid buff size %d", buff_size); 7993 return -EINVAL; 7994 } 7995 mac_ctx->usr_cfg_ba_buff_size = buff_size; 7996 sme_debug("addba buff size is set to %d", 7997 mac_ctx->usr_cfg_ba_buff_size); 7998 7999 return 0; 8000 } 8001 8002 #define DEFAULT_BA_BUFF_SIZE 64 sme_send_addba_req(mac_handle_t mac_handle,uint8_t session_id,uint8_t tid,uint16_t buff_size)8003 int sme_send_addba_req(mac_handle_t mac_handle, uint8_t session_id, uint8_t tid, 8004 uint16_t buff_size) 8005 { 8006 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8007 uint16_t ba_buff = 0; 8008 QDF_STATUS status; 8009 struct scheduler_msg msg = {0}; 8010 struct send_add_ba_req *send_ba_req; 8011 8012 if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) { 8013 sme_err("STA not infra/connected state session_id: %d", 8014 session_id); 8015 return -EINVAL; 8016 } 8017 8018 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 8019 sme_err("CSR session is invalid"); 8020 return -EINVAL; 8021 } 8022 send_ba_req = qdf_mem_malloc(sizeof(*send_ba_req)); 8023 if (!send_ba_req) 8024 return -EIO; 8025 8026 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session_id, 8027 (struct qdf_mac_addr *)&send_ba_req->mac_addr); 8028 ba_buff = buff_size; 8029 if (!buff_size) { 8030 if (mac_ctx->usr_cfg_ba_buff_size) 8031 ba_buff = mac_ctx->usr_cfg_ba_buff_size; 8032 else 8033 ba_buff = DEFAULT_BA_BUFF_SIZE; 8034 } 8035 send_ba_req->param.vdev_id = session_id; 8036 send_ba_req->param.tidno = tid; 8037 send_ba_req->param.buffersize = ba_buff; 8038 msg.type = WMA_SEND_ADDBA_REQ; 8039 msg.bodyptr = send_ba_req; 8040 status = scheduler_post_message(QDF_MODULE_ID_SME, 8041 QDF_MODULE_ID_WMA, 8042 QDF_MODULE_ID_WMA, &msg); 8043 if (QDF_STATUS_SUCCESS != status) { 8044 qdf_mem_free(send_ba_req); 8045 return -EIO; 8046 } 8047 sme_debug("ADDBA_REQ sent to FW: tid %d buff_size %d", tid, ba_buff); 8048 8049 return 0; 8050 } 8051 sme_set_no_ack_policy(mac_handle_t mac_handle,uint8_t session_id,uint8_t val,uint8_t ac)8052 int sme_set_no_ack_policy(mac_handle_t mac_handle, uint8_t session_id, 8053 uint8_t val, uint8_t ac) 8054 { 8055 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8056 uint8_t i, set_val; 8057 struct scheduler_msg msg = {0}; 8058 QDF_STATUS status; 8059 8060 if (ac > QCA_WLAN_AC_ALL) { 8061 sme_err("invalid ac val %d", ac); 8062 return -EINVAL; 8063 } 8064 if (val) 8065 set_val = 1; 8066 else 8067 set_val = 0; 8068 if (ac == QCA_WLAN_AC_ALL) { 8069 for (i = 0; i < ac; i++) 8070 mac_ctx->no_ack_policy_cfg[i] = set_val; 8071 } else { 8072 mac_ctx->no_ack_policy_cfg[ac] = set_val; 8073 } 8074 sme_debug("no ack is set to %d for ac %d", set_val, ac); 8075 qdf_mem_zero(&msg, sizeof(msg)); 8076 msg.type = eWNI_SME_UPDATE_EDCA_PROFILE; 8077 msg.reserved = 0; 8078 msg.bodyval = session_id; 8079 status = scheduler_post_message(QDF_MODULE_ID_SME, 8080 QDF_MODULE_ID_PE, 8081 QDF_MODULE_ID_PE, &msg); 8082 if (status != QDF_STATUS_SUCCESS) { 8083 sme_err("Not able to post update edca profile"); 8084 return -EIO; 8085 } 8086 8087 return 0; 8088 } 8089 sme_set_auto_rate_he_ltf(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)8090 int sme_set_auto_rate_he_ltf(mac_handle_t mac_handle, uint8_t session_id, 8091 uint8_t cfg_val) 8092 { 8093 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8094 uint32_t set_val; 8095 uint32_t bit_mask = 0; 8096 int status; 8097 8098 if (cfg_val > QCA_WLAN_HE_LTF_4X) { 8099 sme_err("invalid HE LTF cfg %d", cfg_val); 8100 return -EINVAL; 8101 } 8102 8103 /*set the corresponding HE LTF cfg BIT*/ 8104 if (cfg_val == QCA_WLAN_HE_LTF_AUTO) 8105 bit_mask = HE_LTF_ALL; 8106 else 8107 bit_mask = (1 << (cfg_val - 1)); 8108 8109 set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask; 8110 8111 SET_AUTO_RATE_HE_LTF_VAL(set_val, bit_mask); 8112 8113 mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val; 8114 status = wma_cli_set_command(session_id, 8115 wmi_vdev_param_autorate_misc_cfg, 8116 set_val, VDEV_CMD); 8117 if (status) { 8118 sme_err("failed to set he_ltf_sgi"); 8119 return status; 8120 } 8121 8122 sme_debug("HE SGI_LTF is set to 0x%08X", 8123 mac_ctx->he_sgi_ltf_cfg_bit_mask); 8124 8125 return 0; 8126 } 8127 sme_set_auto_rate_he_sgi(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)8128 int sme_set_auto_rate_he_sgi(mac_handle_t mac_handle, uint8_t session_id, 8129 uint8_t cfg_val) 8130 { 8131 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8132 uint32_t set_val; 8133 uint32_t sgi_bit_mask = 0; 8134 int status; 8135 8136 if ((cfg_val > AUTO_RATE_GI_3200NS) || 8137 (cfg_val < AUTO_RATE_GI_400NS)) { 8138 sme_err("invalid auto rate GI cfg %d", cfg_val); 8139 return -EINVAL; 8140 } 8141 8142 sgi_bit_mask = (1 << cfg_val); 8143 8144 set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask; 8145 SET_AUTO_RATE_SGI_VAL(set_val, sgi_bit_mask); 8146 8147 mac_ctx->he_sgi_ltf_cfg_bit_mask = set_val; 8148 status = wma_cli_set_command(session_id, 8149 wmi_vdev_param_autorate_misc_cfg, 8150 set_val, VDEV_CMD); 8151 if (status) { 8152 sme_err("failed to set he_ltf_sgi"); 8153 return status; 8154 } 8155 8156 sme_debug("auto rate HE SGI_LTF is set to 0x%08X", 8157 mac_ctx->he_sgi_ltf_cfg_bit_mask); 8158 8159 return 0; 8160 } 8161 sme_set_auto_rate_ldpc(mac_handle_t mac_handle,uint8_t session_id,uint8_t ldpc_disable)8162 int sme_set_auto_rate_ldpc(mac_handle_t mac_handle, uint8_t session_id, 8163 uint8_t ldpc_disable) 8164 { 8165 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8166 uint32_t set_val; 8167 int status; 8168 8169 set_val = mac_ctx->he_sgi_ltf_cfg_bit_mask; 8170 8171 set_val |= (ldpc_disable << AUTO_RATE_LDPC_DIS_BIT); 8172 8173 status = wma_cli_set_command(session_id, 8174 wmi_vdev_param_autorate_misc_cfg, 8175 set_val, VDEV_CMD); 8176 if (status) { 8177 sme_err("failed to set auto rate LDPC cfg"); 8178 return status; 8179 } 8180 8181 sme_debug("auto rate misc cfg set to 0x%08X", set_val); 8182 8183 return 0; 8184 } 8185 8186 #define HT20_SHORT_GI_MCS7_RATE 722 8187 /* 8188 * sme_send_rate_update_ind() - 8189 * API to Update rate 8190 * 8191 * mac_handle - The handle returned by mac_open 8192 * rateUpdateParams - Pointer to rate update params 8193 * Return QDF_STATUS 8194 */ sme_send_rate_update_ind(mac_handle_t mac_handle,tSirRateUpdateInd * rateUpdateParams)8195 QDF_STATUS sme_send_rate_update_ind(mac_handle_t mac_handle, 8196 tSirRateUpdateInd *rateUpdateParams) 8197 { 8198 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8199 QDF_STATUS status; 8200 struct scheduler_msg msg = {0}; 8201 tSirRateUpdateInd *rate_upd = qdf_mem_malloc(sizeof(tSirRateUpdateInd)); 8202 8203 if (!rate_upd) 8204 return QDF_STATUS_E_FAILURE; 8205 8206 *rate_upd = *rateUpdateParams; 8207 8208 if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE) 8209 rate_upd->mcastDataRate24GHzTxFlag = 8210 TX_RATE_HT20 | TX_RATE_SGI; 8211 else if (rate_upd->reliableMcastDataRate == 8212 HT20_SHORT_GI_MCS7_RATE) 8213 rate_upd->reliableMcastDataRateTxFlag = 8214 TX_RATE_HT20 | TX_RATE_SGI; 8215 8216 status = sme_acquire_global_lock(&mac->sme); 8217 if (QDF_IS_STATUS_ERROR(status)) { 8218 qdf_mem_free(rate_upd); 8219 return status; 8220 } 8221 8222 msg.type = WMA_RATE_UPDATE_IND; 8223 msg.bodyptr = rate_upd; 8224 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 8225 NO_SESSION, msg.type)); 8226 8227 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_WMA, 8228 QDF_MODULE_ID_WMA, &msg); 8229 if (QDF_IS_STATUS_ERROR(status)) { 8230 sme_err("Not able to post WMA_RATE_UPDATE_IND to WMA!"); 8231 qdf_mem_free(rate_upd); 8232 status = QDF_STATUS_E_FAILURE; 8233 } 8234 8235 sme_release_global_lock(&mac->sme); 8236 8237 return status; 8238 } 8239 8240 /** 8241 * sme_update_access_policy_vendor_ie() - update vendor ie and access policy. 8242 * @mac_handle: Pointer to the mac context 8243 * @vdev_id: vdev_id 8244 * @vendor_ie: vendor ie 8245 * @access_policy: vendor ie access policy 8246 * 8247 * This function updates the vendor ie and access policy to lim. 8248 * 8249 * Return: success or failure. 8250 */ sme_update_access_policy_vendor_ie(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * vendor_ie,int access_policy)8251 QDF_STATUS sme_update_access_policy_vendor_ie(mac_handle_t mac_handle, 8252 uint8_t vdev_id, 8253 uint8_t *vendor_ie, 8254 int access_policy) 8255 { 8256 struct sme_update_access_policy_vendor_ie *msg; 8257 uint16_t msg_len; 8258 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8259 8260 msg_len = sizeof(*msg); 8261 8262 msg = qdf_mem_malloc(msg_len); 8263 if (!msg) { 8264 return QDF_STATUS_E_NOMEM; 8265 } 8266 8267 msg->msg_type = (uint16_t)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE; 8268 msg->length = (uint16_t)msg_len; 8269 8270 qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie)); 8271 8272 msg->vdev_id = vdev_id; 8273 msg->access_policy = access_policy; 8274 8275 sme_debug("vdev_id: %hu, access_policy: %d", vdev_id, access_policy); 8276 status = umac_send_mb_message_to_mac(msg); 8277 8278 return status; 8279 } 8280 8281 /** 8282 * sme_update_sta_inactivity_timeout(): Update sta_inactivity_timeout to FW 8283 * @mac_handle: Handle returned by mac_open 8284 * @session_id: Session ID on which sta_inactivity_timeout needs 8285 * to be updated to FW 8286 * @sta_inactivity_timeout: sta inactivity timeout. 8287 * 8288 * If a station does not send anything in sta_inactivity_timeout seconds, an 8289 * empty data frame is sent to it in order to verify whether it is 8290 * still in range. If this frame is not ACKed, the station will be 8291 * disassociated and then deauthenticated. 8292 * 8293 * Return: QDF_STATUS_SUCCESS or non-zero on failure. 8294 */ sme_update_sta_inactivity_timeout(mac_handle_t mac_handle,struct sme_sta_inactivity_timeout * sta_inactivity_timer)8295 QDF_STATUS sme_update_sta_inactivity_timeout(mac_handle_t mac_handle, 8296 struct sme_sta_inactivity_timeout *sta_inactivity_timer) 8297 { 8298 struct sme_sta_inactivity_timeout *inactivity_time; 8299 void *wma_handle; 8300 8301 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 8302 inactivity_time = qdf_mem_malloc(sizeof(*inactivity_time)); 8303 if (!inactivity_time) 8304 return QDF_STATUS_E_FAILURE; 8305 8306 sme_debug("sta_inactivity_timeout: %d", 8307 sta_inactivity_timer->sta_inactivity_timeout); 8308 inactivity_time->session_id = sta_inactivity_timer->session_id; 8309 inactivity_time->sta_inactivity_timeout = 8310 sta_inactivity_timer->sta_inactivity_timeout; 8311 8312 wma_update_sta_inactivity_timeout(wma_handle, inactivity_time); 8313 qdf_mem_free(inactivity_time); 8314 return QDF_STATUS_SUCCESS; 8315 } 8316 sme_get_reg_info(mac_handle_t mac_handle,uint32_t chan_freq,uint32_t * regInfo1,uint32_t * regInfo2)8317 QDF_STATUS sme_get_reg_info(mac_handle_t mac_handle, uint32_t chan_freq, 8318 uint32_t *regInfo1, uint32_t *regInfo2) 8319 { 8320 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8321 QDF_STATUS status = QDF_STATUS_SUCCESS; 8322 uint8_t i; 8323 bool found = false; 8324 8325 *regInfo1 = 0; 8326 *regInfo2 = 0; 8327 8328 for (i = 0; i < CFG_VALID_CHANNEL_LIST_LEN; i++) { 8329 if (mac->scan.defaultPowerTable[i].center_freq == chan_freq) { 8330 SME_SET_CHANNEL_REG_POWER(*regInfo1, 8331 mac->scan.defaultPowerTable[i].tx_power); 8332 8333 SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2, 8334 mac->scan.defaultPowerTable[i].tx_power); 8335 found = true; 8336 break; 8337 } 8338 } 8339 if (!found) 8340 status = QDF_STATUS_E_FAILURE; 8341 8342 return status; 8343 } 8344 8345 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN sme_set_auto_shutdown_cb(mac_handle_t mac_handle,void (* callback_fn)(void))8346 QDF_STATUS sme_set_auto_shutdown_cb(mac_handle_t mac_handle, 8347 void (*callback_fn)(void)) 8348 { 8349 QDF_STATUS status; 8350 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8351 8352 sme_info("Plug in Auto shutdown event callback"); 8353 8354 status = sme_acquire_global_lock(&mac->sme); 8355 if (QDF_STATUS_SUCCESS == status) { 8356 if (callback_fn) 8357 mac->sme.auto_shutdown_cb = callback_fn; 8358 sme_release_global_lock(&mac->sme); 8359 } 8360 8361 return status; 8362 } 8363 8364 /* 8365 * sme_set_auto_shutdown_timer() - 8366 * API to set auto shutdown timer value in FW. 8367 * 8368 * mac_handle - The handle returned by mac_open 8369 * timer_val - The auto shutdown timer value to be set 8370 * Return Configuration message posting status, SUCCESS or Fail 8371 */ sme_set_auto_shutdown_timer(mac_handle_t mac_handle,uint32_t timer_val)8372 QDF_STATUS sme_set_auto_shutdown_timer(mac_handle_t mac_handle, 8373 uint32_t timer_val) 8374 { 8375 QDF_STATUS status = QDF_STATUS_SUCCESS; 8376 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 8377 struct auto_shutdown_cmd *auto_sh_cmd; 8378 struct scheduler_msg message = {0}; 8379 8380 auto_sh_cmd = qdf_mem_malloc(sizeof(*auto_sh_cmd)); 8381 if (!auto_sh_cmd) 8382 return QDF_STATUS_E_NOMEM; 8383 8384 8385 auto_sh_cmd->timer_val = timer_val; 8386 8387 /* serialize the req through MC thread */ 8388 message.bodyptr = auto_sh_cmd; 8389 message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ; 8390 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 8391 QDF_MODULE_ID_WMA, 8392 QDF_MODULE_ID_WMA, 8393 &message); 8394 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 8395 sme_err("Post Auto shutdown MSG fail"); 8396 qdf_mem_free(auto_sh_cmd); 8397 return QDF_STATUS_E_FAILURE; 8398 } 8399 8400 return status; 8401 } 8402 #endif 8403 8404 #ifdef FEATURE_WLAN_CH_AVOID 8405 /* 8406 * sme_ch_avoid_update_req() - 8407 * API to request channel avoidance update from FW. 8408 * 8409 * mac_handle - The handle returned by mac_open 8410 * update_type - The update_type parameter of this request call 8411 * Return Configuration message posting status, SUCCESS or Fail 8412 */ sme_ch_avoid_update_req(mac_handle_t mac_handle)8413 QDF_STATUS sme_ch_avoid_update_req(mac_handle_t mac_handle) 8414 { 8415 QDF_STATUS status = QDF_STATUS_SUCCESS; 8416 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 8417 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8418 tSirChAvoidUpdateReq *cauReq; 8419 struct scheduler_msg message = {0}; 8420 8421 status = sme_acquire_global_lock(&mac->sme); 8422 if (QDF_STATUS_SUCCESS == status) { 8423 cauReq = qdf_mem_malloc(sizeof(tSirChAvoidUpdateReq)); 8424 if (!cauReq) { 8425 sme_release_global_lock(&mac->sme); 8426 return QDF_STATUS_E_NOMEM; 8427 } 8428 8429 cauReq->reserved_param = 0; 8430 8431 /* serialize the req through MC thread */ 8432 message.bodyptr = cauReq; 8433 message.type = WMA_CH_AVOID_UPDATE_REQ; 8434 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 8435 QDF_MODULE_ID_WMA, 8436 QDF_MODULE_ID_WMA, 8437 &message); 8438 if (QDF_IS_STATUS_ERROR(qdf_status)) { 8439 sme_err("Post Ch Avoid Update MSG fail"); 8440 qdf_mem_free(cauReq); 8441 sme_release_global_lock(&mac->sme); 8442 return QDF_STATUS_E_FAILURE; 8443 } 8444 sme_debug("Posted Ch Avoid Update MSG"); 8445 sme_release_global_lock(&mac->sme); 8446 } 8447 8448 return status; 8449 } 8450 #endif 8451 8452 /** 8453 * sme_set_miracast() - Function to set miracast value to UMAC 8454 * @mac_handle: Handle returned by macOpen 8455 * @filter_type: 0-Disabled, 1-Source, 2-sink 8456 * 8457 * This function passes down the value of miracast set by 8458 * framework to UMAC 8459 * 8460 * Return: Configuration message posting status, SUCCESS or Fail 8461 * 8462 */ sme_set_miracast(mac_handle_t mac_handle,uint8_t filter_type)8463 QDF_STATUS sme_set_miracast(mac_handle_t mac_handle, uint8_t filter_type) 8464 { 8465 struct scheduler_msg msg = {0}; 8466 uint32_t *val; 8467 struct mac_context *mac_ptr = MAC_CONTEXT(mac_handle); 8468 8469 if (!mac_ptr) { 8470 sme_err("Invalid pointer"); 8471 return QDF_STATUS_E_INVAL; 8472 } 8473 8474 val = qdf_mem_malloc(sizeof(*val)); 8475 if (!val) 8476 return QDF_STATUS_E_NOMEM; 8477 8478 *val = filter_type; 8479 8480 msg.type = SIR_HAL_SET_MIRACAST; 8481 msg.reserved = 0; 8482 msg.bodyptr = val; 8483 8484 if (!QDF_IS_STATUS_SUCCESS( 8485 scheduler_post_message(QDF_MODULE_ID_SME, 8486 QDF_MODULE_ID_WMA, 8487 QDF_MODULE_ID_WMA, 8488 &msg))) { 8489 sme_err("Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!"); 8490 qdf_mem_free(val); 8491 return QDF_STATUS_E_FAILURE; 8492 } 8493 8494 mac_ptr->sme.miracast_value = filter_type; 8495 return QDF_STATUS_SUCCESS; 8496 } 8497 8498 /** 8499 * sme_set_mas() - Function to set MAS value to UMAC 8500 * @val: 1-Enable, 0-Disable 8501 * 8502 * This function passes down the value of MAS to the UMAC. A 8503 * value of 1 will enable MAS and a value of 0 will disable MAS 8504 * 8505 * Return: Configuration message posting status, SUCCESS or Fail 8506 * 8507 */ sme_set_mas(uint32_t val)8508 QDF_STATUS sme_set_mas(uint32_t val) 8509 { 8510 struct scheduler_msg msg = {0}; 8511 uint32_t *ptr_val; 8512 8513 ptr_val = qdf_mem_malloc(sizeof(*ptr_val)); 8514 if (!ptr_val) 8515 return QDF_STATUS_E_NOMEM; 8516 8517 *ptr_val = val; 8518 8519 msg.type = SIR_HAL_SET_MAS; 8520 msg.reserved = 0; 8521 msg.bodyptr = ptr_val; 8522 8523 if (!QDF_IS_STATUS_SUCCESS( 8524 scheduler_post_message(QDF_MODULE_ID_SME, 8525 QDF_MODULE_ID_WMA, 8526 QDF_MODULE_ID_WMA, 8527 &msg))) { 8528 sme_err("Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!"); 8529 qdf_mem_free(ptr_val); 8530 return QDF_STATUS_E_FAILURE; 8531 } 8532 return QDF_STATUS_SUCCESS; 8533 } 8534 sme_send_channel_change_req(mac_handle_t mac_handle,struct channel_change_req * req)8535 QDF_STATUS sme_send_channel_change_req(mac_handle_t mac_handle, 8536 struct channel_change_req *req) 8537 { 8538 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8539 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8540 8541 status = sme_acquire_global_lock(&mac->sme); 8542 if (QDF_IS_STATUS_SUCCESS(status)) { 8543 status = csr_send_channel_change_req(mac, req); 8544 sme_release_global_lock(&mac->sme); 8545 } 8546 return status; 8547 } 8548 8549 /* 8550 * sme_process_channel_change_resp() - 8551 * API to Indicate Channel change response message to SAP. 8552 * 8553 * Return QDF_STATUS 8554 */ sme_process_channel_change_resp(struct mac_context * mac,uint16_t msg_type,void * msg_buf)8555 static QDF_STATUS sme_process_channel_change_resp(struct mac_context *mac, 8556 uint16_t msg_type, void *msg_buf) 8557 { 8558 QDF_STATUS status = QDF_STATUS_SUCCESS; 8559 struct csr_roam_info *roam_info; 8560 eCsrRoamResult roamResult; 8561 uint8_t session_id; 8562 8563 roam_info = qdf_mem_malloc(sizeof(*roam_info)); 8564 if (!roam_info) 8565 return QDF_STATUS_E_NOMEM; 8566 8567 roam_info->channelChangeRespEvent = 8568 (struct sSirChanChangeResponse *)msg_buf; 8569 8570 session_id = roam_info->channelChangeRespEvent->sessionId; 8571 8572 if (roam_info->channelChangeRespEvent->channelChangeStatus == 8573 QDF_STATUS_SUCCESS) { 8574 sme_debug("sapdfs: Received success for vdev %d", session_id); 8575 roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; 8576 } else { 8577 sme_debug("sapdfs: Received failure for vdev %d", session_id); 8578 roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; 8579 } 8580 8581 csr_roam_call_callback(mac, session_id, roam_info, 8582 eCSR_ROAM_SET_CHANNEL_RSP, roamResult); 8583 8584 qdf_mem_free(roam_info); 8585 8586 return status; 8587 } 8588 8589 /* 8590 * sme_roam_start_beacon_req() - 8591 * API to Indicate LIM to start Beacon Tx after SAP CAC Wait is completed. 8592 * 8593 * mac_handle - The handle returned by mac_open 8594 * sessionId - session ID 8595 * dfsCacWaitStatus - CAC WAIT status flag 8596 * Return QDF_STATUS 8597 */ sme_roam_start_beacon_req(mac_handle_t mac_handle,struct qdf_mac_addr bssid,uint8_t dfsCacWaitStatus)8598 QDF_STATUS sme_roam_start_beacon_req(mac_handle_t mac_handle, 8599 struct qdf_mac_addr bssid, 8600 uint8_t dfsCacWaitStatus) 8601 { 8602 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8603 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8604 8605 status = sme_acquire_global_lock(&mac->sme); 8606 8607 if (QDF_IS_STATUS_SUCCESS(status)) { 8608 status = csr_roam_start_beacon_req(mac, bssid, 8609 dfsCacWaitStatus); 8610 sme_release_global_lock(&mac->sme); 8611 } 8612 return status; 8613 } 8614 sme_csa_restart(struct mac_context * mac_ctx,uint8_t session_id)8615 QDF_STATUS sme_csa_restart(struct mac_context *mac_ctx, uint8_t session_id) 8616 { 8617 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8618 8619 status = sme_acquire_global_lock(&mac_ctx->sme); 8620 if (QDF_IS_STATUS_SUCCESS(status)) { 8621 status = csr_csa_restart(mac_ctx, session_id); 8622 sme_release_global_lock(&mac_ctx->sme); 8623 } 8624 8625 return status; 8626 } 8627 sme_roam_csa_ie_request(mac_handle_t mac_handle,struct qdf_mac_addr bssid,uint32_t target_chan_freq,uint8_t csaIeReqd,struct ch_params * ch_params,uint32_t new_cac_ms)8628 QDF_STATUS sme_roam_csa_ie_request(mac_handle_t mac_handle, 8629 struct qdf_mac_addr bssid, 8630 uint32_t target_chan_freq, uint8_t csaIeReqd, 8631 struct ch_params *ch_params, 8632 uint32_t new_cac_ms) 8633 { 8634 QDF_STATUS status = QDF_STATUS_E_FAILURE; 8635 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8636 8637 status = sme_acquire_global_lock(&mac->sme); 8638 if (QDF_IS_STATUS_SUCCESS(status)) { 8639 status = csr_roam_send_chan_sw_ie_request(mac, bssid, 8640 target_chan_freq, 8641 csaIeReqd, ch_params, 8642 new_cac_ms); 8643 sme_release_global_lock(&mac->sme); 8644 } 8645 return status; 8646 } 8647 8648 /* 8649 * sme_init_thermal_info() - 8650 * SME API to initialize the thermal mitigation parameters 8651 * 8652 * mac_handle 8653 * thermalParam : thermal mitigation parameters 8654 * Return QDF_STATUS 8655 */ sme_init_thermal_info(mac_handle_t mac_handle)8656 QDF_STATUS sme_init_thermal_info(mac_handle_t mac_handle) 8657 { 8658 t_thermal_mgmt *pWmaParam; 8659 struct scheduler_msg msg = {0}; 8660 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8661 struct wlan_fwol_thermal_temp thermal_temp = {0}; 8662 QDF_STATUS status; 8663 8664 pWmaParam = qdf_mem_malloc(sizeof(t_thermal_mgmt)); 8665 if (!pWmaParam) 8666 return QDF_STATUS_E_NOMEM; 8667 8668 status = ucfg_fwol_get_thermal_temp(mac->psoc, &thermal_temp); 8669 if (QDF_IS_STATUS_ERROR(status)) 8670 return qdf_status_to_os_return(status); 8671 8672 pWmaParam->thermalMgmtEnabled = thermal_temp.thermal_mitigation_enable; 8673 pWmaParam->throttlePeriod = thermal_temp.throttle_period; 8674 8675 pWmaParam->throttle_duty_cycle_tbl[0] = 8676 thermal_temp.throttle_dutycycle_level[0]; 8677 pWmaParam->throttle_duty_cycle_tbl[1] = 8678 thermal_temp.throttle_dutycycle_level[1]; 8679 pWmaParam->throttle_duty_cycle_tbl[2] = 8680 thermal_temp.throttle_dutycycle_level[2]; 8681 pWmaParam->throttle_duty_cycle_tbl[3] = 8682 thermal_temp.throttle_dutycycle_level[3]; 8683 pWmaParam->throttle_duty_cycle_tbl[4] = 8684 thermal_temp.throttle_dutycycle_level[4]; 8685 pWmaParam->throttle_duty_cycle_tbl[5] = 8686 thermal_temp.throttle_dutycycle_level[5]; 8687 8688 pWmaParam->thermalLevels[0].minTempThreshold = 8689 thermal_temp.thermal_temp_min_level[0]; 8690 pWmaParam->thermalLevels[0].maxTempThreshold = 8691 thermal_temp.thermal_temp_max_level[0]; 8692 pWmaParam->thermalLevels[1].minTempThreshold = 8693 thermal_temp.thermal_temp_min_level[1]; 8694 pWmaParam->thermalLevels[1].maxTempThreshold = 8695 thermal_temp.thermal_temp_max_level[1]; 8696 pWmaParam->thermalLevels[2].minTempThreshold = 8697 thermal_temp.thermal_temp_min_level[2]; 8698 pWmaParam->thermalLevels[2].maxTempThreshold = 8699 thermal_temp.thermal_temp_max_level[2]; 8700 pWmaParam->thermalLevels[3].minTempThreshold = 8701 thermal_temp.thermal_temp_min_level[3]; 8702 pWmaParam->thermalLevels[3].maxTempThreshold = 8703 thermal_temp.thermal_temp_max_level[3]; 8704 pWmaParam->thermalLevels[4].minTempThreshold = 8705 thermal_temp.thermal_temp_min_level[4]; 8706 pWmaParam->thermalLevels[4].maxTempThreshold = 8707 thermal_temp.thermal_temp_max_level[4]; 8708 pWmaParam->thermalLevels[5].minTempThreshold = 8709 thermal_temp.thermal_temp_min_level[5]; 8710 pWmaParam->thermalLevels[5].maxTempThreshold = 8711 thermal_temp.thermal_temp_max_level[5]; 8712 pWmaParam->thermal_action = thermal_temp.thermal_action; 8713 if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) { 8714 msg.type = WMA_INIT_THERMAL_INFO_CMD; 8715 msg.bodyptr = pWmaParam; 8716 8717 if (!QDF_IS_STATUS_SUCCESS 8718 (scheduler_post_message(QDF_MODULE_ID_SME, 8719 QDF_MODULE_ID_WMA, 8720 QDF_MODULE_ID_WMA, 8721 &msg))) { 8722 sme_err("Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!"); 8723 qdf_mem_free(pWmaParam); 8724 sme_release_global_lock(&mac->sme); 8725 return QDF_STATUS_E_FAILURE; 8726 } 8727 sme_release_global_lock(&mac->sme); 8728 return QDF_STATUS_SUCCESS; 8729 } 8730 qdf_mem_free(pWmaParam); 8731 return QDF_STATUS_E_FAILURE; 8732 } 8733 8734 /** 8735 * sme_add_set_thermal_level_callback() - Plug in set thermal level callback 8736 * @mac_handle: Handle returned by macOpen 8737 * @callback: sme_set_thermal_level_callback 8738 * 8739 * Plug in set thermal level callback 8740 * 8741 * Return: none 8742 */ sme_add_set_thermal_level_callback(mac_handle_t mac_handle,sme_set_thermal_level_callback callback)8743 void sme_add_set_thermal_level_callback(mac_handle_t mac_handle, 8744 sme_set_thermal_level_callback callback) 8745 { 8746 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8747 8748 mac->sme.set_thermal_level_cb = callback; 8749 } 8750 8751 /** 8752 * sme_set_thermal_level() - SME API to set the thermal mitigation level 8753 * @mac_handle: Opaque handle to the global MAC context 8754 * @level: Thermal mitigation level 8755 * 8756 * Return: QDF_STATUS 8757 */ sme_set_thermal_level(mac_handle_t mac_handle,uint8_t level)8758 QDF_STATUS sme_set_thermal_level(mac_handle_t mac_handle, uint8_t level) 8759 { 8760 struct scheduler_msg msg = {0}; 8761 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8762 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 8763 8764 if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) { 8765 qdf_mem_zero(&msg, sizeof(msg)); 8766 msg.type = WMA_SET_THERMAL_LEVEL; 8767 msg.bodyval = level; 8768 8769 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 8770 QDF_MODULE_ID_WMA, 8771 QDF_MODULE_ID_WMA, &msg); 8772 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 8773 sme_err("Not able to post WMA_SET_THERMAL_LEVEL to WMA!"); 8774 sme_release_global_lock(&mac->sme); 8775 return QDF_STATUS_E_FAILURE; 8776 } 8777 sme_release_global_lock(&mac->sme); 8778 return QDF_STATUS_SUCCESS; 8779 } 8780 return QDF_STATUS_E_FAILURE; 8781 } 8782 8783 /* 8784 * sme_txpower_limit() - 8785 * SME API to set txpower limits 8786 * 8787 * mac_handle 8788 * psmetx : power limits for 2g/5g 8789 * Return QDF_STATUS 8790 */ sme_txpower_limit(mac_handle_t mac_handle,struct tx_power_limit * psmetx)8791 QDF_STATUS sme_txpower_limit(mac_handle_t mac_handle, 8792 struct tx_power_limit *psmetx) 8793 { 8794 QDF_STATUS status; 8795 struct scheduler_msg message = {0}; 8796 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8797 struct tx_power_limit *tx_power_limit; 8798 8799 tx_power_limit = qdf_mem_malloc(sizeof(*tx_power_limit)); 8800 if (!tx_power_limit) 8801 return QDF_STATUS_E_FAILURE; 8802 8803 *tx_power_limit = *psmetx; 8804 8805 status = sme_acquire_global_lock(&mac->sme); 8806 if (QDF_IS_STATUS_ERROR(status)) { 8807 qdf_mem_free(tx_power_limit); 8808 return status; 8809 } 8810 8811 message.type = WMA_TX_POWER_LIMIT; 8812 message.bodyptr = tx_power_limit; 8813 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_WMA, 8814 QDF_MODULE_ID_WMA, &message); 8815 if (QDF_IS_STATUS_ERROR(status)) { 8816 sme_err("not able to post WMA_TX_POWER_LIMIT"); 8817 status = QDF_STATUS_E_FAILURE; 8818 qdf_mem_free(tx_power_limit); 8819 } 8820 8821 sme_release_global_lock(&mac->sme); 8822 8823 return status; 8824 } 8825 sme_update_connect_debug(mac_handle_t mac_handle,uint32_t set_value)8826 QDF_STATUS sme_update_connect_debug(mac_handle_t mac_handle, uint32_t set_value) 8827 { 8828 QDF_STATUS status = QDF_STATUS_SUCCESS; 8829 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8830 8831 mac->mlme_cfg->gen.debug_packet_log = set_value; 8832 return status; 8833 } 8834 8835 /* 8836 * sme_ap_disable_intra_bss_fwd() - 8837 * SME will send message to WMA to set Intra BSS in txrx 8838 * 8839 * mac_handle - The handle returned by mac_open 8840 * sessionId - session id ( vdev id) 8841 * disablefwd - bool value that indicate disable intrabss fwd disable 8842 * Return QDF_STATUS 8843 */ sme_ap_disable_intra_bss_fwd(mac_handle_t mac_handle,uint8_t sessionId,bool disablefwd)8844 QDF_STATUS sme_ap_disable_intra_bss_fwd(mac_handle_t mac_handle, 8845 uint8_t sessionId, 8846 bool disablefwd) 8847 { 8848 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8849 int status = QDF_STATUS_SUCCESS; 8850 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 8851 struct scheduler_msg message = {0}; 8852 tpDisableIntraBssFwd pSapDisableIntraFwd = NULL; 8853 8854 /* Prepare the request to send to SME. */ 8855 pSapDisableIntraFwd = qdf_mem_malloc(sizeof(tDisableIntraBssFwd)); 8856 if (!pSapDisableIntraFwd) 8857 return QDF_STATUS_E_NOMEM; 8858 8859 pSapDisableIntraFwd->sessionId = sessionId; 8860 pSapDisableIntraFwd->disableintrabssfwd = disablefwd; 8861 8862 status = sme_acquire_global_lock(&mac->sme); 8863 8864 if (QDF_IS_STATUS_ERROR(status)) { 8865 qdf_mem_free(pSapDisableIntraFwd); 8866 return QDF_STATUS_E_FAILURE; 8867 } 8868 /* serialize the req through MC thread */ 8869 message.bodyptr = pSapDisableIntraFwd; 8870 message.type = WMA_SET_SAP_INTRABSS_DIS; 8871 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 8872 QDF_MODULE_ID_WMA, 8873 QDF_MODULE_ID_WMA, 8874 &message); 8875 if (QDF_IS_STATUS_ERROR(status)) { 8876 status = QDF_STATUS_E_FAILURE; 8877 qdf_mem_free(pSapDisableIntraFwd); 8878 } 8879 sme_release_global_lock(&mac->sme); 8880 8881 return status; 8882 } 8883 8884 #ifdef WLAN_FEATURE_STATS_EXT 8885 sme_stats_ext_register_callback(mac_handle_t mac_handle,stats_ext_cb callback)8886 void sme_stats_ext_register_callback(mac_handle_t mac_handle, 8887 stats_ext_cb callback) 8888 { 8889 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8890 8891 if (!mac) { 8892 sme_err("Invalid mac context"); 8893 return; 8894 } 8895 8896 mac->sme.stats_ext_cb = callback; 8897 } 8898 sme_stats_ext_deregister_callback(mac_handle_t mac_handle)8899 void sme_stats_ext_deregister_callback(mac_handle_t mac_handle) 8900 { 8901 sme_stats_ext_register_callback(mac_handle, NULL); 8902 } 8903 sme_stats_ext2_register_callback(mac_handle_t mac_handle,stats_ext2_cb callback)8904 void sme_stats_ext2_register_callback(mac_handle_t mac_handle, 8905 stats_ext2_cb callback) 8906 { 8907 struct mac_context *mac = MAC_CONTEXT(mac_handle); 8908 8909 if (!mac) { 8910 sme_err("Invalid mac context"); 8911 return; 8912 } 8913 8914 mac->sme.stats_ext2_cb = callback; 8915 } 8916 8917 /* 8918 * sme_stats_ext_request() - 8919 * Function called when HDD receives STATS EXT vendor command from userspace 8920 * 8921 * sessionID - vdevID for the stats ext request 8922 * input - Stats Ext Request structure ptr 8923 * Return QDF_STATUS 8924 */ sme_stats_ext_request(uint8_t session_id,tpStatsExtRequestReq input)8925 QDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input) 8926 { 8927 struct scheduler_msg msg = {0}; 8928 tpStatsExtRequest data; 8929 size_t data_len; 8930 8931 data_len = sizeof(tStatsExtRequest) + input->request_data_len; 8932 data = qdf_mem_malloc(data_len); 8933 if (!data) 8934 return QDF_STATUS_E_NOMEM; 8935 8936 data->vdev_id = session_id; 8937 data->request_data_len = input->request_data_len; 8938 if (input->request_data_len) 8939 qdf_mem_copy(data->request_data, 8940 input->request_data, input->request_data_len); 8941 8942 msg.type = WMA_STATS_EXT_REQUEST; 8943 msg.reserved = 0; 8944 msg.bodyptr = data; 8945 8946 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 8947 QDF_MODULE_ID_WMA, 8948 QDF_MODULE_ID_WMA, 8949 &msg)) { 8950 sme_err("Not able to post WMA_STATS_EXT_REQUEST message to WMA"); 8951 qdf_mem_free(data); 8952 return QDF_STATUS_E_FAILURE; 8953 } 8954 8955 return QDF_STATUS_SUCCESS; 8956 } 8957 8958 /** 8959 * sme_stats_ext_event() - eWNI_SME_STATS_EXT_EVENT processor 8960 * @mac: Global MAC context 8961 * @msg: "stats ext" message 8962 8963 * This callback function called when SME received eWNI_SME_STATS_EXT_EVENT 8964 * response from WMA 8965 * 8966 * Return: QDF_STATUS 8967 */ sme_stats_ext_event(struct mac_context * mac,struct stats_ext_event * msg)8968 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac, 8969 struct stats_ext_event *msg) 8970 { 8971 if (!msg) { 8972 sme_err("Null msg"); 8973 return QDF_STATUS_E_FAILURE; 8974 } 8975 8976 if (mac->sme.stats_ext_cb) 8977 mac->sme.stats_ext_cb(mac->hdd_handle, msg); 8978 8979 return QDF_STATUS_SUCCESS; 8980 } 8981 8982 #else 8983 sme_stats_ext_event(struct mac_context * mac,struct stats_ext_event * msg)8984 static QDF_STATUS sme_stats_ext_event(struct mac_context *mac, 8985 struct stats_ext_event *msg) 8986 { 8987 return QDF_STATUS_SUCCESS; 8988 } 8989 8990 #endif 8991 8992 #ifdef FEATURE_FW_STATE sme_get_fw_state(mac_handle_t mac_handle,fw_state_callback callback,void * context)8993 QDF_STATUS sme_get_fw_state(mac_handle_t mac_handle, 8994 fw_state_callback callback, 8995 void *context) 8996 { 8997 QDF_STATUS status; 8998 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 8999 tp_wma_handle wma_handle; 9000 9001 SME_ENTER(); 9002 9003 mac_ctx->sme.fw_state_cb = callback; 9004 mac_ctx->sme.fw_state_context = context; 9005 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 9006 status = wma_get_fw_state(wma_handle); 9007 9008 SME_EXIT(); 9009 return status; 9010 } 9011 9012 /** 9013 * sme_fw_state_resp() - eWNI_SME_FW_STATUS_IND processor 9014 * @mac: Global MAC context 9015 9016 * This callback function called when SME received eWNI_SME_FW_STATUS_IND 9017 * response from WMA 9018 * 9019 * Return: QDF_STATUS 9020 */ sme_fw_state_resp(struct mac_context * mac)9021 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac) 9022 { 9023 if (mac->sme.fw_state_cb) 9024 mac->sme.fw_state_cb(mac->sme.fw_state_context); 9025 mac->sme.fw_state_cb = NULL; 9026 mac->sme.fw_state_context = NULL; 9027 9028 return QDF_STATUS_SUCCESS; 9029 } 9030 9031 #else /* FEATURE_FW_STATE */ sme_fw_state_resp(struct mac_context * mac)9032 static QDF_STATUS sme_fw_state_resp(struct mac_context *mac) 9033 { 9034 return QDF_STATUS_SUCCESS; 9035 } 9036 9037 #endif /* FEATURE_FW_STATE */ 9038 9039 /* 9040 * sme_update_dfs_scan_mode() - 9041 * Update DFS roam scan mode 9042 * This function is called through dynamic setConfig callback function 9043 * to configure allowDFSChannelRoam. 9044 * mac_handle: Opaque handle to the global MAC context 9045 * sessionId - Session Identifier 9046 * allowDFSChannelRoam - DFS roaming scan mode 0 (disable), 9047 * 1 (passive), 2 (active) 9048 * Return QDF_STATUS_SUCCESS - SME update DFS roaming scan config 9049 * successfully. 9050 * Other status means SME failed to update DFS roaming scan config. 9051 */ sme_update_dfs_scan_mode(mac_handle_t mac_handle,uint8_t sessionId,uint8_t allowDFSChannelRoam)9052 QDF_STATUS sme_update_dfs_scan_mode(mac_handle_t mac_handle, uint8_t sessionId, 9053 uint8_t allowDFSChannelRoam) 9054 { 9055 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9056 QDF_STATUS status = QDF_STATUS_SUCCESS; 9057 9058 if (sessionId >= WLAN_MAX_VDEVS) { 9059 sme_err("Invalid vdev %d", sessionId); 9060 return QDF_STATUS_E_INVAL; 9061 } 9062 9063 status = sme_acquire_global_lock(&mac->sme); 9064 if (QDF_IS_STATUS_SUCCESS(status)) { 9065 sme_debug("LFR runtime successfully set AllowDFSChannelRoam Mode to %d - old value is %d", 9066 allowDFSChannelRoam, 9067 mac->mlme_cfg->lfr.roaming_dfs_channel); 9068 mac->mlme_cfg->lfr.roaming_dfs_channel = 9069 allowDFSChannelRoam; 9070 if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) 9071 wlan_roam_update_cfg(mac->psoc, sessionId, 9072 REASON_ROAM_DFS_SCAN_MODE_CHANGED); 9073 9074 sme_release_global_lock(&mac->sme); 9075 } 9076 9077 9078 return status; 9079 } 9080 9081 /* 9082 * sme_get_dfs_scan_mode() - get DFS roam scan mode 9083 * This is a synchronous call 9084 * 9085 * mac_handle - The handle returned by mac_open. 9086 * Return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active) 9087 */ sme_get_dfs_scan_mode(mac_handle_t mac_handle)9088 uint8_t sme_get_dfs_scan_mode(mac_handle_t mac_handle) 9089 { 9090 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9091 9092 return mac->mlme_cfg->lfr.roaming_dfs_channel; 9093 } 9094 9095 /* 9096 * sme_modify_add_ie() - 9097 * This function sends msg to updates the additional IE buffers in PE 9098 * 9099 * mac_handle - global structure 9100 * pModifyIE - pointer to tModifyIE structure 9101 * updateType - type of buffer 9102 * Return Success or failure 9103 */ sme_modify_add_ie(mac_handle_t mac_handle,tSirModifyIE * pModifyIE,eUpdateIEsType updateType)9104 QDF_STATUS sme_modify_add_ie(mac_handle_t mac_handle, 9105 tSirModifyIE *pModifyIE, eUpdateIEsType updateType) 9106 { 9107 QDF_STATUS status = QDF_STATUS_E_FAILURE; 9108 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9109 9110 status = sme_acquire_global_lock(&mac->sme); 9111 9112 if (QDF_IS_STATUS_SUCCESS(status)) { 9113 status = csr_roam_modify_add_ies(mac, pModifyIE, updateType); 9114 sme_release_global_lock(&mac->sme); 9115 } 9116 return status; 9117 } 9118 9119 /* 9120 * sme_update_add_ie() - 9121 * This function sends msg to updates the additional IE buffers in PE 9122 * 9123 * mac_handle - global structure 9124 * pUpdateIE - pointer to structure tUpdateIE 9125 * updateType - type of buffer 9126 * Return Success or failure 9127 */ sme_update_add_ie(mac_handle_t mac_handle,tSirUpdateIE * pUpdateIE,eUpdateIEsType updateType)9128 QDF_STATUS sme_update_add_ie(mac_handle_t mac_handle, 9129 tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType) 9130 { 9131 QDF_STATUS status = QDF_STATUS_E_FAILURE; 9132 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9133 9134 status = sme_acquire_global_lock(&mac->sme); 9135 9136 if (QDF_IS_STATUS_SUCCESS(status)) { 9137 status = csr_roam_update_add_ies(mac, pUpdateIE, updateType); 9138 sme_release_global_lock(&mac->sme); 9139 } 9140 return status; 9141 } 9142 9143 /** 9144 * sme_update_dsc_pto_up_mapping() 9145 * @mac_handle: Opaque handle to the global MAC context 9146 * @dscpmapping: pointer to DSCP mapping structure 9147 * @sessionId: SME session id 9148 * 9149 * This routine is called to update dscp mapping 9150 * 9151 * Return: QDF_STATUS 9152 */ sme_update_dsc_pto_up_mapping(mac_handle_t mac_handle,enum sme_qos_wmmuptype * dscpmapping,uint8_t sessionId)9153 QDF_STATUS sme_update_dsc_pto_up_mapping(mac_handle_t mac_handle, 9154 enum sme_qos_wmmuptype *dscpmapping, 9155 uint8_t sessionId) 9156 { 9157 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9158 QDF_STATUS status = QDF_STATUS_SUCCESS; 9159 uint8_t i, j; 9160 struct csr_roam_session *pCsrSession = NULL; 9161 struct pe_session *pSession = NULL; 9162 struct qos_map_set *pqosmapset; 9163 9164 pCsrSession = CSR_GET_SESSION(mac, sessionId); 9165 if (!pCsrSession) { 9166 sme_err("Session lookup fails for dvev %d", sessionId); 9167 return QDF_STATUS_E_FAILURE; 9168 } 9169 if (!CSR_IS_SESSION_VALID(mac, sessionId)) { 9170 sme_err("Invalid session Id %u", sessionId); 9171 return QDF_STATUS_E_FAILURE; 9172 } 9173 9174 pSession = pe_find_session_by_vdev_id(mac, sessionId); 9175 9176 if (!pSession) 9177 return QDF_STATUS_E_FAILURE; 9178 9179 pqosmapset = &pSession->QosMapSet; 9180 if (!pqosmapset->present) 9181 return QDF_STATUS_E_FAILURE; 9182 9183 for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) { 9184 for (j = pqosmapset->dscp_range[i][0]; 9185 j <= pqosmapset->dscp_range[i][1] && j <= WLAN_MAX_DSCP; 9186 j++) 9187 dscpmapping[j] = i; 9188 } 9189 for (i = 0; i < pqosmapset->num_dscp_exceptions; i++) 9190 if (pqosmapset->dscp_exceptions[i][0] <= WLAN_MAX_DSCP && 9191 pqosmapset->dscp_exceptions[i][1] < SME_QOS_WMM_UP_MAX) 9192 dscpmapping[pqosmapset->dscp_exceptions[i][0]] = 9193 pqosmapset->dscp_exceptions[i][1]; 9194 9195 return status; 9196 } 9197 sme_get_valid_channels_by_band(mac_handle_t mac_handle,uint8_t wifi_band,uint32_t * valid_chan_list,uint8_t * valid_chan_len)9198 QDF_STATUS sme_get_valid_channels_by_band(mac_handle_t mac_handle, 9199 uint8_t wifi_band, 9200 uint32_t *valid_chan_list, 9201 uint8_t *valid_chan_len) 9202 { 9203 QDF_STATUS status = QDF_STATUS_SUCCESS; 9204 uint32_t chan_freq_list[CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; 9205 uint8_t num_channels = 0; 9206 uint8_t i = 0; 9207 uint32_t valid_channels = CFG_VALID_CHANNEL_LIST_LEN; 9208 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 9209 9210 if (!valid_chan_list || !valid_chan_len) { 9211 sme_err("Output channel list/NumChannels is NULL"); 9212 return QDF_STATUS_E_INVAL; 9213 } 9214 9215 if (wifi_band >= WIFI_BAND_MAX) { 9216 sme_err("Invalid wifi Band: %d", wifi_band); 9217 return QDF_STATUS_E_INVAL; 9218 } 9219 9220 status = sme_get_cfg_valid_channels(&chan_freq_list[0], 9221 &valid_channels); 9222 if (!QDF_IS_STATUS_SUCCESS(status)) { 9223 sme_err("Fail to get valid channel list (err=%d)", status); 9224 return status; 9225 } 9226 9227 switch (wifi_band) { 9228 case WIFI_BAND_UNSPECIFIED: 9229 sme_debug("Unspec Band, return all %d valid channels", 9230 valid_channels); 9231 num_channels = valid_channels; 9232 for (i = 0; i < valid_channels; i++) 9233 valid_chan_list[i] = chan_freq_list[i]; 9234 break; 9235 9236 case WIFI_BAND_BG: 9237 sme_debug("WIFI_BAND_BG (2.4 GHz)"); 9238 for (i = 0; i < valid_channels; i++) { 9239 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i])) 9240 valid_chan_list[num_channels++] = 9241 chan_freq_list[i]; 9242 } 9243 break; 9244 9245 case WIFI_BAND_A: 9246 sme_debug("WIFI_BAND_A (5 GHz without DFS)"); 9247 for (i = 0; i < valid_channels; i++) { 9248 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) && 9249 !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 9250 chan_freq_list[i])) 9251 valid_chan_list[num_channels++] = 9252 chan_freq_list[i]; 9253 } 9254 break; 9255 9256 case WIFI_BAND_ABG: 9257 sme_debug("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)"); 9258 for (i = 0; i < valid_channels; i++) { 9259 if ((WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) || 9260 WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) && 9261 !wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 9262 chan_freq_list[i])) 9263 valid_chan_list[num_channels++] = 9264 chan_freq_list[i]; 9265 } 9266 break; 9267 9268 case WIFI_BAND_A_DFS_ONLY: 9269 sme_debug("WIFI_BAND_A_DFS (5 GHz DFS only)"); 9270 for (i = 0; i < valid_channels; i++) { 9271 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i]) && 9272 wlan_reg_is_dfs_for_freq(mac_ctx->pdev, 9273 chan_freq_list[i])) 9274 valid_chan_list[num_channels++] = 9275 chan_freq_list[i]; 9276 } 9277 break; 9278 9279 case WIFI_BAND_A_WITH_DFS: 9280 sme_debug("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)"); 9281 for (i = 0; i < valid_channels; i++) { 9282 if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) 9283 valid_chan_list[num_channels++] = 9284 chan_freq_list[i]; 9285 } 9286 break; 9287 9288 case WIFI_BAND_ABG_WITH_DFS: 9289 sme_debug("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)"); 9290 for (i = 0; i < valid_channels; i++) { 9291 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq_list[i]) || 9292 WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq_list[i])) 9293 valid_chan_list[num_channels++] = 9294 chan_freq_list[i]; 9295 } 9296 break; 9297 9298 default: 9299 sme_err("Unknown wifi Band: %d", wifi_band); 9300 return QDF_STATUS_E_INVAL; 9301 } 9302 *valid_chan_len = num_channels; 9303 9304 return status; 9305 } 9306 9307 #ifdef FEATURE_WLAN_EXTSCAN 9308 9309 QDF_STATUS sme_ext_scan_get_capabilities(mac_handle_t mac_handle,struct extscan_capabilities_params * params)9310 sme_ext_scan_get_capabilities(mac_handle_t mac_handle, 9311 struct extscan_capabilities_params *params) 9312 { 9313 QDF_STATUS status; 9314 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9315 struct scheduler_msg message = {0}; 9316 struct extscan_capabilities_params *bodyptr; 9317 9318 /* per contract must make a copy of the params when messaging */ 9319 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9320 if (!bodyptr) 9321 return QDF_STATUS_E_NOMEM; 9322 9323 *bodyptr = *params; 9324 9325 status = sme_acquire_global_lock(&mac->sme); 9326 if (QDF_IS_STATUS_SUCCESS(status)) { 9327 /* Serialize the req through MC thread */ 9328 message.bodyptr = bodyptr; 9329 message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ; 9330 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9331 NO_SESSION, message.type); 9332 status = scheduler_post_message(QDF_MODULE_ID_SME, 9333 QDF_MODULE_ID_WMA, 9334 QDF_MODULE_ID_WMA, 9335 &message); 9336 sme_release_global_lock(&mac->sme); 9337 } 9338 9339 if (QDF_IS_STATUS_ERROR(status)) { 9340 sme_err("failure: %d", status); 9341 qdf_mem_free(bodyptr); 9342 } 9343 return status; 9344 } 9345 9346 QDF_STATUS sme_ext_scan_start(mac_handle_t mac_handle,struct wifi_scan_cmd_req_params * params)9347 sme_ext_scan_start(mac_handle_t mac_handle, 9348 struct wifi_scan_cmd_req_params *params) 9349 { 9350 QDF_STATUS status; 9351 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9352 struct scheduler_msg message = {0}; 9353 struct wifi_scan_cmd_req_params *bodyptr; 9354 9355 /* per contract must make a copy of the params when messaging */ 9356 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9357 if (!bodyptr) 9358 return QDF_STATUS_E_NOMEM; 9359 9360 *bodyptr = *params; 9361 9362 status = sme_acquire_global_lock(&mac->sme); 9363 if (QDF_IS_STATUS_SUCCESS(status)) { 9364 /* Serialize the req through MC thread */ 9365 message.bodyptr = bodyptr; 9366 message.type = WMA_EXTSCAN_START_REQ; 9367 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9368 NO_SESSION, message.type); 9369 status = scheduler_post_message(QDF_MODULE_ID_SME, 9370 QDF_MODULE_ID_WMA, 9371 QDF_MODULE_ID_WMA, 9372 &message); 9373 sme_release_global_lock(&mac->sme); 9374 } 9375 9376 if (QDF_IS_STATUS_ERROR(status)) { 9377 sme_err("failure: %d", status); 9378 qdf_mem_free(bodyptr); 9379 } 9380 return status; 9381 } 9382 sme_ext_scan_stop(mac_handle_t mac_handle,struct extscan_stop_req_params * params)9383 QDF_STATUS sme_ext_scan_stop(mac_handle_t mac_handle, 9384 struct extscan_stop_req_params *params) 9385 { 9386 QDF_STATUS status; 9387 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9388 struct scheduler_msg message = {0}; 9389 struct extscan_stop_req_params *bodyptr; 9390 9391 /* per contract must make a copy of the params when messaging */ 9392 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9393 if (!bodyptr) 9394 return QDF_STATUS_E_NOMEM; 9395 9396 *bodyptr = *params; 9397 9398 status = sme_acquire_global_lock(&mac->sme); 9399 if (QDF_IS_STATUS_SUCCESS(status)) { 9400 /* Serialize the req through MC thread */ 9401 message.bodyptr = bodyptr; 9402 message.type = WMA_EXTSCAN_STOP_REQ; 9403 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9404 NO_SESSION, message.type); 9405 status = scheduler_post_message(QDF_MODULE_ID_SME, 9406 QDF_MODULE_ID_WMA, 9407 QDF_MODULE_ID_WMA, 9408 &message); 9409 sme_release_global_lock(&mac->sme); 9410 } 9411 9412 if (QDF_IS_STATUS_ERROR(status)) { 9413 sme_err("failure: %d", status); 9414 qdf_mem_free(bodyptr); 9415 } 9416 return status; 9417 } 9418 9419 QDF_STATUS sme_set_bss_hotlist(mac_handle_t mac_handle,struct extscan_bssid_hotlist_set_params * params)9420 sme_set_bss_hotlist(mac_handle_t mac_handle, 9421 struct extscan_bssid_hotlist_set_params *params) 9422 { 9423 QDF_STATUS status; 9424 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9425 struct scheduler_msg message = {0}; 9426 struct extscan_bssid_hotlist_set_params *bodyptr; 9427 9428 /* per contract must make a copy of the params when messaging */ 9429 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9430 if (!bodyptr) 9431 return QDF_STATUS_E_NOMEM; 9432 9433 *bodyptr = *params; 9434 9435 status = sme_acquire_global_lock(&mac->sme); 9436 if (QDF_IS_STATUS_SUCCESS(status)) { 9437 /* Serialize the req through MC thread */ 9438 message.bodyptr = bodyptr; 9439 message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ; 9440 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9441 NO_SESSION, message.type); 9442 status = scheduler_post_message(QDF_MODULE_ID_SME, 9443 QDF_MODULE_ID_WMA, 9444 QDF_MODULE_ID_WMA, &message); 9445 sme_release_global_lock(&mac->sme); 9446 } 9447 9448 if (QDF_IS_STATUS_ERROR(status)) { 9449 sme_err("failure: %d", status); 9450 qdf_mem_free(bodyptr); 9451 } 9452 return status; 9453 } 9454 9455 QDF_STATUS sme_reset_bss_hotlist(mac_handle_t mac_handle,struct extscan_bssid_hotlist_reset_params * params)9456 sme_reset_bss_hotlist(mac_handle_t mac_handle, 9457 struct extscan_bssid_hotlist_reset_params *params) 9458 { 9459 QDF_STATUS status; 9460 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9461 struct scheduler_msg message = {0}; 9462 struct extscan_bssid_hotlist_reset_params *bodyptr; 9463 9464 /* per contract must make a copy of the params when messaging */ 9465 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9466 if (!bodyptr) 9467 return QDF_STATUS_E_NOMEM; 9468 9469 *bodyptr = *params; 9470 9471 status = sme_acquire_global_lock(&mac->sme); 9472 if (QDF_IS_STATUS_SUCCESS(status)) { 9473 /* Serialize the req through MC thread */ 9474 message.bodyptr = bodyptr; 9475 message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ; 9476 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9477 NO_SESSION, message.type)); 9478 status = scheduler_post_message(QDF_MODULE_ID_SME, 9479 QDF_MODULE_ID_WMA, 9480 QDF_MODULE_ID_WMA, &message); 9481 sme_release_global_lock(&mac->sme); 9482 } 9483 9484 if (QDF_IS_STATUS_ERROR(status)) { 9485 sme_err("failure: %d", status); 9486 qdf_mem_free(bodyptr); 9487 } 9488 return status; 9489 } 9490 9491 QDF_STATUS sme_set_significant_change(mac_handle_t mac_handle,struct extscan_set_sig_changereq_params * params)9492 sme_set_significant_change(mac_handle_t mac_handle, 9493 struct extscan_set_sig_changereq_params *params) 9494 { 9495 QDF_STATUS status; 9496 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9497 struct scheduler_msg message = {0}; 9498 struct extscan_set_sig_changereq_params *bodyptr; 9499 9500 /* per contract must make a copy of the params when messaging */ 9501 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9502 if (!bodyptr) 9503 return QDF_STATUS_E_NOMEM; 9504 9505 *bodyptr = *params; 9506 9507 status = sme_acquire_global_lock(&mac->sme); 9508 if (QDF_IS_STATUS_SUCCESS(status)) { 9509 /* Serialize the req through MC thread */ 9510 message.bodyptr = bodyptr; 9511 message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ; 9512 status = scheduler_post_message(QDF_MODULE_ID_SME, 9513 QDF_MODULE_ID_WMA, 9514 QDF_MODULE_ID_WMA, 9515 &message); 9516 sme_release_global_lock(&mac->sme); 9517 } 9518 if (QDF_IS_STATUS_ERROR(status)) { 9519 sme_err("failure: %d", status); 9520 qdf_mem_free(bodyptr); 9521 } 9522 return status; 9523 } 9524 9525 QDF_STATUS sme_reset_significant_change(mac_handle_t mac_handle,struct extscan_capabilities_reset_params * params)9526 sme_reset_significant_change(mac_handle_t mac_handle, 9527 struct extscan_capabilities_reset_params *params) 9528 { 9529 QDF_STATUS status; 9530 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9531 struct scheduler_msg message = {0}; 9532 struct extscan_capabilities_reset_params *bodyptr; 9533 9534 /* per contract must make a copy of the params when messaging */ 9535 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9536 if (!bodyptr) 9537 return QDF_STATUS_E_NOMEM; 9538 9539 *bodyptr = *params; 9540 9541 status = sme_acquire_global_lock(&mac->sme); 9542 if (QDF_IS_STATUS_SUCCESS(status)) { 9543 /* Serialize the req through MC thread */ 9544 message.bodyptr = bodyptr; 9545 message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ; 9546 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9547 NO_SESSION, message.type)); 9548 status = scheduler_post_message(QDF_MODULE_ID_SME, 9549 QDF_MODULE_ID_WMA, 9550 QDF_MODULE_ID_WMA, 9551 &message); 9552 sme_release_global_lock(&mac->sme); 9553 } 9554 if (QDF_IS_STATUS_ERROR(status)) { 9555 sme_err("failure: %d", status); 9556 qdf_mem_free(bodyptr); 9557 } 9558 9559 return status; 9560 } 9561 9562 QDF_STATUS sme_get_cached_results(mac_handle_t mac_handle,struct extscan_cached_result_params * params)9563 sme_get_cached_results(mac_handle_t mac_handle, 9564 struct extscan_cached_result_params *params) 9565 { 9566 QDF_STATUS status; 9567 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9568 struct scheduler_msg message = {0}; 9569 struct extscan_cached_result_params *bodyptr; 9570 9571 /* per contract must make a copy of the params when messaging */ 9572 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 9573 if (!bodyptr) 9574 return QDF_STATUS_E_NOMEM; 9575 9576 *bodyptr = *params; 9577 9578 status = sme_acquire_global_lock(&mac->sme); 9579 if (QDF_IS_STATUS_SUCCESS(status)) { 9580 /* Serialize the req through MC thread */ 9581 message.bodyptr = bodyptr; 9582 message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ; 9583 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9584 NO_SESSION, message.type); 9585 status = scheduler_post_message(QDF_MODULE_ID_SME, 9586 QDF_MODULE_ID_WMA, 9587 QDF_MODULE_ID_WMA, 9588 &message); 9589 sme_release_global_lock(&mac->sme); 9590 } 9591 9592 if (QDF_IS_STATUS_ERROR(status)) { 9593 sme_err("failure: %d", status); 9594 qdf_mem_free(bodyptr); 9595 } 9596 return status; 9597 } 9598 sme_set_epno_list(mac_handle_t mac_handle,struct wifi_enhanced_pno_params * params)9599 QDF_STATUS sme_set_epno_list(mac_handle_t mac_handle, 9600 struct wifi_enhanced_pno_params *params) 9601 { 9602 QDF_STATUS status; 9603 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9604 struct scheduler_msg message = {0}; 9605 struct wifi_enhanced_pno_params *req_msg; 9606 int len; 9607 9608 SME_ENTER(); 9609 9610 /* per contract must make a copy of the params when messaging */ 9611 len = sizeof(*req_msg) + 9612 (params->num_networks * sizeof(req_msg->networks[0])); 9613 9614 req_msg = qdf_mem_malloc(len); 9615 if (!req_msg) 9616 return QDF_STATUS_E_NOMEM; 9617 9618 qdf_mem_copy(req_msg, params, len); 9619 9620 status = sme_acquire_global_lock(&mac->sme); 9621 if (!QDF_IS_STATUS_SUCCESS(status)) { 9622 sme_err("sme_acquire_global_lock failed!(status=%d)", 9623 status); 9624 qdf_mem_free(req_msg); 9625 return status; 9626 } 9627 9628 /* Serialize the req through MC thread */ 9629 message.bodyptr = req_msg; 9630 message.type = WMA_SET_EPNO_LIST_REQ; 9631 status = scheduler_post_message(QDF_MODULE_ID_SME, 9632 QDF_MODULE_ID_WMA, 9633 QDF_MODULE_ID_WMA, &message); 9634 if (!QDF_IS_STATUS_SUCCESS(status)) { 9635 sme_err("scheduler_post_msg failed!(err=%d)", status); 9636 qdf_mem_free(req_msg); 9637 } 9638 sme_release_global_lock(&mac->sme); 9639 9640 return status; 9641 } 9642 sme_set_passpoint_list(mac_handle_t mac_handle,struct wifi_passpoint_req_param * params)9643 QDF_STATUS sme_set_passpoint_list(mac_handle_t mac_handle, 9644 struct wifi_passpoint_req_param *params) 9645 { 9646 QDF_STATUS status; 9647 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9648 struct scheduler_msg message = {0}; 9649 struct wifi_passpoint_req_param *req_msg; 9650 int len; 9651 9652 SME_ENTER(); 9653 9654 len = sizeof(*req_msg) + 9655 (params->num_networks * sizeof(params->networks[0])); 9656 req_msg = qdf_mem_malloc(len); 9657 if (!req_msg) 9658 return QDF_STATUS_E_NOMEM; 9659 9660 qdf_mem_copy(req_msg, params, len); 9661 9662 status = sme_acquire_global_lock(&mac->sme); 9663 if (!QDF_IS_STATUS_SUCCESS(status)) { 9664 sme_err("sme_acquire_global_lock failed!(status=%d)", 9665 status); 9666 qdf_mem_free(req_msg); 9667 return status; 9668 } 9669 9670 /* Serialize the req through MC thread */ 9671 message.bodyptr = req_msg; 9672 message.type = WMA_SET_PASSPOINT_LIST_REQ; 9673 status = scheduler_post_message(QDF_MODULE_ID_SME, 9674 QDF_MODULE_ID_WMA, 9675 QDF_MODULE_ID_WMA, &message); 9676 if (!QDF_IS_STATUS_SUCCESS(status)) { 9677 sme_err("scheduler_post_msg failed!(err=%d)", 9678 status); 9679 qdf_mem_free(req_msg); 9680 } 9681 sme_release_global_lock(&mac->sme); 9682 return status; 9683 } 9684 sme_reset_passpoint_list(mac_handle_t mac_handle,struct wifi_passpoint_req_param * params)9685 QDF_STATUS sme_reset_passpoint_list(mac_handle_t mac_handle, 9686 struct wifi_passpoint_req_param *params) 9687 { 9688 QDF_STATUS status; 9689 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9690 struct scheduler_msg message = {0}; 9691 struct wifi_passpoint_req_param *req_msg; 9692 9693 SME_ENTER(); 9694 9695 req_msg = qdf_mem_malloc(sizeof(*req_msg)); 9696 if (!req_msg) 9697 return QDF_STATUS_E_NOMEM; 9698 9699 *req_msg = *params; 9700 9701 status = sme_acquire_global_lock(&mac->sme); 9702 if (!QDF_IS_STATUS_SUCCESS(status)) { 9703 sme_err("sme_acquire_global_lock failed!(status=%d)", 9704 status); 9705 qdf_mem_free(req_msg); 9706 return status; 9707 } 9708 9709 /* Serialize the req through MC thread */ 9710 message.bodyptr = req_msg; 9711 message.type = WMA_RESET_PASSPOINT_LIST_REQ; 9712 status = scheduler_post_message(QDF_MODULE_ID_SME, 9713 QDF_MODULE_ID_WMA, 9714 QDF_MODULE_ID_WMA, &message); 9715 if (!QDF_IS_STATUS_SUCCESS(status)) { 9716 sme_err("scheduler_post_msg failed!(err=%d)", 9717 status); 9718 qdf_mem_free(req_msg); 9719 } 9720 sme_release_global_lock(&mac->sme); 9721 return status; 9722 } 9723 sme_ext_scan_register_callback(mac_handle_t mac_handle,ext_scan_ind_cb ext_scan_ind_cb)9724 QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle, 9725 ext_scan_ind_cb ext_scan_ind_cb) 9726 { 9727 QDF_STATUS status; 9728 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9729 9730 status = sme_acquire_global_lock(&mac->sme); 9731 if (QDF_IS_STATUS_SUCCESS(status)) { 9732 mac->sme.ext_scan_ind_cb = ext_scan_ind_cb; 9733 sme_release_global_lock(&mac->sme); 9734 } 9735 return status; 9736 } 9737 #endif /* FEATURE_WLAN_EXTSCAN */ 9738 9739 /** 9740 * sme_send_wisa_params(): Pass WISA mode to WMA 9741 * @mac_handle: Opaque handle to the global MAC context 9742 * @wisa_params: pointer to WISA params struct 9743 * @sessionId: SME session id 9744 * 9745 * Pass WISA params to WMA 9746 * 9747 * Return: QDF_STATUS 9748 */ sme_set_wisa_params(mac_handle_t mac_handle,struct sir_wisa_params * wisa_params)9749 QDF_STATUS sme_set_wisa_params(mac_handle_t mac_handle, 9750 struct sir_wisa_params *wisa_params) 9751 { 9752 QDF_STATUS status = QDF_STATUS_SUCCESS; 9753 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9754 struct scheduler_msg message = {0}; 9755 struct sir_wisa_params *cds_msg_wisa_params; 9756 9757 cds_msg_wisa_params = qdf_mem_malloc(sizeof(struct sir_wisa_params)); 9758 if (!cds_msg_wisa_params) 9759 return QDF_STATUS_E_NOMEM; 9760 9761 *cds_msg_wisa_params = *wisa_params; 9762 status = sme_acquire_global_lock(&mac->sme); 9763 9764 if (QDF_IS_STATUS_ERROR(status)) { 9765 qdf_mem_free(cds_msg_wisa_params); 9766 return QDF_STATUS_E_FAILURE; 9767 } 9768 message.bodyptr = cds_msg_wisa_params; 9769 message.type = WMA_SET_WISA_PARAMS; 9770 status = scheduler_post_message(QDF_MODULE_ID_SME, 9771 QDF_MODULE_ID_WMA, 9772 QDF_MODULE_ID_WMA, &message); 9773 if (QDF_IS_STATUS_ERROR(status)) 9774 qdf_mem_free(cds_msg_wisa_params); 9775 sme_release_global_lock(&mac->sme); 9776 return status; 9777 } 9778 9779 #ifdef WLAN_FEATURE_LINK_LAYER_STATS 9780 sme_radio_tx_mem_free(void)9781 void sme_radio_tx_mem_free(void) 9782 { 9783 tp_wma_handle wma_handle; 9784 9785 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 9786 9787 if (!wma_handle) { 9788 sme_err("Invalid wma handle"); 9789 return; 9790 } 9791 wma_unified_radio_tx_mem_free(wma_handle); 9792 } 9793 9794 /* 9795 * sme_ll_stats_clear_req() - 9796 * SME API to clear Link Layer Statistics 9797 * 9798 * mac_handle 9799 * pclearStatsReq: Link Layer clear stats request params structure 9800 * Return QDF_STATUS 9801 */ sme_ll_stats_clear_req(mac_handle_t mac_handle,tSirLLStatsClearReq * pclearStatsReq)9802 QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle, 9803 tSirLLStatsClearReq *pclearStatsReq) 9804 { 9805 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9806 struct scheduler_msg message = {0}; 9807 tSirLLStatsClearReq *clear_stats_req; 9808 9809 sme_debug("staId = %u statsClearReqMask = 0x%X stopReq = %u", 9810 pclearStatsReq->staId, pclearStatsReq->statsClearReqMask, 9811 pclearStatsReq->stopReq); 9812 if (!sme_is_session_id_valid(mac_handle, pclearStatsReq->staId)) { 9813 sme_err("invalid staId %d", pclearStatsReq->staId); 9814 return QDF_STATUS_E_INVAL; 9815 } 9816 9817 clear_stats_req = qdf_mem_malloc(sizeof(*clear_stats_req)); 9818 if (!clear_stats_req) 9819 return QDF_STATUS_E_NOMEM; 9820 9821 *clear_stats_req = *pclearStatsReq; 9822 9823 /* Serialize the req through MC thread */ 9824 message.bodyptr = clear_stats_req; 9825 message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ; 9826 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9827 NO_SESSION, message.type)); 9828 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 9829 QDF_MODULE_ID_WMA, 9830 QDF_MODULE_ID_WMA, 9831 &message); 9832 if (QDF_IS_STATUS_ERROR(qdf_status)) { 9833 sme_err("not able to post WMA_LL_STATS_CLEAR_REQ"); 9834 qdf_mem_free(clear_stats_req); 9835 } 9836 9837 return qdf_status; 9838 } 9839 9840 /* 9841 * sme_ll_stats_set_req() - 9842 * SME API to set the Link Layer Statistics 9843 * 9844 * mac_handle 9845 * psetStatsReq: Link Layer set stats request params structure 9846 * Return QDF_STATUS 9847 */ sme_ll_stats_set_req(mac_handle_t mac_handle,tSirLLStatsSetReq * psetStatsReq)9848 QDF_STATUS sme_ll_stats_set_req(mac_handle_t mac_handle, tSirLLStatsSetReq 9849 *psetStatsReq) 9850 { 9851 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 9852 struct scheduler_msg message = {0}; 9853 tSirLLStatsSetReq *set_stats_req; 9854 9855 sme_debug("MPDU Size = %u Aggressive Stats Collections = %u", 9856 psetStatsReq->mpduSizeThreshold, 9857 psetStatsReq->aggressiveStatisticsGathering); 9858 9859 set_stats_req = qdf_mem_malloc(sizeof(*set_stats_req)); 9860 if (!set_stats_req) 9861 return QDF_STATUS_E_NOMEM; 9862 9863 *set_stats_req = *psetStatsReq; 9864 9865 /* Serialize the req through MC thread */ 9866 message.bodyptr = set_stats_req; 9867 message.type = WMA_LINK_LAYER_STATS_SET_REQ; 9868 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9869 NO_SESSION, message.type)); 9870 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 9871 QDF_MODULE_ID_WMA, 9872 QDF_MODULE_ID_WMA, 9873 &message); 9874 if (QDF_IS_STATUS_ERROR(qdf_status)) { 9875 sme_err("not able to post WMA_LL_STATS_SET_REQ"); 9876 qdf_mem_free(set_stats_req); 9877 } 9878 9879 return qdf_status; 9880 } 9881 sme_ll_stats_get_req(mac_handle_t mac_handle,tSirLLStatsGetReq * get_stats_req,void * context)9882 QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle, 9883 tSirLLStatsGetReq *get_stats_req, 9884 void *context) 9885 { 9886 QDF_STATUS status; 9887 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9888 struct scheduler_msg message = {0}; 9889 tSirLLStatsGetReq *ll_stats_get_req; 9890 9891 ll_stats_get_req = qdf_mem_malloc(sizeof(*ll_stats_get_req)); 9892 if (!ll_stats_get_req) 9893 return QDF_STATUS_E_NOMEM; 9894 9895 *ll_stats_get_req = *get_stats_req; 9896 9897 mac->sme.ll_stats_context = context; 9898 /* Serialize the req through MC thread */ 9899 message.bodyptr = ll_stats_get_req; 9900 message.type = WMA_LINK_LAYER_STATS_GET_REQ; 9901 qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 9902 NO_SESSION, message.type); 9903 status = scheduler_post_message(QDF_MODULE_ID_SME, 9904 QDF_MODULE_ID_WMA, 9905 QDF_MODULE_ID_WMA, &message); 9906 if (QDF_IS_STATUS_ERROR(status)) { 9907 sme_err("Not able to post WMA_LL_STATS_GET_REQ"); 9908 qdf_mem_free(ll_stats_get_req); 9909 } 9910 9911 return status; 9912 } 9913 sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle,link_layer_stats_cb callback)9914 QDF_STATUS sme_set_link_layer_stats_ind_cb(mac_handle_t mac_handle, 9915 link_layer_stats_cb callback) 9916 { 9917 QDF_STATUS status; 9918 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9919 9920 status = sme_acquire_global_lock(&mac->sme); 9921 if (QDF_IS_STATUS_SUCCESS(status)) { 9922 mac->sme.link_layer_stats_cb = callback; 9923 sme_release_global_lock(&mac->sme); 9924 } else { 9925 sme_err("sme_acquire_global_lock error"); 9926 } 9927 9928 return status; 9929 } 9930 9931 /** 9932 * sme_set_link_layer_ext_cb() - Register callback for link layer statistics 9933 * @mac_handle: Mac global handle 9934 * @ll_stats_ext_cb: HDD callback which needs to be invoked after getting 9935 * status notification from FW 9936 * 9937 * Return: QDF_STATUS 9938 */ 9939 QDF_STATUS sme_set_link_layer_ext_cb(mac_handle_t mac_handle,void (* ll_stats_ext_cb)(hdd_handle_t callback_ctx,tSirLLStatsResults * rsp))9940 sme_set_link_layer_ext_cb(mac_handle_t mac_handle, 9941 void (*ll_stats_ext_cb)(hdd_handle_t callback_ctx, 9942 tSirLLStatsResults *rsp)) 9943 { 9944 QDF_STATUS status; 9945 struct mac_context *mac = MAC_CONTEXT(mac_handle); 9946 9947 status = sme_acquire_global_lock(&mac->sme); 9948 if (status == QDF_STATUS_SUCCESS) { 9949 mac->sme.link_layer_stats_ext_cb = ll_stats_ext_cb; 9950 sme_release_global_lock(&mac->sme); 9951 } else 9952 sme_err("sme_qcquire_global_lock error"); 9953 return status; 9954 } 9955 9956 /** 9957 * sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats 9958 * indication 9959 * @mac_handle: Opaque handle to the global MAC context 9960 * 9961 * This function reset's the link layer stats indication 9962 * 9963 * Return: QDF_STATUS Enumeration 9964 */ 9965 sme_reset_link_layer_stats_ind_cb(mac_handle_t mac_handle)9966 QDF_STATUS sme_reset_link_layer_stats_ind_cb(mac_handle_t mac_handle) 9967 { 9968 QDF_STATUS status; 9969 struct mac_context *pmac; 9970 9971 if (!mac_handle) { 9972 sme_err("mac_handle is not valid"); 9973 return QDF_STATUS_E_INVAL; 9974 } 9975 pmac = MAC_CONTEXT(mac_handle); 9976 9977 status = sme_acquire_global_lock(&pmac->sme); 9978 if (QDF_IS_STATUS_SUCCESS(status)) { 9979 pmac->sme.link_layer_stats_cb = NULL; 9980 sme_release_global_lock(&pmac->sme); 9981 } else 9982 sme_err("sme_acquire_global_lock error"); 9983 9984 return status; 9985 } 9986 9987 /** 9988 * sme_ll_stats_set_thresh - set threshold for mac counters 9989 * @mac_handle: Opaque handle to the global MAC context 9990 * @threshold, threshold for mac counters 9991 * 9992 * Return: QDF_STATUS Enumeration 9993 */ sme_ll_stats_set_thresh(mac_handle_t mac_handle,struct sir_ll_ext_stats_threshold * threshold)9994 QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle, 9995 struct sir_ll_ext_stats_threshold *threshold) 9996 { 9997 QDF_STATUS status; 9998 struct scheduler_msg message = {0}; 9999 struct sir_ll_ext_stats_threshold *thresh; 10000 10001 if (!threshold) { 10002 sme_err("threshold is not valid"); 10003 return QDF_STATUS_E_INVAL; 10004 } 10005 10006 if (!mac_handle) { 10007 sme_err("mac_handle is not valid"); 10008 return QDF_STATUS_E_INVAL; 10009 } 10010 10011 thresh = qdf_mem_malloc(sizeof(*thresh)); 10012 if (!thresh) 10013 return QDF_STATUS_E_NOMEM; 10014 10015 *thresh = *threshold; 10016 10017 /* Serialize the req through MC thread */ 10018 message.bodyptr = thresh; 10019 message.type = WDA_LINK_LAYER_STATS_SET_THRESHOLD; 10020 MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, 10021 NO_SESSION, message.type)); 10022 status = scheduler_post_message(QDF_MODULE_ID_SME, 10023 QDF_MODULE_ID_WMA, 10024 QDF_MODULE_ID_WMA, &message); 10025 if (QDF_IS_STATUS_ERROR(status)) { 10026 sme_err("not able to post WDA_LL_STATS_GET_REQ"); 10027 qdf_mem_free(thresh); 10028 } 10029 10030 return status; 10031 } 10032 10033 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ 10034 10035 #ifdef WLAN_POWER_DEBUG sme_reset_power_debug_stats_cb(mac_handle_t mac_handle)10036 void sme_reset_power_debug_stats_cb(mac_handle_t mac_handle) 10037 { 10038 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10039 QDF_STATUS status = QDF_STATUS_SUCCESS; 10040 10041 status = sme_acquire_global_lock(&mac_ctx->sme); 10042 if (QDF_IS_STATUS_SUCCESS(status)) { 10043 mac_ctx->sme.power_debug_stats_context = NULL; 10044 mac_ctx->sme.power_stats_resp_callback = NULL; 10045 sme_release_global_lock(&mac_ctx->sme); 10046 } 10047 } 10048 sme_power_debug_stats_req(mac_handle_t mac_handle,void (* callback_fn)(struct power_stats_response * response,void * context),void * power_stats_context)10049 QDF_STATUS sme_power_debug_stats_req( 10050 mac_handle_t mac_handle, 10051 void (*callback_fn)(struct power_stats_response *response, 10052 void *context), 10053 void *power_stats_context) 10054 { 10055 QDF_STATUS status = QDF_STATUS_SUCCESS; 10056 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10057 struct scheduler_msg msg = {0}; 10058 10059 status = sme_acquire_global_lock(&mac_ctx->sme); 10060 if (QDF_IS_STATUS_SUCCESS(status)) { 10061 if (!callback_fn) { 10062 sme_err("Indication callback did not registered"); 10063 sme_release_global_lock(&mac_ctx->sme); 10064 return QDF_STATUS_E_FAILURE; 10065 } 10066 10067 if (mac_ctx->sme.power_debug_stats_context || 10068 mac_ctx->sme.power_stats_resp_callback) { 10069 sme_err("Already one power stats req in progress"); 10070 sme_release_global_lock(&mac_ctx->sme); 10071 return QDF_STATUS_E_ALREADY; 10072 } 10073 mac_ctx->sme.power_debug_stats_context = power_stats_context; 10074 mac_ctx->sme.power_stats_resp_callback = callback_fn; 10075 msg.bodyptr = NULL; 10076 msg.type = WMA_POWER_DEBUG_STATS_REQ; 10077 status = scheduler_post_message(QDF_MODULE_ID_SME, 10078 QDF_MODULE_ID_WMA, 10079 QDF_MODULE_ID_WMA, &msg); 10080 if (!QDF_IS_STATUS_SUCCESS(status)) 10081 sme_err("not able to post WDA_POWER_DEBUG_STATS_REQ"); 10082 sme_release_global_lock(&mac_ctx->sme); 10083 } 10084 return status; 10085 } 10086 #endif 10087 10088 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS sme_beacon_debug_stats_req(mac_handle_t mac_handle,uint32_t vdev_id,void (* callback_fn)(struct bcn_reception_stats_rsp * response,void * context),void * beacon_stats_context)10089 QDF_STATUS sme_beacon_debug_stats_req( 10090 mac_handle_t mac_handle, uint32_t vdev_id, 10091 void (*callback_fn)(struct bcn_reception_stats_rsp 10092 *response, void *context), 10093 void *beacon_stats_context) 10094 { 10095 QDF_STATUS status; 10096 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10097 uint32_t *val; 10098 struct scheduler_msg msg = {0}; 10099 10100 status = sme_acquire_global_lock(&mac_ctx->sme); 10101 if (QDF_IS_STATUS_SUCCESS(status)) { 10102 if (!callback_fn) { 10103 sme_err("Indication callback did not registered"); 10104 sme_release_global_lock(&mac_ctx->sme); 10105 return QDF_STATUS_E_FAILURE; 10106 } 10107 10108 if (!mac_ctx->bcn_reception_stats && 10109 !mac_ctx->mlme_cfg->gen.enable_beacon_reception_stats) { 10110 sme_err("Beacon Reception stats not supported"); 10111 sme_release_global_lock(&mac_ctx->sme); 10112 return QDF_STATUS_E_NOSUPPORT; 10113 } 10114 10115 val = qdf_mem_malloc(sizeof(*val)); 10116 if (!val) { 10117 sme_release_global_lock(&mac_ctx->sme); 10118 return QDF_STATUS_E_NOMEM; 10119 } 10120 10121 *val = vdev_id; 10122 mac_ctx->sme.beacon_stats_context = beacon_stats_context; 10123 mac_ctx->sme.beacon_stats_resp_callback = callback_fn; 10124 msg.bodyptr = val; 10125 msg.type = WMA_BEACON_DEBUG_STATS_REQ; 10126 status = scheduler_post_message(QDF_MODULE_ID_SME, 10127 QDF_MODULE_ID_WMA, 10128 QDF_MODULE_ID_WMA, &msg); 10129 if (!QDF_IS_STATUS_SUCCESS(status)) { 10130 sme_err("not able to post WMA_BEACON_DEBUG_STATS_REQ"); 10131 qdf_mem_free(val); 10132 } 10133 sme_release_global_lock(&mac_ctx->sme); 10134 } 10135 return status; 10136 } 10137 #endif 10138 10139 /** 10140 * sme_get_temperature() - SME API to get the pdev temperature 10141 * @mac_handle: Handle to global MAC context 10142 * @cb_context: temperature callback context 10143 * @cb: callback function with response (temperature) 10144 * Return: QDF_STATUS 10145 */ sme_get_temperature(mac_handle_t mac_handle,void * cb_context,void (* cb)(int temperature,void * context))10146 QDF_STATUS sme_get_temperature(mac_handle_t mac_handle, 10147 void *cb_context, 10148 void (*cb)(int temperature, 10149 void *context)) 10150 { 10151 QDF_STATUS status = QDF_STATUS_SUCCESS; 10152 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 10153 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10154 struct scheduler_msg message = {0}; 10155 10156 status = sme_acquire_global_lock(&mac->sme); 10157 if (QDF_STATUS_SUCCESS == status) { 10158 if ((!cb) && 10159 (!mac->sme.temperature_cb)) { 10160 sme_err("Indication Call back did not registered"); 10161 sme_release_global_lock(&mac->sme); 10162 return QDF_STATUS_E_FAILURE; 10163 } else if (cb) { 10164 mac->sme.temperature_cb_context = cb_context; 10165 mac->sme.temperature_cb = cb; 10166 } 10167 /* serialize the req through MC thread */ 10168 message.bodyptr = NULL; 10169 message.type = WMA_GET_TEMPERATURE_REQ; 10170 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 10171 QDF_MODULE_ID_WMA, 10172 QDF_MODULE_ID_WMA, 10173 &message); 10174 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 10175 sme_err("Post Get Temperature msg fail"); 10176 status = QDF_STATUS_E_FAILURE; 10177 } 10178 sme_release_global_lock(&mac->sme); 10179 } 10180 return status; 10181 } 10182 sme_set_scanning_mac_oui(mac_handle_t mac_handle,struct scan_mac_oui * scan_mac_oui)10183 QDF_STATUS sme_set_scanning_mac_oui(mac_handle_t mac_handle, 10184 struct scan_mac_oui *scan_mac_oui) 10185 { 10186 QDF_STATUS status = QDF_STATUS_SUCCESS; 10187 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10188 struct scheduler_msg message = {0}; 10189 struct scan_mac_oui *bodyptr; 10190 10191 /* per contract must make a copy of the params when messaging */ 10192 bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); 10193 if (!bodyptr) 10194 return QDF_STATUS_E_NOMEM; 10195 *bodyptr = *scan_mac_oui; 10196 10197 status = sme_acquire_global_lock(&mac->sme); 10198 if (QDF_STATUS_SUCCESS == status) { 10199 /* Serialize the req through MC thread */ 10200 message.bodyptr = bodyptr; 10201 message.type = WMA_SET_SCAN_MAC_OUI_REQ; 10202 status = scheduler_post_message(QDF_MODULE_ID_SME, 10203 QDF_MODULE_ID_WMA, 10204 QDF_MODULE_ID_WMA, 10205 &message); 10206 sme_release_global_lock(&mac->sme); 10207 } 10208 10209 if (QDF_IS_STATUS_ERROR(status)) { 10210 sme_err("failure: %d", status); 10211 qdf_mem_free(bodyptr); 10212 } 10213 10214 return status; 10215 } 10216 10217 #ifdef DHCP_SERVER_OFFLOAD 10218 QDF_STATUS sme_set_dhcp_srv_offload(mac_handle_t mac_handle,struct dhcp_offload_info_params * dhcp_srv_info)10219 sme_set_dhcp_srv_offload(mac_handle_t mac_handle, 10220 struct dhcp_offload_info_params *dhcp_srv_info) 10221 { 10222 struct scheduler_msg message = {0}; 10223 struct dhcp_offload_info_params *payload; 10224 QDF_STATUS status = QDF_STATUS_SUCCESS; 10225 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10226 10227 payload = qdf_mem_malloc(sizeof(*payload)); 10228 if (!payload) 10229 return QDF_STATUS_E_NOMEM; 10230 10231 *payload = *dhcp_srv_info; 10232 10233 status = sme_acquire_global_lock(&mac->sme); 10234 if (QDF_STATUS_SUCCESS == status) { 10235 /* serialize the req through MC thread */ 10236 message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD; 10237 message.bodyptr = payload; 10238 10239 if (!QDF_IS_STATUS_SUCCESS 10240 (scheduler_post_message(QDF_MODULE_ID_SME, 10241 QDF_MODULE_ID_WMA, 10242 QDF_MODULE_ID_WMA, 10243 &message))) { 10244 sme_err("WMA_SET_DHCP_SERVER_OFFLOAD_CMD failed"); 10245 qdf_mem_free(payload); 10246 status = QDF_STATUS_E_FAILURE; 10247 } 10248 sme_release_global_lock(&mac->sme); 10249 } else { 10250 sme_err("sme_acquire_global_lock error!"); 10251 qdf_mem_free(payload); 10252 } 10253 10254 return status; 10255 } 10256 #endif /* DHCP_SERVER_OFFLOAD */ 10257 sme_send_unit_test_cmd(uint32_t vdev_id,uint32_t module_id,uint32_t arg_count,uint32_t * arg)10258 QDF_STATUS sme_send_unit_test_cmd(uint32_t vdev_id, uint32_t module_id, 10259 uint32_t arg_count, uint32_t *arg) 10260 { 10261 return wma_form_unit_test_cmd_and_send(vdev_id, module_id, 10262 arg_count, arg); 10263 } 10264 10265 #ifdef WLAN_FEATURE_GPIO_LED_FLASHING 10266 /* 10267 * sme_set_led_flashing() - 10268 * API to set the Led flashing parameters. 10269 * 10270 * mac_handle - The handle returned by mac_open. 10271 * x0, x1 - led flashing parameters 10272 * Return QDF_STATUS 10273 */ sme_set_led_flashing(mac_handle_t mac_handle,uint8_t type,uint32_t x0,uint32_t x1)10274 QDF_STATUS sme_set_led_flashing(mac_handle_t mac_handle, uint8_t type, 10275 uint32_t x0, uint32_t x1) 10276 { 10277 QDF_STATUS status; 10278 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10279 struct scheduler_msg message = {0}; 10280 struct flashing_req_params *ledflashing; 10281 10282 ledflashing = qdf_mem_malloc(sizeof(*ledflashing)); 10283 if (!ledflashing) 10284 return QDF_STATUS_E_NOMEM; 10285 10286 ledflashing->req_id = 0; 10287 ledflashing->pattern_id = type; 10288 ledflashing->led_x0 = x0; 10289 ledflashing->led_x1 = x1; 10290 10291 status = sme_acquire_global_lock(&mac->sme); 10292 if (QDF_IS_STATUS_SUCCESS(status)) { 10293 /* Serialize the req through MC thread */ 10294 message.bodyptr = ledflashing; 10295 message.type = WMA_LED_FLASHING_REQ; 10296 status = scheduler_post_message(QDF_MODULE_ID_SME, 10297 QDF_MODULE_ID_WMA, 10298 QDF_MODULE_ID_WMA, &message); 10299 sme_release_global_lock(&mac->sme); 10300 } 10301 if (!QDF_IS_STATUS_SUCCESS(status)) 10302 qdf_mem_free(ledflashing); 10303 10304 return status; 10305 } 10306 #endif 10307 10308 /** 10309 * sme_enable_dfS_chan_scan() - set DFS channel scan enable/disable 10310 * @mac_handle: corestack handler 10311 * @dfs_flag: flag indicating dfs channel enable/disable 10312 * Return: QDF_STATUS 10313 */ sme_enable_dfs_chan_scan(mac_handle_t mac_handle,uint8_t dfs_flag)10314 QDF_STATUS sme_enable_dfs_chan_scan(mac_handle_t mac_handle, uint8_t dfs_flag) 10315 { 10316 QDF_STATUS status = QDF_STATUS_SUCCESS; 10317 struct mac_context *mac; 10318 10319 if (!mac_handle) { 10320 sme_err("mac_handle is NULL"); 10321 return QDF_STATUS_E_INVAL; 10322 } 10323 10324 mac = MAC_CONTEXT(mac_handle); 10325 10326 mac->scan.fEnableDFSChnlScan = dfs_flag; 10327 10328 return status; 10329 } 10330 10331 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 10332 /** 10333 * sme_validate_sap_channel_switch() - validate target channel switch w.r.t 10334 * concurreny rules set to avoid channel interference. 10335 * @mac_handle: Opaque handle to the global MAC context 10336 * @sap_ch - channel to switch 10337 * @sap_phy_mode - phy mode of SAP 10338 * @cc_switch_mode - concurreny switch mode 10339 * @vdev_id - vdev id. 10340 * 10341 * Return: true if there is no channel interference else return false 10342 */ sme_validate_sap_channel_switch(mac_handle_t mac_handle,uint32_t sap_ch_freq,eCsrPhyMode sap_phy_mode,uint8_t cc_switch_mode,uint8_t vdev_id)10343 bool sme_validate_sap_channel_switch(mac_handle_t mac_handle, 10344 uint32_t sap_ch_freq, 10345 eCsrPhyMode sap_phy_mode, 10346 uint8_t cc_switch_mode, 10347 uint8_t vdev_id) 10348 { 10349 QDF_STATUS status = QDF_STATUS_E_FAILURE; 10350 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10351 struct csr_roam_session *session = CSR_GET_SESSION(mac, vdev_id); 10352 uint16_t intf_channel_freq = 0; 10353 10354 if (!session) 10355 return false; 10356 10357 session->ch_switch_in_progress = true; 10358 status = sme_acquire_global_lock(&mac->sme); 10359 if (QDF_IS_STATUS_SUCCESS(status)) { 10360 intf_channel_freq = csr_check_concurrent_channel_overlap( 10361 mac, sap_ch_freq, sap_phy_mode, cc_switch_mode, 10362 vdev_id); 10363 sme_release_global_lock(&mac->sme); 10364 } else { 10365 sme_err("sme_acquire_global_lock error!"); 10366 session->ch_switch_in_progress = false; 10367 return false; 10368 } 10369 10370 session->ch_switch_in_progress = false; 10371 return (intf_channel_freq == 0) ? true : false; 10372 } 10373 #endif 10374 10375 /** 10376 * sme_configure_stats_avg_factor() - function to config avg. stats factor 10377 * @mac_handle: Opaque handle to the global MAC context 10378 * @session_id: session ID 10379 * @stats_avg_factor: average stats factor 10380 * 10381 * This function configures the stats avg factor in firmware 10382 * 10383 * Return: QDF_STATUS 10384 */ sme_configure_stats_avg_factor(mac_handle_t mac_handle,uint8_t session_id,uint16_t stats_avg_factor)10385 QDF_STATUS sme_configure_stats_avg_factor(mac_handle_t mac_handle, 10386 uint8_t session_id, 10387 uint16_t stats_avg_factor) 10388 { 10389 struct scheduler_msg msg = {0}; 10390 QDF_STATUS status = QDF_STATUS_SUCCESS; 10391 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10392 struct sir_stats_avg_factor *stats_factor; 10393 10394 stats_factor = qdf_mem_malloc(sizeof(*stats_factor)); 10395 if (!stats_factor) 10396 return QDF_STATUS_E_NOMEM; 10397 10398 status = sme_acquire_global_lock(&mac->sme); 10399 10400 if (QDF_STATUS_SUCCESS == status) { 10401 10402 stats_factor->vdev_id = session_id; 10403 stats_factor->stats_avg_factor = stats_avg_factor; 10404 10405 /* serialize the req through MC thread */ 10406 msg.type = SIR_HAL_CONFIG_STATS_FACTOR; 10407 msg.bodyptr = stats_factor; 10408 10409 if (!QDF_IS_STATUS_SUCCESS( 10410 scheduler_post_message(QDF_MODULE_ID_SME, 10411 QDF_MODULE_ID_WMA, 10412 QDF_MODULE_ID_WMA, &msg))) { 10413 sme_err("Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!"); 10414 qdf_mem_free(stats_factor); 10415 status = QDF_STATUS_E_FAILURE; 10416 } 10417 sme_release_global_lock(&mac->sme); 10418 } else { 10419 sme_err("sme_acquire_global_lock error!"); 10420 qdf_mem_free(stats_factor); 10421 } 10422 10423 return status; 10424 } 10425 10426 /** 10427 * sme_configure_guard_time() - function to configure guard time 10428 * @mac_handle: Opaque handle to the global MAC context 10429 * @session_id: session id 10430 * @guard_time: guard time 10431 * 10432 * This function configures the guard time in firmware 10433 * 10434 * Return: QDF_STATUS 10435 */ sme_configure_guard_time(mac_handle_t mac_handle,uint8_t session_id,uint32_t guard_time)10436 QDF_STATUS sme_configure_guard_time(mac_handle_t mac_handle, uint8_t session_id, 10437 uint32_t guard_time) 10438 { 10439 struct scheduler_msg msg = {0}; 10440 QDF_STATUS status = QDF_STATUS_SUCCESS; 10441 struct mac_context *mac = MAC_CONTEXT(mac_handle); 10442 struct sir_guard_time_request *g_time; 10443 10444 g_time = qdf_mem_malloc(sizeof(*g_time)); 10445 if (!g_time) 10446 return QDF_STATUS_E_NOMEM; 10447 10448 status = sme_acquire_global_lock(&mac->sme); 10449 10450 if (QDF_STATUS_SUCCESS == status) { 10451 10452 g_time->vdev_id = session_id; 10453 g_time->guard_time = guard_time; 10454 10455 /* serialize the req through MC thread */ 10456 msg.type = SIR_HAL_CONFIG_GUARD_TIME; 10457 msg.bodyptr = g_time; 10458 10459 if (!QDF_IS_STATUS_SUCCESS( 10460 scheduler_post_message(QDF_MODULE_ID_SME, 10461 QDF_MODULE_ID_WMA, 10462 QDF_MODULE_ID_WMA, &msg))) { 10463 sme_err("Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!"); 10464 qdf_mem_free(g_time); 10465 status = QDF_STATUS_E_FAILURE; 10466 } 10467 sme_release_global_lock(&mac->sme); 10468 } else { 10469 sme_err("sme_acquire_global_lock error!"); 10470 qdf_mem_free(g_time); 10471 } 10472 10473 return status; 10474 } 10475 10476 /* 10477 * sme_wifi_start_logger() - Send the start/stop logging command to WMA 10478 * to either start/stop logging 10479 * @mac_handle: Opaque handle to the global MAC context 10480 * @start_log: Structure containing the wifi start logger params 10481 * 10482 * This function sends the start/stop logging command to WMA 10483 * 10484 * Return: QDF_STATUS_SUCCESS on successful posting 10485 */ sme_wifi_start_logger(mac_handle_t mac_handle,struct sir_wifi_start_log start_log)10486 QDF_STATUS sme_wifi_start_logger(mac_handle_t mac_handle, 10487 struct sir_wifi_start_log start_log) 10488 { 10489 QDF_STATUS status = QDF_STATUS_SUCCESS; 10490 struct scheduler_msg message = {0}; 10491 struct sir_wifi_start_log *req_msg; 10492 uint32_t len; 10493 10494 len = sizeof(*req_msg); 10495 req_msg = qdf_mem_malloc(len); 10496 if (!req_msg) 10497 return QDF_STATUS_E_NOMEM; 10498 10499 req_msg->verbose_level = start_log.verbose_level; 10500 req_msg->is_iwpriv_command = start_log.is_iwpriv_command; 10501 req_msg->ring_id = start_log.ring_id; 10502 req_msg->ini_triggered = start_log.ini_triggered; 10503 req_msg->user_triggered = start_log.user_triggered; 10504 req_msg->size = start_log.size; 10505 req_msg->is_pktlog_buff_clear = start_log.is_pktlog_buff_clear; 10506 10507 message.bodyptr = req_msg; 10508 message.type = SIR_HAL_START_STOP_LOGGING; 10509 status = scheduler_post_message(QDF_MODULE_ID_SME, 10510 QDF_MODULE_ID_WMA, 10511 QDF_MODULE_ID_WMA, &message); 10512 if (!QDF_IS_STATUS_SUCCESS(status)) { 10513 sme_err("scheduler_post_msg failed!(err=%d)", status); 10514 qdf_mem_free(req_msg); 10515 status = QDF_STATUS_E_FAILURE; 10516 } 10517 10518 return status; 10519 } 10520 sme_is_any_session_in_middle_of_roaming(mac_handle_t mac_handle)10521 bool sme_is_any_session_in_middle_of_roaming(mac_handle_t mac_handle) 10522 { 10523 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10524 uint8_t session_id; 10525 10526 for (session_id = 0; session_id < WLAN_MAX_VDEVS; session_id++) { 10527 if (CSR_IS_SESSION_VALID(mac_ctx, session_id) && 10528 wlan_cm_host_roam_in_progress(mac_ctx->psoc, session_id)) 10529 return true; 10530 } 10531 10532 return false; 10533 } 10534 10535 /* 10536 * sme_send_flush_logs_cmd_to_fw() - Flush FW logs 10537 * 10538 * This function is used to send the command that will 10539 * be used to flush the logs in the firmware 10540 * 10541 * Return: QDF_STATUS 10542 */ sme_send_flush_logs_cmd_to_fw(void)10543 QDF_STATUS sme_send_flush_logs_cmd_to_fw(void) 10544 { 10545 QDF_STATUS status; 10546 struct scheduler_msg message = {0}; 10547 10548 /* Serialize the req through MC thread */ 10549 message.bodyptr = NULL; 10550 message.type = SIR_HAL_FLUSH_LOG_TO_FW; 10551 status = scheduler_post_message(QDF_MODULE_ID_SME, 10552 QDF_MODULE_ID_WMA, 10553 QDF_MODULE_ID_WMA, &message); 10554 if (!QDF_IS_STATUS_SUCCESS(status)) { 10555 sme_err("scheduler_post_msg failed!(err=%d)", status); 10556 status = QDF_STATUS_E_FAILURE; 10557 } 10558 return status; 10559 } 10560 sme_enable_uapsd_for_ac(sme_ac_enum_type ac,uint8_t tid,uint8_t pri,uint32_t srvc_int,uint32_t sus_int,enum sme_qos_wmm_dir_type dir,uint8_t psb,uint32_t sessionId,uint32_t delay_interval)10561 QDF_STATUS sme_enable_uapsd_for_ac(sme_ac_enum_type ac, uint8_t tid, 10562 uint8_t pri, uint32_t srvc_int, 10563 uint32_t sus_int, 10564 enum sme_qos_wmm_dir_type dir, 10565 uint8_t psb, uint32_t sessionId, 10566 uint32_t delay_interval) 10567 { 10568 void *wma_handle; 10569 t_wma_trigger_uapsd_params uapsd_params; 10570 enum uapsd_ac access_category; 10571 10572 if (!psb) { 10573 sme_debug("No need to configure auto trigger:psb is 0"); 10574 return QDF_STATUS_SUCCESS; 10575 } 10576 10577 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 10578 if (!wma_handle) 10579 return QDF_STATUS_E_FAILURE; 10580 10581 switch (ac) { 10582 case SME_AC_BK: 10583 access_category = UAPSD_BK; 10584 break; 10585 case SME_AC_BE: 10586 access_category = UAPSD_BE; 10587 break; 10588 case SME_AC_VI: 10589 access_category = UAPSD_VI; 10590 break; 10591 case SME_AC_VO: 10592 access_category = UAPSD_VO; 10593 break; 10594 default: 10595 return QDF_STATUS_E_FAILURE; 10596 } 10597 10598 uapsd_params.wmm_ac = access_category; 10599 uapsd_params.user_priority = pri; 10600 uapsd_params.service_interval = srvc_int; 10601 uapsd_params.delay_interval = delay_interval; 10602 uapsd_params.suspend_interval = sus_int; 10603 10604 if (QDF_STATUS_SUCCESS != 10605 wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) { 10606 sme_err("Failed to Trigger Uapsd params for vdev %d", 10607 sessionId); 10608 return QDF_STATUS_E_FAILURE; 10609 } 10610 return QDF_STATUS_SUCCESS; 10611 } 10612 sme_disable_uapsd_for_ac(sme_ac_enum_type ac,uint32_t sessionId)10613 QDF_STATUS sme_disable_uapsd_for_ac(sme_ac_enum_type ac, uint32_t sessionId) 10614 { 10615 void *wma_handle; 10616 enum uapsd_ac access_category; 10617 10618 switch (ac) { 10619 case SME_AC_BK: 10620 access_category = UAPSD_BK; 10621 break; 10622 case SME_AC_BE: 10623 access_category = UAPSD_BE; 10624 break; 10625 case SME_AC_VI: 10626 access_category = UAPSD_VI; 10627 break; 10628 case SME_AC_VO: 10629 access_category = UAPSD_VO; 10630 break; 10631 default: 10632 return QDF_STATUS_E_FAILURE; 10633 } 10634 10635 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 10636 if (!wma_handle) 10637 return QDF_STATUS_E_FAILURE; 10638 10639 if (QDF_STATUS_SUCCESS != 10640 wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) { 10641 sme_err("Failed to disable uapsd for ac %d for vdev %d", 10642 ac, sessionId); 10643 return QDF_STATUS_E_FAILURE; 10644 } 10645 return QDF_STATUS_SUCCESS; 10646 } 10647 sme_vdev_ht_tx_stbc(struct mac_context * mac_ctx,bool ht_tx_stbc,uint8_t vdev_id)10648 static void sme_vdev_ht_tx_stbc(struct mac_context *mac_ctx, 10649 bool ht_tx_stbc, uint8_t vdev_id) 10650 { 10651 struct wlan_objmgr_vdev *vdev; 10652 struct vdev_mlme_obj *vdev_mlme; 10653 struct wlan_ht_config ht_cap_info; 10654 10655 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, 10656 WLAN_LEGACY_SME_ID); 10657 if (!vdev) 10658 return; 10659 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 10660 if (!vdev_mlme) { 10661 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 10662 return; 10663 } 10664 ht_cap_info.caps = vdev_mlme->proto.ht_info.ht_caps; 10665 10666 ht_cap_info.ht_caps.tx_stbc = ht_tx_stbc; 10667 vdev_mlme->proto.ht_info.ht_caps = ht_cap_info.caps; 10668 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 10669 } 10670 10671 /** 10672 * sme_update_nss() - SME API to change the number for spatial streams 10673 * (1 or 2) 10674 * @mac_handle: Handle returned by mac open 10675 * @nss: Number of spatial streams 10676 * 10677 * This function is used to update the number of spatial streams supported. 10678 * 10679 * Return: Success upon successfully changing nss else failure 10680 * 10681 */ sme_update_nss(mac_handle_t mac_handle,uint8_t nss)10682 QDF_STATUS sme_update_nss(mac_handle_t mac_handle, uint8_t nss) 10683 { 10684 QDF_STATUS status; 10685 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10686 uint32_t i; 10687 struct mlme_ht_capabilities_info *ht_cap_info; 10688 struct mlme_vht_capabilities_info *vht_cap_info; 10689 10690 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; 10691 10692 status = sme_acquire_global_lock(&mac_ctx->sme); 10693 10694 if (QDF_STATUS_SUCCESS == status) { 10695 vht_cap_info->enable2x2 = (nss == 1) ? 0 : 1; 10696 10697 /* get the HT capability info*/ 10698 ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info; 10699 10700 for (i = 0; i < WLAN_MAX_VDEVS; i++) { 10701 if (CSR_IS_SESSION_VALID(mac_ctx, i)) { 10702 sme_vdev_ht_tx_stbc(mac_ctx, 10703 ht_cap_info->tx_stbc, i); 10704 } 10705 } 10706 10707 sme_release_global_lock(&mac_ctx->sme); 10708 } 10709 return status; 10710 } 10711 10712 /** 10713 * sme_update_user_configured_nss() - sets the nss based on user request 10714 * @mac_handle: Opaque handle to the global MAC context 10715 * @nss: number of streams 10716 * 10717 * Return: None 10718 */ sme_update_user_configured_nss(mac_handle_t mac_handle,uint8_t nss)10719 void sme_update_user_configured_nss(mac_handle_t mac_handle, uint8_t nss) 10720 { 10721 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10722 10723 mac_ctx->user_configured_nss = nss; 10724 } 10725 sme_update_tx_bfee_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)10726 int sme_update_tx_bfee_supp(mac_handle_t mac_handle, uint8_t session_id, 10727 uint8_t cfg_val) 10728 { 10729 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10730 10731 mac_ctx->mlme_cfg->vht_caps.vht_cap_info.su_bformee = cfg_val; 10732 10733 return sme_update_he_tx_bfee_supp(mac_handle, session_id, cfg_val); 10734 } 10735 sme_update_tx_bfee_nsts(mac_handle_t mac_handle,uint8_t session_id,uint8_t usr_cfg_val,uint8_t nsts_val)10736 int sme_update_tx_bfee_nsts(mac_handle_t mac_handle, uint8_t session_id, 10737 uint8_t usr_cfg_val, uint8_t nsts_val) 10738 { 10739 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10740 uint8_t nsts_set_val; 10741 struct mlme_vht_capabilities_info *vht_cap_info; 10742 10743 vht_cap_info = &mac_ctx->mlme_cfg->vht_caps.vht_cap_info; 10744 mac_ctx->usr_cfg_tx_bfee_nsts = usr_cfg_val; 10745 if (usr_cfg_val) 10746 nsts_set_val = usr_cfg_val; 10747 else 10748 nsts_set_val = nsts_val; 10749 10750 vht_cap_info->tx_bfee_ant_supp = nsts_set_val; 10751 10752 if (usr_cfg_val) 10753 sme_set_he_tx_bf_cbf_rates(session_id); 10754 10755 return sme_update_he_tx_bfee_nsts(mac_handle, session_id, nsts_set_val); 10756 } 10757 10758 #ifdef WLAN_FEATURE_11BE sme_update_tgt_eht_cap(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg,tDot11fIEeht_cap * eht_cap_ini)10759 void sme_update_tgt_eht_cap(mac_handle_t mac_handle, 10760 struct wma_tgt_cfg *cfg, 10761 tDot11fIEeht_cap *eht_cap_ini) 10762 { 10763 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10764 10765 qdf_mem_copy(&mac_ctx->eht_cap_2g, 10766 &cfg->eht_cap_2g, 10767 sizeof(tDot11fIEeht_cap)); 10768 10769 qdf_mem_copy(&mac_ctx->eht_cap_5g, 10770 &cfg->eht_cap_5g, 10771 sizeof(tDot11fIEeht_cap)); 10772 10773 qdf_mem_copy(&mac_ctx->eht_cap_2g_orig, 10774 &mac_ctx->eht_cap_2g, 10775 sizeof(tDot11fIEeht_cap)); 10776 10777 qdf_mem_copy(&mac_ctx->eht_cap_5g_orig, 10778 &mac_ctx->eht_cap_5g, 10779 sizeof(tDot11fIEeht_cap)); 10780 } 10781 sme_set_eht_bw_cap(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelWidth chwidth)10782 void sme_set_eht_bw_cap(mac_handle_t mac_handle, uint8_t vdev_id, 10783 enum eSirMacHTChannelWidth chwidth) 10784 { 10785 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10786 struct csr_roam_session *session; 10787 10788 session = CSR_GET_SESSION(mac_ctx, vdev_id); 10789 if (!session) { 10790 sme_debug("No session for id %d", vdev_id); 10791 return; 10792 } 10793 sme_debug("Config EHT caps for BW %d", chwidth); 10794 mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.support_320mhz_6ghz = 0; 10795 10796 if (chwidth < eHT_CHANNEL_WIDTH_320MHZ) { 10797 sme_debug("EHT caps config not required for bw: %d", chwidth); 10798 return; 10799 } 10800 10801 mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.support_320mhz_6ghz = 1; 10802 qdf_mem_copy(&mac_ctx->eht_cap_5g, 10803 &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap, 10804 sizeof(tDot11fIEeht_cap)); 10805 10806 csr_update_session_eht_cap(mac_ctx, session); 10807 } 10808 sme_update_eht_om_ctrl_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)10809 int sme_update_eht_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id, 10810 uint8_t cfg_val) 10811 { 10812 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10813 struct csr_roam_session *session; 10814 10815 session = CSR_GET_SESSION(mac_ctx, session_id); 10816 10817 if (!session) { 10818 sme_err("No session for id %d", session_id); 10819 return -EINVAL; 10820 } 10821 mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap.eht_om_ctl = cfg_val; 10822 mac_ctx->eht_cap_2g.eht_om_ctl = cfg_val; 10823 mac_ctx->eht_cap_5g.eht_om_ctl = cfg_val; 10824 10825 csr_update_session_eht_cap(mac_ctx, session); 10826 10827 return 0; 10828 } 10829 #endif 10830 10831 #ifdef WLAN_FEATURE_11AX sme_update_tgt_he_cap(mac_handle_t mac_handle,struct wma_tgt_cfg * cfg,tDot11fIEhe_cap * he_cap_ini)10832 void sme_update_tgt_he_cap(mac_handle_t mac_handle, 10833 struct wma_tgt_cfg *cfg, 10834 tDot11fIEhe_cap *he_cap_ini) 10835 { 10836 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10837 10838 qdf_mem_copy(&mac_ctx->he_cap_2g, 10839 &cfg->he_cap_2g, 10840 sizeof(tDot11fIEhe_cap)); 10841 10842 qdf_mem_copy(&mac_ctx->he_cap_5g, 10843 &cfg->he_cap_5g, 10844 sizeof(tDot11fIEhe_cap)); 10845 10846 if (!mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_pream_puncturing) { 10847 sme_debug("feature is disabled via INI, FW caps 2G:%d, 5G:%d", 10848 mac_ctx->he_cap_2g.rx_pream_puncturing, 10849 mac_ctx->he_cap_5g.rx_pream_puncturing); 10850 10851 mac_ctx->he_cap_2g.rx_pream_puncturing = 0; 10852 mac_ctx->he_cap_5g.rx_pream_puncturing = 0; 10853 } 10854 10855 if (!mac_ctx->mlme_cfg->he_caps.enable_ul_mimo) { 10856 sme_debug("feature is disabled via INI, FW caps 2G:%d, 5G:%d", 10857 mac_ctx->he_cap_2g.ul_mu, mac_ctx->he_cap_5g.ul_mu); 10858 mac_ctx->he_cap_2g.ul_mu = 0; 10859 mac_ctx->he_cap_5g.ul_mu = 0; 10860 } 10861 10862 /* modify HE Caps field according to INI setting */ 10863 mac_ctx->he_cap_2g.bfee_sts_lt_80 = 10864 QDF_MIN(cfg->he_cap_2g.bfee_sts_lt_80, 10865 he_cap_ini->bfee_sts_lt_80); 10866 10867 mac_ctx->he_cap_5g.bfee_sts_lt_80 = 10868 QDF_MIN(cfg->he_cap_5g.bfee_sts_lt_80, 10869 he_cap_ini->bfee_sts_lt_80); 10870 10871 if (!mac_ctx->mlme_cfg->vht_caps.vht_cap_info.enable2x2) { 10872 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS( 10873 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80, 10874 HE_MCS_DISABLE, 2); 10875 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS( 10876 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80, 10877 HE_MCS_DISABLE, 2); 10878 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS( 10879 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80, 10880 HE_MCS_DISABLE, 2); 10881 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = HE_SET_MCS_4_NSS( 10882 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80, 10883 HE_MCS_DISABLE, 2); 10884 } 10885 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS( 10886 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80, 10887 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80); 10888 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS( 10889 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80, 10890 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80); 10891 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS( 10892 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80, 10893 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80); 10894 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS( 10895 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80, 10896 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80); 10897 10898 qdf_mem_copy(&mac_ctx->he_cap_2g_orig, 10899 &mac_ctx->he_cap_2g, 10900 sizeof(tDot11fIEhe_cap)); 10901 10902 qdf_mem_copy(&mac_ctx->he_cap_5g_orig, 10903 &mac_ctx->he_cap_5g, 10904 sizeof(tDot11fIEhe_cap)); 10905 10906 } 10907 sme_update_he_cap_nss(mac_handle_t mac_handle,uint8_t session_id,uint8_t nss)10908 void sme_update_he_cap_nss(mac_handle_t mac_handle, uint8_t session_id, 10909 uint8_t nss) 10910 { 10911 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10912 struct csr_roam_session *csr_session; 10913 uint32_t tx_mcs_map = 0; 10914 uint32_t rx_mcs_map = 0; 10915 uint32_t mcs_map = 0; 10916 10917 if (!nss || (nss > 2)) { 10918 sme_err("invalid Nss value nss %d", nss); 10919 return; 10920 } 10921 csr_session = CSR_GET_SESSION(mac_ctx, session_id); 10922 if (!csr_session) { 10923 sme_err("No session for id %d", session_id); 10924 return; 10925 } 10926 rx_mcs_map = 10927 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80; 10928 tx_mcs_map = 10929 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80; 10930 mcs_map = rx_mcs_map & 0x3; 10931 10932 if (nss == 1) { 10933 tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, HE_MCS_DISABLE, 2); 10934 rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, HE_MCS_DISABLE, 2); 10935 } else { 10936 tx_mcs_map = HE_SET_MCS_4_NSS(tx_mcs_map, mcs_map, 2); 10937 rx_mcs_map = HE_SET_MCS_4_NSS(rx_mcs_map, mcs_map, 2); 10938 } 10939 sme_debug("new HE Nss MCS MAP: Rx 0x%0X, Tx: 0x%0X", 10940 rx_mcs_map, tx_mcs_map); 10941 if (cfg_in_range(CFG_HE_RX_MCS_MAP_LT_80, rx_mcs_map)) 10942 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80 = 10943 rx_mcs_map; 10944 if (cfg_in_range(CFG_HE_TX_MCS_MAP_LT_80, tx_mcs_map)) 10945 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80 = 10946 tx_mcs_map; 10947 if (cfg_in_range(CFG_HE_RX_MCS_MAP_160, rx_mcs_map)) 10948 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 10949 rx_he_mcs_map_160, 10950 &rx_mcs_map, sizeof(uint16_t)); 10951 if (cfg_in_range(CFG_HE_TX_MCS_MAP_160, tx_mcs_map)) 10952 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 10953 tx_he_mcs_map_160, 10954 &tx_mcs_map, sizeof(uint16_t)); 10955 10956 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = rx_mcs_map; 10957 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = tx_mcs_map; 10958 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = rx_mcs_map; 10959 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = tx_mcs_map; 10960 qdf_mem_copy(mac_ctx->he_cap_5g.rx_he_mcs_map_160, 10961 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_160, 10962 sizeof(uint16_t)); 10963 qdf_mem_copy(mac_ctx->he_cap_5g.tx_he_mcs_map_160, 10964 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_160, 10965 sizeof(uint16_t)); 10966 csr_update_session_he_cap(mac_ctx, csr_session); 10967 10968 } 10969 sme_update_he_mcs(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_mcs)10970 int sme_update_he_mcs(mac_handle_t mac_handle, uint8_t session_id, 10971 uint16_t he_mcs) 10972 { 10973 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 10974 struct csr_roam_session *csr_session; 10975 uint16_t mcs_val = 0; 10976 uint16_t mcs_map = HE_MCS_ALL_DISABLED; 10977 uint16_t mcs_map_cfg; 10978 uint8_t nss = 0, i; 10979 uint16_t mcs_mask = 0x3; 10980 10981 csr_session = CSR_GET_SESSION(mac_ctx, session_id); 10982 if (!csr_session) { 10983 sme_err("No session for id %d", session_id); 10984 return -EINVAL; 10985 } 10986 10987 mcs_map_cfg = 10988 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80; 10989 for (nss = 0; nss < VHT_MAX_NSS; nss++) { 10990 if ((mcs_map_cfg & mcs_mask) == mcs_mask) 10991 break; 10992 mcs_mask = (mcs_mask << 2); 10993 } 10994 if (nss > 2) 10995 nss = 2; 10996 10997 if ((he_mcs & 0x3) == HE_MCS_DISABLE) { 10998 sme_err("Invalid HE MCS 0x%0x, can't disable 0-7 for 1ss", 10999 he_mcs); 11000 return -EINVAL; 11001 } 11002 mcs_val = he_mcs & 0x3; 11003 switch (he_mcs) { 11004 case HE_80_MCS0_7: 11005 case HE_80_MCS0_9: 11006 case HE_80_MCS0_11: 11007 for (i = 1; i <= nss; i++) 11008 mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, i); 11009 11010 sme_debug("HE 80 nss: %d, mcs: 0x%0X", nss, mcs_map); 11011 if (cfg_in_range(CFG_HE_TX_MCS_MAP_LT_80, mcs_map)) 11012 mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11013 tx_he_mcs_map_lt_80 = mcs_map; 11014 if (cfg_in_range(CFG_HE_RX_MCS_MAP_LT_80, mcs_map)) 11015 mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11016 rx_he_mcs_map_lt_80 = mcs_map; 11017 mac_ctx->he_cap_2g.tx_he_mcs_map_lt_80 = mcs_map; 11018 mac_ctx->he_cap_2g.rx_he_mcs_map_lt_80 = mcs_map; 11019 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80 = mcs_map; 11020 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80 = mcs_map; 11021 break; 11022 11023 case HE_160_MCS0_7: 11024 case HE_160_MCS0_9: 11025 case HE_160_MCS0_11: 11026 for (i = 1; i <= nss; i++) 11027 mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, i); 11028 11029 sme_debug("HE 160 nss: %d, mcs: 0x%0X", nss, mcs_map); 11030 if (cfg_in_range(CFG_HE_TX_MCS_MAP_160, mcs_map)) 11031 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11032 tx_he_mcs_map_160, &mcs_map, 11033 sizeof(uint16_t)); 11034 if (cfg_in_range(CFG_HE_RX_MCS_MAP_160, mcs_map)) 11035 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11036 rx_he_mcs_map_160, &mcs_map, 11037 sizeof(uint16_t)); 11038 qdf_mem_copy(mac_ctx->he_cap_5g.tx_he_mcs_map_160, 11039 mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11040 tx_he_mcs_map_160, 11041 sizeof(uint16_t)); 11042 qdf_mem_copy(mac_ctx->he_cap_5g.rx_he_mcs_map_160, 11043 mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11044 rx_he_mcs_map_160, 11045 sizeof(uint16_t)); 11046 break; 11047 11048 case HE_80p80_MCS0_7: 11049 case HE_80p80_MCS0_9: 11050 case HE_80p80_MCS0_11: 11051 mcs_map = HE_SET_MCS_4_NSS(mcs_map, mcs_val, 1); 11052 if (cfg_in_range(CFG_HE_TX_MCS_MAP_80_80, mcs_map)) 11053 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11054 tx_he_mcs_map_80_80, &mcs_map, 11055 sizeof(uint16_t)); 11056 if (cfg_in_range(CFG_HE_RX_MCS_MAP_80_80, mcs_map)) 11057 qdf_mem_copy(mac_ctx->mlme_cfg->he_caps.dot11_he_cap. 11058 rx_he_mcs_map_80_80, &mcs_map, 11059 sizeof(uint16_t)); 11060 break; 11061 11062 default: 11063 sme_err("Invalid HE MCS 0x%0x", he_mcs); 11064 return -EINVAL; 11065 } 11066 sme_debug("new HE MCS 0x%0x", mcs_map); 11067 sme_set_vdev_ies_per_band(mac_handle, session_id, QDF_STA_MODE); 11068 csr_update_session_he_cap(mac_ctx, csr_session); 11069 11070 return 0; 11071 } 11072 sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle,bool val)11073 void sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle, bool val) 11074 { 11075 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11076 11077 mac_ctx->usr_cfg_mu_edca_params = val; 11078 } 11079 sme_update_mu_edca_params(mac_handle_t mac_handle,uint8_t session_id)11080 int sme_update_mu_edca_params(mac_handle_t mac_handle, uint8_t session_id) 11081 { 11082 struct scheduler_msg msg = {0}; 11083 QDF_STATUS status; 11084 11085 qdf_mem_zero(&msg, sizeof(msg)); 11086 msg.type = WNI_SME_UPDATE_MU_EDCA_PARAMS; 11087 msg.reserved = 0; 11088 msg.bodyval = session_id; 11089 status = scheduler_post_message(QDF_MODULE_ID_SME, 11090 QDF_MODULE_ID_PE, 11091 QDF_MODULE_ID_PE, &msg); 11092 if (status != QDF_STATUS_SUCCESS) { 11093 sme_err("Not able to post update edca profile"); 11094 return -EIO; 11095 } 11096 11097 return 0; 11098 } 11099 sme_set_he_mu_edca_def_cfg(mac_handle_t mac_handle)11100 void sme_set_he_mu_edca_def_cfg(mac_handle_t mac_handle) 11101 { 11102 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11103 uint8_t i; 11104 11105 sme_debug("Set MU EDCA params to default"); 11106 for (i = 0; i < QCA_WLAN_AC_ALL; i++) { 11107 mac_ctx->usr_mu_edca_params[i].aci.aifsn = MU_EDCA_DEF_AIFSN; 11108 mac_ctx->usr_mu_edca_params[i].aci.aci = i; 11109 mac_ctx->usr_mu_edca_params[i].cw.max = MU_EDCA_DEF_CW_MAX; 11110 mac_ctx->usr_mu_edca_params[i].cw.min = MU_EDCA_DEF_CW_MIN; 11111 mac_ctx->usr_mu_edca_params[i].mu_edca_timer = 11112 MU_EDCA_DEF_TIMER; 11113 } 11114 } 11115 sme_update_he_capabilities(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val,uint8_t cfg_id)11116 int sme_update_he_capabilities(mac_handle_t mac_handle, uint8_t session_id, 11117 uint8_t cfg_val, uint8_t cfg_id) 11118 { 11119 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11120 struct csr_roam_session *session; 11121 tDot11fIEhe_cap *cfg_he_cap; 11122 tDot11fIEhe_cap *he_cap_orig; 11123 11124 session = CSR_GET_SESSION(mac_ctx, session_id); 11125 11126 if (!session) { 11127 sme_err("No session for id %d", session_id); 11128 return -EINVAL; 11129 } 11130 cfg_he_cap = &mac_ctx->mlme_cfg->he_caps.dot11_he_cap; 11131 he_cap_orig = &mac_ctx->mlme_cfg->he_caps.he_cap_orig; 11132 11133 switch (cfg_id) { 11134 case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT: 11135 if (cfg_val) { 11136 mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = false; 11137 cfg_he_cap->broadcast_twt = he_cap_orig->broadcast_twt; 11138 } else { 11139 cfg_he_cap->broadcast_twt = 0; 11140 mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = true; 11141 } 11142 break; 11143 case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS: 11144 if (cfg_val) 11145 cfg_he_cap->rx_ctrl_frame = he_cap_orig->rx_ctrl_frame; 11146 else 11147 cfg_he_cap->rx_ctrl_frame = 0; 11148 break; 11149 case QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX: 11150 if (cfg_val) 11151 cfg_he_cap->rx_pream_puncturing = 11152 he_cap_orig->rx_pream_puncturing; 11153 else 11154 cfg_he_cap->rx_pream_puncturing = 0; 11155 break; 11156 default: 11157 sme_debug("default: Unhandled cfg %d", cfg_id); 11158 return -EINVAL; 11159 } 11160 11161 sme_debug("HE cap: cfg id %d, cfg val %d", cfg_id, cfg_val); 11162 csr_update_session_he_cap(mac_ctx, session); 11163 return 0; 11164 } 11165 sme_update_he_tx_bfee_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11166 int sme_update_he_tx_bfee_supp(mac_handle_t mac_handle, uint8_t session_id, 11167 uint8_t cfg_val) 11168 { 11169 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11170 struct csr_roam_session *session; 11171 11172 session = CSR_GET_SESSION(mac_ctx, session_id); 11173 11174 if (!session) { 11175 sme_err("No session for id %d", session_id); 11176 return -EINVAL; 11177 } 11178 if (cfg_val <= 1) 11179 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_beamformee = cfg_val; 11180 else 11181 return -EINVAL; 11182 11183 csr_update_session_he_cap(mac_ctx, session); 11184 return 0; 11185 } 11186 sme_update_he_trigger_frm_mac_pad(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11187 int sme_update_he_trigger_frm_mac_pad(mac_handle_t mac_handle, 11188 uint8_t session_id, 11189 uint8_t cfg_val) 11190 { 11191 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11192 struct csr_roam_session *session; 11193 11194 session = CSR_GET_SESSION(mac_ctx, session_id); 11195 11196 if (!session) { 11197 sme_err("No session for id %d", session_id); 11198 return -EINVAL; 11199 } 11200 if (cfg_in_range(CFG_HE_TRIG_PAD, cfg_val)) 11201 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.trigger_frm_mac_pad = 11202 cfg_val; 11203 else 11204 return -EINVAL; 11205 11206 csr_update_session_he_cap(mac_ctx, session); 11207 return 0; 11208 11209 } 11210 sme_update_he_om_ctrl_supp(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11211 int sme_update_he_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id, 11212 uint8_t cfg_val) 11213 { 11214 11215 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11216 struct csr_roam_session *session; 11217 11218 session = CSR_GET_SESSION(mac_ctx, session_id); 11219 11220 if (!session) { 11221 sme_err("No session for id %d", session_id); 11222 return -EINVAL; 11223 } 11224 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.omi_a_ctrl = cfg_val; 11225 mac_ctx->he_cap_2g.omi_a_ctrl = cfg_val; 11226 mac_ctx->he_cap_5g.omi_a_ctrl = cfg_val; 11227 11228 csr_update_session_he_cap(mac_ctx, session); 11229 return 0; 11230 } 11231 sme_update_he_htc_he_supp(mac_handle_t mac_handle,uint8_t session_id,bool cfg_val)11232 int sme_update_he_htc_he_supp(mac_handle_t mac_handle, uint8_t session_id, 11233 bool cfg_val) 11234 { 11235 11236 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11237 struct csr_roam_session *session; 11238 11239 session = CSR_GET_SESSION(mac_ctx, session_id); 11240 11241 if (!session) { 11242 sme_err("No session for id %d", session_id); 11243 return -EINVAL; 11244 } 11245 11246 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.htc_he = cfg_val; 11247 csr_update_session_he_cap(mac_ctx, session); 11248 11249 return 0; 11250 } 11251 11252 static QDF_STATUS sme_validate_session_for_cap_update(struct mac_context * mac_ctx,uint8_t session_id,struct csr_roam_session * session)11253 sme_validate_session_for_cap_update(struct mac_context *mac_ctx, 11254 uint8_t session_id, 11255 struct csr_roam_session *session) 11256 { 11257 if (!session) { 11258 sme_err("Session does not exist, Session_id: %d", session_id); 11259 return QDF_STATUS_E_INVAL; 11260 } 11261 11262 if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) { 11263 sme_debug("STA is not connected, Session_id: %d", session_id); 11264 return QDF_STATUS_E_INVAL; 11265 } 11266 11267 return QDF_STATUS_SUCCESS; 11268 } 11269 sme_send_he_om_ctrl_update(mac_handle_t mac_handle,uint8_t session_id,struct omi_ctrl_tx * omi_data)11270 int sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id, 11271 struct omi_ctrl_tx *omi_data) 11272 { 11273 QDF_STATUS status = QDF_STATUS_SUCCESS; 11274 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11275 void *wma_handle; 11276 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); 11277 uint32_t param_val = 0; 11278 qdf_freq_t op_chan_freq; 11279 qdf_freq_t freq_seg_0; 11280 enum phy_ch_width ch_width; 11281 struct qdf_mac_addr connected_bssid; 11282 11283 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 11284 if (!wma_handle) 11285 return -EIO; 11286 11287 status = sme_validate_session_for_cap_update(mac_ctx, session_id, 11288 session); 11289 if (QDF_IS_STATUS_ERROR(status)) 11290 return -EINVAL; 11291 11292 wlan_get_op_chan_freq_info_vdev_id(mac_ctx->pdev, session_id, 11293 &op_chan_freq, &freq_seg_0, 11294 &ch_width); 11295 11296 if (!omi_data) { 11297 sme_err("OMI data is NULL"); 11298 return -EIO; 11299 } 11300 11301 omi_data->a_ctrl_id = A_CTRL_ID_OMI; 11302 11303 if (mac_ctx->he_om_ctrl_cfg_nss_set) 11304 omi_data->rx_nss = mac_ctx->he_om_ctrl_cfg_nss; 11305 else 11306 omi_data->rx_nss = session->nss - 1; 11307 11308 if (mac_ctx->he_om_ctrl_cfg_tx_nsts_set) 11309 omi_data->tx_nsts = mac_ctx->he_om_ctrl_cfg_tx_nsts; 11310 else 11311 omi_data->tx_nsts = session->nss - 1; 11312 11313 if (mac_ctx->he_om_ctrl_cfg_bw_set) 11314 omi_data->ch_bw = mac_ctx->he_om_ctrl_cfg_bw; 11315 else 11316 omi_data->ch_bw = ch_width; 11317 11318 omi_data->ul_mu_dis = mac_ctx->he_om_ctrl_cfg_ul_mu_dis; 11319 omi_data->ul_mu_data_dis = mac_ctx->he_om_ctrl_ul_mu_data_dis; 11320 omi_data->omi_in_vht = 0x1; 11321 omi_data->omi_in_he = 0x1; 11322 11323 sme_debug("OMI: BW %d TxNSTS %d RxNSS %d ULMU %d, OMI_VHT %d, OMI_HE %d", 11324 omi_data->ch_bw, omi_data->tx_nsts, omi_data->rx_nss, 11325 omi_data->ul_mu_dis, omi_data->omi_in_vht, 11326 omi_data->omi_in_he); 11327 sme_debug("EHT OMI: BW %d rx nss %d tx nss %d", omi_data->eht_ch_bw_ext, 11328 omi_data->eht_rx_nss_ext, omi_data->eht_tx_nss_ext); 11329 11330 qdf_mem_copy(¶m_val, omi_data, sizeof(param_val)); 11331 wlan_mlme_get_bssid_vdev_id(mac_ctx->pdev, session_id, 11332 &connected_bssid); 11333 sme_debug("param val %08X, bssid:"QDF_MAC_ADDR_FMT, param_val, 11334 QDF_MAC_ADDR_REF(connected_bssid.bytes)); 11335 status = wma_set_peer_param(wma_handle, 11336 connected_bssid.bytes, 11337 WMI_PEER_PARAM_XMIT_OMI, 11338 param_val, session_id); 11339 if (QDF_STATUS_SUCCESS != status) { 11340 sme_err("set_peer_param_cmd returned %d", status); 11341 return -EIO; 11342 } 11343 11344 return 0; 11345 } 11346 sme_set_he_om_ctrl_param(mac_handle_t mac_handle,uint8_t session_id,enum qca_wlan_vendor_attr_he_omi_tx param,uint8_t cfg_val)11347 int sme_set_he_om_ctrl_param(mac_handle_t mac_handle, uint8_t session_id, 11348 enum qca_wlan_vendor_attr_he_omi_tx param, 11349 uint8_t cfg_val) 11350 { 11351 QDF_STATUS status; 11352 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11353 struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); 11354 qdf_freq_t op_chan_freq; 11355 qdf_freq_t freq_seg_0; 11356 enum phy_ch_width ch_width; 11357 11358 status = sme_validate_session_for_cap_update(mac_ctx, session_id, 11359 session); 11360 if (QDF_IS_STATUS_ERROR(status)) 11361 return -EINVAL; 11362 11363 wlan_get_op_chan_freq_info_vdev_id(mac_ctx->pdev, session_id, 11364 &op_chan_freq, &freq_seg_0, 11365 &ch_width); 11366 11367 switch(param) { 11368 case QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE: 11369 sme_debug("Set OM ctrl UL MU dis to %d", cfg_val); 11370 mac_ctx->he_om_ctrl_cfg_ul_mu_dis = cfg_val; 11371 break; 11372 case QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS: 11373 if ((cfg_val + 1) > session->nss) { 11374 sme_debug("OMI Nss %d is > connected Nss %d", 11375 cfg_val, session->nss); 11376 mac_ctx->he_om_ctrl_cfg_nss_set = false; 11377 return 0; 11378 } 11379 sme_debug("Set OM ctrl Rx Nss cfg to %d", cfg_val); 11380 mac_ctx->he_om_ctrl_cfg_nss_set = true; 11381 mac_ctx->he_om_ctrl_cfg_nss = cfg_val; 11382 break; 11383 case QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW: 11384 if (cfg_val > ch_width) { 11385 sme_debug("OMI BW %d is > connected BW %d", 11386 cfg_val, ch_width); 11387 mac_ctx->he_om_ctrl_cfg_bw_set = false; 11388 return 0; 11389 } 11390 sme_debug("Set OM ctrl BW cfg to %d", cfg_val); 11391 mac_ctx->he_om_ctrl_cfg_bw_set = true; 11392 mac_ctx->he_om_ctrl_cfg_bw = cfg_val; 11393 break; 11394 case QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS: 11395 if ((cfg_val + 1) > session->nss) { 11396 sme_debug("OMI NSTS %d is > connected Nss %d", 11397 cfg_val, session->nss); 11398 mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false; 11399 return 0; 11400 } 11401 sme_debug("Set OM ctrl tx nsts cfg to %d", cfg_val); 11402 mac_ctx->he_om_ctrl_cfg_tx_nsts_set = true; 11403 mac_ctx->he_om_ctrl_cfg_tx_nsts = cfg_val; 11404 break; 11405 case QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE: 11406 sme_debug("Set OM ctrl UL MU data dis to %d", cfg_val); 11407 mac_ctx->he_om_ctrl_ul_mu_data_dis = cfg_val; 11408 break; 11409 default: 11410 sme_debug("Invalid OMI param %d", param); 11411 return -EINVAL; 11412 } 11413 11414 return 0; 11415 } 11416 sme_reset_he_om_ctrl(mac_handle_t mac_handle)11417 void sme_reset_he_om_ctrl(mac_handle_t mac_handle) 11418 { 11419 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11420 11421 mac_ctx->he_om_ctrl_cfg_bw_set = false; 11422 mac_ctx->he_om_ctrl_cfg_nss_set = false; 11423 mac_ctx->he_om_ctrl_cfg_bw = 0; 11424 mac_ctx->he_om_ctrl_cfg_nss = 0; 11425 mac_ctx->he_om_ctrl_cfg_ul_mu_dis = false; 11426 mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false; 11427 mac_ctx->he_om_ctrl_cfg_tx_nsts = 0; 11428 mac_ctx->he_om_ctrl_ul_mu_data_dis = false; 11429 } 11430 sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11431 int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, uint8_t session_id, 11432 uint8_t cfg_val) 11433 { 11434 QDF_STATUS status; 11435 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11436 struct scheduler_msg msg = {0}; 11437 struct sir_cfg_action_frm_tb_ppdu *cfg_msg; 11438 11439 if (!cm_is_vdevid_connected(mac_ctx->pdev, session_id)) { 11440 sme_debug("STA is not connected, Session_id: %d", session_id); 11441 return -EINVAL; 11442 } 11443 11444 cfg_msg = qdf_mem_malloc(sizeof(*cfg_msg)); 11445 if (!cfg_msg) 11446 return -EIO; 11447 11448 cfg_msg->type = WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU; 11449 cfg_msg->vdev_id = session_id; 11450 cfg_msg->cfg = cfg_val; 11451 11452 msg.bodyptr = cfg_msg; 11453 msg.type = WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU; 11454 status = scheduler_post_message(QDF_MODULE_ID_SME, QDF_MODULE_ID_PE, 11455 QDF_MODULE_ID_PE, &msg); 11456 if (QDF_STATUS_SUCCESS != status) { 11457 sme_err("Failed to send CFG_ACTION_FRAME_IN_TB_PPDU to PE %d", 11458 status); 11459 qdf_mem_free(cfg_msg); 11460 return -EIO; 11461 } 11462 11463 return 0; 11464 } 11465 sme_update_he_tx_bfee_nsts(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11466 int sme_update_he_tx_bfee_nsts(mac_handle_t mac_handle, uint8_t session_id, 11467 uint8_t cfg_val) 11468 { 11469 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11470 struct csr_roam_session *session; 11471 11472 session = CSR_GET_SESSION(mac_ctx, session_id); 11473 11474 if (!session) { 11475 sme_err("No session for id %d", session_id); 11476 return -EINVAL; 11477 } 11478 if (cfg_in_range(CFG_HE_BFEE_STS_LT80, cfg_val)) { 11479 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_lt_80 = 11480 cfg_val; 11481 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bfee_sts_gt_80 = 11482 cfg_val; 11483 } else { 11484 return -EINVAL; 11485 } 11486 11487 11488 csr_update_session_he_cap(mac_ctx, session); 11489 return 0; 11490 } 11491 sme_set_he_tx_bf_cbf_rates(uint8_t session_id)11492 void sme_set_he_tx_bf_cbf_rates(uint8_t session_id) 11493 { 11494 uint32_t tx_bf_cbf_rates_5g[] = {91, 1, 0, 3, 2, 4, 0}; 11495 uint32_t tx_bf_cbf_rates_2g[] = {91, 1, 1, 3, 1, 3, 0}; 11496 QDF_STATUS status; 11497 11498 status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7, 11499 tx_bf_cbf_rates_5g); 11500 if (QDF_STATUS_SUCCESS != status) 11501 sme_err("send_unit_test_cmd returned %d", status); 11502 11503 status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 7, 11504 tx_bf_cbf_rates_2g); 11505 if (QDF_STATUS_SUCCESS != status) 11506 sme_err("send_unit_test_cmd returned %d", status); 11507 } 11508 sme_config_su_ppdu_queue(uint8_t session_id,bool enable)11509 void sme_config_su_ppdu_queue(uint8_t session_id, bool enable) 11510 { 11511 uint32_t su_ppdu_enable[] = {69, 1, 1, 1}; 11512 uint32_t su_ppdu_disable[] = {69, 1, 1, 0}; 11513 QDF_STATUS status; 11514 11515 if (enable) { 11516 sme_debug("Send Tx SU PPDU queue ENABLE cmd to FW"); 11517 status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4, 11518 su_ppdu_enable); 11519 } else { 11520 sme_debug("Send Tx SU PPDU queue DISABLE cmd to FW"); 11521 status = wma_form_unit_test_cmd_and_send(session_id, 0x48, 4, 11522 su_ppdu_disable); 11523 } 11524 if (QDF_STATUS_SUCCESS != status) 11525 sme_err("send_unit_test_cmd returned %d", status); 11526 } 11527 sme_update_he_tx_stbc_cap(mac_handle_t mac_handle,uint8_t session_id,int value)11528 int sme_update_he_tx_stbc_cap(mac_handle_t mac_handle, uint8_t session_id, 11529 int value) 11530 { 11531 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11532 struct csr_roam_session *session; 11533 uint32_t he_cap_val = 0; 11534 11535 he_cap_val = value ? 1 : 0; 11536 session = CSR_GET_SESSION(mac_ctx, session_id); 11537 11538 if (!session) { 11539 sme_err("No session for id %d", session_id); 11540 return -EINVAL; 11541 } 11542 if (he_cap_val <= 1) 11543 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tb_ppdu_tx_stbc_lt_80mhz 11544 = he_cap_val; 11545 else 11546 return -EINVAL; 11547 if (he_cap_val <= 1) 11548 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tb_ppdu_tx_stbc_gt_80mhz 11549 = he_cap_val; 11550 else 11551 return -EINVAL; 11552 csr_update_session_he_cap(mac_ctx, session); 11553 return 0; 11554 } 11555 sme_update_he_rx_stbc_cap(mac_handle_t mac_handle,uint8_t session_id,int value)11556 int sme_update_he_rx_stbc_cap(mac_handle_t mac_handle, uint8_t session_id, 11557 int value) 11558 { 11559 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11560 struct csr_roam_session *session; 11561 uint32_t he_cap_val = 0; 11562 11563 he_cap_val = value ? 1 : 0; 11564 session = CSR_GET_SESSION(mac_ctx, session_id); 11565 11566 if (!session) { 11567 sme_err("No session for id %d", session_id); 11568 return -EINVAL; 11569 } 11570 if (he_cap_val <= 1) 11571 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_stbc_lt_80mhz = 11572 he_cap_val; 11573 else 11574 return -EINVAL; 11575 if (he_cap_val <= 1) 11576 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_stbc_gt_80mhz = 11577 he_cap_val; 11578 else 11579 return -EINVAL; 11580 csr_update_session_he_cap(mac_ctx, session); 11581 return 0; 11582 } 11583 sme_update_he_frag_supp(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_frag)11584 int sme_update_he_frag_supp(mac_handle_t mac_handle, uint8_t session_id, 11585 uint16_t he_frag) 11586 { 11587 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11588 struct csr_roam_session *session; 11589 11590 session = CSR_GET_SESSION(mac_ctx, session_id); 11591 11592 if (!session) { 11593 sme_err("No session for id %d", session_id); 11594 return -EINVAL; 11595 } 11596 if (cfg_in_range(CFG_HE_FRAGMENTATION, he_frag)) 11597 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.fragmentation = he_frag; 11598 else 11599 return -EINVAL; 11600 11601 csr_update_session_he_cap(mac_ctx, session); 11602 return 0; 11603 11604 } 11605 sme_update_he_ldpc_supp(mac_handle_t mac_handle,uint8_t session_id,uint16_t he_ldpc)11606 int sme_update_he_ldpc_supp(mac_handle_t mac_handle, uint8_t session_id, 11607 uint16_t he_ldpc) 11608 { 11609 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11610 struct csr_roam_session *session; 11611 11612 session = CSR_GET_SESSION(mac_ctx, session_id); 11613 11614 if (!session) { 11615 sme_err("No session for id %d", session_id); 11616 return -EINVAL; 11617 } 11618 if (he_ldpc <= 1) 11619 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ldpc_coding = he_ldpc; 11620 else 11621 return -EINVAL; 11622 11623 csr_update_session_he_cap(mac_ctx, session); 11624 return 0; 11625 11626 } 11627 sme_update_he_twt_req_support(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11628 int sme_update_he_twt_req_support(mac_handle_t mac_handle, uint8_t session_id, 11629 uint8_t cfg_val) 11630 { 11631 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11632 struct csr_roam_session *session; 11633 11634 session = CSR_GET_SESSION(mac_ctx, session_id); 11635 11636 if (!session) { 11637 sme_err("No session for id %d", session_id); 11638 return -EINVAL; 11639 } 11640 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request = cfg_val; 11641 11642 csr_update_session_he_cap(mac_ctx, session); 11643 11644 return 0; 11645 } 11646 sme_update_he_full_ul_mumimo(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)11647 int sme_update_he_full_ul_mumimo(mac_handle_t mac_handle, uint8_t session_id, 11648 uint8_t cfg_val) 11649 { 11650 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11651 struct csr_roam_session *session; 11652 11653 session = CSR_GET_SESSION(mac_ctx, session_id); 11654 11655 if (!session) { 11656 sme_err("No session for id %d", session_id); 11657 return -EINVAL; 11658 } 11659 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_mu = cfg_val; 11660 11661 csr_update_session_he_cap(mac_ctx, session); 11662 11663 return 0; 11664 } 11665 #endif 11666 11667 QDF_STATUS sme_update_session_txq_edca_params(mac_handle_t mac_handle,uint8_t session_id,tSirMacEdcaParamRecord * txq_edca_params)11668 sme_update_session_txq_edca_params(mac_handle_t mac_handle, 11669 uint8_t session_id, 11670 tSirMacEdcaParamRecord *txq_edca_params) 11671 { 11672 QDF_STATUS status; 11673 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11674 struct sir_update_session_txq_edca_param *msg; 11675 struct pe_session *pe_session; 11676 11677 pe_session = pe_find_session_by_vdev_id(mac_ctx, session_id); 11678 if (!pe_session) { 11679 pe_warn("Session does not exist for given session_id %d", 11680 session_id); 11681 return QDF_STATUS_E_INVAL; 11682 } 11683 11684 status = sme_acquire_global_lock(&mac_ctx->sme); 11685 if (QDF_IS_STATUS_ERROR(status)) 11686 return QDF_STATUS_E_AGAIN; 11687 11688 msg = qdf_mem_malloc(sizeof(*msg)); 11689 if (!msg) { 11690 sme_release_global_lock(&mac_ctx->sme); 11691 return QDF_STATUS_E_NOMEM; 11692 } 11693 11694 msg->message_type = eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS; 11695 msg->vdev_id = session_id; 11696 qdf_mem_copy(&msg->txq_edca_params, txq_edca_params, 11697 sizeof(tSirMacEdcaParamRecord)); 11698 msg->length = sizeof(*msg); 11699 11700 status = umac_send_mb_message_to_mac(msg); 11701 11702 sme_release_global_lock(&mac_ctx->sme); 11703 if (status != QDF_STATUS_SUCCESS) 11704 return QDF_STATUS_E_IO; 11705 11706 pe_session->user_edca_set = 1; 11707 11708 return QDF_STATUS_SUCCESS; 11709 } 11710 11711 /** 11712 * sme_set_nud_debug_stats_cb() - set nud debug stats callback 11713 * @mac_handle: Opaque handle to the global MAC context 11714 * @cb: callback function pointer 11715 * @context: callback context 11716 * 11717 * This function stores nud debug stats callback function. 11718 * 11719 * Return: QDF_STATUS enumeration. 11720 */ sme_set_nud_debug_stats_cb(mac_handle_t mac_handle,void (* cb)(void *,struct rsp_stats *,void *),void * context)11721 QDF_STATUS sme_set_nud_debug_stats_cb(mac_handle_t mac_handle, 11722 void (*cb)(void *, struct rsp_stats *, void *), 11723 void *context) 11724 { 11725 QDF_STATUS status = QDF_STATUS_SUCCESS; 11726 struct mac_context *mac; 11727 11728 if (!mac_handle) { 11729 sme_err("mac_handle is not valid"); 11730 return QDF_STATUS_E_INVAL; 11731 } 11732 mac = MAC_CONTEXT(mac_handle); 11733 11734 status = sme_acquire_global_lock(&mac->sme); 11735 if (!QDF_IS_STATUS_SUCCESS(status)) { 11736 sme_err("sme_acquire_global_lock failed!(status=%d)", 11737 status); 11738 return status; 11739 } 11740 11741 mac->sme.get_arp_stats_cb = cb; 11742 mac->sme.get_arp_stats_context = context; 11743 sme_release_global_lock(&mac->sme); 11744 return status; 11745 } 11746 11747 /** 11748 * sme_is_any_session_in_connected_state() - SME wrapper API to 11749 * check if any session is in connected state or not. 11750 * 11751 * @mac_handle: Handle returned by mac open 11752 * 11753 * This function is used to check if any valid sme session is in 11754 * connected state or not. 11755 * 11756 * Return: true if any session is connected, else false. 11757 * 11758 */ sme_is_any_session_in_connected_state(mac_handle_t mac_handle)11759 bool sme_is_any_session_in_connected_state(mac_handle_t mac_handle) 11760 { 11761 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 11762 QDF_STATUS status; 11763 bool ret = false; 11764 11765 status = sme_acquire_global_lock(&mac_ctx->sme); 11766 if (QDF_STATUS_SUCCESS == status) { 11767 ret = csr_is_any_session_in_connect_state(mac_ctx); 11768 sme_release_global_lock(&mac_ctx->sme); 11769 } 11770 return ret; 11771 } 11772 sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle,pwr_save_fail_cb cb)11773 QDF_STATUS sme_set_chip_pwr_save_fail_cb(mac_handle_t mac_handle, 11774 pwr_save_fail_cb cb) 11775 { 11776 QDF_STATUS status; 11777 struct mac_context *mac = MAC_CONTEXT(mac_handle); 11778 11779 status = sme_acquire_global_lock(&mac->sme); 11780 if (status != QDF_STATUS_SUCCESS) { 11781 sme_err("sme_AcquireGlobalLock failed!(status=%d)", status); 11782 return status; 11783 } 11784 mac->sme.chip_power_save_fail_cb = cb; 11785 sme_release_global_lock(&mac->sme); 11786 return status; 11787 } 11788 11789 #ifdef FEATURE_RSSI_MONITOR 11790 /** 11791 * sme_set_rssi_monitoring() - set rssi monitoring 11792 * @mac_handle: Opaque handle to the global MAC context 11793 * @input: request message 11794 * 11795 * This function constructs the vos message and fill in message type, 11796 * bodyptr with @input and posts it to WDA queue. 11797 * 11798 * Return: QDF_STATUS enumeration 11799 */ sme_set_rssi_monitoring(mac_handle_t mac_handle,struct rssi_monitor_param * input)11800 QDF_STATUS sme_set_rssi_monitoring(mac_handle_t mac_handle, 11801 struct rssi_monitor_param *input) 11802 { 11803 QDF_STATUS status = QDF_STATUS_SUCCESS; 11804 struct mac_context *mac = MAC_CONTEXT(mac_handle); 11805 struct scheduler_msg message = {0}; 11806 struct rssi_monitor_param *req_msg; 11807 11808 SME_ENTER(); 11809 req_msg = qdf_mem_malloc(sizeof(*req_msg)); 11810 if (!req_msg) 11811 return QDF_STATUS_E_NOMEM; 11812 11813 *req_msg = *input; 11814 11815 status = sme_acquire_global_lock(&mac->sme); 11816 if (!QDF_IS_STATUS_SUCCESS(status)) { 11817 sme_err("sme_acquire_global_lock failed!(status=%d)", status); 11818 qdf_mem_free(req_msg); 11819 return status; 11820 } 11821 11822 /* Serialize the req through MC thread */ 11823 message.bodyptr = req_msg; 11824 message.type = WMA_SET_RSSI_MONITOR_REQ; 11825 status = scheduler_post_message(QDF_MODULE_ID_SME, 11826 QDF_MODULE_ID_WMA, 11827 QDF_MODULE_ID_WMA, &message); 11828 if (!QDF_IS_STATUS_SUCCESS(status)) { 11829 sme_err("scheduler_post_msg failed!(err=%d)", status); 11830 qdf_mem_free(req_msg); 11831 } 11832 sme_release_global_lock(&mac->sme); 11833 11834 return status; 11835 } 11836 sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle,rssi_threshold_breached_cb cb)11837 QDF_STATUS sme_set_rssi_threshold_breached_cb(mac_handle_t mac_handle, 11838 rssi_threshold_breached_cb cb) 11839 { 11840 QDF_STATUS status; 11841 struct mac_context *mac; 11842 11843 mac = MAC_CONTEXT(mac_handle); 11844 if (!mac) { 11845 sme_err("Invalid mac context"); 11846 return QDF_STATUS_E_INVAL; 11847 } 11848 11849 status = sme_acquire_global_lock(&mac->sme); 11850 if (!QDF_IS_STATUS_SUCCESS(status)) { 11851 sme_err("sme_acquire_global_lock failed!(status=%d)", 11852 status); 11853 return status; 11854 } 11855 11856 mac->sme.rssi_threshold_breached_cb = cb; 11857 sme_release_global_lock(&mac->sme); 11858 return status; 11859 } 11860 #endif /* FEATURE_RSSI_MONITOR */ 11861 sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle)11862 QDF_STATUS sme_reset_rssi_threshold_breached_cb(mac_handle_t mac_handle) 11863 { 11864 return sme_set_rssi_threshold_breached_cb(mac_handle, NULL); 11865 } 11866 11867 /* 11868 * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA 11869 * @mac_handle: Handle returned by macOpen 11870 * @msg: HW mode structure containing hw mode and callback details 11871 * 11872 * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW 11873 * Return: QDF_STATUS_SUCCESS on successful posting 11874 */ sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg)11875 QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg) 11876 { 11877 QDF_STATUS status = QDF_STATUS_SUCCESS; 11878 struct mac_context *mac = sme_get_mac_context(); 11879 tSmeCmd *cmd = NULL; 11880 11881 if (!mac) { 11882 sme_err("mac is NULL"); 11883 return QDF_STATUS_E_FAILURE; 11884 } 11885 status = sme_acquire_global_lock(&mac->sme); 11886 if (!QDF_IS_STATUS_SUCCESS(status)) { 11887 sme_err("Failed to acquire lock"); 11888 return QDF_STATUS_E_RESOURCES; 11889 } 11890 11891 cmd = csr_get_command_buffer(mac); 11892 if (!cmd) { 11893 sme_err("Get command buffer failed"); 11894 sme_release_global_lock(&mac->sme); 11895 return QDF_STATUS_E_NULL_VALUE; 11896 } 11897 11898 cmd->command = e_sme_command_set_hw_mode; 11899 cmd->vdev_id = msg.session_id; 11900 cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index; 11901 cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb; 11902 cmd->u.set_hw_mode_cmd.reason = msg.reason; 11903 cmd->u.set_hw_mode_cmd.session_id = msg.session_id; 11904 cmd->u.set_hw_mode_cmd.next_action = msg.next_action; 11905 cmd->u.set_hw_mode_cmd.action = msg.action; 11906 cmd->u.set_hw_mode_cmd.context = msg.context; 11907 cmd->u.set_hw_mode_cmd.request_id = msg.request_id; 11908 11909 sme_debug("Queuing set hw mode to CSR, session: %d reason: %d request_id: %x", 11910 cmd->u.set_hw_mode_cmd.session_id, 11911 cmd->u.set_hw_mode_cmd.reason, 11912 cmd->u.set_hw_mode_cmd.request_id); 11913 csr_queue_sme_command(mac, cmd, false); 11914 11915 sme_release_global_lock(&mac->sme); 11916 return QDF_STATUS_SUCCESS; 11917 } 11918 sme_nss_update_request(uint32_t vdev_id,uint8_t new_nss,uint8_t ch_width,policy_mgr_nss_update_cback cback,uint8_t next_action,struct wlan_objmgr_psoc * psoc,enum policy_mgr_conn_update_reason reason,uint32_t original_vdev_id,uint32_t request_id)11919 QDF_STATUS sme_nss_update_request(uint32_t vdev_id, 11920 uint8_t new_nss, uint8_t ch_width, 11921 policy_mgr_nss_update_cback cback, 11922 uint8_t next_action, struct wlan_objmgr_psoc *psoc, 11923 enum policy_mgr_conn_update_reason reason, 11924 uint32_t original_vdev_id, uint32_t request_id) 11925 { 11926 QDF_STATUS status = QDF_STATUS_E_FAILURE; 11927 struct mac_context *mac = sme_get_mac_context(); 11928 tSmeCmd *cmd = NULL; 11929 11930 if (!mac) { 11931 sme_err("mac is null"); 11932 return status; 11933 } 11934 status = sme_acquire_global_lock(&mac->sme); 11935 if (QDF_IS_STATUS_SUCCESS(status)) { 11936 cmd = csr_get_command_buffer(mac); 11937 if (!cmd) { 11938 sme_err("Get command buffer failed"); 11939 sme_release_global_lock(&mac->sme); 11940 return QDF_STATUS_E_NULL_VALUE; 11941 } 11942 cmd->command = e_sme_command_nss_update; 11943 /* Sessionized modules may require this info */ 11944 cmd->vdev_id = vdev_id; 11945 cmd->u.nss_update_cmd.new_nss = new_nss; 11946 cmd->u.nss_update_cmd.ch_width = ch_width; 11947 cmd->u.nss_update_cmd.session_id = vdev_id; 11948 cmd->u.nss_update_cmd.nss_update_cb = cback; 11949 cmd->u.nss_update_cmd.context = psoc; 11950 cmd->u.nss_update_cmd.next_action = next_action; 11951 cmd->u.nss_update_cmd.reason = reason; 11952 cmd->u.nss_update_cmd.original_vdev_id = original_vdev_id; 11953 cmd->u.nss_update_cmd.request_id = request_id; 11954 11955 sme_debug("Queuing e_sme_command_nss_update to CSR:vdev (%d %d) ss %d r %d req id %x", 11956 vdev_id, original_vdev_id, new_nss, reason, request_id); 11957 csr_queue_sme_command(mac, cmd, false); 11958 sme_release_global_lock(&mac->sme); 11959 } 11960 return status; 11961 } 11962 11963 QDF_STATUS sme_sap_update_ch_width(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum phy_ch_width ch_width,enum policy_mgr_conn_update_reason reason,uint8_t conc_vdev_id,uint32_t request_id)11964 sme_sap_update_ch_width(struct wlan_objmgr_psoc *psoc, 11965 uint8_t vdev_id, 11966 enum phy_ch_width ch_width, 11967 enum policy_mgr_conn_update_reason reason, 11968 uint8_t conc_vdev_id, uint32_t request_id) 11969 { 11970 QDF_STATUS status = QDF_STATUS_E_FAILURE; 11971 struct mac_context *mac = sme_get_mac_context(); 11972 tSmeCmd *cmd = NULL; 11973 11974 if (!mac) { 11975 sme_err("mac is null"); 11976 return status; 11977 } 11978 status = sme_acquire_global_lock(&mac->sme); 11979 if (QDF_IS_STATUS_ERROR(status)) 11980 return status; 11981 11982 cmd = csr_get_command_buffer(mac); 11983 if (!cmd) { 11984 sme_err("Get command buffer failed"); 11985 sme_release_global_lock(&mac->sme); 11986 return QDF_STATUS_E_NULL_VALUE; 11987 } 11988 cmd->command = e_sme_command_sap_ch_width_update; 11989 /* Sessionized modules may require this info */ 11990 cmd->vdev_id = vdev_id; 11991 cmd->u.bw_update_cmd.ch_width = ch_width; 11992 cmd->u.bw_update_cmd.vdev_id = vdev_id; 11993 cmd->u.bw_update_cmd.reason = reason; 11994 cmd->u.bw_update_cmd.request_id = request_id; 11995 cmd->u.bw_update_cmd.conc_vdev_id = conc_vdev_id; 11996 11997 sme_debug("vdev %d ch_width: %d reason: %d", vdev_id, ch_width, reason); 11998 csr_queue_sme_command(mac, cmd, false); 11999 sme_release_global_lock(&mac->sme); 12000 12001 return status; 12002 } 12003 12004 /** 12005 * sme_soc_set_dual_mac_config() - Set dual mac configurations 12006 * @mac_handle: Handle returned by macOpen 12007 * @msg: Structure containing the dual mac config parameters 12008 * 12009 * Queues configuration information to CSR to configure 12010 * WLAN firmware for the dual MAC features 12011 * 12012 * Return: QDF_STATUS 12013 */ sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg)12014 QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg) 12015 { 12016 QDF_STATUS status = QDF_STATUS_SUCCESS; 12017 struct mac_context *mac = sme_get_mac_context(); 12018 tSmeCmd *cmd; 12019 12020 if (!mac) { 12021 sme_err("mac is null"); 12022 return QDF_STATUS_E_FAILURE; 12023 } 12024 status = sme_acquire_global_lock(&mac->sme); 12025 if (!QDF_IS_STATUS_SUCCESS(status)) { 12026 sme_err("Failed to acquire lock"); 12027 return QDF_STATUS_E_RESOURCES; 12028 } 12029 12030 cmd = csr_get_command_buffer(mac); 12031 if (!cmd) { 12032 sme_err("Get command buffer failed"); 12033 sme_release_global_lock(&mac->sme); 12034 return QDF_STATUS_E_NULL_VALUE; 12035 } 12036 12037 cmd->command = e_sme_command_set_dual_mac_config; 12038 cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config; 12039 cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config; 12040 cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb; 12041 12042 sme_debug("set_dual_mac_config scan_config: %x fw_mode_config: %x", 12043 cmd->u.set_dual_mac_cmd.scan_config, 12044 cmd->u.set_dual_mac_cmd.fw_mode_config); 12045 status = csr_queue_sme_command(mac, cmd, false); 12046 12047 sme_release_global_lock(&mac->sme); 12048 return status; 12049 } 12050 12051 #ifdef FEATURE_LFR_SUBNET_DETECTION 12052 /** 12053 * sme_gateway_param_update() - to update gateway parameters with WMA 12054 * @mac_handle: Opaque handle to the global MAC context 12055 * @gw_params: request parameters from HDD 12056 * 12057 * Return: QDF_STATUS 12058 * 12059 * This routine will update gateway parameters to WMA 12060 */ sme_gateway_param_update(mac_handle_t mac_handle,struct gateway_update_req_param * gw_params)12061 QDF_STATUS sme_gateway_param_update(mac_handle_t mac_handle, 12062 struct gateway_update_req_param *gw_params) 12063 { 12064 QDF_STATUS qdf_status; 12065 struct scheduler_msg message = {0}; 12066 struct gateway_update_req_param *request_buf; 12067 12068 request_buf = qdf_mem_malloc(sizeof(*request_buf)); 12069 if (!request_buf) 12070 return QDF_STATUS_E_NOMEM; 12071 12072 *request_buf = *gw_params; 12073 12074 message.type = WMA_GW_PARAM_UPDATE_REQ; 12075 message.reserved = 0; 12076 message.bodyptr = request_buf; 12077 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 12078 QDF_MODULE_ID_WMA, 12079 QDF_MODULE_ID_WMA, &message); 12080 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 12081 sme_err("Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL"); 12082 qdf_mem_free(request_buf); 12083 return QDF_STATUS_E_FAILURE; 12084 } 12085 12086 return QDF_STATUS_SUCCESS; 12087 } 12088 #endif /* FEATURE_LFR_SUBNET_DETECTION */ 12089 12090 /** 12091 * sme_soc_set_antenna_mode() - set antenna mode 12092 * @mac_handle: Handle returned by macOpen 12093 * @msg: Structure containing the antenna mode parameters 12094 * 12095 * Send the command to CSR to send 12096 * WMI_SOC_SET_ANTENNA_MODE_CMDID to FW 12097 * 12098 * Return: QDF_STATUS 12099 */ sme_soc_set_antenna_mode(mac_handle_t mac_handle,struct sir_antenna_mode_param * msg)12100 QDF_STATUS sme_soc_set_antenna_mode(mac_handle_t mac_handle, 12101 struct sir_antenna_mode_param *msg) 12102 { 12103 QDF_STATUS status = QDF_STATUS_SUCCESS; 12104 struct mac_context *mac = MAC_CONTEXT(mac_handle); 12105 tSmeCmd *cmd; 12106 12107 if (!msg) { 12108 sme_err("antenna mode mesg is NULL"); 12109 return QDF_STATUS_E_FAILURE; 12110 } 12111 12112 status = sme_acquire_global_lock(&mac->sme); 12113 if (!QDF_IS_STATUS_SUCCESS(status)) { 12114 sme_err("Failed to acquire lock"); 12115 return QDF_STATUS_E_RESOURCES; 12116 } 12117 12118 cmd = csr_get_command_buffer(mac); 12119 if (!cmd) { 12120 sme_release_global_lock(&mac->sme); 12121 sme_err("Get command buffer failed"); 12122 return QDF_STATUS_E_NULL_VALUE; 12123 } 12124 12125 cmd->command = e_sme_command_set_antenna_mode; 12126 cmd->u.set_antenna_mode_cmd = *msg; 12127 12128 sme_debug("Antenna mode rx_chains: %d tx_chains: %d", 12129 cmd->u.set_antenna_mode_cmd.num_rx_chains, 12130 cmd->u.set_antenna_mode_cmd.num_tx_chains); 12131 12132 csr_queue_sme_command(mac, cmd, false); 12133 sme_release_global_lock(&mac->sme); 12134 12135 return QDF_STATUS_SUCCESS; 12136 } 12137 12138 /** 12139 * sme_set_peer_authorized() - call peer authorized callback 12140 * @peer_addr: peer mac address 12141 * @vdev_id: vdev id 12142 * 12143 * Return: QDF Status 12144 */ sme_set_peer_authorized(uint8_t * peer_addr,uint32_t vdev_id)12145 QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr, 12146 uint32_t vdev_id) 12147 { 12148 void *wma_handle; 12149 12150 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12151 if (!wma_handle) 12152 return QDF_STATUS_E_FAILURE; 12153 12154 return wma_set_peer_param(wma_handle, peer_addr, 12155 WMI_HOST_PEER_AUTHORIZE, 1, vdev_id); 12156 } 12157 12158 /** 12159 * sme_setdef_dot11mode() - Updates mac with default dot11mode 12160 * @mac_handle: Global MAC pointer 12161 * 12162 * Return: NULL. 12163 */ sme_setdef_dot11mode(mac_handle_t mac_handle)12164 void sme_setdef_dot11mode(mac_handle_t mac_handle) 12165 { 12166 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12167 12168 csr_set_default_dot11_mode(mac_ctx); 12169 } 12170 12171 /** 12172 * sme_update_tgt_services() - update the target services config. 12173 * @mac_handle: Opaque handle to the global MAC context. 12174 * @cfg: wma_tgt_services parameters. 12175 * 12176 * update the target services config. 12177 * 12178 * Return: None. 12179 */ sme_update_tgt_services(mac_handle_t mac_handle,struct wma_tgt_services * cfg)12180 void sme_update_tgt_services(mac_handle_t mac_handle, 12181 struct wma_tgt_services *cfg) 12182 { 12183 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12184 struct wlan_mlme_psoc_ext_obj *mlme_obj; 12185 12186 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 12187 if (!mlme_obj) 12188 return; 12189 12190 mac_ctx->obss_scan_offload = cfg->obss_scan_offload; 12191 mac_ctx->mlme_cfg->gen.as_enabled = cfg->lte_coex_ant_share; 12192 mac_ctx->beacon_offload = cfg->beacon_offload; 12193 mac_ctx->pmf_offload = cfg->pmf_offload; 12194 mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported = 12195 cfg->is_fils_roaming_supported; 12196 mac_ctx->is_11k_offload_supported = 12197 cfg->is_11k_offload_supported; 12198 sme_debug("obss_scan_offload: %d pmf_offload: %d fils_roam support %d 11k_offload %d", 12199 mac_ctx->obss_scan_offload, mac_ctx->pmf_offload, 12200 mlme_obj->cfg.lfr.rso_user_config.is_fils_roaming_supported, 12201 mac_ctx->is_11k_offload_supported); 12202 mac_ctx->bcn_reception_stats = cfg->bcn_reception_stats; 12203 } 12204 12205 /** 12206 * sme_is_session_id_valid() - Check if the session id is valid 12207 * @mac_handle: Opaque handle to the global MAC context 12208 * @session_id: Session id 12209 * 12210 * Checks if the session id is valid or not 12211 * 12212 * Return: True is the session id is valid, false otherwise 12213 */ sme_is_session_id_valid(mac_handle_t mac_handle,uint32_t session_id)12214 bool sme_is_session_id_valid(mac_handle_t mac_handle, uint32_t session_id) 12215 { 12216 struct mac_context *mac; 12217 12218 if (mac_handle) { 12219 mac = MAC_CONTEXT(mac_handle); 12220 } else { 12221 sme_err("null mac pointer"); 12222 return false; 12223 } 12224 12225 if (CSR_IS_SESSION_VALID(mac, session_id)) 12226 return true; 12227 12228 return false; 12229 } 12230 12231 #ifdef FEATURE_WLAN_TDLS 12232 12233 /** 12234 * sme_get_opclass() - determine operating class 12235 * @mac_handle: Opaque handle to the global MAC context 12236 * @channel: channel id 12237 * @bw_offset: bandwidth offset 12238 * @opclass: pointer to operating class 12239 * 12240 * Function will determine operating class from regdm_get_opclass_from_channel 12241 * 12242 * Return: none 12243 */ sme_get_opclass(mac_handle_t mac_handle,uint8_t channel,uint8_t bw_offset,uint8_t * opclass)12244 void sme_get_opclass(mac_handle_t mac_handle, uint8_t channel, 12245 uint8_t bw_offset, uint8_t *opclass) 12246 { 12247 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12248 uint8_t reg_cc[REG_ALPHA2_LEN + 1]; 12249 12250 wlan_reg_read_current_country(mac_ctx->psoc, reg_cc); 12251 /* redgm opclass table contains opclass for 40MHz low primary, 12252 * 40MHz high primary and 20MHz. No support for 80MHz yet. So 12253 * first we will check if bit for 40MHz is set and if so find 12254 * matching opclass either with low primary or high primary 12255 * (a channel would never be in both) and then search for opclass 12256 * matching 20MHz, else for any BW. 12257 */ 12258 if (bw_offset & (1 << BW_40_OFFSET_BIT)) { 12259 *opclass = wlan_reg_dmn_get_opclass_from_channel( 12260 reg_cc, channel, BW40_LOW_PRIMARY); 12261 if (!(*opclass)) { 12262 *opclass = wlan_reg_dmn_get_opclass_from_channel( 12263 reg_cc, channel, BW40_HIGH_PRIMARY); 12264 } 12265 } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { 12266 *opclass = wlan_reg_dmn_get_opclass_from_channel( 12267 reg_cc, channel, BW20); 12268 } else { 12269 *opclass = wlan_reg_dmn_get_opclass_from_channel( 12270 reg_cc, channel, BWALL); 12271 } 12272 } 12273 #endif 12274 12275 /** 12276 * sme_set_fw_test() - set fw test 12277 * @fw_test: fw test param 12278 * 12279 * Return: Return QDF_STATUS, otherwise appropriate failure code 12280 */ sme_set_fw_test(struct set_fwtest_params * fw_test)12281 QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test) 12282 { 12283 void *wma_handle; 12284 12285 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12286 if (!wma_handle) 12287 return QDF_STATUS_E_FAILURE; 12288 12289 return wma_process_fw_test_cmd(wma_handle, fw_test); 12290 } 12291 12292 /** 12293 * sme_ht40_stop_obss_scan() - ht40 obss stop scan 12294 * @mac_handle: mac handle 12295 * @vdev_id: vdev identifier 12296 * 12297 * Return: Return QDF_STATUS, otherwise appropriate failure code 12298 */ sme_ht40_stop_obss_scan(mac_handle_t mac_handle,uint32_t vdev_id)12299 QDF_STATUS sme_ht40_stop_obss_scan(mac_handle_t mac_handle, uint32_t vdev_id) 12300 { 12301 void *wma_handle; 12302 12303 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12304 if (!wma_handle) 12305 return QDF_STATUS_E_FAILURE; 12306 12307 wma_ht40_stop_obss_scan(wma_handle, vdev_id); 12308 return QDF_STATUS_SUCCESS; 12309 } 12310 12311 #ifdef WLAN_BCN_RECV_FEATURE sme_handle_bcn_recv_start(mac_handle_t mac_handle,uint32_t vdev_id,uint32_t nth_value,bool do_not_resume)12312 QDF_STATUS sme_handle_bcn_recv_start(mac_handle_t mac_handle, 12313 uint32_t vdev_id, uint32_t nth_value, 12314 bool do_not_resume) 12315 { 12316 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12317 struct csr_roam_session *session; 12318 QDF_STATUS status; 12319 int ret; 12320 12321 session = CSR_GET_SESSION(mac_ctx, vdev_id); 12322 if (!session) { 12323 sme_err("vdev_id %d not found", vdev_id); 12324 return QDF_STATUS_E_FAILURE; 12325 } 12326 12327 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 12328 sme_err("CSR session not valid: %d", vdev_id); 12329 return QDF_STATUS_E_FAILURE; 12330 } 12331 12332 status = sme_acquire_global_lock(&mac_ctx->sme); 12333 if (QDF_IS_STATUS_SUCCESS(status)) { 12334 if (session->is_bcn_recv_start) { 12335 sme_release_global_lock(&mac_ctx->sme); 12336 sme_err("Beacon receive already started"); 12337 return QDF_STATUS_SUCCESS; 12338 } 12339 session->is_bcn_recv_start = true; 12340 session->beacon_report_do_not_resume = do_not_resume; 12341 sme_release_global_lock(&mac_ctx->sme); 12342 } 12343 12344 /* 12345 * Allows fw to send beacons of connected AP to driver. 12346 * MSB set : means fw do not wakeup host in wow mode 12347 * LSB set: Value of beacon report period (say n), Means fw sends nth 12348 * beacons of connected AP to HOST 12349 */ 12350 ret = sme_cli_set_command(vdev_id, 12351 wmi_vdev_param_nth_beacon_to_host, 12352 nth_value, VDEV_CMD); 12353 if (ret) { 12354 status = sme_acquire_global_lock(&mac_ctx->sme); 12355 if (QDF_IS_STATUS_SUCCESS(status)) { 12356 session->is_bcn_recv_start = false; 12357 session->beacon_report_do_not_resume = false; 12358 sme_release_global_lock(&mac_ctx->sme); 12359 } 12360 sme_err("wmi_vdev_param_nth_beacon_to_host %d", ret); 12361 status = qdf_status_from_os_return(ret); 12362 } 12363 12364 return status; 12365 } 12366 sme_stop_beacon_report(mac_handle_t mac_handle,uint32_t session_id)12367 void sme_stop_beacon_report(mac_handle_t mac_handle, uint32_t session_id) 12368 { 12369 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12370 struct csr_roam_session *session; 12371 QDF_STATUS status; 12372 int ret; 12373 12374 session = CSR_GET_SESSION(mac_ctx, session_id); 12375 if (!session) { 12376 sme_err("vdev_id %d not found", session_id); 12377 return; 12378 } 12379 12380 ret = sme_cli_set_command(session_id, 12381 wmi_vdev_param_nth_beacon_to_host, 0, 12382 VDEV_CMD); 12383 if (ret) 12384 sme_err("wmi_vdev_param_nth_beacon_to_host command failed to FW"); 12385 status = sme_acquire_global_lock(&mac_ctx->sme); 12386 if (QDF_IS_STATUS_SUCCESS(status)) { 12387 session->is_bcn_recv_start = false; 12388 session->beacon_report_do_not_resume = false; 12389 sme_release_global_lock(&mac_ctx->sme); 12390 } 12391 } 12392 sme_is_beacon_report_started(mac_handle_t mac_handle,uint32_t session_id)12393 bool sme_is_beacon_report_started(mac_handle_t mac_handle, uint32_t session_id) 12394 { 12395 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12396 struct csr_roam_session *session; 12397 12398 session = CSR_GET_SESSION(mac_ctx, session_id); 12399 if (!session) { 12400 sme_err("vdev_id %d not found", session_id); 12401 return false; 12402 } 12403 12404 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 12405 sme_err("CSR session not valid: %d", session_id); 12406 return false; 12407 } 12408 12409 return session->is_bcn_recv_start; 12410 } 12411 sme_is_beacon_reporting_do_not_resume(mac_handle_t mac_handle,uint32_t session_id)12412 bool sme_is_beacon_reporting_do_not_resume(mac_handle_t mac_handle, 12413 uint32_t session_id) 12414 { 12415 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12416 struct csr_roam_session *session; 12417 12418 session = CSR_GET_SESSION(mac_ctx, session_id); 12419 if (!session) { 12420 sme_err("vdev_id %d not found", session_id); 12421 return false; 12422 } 12423 12424 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 12425 sme_err("CSR session not valid: %d", session_id); 12426 return false; 12427 } 12428 12429 return session->beacon_report_do_not_resume; 12430 } 12431 #endif 12432 12433 /** 12434 * sme_add_beacon_filter() - set the beacon filter configuration 12435 * @mac_handle: The handle returned by macOpen 12436 * @session_id: session id 12437 * @ie_map: bitwise array of IEs 12438 * 12439 * Return: Return QDF_STATUS, otherwise appropriate failure code 12440 */ sme_add_beacon_filter(mac_handle_t mac_handle,uint32_t session_id,uint32_t * ie_map)12441 QDF_STATUS sme_add_beacon_filter(mac_handle_t mac_handle, 12442 uint32_t session_id, 12443 uint32_t *ie_map) 12444 { 12445 struct scheduler_msg message = {0}; 12446 QDF_STATUS qdf_status; 12447 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12448 struct beacon_filter_param *filter_param; 12449 12450 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 12451 sme_err("CSR session not valid: %d", session_id); 12452 return QDF_STATUS_E_FAILURE; 12453 } 12454 12455 filter_param = qdf_mem_malloc(sizeof(*filter_param)); 12456 if (!filter_param) 12457 return QDF_STATUS_E_FAILURE; 12458 12459 filter_param->vdev_id = session_id; 12460 12461 qdf_mem_copy(filter_param->ie_map, ie_map, 12462 SIR_BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(uint32_t)); 12463 12464 message.type = WMA_ADD_BCN_FILTER_CMDID; 12465 message.bodyptr = filter_param; 12466 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 12467 QDF_MODULE_ID_WMA, 12468 QDF_MODULE_ID_WMA, 12469 &message); 12470 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 12471 sme_err("Not able to post msg to WDA!"); 12472 12473 qdf_mem_free(filter_param); 12474 } 12475 return qdf_status; 12476 } 12477 12478 /** 12479 * sme_remove_beacon_filter() - set the beacon filter configuration 12480 * @mac_handle: The handle returned by macOpen 12481 * @session_id: session id 12482 * 12483 * Return: Return QDF_STATUS, otherwise appropriate failure code 12484 */ sme_remove_beacon_filter(mac_handle_t mac_handle,uint32_t session_id)12485 QDF_STATUS sme_remove_beacon_filter(mac_handle_t mac_handle, 12486 uint32_t session_id) 12487 { 12488 struct scheduler_msg message = {0}; 12489 QDF_STATUS qdf_status; 12490 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12491 struct beacon_filter_param *filter_param; 12492 12493 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 12494 sme_err("CSR session not valid: %d", session_id); 12495 return QDF_STATUS_E_FAILURE; 12496 } 12497 12498 filter_param = qdf_mem_malloc(sizeof(*filter_param)); 12499 if (!filter_param) 12500 return QDF_STATUS_E_FAILURE; 12501 12502 filter_param->vdev_id = session_id; 12503 12504 message.type = WMA_REMOVE_BCN_FILTER_CMDID; 12505 message.bodyptr = filter_param; 12506 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 12507 QDF_MODULE_ID_WMA, 12508 QDF_MODULE_ID_WMA, 12509 &message); 12510 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 12511 sme_err("Not able to post msg to WDA!"); 12512 12513 qdf_mem_free(filter_param); 12514 } 12515 return qdf_status; 12516 } 12517 12518 /** 12519 * sme_send_disassoc_req_frame - send disassoc req 12520 * @mac_handle: Opaque handle to the global MAC context 12521 * @session_id: session id 12522 * @peer_mac: peer mac address 12523 * @reason: reason for disassociation 12524 * wait_for_ack: wait for acknowledgment 12525 * 12526 * function to send disassoc request to lim 12527 * 12528 * return: none 12529 */ sme_send_disassoc_req_frame(mac_handle_t mac_handle,uint8_t session_id,uint8_t * peer_mac,uint16_t reason,uint8_t wait_for_ack)12530 void sme_send_disassoc_req_frame(mac_handle_t mac_handle, uint8_t session_id, 12531 uint8_t *peer_mac, uint16_t reason, 12532 uint8_t wait_for_ack) 12533 { 12534 struct sme_send_disassoc_frm_req *msg; 12535 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 12536 12537 msg = qdf_mem_malloc(sizeof(*msg)); 12538 if (!msg) 12539 return; 12540 12541 msg->msg_type = eWNI_SME_SEND_DISASSOC_FRAME; 12542 msg->length = sizeof(*msg); 12543 msg->vdev_id = session_id; 12544 qdf_mem_copy(msg->peer_mac, peer_mac, QDF_MAC_ADDR_SIZE); 12545 msg->reason = reason; 12546 msg->wait_for_ack = wait_for_ack; 12547 12548 qdf_status = umac_send_mb_message_to_mac(msg); 12549 if (QDF_IS_STATUS_ERROR(qdf_status)) 12550 sme_err("umac_send_mb_message_to_mac failed, %d", 12551 qdf_status); 12552 } 12553 12554 #ifdef FEATURE_WLAN_APF sme_get_apf_capabilities(mac_handle_t mac_handle,apf_get_offload_cb callback,void * context)12555 QDF_STATUS sme_get_apf_capabilities(mac_handle_t mac_handle, 12556 apf_get_offload_cb callback, 12557 void *context) 12558 { 12559 QDF_STATUS status = QDF_STATUS_SUCCESS; 12560 struct mac_context * mac_ctx = MAC_CONTEXT(mac_handle); 12561 struct scheduler_msg cds_msg = {0}; 12562 12563 SME_ENTER(); 12564 12565 status = sme_acquire_global_lock(&mac_ctx->sme); 12566 if (QDF_STATUS_SUCCESS == status) { 12567 /* Serialize the req through MC thread */ 12568 mac_ctx->sme.apf_get_offload_cb = callback; 12569 mac_ctx->sme.apf_get_offload_context = context; 12570 cds_msg.bodyptr = NULL; 12571 cds_msg.type = WDA_APF_GET_CAPABILITIES_REQ; 12572 status = scheduler_post_message(QDF_MODULE_ID_SME, 12573 QDF_MODULE_ID_WMA, 12574 QDF_MODULE_ID_WMA, &cds_msg); 12575 if (!QDF_IS_STATUS_SUCCESS(status)) { 12576 sme_err("Post apf get offload msg fail"); 12577 status = QDF_STATUS_E_FAILURE; 12578 } 12579 sme_release_global_lock(&mac_ctx->sme); 12580 } 12581 12582 SME_EXIT(); 12583 return status; 12584 } 12585 sme_set_apf_instructions(mac_handle_t mac_handle,struct sir_apf_set_offload * req)12586 QDF_STATUS sme_set_apf_instructions(mac_handle_t mac_handle, 12587 struct sir_apf_set_offload *req) 12588 { 12589 void *wma_handle; 12590 12591 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12592 if (!wma_handle) 12593 return QDF_STATUS_E_FAILURE; 12594 12595 return wma_set_apf_instructions(wma_handle, req); 12596 } 12597 sme_set_apf_enable_disable(mac_handle_t mac_handle,uint8_t vdev_id,bool apf_enable)12598 QDF_STATUS sme_set_apf_enable_disable(mac_handle_t mac_handle, uint8_t vdev_id, 12599 bool apf_enable) 12600 { 12601 void *wma_handle; 12602 12603 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12604 if (!wma_handle) 12605 return QDF_STATUS_E_FAILURE; 12606 12607 return wma_send_apf_enable_cmd(wma_handle, vdev_id, apf_enable); 12608 } 12609 12610 QDF_STATUS sme_apf_write_work_memory(mac_handle_t mac_handle,struct wmi_apf_write_memory_params * write_params)12611 sme_apf_write_work_memory(mac_handle_t mac_handle, 12612 struct wmi_apf_write_memory_params *write_params) 12613 { 12614 void *wma_handle; 12615 12616 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12617 if (!wma_handle) 12618 return QDF_STATUS_E_FAILURE; 12619 12620 return wma_send_apf_write_work_memory_cmd(wma_handle, write_params); 12621 } 12622 12623 QDF_STATUS sme_apf_read_work_memory(mac_handle_t mac_handle,struct wmi_apf_read_memory_params * read_params,apf_read_mem_cb callback)12624 sme_apf_read_work_memory(mac_handle_t mac_handle, 12625 struct wmi_apf_read_memory_params *read_params, 12626 apf_read_mem_cb callback) 12627 { 12628 QDF_STATUS status = QDF_STATUS_SUCCESS; 12629 struct mac_context *mac = MAC_CONTEXT(mac_handle); 12630 void *wma_handle; 12631 12632 status = sme_acquire_global_lock(&mac->sme); 12633 if (QDF_IS_STATUS_SUCCESS(status)) { 12634 mac->sme.apf_read_mem_cb = callback; 12635 sme_release_global_lock(&mac->sme); 12636 } else { 12637 sme_err("sme_acquire_global_lock failed"); 12638 } 12639 12640 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 12641 if (!wma_handle) 12642 return QDF_STATUS_E_FAILURE; 12643 12644 return wma_send_apf_read_work_memory_cmd(wma_handle, read_params); 12645 } 12646 #endif /* FEATURE_WLAN_APF */ 12647 12648 /** 12649 * sme_get_wni_dot11_mode() - return configured wni dot11mode 12650 * @mac_handle: Opaque handle to the global MAC context 12651 * 12652 * Return: wni dot11 mode. 12653 */ sme_get_wni_dot11_mode(mac_handle_t mac_handle)12654 uint32_t sme_get_wni_dot11_mode(mac_handle_t mac_handle) 12655 { 12656 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12657 12658 return csr_translate_to_wni_cfg_dot11_mode(mac_ctx, 12659 mac_ctx->roam.configParam.uCfgDot11Mode); 12660 } 12661 12662 /** 12663 * sme_create_mon_session() - post message to create PE session for monitormode 12664 * operation 12665 * @mac_handle: Opaque handle to the global MAC context 12666 * @bssid: pointer to bssid 12667 * @vdev_id: sme session id 12668 * 12669 * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure. 12670 */ sme_create_mon_session(mac_handle_t mac_handle,uint8_t * bss_id,uint8_t vdev_id)12671 QDF_STATUS sme_create_mon_session(mac_handle_t mac_handle, uint8_t *bss_id, 12672 uint8_t vdev_id) 12673 { 12674 QDF_STATUS status = QDF_STATUS_E_FAILURE; 12675 struct sir_create_session *msg; 12676 12677 msg = qdf_mem_malloc(sizeof(*msg)); 12678 if (msg) { 12679 msg->type = eWNI_SME_MON_INIT_SESSION; 12680 msg->vdev_id = vdev_id; 12681 msg->msg_len = sizeof(*msg); 12682 qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE); 12683 status = umac_send_mb_message_to_mac(msg); 12684 } 12685 return status; 12686 } 12687 sme_delete_mon_session(mac_handle_t mac_handle,uint8_t vdev_id)12688 QDF_STATUS sme_delete_mon_session(mac_handle_t mac_handle, uint8_t vdev_id) 12689 { 12690 QDF_STATUS status = QDF_STATUS_E_FAILURE; 12691 struct sir_delete_session *msg; 12692 12693 msg = qdf_mem_malloc(sizeof(*msg)); 12694 if (msg) { 12695 msg->type = eWNI_SME_MON_DEINIT_SESSION; 12696 msg->vdev_id = vdev_id; 12697 msg->msg_len = sizeof(*msg); 12698 status = umac_send_mb_message_to_mac(msg); 12699 } 12700 12701 return status; 12702 } 12703 12704 void sme_set_del_peers_ind_callback(mac_handle_t mac_handle,void (* callback)(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id))12705 sme_set_del_peers_ind_callback(mac_handle_t mac_handle, 12706 void (*callback)(struct wlan_objmgr_psoc *psoc, 12707 uint8_t vdev_id)) 12708 { 12709 struct mac_context *mac; 12710 12711 if (!mac_handle) { 12712 QDF_ASSERT(0); 12713 return; 12714 } 12715 mac = MAC_CONTEXT(mac_handle); 12716 mac->del_peers_ind_cb = callback; 12717 } 12718 sme_set_chan_info_callback(mac_handle_t mac_handle,void (* callback)(struct scan_chan_info * chan_info))12719 void sme_set_chan_info_callback(mac_handle_t mac_handle, 12720 void (*callback)(struct scan_chan_info *chan_info)) 12721 { 12722 struct mac_context *mac; 12723 12724 if (!mac_handle) { 12725 QDF_ASSERT(0); 12726 return; 12727 } 12728 mac = MAC_CONTEXT(mac_handle); 12729 mac->chan_info_cb = callback; 12730 } 12731 12732 #ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER sme_set_cal_failure_event_cb(mac_handle_t mac_handle,void (* callback)(uint8_t cal_type,uint8_t reason))12733 void sme_set_cal_failure_event_cb( 12734 mac_handle_t mac_handle, 12735 void (*callback)(uint8_t cal_type, uint8_t reason)) 12736 { 12737 struct mac_context *mac; 12738 QDF_STATUS status = QDF_STATUS_SUCCESS; 12739 12740 if (!mac_handle) { 12741 QDF_ASSERT(0); 12742 return; 12743 } 12744 mac = MAC_CONTEXT(mac_handle); 12745 12746 status = sme_acquire_global_lock(&mac->sme); 12747 if (QDF_IS_STATUS_SUCCESS(status)) { 12748 mac->cal_failure_event_cb = callback; 12749 sme_release_global_lock(&mac->sme); 12750 } else { 12751 sme_err("sme_acquire_global_lock failed"); 12752 } 12753 } 12754 #endif 12755 sme_set_vdev_ies_per_band(mac_handle_t mac_handle,uint8_t vdev_id,enum QDF_OPMODE device_mode)12756 void sme_set_vdev_ies_per_band(mac_handle_t mac_handle, uint8_t vdev_id, 12757 enum QDF_OPMODE device_mode) 12758 { 12759 QDF_STATUS status = QDF_STATUS_E_FAILURE; 12760 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12761 12762 status = sme_acquire_global_lock(&mac_ctx->sme); 12763 if (QDF_IS_STATUS_SUCCESS(status)) { 12764 csr_set_vdev_ies_per_band(mac_handle, vdev_id, 12765 device_mode); 12766 sme_release_global_lock(&mac_ctx->sme); 12767 } 12768 } 12769 12770 /** 12771 * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req 12772 * @mac_handle: Opaque handle to the global MAC context 12773 * @enable2x2: 1x1 or 2x2 mode. 12774 * 12775 * Sends the set pdev IE req with Nss value. 12776 * 12777 * Return: None 12778 */ sme_set_pdev_ht_vht_ies(mac_handle_t mac_handle,bool enable2x2)12779 void sme_set_pdev_ht_vht_ies(mac_handle_t mac_handle, bool enable2x2) 12780 { 12781 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12782 struct sir_set_ht_vht_cfg *ht_vht_cfg; 12783 QDF_STATUS status = QDF_STATUS_E_FAILURE; 12784 12785 if (!((mac_ctx->roam.configParam.uCfgDot11Mode == 12786 eCSR_CFG_DOT11_MODE_AUTO) || 12787 (mac_ctx->roam.configParam.uCfgDot11Mode == 12788 eCSR_CFG_DOT11_MODE_11N) || 12789 (mac_ctx->roam.configParam.uCfgDot11Mode == 12790 eCSR_CFG_DOT11_MODE_11N_ONLY) || 12791 (mac_ctx->roam.configParam.uCfgDot11Mode == 12792 eCSR_CFG_DOT11_MODE_11AC) || 12793 (mac_ctx->roam.configParam.uCfgDot11Mode == 12794 eCSR_CFG_DOT11_MODE_11AC_ONLY))) 12795 return; 12796 12797 status = sme_acquire_global_lock(&mac_ctx->sme); 12798 if (QDF_STATUS_SUCCESS == status) { 12799 ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg)); 12800 if (!ht_vht_cfg) { 12801 sme_release_global_lock(&mac_ctx->sme); 12802 return; 12803 } 12804 12805 ht_vht_cfg->pdev_id = 0; 12806 if (enable2x2) 12807 ht_vht_cfg->nss = 2; 12808 else 12809 ht_vht_cfg->nss = 1; 12810 ht_vht_cfg->dot11mode = 12811 (uint8_t)csr_translate_to_wni_cfg_dot11_mode(mac_ctx, 12812 mac_ctx->roam.configParam.uCfgDot11Mode); 12813 12814 ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE; 12815 ht_vht_cfg->len = sizeof(*ht_vht_cfg); 12816 sme_debug("SET_HT_VHT_IE with nss: %d, dot11mode: %d", 12817 ht_vht_cfg->nss, 12818 ht_vht_cfg->dot11mode); 12819 status = umac_send_mb_message_to_mac(ht_vht_cfg); 12820 if (QDF_STATUS_SUCCESS != status) 12821 sme_err("Send SME_PDEV_SET_HT_VHT_IE fail"); 12822 12823 sme_release_global_lock(&mac_ctx->sme); 12824 } 12825 } 12826 sme_get_sap_vdev_type_nss(mac_handle_t mac_handle,uint8_t * vdev_nss,enum band_info band)12827 void sme_get_sap_vdev_type_nss(mac_handle_t mac_handle, uint8_t *vdev_nss, 12828 enum band_info band) 12829 { 12830 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12831 12832 if (band == BAND_5G) 12833 *vdev_nss = mac_ctx->vdev_type_nss_5g.sap; 12834 else 12835 *vdev_nss = mac_ctx->vdev_type_nss_2g.sap; 12836 } 12837 sme_update_vdev_type_nss(mac_handle_t mac_handle,uint8_t max_supp_nss,enum nss_chains_band_info band)12838 void sme_update_vdev_type_nss(mac_handle_t mac_handle, uint8_t max_supp_nss, 12839 enum nss_chains_band_info band) 12840 { 12841 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12842 struct vdev_type_nss *vdev_nss; 12843 12844 struct wlan_mlme_nss_chains *nss_chains_ini_cfg = 12845 &mac_ctx->mlme_cfg->nss_chains_ini_cfg; 12846 12847 if (band == NSS_CHAINS_BAND_5GHZ) 12848 vdev_nss = &mac_ctx->vdev_type_nss_5g; 12849 else 12850 vdev_nss = &mac_ctx->vdev_type_nss_2g; 12851 12852 vdev_nss->sta = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12853 nss_chains_ini_cfg-> 12854 rx_nss[band], 12855 STA_NSS_CHAINS_SHIFT)); 12856 vdev_nss->sap = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12857 nss_chains_ini_cfg-> 12858 rx_nss[band], 12859 SAP_NSS_CHAINS_SHIFT)); 12860 vdev_nss->p2p_go = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12861 nss_chains_ini_cfg-> 12862 rx_nss[band], 12863 P2P_GO_NSS_CHAINS_SHIFT)); 12864 vdev_nss->p2p_cli = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12865 nss_chains_ini_cfg-> 12866 rx_nss[band], 12867 P2P_CLI_CHAINS_SHIFT)); 12868 vdev_nss->p2p_dev = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12869 nss_chains_ini_cfg-> 12870 rx_nss[band], 12871 P2P_DEV_NSS_CHAINS_SHIFT)); 12872 vdev_nss->ibss = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12873 nss_chains_ini_cfg-> 12874 rx_nss[band], 12875 IBSS_NSS_CHAINS_SHIFT)); 12876 vdev_nss->tdls = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12877 nss_chains_ini_cfg-> 12878 rx_nss[band], 12879 TDLS_NSS_CHAINS_SHIFT)); 12880 vdev_nss->ocb = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12881 nss_chains_ini_cfg-> 12882 rx_nss[band], 12883 OCB_NSS_CHAINS_SHIFT)); 12884 vdev_nss->nan = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12885 nss_chains_ini_cfg-> 12886 rx_nss[band], 12887 NAN_NSS_CHAIN_SHIFT)); 12888 vdev_nss->ndi = QDF_MIN(max_supp_nss, GET_VDEV_NSS_CHAIN( 12889 nss_chains_ini_cfg-> 12890 rx_nss[band], 12891 NAN_NSS_CHAIN_SHIFT)); 12892 12893 sme_debug("band %d NSS:sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d nan %d", 12894 band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli, 12895 vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss, 12896 vdev_nss->tdls, vdev_nss->ocb, vdev_nss->nan); 12897 } 12898 12899 #ifdef WLAN_FEATURE_11AX_BSS_COLOR 12900 #define MAX_BSS_COLOR_VAL 63 12901 #define MIN_BSS_COLOR_VAL 1 12902 sme_set_he_bss_color(mac_handle_t mac_handle,uint8_t session_id,uint8_t bss_color)12903 QDF_STATUS sme_set_he_bss_color(mac_handle_t mac_handle, uint8_t session_id, 12904 uint8_t bss_color) 12905 12906 { 12907 struct sir_set_he_bss_color *bss_color_msg; 12908 uint8_t len; 12909 12910 if (!mac_handle) { 12911 sme_err("Invalid mac_handle pointer"); 12912 return QDF_STATUS_E_FAULT; 12913 } 12914 12915 sme_debug("Set HE bss_color %d", bss_color); 12916 12917 if (bss_color < MIN_BSS_COLOR_VAL || bss_color > MAX_BSS_COLOR_VAL) { 12918 sme_debug("Invalid HE bss_color %d", bss_color); 12919 return QDF_STATUS_E_INVAL; 12920 } 12921 len = sizeof(*bss_color_msg); 12922 bss_color_msg = qdf_mem_malloc(len); 12923 if (!bss_color_msg) 12924 return QDF_STATUS_E_NOMEM; 12925 12926 bss_color_msg->message_type = eWNI_SME_SET_HE_BSS_COLOR; 12927 bss_color_msg->length = len; 12928 bss_color_msg->vdev_id = session_id; 12929 bss_color_msg->bss_color = bss_color; 12930 return umac_send_mb_message_to_mac(bss_color_msg); 12931 } 12932 sme_reconfig_obss_scan_param(mac_handle_t mac_handle,uint8_t session_id,bool is_scan_reconfig)12933 QDF_STATUS sme_reconfig_obss_scan_param(mac_handle_t mac_handle, 12934 uint8_t session_id, 12935 bool is_scan_reconfig) 12936 { 12937 struct sir_cfg_obss_scan *obss_scan_msg; 12938 uint8_t len; 12939 12940 if (!mac_handle) { 12941 sme_err("Invalid mac_handle pointer"); 12942 return QDF_STATUS_E_FAULT; 12943 } 12944 12945 len = sizeof(*obss_scan_msg); 12946 obss_scan_msg = qdf_mem_malloc(len); 12947 if (!obss_scan_msg) 12948 return QDF_STATUS_E_NOMEM; 12949 12950 obss_scan_msg->message_type = eWNI_SME_RECONFIG_OBSS_SCAN_PARAM; 12951 obss_scan_msg->length = len; 12952 obss_scan_msg->vdev_id = session_id; 12953 obss_scan_msg->is_scan_reconfig = is_scan_reconfig; 12954 return umac_send_mb_message_to_mac(obss_scan_msg); 12955 } 12956 #endif 12957 12958 #ifdef FEATURE_P2P_LISTEN_OFFLOAD 12959 /** 12960 * sme_register_p2p_lo_event() - Register for the p2p lo event 12961 * @mac_handle: Opaque handle to the global MAC context 12962 * @context: the context of the call 12963 * @callback: the callback to hdd 12964 * 12965 * This function registers the callback function for P2P listen 12966 * offload stop event. 12967 * 12968 * Return: none 12969 */ sme_register_p2p_lo_event(mac_handle_t mac_handle,void * context,p2p_lo_callback callback)12970 void sme_register_p2p_lo_event(mac_handle_t mac_handle, void *context, 12971 p2p_lo_callback callback) 12972 { 12973 struct mac_context *mac = MAC_CONTEXT(mac_handle); 12974 QDF_STATUS status = QDF_STATUS_E_FAILURE; 12975 12976 status = sme_acquire_global_lock(&mac->sme); 12977 mac->sme.p2p_lo_event_callback = callback; 12978 mac->sme.p2p_lo_event_context = context; 12979 sme_release_global_lock(&mac->sme); 12980 } 12981 #endif 12982 12983 /** 12984 * sme_process_mac_pwr_dbg_cmd() - enable mac pwr debugging 12985 * @mac_handle: The handle returned by macOpen 12986 * @session_id: session id 12987 * @dbg_args: args for mac pwr debug command 12988 * Return: Return QDF_STATUS, otherwise appropriate failure code 12989 */ sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle,uint32_t session_id,struct sir_mac_pwr_dbg_cmd * dbg_args)12990 QDF_STATUS sme_process_mac_pwr_dbg_cmd(mac_handle_t mac_handle, 12991 uint32_t session_id, 12992 struct sir_mac_pwr_dbg_cmd *dbg_args) 12993 { 12994 struct scheduler_msg message = {0}; 12995 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 12996 struct sir_mac_pwr_dbg_cmd *req; 12997 int i; 12998 12999 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 13000 sme_err("CSR session not valid: %d", session_id); 13001 return QDF_STATUS_E_FAILURE; 13002 } 13003 13004 req = qdf_mem_malloc(sizeof(*req)); 13005 if (!req) 13006 return QDF_STATUS_E_FAILURE; 13007 13008 req->module_id = dbg_args->module_id; 13009 req->pdev_id = dbg_args->pdev_id; 13010 req->num_args = dbg_args->num_args; 13011 for (i = 0; i < req->num_args; i++) 13012 req->args[i] = dbg_args->args[i]; 13013 13014 message.type = SIR_HAL_POWER_DBG_CMD; 13015 message.bodyptr = req; 13016 13017 if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME, 13018 QDF_MODULE_ID_WMA, 13019 QDF_MODULE_ID_WMA, 13020 &message))) { 13021 sme_err("Not able to post msg to WDA!"); 13022 qdf_mem_free(req); 13023 } 13024 return QDF_STATUS_SUCCESS; 13025 } 13026 /** 13027 * sme_get_vdev_type_nss() - gets the nss per vdev type 13028 * @dev_mode: connection type. 13029 * @nss2g: Pointer to the 2G Nss parameter. 13030 * @nss5g: Pointer to the 5G Nss parameter. 13031 * 13032 * Fills the 2G and 5G Nss values based on connection type. 13033 * 13034 * Return: None 13035 */ sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode,uint8_t * nss_2g,uint8_t * nss_5g)13036 void sme_get_vdev_type_nss(enum QDF_OPMODE dev_mode, 13037 uint8_t *nss_2g, uint8_t *nss_5g) 13038 { 13039 csr_get_vdev_type_nss(dev_mode, nss_2g, nss_5g); 13040 } 13041 13042 /** 13043 * sme_update_sta_roam_policy() - update sta roam policy for 13044 * unsafe and DFS channels. 13045 * @mac_handle: Opaque handle to the global MAC context 13046 * @dfs_mode: dfs mode which tell if dfs channel needs to be 13047 * skipped or not 13048 * @skip_unsafe_channels: Param to tell if driver needs to 13049 * skip unsafe channels or not. 13050 * @vdev_id: vdev_id 13051 * @sap_operating_band: Band on which SAP is operating 13052 * 13053 * sme_update_sta_roam_policy update sta rome policies to csr 13054 * this function will call csrUpdateChannelList as well 13055 * to include/exclude DFS channels and unsafe channels. 13056 * 13057 * Return: eHAL_STATUS_SUCCESS or non-zero on failure. 13058 */ sme_update_sta_roam_policy(mac_handle_t mac_handle,enum sta_roam_policy_dfs_mode dfs_mode,bool skip_unsafe_channels,uint8_t vdev_id,uint8_t sap_operating_band)13059 QDF_STATUS sme_update_sta_roam_policy(mac_handle_t mac_handle, 13060 enum sta_roam_policy_dfs_mode dfs_mode, 13061 bool skip_unsafe_channels, 13062 uint8_t vdev_id, 13063 uint8_t sap_operating_band) 13064 { 13065 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13066 QDF_STATUS status = QDF_STATUS_SUCCESS; 13067 struct wlan_mlme_psoc_ext_obj *mlme_obj; 13068 13069 if (!mac_ctx) { 13070 sme_err("mac_ctx is null"); 13071 return QDF_STATUS_E_FAILURE; 13072 } 13073 13074 mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); 13075 if (!mlme_obj) 13076 return QDF_STATUS_E_FAILURE; 13077 13078 mlme_obj->cfg.lfr.rso_user_config.policy_params.dfs_mode = 13079 dfs_mode; 13080 mlme_obj->cfg.lfr.rso_user_config.policy_params.skip_unsafe_channels = 13081 skip_unsafe_channels; 13082 mlme_obj->cfg.lfr.rso_user_config.policy_params.sap_operating_band = 13083 sap_operating_band; 13084 13085 status = csr_update_channel_list(mac_ctx); 13086 if (QDF_STATUS_SUCCESS != status) { 13087 sme_err("failed to update the supported channel list"); 13088 } 13089 13090 if (mac_ctx->mlme_cfg->lfr.roam_scan_offload_enabled) { 13091 status = sme_acquire_global_lock(&mac_ctx->sme); 13092 if (QDF_IS_STATUS_SUCCESS(status)) { 13093 wlan_roam_update_cfg(mac_ctx->psoc, vdev_id, 13094 REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED); 13095 sme_release_global_lock(&mac_ctx->sme); 13096 } 13097 } 13098 13099 return status; 13100 } 13101 13102 /** 13103 * sme_enable_disable_chanavoidind_event - configure ca event ind 13104 * @mac_handle: Opaque handle to the global MAC context 13105 * @set_value: enable/disable 13106 * 13107 * function to enable/disable chan avoidance indication 13108 * 13109 * Return: QDF_STATUS 13110 */ sme_enable_disable_chanavoidind_event(mac_handle_t mac_handle,uint8_t set_value)13111 QDF_STATUS sme_enable_disable_chanavoidind_event(mac_handle_t mac_handle, 13112 uint8_t set_value) 13113 { 13114 QDF_STATUS status; 13115 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13116 struct scheduler_msg msg = {0}; 13117 13118 if (!mac_ctx->mlme_cfg->gen.optimize_ca_event) { 13119 sme_debug("optimize_ca_event not enabled in ini"); 13120 return QDF_STATUS_E_NOSUPPORT; 13121 } 13122 13123 sme_debug("set_value: %d", set_value); 13124 status = sme_acquire_global_lock(&mac_ctx->sme); 13125 if (QDF_STATUS_SUCCESS == status) { 13126 qdf_mem_zero(&msg, sizeof(struct scheduler_msg)); 13127 msg.type = WMA_SEND_FREQ_RANGE_CONTROL_IND; 13128 msg.bodyval = set_value; 13129 status = scheduler_post_message(QDF_MODULE_ID_SME, 13130 QDF_MODULE_ID_WMA, 13131 QDF_MODULE_ID_WMA, &msg); 13132 sme_release_global_lock(&mac_ctx->sme); 13133 return status; 13134 } 13135 return status; 13136 } 13137 13138 /* 13139 * sme_set_default_scan_ie() - API to send default scan IE to LIM 13140 * @mac_handle: Opaque handle to the global MAC context 13141 * @session_id: current session ID 13142 * @ie_data: Pointer to Scan IE data 13143 * @ie_len: Length of @ie_data 13144 * 13145 * Return: QDF_STATUS 13146 */ sme_set_default_scan_ie(mac_handle_t mac_handle,uint16_t session_id,uint8_t * ie_data,uint16_t ie_len)13147 QDF_STATUS sme_set_default_scan_ie(mac_handle_t mac_handle, uint16_t session_id, 13148 uint8_t *ie_data, uint16_t ie_len) 13149 { 13150 QDF_STATUS status; 13151 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13152 struct hdd_default_scan_ie *set_ie_params; 13153 13154 if (!ie_data) 13155 return QDF_STATUS_E_INVAL; 13156 13157 status = sme_acquire_global_lock(&mac_ctx->sme); 13158 if (QDF_IS_STATUS_SUCCESS(status)) { 13159 set_ie_params = qdf_mem_malloc(sizeof(*set_ie_params)); 13160 if (!set_ie_params) 13161 status = QDF_STATUS_E_NOMEM; 13162 else { 13163 set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE; 13164 set_ie_params->length = sizeof(*set_ie_params); 13165 set_ie_params->vdev_id = session_id; 13166 set_ie_params->ie_len = ie_len; 13167 qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len); 13168 status = umac_send_mb_message_to_mac(set_ie_params); 13169 } 13170 sme_release_global_lock(&mac_ctx->sme); 13171 } 13172 return status; 13173 } 13174 sme_get_sar_power_limits(mac_handle_t mac_handle,wma_sar_cb callback,void * context)13175 QDF_STATUS sme_get_sar_power_limits(mac_handle_t mac_handle, 13176 wma_sar_cb callback, void *context) 13177 { 13178 void *wma_handle; 13179 13180 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13181 if (!wma_handle) 13182 return QDF_STATUS_E_FAILURE; 13183 13184 return wma_get_sar_limit(wma_handle, callback, context); 13185 } 13186 sme_set_sar_power_limits(mac_handle_t mac_handle,struct sar_limit_cmd_params * sar_limit_cmd)13187 QDF_STATUS sme_set_sar_power_limits(mac_handle_t mac_handle, 13188 struct sar_limit_cmd_params *sar_limit_cmd) 13189 { 13190 void *wma_handle; 13191 13192 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13193 if (!wma_handle) 13194 return QDF_STATUS_E_FAILURE; 13195 13196 return wma_set_sar_limit(wma_handle, sar_limit_cmd); 13197 } 13198 sme_send_coex_config_cmd(struct coex_config_params * coex_cfg_params)13199 QDF_STATUS sme_send_coex_config_cmd(struct coex_config_params *coex_cfg_params) 13200 { 13201 void *wma_handle; 13202 13203 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13204 if (!wma_handle) 13205 return QDF_STATUS_E_FAILURE; 13206 13207 return wma_send_coex_config_cmd(wma_handle, coex_cfg_params); 13208 } 13209 13210 #ifdef WLAN_FEATURE_FIPS sme_fips_request(mac_handle_t mac_handle,struct fips_params * param,wma_fips_cb callback,void * context)13211 QDF_STATUS sme_fips_request(mac_handle_t mac_handle, struct fips_params *param, 13212 wma_fips_cb callback, void *context) 13213 { 13214 void *wma_handle; 13215 13216 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13217 if (!wma_handle) 13218 return QDF_STATUS_E_FAILURE; 13219 13220 return wma_fips_request(wma_handle, param, callback, context); 13221 } 13222 #endif 13223 sme_set_cts2self_for_p2p_go(mac_handle_t mac_handle)13224 QDF_STATUS sme_set_cts2self_for_p2p_go(mac_handle_t mac_handle) 13225 { 13226 void *wma_handle; 13227 13228 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13229 if (!wma_handle) 13230 return QDF_STATUS_E_FAILURE; 13231 13232 if (QDF_STATUS_SUCCESS != 13233 wma_set_cts2self_for_p2p_go(wma_handle, true)) { 13234 sme_err("Failed to set cts2self for p2p GO to firmware"); 13235 return QDF_STATUS_E_FAILURE; 13236 } 13237 return QDF_STATUS_SUCCESS; 13238 } 13239 13240 /** 13241 * sme_update_tx_fail_cnt_threshold() - update tx fail count Threshold 13242 * @mac_handle: Handle returned by mac_open 13243 * @session_id: Session ID on which tx fail count needs to be updated to FW 13244 * @tx_fail_count: Count for tx fail threshold after which FW will disconnect 13245 * 13246 * This function is used to set tx fail count threshold to firmware. 13247 * firmware will issue disocnnect with peer device once this threshold is 13248 * reached. 13249 * 13250 * Return: Return QDF_STATUS, otherwise appropriate failure code 13251 */ sme_update_tx_fail_cnt_threshold(mac_handle_t mac_handle,uint8_t session_id,uint32_t tx_fail_count)13252 QDF_STATUS sme_update_tx_fail_cnt_threshold(mac_handle_t mac_handle, 13253 uint8_t session_id, 13254 uint32_t tx_fail_count) 13255 { 13256 QDF_STATUS status = QDF_STATUS_E_FAILURE; 13257 struct sme_tx_fail_cnt_threshold *tx_fail_cnt; 13258 struct scheduler_msg msg = {0}; 13259 13260 tx_fail_cnt = qdf_mem_malloc(sizeof(*tx_fail_cnt)); 13261 if (!tx_fail_cnt) 13262 return QDF_STATUS_E_FAILURE; 13263 13264 sme_debug("session_id: %d tx_fail_count: %d", 13265 session_id, tx_fail_count); 13266 tx_fail_cnt->session_id = session_id; 13267 tx_fail_cnt->tx_fail_cnt_threshold = tx_fail_count; 13268 13269 qdf_mem_zero(&msg, sizeof(struct scheduler_msg)); 13270 msg.type = SIR_HAL_UPDATE_TX_FAIL_CNT_TH; 13271 msg.reserved = 0; 13272 msg.bodyptr = tx_fail_cnt; 13273 status = scheduler_post_message(QDF_MODULE_ID_SME, 13274 QDF_MODULE_ID_WMA, 13275 QDF_MODULE_ID_WMA, &msg); 13276 13277 if (!QDF_IS_STATUS_SUCCESS(status)) { 13278 sme_err("Not able to post Tx fail count message to WDA"); 13279 qdf_mem_free(tx_fail_cnt); 13280 } 13281 return status; 13282 } 13283 sme_set_lost_link_info_cb(mac_handle_t mac_handle,lost_link_info_cb cb)13284 QDF_STATUS sme_set_lost_link_info_cb(mac_handle_t mac_handle, 13285 lost_link_info_cb cb) 13286 { 13287 QDF_STATUS status; 13288 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13289 13290 status = sme_acquire_global_lock(&mac->sme); 13291 if (QDF_IS_STATUS_SUCCESS(status)) { 13292 mac->sme.lost_link_info_cb = cb; 13293 sme_release_global_lock(&mac->sme); 13294 } 13295 13296 return status; 13297 } 13298 sme_neighbor_roam_is11r_assoc(mac_handle_t mac_handle,uint8_t session_id)13299 bool sme_neighbor_roam_is11r_assoc(mac_handle_t mac_handle, uint8_t session_id) 13300 { 13301 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13302 struct cm_roam_values_copy config; 13303 13304 wlan_cm_roam_cfg_get_value(mac_ctx->psoc, session_id, IS_11R_CONNECTION, 13305 &config); 13306 13307 return config.bool_value; 13308 } 13309 13310 #ifdef WLAN_FEATURE_WOW_PULSE 13311 /** 13312 * sme_set_wow_pulse() - set wow pulse info 13313 * @wow_pulse_set_info: wow_pulse_mode structure pointer 13314 * 13315 * Return: QDF_STATUS 13316 */ sme_set_wow_pulse(struct wow_pulse_mode * wow_pulse_set_info)13317 QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info) 13318 { 13319 struct scheduler_msg message = {0}; 13320 QDF_STATUS status; 13321 struct wow_pulse_mode *wow_pulse_set_cmd; 13322 13323 if (!wow_pulse_set_info) { 13324 sme_err("invalid wow_pulse_set_info pointer"); 13325 return QDF_STATUS_E_FAILURE; 13326 } 13327 13328 wow_pulse_set_cmd = qdf_mem_malloc(sizeof(*wow_pulse_set_cmd)); 13329 if (!wow_pulse_set_cmd) 13330 return QDF_STATUS_E_NOMEM; 13331 13332 *wow_pulse_set_cmd = *wow_pulse_set_info; 13333 13334 message.type = WMA_SET_WOW_PULSE_CMD; 13335 message.bodyptr = wow_pulse_set_cmd; 13336 status = scheduler_post_message(QDF_MODULE_ID_SME, 13337 QDF_MODULE_ID_WMA, 13338 QDF_MODULE_ID_WMA, 13339 &message); 13340 if (!QDF_IS_STATUS_SUCCESS(status)) { 13341 sme_err("Not able to post msg to WDA!"); 13342 qdf_mem_free(wow_pulse_set_cmd); 13343 status = QDF_STATUS_E_FAILURE; 13344 } 13345 13346 return status; 13347 } 13348 #endif 13349 sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle,const uint8_t * bssid,int8_t * rssi,int8_t * snr)13350 QDF_STATUS sme_get_rssi_snr_by_bssid(mac_handle_t mac_handle, 13351 const uint8_t *bssid, 13352 int8_t *rssi, int8_t *snr) 13353 { 13354 QDF_STATUS status = QDF_STATUS_SUCCESS; 13355 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13356 struct qdf_mac_addr mac_addr; 13357 13358 qdf_mem_copy(mac_addr.bytes, 13359 bssid, sizeof(struct qdf_mac_addr)); 13360 status = cm_get_rssi_snr_by_bssid(mac_ctx->pdev, &mac_addr, rssi, snr); 13361 13362 sme_debug("status %d snr: %d, rssi: %d", status, 13363 snr ? *snr : 0, rssi ? *rssi: 0); 13364 13365 return status; 13366 } 13367 sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache_info)13368 void sme_clear_sae_single_pmk_info(struct wlan_objmgr_psoc *psoc, 13369 uint8_t session_id, 13370 struct wlan_crypto_pmksa *pmk_cache_info) 13371 { 13372 struct wlan_crypto_pmksa *pmksa; 13373 struct wlan_objmgr_vdev *vdev; 13374 struct wlan_crypto_pmksa pmk_to_del; 13375 13376 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, 13377 WLAN_LEGACY_SME_ID); 13378 if (!vdev) { 13379 sme_err("Invalid vdev"); 13380 return; 13381 } 13382 pmksa = wlan_crypto_get_pmksa(vdev, &pmk_cache_info->bssid); 13383 if (!pmksa) { 13384 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 13385 return; 13386 } 13387 qdf_mem_copy(&pmk_to_del.pmk, pmksa->pmk, pmksa->pmk_len); 13388 pmk_to_del.pmk_len = pmksa->pmk_len; 13389 csr_clear_sae_single_pmk(psoc, session_id, &pmk_to_del); 13390 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 13391 } 13392 sme_set_del_pmkid_cache(struct wlan_objmgr_psoc * psoc,uint8_t session_id,struct wlan_crypto_pmksa * pmk_cache_info,bool is_add)13393 QDF_STATUS sme_set_del_pmkid_cache(struct wlan_objmgr_psoc *psoc, 13394 uint8_t session_id, 13395 struct wlan_crypto_pmksa *pmk_cache_info, 13396 bool is_add) 13397 { 13398 struct wmi_unified_pmk_cache *pmk_cache; 13399 struct scheduler_msg msg; 13400 13401 pmk_cache = qdf_mem_malloc(sizeof(*pmk_cache)); 13402 if (!pmk_cache) 13403 return QDF_STATUS_E_NOMEM; 13404 13405 qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); 13406 13407 pmk_cache->vdev_id = session_id; 13408 13409 if (!pmk_cache_info) { 13410 pmk_cache->is_flush_all = true; 13411 csr_clear_sae_single_pmk(psoc, session_id, NULL); 13412 goto send_flush_cmd; 13413 } 13414 13415 if (!pmk_cache_info->ssid_len) { 13416 pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_BSSID; 13417 WMI_CHAR_ARRAY_TO_MAC_ADDR(pmk_cache_info->bssid.bytes, 13418 &pmk_cache->bssid); 13419 } else { 13420 pmk_cache->cat_flag = WMI_PMK_CACHE_CAT_FLAG_SSID_CACHE_ID; 13421 pmk_cache->ssid.length = pmk_cache_info->ssid_len; 13422 qdf_mem_copy(pmk_cache->ssid.ssid, 13423 pmk_cache_info->ssid, 13424 pmk_cache->ssid.length); 13425 } 13426 pmk_cache->cache_id = (uint32_t) (pmk_cache_info->cache_id[0] << 8 | 13427 pmk_cache_info->cache_id[1]); 13428 13429 if (is_add) 13430 pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_ADD_ENTRY; 13431 else 13432 pmk_cache->action_flag = WMI_PMK_CACHE_ACTION_FLAG_DEL_ENTRY; 13433 13434 pmk_cache->pmkid_len = PMKID_LEN; 13435 qdf_mem_copy(pmk_cache->pmkid, pmk_cache_info->pmkid, 13436 PMKID_LEN); 13437 13438 pmk_cache->pmk_len = pmk_cache_info->pmk_len; 13439 qdf_mem_copy(pmk_cache->pmk, pmk_cache_info->pmk, 13440 pmk_cache->pmk_len); 13441 13442 send_flush_cmd: 13443 msg.type = SIR_HAL_SET_DEL_PMKID_CACHE; 13444 msg.reserved = 0; 13445 msg.bodyptr = pmk_cache; 13446 if (QDF_STATUS_SUCCESS != 13447 scheduler_post_message(QDF_MODULE_ID_SME, 13448 QDF_MODULE_ID_WMA, 13449 QDF_MODULE_ID_WMA, &msg)) { 13450 sme_err("Not able to post message to WDA"); 13451 if (pmk_cache) { 13452 qdf_mem_zero(pmk_cache, sizeof(*pmk_cache)); 13453 qdf_mem_free(pmk_cache); 13454 } 13455 return QDF_STATUS_E_FAILURE; 13456 } 13457 13458 return QDF_STATUS_SUCCESS; 13459 } 13460 13461 /* ARP DEBUG STATS */ 13462 13463 /** 13464 * sme_set_nud_debug_stats() - sme api to set nud debug stats 13465 * @mac_handle: Opaque handle to the global MAC context 13466 * @set_stats_param: pointer to set stats param 13467 * 13468 * Return: Return QDF_STATUS. 13469 */ sme_set_nud_debug_stats(mac_handle_t mac_handle,struct set_arp_stats_params * set_stats_param)13470 QDF_STATUS sme_set_nud_debug_stats(mac_handle_t mac_handle, 13471 struct set_arp_stats_params 13472 *set_stats_param) 13473 { 13474 struct set_arp_stats_params *arp_set_param; 13475 struct scheduler_msg msg; 13476 13477 arp_set_param = qdf_mem_malloc(sizeof(*arp_set_param)); 13478 if (!arp_set_param) 13479 return QDF_STATUS_E_NOMEM; 13480 13481 qdf_mem_copy(arp_set_param, set_stats_param, sizeof(*arp_set_param)); 13482 13483 msg.type = WMA_SET_ARP_STATS_REQ; 13484 msg.reserved = 0; 13485 msg.bodyptr = arp_set_param; 13486 13487 if (QDF_STATUS_SUCCESS != 13488 scheduler_post_message(QDF_MODULE_ID_SME, 13489 QDF_MODULE_ID_WMA, 13490 QDF_MODULE_ID_WMA, &msg)) { 13491 sme_err("Not able to post message to WDA"); 13492 qdf_mem_free(arp_set_param); 13493 return QDF_STATUS_E_FAILURE; 13494 } 13495 13496 return QDF_STATUS_SUCCESS; 13497 } 13498 13499 /** 13500 * sme_get_nud_debug_stats() - sme api to get nud debug stats 13501 * @mac_handle: Opaque handle to the global MAC context 13502 * @get_stats_param: pointer to set stats param 13503 * 13504 * Return: Return QDF_STATUS. 13505 */ sme_get_nud_debug_stats(mac_handle_t mac_handle,struct get_arp_stats_params * get_stats_param)13506 QDF_STATUS sme_get_nud_debug_stats(mac_handle_t mac_handle, 13507 struct get_arp_stats_params 13508 *get_stats_param) 13509 { 13510 struct get_arp_stats_params *arp_get_param; 13511 struct scheduler_msg msg; 13512 13513 arp_get_param = qdf_mem_malloc(sizeof(*arp_get_param)); 13514 if (!arp_get_param) 13515 return QDF_STATUS_E_NOMEM; 13516 13517 qdf_mem_copy(arp_get_param, get_stats_param, sizeof(*arp_get_param)); 13518 13519 msg.type = WMA_GET_ARP_STATS_REQ; 13520 msg.reserved = 0; 13521 msg.bodyptr = arp_get_param; 13522 13523 if (QDF_STATUS_SUCCESS != 13524 scheduler_post_message(QDF_MODULE_ID_SME, 13525 QDF_MODULE_ID_WMA, 13526 QDF_MODULE_ID_WMA, &msg)) { 13527 sme_err("Not able to post message to WDA"); 13528 qdf_mem_free(arp_get_param); 13529 return QDF_STATUS_E_FAILURE; 13530 } 13531 13532 return QDF_STATUS_SUCCESS; 13533 } 13534 sme_set_peer_param(uint8_t * peer_addr,uint32_t param_id,uint32_t param_value,uint32_t vdev_id)13535 QDF_STATUS sme_set_peer_param(uint8_t *peer_addr, uint32_t param_id, 13536 uint32_t param_value, uint32_t vdev_id) 13537 { 13538 void *wma_handle; 13539 13540 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13541 if (!wma_handle) 13542 return QDF_STATUS_E_FAILURE; 13543 13544 return wma_set_peer_param(wma_handle, peer_addr, param_id, 13545 param_value, vdev_id); 13546 } 13547 sme_register_set_connection_info_cb(mac_handle_t mac_handle,bool (* set_connection_info_cb)(bool),bool (* get_connection_info_cb)(uint8_t * session_id,enum scan_reject_states * reason))13548 QDF_STATUS sme_register_set_connection_info_cb(mac_handle_t mac_handle, 13549 bool (*set_connection_info_cb)(bool), 13550 bool (*get_connection_info_cb)(uint8_t *session_id, 13551 enum scan_reject_states *reason)) 13552 { 13553 QDF_STATUS status = QDF_STATUS_SUCCESS; 13554 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13555 13556 status = sme_acquire_global_lock(&mac->sme); 13557 if (QDF_IS_STATUS_SUCCESS(status)) { 13558 mac->sme.set_connection_info_cb = set_connection_info_cb; 13559 mac->sme.get_connection_info_cb = get_connection_info_cb; 13560 sme_release_global_lock(&mac->sme); 13561 } 13562 return status; 13563 } 13564 sme_rso_cmd_status_cb(mac_handle_t mac_handle,rso_cmd_status_cb cb)13565 QDF_STATUS sme_rso_cmd_status_cb(mac_handle_t mac_handle, 13566 rso_cmd_status_cb cb) 13567 { 13568 QDF_STATUS status = QDF_STATUS_SUCCESS; 13569 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13570 13571 mac->sme.rso_cmd_status_cb = cb; 13572 sme_debug("Registered RSO command status callback"); 13573 return status; 13574 } 13575 sme_set_dbs_scan_selection_config(mac_handle_t mac_handle,struct wmi_dbs_scan_sel_params * params)13576 QDF_STATUS sme_set_dbs_scan_selection_config(mac_handle_t mac_handle, 13577 struct wmi_dbs_scan_sel_params *params) 13578 { 13579 struct scheduler_msg message = {0}; 13580 QDF_STATUS status; 13581 struct wmi_dbs_scan_sel_params *dbs_scan_params; 13582 uint32_t i; 13583 13584 if (0 == params->num_clients) { 13585 sme_err("Num of clients is 0"); 13586 return QDF_STATUS_E_FAILURE; 13587 } 13588 13589 dbs_scan_params = qdf_mem_malloc(sizeof(*dbs_scan_params)); 13590 if (!dbs_scan_params) 13591 return QDF_STATUS_E_NOMEM; 13592 13593 dbs_scan_params->num_clients = params->num_clients; 13594 dbs_scan_params->pdev_id = params->pdev_id; 13595 for (i = 0; i < params->num_clients; i++) { 13596 dbs_scan_params->module_id[i] = params->module_id[i]; 13597 dbs_scan_params->num_dbs_scans[i] = params->num_dbs_scans[i]; 13598 dbs_scan_params->num_non_dbs_scans[i] = 13599 params->num_non_dbs_scans[i]; 13600 } 13601 message.type = WMA_SET_DBS_SCAN_SEL_CONF_PARAMS; 13602 message.bodyptr = dbs_scan_params; 13603 status = scheduler_post_message(QDF_MODULE_ID_SME, 13604 QDF_MODULE_ID_WMA, 13605 QDF_MODULE_ID_WMA, &message); 13606 if (!QDF_IS_STATUS_SUCCESS(status)) { 13607 sme_err("Not able to post msg to WMA!"); 13608 qdf_mem_free(dbs_scan_params); 13609 } 13610 13611 return status; 13612 } 13613 sme_get_rcpi(mac_handle_t mac_handle,struct sme_rcpi_req * rcpi)13614 QDF_STATUS sme_get_rcpi(mac_handle_t mac_handle, struct sme_rcpi_req *rcpi) 13615 { 13616 QDF_STATUS status = QDF_STATUS_E_FAILURE; 13617 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13618 struct scheduler_msg msg = {0}; 13619 struct sme_rcpi_req *rcpi_req; 13620 13621 rcpi_req = qdf_mem_malloc(sizeof(*rcpi_req)); 13622 if (!rcpi_req) 13623 return QDF_STATUS_E_NOMEM; 13624 13625 qdf_mem_copy(rcpi_req, rcpi, sizeof(*rcpi_req)); 13626 13627 status = sme_acquire_global_lock(&mac->sme); 13628 if (QDF_IS_STATUS_SUCCESS(status)) { 13629 msg.bodyptr = rcpi_req; 13630 msg.type = WMA_GET_RCPI_REQ; 13631 status = scheduler_post_message(QDF_MODULE_ID_SME, 13632 QDF_MODULE_ID_WMA, 13633 QDF_MODULE_ID_WMA, &msg); 13634 sme_release_global_lock(&mac->sme); 13635 if (!QDF_IS_STATUS_SUCCESS(status)) { 13636 sme_err("post get rcpi req failed"); 13637 status = QDF_STATUS_E_FAILURE; 13638 qdf_mem_free(rcpi_req); 13639 } 13640 } else { 13641 qdf_mem_free(rcpi_req); 13642 } 13643 13644 return status; 13645 } 13646 sme_store_pdev(mac_handle_t mac_handle,struct wlan_objmgr_pdev * pdev)13647 void sme_store_pdev(mac_handle_t mac_handle, struct wlan_objmgr_pdev *pdev) 13648 { 13649 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 13650 void *wma_handle; 13651 QDF_STATUS status; 13652 13653 status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_LEGACY_MAC_ID); 13654 if (QDF_STATUS_SUCCESS != status) { 13655 mac_ctx->pdev = NULL; 13656 return; 13657 } 13658 mac_ctx->pdev = pdev; 13659 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13660 if (!wma_handle) 13661 return; 13662 13663 wma_store_pdev(wma_handle, pdev); 13664 pdev->pdev_nif.pdev_fw_caps |= SUPPORTED_CRYPTO_CAPS; 13665 } 13666 sme_register_tx_queue_cb(mac_handle_t mac_handle,tx_queue_cb tx_queue_cb)13667 QDF_STATUS sme_register_tx_queue_cb(mac_handle_t mac_handle, 13668 tx_queue_cb tx_queue_cb) 13669 { 13670 QDF_STATUS status; 13671 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13672 13673 status = sme_acquire_global_lock(&mac->sme); 13674 if (QDF_IS_STATUS_SUCCESS(status)) { 13675 mac->sme.tx_queue_cb = tx_queue_cb; 13676 sme_release_global_lock(&mac->sme); 13677 sme_debug("Tx queue callback set"); 13678 } 13679 13680 return status; 13681 } 13682 sme_deregister_tx_queue_cb(mac_handle_t mac_handle)13683 QDF_STATUS sme_deregister_tx_queue_cb(mac_handle_t mac_handle) 13684 { 13685 return sme_register_tx_queue_cb(mac_handle, NULL); 13686 } 13687 13688 #ifdef WLAN_SUPPORT_TWT 13689 sme_test_config_twt_setup(struct wmi_twt_add_dialog_param * params)13690 QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params) 13691 { 13692 t_wma_handle *wma_handle; 13693 13694 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13695 if (!wma_handle) 13696 return QDF_STATUS_E_FAILURE; 13697 13698 return wma_twt_process_add_dialog(wma_handle, params); 13699 } 13700 13701 QDF_STATUS sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param * params)13702 sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params) 13703 { 13704 t_wma_handle *wma_handle; 13705 13706 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13707 if (!wma_handle) 13708 return QDF_STATUS_E_FAILURE; 13709 13710 return wma_twt_process_del_dialog(wma_handle, params); 13711 } 13712 sme_clear_twt_complete_cb(mac_handle_t mac_handle)13713 QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle) 13714 { 13715 QDF_STATUS status; 13716 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13717 13718 status = sme_acquire_global_lock(&mac->sme); 13719 if (QDF_IS_STATUS_SUCCESS(status)) { 13720 mac->sme.twt_add_dialog_cb = NULL; 13721 mac->sme.twt_del_dialog_cb = NULL; 13722 mac->sme.twt_pause_dialog_cb = NULL; 13723 mac->sme.twt_resume_dialog_cb = NULL; 13724 mac->sme.twt_notify_cb = NULL; 13725 mac->sme.twt_nudge_dialog_cb = NULL; 13726 mac->sme.twt_ack_comp_cb = NULL; 13727 sme_release_global_lock(&mac->sme); 13728 13729 sme_debug("TWT: callbacks Initialized"); 13730 } 13731 13732 return status; 13733 } 13734 sme_register_twt_callbacks(mac_handle_t mac_handle,struct twt_callbacks * twt_cb)13735 QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle, 13736 struct twt_callbacks *twt_cb) 13737 { 13738 QDF_STATUS status; 13739 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13740 13741 status = sme_acquire_global_lock(&mac->sme); 13742 if (QDF_IS_STATUS_SUCCESS(status)) { 13743 mac->sme.twt_enable_cb = twt_cb->twt_enable_cb; 13744 mac->sme.twt_add_dialog_cb = twt_cb->twt_add_dialog_cb; 13745 mac->sme.twt_del_dialog_cb = twt_cb->twt_del_dialog_cb; 13746 mac->sme.twt_pause_dialog_cb = twt_cb->twt_pause_dialog_cb; 13747 mac->sme.twt_resume_dialog_cb = twt_cb->twt_resume_dialog_cb; 13748 mac->sme.twt_disable_cb = twt_cb->twt_disable_cb; 13749 mac->sme.twt_notify_cb = twt_cb->twt_notify_cb; 13750 mac->sme.twt_nudge_dialog_cb = twt_cb->twt_nudge_dialog_cb; 13751 mac->sme.twt_ack_comp_cb = twt_cb->twt_ack_comp_cb; 13752 sme_release_global_lock(&mac->sme); 13753 sme_debug("TWT: callbacks registered"); 13754 } 13755 13756 return status; 13757 } 13758 sme_add_dialog_cmd(mac_handle_t mac_handle,twt_add_dialog_cb twt_add_dialog_cb,struct wmi_twt_add_dialog_param * twt_params,void * context)13759 QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle, 13760 twt_add_dialog_cb twt_add_dialog_cb, 13761 struct wmi_twt_add_dialog_param *twt_params, 13762 void *context) 13763 { 13764 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13765 struct scheduler_msg twt_msg = {0}; 13766 bool is_twt_cmd_in_progress, is_twt_notify_in_progress; 13767 bool usr_cfg_ps_enable; 13768 QDF_STATUS status; 13769 void *wma_handle; 13770 struct wmi_twt_add_dialog_param *cmd_params; 13771 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 13772 13773 SME_ENTER(); 13774 13775 usr_cfg_ps_enable = mlme_get_user_ps(mac->psoc, twt_params->vdev_id); 13776 if (!usr_cfg_ps_enable) { 13777 sme_debug("Power save mode disable"); 13778 return QDF_STATUS_E_AGAIN; 13779 } 13780 13781 is_twt_notify_in_progress = mlme_is_twt_notify_in_progress( 13782 mac->psoc, twt_params->vdev_id); 13783 13784 if (is_twt_notify_in_progress) { 13785 sme_debug("Waiting for TWT Notify"); 13786 return QDF_STATUS_E_BUSY; 13787 } 13788 13789 is_twt_cmd_in_progress = mlme_twt_is_command_in_progress( 13790 mac->psoc, 13791 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13792 twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd); 13793 if (is_twt_cmd_in_progress) { 13794 sme_debug("Already TWT command:%d is in progress", active_cmd); 13795 return QDF_STATUS_E_PENDING; 13796 } 13797 13798 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13799 if (!wma_handle) 13800 return QDF_STATUS_E_FAILURE; 13801 13802 /*bodyptr should be freeable*/ 13803 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 13804 if (!cmd_params) 13805 return QDF_STATUS_E_NOMEM; 13806 13807 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 13808 13809 status = sme_acquire_global_lock(&mac->sme); 13810 if (QDF_IS_STATUS_ERROR(status)) { 13811 sme_err("failed to register add dialog callback"); 13812 qdf_mem_free(cmd_params); 13813 return status; 13814 } 13815 13816 /* 13817 * Add the dialog id to TWT context to drop back to back 13818 * commands 13819 */ 13820 mlme_add_twt_session(mac->psoc, 13821 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13822 twt_params->dialog_id); 13823 13824 mlme_set_twt_command_in_progress(mac->psoc, 13825 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13826 twt_params->dialog_id, WLAN_TWT_SETUP); 13827 13828 /* Serialize the req through MC thread */ 13829 mac->sme.twt_add_dialog_cb = twt_add_dialog_cb; 13830 mac->sme.twt_ack_context_cb = context; 13831 twt_msg.bodyptr = cmd_params; 13832 twt_msg.type = WMA_TWT_ADD_DIALOG_REQUEST; 13833 sme_release_global_lock(&mac->sme); 13834 13835 status = scheduler_post_message(QDF_MODULE_ID_SME, 13836 QDF_MODULE_ID_WMA, 13837 QDF_MODULE_ID_WMA, &twt_msg); 13838 13839 if (QDF_IS_STATUS_ERROR(status)) { 13840 sme_err("Post twt add dialog msg fail"); 13841 mlme_set_twt_command_in_progress(mac->psoc, 13842 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13843 twt_params->dialog_id, WLAN_TWT_NONE); 13844 mlme_init_twt_context(mac->psoc, 13845 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13846 twt_params->dialog_id); 13847 qdf_mem_free(cmd_params); 13848 } 13849 13850 SME_EXIT(); 13851 return status; 13852 } 13853 sme_del_dialog_cmd(mac_handle_t mac_handle,twt_del_dialog_cb del_dialog_cb,struct wmi_twt_del_dialog_param * twt_params,void * context)13854 QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle, 13855 twt_del_dialog_cb del_dialog_cb, 13856 struct wmi_twt_del_dialog_param *twt_params, 13857 void *context) 13858 { 13859 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13860 struct scheduler_msg twt_msg = {0}; 13861 bool is_twt_cmd_in_progress; 13862 QDF_STATUS status; 13863 void *wma_handle; 13864 struct wmi_twt_del_dialog_param *cmd_params; 13865 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 13866 13867 SME_ENTER(); 13868 13869 is_twt_cmd_in_progress = 13870 mlme_twt_is_command_in_progress( 13871 mac->psoc, 13872 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13873 twt_params->dialog_id, WLAN_TWT_SETUP, &active_cmd) || 13874 mlme_twt_is_command_in_progress( 13875 mac->psoc, 13876 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13877 twt_params->dialog_id, WLAN_TWT_TERMINATE, 13878 &active_cmd); 13879 if (is_twt_cmd_in_progress) { 13880 sme_debug("Already TWT command:%d is in progress", active_cmd); 13881 return QDF_STATUS_E_PENDING; 13882 } 13883 13884 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13885 if (!wma_handle) 13886 return QDF_STATUS_E_FAILURE; 13887 13888 /*bodyptr should be freeable*/ 13889 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 13890 if (!cmd_params) 13891 return QDF_STATUS_E_NOMEM; 13892 13893 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 13894 13895 status = sme_acquire_global_lock(&mac->sme); 13896 if (QDF_IS_STATUS_ERROR(status)) { 13897 sme_err("Failed to acquire SME global lock"); 13898 qdf_mem_free(cmd_params); 13899 return status; 13900 } 13901 13902 mlme_set_twt_command_in_progress(mac->psoc, 13903 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13904 twt_params->dialog_id, WLAN_TWT_TERMINATE); 13905 13906 /* Serialize the req through MC thread */ 13907 mac->sme.twt_del_dialog_cb = del_dialog_cb; 13908 mac->sme.twt_ack_context_cb = context; 13909 twt_msg.bodyptr = cmd_params; 13910 twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST; 13911 sme_release_global_lock(&mac->sme); 13912 13913 status = scheduler_post_message(QDF_MODULE_ID_SME, 13914 QDF_MODULE_ID_WMA, 13915 QDF_MODULE_ID_WMA, &twt_msg); 13916 13917 if (QDF_IS_STATUS_ERROR(status)) { 13918 sme_err("Post twt del dialog msg fail"); 13919 mlme_set_twt_command_in_progress( 13920 mac->psoc, 13921 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13922 twt_params->dialog_id, WLAN_TWT_NONE); 13923 qdf_mem_free(cmd_params); 13924 } 13925 13926 SME_EXIT(); 13927 return status; 13928 } 13929 sme_sap_del_dialog_cmd(mac_handle_t mac_handle,twt_del_dialog_cb del_dialog_cb,struct wmi_twt_del_dialog_param * twt_params)13930 QDF_STATUS sme_sap_del_dialog_cmd(mac_handle_t mac_handle, 13931 twt_del_dialog_cb del_dialog_cb, 13932 struct wmi_twt_del_dialog_param *twt_params) 13933 { 13934 struct mac_context *mac = MAC_CONTEXT(mac_handle); 13935 struct scheduler_msg twt_msg = {0}; 13936 bool is_twt_cmd_in_progress; 13937 QDF_STATUS status; 13938 void *wma_handle; 13939 struct wmi_twt_del_dialog_param *cmd_params; 13940 13941 SME_ENTER(); 13942 13943 is_twt_cmd_in_progress = 13944 sme_sap_twt_is_command_in_progress(mac->psoc, 13945 twt_params->vdev_id, 13946 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13947 twt_params->dialog_id, WLAN_TWT_TERMINATE); 13948 13949 if (is_twt_cmd_in_progress) { 13950 sme_debug("Already TWT teardown command is in progress"); 13951 return QDF_STATUS_E_PENDING; 13952 } 13953 13954 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 13955 if (!wma_handle) 13956 return QDF_STATUS_E_FAILURE; 13957 13958 /* bodyptr should be freeable */ 13959 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 13960 if (!cmd_params) 13961 return QDF_STATUS_E_NOMEM; 13962 13963 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 13964 13965 status = sme_acquire_global_lock(&mac->sme); 13966 if (QDF_IS_STATUS_ERROR(status)) { 13967 qdf_mem_free(cmd_params); 13968 sme_err("Failed to acquire SME global lock"); 13969 return status; 13970 } 13971 13972 /* 13973 * Add the dialog id to TWT context to drop back to back 13974 * commands 13975 */ 13976 sme_sap_add_twt_session(mac->psoc, twt_params->vdev_id, 13977 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13978 twt_params->dialog_id); 13979 13980 sme_sap_set_twt_command_in_progress(mac->psoc, twt_params->vdev_id, 13981 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13982 twt_params->dialog_id, WLAN_TWT_TERMINATE); 13983 13984 /* Serialize the req through MC thread */ 13985 mac->sme.twt_del_dialog_cb = del_dialog_cb; 13986 twt_msg.bodyptr = cmd_params; 13987 twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST; 13988 sme_release_global_lock(&mac->sme); 13989 13990 status = scheduler_post_message(QDF_MODULE_ID_SME, 13991 QDF_MODULE_ID_WMA, 13992 QDF_MODULE_ID_WMA, &twt_msg); 13993 13994 if (QDF_IS_STATUS_ERROR(status)) { 13995 sme_err("Post twt del dialog msg fail"); 13996 sme_sap_set_twt_command_in_progress(mac->psoc, 13997 twt_params->vdev_id, 13998 (struct qdf_mac_addr *)twt_params->peer_macaddr, 13999 twt_params->dialog_id, WLAN_TWT_NONE); 14000 sme_sap_init_twt_context(mac->psoc, 14001 twt_params->vdev_id, 14002 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14003 twt_params->dialog_id); 14004 qdf_mem_free(cmd_params); 14005 } 14006 14007 SME_EXIT(); 14008 return status; 14009 } 14010 14011 QDF_STATUS sme_pause_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_pause_dialog_cmd_param * twt_params,void * context)14012 sme_pause_dialog_cmd(mac_handle_t mac_handle, 14013 struct wmi_twt_pause_dialog_cmd_param *twt_params, 14014 void *context) 14015 { 14016 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14017 struct wmi_twt_pause_dialog_cmd_param *cmd_params; 14018 struct scheduler_msg twt_msg = {0}; 14019 bool is_twt_cmd_in_progress; 14020 QDF_STATUS status; 14021 void *wma_handle; 14022 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 14023 14024 SME_ENTER(); 14025 14026 is_twt_cmd_in_progress = mlme_twt_is_command_in_progress( 14027 mac->psoc, 14028 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14029 twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd); 14030 if (is_twt_cmd_in_progress) { 14031 sme_debug("Already TWT command:%d is in progress", active_cmd); 14032 return QDF_STATUS_E_PENDING; 14033 } 14034 14035 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14036 if (!wma_handle) 14037 return QDF_STATUS_E_FAILURE; 14038 14039 /*bodyptr should be freeable*/ 14040 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 14041 if (!cmd_params) 14042 return QDF_STATUS_E_NOMEM; 14043 14044 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 14045 14046 status = sme_acquire_global_lock(&mac->sme); 14047 if (QDF_IS_STATUS_ERROR(status)) { 14048 sme_err("failed to register pause dialog callback"); 14049 qdf_mem_free(cmd_params); 14050 return status; 14051 } 14052 14053 mlme_set_twt_command_in_progress(mac->psoc, 14054 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14055 twt_params->dialog_id, WLAN_TWT_SUSPEND); 14056 14057 /* Serialize the req through MC thread */ 14058 mac->sme.twt_ack_context_cb = context; 14059 twt_msg.bodyptr = cmd_params; 14060 twt_msg.type = WMA_TWT_PAUSE_DIALOG_REQUEST; 14061 sme_release_global_lock(&mac->sme); 14062 14063 status = scheduler_post_message(QDF_MODULE_ID_SME, 14064 QDF_MODULE_ID_WMA, 14065 QDF_MODULE_ID_WMA, &twt_msg); 14066 14067 if (QDF_IS_STATUS_ERROR(status)) { 14068 sme_err("Post twt pause dialog msg fail"); 14069 mlme_set_twt_command_in_progress( 14070 mac->psoc, 14071 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14072 twt_params->dialog_id, WLAN_TWT_NONE); 14073 qdf_mem_free(cmd_params); 14074 } 14075 14076 SME_EXIT(); 14077 return status; 14078 } 14079 14080 QDF_STATUS sme_nudge_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_nudge_dialog_cmd_param * twt_params,void * context)14081 sme_nudge_dialog_cmd(mac_handle_t mac_handle, 14082 struct wmi_twt_nudge_dialog_cmd_param *twt_params, 14083 void *context) 14084 { 14085 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14086 struct wmi_twt_nudge_dialog_cmd_param *cmd_params; 14087 struct scheduler_msg twt_msg = {0}; 14088 bool is_twt_cmd_in_progress; 14089 QDF_STATUS status; 14090 void *wma_handle; 14091 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 14092 14093 SME_ENTER(); 14094 14095 is_twt_cmd_in_progress = mlme_twt_is_command_in_progress( 14096 mac->psoc, 14097 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14098 twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd); 14099 if (is_twt_cmd_in_progress) { 14100 sme_debug("Already TWT command:%d is in progress", active_cmd); 14101 return QDF_STATUS_E_PENDING; 14102 } 14103 14104 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14105 if (!wma_handle) { 14106 sme_err("wma_handle is NULL"); 14107 return QDF_STATUS_E_FAILURE; 14108 } 14109 14110 /*bodyptr should be freeable*/ 14111 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 14112 if (!cmd_params) 14113 return QDF_STATUS_E_NOMEM; 14114 14115 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 14116 14117 status = sme_acquire_global_lock(&mac->sme); 14118 if (QDF_IS_STATUS_ERROR(status)) { 14119 sme_err("failed to register nudge dialog callback"); 14120 qdf_mem_free(cmd_params); 14121 return status; 14122 } 14123 14124 mlme_set_twt_command_in_progress(mac->psoc, 14125 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14126 twt_params->dialog_id, WLAN_TWT_NUDGE); 14127 14128 /* Serialize the req through MC thread */ 14129 mac->sme.twt_ack_context_cb = context; 14130 twt_msg.bodyptr = cmd_params; 14131 twt_msg.type = WMA_TWT_NUDGE_DIALOG_REQUEST; 14132 sme_release_global_lock(&mac->sme); 14133 14134 status = scheduler_post_message(QDF_MODULE_ID_SME, 14135 QDF_MODULE_ID_WMA, 14136 QDF_MODULE_ID_WMA, &twt_msg); 14137 14138 if (QDF_IS_STATUS_ERROR(status)) { 14139 sme_err("Post twt nudge dialog msg fail"); 14140 mlme_set_twt_command_in_progress( 14141 mac->psoc, 14142 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14143 twt_params->dialog_id, WLAN_TWT_NONE); 14144 qdf_mem_free(cmd_params); 14145 } 14146 14147 SME_EXIT(); 14148 return status; 14149 } 14150 14151 QDF_STATUS sme_resume_dialog_cmd(mac_handle_t mac_handle,struct wmi_twt_resume_dialog_cmd_param * twt_params,void * context)14152 sme_resume_dialog_cmd(mac_handle_t mac_handle, 14153 struct wmi_twt_resume_dialog_cmd_param *twt_params, 14154 void *context) 14155 { 14156 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14157 struct wmi_twt_resume_dialog_cmd_param *cmd_params; 14158 struct scheduler_msg twt_msg = {0}; 14159 bool is_twt_cmd_in_progress; 14160 QDF_STATUS status; 14161 void *wma_handle; 14162 enum wlan_twt_commands active_cmd = WLAN_TWT_NONE; 14163 14164 SME_ENTER(); 14165 14166 is_twt_cmd_in_progress = mlme_twt_is_command_in_progress( 14167 mac->psoc, 14168 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14169 twt_params->dialog_id, WLAN_TWT_ANY, &active_cmd); 14170 if (is_twt_cmd_in_progress) { 14171 sme_debug("Already TWT command:%d is in progress", active_cmd); 14172 return QDF_STATUS_E_PENDING; 14173 } 14174 14175 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14176 if (!wma_handle) 14177 return QDF_STATUS_E_FAILURE; 14178 14179 /*bodyptr should be freeable*/ 14180 cmd_params = qdf_mem_malloc(sizeof(*cmd_params)); 14181 if (!cmd_params) 14182 return QDF_STATUS_E_NOMEM; 14183 14184 qdf_mem_copy(cmd_params, twt_params, sizeof(*cmd_params)); 14185 14186 status = sme_acquire_global_lock(&mac->sme); 14187 if (QDF_IS_STATUS_ERROR(status)) { 14188 sme_err("failed to register resume dialog callback"); 14189 qdf_mem_free(cmd_params); 14190 return status; 14191 } 14192 14193 mlme_set_twt_command_in_progress(mac->psoc, 14194 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14195 twt_params->dialog_id, WLAN_TWT_RESUME); 14196 14197 /* Serialize the req through MC thread */ 14198 mac->sme.twt_ack_context_cb = context; 14199 twt_msg.bodyptr = cmd_params; 14200 twt_msg.type = WMA_TWT_RESUME_DIALOG_REQUEST; 14201 sme_release_global_lock(&mac->sme); 14202 14203 status = scheduler_post_message(QDF_MODULE_ID_SME, 14204 QDF_MODULE_ID_WMA, 14205 QDF_MODULE_ID_WMA, &twt_msg); 14206 if (QDF_IS_STATUS_ERROR(status)) { 14207 sme_err("Post twt resume dialog msg fail"); 14208 mlme_set_twt_command_in_progress( 14209 mac->psoc, 14210 (struct qdf_mac_addr *)twt_params->peer_macaddr, 14211 twt_params->dialog_id, WLAN_TWT_NONE); 14212 qdf_mem_free(cmd_params); 14213 } 14214 14215 SME_EXIT(); 14216 return status; 14217 } 14218 #endif 14219 sme_set_smps_cfg(uint32_t vdev_id,uint32_t param_id,uint32_t param_val)14220 QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id, 14221 uint32_t param_val) 14222 { 14223 return wma_configure_smps_params(vdev_id, param_id, param_val); 14224 } 14225 sme_set_reorder_timeout(mac_handle_t mac_handle,struct sir_set_rx_reorder_timeout_val * req)14226 QDF_STATUS sme_set_reorder_timeout(mac_handle_t mac_handle, 14227 struct sir_set_rx_reorder_timeout_val *req) 14228 { 14229 QDF_STATUS status; 14230 tp_wma_handle wma_handle; 14231 14232 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14233 status = wma_set_rx_reorder_timeout_val(wma_handle, req); 14234 14235 return status; 14236 } 14237 sme_set_rx_set_blocksize(mac_handle_t mac_handle,struct sir_peer_set_rx_blocksize * req)14238 QDF_STATUS sme_set_rx_set_blocksize(mac_handle_t mac_handle, 14239 struct sir_peer_set_rx_blocksize *req) 14240 { 14241 QDF_STATUS status; 14242 tp_wma_handle wma_handle; 14243 14244 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14245 status = wma_set_rx_blocksize(wma_handle, req); 14246 14247 return status; 14248 } 14249 sme_cli_set_command(int vdev_id,int param_id,int sval,int vpdev)14250 int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev) 14251 { 14252 return wma_cli_set_command(vdev_id, param_id, sval, vpdev); 14253 } 14254 sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle,int vdev_id)14255 int sme_set_enable_mem_deep_sleep(mac_handle_t mac_handle, int vdev_id) 14256 { 14257 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14258 14259 return wma_cli_set_command(vdev_id, wmi_pdev_param_hyst_en, 14260 mac_ctx->mlme_cfg->gen.memory_deep_sleep, 14261 PDEV_CMD); 14262 } 14263 sme_set_cck_tx_fir_override(mac_handle_t mac_handle,int vdev_id)14264 int sme_set_cck_tx_fir_override(mac_handle_t mac_handle, int vdev_id) 14265 { 14266 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14267 14268 return wma_cli_set_command(vdev_id, 14269 wmi_pdev_param_enable_cck_txfir_override, 14270 mac_ctx->mlme_cfg->gen.cck_tx_fir_override, 14271 PDEV_CMD); 14272 } 14273 sme_set_bt_activity_info_cb(mac_handle_t mac_handle,bt_activity_info_cb cb)14274 QDF_STATUS sme_set_bt_activity_info_cb(mac_handle_t mac_handle, 14275 bt_activity_info_cb cb) 14276 { 14277 QDF_STATUS status; 14278 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14279 14280 status = sme_acquire_global_lock(&mac->sme); 14281 if (QDF_IS_STATUS_SUCCESS(status)) { 14282 mac->sme.bt_activity_info_cb = cb; 14283 sme_release_global_lock(&mac->sme); 14284 sme_debug("bt activity info callback set"); 14285 } 14286 14287 return status; 14288 } 14289 sme_get_chain_rssi(mac_handle_t mac_handle,struct get_chain_rssi_req_params * input,get_chain_rssi_callback callback,void * context)14290 QDF_STATUS sme_get_chain_rssi(mac_handle_t mac_handle, 14291 struct get_chain_rssi_req_params *input, 14292 get_chain_rssi_callback callback, 14293 void *context) 14294 { 14295 QDF_STATUS status = QDF_STATUS_SUCCESS; 14296 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14297 tp_wma_handle wma_handle; 14298 14299 SME_ENTER(); 14300 14301 if (!input) { 14302 sme_err("Invalid req params"); 14303 return QDF_STATUS_E_INVAL; 14304 } 14305 14306 mac_ctx->sme.get_chain_rssi_cb = callback; 14307 mac_ctx->sme.get_chain_rssi_context = context; 14308 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14309 wma_get_chain_rssi(wma_handle, input); 14310 14311 SME_EXIT(); 14312 return status; 14313 } 14314 sme_process_msg_callback(struct mac_context * mac,struct scheduler_msg * msg)14315 QDF_STATUS sme_process_msg_callback(struct mac_context *mac, 14316 struct scheduler_msg *msg) 14317 { 14318 QDF_STATUS status = QDF_STATUS_E_FAILURE; 14319 14320 if (!msg) { 14321 sme_err("Empty message for SME Msg callback"); 14322 return status; 14323 } 14324 status = sme_process_msg(mac, msg); 14325 return status; 14326 } 14327 sme_display_disconnect_stats(mac_handle_t mac_handle,uint8_t session_id)14328 void sme_display_disconnect_stats(mac_handle_t mac_handle, uint8_t session_id) 14329 { 14330 struct csr_roam_session *session; 14331 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14332 14333 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 14334 sme_err("%s Invalid session id: %d", __func__, session_id); 14335 return; 14336 } 14337 14338 session = CSR_GET_SESSION(mac_ctx, session_id); 14339 if (!session) { 14340 sme_err("%s Failed to get session for id: %d", 14341 __func__, session_id); 14342 return; 14343 } 14344 14345 sme_nofl_info("Total No. of Disconnections: %d", 14346 session->disconnect_stats.disconnection_cnt); 14347 14348 sme_nofl_info("No. of Disconnects Triggered by Application: %d", 14349 session->disconnect_stats.disconnection_by_app); 14350 14351 sme_nofl_info("No. of Disassoc Sent by Peer: %d", 14352 session->disconnect_stats.disassoc_by_peer); 14353 14354 sme_nofl_info("No. of Deauth Sent by Peer: %d", 14355 session->disconnect_stats.deauth_by_peer); 14356 14357 sme_nofl_info("No. of Disconnections due to Beacon Miss: %d", 14358 session->disconnect_stats.bmiss); 14359 14360 sme_nofl_info("No. of Disconnections due to Peer Kickout: %d", 14361 session->disconnect_stats.peer_kickout); 14362 } 14363 14364 #ifdef FEATURE_WLAN_DYNAMIC_CVM 14365 /** 14366 * sme_set_vc_mode_config() - Set voltage corner config to FW 14367 * @bitmap: Bitmap that refers to voltage corner config with 14368 * different phymode and bw configuration 14369 * 14370 * Return: QDF_STATUS 14371 */ sme_set_vc_mode_config(uint32_t vc_bitmap)14372 QDF_STATUS sme_set_vc_mode_config(uint32_t vc_bitmap) 14373 { 14374 void *wma_handle; 14375 14376 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 14377 if (!wma_handle) 14378 return QDF_STATUS_E_FAILURE; 14379 14380 if (QDF_STATUS_SUCCESS != 14381 wma_set_vc_mode_config(wma_handle, vc_bitmap)) { 14382 sme_err("Failed to set Voltage Control config to FW"); 14383 return QDF_STATUS_E_FAILURE; 14384 } 14385 return QDF_STATUS_SUCCESS; 14386 } 14387 #endif 14388 14389 /** 14390 * sme_set_bmiss_bcnt() - set bmiss config parameters 14391 * @vdev_id: virtual device for the command 14392 * @first_cnt: bmiss first value 14393 * @final_cnt: bmiss final value 14394 * 14395 * Return: QDF_STATUS_SUCCESS or non-zero on failure 14396 */ sme_set_bmiss_bcnt(uint32_t vdev_id,uint32_t first_cnt,uint32_t final_cnt)14397 QDF_STATUS sme_set_bmiss_bcnt(uint32_t vdev_id, uint32_t first_cnt, 14398 uint32_t final_cnt) 14399 { 14400 return wma_config_bmiss_bcnt_params(vdev_id, first_cnt, final_cnt); 14401 } 14402 sme_send_limit_off_channel_params(mac_handle_t mac_handle,uint8_t vdev_id,bool is_tos_active,uint32_t max_off_chan_time,uint32_t rest_time,bool skip_dfs_chan)14403 QDF_STATUS sme_send_limit_off_channel_params(mac_handle_t mac_handle, 14404 uint8_t vdev_id, 14405 bool is_tos_active, 14406 uint32_t max_off_chan_time, 14407 uint32_t rest_time, 14408 bool skip_dfs_chan) 14409 { 14410 struct sir_limit_off_chan *cmd; 14411 struct scheduler_msg msg = {0}; 14412 14413 cmd = qdf_mem_malloc(sizeof(*cmd)); 14414 if (!cmd) 14415 return QDF_STATUS_E_NOMEM; 14416 14417 cmd->vdev_id = vdev_id; 14418 cmd->is_tos_active = is_tos_active; 14419 cmd->max_off_chan_time = max_off_chan_time; 14420 cmd->rest_time = rest_time; 14421 cmd->skip_dfs_chans = skip_dfs_chan; 14422 14423 msg.type = WMA_SET_LIMIT_OFF_CHAN; 14424 msg.reserved = 0; 14425 msg.bodyptr = cmd; 14426 14427 if (!QDF_IS_STATUS_SUCCESS(scheduler_post_message(QDF_MODULE_ID_SME, 14428 QDF_MODULE_ID_WMA, 14429 QDF_MODULE_ID_WMA, 14430 &msg))) { 14431 sme_err("Not able to post WMA_SET_LIMIT_OFF_CHAN to WMA"); 14432 qdf_mem_free(cmd); 14433 return QDF_STATUS_E_FAILURE; 14434 } 14435 14436 return QDF_STATUS_SUCCESS; 14437 } 14438 sme_unpack_rsn_ie(mac_handle_t mac_handle,uint8_t * buf,uint8_t buf_len,tDot11fIERSN * rsn_ie,bool append_ie)14439 uint32_t sme_unpack_rsn_ie(mac_handle_t mac_handle, uint8_t *buf, 14440 uint8_t buf_len, tDot11fIERSN *rsn_ie, 14441 bool append_ie) 14442 { 14443 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14444 14445 return dot11f_unpack_ie_rsn(mac_ctx, buf, buf_len, rsn_ie, append_ie); 14446 } 14447 sme_unpack_assoc_rsp(mac_handle_t mac_handle,struct wlan_cm_connect_resp * rsp,struct sDot11fAssocResponse * assoc_resp)14448 QDF_STATUS sme_unpack_assoc_rsp(mac_handle_t mac_handle, 14449 struct wlan_cm_connect_resp *rsp, 14450 struct sDot11fAssocResponse *assoc_resp) 14451 { 14452 QDF_STATUS status; 14453 uint8_t ies_offset = WLAN_ASSOC_RSP_IES_OFFSET; 14454 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14455 14456 status = dot11f_parse_assoc_response(mac_ctx, 14457 rsp->connect_ies.assoc_rsp.ptr, 14458 rsp->connect_ies.assoc_rsp.len, 14459 assoc_resp, false); 14460 14461 lim_strip_and_decode_eht_cap(rsp->connect_ies.assoc_rsp.ptr + ies_offset, 14462 rsp->connect_ies.assoc_rsp.len - ies_offset, 14463 &assoc_resp->eht_cap, 14464 assoc_resp->he_cap, 14465 rsp->freq); 14466 return status; 14467 } 14468 sme_get_hs20vendor_ie(mac_handle_t mac_handle,uint8_t * frame,uint32_t frame_len,struct sDot11fIEhs20vendor_ie * hs20vendor_ie)14469 void sme_get_hs20vendor_ie(mac_handle_t mac_handle, uint8_t *frame, 14470 uint32_t frame_len, 14471 struct sDot11fIEhs20vendor_ie *hs20vendor_ie) 14472 { 14473 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14474 struct sSirProbeRespBeacon *beacon_probe_resp = 14475 qdf_mem_malloc(sizeof(struct sSirProbeRespBeacon)); 14476 14477 if (!beacon_probe_resp) 14478 return; 14479 14480 sir_parse_beacon_ie(mac_ctx, beacon_probe_resp, frame, frame_len); 14481 14482 qdf_mem_copy(hs20vendor_ie, &beacon_probe_resp->hs20vendor_ie, 14483 sizeof(struct sDot11fIEhs20vendor_ie)); 14484 14485 qdf_mem_free(beacon_probe_resp); 14486 } 14487 sme_add_qcn_ie(mac_handle_t mac_handle,uint8_t * ie_data,uint16_t * ie_len)14488 void sme_add_qcn_ie(mac_handle_t mac_handle, uint8_t *ie_data, 14489 uint16_t *ie_len) 14490 { 14491 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14492 static const uint8_t qcn_ie[] = {WLAN_ELEMID_VENDOR, 8, 14493 0x8C, 0xFD, 0xF0, 0x1, 14494 QCN_IE_VERSION_SUBATTR_ID, 14495 QCN_IE_VERSION_SUBATTR_DATA_LEN, 14496 QCN_IE_VERSION_SUPPORTED, 14497 QCN_IE_SUBVERSION_SUPPORTED}; 14498 14499 if (!mac_ctx->mlme_cfg->sta.qcn_ie_support) { 14500 sme_debug("QCN IE is not supported"); 14501 return; 14502 } 14503 14504 if (((*ie_len) + sizeof(qcn_ie)) > MAX_DEFAULT_SCAN_IE_LEN) { 14505 sme_err("IE buffer not enough for QCN IE"); 14506 return; 14507 } 14508 14509 qdf_mem_copy(ie_data + (*ie_len), qcn_ie, sizeof(qcn_ie)); 14510 (*ie_len) += sizeof(qcn_ie); 14511 } 14512 14513 #ifdef FEATURE_BSS_TRANSITION 14514 /** 14515 * sme_get_status_for_candidate() - Get bss transition status for candidate 14516 * @mac_handle: Opaque handle to the global MAC context 14517 * @conn_bss: connected bss scan entry 14518 * @candidate_bss: candidate bss scan entry 14519 * @info: candiadate bss information 14520 * @trans_reason: transition reason code 14521 * @is_bt_in_progress: bt activity indicator 14522 * 14523 * Return : true if candidate is rejected and reject reason is filled 14524 * @info->status. Otherwise returns false. 14525 */ sme_get_status_for_candidate(mac_handle_t mac_handle,struct scan_cache_entry * conn_bss,struct scan_cache_entry * candidate_bss,struct bss_candidate_info * info,uint8_t trans_reason,bool is_bt_in_progress)14526 static bool sme_get_status_for_candidate(mac_handle_t mac_handle, 14527 struct scan_cache_entry *conn_bss, 14528 struct scan_cache_entry *candidate_bss, 14529 struct bss_candidate_info *info, 14530 uint8_t trans_reason, 14531 bool is_bt_in_progress) 14532 { 14533 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14534 struct wlan_mlme_mbo *mbo_cfg; 14535 int8_t current_rssi_mcc_thres; 14536 uint32_t bss_chan_freq, conn_bss_chan_freq; 14537 bool bss_chan_safe, conn_bss_chan_safe; 14538 14539 if (!(mac_ctx->mlme_cfg)) { 14540 pe_err("mlme cfg is NULL"); 14541 return false; 14542 } 14543 mbo_cfg = &mac_ctx->mlme_cfg->mbo_cfg; 14544 14545 /* 14546 * Low RSSI based rejection 14547 * If candidate rssi is less than mbo_candidate_rssi_thres and connected 14548 * bss rssi is greater than mbo_current_rssi_thres, then reject the 14549 * candidate with MBO reason code 4. 14550 */ 14551 if ((candidate_bss->rssi_raw < mbo_cfg->mbo_candidate_rssi_thres) && 14552 (conn_bss->rssi_raw > mbo_cfg->mbo_current_rssi_thres)) { 14553 sme_err("Candidate BSS " QDF_MAC_ADDR_FMT " has LOW RSSI(%d), hence reject", 14554 QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes), 14555 candidate_bss->rssi_raw); 14556 info->status = QCA_STATUS_REJECT_LOW_RSSI; 14557 return true; 14558 } 14559 14560 if (trans_reason == MBO_TRANSITION_REASON_LOAD_BALANCING || 14561 trans_reason == MBO_TRANSITION_REASON_TRANSITIONING_TO_PREMIUM_AP) { 14562 bss_chan_freq = candidate_bss->channel.chan_freq; 14563 conn_bss_chan_freq = conn_bss->channel.chan_freq; 14564 /* 14565 * MCC rejection 14566 * If moving to candidate's channel will result in MCC scenario 14567 * and the rssi of connected bss is greater than 14568 * mbo_current_rssi_mss_thres, then reject the candidate with 14569 * MBO reason code 3. 14570 */ 14571 current_rssi_mcc_thres = mbo_cfg->mbo_current_rssi_mcc_thres; 14572 if ((conn_bss->rssi_raw > current_rssi_mcc_thres) && 14573 csr_is_mcc_channel(mac_ctx, bss_chan_freq)) { 14574 sme_err("Candidate BSS " QDF_MAC_ADDR_FMT " causes MCC, hence reject", 14575 QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes)); 14576 info->status = 14577 QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY; 14578 return true; 14579 } 14580 14581 /* 14582 * BT coex rejection 14583 * If AP is trying to move the client from 5G to 2.4G and moving 14584 * to 2.4G will result in BT coex and candidate channel rssi is 14585 * less than mbo_candidate_rssi_btc_thres, then reject the 14586 * candidate with MBO reason code 2. 14587 */ 14588 if (WLAN_REG_IS_5GHZ_CH_FREQ(conn_bss_chan_freq) && 14589 WLAN_REG_IS_24GHZ_CH_FREQ(bss_chan_freq) && 14590 is_bt_in_progress && 14591 (candidate_bss->rssi_raw < mbo_cfg->mbo_candidate_rssi_btc_thres)) { 14592 sme_err("Candidate BSS " QDF_MAC_ADDR_FMT " causes BT coex, hence reject", 14593 QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes)); 14594 info->status = 14595 QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED; 14596 return true; 14597 } 14598 14599 /* 14600 * LTE coex rejection 14601 * If moving to candidate's channel can cause LTE coex, then 14602 * reject the candidate with MBO reason code 5. 14603 */ 14604 conn_bss_chan_safe = policy_mgr_is_safe_channel( 14605 mac_ctx->psoc, conn_bss_chan_freq); 14606 bss_chan_safe = policy_mgr_is_safe_channel( 14607 mac_ctx->psoc, bss_chan_freq); 14608 14609 if (conn_bss_chan_safe && !bss_chan_safe) { 14610 sme_err("High interference expected if transitioned to BSS " 14611 QDF_MAC_ADDR_FMT " hence reject", 14612 QDF_MAC_ADDR_REF(candidate_bss->bssid.bytes)); 14613 info->status = 14614 QCA_STATUS_REJECT_HIGH_INTERFERENCE; 14615 return true; 14616 } 14617 } 14618 14619 return false; 14620 } 14621 sme_get_bss_transition_status(mac_handle_t mac_handle,uint8_t transition_reason,struct qdf_mac_addr * bssid,struct bss_candidate_info * info,uint16_t n_candidates,bool is_bt_in_progress)14622 QDF_STATUS sme_get_bss_transition_status(mac_handle_t mac_handle, 14623 uint8_t transition_reason, 14624 struct qdf_mac_addr *bssid, 14625 struct bss_candidate_info *info, 14626 uint16_t n_candidates, 14627 bool is_bt_in_progress) 14628 { 14629 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14630 QDF_STATUS status = QDF_STATUS_SUCCESS; 14631 uint16_t i; 14632 qdf_list_t *bssid_list = NULL, *candidate_list = NULL; 14633 struct scan_cache_node *conn_bss = NULL, *candidate_bss = NULL; 14634 qdf_list_node_t *cur_lst = NULL; 14635 14636 if (!n_candidates || !info) { 14637 sme_err("No candidate info available"); 14638 return QDF_STATUS_E_INVAL; 14639 } 14640 14641 /* Get the connected BSS descriptor */ 14642 status = csr_scan_get_result_for_bssid(mac_ctx, bssid, &bssid_list); 14643 if (QDF_IS_STATUS_ERROR(status)) { 14644 sme_err("connected BSS: " QDF_MAC_ADDR_FMT " not present in scan db", 14645 QDF_MAC_ADDR_REF(bssid->bytes)); 14646 goto purge; 14647 } 14648 qdf_list_peek_front(bssid_list, &cur_lst); 14649 if (!cur_lst) { 14650 sme_err("Failed to peek connected BSS : " QDF_MAC_ADDR_FMT, 14651 QDF_MAC_ADDR_REF(bssid->bytes)); 14652 goto purge; 14653 } 14654 14655 conn_bss = 14656 qdf_container_of(cur_lst, struct scan_cache_node, node); 14657 14658 for (i = 0; i < n_candidates; i++) { 14659 /* Get candidate BSS descriptors */ 14660 status = csr_scan_get_result_for_bssid(mac_ctx, &info[i].bssid, 14661 &candidate_list); 14662 if (QDF_IS_STATUS_ERROR(status)) { 14663 sme_err("BSS " QDF_MAC_ADDR_FMT " not present in scan db", 14664 QDF_MAC_ADDR_REF(info[i].bssid.bytes)); 14665 info[i].status = QCA_STATUS_REJECT_UNKNOWN; 14666 continue; 14667 } 14668 cur_lst = NULL; 14669 qdf_list_peek_front(candidate_list, &cur_lst); 14670 if (!cur_lst) { 14671 sme_err("Failed to peek candidate: " QDF_MAC_ADDR_FMT, 14672 QDF_MAC_ADDR_REF(info[i].bssid.bytes)); 14673 goto next; 14674 } 14675 14676 candidate_bss = 14677 qdf_container_of(cur_lst, struct scan_cache_node, node); 14678 if (!sme_get_status_for_candidate(mac_handle, 14679 conn_bss->entry, 14680 candidate_bss->entry, 14681 &info[i], transition_reason, 14682 is_bt_in_progress)) { 14683 /* 14684 * If status is not over written, it means it is a 14685 * candidate for accept. 14686 */ 14687 info[i].status = QCA_STATUS_ACCEPT; 14688 } 14689 next: 14690 wlan_scan_purge_results(candidate_list); 14691 candidate_list = NULL; 14692 } 14693 14694 /* success */ 14695 status = QDF_STATUS_SUCCESS; 14696 14697 purge: 14698 if (bssid_list) 14699 wlan_scan_purge_results(bssid_list); 14700 if (candidate_list) 14701 wlan_scan_purge_results(candidate_list); 14702 14703 return status; 14704 } 14705 #endif /* FEATURE_BSS_TRANSITION */ 14706 sme_is_conn_state_connected(mac_handle_t mac_handle,uint8_t session_id)14707 bool sme_is_conn_state_connected(mac_handle_t mac_handle, uint8_t session_id) 14708 { 14709 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14710 14711 return csr_is_conn_state_connected(mac_ctx, session_id); 14712 } 14713 sme_get_oper_chan_freq(struct wlan_objmgr_vdev * vdev)14714 int16_t sme_get_oper_chan_freq(struct wlan_objmgr_vdev *vdev) 14715 { 14716 uint8_t vdev_id; 14717 struct csr_roam_session *session; 14718 struct mac_context *mac_ctx; 14719 mac_handle_t mac_handle; 14720 14721 if (!vdev) { 14722 sme_err("Invalid vdev id is passed"); 14723 return 0; 14724 } 14725 14726 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 14727 if (!mac_handle) 14728 return 0; 14729 14730 mac_ctx = MAC_CONTEXT(mac_handle); 14731 vdev_id = wlan_vdev_get_id(vdev); 14732 if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) { 14733 sme_err("Invalid vdev id is passed"); 14734 return 0; 14735 } 14736 14737 session = CSR_GET_SESSION(mac_ctx, vdev_id); 14738 14739 return wlan_get_operation_chan_freq(vdev); 14740 } 14741 sme_get_oper_ch_width(struct wlan_objmgr_vdev * vdev)14742 enum phy_ch_width sme_get_oper_ch_width(struct wlan_objmgr_vdev *vdev) 14743 { 14744 struct wlan_channel *des_chan; 14745 14746 if (!vdev) { 14747 sme_err("Invalid vdev id is passed"); 14748 return CH_WIDTH_INVALID; 14749 } 14750 14751 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 14752 if (!des_chan) { 14753 sme_debug("NULL des_chan"); 14754 return CH_WIDTH_INVALID; 14755 } 14756 14757 return des_chan->ch_width; 14758 14759 } 14760 sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev * vdev,uint16_t * sec20chan_freq)14761 int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev, 14762 uint16_t *sec20chan_freq) 14763 { 14764 uint8_t vdev_id; 14765 14766 vdev_id = wlan_vdev_get_id(vdev); 14767 /* Need to extend */ 14768 return 0; 14769 } 14770 14771 #ifdef WLAN_FEATURE_SAE sme_handle_sae_msg(mac_handle_t mac_handle,uint8_t session_id,uint8_t sae_status,struct qdf_mac_addr peer_mac_addr,const uint8_t * pmkid)14772 QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, 14773 uint8_t session_id, 14774 uint8_t sae_status, 14775 struct qdf_mac_addr peer_mac_addr, 14776 const uint8_t *pmkid) 14777 { 14778 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 14779 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14780 struct sir_sae_msg *sae_msg; 14781 struct scheduler_msg sch_msg = {0}; 14782 struct wmi_roam_auth_status_params *params; 14783 struct csr_roam_session *csr_session; 14784 enum QDF_OPMODE opmode; 14785 14786 qdf_status = sme_acquire_global_lock(&mac->sme); 14787 if (QDF_IS_STATUS_ERROR(qdf_status)) 14788 return qdf_status; 14789 14790 csr_session = CSR_GET_SESSION(mac, session_id); 14791 if (!csr_session) { 14792 sme_err("session %d not found", session_id); 14793 qdf_status = QDF_STATUS_E_FAILURE; 14794 goto error; 14795 } 14796 14797 /* Update the status to SME in below cases 14798 * 1. SAP mode: Always 14799 * 2. STA mode: When the device is not in joined state 14800 * 14801 * If the device is in joined state, send the status to WMA which 14802 * is meant for roaming. 14803 */ 14804 opmode = wlan_get_opmode_from_vdev_id(mac->pdev, session_id); 14805 if ((opmode == QDF_SAP_MODE) || (opmode == QDF_P2P_GO_MODE) || 14806 !CSR_IS_ROAM_JOINED(mac, session_id)) { 14807 sae_msg = qdf_mem_malloc(sizeof(*sae_msg)); 14808 if (!sae_msg) { 14809 qdf_status = QDF_STATUS_E_NOMEM; 14810 goto error; 14811 } 14812 14813 sae_msg->message_type = eWNI_SME_SEND_SAE_MSG; 14814 sae_msg->length = sizeof(*sae_msg); 14815 sae_msg->vdev_id = session_id; 14816 sae_msg->sae_status = sae_status; 14817 sae_msg->result_code = eSIR_SME_AUTH_REFUSED; 14818 qdf_mem_copy(sae_msg->peer_mac_addr, 14819 peer_mac_addr.bytes, 14820 QDF_MAC_ADDR_SIZE); 14821 qdf_mem_zero(sae_msg->pmkid, PMKID_LEN); 14822 if (pmkid) 14823 qdf_mem_copy(sae_msg->pmkid, pmkid, PMKID_LEN); 14824 sme_debug("SAE: sae_status %d vdev_id %d Peer: " 14825 QDF_MAC_ADDR_FMT, sae_msg->sae_status, 14826 sae_msg->vdev_id, 14827 QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr)); 14828 14829 sch_msg.type = eWNI_SME_SEND_SAE_MSG; 14830 sch_msg.bodyptr = sae_msg; 14831 14832 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 14833 QDF_MODULE_ID_PE, 14834 QDF_MODULE_ID_PE, 14835 &sch_msg); 14836 if (QDF_IS_STATUS_ERROR(qdf_status)) { 14837 qdf_mem_free(sae_msg); 14838 goto error; 14839 } 14840 } else { 14841 /* 14842 * For WPA3 SAE roaming, external auth offload is enabled. The 14843 * firmware will send preauth start event after candidate 14844 * selection. The supplicant will perform the SAE authentication 14845 * and will send the auth status, PMKID in the external auth 14846 * cmd. 14847 * 14848 * csr roam state is CSR_ROAM_STATE_JOINED. So this SAE 14849 * external auth event is for wpa3 roam pre-auth offload. 14850 * 14851 * Post the preauth status to WMA. 14852 */ 14853 params = qdf_mem_malloc(sizeof(*params)); 14854 if (!params) { 14855 qdf_status = QDF_STATUS_E_NOMEM; 14856 goto error; 14857 } 14858 14859 params->vdev_id = session_id; 14860 params->preauth_status = sae_status; 14861 qdf_copy_macaddr(¶ms->bssid, &peer_mac_addr); 14862 14863 qdf_mem_zero(params->pmkid, PMKID_LEN); 14864 if (pmkid) 14865 qdf_mem_copy(params->pmkid, pmkid, PMKID_LEN); 14866 14867 sch_msg.type = WMA_ROAM_PRE_AUTH_STATUS; 14868 sch_msg.bodyptr = params; 14869 14870 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 14871 QDF_MODULE_ID_WMA, 14872 QDF_MODULE_ID_WMA, 14873 &sch_msg); 14874 if (QDF_IS_STATUS_ERROR(qdf_status)) { 14875 sme_err("WMA_ROAM_PRE_AUTH_STATUS cmd posting failed"); 14876 qdf_mem_free(params); 14877 } 14878 } 14879 error: 14880 sme_release_global_lock(&mac->sme); 14881 14882 return qdf_status; 14883 } 14884 #endif 14885 sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle,uint8_t session_id)14886 bool sme_is_sta_key_exchange_in_progress(mac_handle_t mac_handle, 14887 uint8_t session_id) 14888 { 14889 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14890 14891 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { 14892 sme_err("Invalid session id: %d", session_id); 14893 return false; 14894 } 14895 14896 return CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id); 14897 } 14898 sme_validate_channel_list(mac_handle_t mac_handle,uint32_t * chan_freq_list,uint8_t num_channels)14899 bool sme_validate_channel_list(mac_handle_t mac_handle, 14900 uint32_t *chan_freq_list, 14901 uint8_t num_channels) 14902 { 14903 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14904 uint8_t i = 0; 14905 uint8_t j; 14906 bool found; 14907 struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels; 14908 14909 if (!chan_freq_list || !num_channels) { 14910 sme_err("Chan list empty %pK or num_channels is 0", 14911 chan_freq_list); 14912 return false; 14913 } 14914 14915 while (i < num_channels) { 14916 found = false; 14917 for (j = 0; j < ch_lst_info->numChannels; j++) { 14918 if (ch_lst_info->channel_freq_list[j] == 14919 chan_freq_list[i]) { 14920 found = true; 14921 break; 14922 } 14923 } 14924 14925 if (!found) { 14926 sme_debug("Invalid channel %d", chan_freq_list[i]); 14927 return false; 14928 } 14929 14930 i++; 14931 } 14932 14933 return true; 14934 } 14935 sme_set_pmf_wep_cfg(mac_handle_t mac_handle,uint8_t pmf_wep)14936 void sme_set_pmf_wep_cfg(mac_handle_t mac_handle, uint8_t pmf_wep) 14937 { 14938 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14939 14940 mac_ctx->is_usr_cfg_pmf_wep = pmf_wep; 14941 } 14942 sme_set_cfg_disable_tx(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)14943 void sme_set_cfg_disable_tx(mac_handle_t mac_handle, uint8_t vdev_id, 14944 uint8_t val) 14945 { 14946 struct mac_context *mac = MAC_CONTEXT(mac_handle); 14947 int ret_val; 14948 14949 sme_debug("Block Tx %d", val); 14950 if (val) { 14951 if (mac->sme.tx_queue_cb) { 14952 sme_debug("Blocking the Tx queue"); 14953 mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id, 14954 WLAN_STOP_ALL_NETIF_QUEUE, 14955 WLAN_CONTROL_PATH); 14956 } 14957 } else { 14958 if (mac->sme.tx_queue_cb) { 14959 sme_debug("Enable the Tx queue"); 14960 mac->sme.tx_queue_cb(mac->hdd_handle, vdev_id, 14961 WLAN_START_ALL_NETIF_QUEUE, 14962 WLAN_CONTROL_PATH); 14963 } 14964 } 14965 14966 ret_val = wma_cli_set_command(vdev_id, 14967 wmi_vdev_param_prohibit_data_mgmt, 14968 val, VDEV_CMD); 14969 if (ret_val) 14970 sme_err("Failed to set firmware, errno %d", ret_val); 14971 14972 mac->usr_cfg_disable_rsp_tx = val; 14973 } 14974 sme_set_amsdu(mac_handle_t mac_handle,bool enable)14975 void sme_set_amsdu(mac_handle_t mac_handle, bool enable) 14976 { 14977 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14978 mac_ctx->is_usr_cfg_amsdu_enabled = enable; 14979 } 14980 sme_set_bss_max_idle_period(mac_handle_t mac_handle,uint16_t cfg_val)14981 void sme_set_bss_max_idle_period(mac_handle_t mac_handle, uint16_t cfg_val) 14982 { 14983 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 14984 mac_ctx->mlme_cfg->sta.bss_max_idle_period = cfg_val; 14985 } 14986 14987 #ifdef WLAN_FEATURE_11BE sme_set_eht_mcs_info(struct mac_context * mac_ctx)14988 static void sme_set_eht_mcs_info(struct mac_context *mac_ctx) 14989 { 14990 if (mac_ctx->usr_eht_testbed_cfg) { 14991 mac_ctx->eht_cap_2g.bw_le_80_rx_max_nss_for_mcs_0_to_9 = 1; 14992 mac_ctx->eht_cap_2g.bw_le_80_tx_max_nss_for_mcs_0_to_9 = 1; 14993 } 14994 } 14995 #else 14996 #ifdef WLAN_FEATURE_11AX sme_set_eht_mcs_info(struct mac_context * mac_ctx)14997 static void sme_set_eht_mcs_info(struct mac_context *mac_ctx) 14998 { 14999 } 15000 #endif 15001 #endif 15002 15003 #ifdef WLAN_FEATURE_11AX sme_set_he_bw_cap(mac_handle_t mac_handle,uint8_t vdev_id,enum eSirMacHTChannelWidth chwidth)15004 void sme_set_he_bw_cap(mac_handle_t mac_handle, uint8_t vdev_id, 15005 enum eSirMacHTChannelWidth chwidth) 15006 { 15007 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15008 struct csr_roam_session *session; 15009 15010 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15011 if (!session) { 15012 sme_debug("No session for id %d", vdev_id); 15013 return; 15014 } 15015 sme_debug("Config HE caps for BW %d", chwidth); 15016 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 0; 15017 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 0; 15018 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 0; 15019 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_3 = 0; 15020 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_4 = 0; 15021 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_5 = 0; 15022 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_6 = 0; 15023 15024 mac_ctx->he_cap_2g.chan_width_0 = 0; 15025 mac_ctx->he_cap_2g.chan_width_1 = 0; 15026 mac_ctx->he_cap_2g.chan_width_2 = 0; 15027 mac_ctx->he_cap_2g.chan_width_3 = 0; 15028 mac_ctx->he_cap_2g.chan_width_4 = 0; 15029 mac_ctx->he_cap_2g.chan_width_5 = 0; 15030 mac_ctx->he_cap_2g.chan_width_6 = 0; 15031 15032 mac_ctx->he_cap_5g.chan_width_0 = 0; 15033 mac_ctx->he_cap_5g.chan_width_1 = 0; 15034 mac_ctx->he_cap_5g.chan_width_2 = 0; 15035 mac_ctx->he_cap_5g.chan_width_3 = 0; 15036 mac_ctx->he_cap_5g.chan_width_4 = 0; 15037 mac_ctx->he_cap_5g.chan_width_5 = 0; 15038 mac_ctx->he_cap_5g.chan_width_6 = 0; 15039 15040 switch (chwidth) { 15041 case eHT_CHANNEL_WIDTH_160MHZ: 15042 case eHT_CHANNEL_WIDTH_320MHZ: 15043 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1; 15044 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 1; 15045 *((uint16_t *) 15046 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_160) = 15047 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_he_mcs_map_lt_80; 15048 *((uint16_t *) 15049 mac_ctx->he_cap_5g.rx_he_mcs_map_160) = 15050 mac_ctx->he_cap_5g.rx_he_mcs_map_lt_80; 15051 *((uint16_t *) 15052 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_160) = 15053 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_he_mcs_map_lt_80; 15054 *((uint16_t *) 15055 mac_ctx->he_cap_5g.tx_he_mcs_map_160) = 15056 mac_ctx->he_cap_5g.tx_he_mcs_map_lt_80; 15057 mac_ctx->he_cap_5g.chan_width_1 = 1; 15058 mac_ctx->he_cap_5g.chan_width_2 = 1; 15059 fallthrough; 15060 case eHT_CHANNEL_WIDTH_80MHZ: 15061 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1; 15062 mac_ctx->he_cap_5g.chan_width_1 = 1; 15063 fallthrough; 15064 case eHT_CHANNEL_WIDTH_40MHZ: 15065 sme_set_eht_mcs_info(mac_ctx); 15066 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 1; 15067 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1; 15068 mac_ctx->he_cap_2g.chan_width_0 = 1; 15069 mac_ctx->he_cap_5g.chan_width_1 = 1; 15070 fallthrough; 15071 case eHT_CHANNEL_WIDTH_20MHZ: 15072 break; 15073 default: 15074 sme_debug("Config BW %d not handled", chwidth); 15075 } 15076 csr_update_session_he_cap(mac_ctx, session); 15077 } 15078 sme_check_enable_ru_242_tx(mac_handle_t mac_handle,uint8_t vdev_id)15079 void sme_check_enable_ru_242_tx(mac_handle_t mac_handle, uint8_t vdev_id) 15080 { 15081 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15082 int ret; 15083 15084 sme_debug("Config VDEV for RU 242 Tx, usr cfg %d", 15085 mac_ctx->usr_cfg_ru_242_tone_tx); 15086 if (mac_ctx->usr_cfg_ru_242_tone_tx) { 15087 ret = wma_cli_set_command(vdev_id, wmi_vdev_param_chwidth, 15088 0, VDEV_CMD); 15089 if (ret) 15090 sme_err("Failed to set VDEV BW to 20MHz"); 15091 } 15092 } 15093 sme_set_ru_242_tone_tx_cfg(mac_handle_t mac_handle,uint8_t cfg_val)15094 void sme_set_ru_242_tone_tx_cfg(mac_handle_t mac_handle, uint8_t cfg_val) 15095 { 15096 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15097 15098 mac_ctx->usr_cfg_ru_242_tone_tx = cfg_val; 15099 } 15100 sme_set_he_testbed_def(mac_handle_t mac_handle,uint8_t vdev_id)15101 void sme_set_he_testbed_def(mac_handle_t mac_handle, uint8_t vdev_id) 15102 { 15103 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15104 struct csr_roam_session *session; 15105 QDF_STATUS status; 15106 uint32_t prevent_pm[] = {29, 1}; 15107 15108 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15109 15110 if (!session) { 15111 sme_debug("No session for id %d", vdev_id); 15112 return; 15113 } 15114 sme_debug("set HE testbed defaults"); 15115 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.htc_he = 0; 15116 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.amsdu_in_ampdu = 0; 15117 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request = 0; 15118 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.broadcast_twt = 0; 15119 mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = true; 15120 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_ctrl_frame = 0; 15121 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.omi_a_ctrl = 0; 15122 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_20_in_160_80p80Mhz = 0; 15123 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_20_in_40Mhz_2G = 0; 15124 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_ppdu_80_in_160_80p80Mhz = 0; 15125 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_tx = 0; 15126 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dcm_enc_rx = 0; 15127 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_mu = 0; 15128 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.max_nc = 0; 15129 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.trigger_frm_mac_pad = 15130 QCA_WLAN_HE_16US_OF_PROCESS_TIME; 15131 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.flex_twt_sched = 0; 15132 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ofdma_ra = 0; 15133 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_4x_ltf_3200_gi_ndp = 0; 15134 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.qtp = 0; 15135 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.bsrp_ampdu_aggr = 0; 15136 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.a_bqr = 0; 15137 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_sub_ch_sel_tx_supp = 0; 15138 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ndp_feedback_supp = 0; 15139 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ops_supp = 0; 15140 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.srp = 0; 15141 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.power_boost = 0; 15142 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.num_sounding_lt_80 = 0; 15143 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.num_sounding_gt_80 = 0; 15144 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dl_mu_mimo_part_bw = 0; 15145 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.non_trig_cqi_feedback = 0; 15146 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.tx_1024_qam_lt_242_tone_ru = 0; 15147 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_1024_qam_lt_242_tone_ru = 0; 15148 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_full_bw_su_he_mu_compress_sigb = 0; 15149 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_full_bw_su_he_mu_non_cmpr_sigb = 0; 15150 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_beamformer = 0; 15151 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.multi_tid_aggr_rx_supp = 0; 15152 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.multi_tid_aggr_tx_supp = 0; 15153 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_dynamic_smps = 0; 15154 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.punctured_sounding_supp = 0; 15155 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ht_vht_trg_frm_rx_supp = 0; 15156 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.su_feedback_tone16 = 0; 15157 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.mu_feedback_tone16 = 0; 15158 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.codebook_su = 0; 15159 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.codebook_mu = 0; 15160 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.ul_2x996_tone_ru_supp = 0; 15161 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.beamforming_feedback = 0; 15162 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.he_er_su_ppdu = 0; 15163 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.dl_mu_mimo_part_bw = 0; 15164 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.rx_pream_puncturing = 0; 15165 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_0 = 0; 15166 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_1 = 1; 15167 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_2 = 0; 15168 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_3 = 0; 15169 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_4 = 0; 15170 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_5 = 0; 15171 mac_ctx->mlme_cfg->he_caps.dot11_he_cap.chan_width_6 = 0; 15172 csr_update_session_he_cap(mac_ctx, session); 15173 15174 qdf_mem_copy(&mac_ctx->he_cap_2g, 15175 &mac_ctx->mlme_cfg->he_caps.dot11_he_cap, 15176 sizeof(tDot11fIEhe_cap)); 15177 15178 mac_ctx->he_cap_2g.chan_width_1 = 0; 15179 ucfg_mlme_set_channel_bonding_24ghz(mac_ctx->psoc, 0); 15180 qdf_mem_copy(&mac_ctx->he_cap_5g, 15181 &mac_ctx->mlme_cfg->he_caps.dot11_he_cap, 15182 sizeof(tDot11fIEhe_cap)); 15183 status = ucfg_mlme_set_enable_bcast_probe_rsp(mac_ctx->psoc, false); 15184 if (QDF_IS_STATUS_ERROR(status)) 15185 sme_err("Failed not set enable bcast probe resp info, %d", 15186 status); 15187 status = sme_send_unit_test_cmd(vdev_id, 77, 2, prevent_pm); 15188 if (QDF_STATUS_SUCCESS != status) 15189 sme_err("prevent pm cmd send failed"); 15190 status = wma_cli_set_command(vdev_id, 15191 wmi_vdev_param_enable_bcast_probe_response, 15192 0, VDEV_CMD); 15193 if (QDF_IS_STATUS_ERROR(status)) 15194 sme_err("Failed to set enable bcast probe resp in FW, %d", 15195 status); 15196 15197 mac_ctx->mlme_cfg->sta.usr_disabled_roaming = true; 15198 mac_ctx->mlme_cfg->sta.bss_max_idle_period = 0; 15199 } 15200 sme_reset_he_caps(mac_handle_t mac_handle,uint8_t vdev_id)15201 void sme_reset_he_caps(mac_handle_t mac_handle, uint8_t vdev_id) 15202 { 15203 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15204 struct csr_roam_session *session; 15205 QDF_STATUS status; 15206 uint32_t prevent_pm[] = {29, 0}; 15207 15208 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15209 15210 if (!session) { 15211 sme_err("No session for id %d", vdev_id); 15212 return; 15213 } 15214 sme_debug("reset HE caps"); 15215 mac_ctx->mlme_cfg->he_caps.dot11_he_cap = 15216 mac_ctx->mlme_cfg->he_caps.he_cap_orig; 15217 csr_update_session_he_cap(mac_ctx, session); 15218 15219 qdf_mem_copy(&mac_ctx->he_cap_2g, 15220 &mac_ctx->he_cap_2g_orig, 15221 sizeof(tDot11fIEhe_cap)); 15222 qdf_mem_copy(&mac_ctx->he_cap_5g, 15223 &mac_ctx->he_cap_5g_orig, 15224 sizeof(tDot11fIEhe_cap)); 15225 ucfg_mlme_set_channel_bonding_24ghz(mac_ctx->psoc, 1); 15226 wlan_cm_set_check_6ghz_security(mac_ctx->psoc, true); 15227 status = sme_send_unit_test_cmd(vdev_id, 77, 2, prevent_pm); 15228 15229 if (QDF_STATUS_SUCCESS != status) 15230 sme_err("prevent PM reset cmd send failed"); 15231 15232 mac_ctx->mlme_cfg->twt_cfg.disable_btwt_usr_cfg = false; 15233 status = ucfg_mlme_set_enable_bcast_probe_rsp(mac_ctx->psoc, true); 15234 if (QDF_IS_STATUS_ERROR(status)) 15235 sme_err("Failed not set enable bcast probe resp info, %d", 15236 status); 15237 15238 status = wma_cli_set_command(vdev_id, 15239 wmi_vdev_param_enable_bcast_probe_response, 15240 1, VDEV_CMD); 15241 if (QDF_IS_STATUS_ERROR(status)) 15242 sme_err("Failed to set enable bcast probe resp in FW, %d", 15243 status); 15244 mac_ctx->is_usr_cfg_pmf_wep = PMF_CORRECT_KEY; 15245 mac_ctx->mlme_cfg->sta.bss_max_idle_period = 15246 mac_ctx->mlme_cfg->sta.sta_keep_alive_period; 15247 15248 if (mac_ctx->usr_cfg_disable_rsp_tx) 15249 sme_set_cfg_disable_tx(mac_handle, vdev_id, 0); 15250 mac_ctx->is_usr_cfg_amsdu_enabled = true; 15251 status = wlan_scan_cfg_set_scan_mode_6g(mac_ctx->psoc, 15252 SCAN_MODE_6G_ALL_CHANNEL); 15253 if (QDF_IS_STATUS_ERROR(status)) 15254 sme_err("Failed to set scan mode for 6 GHz, %d", status); 15255 } 15256 #endif 15257 15258 #ifdef WLAN_FEATURE_11BE sme_set_mlo_max_links(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15259 void sme_set_mlo_max_links(mac_handle_t mac_handle, uint8_t vdev_id, 15260 uint8_t val) 15261 { 15262 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15263 struct csr_roam_session *session; 15264 15265 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15266 15267 if (!session) { 15268 sme_err("No session for id %d", vdev_id); 15269 return; 15270 } 15271 wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, val); 15272 wlan_mlme_set_user_set_link_num(mac_ctx->psoc, val); 15273 } 15274 sme_set_mlo_max_simultaneous_links(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15275 void sme_set_mlo_max_simultaneous_links(mac_handle_t mac_handle, 15276 uint8_t vdev_id, uint8_t val) 15277 { 15278 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15279 struct csr_roam_session *session; 15280 15281 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15282 if (!session) { 15283 sme_err("No session for id %d", vdev_id); 15284 return; 15285 } 15286 wlan_mlme_set_sta_mlo_simultaneous_links(mac_ctx->psoc, val); 15287 } 15288 sme_set_mlo_assoc_link_band(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t val)15289 void sme_set_mlo_assoc_link_band(mac_handle_t mac_handle, uint8_t vdev_id, 15290 uint8_t val) 15291 { 15292 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15293 struct csr_roam_session *session; 15294 15295 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15296 15297 if (!session) { 15298 sme_err("No session for id %d", vdev_id); 15299 return; 15300 } 15301 wlan_mlme_set_sta_mlo_conn_band_bmp(mac_ctx->psoc, val); 15302 } 15303 sme_set_eht_testbed_def(mac_handle_t mac_handle,uint8_t vdev_id)15304 void sme_set_eht_testbed_def(mac_handle_t mac_handle, uint8_t vdev_id) 15305 { 15306 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15307 struct csr_roam_session *session; 15308 tDot11fIEeht_cap *mlme_eht_cap; 15309 15310 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15311 15312 if (!session) { 15313 sme_err("No session for id %d", vdev_id); 15314 return; 15315 } 15316 mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap; 15317 sme_debug("set EHT caps testbed defaults"); 15318 mlme_eht_cap->epcs_pri_access = 0; 15319 mlme_eht_cap->eht_om_ctl = 0; 15320 mlme_eht_cap->triggered_txop_sharing_mode1 = 0; 15321 mlme_eht_cap->restricted_twt = 0; 15322 mlme_eht_cap->support_320mhz_6ghz = 0; 15323 mlme_eht_cap->partial_bw_mu_mimo = 0; 15324 mlme_eht_cap->su_beamformer = 0; 15325 mlme_eht_cap->su_beamformee = 1; 15326 mlme_eht_cap->bfee_ss_le_80mhz = 3; 15327 mlme_eht_cap->bfee_ss_160mhz = 0; 15328 mlme_eht_cap->bfee_ss_320mhz = 0; 15329 mlme_eht_cap->num_sounding_dim_le_80mhz = 0; 15330 mlme_eht_cap->num_sounding_dim_160mhz = 0; 15331 mlme_eht_cap->num_sounding_dim_320mhz = 0; 15332 mlme_eht_cap->mu_bformer_le_80mhz = 0; 15333 mlme_eht_cap->mu_bformer_160mhz = 0; 15334 mlme_eht_cap->mu_bformer_320mhz = 0; 15335 mlme_eht_cap->partial_bw_dl_mu_mimo = 0; 15336 mlme_eht_cap->ru_242tone_wt_20mhz = 0; 15337 mlme_eht_cap->psr_based_sr = 0; 15338 mlme_eht_cap->triggered_cqi_feedback = 0; 15339 mlme_eht_cap->trig_mu_bforming_partial_bw_feedback = 0; 15340 mlme_eht_cap->trig_su_bforming_feedback = 0; 15341 mlme_eht_cap->cb_sz_7_5_su_feedback = 0; 15342 mlme_eht_cap->cb_sz_4_2_su_feedback = 0; 15343 mlme_eht_cap->ng_16_mu_feedback = 0; 15344 mlme_eht_cap->ng_16_su_feedback = 0; 15345 mlme_eht_cap->ndp_4x_eht_ltf_3dot2_us_gi = 0; 15346 mlme_eht_cap->common_nominal_pkt_padding = 3; 15347 mlme_eht_cap->ppet_present = 0; 15348 mlme_eht_cap->rx_1024_4096_qam_lt_242_tone_ru = 0; 15349 mlme_eht_cap->tx_1024_4096_qam_lt_242_tone_ru = 0; 15350 mlme_eht_cap->non_trig_cqi_feedback = 0; 15351 mlme_eht_cap->max_nc = 0; 15352 mlme_eht_cap->rx_4k_qam_in_wider_bw_dl_ofdma = 0; 15353 mlme_eht_cap->rx_1k_qam_in_wider_bw_dl_ofdma = 0; 15354 mlme_eht_cap->tb_sounding_feedback_rl = 0; 15355 mlme_eht_cap->op_sta_rx_ndp_wider_bw_20mhz = 0; 15356 mlme_eht_cap->eht_dup_6ghz = 0; 15357 mlme_eht_cap->mcs_15 = 0; 15358 mlme_eht_cap->max_num_eht_ltf = 0; 15359 mlme_eht_cap->eht_mu_ppdu_4x_ltf_0_8_us_gi = 0; 15360 mlme_eht_cap->power_boost_factor = 0; 15361 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 = 1; 15362 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 = 1; 15363 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 = 1; 15364 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 = 1; 15365 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = 0; 15366 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = 0; 15367 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = 0; 15368 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = 0; 15369 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9 = 1; 15370 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9 = 1; 15371 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = 0; 15372 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = 0; 15373 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = 0; 15374 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = 0; 15375 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_0_to_9 = 1; 15376 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_0_to_9 = 1; 15377 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = 0; 15378 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = 0; 15379 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = 0; 15380 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = 0; 15381 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_0_to_9 = 1; 15382 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_0_to_9 = 1; 15383 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = 0; 15384 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = 0; 15385 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = 0; 15386 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = 0; 15387 15388 csr_update_session_eht_cap(mac_ctx, session); 15389 15390 qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap, 15391 sizeof(tDot11fIEeht_cap)); 15392 15393 mac_ctx->eht_cap_2g.bw_le_80_rx_max_nss_for_mcs_0_to_9 = 0; 15394 mac_ctx->eht_cap_2g.bw_le_80_tx_max_nss_for_mcs_0_to_9 = 0; 15395 15396 qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap, 15397 sizeof(tDot11fIEeht_cap)); 15398 15399 mac_ctx->usr_eht_testbed_cfg = true; 15400 mac_ctx->roam.configParam.channelBondingMode24GHz = 0; 15401 wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, 1); 15402 ucfg_mlme_set_bss_color_collision_det_sta(mac_ctx->psoc, false); 15403 } 15404 sme_set_per_link_ba_mode(mac_handle_t mac_handle,uint8_t val)15405 void sme_set_per_link_ba_mode(mac_handle_t mac_handle, uint8_t val) 15406 { 15407 struct mac_context *mac = MAC_CONTEXT(mac_handle); 15408 enum QDF_OPMODE op_mode; 15409 uint8_t vdev_id; 15410 int ret_val = 0; 15411 15412 for (vdev_id = 0; vdev_id < WLAN_MAX_VDEVS; vdev_id++) { 15413 op_mode = wlan_get_opmode_from_vdev_id(mac->pdev, vdev_id); 15414 if (op_mode == QDF_STA_MODE) { 15415 ret_val = wma_cli_set_command( 15416 vdev_id, 15417 wmi_vdev_param_set_ba_mode, 15418 val, VDEV_CMD); 15419 15420 if (QDF_IS_STATUS_ERROR(ret_val)) 15421 sme_err("BA mode set failed for vdev: %d, ret %d", 15422 vdev_id, ret_val); 15423 else 15424 sme_debug("vdev: %d ba mode: %d param id %d", 15425 vdev_id, val, wmi_vdev_param_set_ba_mode); 15426 } 15427 } 15428 } 15429 15430 static inline sme_set_mcs_15_tx_rx_disable(uint8_t vdev_id)15431 void sme_set_mcs_15_tx_rx_disable(uint8_t vdev_id) 15432 { 15433 uint32_t tx_disable[2] = {67, 0}; 15434 uint32_t rx_disable[3] = {125, 0, 1}; 15435 QDF_STATUS status; 15436 15437 sme_debug("Send MCS 15 rx/tx disable to FW"); 15438 15439 status = sme_send_unit_test_cmd(vdev_id, 10, 2, tx_disable); 15440 if (status) 15441 sme_err("Failed to send MCS 15 tx disable"); 15442 15443 status = sme_send_unit_test_cmd(vdev_id, 67, 3, rx_disable); 15444 if (status) 15445 sme_err("Failed to send MCS 15 rx disable"); 15446 } 15447 sme_reset_eht_caps(mac_handle_t mac_handle,uint8_t vdev_id)15448 void sme_reset_eht_caps(mac_handle_t mac_handle, uint8_t vdev_id) 15449 { 15450 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15451 struct csr_roam_session *session; 15452 bool val; 15453 QDF_STATUS status; 15454 uint8_t ba_mode_auto = 0; 15455 15456 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15457 15458 if (!session) { 15459 sme_err("No session for id %d", vdev_id); 15460 return; 15461 } 15462 sme_debug("reset EHT caps"); 15463 mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap = 15464 mac_ctx->mlme_cfg->eht_caps.eht_cap_orig; 15465 csr_update_session_eht_cap(mac_ctx, session); 15466 15467 qdf_mem_copy(&mac_ctx->eht_cap_2g, 15468 &mac_ctx->eht_cap_2g_orig, 15469 sizeof(tDot11fIEeht_cap)); 15470 15471 qdf_mem_copy(&mac_ctx->eht_cap_5g, 15472 &mac_ctx->eht_cap_5g_orig, 15473 sizeof(tDot11fIEeht_cap)); 15474 mac_ctx->usr_eht_testbed_cfg = false; 15475 mac_ctx->roam.configParam.channelBondingMode24GHz = 1; 15476 wlan_mlme_set_sta_mlo_conn_band_bmp(mac_ctx->psoc, 0x77); 15477 wlan_mlme_set_sta_mlo_conn_max_num(mac_ctx->psoc, 2); 15478 status = ucfg_mlme_get_bss_color_collision_det_support(mac_ctx->psoc, 15479 &val); 15480 if (QDF_IS_STATUS_SUCCESS(status)) 15481 ucfg_mlme_set_bss_color_collision_det_sta(mac_ctx->psoc, val); 15482 sme_set_per_link_ba_mode(mac_handle, ba_mode_auto); 15483 sme_set_mcs_15_tx_rx_disable(vdev_id); 15484 wlan_mlme_set_btm_abridge_flag(mac_ctx->psoc, false); 15485 wlan_mlme_set_eht_mld_id(mac_ctx->psoc, 0); 15486 } 15487 sme_update_eht_cap_nss(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t nss)15488 void sme_update_eht_cap_nss(mac_handle_t mac_handle, uint8_t vdev_id, 15489 uint8_t nss) 15490 { 15491 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15492 struct csr_roam_session *session; 15493 tDot11fIEeht_cap *mlme_eht_cap; 15494 15495 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15496 15497 if (!session) { 15498 sme_err("No session for id %d", vdev_id); 15499 return; 15500 } 15501 mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap; 15502 if (!nss || (nss > 2)) { 15503 sme_err("invalid Nss value nss %d", nss); 15504 return; 15505 } 15506 sme_debug("Nss value %d", nss); 15507 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7 = nss; 15508 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_0_to_7 = nss; 15509 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_8_and_9 = nss; 15510 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_8_and_9 = nss; 15511 if (mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11) { 15512 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = nss; 15513 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = nss; 15514 } 15515 if (mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13) { 15516 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = nss; 15517 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = nss; 15518 } 15519 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9 = nss; 15520 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_0_to_9 = nss; 15521 if (mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11) { 15522 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = nss; 15523 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = nss; 15524 } 15525 if (mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13) { 15526 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = nss; 15527 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = nss; 15528 } 15529 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_0_to_9 = nss; 15530 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_0_to_9 = nss; 15531 if (mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11) { 15532 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = nss; 15533 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = nss; 15534 } 15535 if (mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13) { 15536 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = nss; 15537 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = nss; 15538 } 15539 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_0_to_9 = nss; 15540 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_0_to_9 = nss; 15541 15542 if (mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11) { 15543 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = nss; 15544 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = nss; 15545 } 15546 if (mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13) { 15547 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = nss; 15548 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = nss; 15549 } 15550 15551 csr_update_session_eht_cap(mac_ctx, session); 15552 15553 qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap, 15554 sizeof(tDot11fIEeht_cap)); 15555 15556 qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap, 15557 sizeof(tDot11fIEeht_cap)); 15558 } 15559 sme_update_eht_cap_mcs(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t mcs)15560 void sme_update_eht_cap_mcs(mac_handle_t mac_handle, uint8_t vdev_id, 15561 uint8_t mcs) 15562 { 15563 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15564 struct csr_roam_session *session; 15565 tDot11fIEeht_cap *mlme_eht_cap; 15566 uint8_t nss; 15567 15568 session = CSR_GET_SESSION(mac_ctx, vdev_id); 15569 15570 if (!session) { 15571 sme_err("No session for id %d", vdev_id); 15572 return; 15573 } 15574 mlme_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap; 15575 nss = mlme_eht_cap->bw_20_rx_max_nss_for_mcs_0_to_7; 15576 15577 if (!nss) 15578 nss = mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_0_to_9; 15579 if (!nss) { 15580 sme_err("No valid Nss"); 15581 return; 15582 } 15583 sme_debug("nss %d, mcs %d", nss, mcs); 15584 15585 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = 0; 15586 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = 0; 15587 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = 0; 15588 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = 0; 15589 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = 0; 15590 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = 0; 15591 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = 0; 15592 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = 0; 15593 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = 0; 15594 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = 0; 15595 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = 0; 15596 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = 0; 15597 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = 0; 15598 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = 0; 15599 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = 0; 15600 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = 0; 15601 15602 if (mcs > 1) { /* 0 - 11*/ 15603 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_10_and_11 = nss; 15604 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_10_and_11 = nss; 15605 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_10_and_11 = nss; 15606 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_10_and_11 = nss; 15607 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_10_and_11 = nss; 15608 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_10_and_11 = nss; 15609 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_10_and_11 = nss; 15610 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_10_and_11 = nss; 15611 mlme_eht_cap->rx_1024_4096_qam_lt_242_tone_ru = 1; 15612 mlme_eht_cap->tx_1024_4096_qam_lt_242_tone_ru = 1; 15613 } 15614 15615 if (mcs == 3) { /* 0 - 13*/ 15616 mlme_eht_cap->bw_20_rx_max_nss_for_mcs_12_and_13 = nss; 15617 mlme_eht_cap->bw_20_tx_max_nss_for_mcs_12_and_13 = nss; 15618 mlme_eht_cap->bw_le_80_rx_max_nss_for_mcs_12_and_13 = nss; 15619 mlme_eht_cap->bw_le_80_tx_max_nss_for_mcs_12_and_13 = nss; 15620 mlme_eht_cap->bw_160_rx_max_nss_for_mcs_12_and_13 = nss; 15621 mlme_eht_cap->bw_160_tx_max_nss_for_mcs_12_and_13 = nss; 15622 mlme_eht_cap->bw_320_rx_max_nss_for_mcs_12_and_13 = nss; 15623 mlme_eht_cap->bw_320_tx_max_nss_for_mcs_12_and_13 = nss; 15624 } 15625 csr_update_session_eht_cap(mac_ctx, session); 15626 15627 qdf_mem_copy(&mac_ctx->eht_cap_2g, mlme_eht_cap, 15628 sizeof(tDot11fIEeht_cap)); 15629 15630 qdf_mem_copy(&mac_ctx->eht_cap_5g, mlme_eht_cap, 15631 sizeof(tDot11fIEeht_cap)); 15632 } 15633 sme_activate_mlo_links(mac_handle_t mac_handle,uint8_t session_id,uint8_t num_links,struct qdf_mac_addr active_link_addr[2])15634 void sme_activate_mlo_links(mac_handle_t mac_handle, uint8_t session_id, 15635 uint8_t num_links, 15636 struct qdf_mac_addr active_link_addr[2]) 15637 { 15638 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15639 struct csr_roam_session *session; 15640 15641 session = CSR_GET_SESSION(mac_ctx, session_id); 15642 15643 if (!session) { 15644 sme_err("No session for id %d", session_id); 15645 return; 15646 } 15647 15648 if (ml_is_nlink_service_supported(mac_ctx->psoc)) { 15649 policy_mgr_activate_mlo_links_nlink(mac_ctx->psoc, session_id, 15650 num_links, 15651 active_link_addr); 15652 } else { 15653 policy_mgr_activate_mlo_links(mac_ctx->psoc, session_id, 15654 num_links, active_link_addr); 15655 } 15656 } 15657 sme_update_eht_caps(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val,enum sme_eht_tx_bfee_cap_type cap_type,enum QDF_OPMODE op_mode)15658 int sme_update_eht_caps(mac_handle_t mac_handle, uint8_t session_id, 15659 uint8_t cfg_val, enum sme_eht_tx_bfee_cap_type cap_type, 15660 enum QDF_OPMODE op_mode) 15661 { 15662 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15663 struct csr_roam_session *session; 15664 tDot11fIEeht_cap *cfg_eht_cap; 15665 15666 session = CSR_GET_SESSION(mac_ctx, session_id); 15667 15668 if (!session) { 15669 sme_err("No session for id %d", session_id); 15670 return -EINVAL; 15671 } 15672 cfg_eht_cap = &mac_ctx->mlme_cfg->eht_caps.dot11_eht_cap; 15673 15674 switch (cap_type) { 15675 case EHT_TX_BFEE_ENABLE: 15676 cfg_eht_cap->su_beamformee = cfg_val; 15677 break; 15678 case EHT_TX_BFEE_SS_80MHZ: 15679 cfg_eht_cap->bfee_ss_le_80mhz = cfg_val; 15680 break; 15681 case EHT_TX_BFEE_SS_160MHZ: 15682 cfg_eht_cap->bfee_ss_160mhz = cfg_val; 15683 break; 15684 case EHT_TX_BFEE_SS_320MHZ: 15685 cfg_eht_cap->bfee_ss_320mhz = cfg_val; 15686 break; 15687 case EHT_TX_BFEE_SOUNDING_FEEDBACK_RATELIMIT: 15688 cfg_eht_cap->tb_sounding_feedback_rl = cfg_val; 15689 break; 15690 default: 15691 sme_debug("default: Unhandled cap type %d", cap_type); 15692 return -EINVAL; 15693 } 15694 15695 sme_debug("EHT cap: cap type %d, cfg val %d", cap_type, cfg_val); 15696 csr_update_session_eht_cap(mac_ctx, session); 15697 15698 qdf_mem_copy(&mac_ctx->eht_cap_2g, cfg_eht_cap, 15699 sizeof(tDot11fIEeht_cap)); 15700 qdf_mem_copy(&mac_ctx->eht_cap_5g, cfg_eht_cap, 15701 sizeof(tDot11fIEeht_cap)); 15702 sme_set_vdev_ies_per_band(mac_handle, session_id, op_mode); 15703 15704 return 0; 15705 } 15706 15707 int sme_send_vdev_pause_for_bcn_period(mac_handle_t mac_handle,uint8_t session_id,uint8_t cfg_val)15708 sme_send_vdev_pause_for_bcn_period(mac_handle_t mac_handle, uint8_t session_id, 15709 uint8_t cfg_val) 15710 { 15711 struct sme_vdev_pause *vdev_pause; 15712 struct scheduler_msg msg = {0}; 15713 QDF_STATUS status; 15714 15715 vdev_pause = qdf_mem_malloc(sizeof(*vdev_pause)); 15716 if (!vdev_pause) 15717 return -EIO; 15718 15719 vdev_pause->session_id = session_id; 15720 vdev_pause->vdev_pause_duration = cfg_val; 15721 qdf_mem_zero(&msg, sizeof(msg)); 15722 msg.type = eWNI_SME_VDEV_PAUSE_IND; 15723 msg.reserved = 0; 15724 msg.bodyptr = vdev_pause; 15725 status = scheduler_post_message(QDF_MODULE_ID_SME, 15726 QDF_MODULE_ID_PE, 15727 QDF_MODULE_ID_PE, &msg); 15728 if (status != QDF_STATUS_SUCCESS) { 15729 sme_err("Not able to post vdev pause indication"); 15730 qdf_mem_free(vdev_pause); 15731 return -EIO; 15732 } 15733 15734 return 0; 15735 } 15736 #endif 15737 sme_set_nss_capability(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t nss,enum QDF_OPMODE op_mode)15738 void sme_set_nss_capability(mac_handle_t mac_handle, uint8_t vdev_id, 15739 uint8_t nss, enum QDF_OPMODE op_mode) 15740 { 15741 sme_debug("Nss cap update, NSS %d", nss); 15742 15743 sme_update_he_cap_nss(mac_handle, vdev_id, nss); 15744 sme_update_eht_cap_nss(mac_handle, vdev_id, nss); 15745 sme_set_vdev_ies_per_band(mac_handle, vdev_id, op_mode); 15746 } 15747 sme_get_mcs_idx(uint16_t raw_rate,enum tx_rate_info rate_flags,bool is_he_mcs_12_13_supported,uint8_t * nss,uint8_t * dcm,enum txrate_gi * guard_interval,enum tx_rate_info * mcs_rate_flags)15748 uint8_t sme_get_mcs_idx(uint16_t raw_rate, enum tx_rate_info rate_flags, 15749 bool is_he_mcs_12_13_supported, 15750 uint8_t *nss, uint8_t *dcm, 15751 enum txrate_gi *guard_interval, 15752 enum tx_rate_info *mcs_rate_flags) 15753 { 15754 return wma_get_mcs_idx(raw_rate, rate_flags, is_he_mcs_12_13_supported, 15755 nss, dcm, guard_interval, mcs_rate_flags); 15756 } 15757 15758 #ifdef WLAN_UNIT_TEST 15759 #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR sme_get_sta_cxn_info(mac_handle_t mac_handle,uint32_t session_id,char * buf,uint32_t buf_sz)15760 QDF_STATUS sme_get_sta_cxn_info(mac_handle_t mac_handle, uint32_t session_id, 15761 char *buf, uint32_t buf_sz) 15762 { 15763 QDF_STATUS status; 15764 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15765 15766 status = sme_acquire_global_lock(&mac_ctx->sme); 15767 csr_cm_get_sta_cxn_info(mac_ctx, session_id, buf, buf_sz); 15768 sme_release_global_lock(&mac_ctx->sme); 15769 15770 return status; 15771 } 15772 #endif 15773 #endif 15774 15775 QDF_STATUS sme_get_roam_scan_stats(mac_handle_t mac_handle,roam_scan_stats_cb cb,void * context,uint32_t vdev_id)15776 sme_get_roam_scan_stats(mac_handle_t mac_handle, 15777 roam_scan_stats_cb cb, void *context, 15778 uint32_t vdev_id) 15779 { 15780 QDF_STATUS status = QDF_STATUS_E_FAILURE; 15781 struct mac_context *mac = MAC_CONTEXT(mac_handle); 15782 struct scheduler_msg msg = {0}; 15783 struct sir_roam_scan_stats *req; 15784 15785 req = qdf_mem_malloc(sizeof(*req)); 15786 if (!req) 15787 return QDF_STATUS_E_NOMEM; 15788 15789 req->vdev_id = vdev_id; 15790 req->cb = cb; 15791 req->context = context; 15792 15793 status = sme_acquire_global_lock(&mac->sme); 15794 if (QDF_IS_STATUS_SUCCESS(status)) { 15795 msg.bodyptr = req; 15796 msg.type = WMA_GET_ROAM_SCAN_STATS; 15797 msg.reserved = 0; 15798 status = scheduler_post_message(QDF_MODULE_ID_SME, 15799 QDF_MODULE_ID_WMA, 15800 QDF_MODULE_ID_WMA, 15801 &msg); 15802 sme_release_global_lock(&mac->sme); 15803 if (!QDF_IS_STATUS_SUCCESS(status)) { 15804 sme_err("post roam scan stats req failed"); 15805 status = QDF_STATUS_E_FAILURE; 15806 qdf_mem_free(req); 15807 } 15808 } else { 15809 qdf_mem_free(req); 15810 } 15811 15812 return status; 15813 } 15814 15815 #ifdef WLAN_FEATURE_11BE sme_is_phy_mode_11be(eCsrPhyMode phy_mode)15816 static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode) 15817 { 15818 if (phy_mode == eCSR_DOT11_MODE_AUTO || 15819 CSR_IS_DOT11_PHY_MODE_11BE(phy_mode) || 15820 CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phy_mode)) { 15821 return true; 15822 } 15823 15824 return false; 15825 } 15826 #else sme_is_phy_mode_11be(eCsrPhyMode phy_mode)15827 static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode) 15828 { 15829 return false; 15830 } 15831 #endif 15832 sme_update_score_config(mac_handle_t mac_handle,eCsrPhyMode phy_mode,uint8_t num_rf_chains)15833 void sme_update_score_config(mac_handle_t mac_handle, eCsrPhyMode phy_mode, 15834 uint8_t num_rf_chains) 15835 { 15836 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15837 struct wlan_mlme_nss_chains vdev_ini_cfg; 15838 bool bval = false; 15839 uint32_t channel_bonding_mode; 15840 QDF_STATUS status; 15841 struct psoc_phy_config config = {0}; 15842 bool eht_cap; 15843 15844 ucfg_psoc_mlme_get_11be_capab(mac_ctx->psoc, &eht_cap); 15845 config.eht_cap = eht_cap; 15846 15847 qdf_mem_zero(&vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains)); 15848 /* Populate the nss chain params from ini for this vdev type */ 15849 sme_populate_nss_chain_params(mac_handle, &vdev_ini_cfg, 15850 QDF_STA_MODE, num_rf_chains); 15851 15852 config.vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]; 15853 config.vdev_nss_5g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]; 15854 15855 if (config.eht_cap || 15856 phy_mode == eCSR_DOT11_MODE_AUTO || 15857 phy_mode == eCSR_DOT11_MODE_11ax || 15858 phy_mode == eCSR_DOT11_MODE_11ax_ONLY) 15859 config.he_cap = 1; 15860 15861 if (config.he_cap || 15862 phy_mode == eCSR_DOT11_MODE_11ac || 15863 phy_mode == eCSR_DOT11_MODE_11ac_ONLY) 15864 config.vht_cap = 1; 15865 15866 if (config.vht_cap || phy_mode == eCSR_DOT11_MODE_11n || 15867 phy_mode == eCSR_DOT11_MODE_11n_ONLY) 15868 config.ht_cap = 1; 15869 15870 if (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AX)) 15871 config.he_cap = 0; 15872 15873 if (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) 15874 config.vht_cap = 0; 15875 15876 status = wlan_mlme_get_vht_for_24ghz(mac_ctx->psoc, &bval); 15877 if (!QDF_IS_STATUS_SUCCESS(status)) 15878 sme_err("Failed to get vht_for_24ghz"); 15879 if (config.vht_cap && bval) 15880 config.vht_24G_cap = 1; 15881 15882 status = wlan_mlme_get_vht_enable_tx_bf(mac_ctx->psoc, 15883 &bval); 15884 if (!QDF_IS_STATUS_SUCCESS(status)) 15885 sme_err("unable to get vht_enable_tx_bf"); 15886 15887 if (bval) 15888 config.beamformee_cap = 1; 15889 15890 ucfg_mlme_get_channel_bonding_24ghz(mac_ctx->psoc, 15891 &channel_bonding_mode); 15892 config.bw_above_20_24ghz = channel_bonding_mode; 15893 ucfg_mlme_get_channel_bonding_5ghz(mac_ctx->psoc, 15894 &channel_bonding_mode); 15895 config.bw_above_20_5ghz = channel_bonding_mode; 15896 config.max_chan_switch_ie = mlme_max_chan_switch_is_set(mac_ctx->psoc); 15897 15898 wlan_psoc_set_phy_config(mac_ctx->psoc, &config); 15899 } 15900 15901 static void __sme_enable_fw_module_log_level(uint8_t * enable_fw_module_log_level,uint8_t enable_fw_module_log_level_num,int vdev_id,int param_id)15902 __sme_enable_fw_module_log_level(uint8_t *enable_fw_module_log_level, 15903 uint8_t enable_fw_module_log_level_num, 15904 int vdev_id, int param_id) 15905 { 15906 uint8_t count = 0; 15907 uint32_t value = 0; 15908 int ret; 15909 15910 while (count < enable_fw_module_log_level_num) { 15911 /* 15912 * FW module log level input array looks like 15913 * below: 15914 * enable_fw_module_log_level = {<FW Module ID>, 15915 * <Log Level>,...} 15916 * For example: 15917 * enable_fw_module_log_level= 15918 * {1,0,2,1,3,2,4,3,5,4,6,5,7,6} 15919 * Above input array means : 15920 * For FW module ID 1 enable log level 0 15921 * For FW module ID 2 enable log level 1 15922 * For FW module ID 3 enable log level 2 15923 * For FW module ID 4 enable log level 3 15924 * For FW module ID 5 enable log level 4 15925 * For FW module ID 6 enable log level 5 15926 * For FW module ID 7 enable log level 6 15927 */ 15928 15929 if ((enable_fw_module_log_level[count] > WLAN_MODULE_ID_MAX) || 15930 (enable_fw_module_log_level[count + 1] > DBGLOG_LVL_MAX)) { 15931 sme_err("Module id %d or dbglog level %d input value is more than max", 15932 enable_fw_module_log_level[count], 15933 enable_fw_module_log_level[count + 1]); 15934 count += 2; 15935 continue; 15936 } 15937 15938 value = enable_fw_module_log_level[count] << 16; 15939 value |= enable_fw_module_log_level[count + 1]; 15940 ret = sme_cli_set_command(vdev_id, param_id, value, DBG_CMD); 15941 if (ret != 0) 15942 sme_err("Failed to enable FW module log level %d ret %d", 15943 value, ret); 15944 15945 count += 2; 15946 } 15947 } 15948 sme_enable_fw_module_log_level(mac_handle_t mac_handle,int vdev_id)15949 void sme_enable_fw_module_log_level(mac_handle_t mac_handle, int vdev_id) 15950 { 15951 QDF_STATUS status; 15952 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 15953 uint8_t *enable_fw_module_log_level; 15954 uint8_t enable_fw_module_log_level_num; 15955 15956 status = ucfg_fwol_get_enable_fw_module_log_level( 15957 mac_ctx->psoc, &enable_fw_module_log_level, 15958 &enable_fw_module_log_level_num); 15959 if (QDF_IS_STATUS_ERROR(status)) 15960 return; 15961 __sme_enable_fw_module_log_level(enable_fw_module_log_level, 15962 enable_fw_module_log_level_num, 15963 vdev_id, 15964 WMI_DBGLOG_MOD_LOG_LEVEL); 15965 15966 enable_fw_module_log_level_num = 0; 15967 status = ucfg_fwol_wow_get_enable_fw_module_log_level( 15968 mac_ctx->psoc, &enable_fw_module_log_level, 15969 &enable_fw_module_log_level_num); 15970 if (QDF_IS_STATUS_ERROR(status)) 15971 return; 15972 __sme_enable_fw_module_log_level(enable_fw_module_log_level, 15973 enable_fw_module_log_level_num, 15974 vdev_id, 15975 WMI_DBGLOG_MOD_WOW_LOG_LEVEL); 15976 } 15977 15978 #ifdef WLAN_FEATURE_MOTION_DETECTION 15979 /** 15980 * sme_set_md_bl_evt_cb - Register/set motion detection baseline callback 15981 * @mac_handle: mac handle 15982 * @callback_fn: callback function pointer 15983 * @hdd_ctx: hdd context 15984 * 15985 * Return: QDF_STATUS_SUCCESS or non-zero on failure 15986 */ sme_set_md_bl_evt_cb(mac_handle_t mac_handle,QDF_STATUS (* callback_fn)(void * ctx,struct sir_md_bl_evt * event),void * hdd_ctx)15987 QDF_STATUS sme_set_md_bl_evt_cb( 15988 mac_handle_t mac_handle, 15989 QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_bl_evt *event), 15990 void *hdd_ctx 15991 ) 15992 { 15993 struct mac_context *mac = MAC_CONTEXT(mac_handle); 15994 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 15995 15996 qdf_status = sme_acquire_global_lock(&mac->sme); 15997 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 15998 mac->sme.md_bl_evt_cb = callback_fn; 15999 mac->sme.md_ctx = hdd_ctx; 16000 sme_release_global_lock(&mac->sme); 16001 } 16002 return qdf_status; 16003 } 16004 16005 /** 16006 * sme_set_md_host_evt_cb - Register/set motion detection callback 16007 * @mac_handle: mac handle 16008 * @callback_fn: motion detection callback function pointer 16009 * @hdd_ctx: hdd context 16010 * 16011 * Return: QDF_STATUS_SUCCESS or non-zero on failure 16012 */ sme_set_md_host_evt_cb(mac_handle_t mac_handle,QDF_STATUS (* callback_fn)(void * ctx,struct sir_md_evt * event),void * hdd_ctx)16013 QDF_STATUS sme_set_md_host_evt_cb( 16014 mac_handle_t mac_handle, 16015 QDF_STATUS (*callback_fn)(void *ctx, struct sir_md_evt *event), 16016 void *hdd_ctx 16017 ) 16018 { 16019 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16020 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16021 16022 qdf_status = sme_acquire_global_lock(&mac->sme); 16023 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 16024 mac->sme.md_host_evt_cb = callback_fn; 16025 mac->sme.md_ctx = hdd_ctx; 16026 sme_release_global_lock(&mac->sme); 16027 } 16028 return qdf_status; 16029 } 16030 16031 /** 16032 * sme_motion_det_config - Post motion detection configuration msg to scheduler 16033 * @mac_handle: mac handle 16034 * @motion_det_config: motion detection configuration 16035 * 16036 * Return: QDF_STATUS_SUCCESS or non-zero on failure 16037 */ sme_motion_det_config(mac_handle_t mac_handle,struct sme_motion_det_cfg * motion_det_config)16038 QDF_STATUS sme_motion_det_config(mac_handle_t mac_handle, 16039 struct sme_motion_det_cfg *motion_det_config) 16040 { 16041 struct scheduler_msg msg; 16042 struct sme_motion_det_cfg *motion_det_cfg; 16043 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16044 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16045 16046 qdf_status = sme_acquire_global_lock(&mac->sme); 16047 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 16048 motion_det_cfg = 16049 qdf_mem_malloc(sizeof(*motion_det_cfg)); 16050 if (!motion_det_cfg) { 16051 sme_release_global_lock(&mac->sme); 16052 return QDF_STATUS_E_NOMEM; 16053 } 16054 16055 *motion_det_cfg = *motion_det_config; 16056 16057 qdf_mem_set(&msg, sizeof(msg), 0); 16058 msg.type = WMA_SET_MOTION_DET_CONFIG; 16059 msg.bodyptr = motion_det_cfg; 16060 16061 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16062 QDF_MODULE_ID_WMA, 16063 QDF_MODULE_ID_WMA, 16064 &msg); 16065 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16066 qdf_mem_free(motion_det_cfg); 16067 qdf_status = QDF_STATUS_E_FAILURE; 16068 } 16069 sme_release_global_lock(&mac->sme); 16070 } 16071 return qdf_status; 16072 } 16073 16074 /** 16075 * sme_motion_det_enable - Post motion detection start/stop msg to scheduler 16076 * @mac_handle: mac handle 16077 * @motion_det_enable: motion detection start/stop 16078 * 16079 * Return: QDF_STATUS_SUCCESS or non-zero on failure 16080 */ sme_motion_det_enable(mac_handle_t mac_handle,struct sme_motion_det_en * motion_det_enable)16081 QDF_STATUS sme_motion_det_enable(mac_handle_t mac_handle, 16082 struct sme_motion_det_en *motion_det_enable) 16083 { 16084 struct scheduler_msg msg; 16085 struct sme_motion_det_en *motion_det_en; 16086 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16087 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16088 16089 qdf_status = sme_acquire_global_lock(&mac->sme); 16090 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 16091 motion_det_en = qdf_mem_malloc(sizeof(*motion_det_en)); 16092 if (!motion_det_en) { 16093 sme_release_global_lock(&mac->sme); 16094 return QDF_STATUS_E_NOMEM; 16095 } 16096 16097 *motion_det_en = *motion_det_enable; 16098 16099 qdf_mem_set(&msg, sizeof(msg), 0); 16100 msg.type = WMA_SET_MOTION_DET_ENABLE; 16101 msg.bodyptr = motion_det_en; 16102 16103 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16104 QDF_MODULE_ID_WMA, 16105 QDF_MODULE_ID_WMA, 16106 &msg); 16107 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16108 qdf_mem_free(motion_det_en); 16109 qdf_status = QDF_STATUS_E_FAILURE; 16110 } 16111 sme_release_global_lock(&mac->sme); 16112 } 16113 return qdf_status; 16114 } 16115 16116 /** 16117 * sme_motion_det_base_line_config - Post md baselining cfg msg to scheduler 16118 * @mac_handle: mac handle 16119 * @motion_det_base_line_config: motion detection baselining configuration 16120 * 16121 * Return: QDF_STATUS_SUCCESS or non-zero on failure 16122 */ sme_motion_det_base_line_config(mac_handle_t mac_handle,struct sme_motion_det_base_line_cfg * motion_det_base_line_config)16123 QDF_STATUS sme_motion_det_base_line_config( 16124 mac_handle_t mac_handle, 16125 struct sme_motion_det_base_line_cfg *motion_det_base_line_config) 16126 { 16127 struct scheduler_msg msg; 16128 struct sme_motion_det_base_line_cfg *motion_det_base_line_cfg; 16129 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16130 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16131 16132 qdf_status = sme_acquire_global_lock(&mac->sme); 16133 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 16134 motion_det_base_line_cfg = 16135 qdf_mem_malloc(sizeof(*motion_det_base_line_cfg)); 16136 16137 if (!motion_det_base_line_cfg) { 16138 sme_release_global_lock(&mac->sme); 16139 return QDF_STATUS_E_NOMEM; 16140 } 16141 16142 *motion_det_base_line_cfg = *motion_det_base_line_config; 16143 16144 qdf_mem_set(&msg, sizeof(msg), 0); 16145 msg.type = WMA_SET_MOTION_DET_BASE_LINE_CONFIG; 16146 msg.bodyptr = motion_det_base_line_cfg; 16147 16148 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16149 QDF_MODULE_ID_WMA, 16150 QDF_MODULE_ID_WMA, 16151 &msg); 16152 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16153 qdf_mem_free(motion_det_base_line_cfg); 16154 qdf_status = QDF_STATUS_E_FAILURE; 16155 } 16156 sme_release_global_lock(&mac->sme); 16157 } 16158 return qdf_status; 16159 } 16160 16161 /** 16162 * sme_motion_det_base_line_enable - Post md baselining enable msg to scheduler 16163 * @mac_handle: mac handle 16164 * @motion_det_base_line_enable: motion detection baselining start/stop 16165 * 16166 * Return: QDF_STATUS_SUCCESS or non-zero on failure 16167 */ sme_motion_det_base_line_enable(mac_handle_t mac_handle,struct sme_motion_det_base_line_en * motion_det_base_line_enable)16168 QDF_STATUS sme_motion_det_base_line_enable( 16169 mac_handle_t mac_handle, 16170 struct sme_motion_det_base_line_en *motion_det_base_line_enable) 16171 { 16172 struct scheduler_msg msg; 16173 struct sme_motion_det_base_line_en *motion_det_base_line_en; 16174 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16175 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16176 16177 qdf_status = sme_acquire_global_lock(&mac->sme); 16178 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 16179 motion_det_base_line_en = 16180 qdf_mem_malloc(sizeof(*motion_det_base_line_en)); 16181 16182 if (!motion_det_base_line_en) { 16183 sme_release_global_lock(&mac->sme); 16184 return QDF_STATUS_E_NOMEM; 16185 } 16186 16187 *motion_det_base_line_en = *motion_det_base_line_enable; 16188 16189 qdf_mem_set(&msg, sizeof(msg), 0); 16190 msg.type = WMA_SET_MOTION_DET_BASE_LINE_ENABLE; 16191 msg.bodyptr = motion_det_base_line_en; 16192 16193 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16194 QDF_MODULE_ID_WMA, 16195 QDF_MODULE_ID_WMA, 16196 &msg); 16197 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16198 qdf_mem_free(motion_det_base_line_en); 16199 qdf_status = QDF_STATUS_E_FAILURE; 16200 } 16201 sme_release_global_lock(&mac->sme); 16202 } 16203 return qdf_status; 16204 } 16205 #endif /* WLAN_FEATURE_MOTION_DETECTION */ 16206 16207 #ifdef FW_THERMAL_THROTTLE_SUPPORT 16208 16209 /** 16210 * sme_set_thermal_throttle_cfg() - SME API to set the thermal throttle 16211 * configuration parameters 16212 * @mac_handle: Opaque handle to the global MAC context 16213 * @therm_params: structure of thermal configuration parameters 16214 * 16215 * Return: QDF_STATUS 16216 */ sme_set_thermal_throttle_cfg(mac_handle_t mac_handle,struct thermal_mitigation_params * therm_params)16217 QDF_STATUS sme_set_thermal_throttle_cfg(mac_handle_t mac_handle, 16218 struct thermal_mitigation_params *therm_params) 16219 16220 { 16221 struct scheduler_msg msg; 16222 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16223 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16224 struct thermal_mitigation_params *therm_cfg_params; 16225 16226 therm_cfg_params = qdf_mem_malloc(sizeof(*therm_cfg_params)); 16227 if (!therm_cfg_params) 16228 return QDF_STATUS_E_NOMEM; 16229 16230 qdf_mem_set(therm_cfg_params, sizeof(*therm_cfg_params), 0); 16231 qdf_mem_copy(therm_cfg_params, therm_params, sizeof(*therm_cfg_params)); 16232 16233 qdf_mem_set(&msg, sizeof(msg), 0); 16234 msg.type = WMA_SET_THERMAL_THROTTLE_CFG; 16235 msg.reserved = 0; 16236 msg.bodyptr = therm_cfg_params; 16237 16238 qdf_status = sme_acquire_global_lock(&mac->sme); 16239 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16240 QDF_MODULE_ID_WMA, 16241 QDF_MODULE_ID_WMA, &msg); 16242 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16243 sme_err("failed to schedule throttle config req %d", 16244 qdf_status); 16245 qdf_mem_free(therm_cfg_params); 16246 qdf_status = QDF_STATUS_E_FAILURE; 16247 } 16248 sme_release_global_lock(&mac->sme); 16249 return qdf_status; 16250 } 16251 16252 /** 16253 * sme_set_thermal_mgmt() - SME API to set the thermal management params 16254 * @mac_handle: Opaque handle to the global MAC context 16255 * @lower_thresh_deg: Lower threshold value of Temperature 16256 * @higher_thresh_deg: Higher threshold value of Temperature 16257 * 16258 * Return: QDF_STATUS 16259 */ sme_set_thermal_mgmt(mac_handle_t mac_handle,uint16_t lower_thresh_deg,uint16_t higher_thresh_deg)16260 QDF_STATUS sme_set_thermal_mgmt(mac_handle_t mac_handle, 16261 uint16_t lower_thresh_deg, 16262 uint16_t higher_thresh_deg) 16263 { 16264 struct scheduler_msg msg; 16265 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16266 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 16267 t_thermal_cmd_params *therm_mgmt_cmd; 16268 16269 qdf_status = sme_acquire_global_lock(&mac->sme); 16270 if (QDF_STATUS_SUCCESS == qdf_status) { 16271 therm_mgmt_cmd = qdf_mem_malloc(sizeof(*therm_mgmt_cmd)); 16272 if (!therm_mgmt_cmd) { 16273 sme_release_global_lock(&mac->sme); 16274 return QDF_STATUS_E_NOMEM; 16275 } 16276 16277 therm_mgmt_cmd->minTemp = lower_thresh_deg; 16278 therm_mgmt_cmd->maxTemp = higher_thresh_deg; 16279 therm_mgmt_cmd->thermalEnable = 1; 16280 16281 qdf_mem_set(&msg, sizeof(msg), 0); 16282 msg.type = WMA_SET_THERMAL_MGMT; 16283 msg.reserved = 0; 16284 msg.bodyptr = therm_mgmt_cmd; 16285 16286 qdf_status = scheduler_post_message(QDF_MODULE_ID_SME, 16287 QDF_MODULE_ID_WMA, 16288 QDF_MODULE_ID_WMA, &msg); 16289 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 16290 qdf_mem_free(therm_mgmt_cmd); 16291 qdf_status = QDF_STATUS_E_FAILURE; 16292 } 16293 sme_release_global_lock(&mac->sme); 16294 } 16295 return qdf_status; 16296 } 16297 #endif /* FW_THERMAL_THROTTLE_SUPPORT */ 16298 sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle,hidden_ssid_cb cb)16299 QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle, 16300 hidden_ssid_cb cb) 16301 { 16302 QDF_STATUS status; 16303 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16304 16305 status = sme_acquire_global_lock(&mac->sme); 16306 if (QDF_IS_STATUS_SUCCESS(status)) { 16307 mac->sme.hidden_ssid_cb = cb; 16308 sme_release_global_lock(&mac->sme); 16309 } 16310 16311 return status; 16312 } 16313 sme_update_owe_info(struct mac_context * mac,struct assoc_ind * assoc_ind)16314 QDF_STATUS sme_update_owe_info(struct mac_context *mac, 16315 struct assoc_ind *assoc_ind) 16316 { 16317 QDF_STATUS status; 16318 16319 status = sme_acquire_global_lock(&mac->sme); 16320 if (QDF_IS_STATUS_SUCCESS(status)) { 16321 status = csr_update_owe_info(mac, assoc_ind); 16322 sme_release_global_lock(&mac->sme); 16323 } 16324 16325 return status; 16326 } 16327 sme_update_ft_info(struct mac_context * mac,struct assoc_ind * assoc_ind)16328 QDF_STATUS sme_update_ft_info(struct mac_context *mac, 16329 struct assoc_ind *assoc_ind) 16330 { 16331 QDF_STATUS status; 16332 16333 status = sme_acquire_global_lock(&mac->sme); 16334 if (QDF_IS_STATUS_SUCCESS(status)) { 16335 status = csr_update_ft_info(mac, assoc_ind); 16336 sme_release_global_lock(&mac->sme); 16337 } 16338 16339 return status; 16340 } 16341 16342 #ifdef WLAN_MWS_INFO_DEBUGFS 16343 QDF_STATUS sme_get_mws_coex_info(mac_handle_t mac_handle,uint32_t vdev_id,uint32_t cmd_id,void (* callback_fn)(void * coex_info_data,void * context,wmi_mws_coex_cmd_id cmd_id),void * context)16344 sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id, 16345 uint32_t cmd_id, void (*callback_fn)(void *coex_info_data, 16346 void *context, 16347 wmi_mws_coex_cmd_id 16348 cmd_id), 16349 void *context) 16350 { 16351 QDF_STATUS status = QDF_STATUS_E_FAILURE; 16352 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16353 struct scheduler_msg msg = {0}; 16354 struct sir_get_mws_coex_info *req; 16355 16356 req = qdf_mem_malloc(sizeof(*req)); 16357 if (!req) 16358 return QDF_STATUS_E_NOMEM; 16359 16360 req->vdev_id = vdev_id; 16361 req->cmd_id = cmd_id; 16362 mac->sme.mws_coex_info_state_resp_callback = callback_fn; 16363 mac->sme.mws_coex_info_ctx = context; 16364 status = sme_acquire_global_lock(&mac->sme); 16365 if (QDF_IS_STATUS_SUCCESS(status)) { 16366 msg.bodyptr = req; 16367 msg.type = WMA_GET_MWS_COEX_INFO_REQ; 16368 status = scheduler_post_message(QDF_MODULE_ID_SME, 16369 QDF_MODULE_ID_WMA, 16370 QDF_MODULE_ID_WMA, 16371 &msg); 16372 sme_release_global_lock(&mac->sme); 16373 if (!QDF_IS_STATUS_SUCCESS(status)) { 16374 sme_err("post MWS coex info req failed"); 16375 status = QDF_STATUS_E_FAILURE; 16376 qdf_mem_free(req); 16377 } 16378 } else { 16379 sme_err("sme_acquire_global_lock failed"); 16380 qdf_mem_free(req); 16381 } 16382 16383 return status; 16384 } 16385 #endif /* WLAN_MWS_INFO_DEBUGFS */ 16386 16387 #ifdef WLAN_BCN_RECV_FEATURE 16388 /** 16389 * sme_scan_event_handler() - Scan complete event handler 16390 * @vdev: vdev obj manager 16391 * @event: scan event 16392 * @arg: arg of scan event 16393 * 16394 * This function is getting called after Host receive scan start 16395 * 16396 * Return: None 16397 */ sme_scan_event_handler(struct wlan_objmgr_vdev * vdev,struct scan_event * event,void * arg)16398 static void sme_scan_event_handler(struct wlan_objmgr_vdev *vdev, 16399 struct scan_event *event, 16400 void *arg) 16401 { 16402 struct mac_context *mac = arg; 16403 uint8_t vdev_id; 16404 16405 if (!mac) { 16406 sme_err("Invalid mac context"); 16407 return; 16408 } 16409 16410 if (!mac->sme.beacon_pause_cb) 16411 return; 16412 16413 if (event->type != SCAN_EVENT_TYPE_STARTED) 16414 return; 16415 16416 for (vdev_id = 0 ; vdev_id < WLAN_MAX_VDEVS ; vdev_id++) { 16417 if (CSR_IS_SESSION_VALID(mac, vdev_id) && 16418 sme_is_beacon_report_started(MAC_HANDLE(mac), vdev_id)) { 16419 sme_debug("Send pause ind for vdev_id : %d", vdev_id); 16420 mac->sme.beacon_pause_cb(mac->hdd_handle, vdev_id, 16421 event->type, false); 16422 } 16423 } 16424 } 16425 sme_register_bcn_recv_pause_ind_cb(mac_handle_t mac_handle,beacon_pause_cb cb)16426 QDF_STATUS sme_register_bcn_recv_pause_ind_cb(mac_handle_t mac_handle, 16427 beacon_pause_cb cb) 16428 { 16429 QDF_STATUS status; 16430 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16431 16432 if (!mac) { 16433 sme_err("Invalid mac context"); 16434 return QDF_STATUS_E_NOMEM; 16435 } 16436 16437 /* scan event de-registration */ 16438 if (!cb) { 16439 ucfg_scan_unregister_event_handler(mac->pdev, 16440 sme_scan_event_handler, mac); 16441 return QDF_STATUS_SUCCESS; 16442 } 16443 status = sme_acquire_global_lock(&mac->sme); 16444 if (QDF_IS_STATUS_SUCCESS(status)) { 16445 mac->sme.beacon_pause_cb = cb; 16446 sme_release_global_lock(&mac->sme); 16447 } 16448 16449 /* scan event registration */ 16450 status = ucfg_scan_register_event_handler(mac->pdev, 16451 sme_scan_event_handler, mac); 16452 if (QDF_IS_STATUS_ERROR(status)) 16453 sme_err("scan event register failed "); 16454 16455 return status; 16456 } 16457 #endif 16458 sme_set_vdev_sw_retry(uint8_t vdev_id,uint8_t sw_retry_count,wmi_vdev_custom_sw_retry_type_t sw_retry_type)16459 QDF_STATUS sme_set_vdev_sw_retry(uint8_t vdev_id, uint8_t sw_retry_count, 16460 wmi_vdev_custom_sw_retry_type_t sw_retry_type) 16461 { 16462 QDF_STATUS status; 16463 16464 status = wma_set_vdev_sw_retry_th(vdev_id, sw_retry_count, 16465 sw_retry_type); 16466 if (QDF_IS_STATUS_ERROR(status)) { 16467 sme_err("Failed to set retry count for vdev: %d", vdev_id); 16468 return status; 16469 } 16470 16471 return QDF_STATUS_SUCCESS; 16472 } 16473 sme_set_disconnect_ies(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * ie_data,uint16_t ie_len)16474 QDF_STATUS sme_set_disconnect_ies(mac_handle_t mac_handle, uint8_t vdev_id, 16475 uint8_t *ie_data, uint16_t ie_len) 16476 { 16477 struct mac_context *mac_ctx; 16478 struct wlan_objmgr_vdev *vdev; 16479 struct element_info ie; 16480 16481 if (!ie_data || !ie_len) { 16482 sme_debug("Got NULL disconnect IEs"); 16483 return QDF_STATUS_E_INVAL; 16484 } 16485 16486 mac_ctx = MAC_CONTEXT(mac_handle); 16487 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, 16488 vdev_id, 16489 WLAN_LEGACY_SME_ID); 16490 if (!vdev) { 16491 sme_err("Got NULL vdev obj, returning"); 16492 return QDF_STATUS_E_FAILURE; 16493 } 16494 16495 ie.ptr = ie_data; 16496 ie.len = ie_len; 16497 16498 mlme_set_self_disconnect_ies(vdev, &ie); 16499 16500 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); 16501 return QDF_STATUS_SUCCESS; 16502 } 16503 16504 QDF_STATUS sme_send_vendor_btm_params(mac_handle_t mac_handle,uint8_t vdev_id)16505 sme_send_vendor_btm_params(mac_handle_t mac_handle, uint8_t vdev_id) 16506 { 16507 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16508 QDF_STATUS status = QDF_STATUS_SUCCESS; 16509 16510 if (vdev_id >= WLAN_MAX_VDEVS) { 16511 sme_err("Invalid sme session id: %d", vdev_id); 16512 return QDF_STATUS_E_INVAL; 16513 } 16514 16515 status = sme_acquire_global_lock(&mac->sme); 16516 if (QDF_IS_STATUS_SUCCESS(status)) { 16517 if (mac->mlme_cfg->lfr.roam_scan_offload_enabled) 16518 wlan_roam_update_cfg(mac->psoc, vdev_id, 16519 REASON_ROAM_CONTROL_CONFIG_CHANGED); 16520 sme_release_global_lock(&mac->sme); 16521 } 16522 16523 return status; 16524 } 16525 sme_set_roam_config_enable(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t roam_control_enable)16526 QDF_STATUS sme_set_roam_config_enable(mac_handle_t mac_handle, 16527 uint8_t vdev_id, 16528 uint8_t roam_control_enable) 16529 { 16530 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16531 struct cm_roam_values_copy src_config = {}; 16532 16533 if (!mac->mlme_cfg->lfr.roam_scan_offload_enabled) 16534 return QDF_STATUS_E_INVAL; 16535 16536 src_config.bool_value = !!roam_control_enable; 16537 return wlan_cm_roam_cfg_set_value(mac->psoc, vdev_id, 16538 ROAM_CONFIG_ENABLE, 16539 &src_config); 16540 } 16541 sme_get_roam_config_status(mac_handle_t mac_handle,uint8_t vdev_id,uint8_t * config_status)16542 QDF_STATUS sme_get_roam_config_status(mac_handle_t mac_handle, 16543 uint8_t vdev_id, 16544 uint8_t *config_status) 16545 { 16546 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16547 struct cm_roam_values_copy temp; 16548 16549 wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id, ROAM_CONTROL_ENABLE, 16550 &temp); 16551 *config_status = temp.bool_value; 16552 16553 return QDF_STATUS_SUCCESS; 16554 } 16555 sme_get_full_roam_scan_period_global(mac_handle_t mac_handle)16556 uint16_t sme_get_full_roam_scan_period_global(mac_handle_t mac_handle) 16557 { 16558 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16559 16560 return mac->mlme_cfg->lfr.roam_full_scan_period; 16561 } 16562 16563 QDF_STATUS sme_get_full_roam_scan_period(mac_handle_t mac_handle,uint8_t vdev_id,uint32_t * full_roam_scan_period)16564 sme_get_full_roam_scan_period(mac_handle_t mac_handle, uint8_t vdev_id, 16565 uint32_t *full_roam_scan_period) 16566 { 16567 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16568 struct cm_roam_values_copy temp; 16569 16570 wlan_cm_roam_cfg_get_value(mac->psoc, vdev_id, 16571 FULL_ROAM_SCAN_PERIOD, &temp); 16572 *full_roam_scan_period = temp.uint_value; 16573 16574 return QDF_STATUS_SUCCESS; 16575 } 16576 sme_check_for_duplicate_session(mac_handle_t mac_handle,uint8_t ** mac_list)16577 QDF_STATUS sme_check_for_duplicate_session(mac_handle_t mac_handle, 16578 uint8_t **mac_list) 16579 { 16580 QDF_STATUS status = QDF_STATUS_SUCCESS; 16581 bool peer_exist = false; 16582 void *soc = cds_get_context(QDF_MODULE_ID_SOC); 16583 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 16584 uint8_t **peer_addr = mac_list; 16585 16586 if (!soc) 16587 return QDF_STATUS_E_INVAL; 16588 16589 if (QDF_STATUS_SUCCESS != sme_acquire_global_lock(&mac_ctx->sme)) 16590 return QDF_STATUS_E_INVAL; 16591 16592 while (*peer_addr) { 16593 peer_exist = cdp_find_peer_exist(soc, OL_TXRX_PDEV_ID, 16594 *peer_addr); 16595 if (peer_exist) { 16596 sme_err("Peer exists with same MAC"); 16597 status = QDF_STATUS_E_EXISTS; 16598 break; 16599 } 16600 peer_addr++; 16601 } 16602 sme_release_global_lock(&mac_ctx->sme); 16603 16604 return status; 16605 } 16606 16607 #ifdef FEATURE_ANI_LEVEL_REQUEST sme_get_ani_level(mac_handle_t mac_handle,uint32_t * freqs,uint8_t num_freqs,void (* callback)(struct wmi_host_ani_level_event * ani,uint8_t num,void * context),void * context)16608 QDF_STATUS sme_get_ani_level(mac_handle_t mac_handle, uint32_t *freqs, 16609 uint8_t num_freqs, void (*callback)( 16610 struct wmi_host_ani_level_event *ani, uint8_t num, 16611 void *context), void *context) 16612 { 16613 QDF_STATUS status = QDF_STATUS_E_FAILURE; 16614 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16615 void *wma_handle; 16616 16617 wma_handle = cds_get_context(QDF_MODULE_ID_WMA); 16618 if (!wma_handle) 16619 return QDF_STATUS_E_FAILURE; 16620 16621 mac->ani_params.ani_level_cb = callback; 16622 mac->ani_params.context = context; 16623 16624 status = wma_send_ani_level_request(wma_handle, freqs, num_freqs); 16625 return status; 16626 } 16627 #endif /* FEATURE_ANI_LEVEL_REQUEST */ 16628 16629 #ifdef FEATURE_MONITOR_MODE_SUPPORT 16630 sme_set_monitor_mode_cb(mac_handle_t mac_handle,void (* monitor_mode_cb)(uint8_t vdev_id))16631 QDF_STATUS sme_set_monitor_mode_cb(mac_handle_t mac_handle, 16632 void (*monitor_mode_cb)(uint8_t vdev_id)) 16633 { 16634 QDF_STATUS qdf_status; 16635 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16636 16637 qdf_status = sme_acquire_global_lock(&mac->sme); 16638 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16639 sme_err("Failed to acquire sme lock; status: %d", qdf_status); 16640 return qdf_status; 16641 } 16642 mac->sme.monitor_mode_cb = monitor_mode_cb; 16643 sme_release_global_lock(&mac->sme); 16644 16645 return qdf_status; 16646 } 16647 sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id)16648 QDF_STATUS sme_process_monitor_mode_vdev_up_evt(uint8_t vdev_id) 16649 { 16650 mac_handle_t mac_handle; 16651 struct mac_context *mac; 16652 16653 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 16654 if (!mac_handle) 16655 return QDF_STATUS_E_INVAL; 16656 16657 mac = MAC_CONTEXT(mac_handle); 16658 16659 if (mac->sme.monitor_mode_cb) 16660 mac->sme.monitor_mode_cb(vdev_id); 16661 else { 16662 sme_warn_rl("monitor_mode_cb is not registered"); 16663 return QDF_STATUS_E_FAILURE; 16664 } 16665 16666 return QDF_STATUS_SUCCESS; 16667 } 16668 #endif 16669 16670 #if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE) 16671 QDF_STATUS sme_set_beacon_latency_event_cb(mac_handle_t mac_handle,void (* beacon_latency_event_cb)(uint32_t latency_level))16672 sme_set_beacon_latency_event_cb(mac_handle_t mac_handle, 16673 void (*beacon_latency_event_cb) 16674 (uint32_t latency_level)) 16675 { 16676 QDF_STATUS qdf_status; 16677 struct mac_context *mac = MAC_CONTEXT(mac_handle); 16678 16679 qdf_status = sme_acquire_global_lock(&mac->sme); 16680 if (QDF_IS_STATUS_ERROR(qdf_status)) { 16681 sme_err("Failed to acquire sme lock; status: %d", qdf_status); 16682 return qdf_status; 16683 } 16684 mac->sme.beacon_latency_event_cb = beacon_latency_event_cb; 16685 sme_release_global_lock(&mac->sme); 16686 16687 return qdf_status; 16688 } 16689 #endif 16690 sme_fill_enc_type(eCsrEncryptionType * cipher_type,uint32_t cipherset)16691 void sme_fill_enc_type(eCsrEncryptionType *cipher_type, 16692 uint32_t cipherset) 16693 { 16694 csr_fill_enc_type(cipher_type, cipherset); 16695 } 16696 sme_fill_auth_type(enum csr_akm_type * auth_type,uint32_t authmodeset,uint32_t akm,uint32_t ucastcipherset)16697 void sme_fill_auth_type(enum csr_akm_type *auth_type, 16698 uint32_t authmodeset, uint32_t akm, 16699 uint32_t ucastcipherset) 16700 { 16701 csr_fill_auth_type(auth_type, authmodeset, 16702 akm, ucastcipherset); 16703 } 16704 sme_phy_mode_to_dot11mode(enum wlan_phymode phy_mode)16705 enum csr_cfgdot11mode sme_phy_mode_to_dot11mode(enum wlan_phymode phy_mode) 16706 { 16707 return csr_phy_mode_to_dot11mode(phy_mode); 16708 } 16709 sme_switch_channel(mac_handle_t mac_handle,struct qdf_mac_addr * bssid,qdf_freq_t chan_freq,enum phy_ch_width chan_width)16710 QDF_STATUS sme_switch_channel(mac_handle_t mac_handle, 16711 struct qdf_mac_addr *bssid, 16712 qdf_freq_t chan_freq, 16713 enum phy_ch_width chan_width) 16714 { 16715 struct scheduler_msg msg = {0}; 16716 struct csa_offload_params *csa_offload_event; 16717 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 16718 16719 csa_offload_event = qdf_mem_malloc(sizeof(*csa_offload_event)); 16720 if (!csa_offload_event) 16721 return QDF_STATUS_E_NOMEM; 16722 16723 qdf_copy_macaddr(&csa_offload_event->bssid, bssid); 16724 csa_offload_event->csa_chan_freq = (uint32_t)chan_freq; 16725 csa_offload_event->new_ch_width = chan_width; 16726 csa_offload_event->channel = 16727 wlan_reg_freq_to_chan(mac_ctx->pdev, 16728 csa_offload_event->csa_chan_freq); 16729 csa_offload_event->switch_mode = 1; 16730 16731 sme_debug("bssid " QDF_MAC_ADDR_FMT " freq %u width %u", 16732 QDF_MAC_ADDR_REF(csa_offload_event->bssid.bytes), 16733 csa_offload_event->csa_chan_freq, 16734 csa_offload_event->new_ch_width); 16735 16736 msg.type = eWNI_SME_CSA_REQ; 16737 msg.reserved = 0; 16738 msg.bodyptr = csa_offload_event; 16739 16740 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 16741 QDF_MODULE_ID_PE, 16742 QDF_MODULE_ID_PE, 16743 &msg)) { 16744 qdf_mem_free(csa_offload_event); 16745 sme_err("Not able to post WMA_CSA_OFFLOAD_EVENT to PE"); 16746 return QDF_STATUS_E_FAILURE; 16747 } 16748 16749 return QDF_STATUS_SUCCESS; 16750 } 16751 16752 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,struct wlan_objmgr_vdev * vdev)16753 QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr, 16754 struct qdf_mac_addr mld_addr, 16755 struct wlan_objmgr_vdev *vdev) 16756 { 16757 enum QDF_OPMODE vdev_opmode; 16758 QDF_STATUS status; 16759 struct vdev_mlme_obj *vdev_mlme; 16760 16761 if (!vdev) { 16762 sme_err("Invalid VDEV"); 16763 return QDF_STATUS_E_INVAL; 16764 } 16765 16766 vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); 16767 16768 if (vdev_opmode == QDF_P2P_DEVICE_MODE) { 16769 status = wma_p2p_self_peer_remove(vdev); 16770 if (QDF_IS_STATUS_ERROR(status)) 16771 return status; 16772 } 16773 16774 status = wlan_vdev_mlme_send_set_mac_addr(mac_addr, mld_addr, vdev); 16775 if (QDF_IS_STATUS_SUCCESS(status)) 16776 return status; 16777 16778 /** 16779 * Failed to send set MAC address command to FW. Create P2P self peer 16780 * again with old MAC address 16781 */ 16782 if (vdev_opmode == QDF_P2P_DEVICE_MODE) { 16783 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 16784 if (!vdev_mlme) { 16785 sme_err("Invalid vdev MLME context"); 16786 return QDF_STATUS_E_INVAL; 16787 } 16788 16789 status = wma_vdev_self_peer_create(vdev_mlme); 16790 if (QDF_IS_STATUS_ERROR(status)) { 16791 sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d", 16792 status); 16793 return QDF_STATUS_E_INVAL; 16794 } 16795 } 16796 16797 return QDF_STATUS_E_INVAL; 16798 } 16799 sme_update_vdev_mac_addr(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,bool update_sta_self_peer,bool update_mld_addr,int req_status)16800 QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_vdev *vdev, 16801 struct qdf_mac_addr mac_addr, 16802 struct qdf_mac_addr mld_addr, 16803 bool update_sta_self_peer, 16804 bool update_mld_addr, int req_status) 16805 { 16806 enum QDF_OPMODE vdev_opmode; 16807 uint8_t *old_macaddr, *new_macaddr; 16808 QDF_STATUS qdf_ret_status; 16809 struct wlan_objmgr_peer *peer; 16810 struct vdev_mlme_obj *vdev_mlme; 16811 struct wlan_objmgr_psoc *psoc; 16812 16813 psoc = wlan_vdev_get_psoc(vdev); 16814 16815 vdev_opmode = wlan_vdev_mlme_get_opmode(vdev); 16816 16817 if (req_status) 16818 goto p2p_self_peer_create; 16819 16820 if (vdev_opmode == QDF_STA_MODE && update_sta_self_peer) { 16821 if (update_mld_addr) { 16822 old_macaddr = wlan_vdev_mlme_get_mldaddr(vdev); 16823 new_macaddr = mld_addr.bytes; 16824 } else { 16825 old_macaddr = wlan_vdev_mlme_get_macaddr(vdev); 16826 new_macaddr = mac_addr.bytes; 16827 } 16828 16829 /* Update self peer MAC address */ 16830 peer = wlan_objmgr_get_peer_by_mac(psoc, old_macaddr, 16831 WLAN_MLME_NB_ID); 16832 if (peer) { 16833 qdf_ret_status = wlan_peer_update_macaddr(peer, 16834 new_macaddr); 16835 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID); 16836 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) { 16837 sme_nofl_err("Failed to update self peer MAC address. Status:%d", 16838 qdf_ret_status); 16839 return qdf_ret_status; 16840 } 16841 } else { 16842 sme_err("Self peer not found with MAC addr:" 16843 QDF_MAC_ADDR_FMT, 16844 QDF_MAC_ADDR_REF(old_macaddr)); 16845 return QDF_STATUS_E_INVAL; 16846 } 16847 } 16848 16849 /* Update VDEV MAC address */ 16850 if (update_mld_addr) { 16851 if (update_sta_self_peer || vdev_opmode == QDF_SAP_MODE) { 16852 qdf_ret_status = wlan_mlo_mgr_update_mld_addr( 16853 (struct qdf_mac_addr *) 16854 wlan_vdev_mlme_get_mldaddr(vdev), 16855 &mld_addr); 16856 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) 16857 return qdf_ret_status; 16858 } 16859 wlan_vdev_mlme_set_mldaddr(vdev, mld_addr.bytes); 16860 } 16861 wlan_vdev_mlme_set_macaddr(vdev, mac_addr.bytes); 16862 wlan_vdev_mlme_set_linkaddr(vdev, mac_addr.bytes); 16863 16864 ucfg_vdev_mgr_cdp_vdev_attach(vdev); 16865 p2p_self_peer_create: 16866 if (vdev_opmode == QDF_P2P_DEVICE_MODE) { 16867 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 16868 if (!vdev_mlme) { 16869 sme_err("Invalid vdev MLME context"); 16870 return QDF_STATUS_E_INVAL; 16871 } 16872 16873 qdf_ret_status = wma_vdev_self_peer_create(vdev_mlme); 16874 if (QDF_IS_STATUS_ERROR(qdf_ret_status)) { 16875 sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d", 16876 qdf_ret_status); 16877 return QDF_STATUS_E_INVAL; 16878 } 16879 } 16880 return QDF_STATUS_SUCCESS; 16881 } 16882 #endif 16883 sme_send_start_bss_msg(struct mac_context * mac,struct start_bss_config * cfg)16884 static QDF_STATUS sme_send_start_bss_msg(struct mac_context *mac, 16885 struct start_bss_config *cfg) 16886 { 16887 struct scheduler_msg msg = {0}; 16888 struct start_bss_config *start_bss_cfg; 16889 struct start_bss_rsp rsp; 16890 16891 if (!cfg) 16892 return QDF_STATUS_E_FAILURE; 16893 16894 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, cfg->vdev_id); 16895 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_START_BSS_REQ, 16896 cfg->vdev_id); 16897 16898 start_bss_cfg = qdf_mem_malloc(sizeof(*start_bss_cfg)); 16899 if (!start_bss_cfg) 16900 return QDF_STATUS_E_NOMEM; 16901 16902 qdf_mem_copy(start_bss_cfg, cfg, sizeof(*start_bss_cfg)); 16903 msg.type = eWNI_SME_START_BSS_REQ; 16904 msg.bodyptr = start_bss_cfg; 16905 msg.reserved = 0; 16906 16907 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 16908 QDF_MODULE_ID_PE, 16909 QDF_MODULE_ID_PE, 16910 &msg)) 16911 goto failure; 16912 16913 return QDF_STATUS_SUCCESS; 16914 failure: 16915 sme_err("Failed to post start bss request to PE for vdev : %d", 16916 start_bss_cfg->vdev_id); 16917 csr_process_sap_response(mac, CSR_SAP_START_BSS_FAILURE, &rsp, 16918 start_bss_cfg->vdev_id); 16919 qdf_mem_free(start_bss_cfg); 16920 return QDF_STATUS_E_FAILURE; 16921 } 16922 sme_send_stop_bss_msg(struct mac_context * mac,struct stop_bss_req * cfg)16923 static QDF_STATUS sme_send_stop_bss_msg(struct mac_context *mac, 16924 struct stop_bss_req *cfg) 16925 { 16926 struct scheduler_msg msg = {0}; 16927 struct stop_bss_req *stop_bss_req; 16928 16929 csr_roam_state_change(mac, eCSR_ROAMING_STATE_JOINING, cfg->vdev_id); 16930 csr_roam_substate_change(mac, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, 16931 cfg->vdev_id); 16932 16933 sme_err("Stop bss request received for vdev : %d cmd_id : %d", 16934 cfg->vdev_id, cfg->cmd_id); 16935 16936 stop_bss_req = qdf_mem_malloc(sizeof(*stop_bss_req)); 16937 if (!stop_bss_req) 16938 return QDF_STATUS_E_NOMEM; 16939 16940 qdf_mem_copy(stop_bss_req, cfg, sizeof(*stop_bss_req)); 16941 16942 msg.type = eWNI_SME_STOP_BSS_REQ; 16943 msg.bodyptr = stop_bss_req; 16944 msg.reserved = 0; 16945 16946 if (QDF_STATUS_SUCCESS != scheduler_post_message(QDF_MODULE_ID_SME, 16947 QDF_MODULE_ID_PE, 16948 QDF_MODULE_ID_PE, 16949 &msg)) { 16950 sme_err("Failed to post stop bss request for vdev id : %d", 16951 cfg->vdev_id); 16952 qdf_mem_free(stop_bss_req); 16953 return QDF_STATUS_E_FAILURE; 16954 } 16955 return QDF_STATUS_SUCCESS; 16956 } 16957 sme_sap_activate_cmd(struct wlan_serialization_command * cmd)16958 static QDF_STATUS sme_sap_activate_cmd(struct wlan_serialization_command *cmd) 16959 { 16960 QDF_STATUS status = QDF_STATUS_SUCCESS; 16961 mac_handle_t mac_handle; 16962 struct mac_context *mac; 16963 16964 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 16965 mac = MAC_CONTEXT(mac_handle); 16966 if (!mac) { 16967 QDF_ASSERT(0); 16968 return QDF_STATUS_E_INVAL; 16969 } 16970 16971 switch (cmd->cmd_type) { 16972 case WLAN_SER_CMD_VDEV_START_BSS: 16973 status = sme_send_start_bss_msg(mac, cmd->umac_cmd); 16974 break; 16975 case WLAN_SER_CMD_VDEV_STOP_BSS: 16976 status = sme_send_stop_bss_msg(mac, cmd->umac_cmd); 16977 break; 16978 default: 16979 status = QDF_STATUS_E_FAILURE; 16980 break; 16981 } 16982 return status; 16983 } 16984 sme_sap_ser_callback(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)16985 QDF_STATUS sme_sap_ser_callback(struct wlan_serialization_command *cmd, 16986 enum wlan_serialization_cb_reason reason) 16987 { 16988 QDF_STATUS status = QDF_STATUS_SUCCESS; 16989 mac_handle_t mac_handle; 16990 struct mac_context *mac_ctx; 16991 16992 if (!cmd) { 16993 sme_err("Invalid Serialization command"); 16994 return QDF_STATUS_E_FAILURE; 16995 } 16996 16997 mac_handle = cds_get_context(QDF_MODULE_ID_SME); 16998 if (mac_handle) 16999 mac_ctx = MAC_CONTEXT(mac_handle); 17000 else 17001 return QDF_STATUS_E_FAILURE; 17002 17003 switch (reason) { 17004 case WLAN_SER_CB_ACTIVATE_CMD: 17005 status = sme_sap_activate_cmd(cmd); 17006 break; 17007 case WLAN_SER_CB_CANCEL_CMD: 17008 break; 17009 case WLAN_SER_CB_RELEASE_MEM_CMD: 17010 if (cmd->vdev) 17011 wlan_objmgr_vdev_release_ref(cmd->vdev, 17012 WLAN_LEGACY_MAC_ID); 17013 if (cmd->umac_cmd) 17014 qdf_mem_free(cmd->umac_cmd); 17015 break; 17016 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 17017 qdf_trigger_self_recovery(mac_ctx->psoc, 17018 QDF_ACTIVE_LIST_TIMEOUT); 17019 break; 17020 default: 17021 sme_debug("unknown reason code"); 17022 return QDF_STATUS_E_FAILURE; 17023 } 17024 return status; 17025 } 17026 sme_fill_channel_change_request(mac_handle_t mac_handle,struct channel_change_req * req,eCsrPhyMode phy_mode)17027 void sme_fill_channel_change_request(mac_handle_t mac_handle, 17028 struct channel_change_req *req, 17029 eCsrPhyMode phy_mode) 17030 { 17031 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); 17032 struct bss_dot11_config dot11_cfg = {0}; 17033 17034 dot11_cfg.vdev_id = req->vdev_id; 17035 dot11_cfg.bss_op_ch_freq = req->target_chan_freq; 17036 dot11_cfg.phy_mode = phy_mode; 17037 17038 sme_get_network_params(mac_ctx, &dot11_cfg); 17039 17040 req->dot11mode = dot11_cfg.dot11_mode; 17041 req->nw_type = dot11_cfg.nw_type; 17042 17043 if (dot11_cfg.opr_rates.numRates) { 17044 qdf_mem_copy(req->opr_rates.rate, 17045 dot11_cfg.opr_rates.rate, 17046 dot11_cfg.opr_rates.numRates); 17047 req->opr_rates.numRates = 17048 dot11_cfg.opr_rates.numRates; 17049 } 17050 17051 if (dot11_cfg.ext_rates.numRates) { 17052 qdf_mem_copy(req->ext_rates.rate, 17053 dot11_cfg.ext_rates.rate, 17054 dot11_cfg.ext_rates.numRates); 17055 req->ext_rates.numRates = 17056 dot11_cfg.ext_rates.numRates; 17057 } 17058 } 17059 sme_update_beacon_country_ie(mac_handle_t mac_handle,uint8_t vdev_id,bool country_ie_for_all_band)17060 QDF_STATUS sme_update_beacon_country_ie(mac_handle_t mac_handle, 17061 uint8_t vdev_id, 17062 bool country_ie_for_all_band) 17063 { 17064 struct mac_context *mac = MAC_CONTEXT(mac_handle); 17065 struct wlan_objmgr_vdev *vdev; 17066 struct mlme_legacy_priv *mlme_priv; 17067 17068 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, 17069 WLAN_MLME_NB_ID); 17070 if (!vdev) { 17071 sme_err("vdev object is NULL for vdev_id %d", vdev_id); 17072 return QDF_STATUS_E_FAILURE; 17073 } 17074 17075 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); 17076 if (!mlme_priv) { 17077 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 17078 return QDF_STATUS_E_FAILURE; 17079 } 17080 17081 mlme_priv->country_ie_for_all_band = country_ie_for_all_band; 17082 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); 17083 17084 csr_update_beacon(mac); 17085 17086 return QDF_STATUS_SUCCESS; 17087 } 17088 17089 QDF_STATUS sme_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type,uint8_t dev_id,struct dev_set_param * param,uint8_t max_index)17090 sme_send_multi_pdev_vdev_set_params(enum mlme_dev_setparam param_type, 17091 uint8_t dev_id, 17092 struct dev_set_param *param, 17093 uint8_t max_index) 17094 { 17095 return wma_send_multi_pdev_vdev_set_params(param_type, dev_id, param, 17096 max_index); 17097 } 17098 17099 QDF_STATUS sme_validate_txrx_chain_mask(uint32_t id,uint32_t value)17100 sme_validate_txrx_chain_mask(uint32_t id, uint32_t value) 17101 { 17102 return wma_validate_txrx_chain_mask(id, value); 17103 } 17104