| /* |
| * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /**========================================================================= |
| |
| \file smeApi.c |
| |
| \brief Definitions for SME APIs |
| |
| ========================================================================*/ |
| |
| /*-------------------------------------------------------------------------- |
| Include Files |
| ------------------------------------------------------------------------*/ |
| |
| #include "sms_debug.h" |
| #include "sme_api.h" |
| #include "csr_inside_api.h" |
| #include "sme_inside.h" |
| #include "csr_internal.h" |
| #include "wma_types.h" |
| #include "wma_if.h" |
| #include "qdf_trace.h" |
| #include "sme_trace.h" |
| #include "qdf_types.h" |
| #include "qdf_trace.h" |
| #include "cds_utils.h" |
| #include "sap_api.h" |
| #include "mac_trace.h" |
| #ifdef WLAN_FEATURE_NAN |
| #include "nan_api.h" |
| #endif |
| #include "cds_regdomain.h" |
| #include "cfg_api.h" |
| #include "sme_power_save_api.h" |
| #include "wma.h" |
| #include "sch_api.h" |
| #include "sme_nan_datapath.h" |
| |
| extern tSirRetStatus u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb); |
| |
| #define LOG_SIZE 256 |
| |
| static tSelfRecoveryStats g_self_recovery_stats; |
| /* TxMB Functions */ |
| extern QDF_STATUS pmc_prepare_command(tpAniSirGlobal pMac, uint32_t sessionId, |
| eSmeCommandType cmdType, void *pvParam, |
| uint32_t size, tSmeCmd **ppCmd); |
| extern void pmc_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand); |
| extern void qos_release_command(tpAniSirGlobal pMac, tSmeCmd *pCommand); |
| extern QDF_STATUS p2p_process_remain_on_channel_cmd(tpAniSirGlobal pMac, |
| tSmeCmd *p2pRemainonChn); |
| extern QDF_STATUS sme_remain_on_chn_rsp(tpAniSirGlobal pMac, uint8_t *pMsg); |
| extern QDF_STATUS sme_remain_on_chn_ready(tHalHandle hHal, uint8_t *pMsg); |
| |
| static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac); |
| static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand, |
| bool fStopping); |
| |
| eCsrPhyMode sme_get_phy_mode(tHalHandle hHal); |
| |
| QDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf); |
| |
| void sme_disconnect_connected_sessions(tpAniSirGlobal pMac); |
| |
| QDF_STATUS sme_handle_generic_change_country_code(tpAniSirGlobal pMac, |
| void *pMsgBuf); |
| |
| QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg); |
| |
| #ifdef FEATURE_WLAN_ESE |
| bool csr_is_supported_channel(tpAniSirGlobal pMac, uint8_t channelId); |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| QDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal, |
| tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm); |
| #endif |
| |
| /* Message processor for events from DFS */ |
| QDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac, |
| uint16_t msg_type, void *pMsgBuf); |
| |
| /* Channel Change Response Indication Handler */ |
| QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac, |
| uint16_t msg_type, void *pMsgBuf); |
| |
| /* Internal SME APIs */ |
| QDF_STATUS sme_acquire_global_lock(tSmeStruct *psSme) |
| { |
| QDF_STATUS status = QDF_STATUS_E_INVAL; |
| |
| if (psSme) { |
| if (QDF_IS_STATUS_SUCCESS |
| (qdf_mutex_acquire(&psSme->lkSmeGlobalLock))) { |
| status = QDF_STATUS_SUCCESS; |
| } |
| } |
| |
| return status; |
| } |
| |
| QDF_STATUS sme_release_global_lock(tSmeStruct *psSme) |
| { |
| QDF_STATUS status = QDF_STATUS_E_INVAL; |
| |
| if (psSme) { |
| if (QDF_IS_STATUS_SUCCESS |
| (qdf_mutex_release(&psSme->lkSmeGlobalLock))) { |
| status = QDF_STATUS_SUCCESS; |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_process_set_hw_mode_resp() - Process set HW mode response |
| * @mac: Global MAC pointer |
| * @msg: HW mode response |
| * |
| * Processes the HW mode response and invokes the HDD callback |
| * to process further |
| */ |
| static QDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg) |
| { |
| tListElem *entry = NULL; |
| tSmeCmd *command = NULL; |
| bool found; |
| hw_mode_cb callback = NULL; |
| struct sir_set_hw_mode_resp *param; |
| enum sir_conn_update_reason reason; |
| tSmeCmd *saved_cmd; |
| |
| sms_log(mac, LOG1, FL("%s"), __func__); |
| param = (struct sir_set_hw_mode_resp *)msg; |
| if (!param) { |
| sms_log(mac, LOGE, FL("HW mode resp param is NULL")); |
| /* Not returning. Need to check if active command list |
| * needs to be freed |
| */ |
| } |
| |
| entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (!entry) { |
| sms_log(mac, LOGE, FL("No cmd found in active list")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| command = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| if (!command) { |
| sms_log(mac, LOGE, FL("Base address is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (e_sme_command_set_hw_mode != command->command) { |
| sms_log(mac, LOGE, FL("Command mismatch!")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| callback = command->u.set_hw_mode_cmd.set_hw_mode_cb; |
| reason = command->u.set_hw_mode_cmd.reason; |
| |
| sms_log(mac, LOG1, FL("reason:%d session:%d"), |
| command->u.set_hw_mode_cmd.reason, |
| command->u.set_hw_mode_cmd.session_id); |
| |
| if (!callback) { |
| sms_log(mac, LOGE, FL("Callback does not exist")); |
| goto end; |
| } |
| |
| if (!param) { |
| sms_log(mac, LOGE, |
| FL("Callback failed since HW mode params is NULL")); |
| goto end; |
| } |
| |
| /* Irrespective of the reason for which the hw mode change request |
| * was issued, the policy manager connection table needs to be updated |
| * with the new vdev-mac id mapping, tx/rx spatial streams etc., if the |
| * set hw mode was successful. |
| */ |
| callback(param->status, |
| param->cfgd_hw_mode_index, |
| param->num_vdev_mac_entries, |
| param->vdev_mac_map); |
| |
| if (reason == SIR_UPDATE_REASON_HIDDEN_STA) { |
| /* In the case of hidden SSID, connection update |
| * (set hw mode) is done after the scan with reason |
| * code eCsrScanForSsid completes. The connect/failure |
| * needs to be handled after the response of set hw |
| * mode |
| */ |
| saved_cmd = (tSmeCmd *)mac->sme.saved_scan_cmd; |
| if (!saved_cmd) { |
| sms_log(mac, LOGP, |
| FL("saved cmd is NULL, Check this")); |
| goto end; |
| } |
| if (param->status == SET_HW_MODE_STATUS_OK) { |
| sms_log(mac, LOG1, |
| FL("search for ssid success")); |
| csr_scan_handle_search_for_ssid(mac, |
| saved_cmd); |
| } else { |
| sms_log(mac, LOG1, |
| FL("search for ssid failure")); |
| csr_scan_handle_search_for_ssid_failure(mac, |
| saved_cmd); |
| } |
| if (saved_cmd->u.roamCmd.pRoamBssEntry) |
| qdf_mem_free( |
| saved_cmd->u.roamCmd.pRoamBssEntry); |
| if (saved_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList) |
| qdf_mem_free(saved_cmd->u.scanCmd.u. |
| scanRequest.SSIDs.SSIDList); |
| if (saved_cmd->u.scanCmd.pToRoamProfile) |
| qdf_mem_free(saved_cmd->u.scanCmd. |
| pToRoamProfile); |
| if (saved_cmd) { |
| qdf_mem_free(saved_cmd); |
| saved_cmd = NULL; |
| mac->sme.saved_scan_cmd = NULL; |
| } |
| } |
| |
| end: |
| found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry, |
| LL_ACCESS_LOCK); |
| if (found) { |
| /* Now put this command back on the avilable command list */ |
| sme_release_command(mac, command); |
| } |
| sme_process_pending_queue(mac); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_process_hw_mode_trans_ind() - Process HW mode transition indication |
| * @mac: Global MAC pointer |
| * @msg: HW mode transition response |
| * |
| * Processes the HW mode transition indication and invoke the HDD callback |
| * to process further |
| */ |
| static QDF_STATUS sme_process_hw_mode_trans_ind(tpAniSirGlobal mac, |
| uint8_t *msg) |
| { |
| hw_mode_transition_cb callback = NULL; |
| struct sir_hw_mode_trans_ind *param; |
| |
| param = (struct sir_hw_mode_trans_ind *)msg; |
| if (!param) { |
| sms_log(mac, LOGE, FL("HW mode trans ind param is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| callback = mac->sme.sme_hw_mode_trans_cb; |
| if (callback) { |
| sms_log(mac, LOGE, FL("Calling registered callback...")); |
| callback(param->old_hw_mode_index, |
| param->new_hw_mode_index, |
| param->num_vdev_mac_entries, |
| param->vdev_mac_map); |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * free_sme_cmds() - This function frees memory allocated for SME commands |
| * @mac_ctx: Pointer to Global MAC structure |
| * |
| * This function frees memory allocated for SME commands |
| * |
| * @Return: void |
| */ |
| static void free_sme_cmds(tpAniSirGlobal mac_ctx) |
| { |
| uint32_t idx; |
| if (NULL == mac_ctx->sme.pSmeCmdBufAddr) |
| return; |
| |
| for (idx = 0; idx < mac_ctx->sme.totalSmeCmd; idx++) |
| qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr[idx]); |
| |
| qdf_mem_free(mac_ctx->sme.pSmeCmdBufAddr); |
| mac_ctx->sme.pSmeCmdBufAddr = NULL; |
| } |
| |
| static QDF_STATUS init_sme_cmd_list(tpAniSirGlobal pMac) |
| { |
| QDF_STATUS status; |
| tSmeCmd *pCmd; |
| uint32_t cmd_idx; |
| QDF_STATUS qdf_status; |
| qdf_mc_timer_t *cmdTimeoutTimer = NULL; |
| uint32_t sme_cmd_ptr_ary_sz; |
| |
| pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND; |
| |
| status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdActiveList); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| goto end; |
| |
| status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdPendingList); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| goto end; |
| |
| status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdActiveList); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| goto end; |
| |
| status = csr_ll_open(pMac->hHdd, &pMac->sme.smeScanCmdPendingList); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| goto end; |
| |
| status = csr_ll_open(pMac->hHdd, &pMac->sme.smeCmdFreeList); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| goto end; |
| |
| /* following pointer contains array of pointers for tSmeCmd* */ |
| sme_cmd_ptr_ary_sz = sizeof(void *) * pMac->sme.totalSmeCmd; |
| pMac->sme.pSmeCmdBufAddr = qdf_mem_malloc(sme_cmd_ptr_ary_sz); |
| if (NULL == pMac->sme.pSmeCmdBufAddr) { |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| |
| status = QDF_STATUS_SUCCESS; |
| qdf_mem_set(pMac->sme.pSmeCmdBufAddr, sme_cmd_ptr_ary_sz, 0); |
| for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) { |
| /* |
| * Since total size of all commands together can be huge chunk |
| * of memory, allocate SME cmd individually. These SME CMDs are |
| * moved between pending and active queues. And these freeing of |
| * these queues just manipulates the list but does not actually |
| * frees SME CMD pointers. Hence store each SME CMD address in |
| * the array, sme.pSmeCmdBufAddr. This will later facilitate |
| * freeing up of all SME CMDs with just a for loop. |
| */ |
| pMac->sme.pSmeCmdBufAddr[cmd_idx] = |
| qdf_mem_malloc(sizeof(tSmeCmd)); |
| if (NULL == pMac->sme.pSmeCmdBufAddr[cmd_idx]) { |
| status = QDF_STATUS_E_NOMEM; |
| free_sme_cmds(pMac); |
| goto end; |
| } |
| pCmd = (tSmeCmd *)pMac->sme.pSmeCmdBufAddr[cmd_idx]; |
| csr_ll_insert_tail(&pMac->sme.smeCmdFreeList, |
| &pCmd->Link, LL_ACCESS_LOCK); |
| } |
| |
| /* This timer is only to debug the active list command timeout */ |
| |
| cmdTimeoutTimer = |
| (qdf_mc_timer_t *) qdf_mem_malloc(sizeof(qdf_mc_timer_t)); |
| if (cmdTimeoutTimer) { |
| pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer; |
| qdf_status = |
| qdf_mc_timer_init(pMac->sme.smeCmdActiveList. |
| cmdTimeoutTimer, QDF_TIMER_TYPE_SW, |
| active_list_cmd_timeout_handle, (void *)pMac); |
| |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Init Timer fail for active list command process time out"); |
| qdf_mem_free(pMac->sme.smeCmdActiveList. |
| cmdTimeoutTimer); |
| pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL; |
| } else { |
| pMac->sme.smeCmdActiveList.cmdTimeoutDuration = |
| CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; |
| } |
| } |
| |
| end: |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| sms_log(pMac, LOGE, "failed to initialize sme command list:%d\n", |
| status); |
| |
| return status; |
| } |
| |
| void sme_release_command(tpAniSirGlobal pMac, tSmeCmd *pCmd) |
| { |
| pCmd->command = eSmeNoCommand; |
| csr_ll_insert_tail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK); |
| } |
| |
| static void sme_release_cmd_list(tpAniSirGlobal pMac, tDblLinkList *pList) |
| { |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| |
| while ((pEntry = csr_ll_remove_head(pList, LL_ACCESS_LOCK)) != NULL) { |
| /* TODO: base on command type to call release functions */ |
| /* reinitialize different command types so they can be reused */ |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| sme_abort_command(pMac, pCommand, true); |
| } |
| } |
| |
| static void purge_sme_cmd_list(tpAniSirGlobal pMac) |
| { |
| /* release any out standing commands back to free command list */ |
| sme_release_cmd_list(pMac, &pMac->sme.smeCmdPendingList); |
| sme_release_cmd_list(pMac, &pMac->sme.smeCmdActiveList); |
| sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdPendingList); |
| sme_release_cmd_list(pMac, &pMac->sme.smeScanCmdActiveList); |
| } |
| |
| void purge_sme_session_cmd_list(tpAniSirGlobal pMac, uint32_t sessionId, |
| tDblLinkList *pList) |
| { |
| /* release any out standing commands back to free command list */ |
| tListElem *pEntry, *pNext; |
| tSmeCmd *pCommand; |
| tDblLinkList localList; |
| |
| qdf_mem_zero(&localList, sizeof(tDblLinkList)); |
| if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) { |
| sms_log(pMac, LOGE, FL(" failed to open list")); |
| return; |
| } |
| |
| csr_ll_lock(pList); |
| pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK); |
| while (pEntry != NULL) { |
| pNext = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK); |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| if (pCommand->sessionId == sessionId) { |
| if (csr_ll_remove_entry(pList, pEntry, LL_ACCESS_NOLOCK)) { |
| csr_ll_insert_tail(&localList, pEntry, |
| LL_ACCESS_NOLOCK); |
| } |
| } |
| pEntry = pNext; |
| } |
| csr_ll_unlock(pList); |
| |
| while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) { |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| sme_abort_command(pMac, pCommand, true); |
| } |
| csr_ll_close(&localList); |
| } |
| |
| static QDF_STATUS free_sme_cmd_list(tpAniSirGlobal pMac) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| purge_sme_cmd_list(pMac); |
| csr_ll_close(&pMac->sme.smeCmdPendingList); |
| csr_ll_close(&pMac->sme.smeCmdActiveList); |
| csr_ll_close(&pMac->sme.smeScanCmdPendingList); |
| csr_ll_close(&pMac->sme.smeScanCmdActiveList); |
| csr_ll_close(&pMac->sme.smeCmdFreeList); |
| |
| /*destroy active list command time out timer */ |
| qdf_mc_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); |
| qdf_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); |
| pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL; |
| |
| status = qdf_mutex_acquire(&pMac->sme.lkSmeGlobalLock); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(pMac, LOGE, |
| FL("Failed to acquire the lock status = %d"), status); |
| goto done; |
| } |
| |
| free_sme_cmds(pMac); |
| |
| status = qdf_mutex_release(&pMac->sme.lkSmeGlobalLock); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(pMac, LOGE, |
| FL("Failed to release the lock status = %d"), status); |
| } |
| done: |
| return status; |
| } |
| |
| void dump_csr_command_info(tpAniSirGlobal pMac, tSmeCmd *pCmd) |
| { |
| switch (pCmd->command) { |
| case eSmeCommandScan: |
| sms_log(pMac, LOGE, " scan command reason is %d", |
| pCmd->u.scanCmd.reason); |
| break; |
| |
| case eSmeCommandRoam: |
| sms_log(pMac, LOGE, " roam command reason is %d", |
| pCmd->u.roamCmd.roamReason); |
| break; |
| |
| case eSmeCommandWmStatusChange: |
| sms_log(pMac, LOGE, " WMStatusChange command type is %d", |
| pCmd->u.wmStatusChangeCmd.Type); |
| break; |
| |
| case eSmeCommandSetKey: |
| sms_log(pMac, LOGE, " setKey command auth(%d) enc(%d)", |
| pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType); |
| break; |
| |
| default: |
| sms_log(pMac, LOGE, " default: Unhandled command %d", |
| pCmd->command); |
| break; |
| } |
| } |
| |
| tSmeCmd *sme_get_command_buffer(tpAniSirGlobal pMac) |
| { |
| tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL; |
| tListElem *pEntry; |
| static int sme_command_queue_full; |
| |
| pEntry = csr_ll_remove_head(&pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK); |
| |
| /* If we can get another MS Msg buffer, then we are ok. Just link */ |
| /* the entry onto the linked list. (We are using the linked list */ |
| /* to keep track of tfhe message buffers). */ |
| if (pEntry) { |
| pRetCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| /* reset when free list is available */ |
| sme_command_queue_full = 0; |
| } else { |
| int idx = 1; |
| |
| /* Cannot change pRetCmd here since it needs to return later. */ |
| pEntry = |
| csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); |
| if (pEntry) { |
| pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| } |
| sms_log(pMac, LOGE, |
| "Out of command buffer.... command (0x%X) stuck", |
| (pTempCmd) ? pTempCmd->command : eSmeNoCommand); |
| if (pTempCmd) { |
| if (eSmeCsrCommandMask & pTempCmd->command) { |
| /* CSR command is stuck. See what the reason code is for that command */ |
| dump_csr_command_info(pMac, pTempCmd); |
| } |
| } /* if(pTempCmd) */ |
| |
| /* dump what is in the pending queue */ |
| csr_ll_lock(&pMac->sme.smeCmdPendingList); |
| pEntry = |
| csr_ll_peek_head(&pMac->sme.smeCmdPendingList, |
| LL_ACCESS_NOLOCK); |
| while (pEntry && !sme_command_queue_full) { |
| pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| /* Print only 1st five commands from pending queue. */ |
| if (idx <= 5) |
| sms_log(pMac, LOGE, |
| "Out of command buffer.... SME pending command #%d (0x%X)", |
| idx, pTempCmd->command); |
| idx++; |
| if (eSmeCsrCommandMask & pTempCmd->command) { |
| /* CSR command is stuck. See what the reason code is for that command */ |
| dump_csr_command_info(pMac, pTempCmd); |
| } |
| pEntry = |
| csr_ll_next(&pMac->sme.smeCmdPendingList, pEntry, |
| LL_ACCESS_NOLOCK); |
| } |
| csr_ll_unlock(&pMac->sme.smeCmdPendingList); |
| |
| idx = 1; |
| /* There may be some more command in CSR's own pending queue */ |
| csr_ll_lock(&pMac->roam.roamCmdPendingList); |
| pEntry = |
| csr_ll_peek_head(&pMac->roam.roamCmdPendingList, |
| LL_ACCESS_NOLOCK); |
| while (pEntry && !sme_command_queue_full) { |
| pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| /* Print only 1st five commands from CSR pending queue */ |
| if (idx <= 5) |
| sms_log(pMac, LOGE, |
| "Out of command buffer.... " |
| "CSR roamCmdPendingList command #%d (0x%X)", |
| idx, pTempCmd->command); |
| idx++; |
| dump_csr_command_info(pMac, pTempCmd); |
| pEntry = |
| csr_ll_next(&pMac->roam.roamCmdPendingList, pEntry, |
| LL_ACCESS_NOLOCK); |
| } |
| |
| /* Increment static variable so that it prints |
| * pending command only once |
| */ |
| sme_command_queue_full++; |
| csr_ll_unlock(&pMac->roam.roamCmdPendingList); |
| |
| if (pMac->roam.configParam.enable_fatal_event) |
| cds_flush_logs(WLAN_LOG_TYPE_FATAL, |
| WLAN_LOG_INDICATOR_HOST_DRIVER, |
| WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, |
| false, |
| pMac->sme.enableSelfRecovery ? true : false); |
| else if (pMac->sme.enableSelfRecovery) |
| cds_trigger_recovery(); |
| else |
| QDF_BUG(0); |
| } |
| |
| /* memset to zero */ |
| if (pRetCmd) { |
| qdf_mem_set((uint8_t *)&pRetCmd->command, |
| sizeof(pRetCmd->command), 0); |
| qdf_mem_set((uint8_t *)&pRetCmd->sessionId, |
| sizeof(pRetCmd->sessionId), 0); |
| qdf_mem_set((uint8_t *)&pRetCmd->u, sizeof(pRetCmd->u), 0); |
| } |
| |
| return pRetCmd; |
| } |
| |
| void sme_push_command(tpAniSirGlobal pMac, tSmeCmd *pCmd, bool fHighPriority) |
| { |
| if (!SME_IS_START(pMac)) { |
| sms_log(pMac, LOGE, FL("Sme in stop state")); |
| QDF_ASSERT(0); |
| return; |
| } |
| |
| if (fHighPriority) { |
| csr_ll_insert_head(&pMac->sme.smeCmdPendingList, &pCmd->Link, |
| LL_ACCESS_LOCK); |
| } else { |
| csr_ll_insert_tail(&pMac->sme.smeCmdPendingList, &pCmd->Link, |
| LL_ACCESS_LOCK); |
| } |
| |
| /* process the command queue... */ |
| sme_process_pending_queue(pMac); |
| |
| return; |
| } |
| |
| /* For commands that need to do extra cleanup. */ |
| static void sme_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand, |
| bool fStopping) |
| { |
| if (eSmePmcCommandMask & pCommand->command) { |
| sms_log(pMac, LOG1, |
| "No need to process PMC commands"); |
| return; |
| } |
| if (eSmeCsrCommandMask & pCommand->command) { |
| csr_abort_command(pMac, pCommand, fStopping); |
| return; |
| } |
| switch (pCommand->command) { |
| case eSmeCommandRemainOnChannel: |
| if (NULL != pCommand->u.remainChlCmd.callback) { |
| remainOnChanCallback callback = |
| pCommand->u.remainChlCmd.callback; |
| /* process the msg */ |
| if (callback) { |
| callback(pMac, pCommand->u.remainChlCmd. |
| callbackCtx, eCSR_SCAN_ABORT, |
| pCommand->u.remainChlCmd.scan_id); |
| } |
| } |
| sme_release_command(pMac, pCommand); |
| break; |
| default: |
| sme_release_command(pMac, pCommand); |
| break; |
| } |
| |
| } |
| |
| tListElem *csr_get_cmd_to_process(tpAniSirGlobal pMac, tDblLinkList *pList, |
| uint8_t sessionId, bool fInterlocked) |
| { |
| tListElem *pCurEntry = NULL; |
| tSmeCmd *pCommand; |
| |
| /* Go through the list and return the command whose session id is not |
| * matching with the current ongoing scan cmd sessionId */ |
| pCurEntry = csr_ll_peek_head(pList, LL_ACCESS_LOCK); |
| while (pCurEntry) { |
| pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link); |
| if (pCommand->sessionId != sessionId) { |
| sms_log(pMac, LOG1, |
| "selected the command with different sessionId"); |
| return pCurEntry; |
| } |
| |
| pCurEntry = csr_ll_next(pList, pCurEntry, fInterlocked); |
| } |
| |
| sms_log(pMac, LOG1, "No command pending with different sessionId"); |
| return NULL; |
| } |
| |
| bool sme_process_scan_queue(tpAniSirGlobal pMac) |
| { |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| tListElem *pSmeEntry = NULL; |
| tSmeCmd *pSmeCommand = NULL; |
| bool status = true; |
| |
| if ((!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK))) { |
| pSmeEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (pSmeEntry) |
| pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link); |
| } |
| csr_ll_lock(&pMac->sme.smeScanCmdActiveList); |
| if (csr_ll_is_list_empty(&pMac->sme.smeScanCmdPendingList, |
| LL_ACCESS_LOCK)) |
| goto end; |
| pEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdPendingList, |
| LL_ACCESS_LOCK); |
| if (!pEntry) |
| goto end; |
| |
| sms_log(pMac, LOGE, |
| FL("scan_count in active scanlist %d "), |
| pMac->sme.smeScanCmdActiveList.Count); |
| |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| if (pSmeCommand != NULL) { |
| /* |
| * if scan is running on one interface and SME receives |
| * the next command on the same interface then |
| * dont the allow the command to be queued to |
| * smeCmdPendingList. If next scan is allowed on |
| * the same interface the CSR state machine will |
| * get screwed up. |
| */ |
| if (pSmeCommand->sessionId == pCommand->sessionId) { |
| status = false; |
| goto end; |
| } |
| } |
| /* |
| * We cannot execute any command in wait-for-key state until setKey is |
| * through. |
| */ |
| if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId)) { |
| if (!CSR_IS_SET_KEY_COMMAND(pCommand)) { |
| sms_log(pMac, LOGE, |
| FL("Can't process cmd(%d), waiting for key"), |
| pCommand->command); |
| status = false; |
| goto end; |
| } |
| } |
| if (csr_ll_remove_entry(&pMac->sme.smeScanCmdPendingList, pEntry, |
| LL_ACCESS_LOCK)) { |
| csr_ll_insert_head(&pMac->sme.smeScanCmdActiveList, |
| &pCommand->Link, LL_ACCESS_NOLOCK); |
| switch (pCommand->command) { |
| case eSmeCommandScan: |
| sms_log(pMac, LOG1, FL("Processing scan offload cmd.")); |
| qdf_mc_timer_start(&pCommand->u.scanCmd.csr_scan_timer, |
| CSR_ACTIVE_SCAN_LIST_CMD_TIMEOUT); |
| csr_process_scan_command(pMac, pCommand); |
| break; |
| case eSmeCommandRemainOnChannel: |
| sms_log(pMac, LOG1, |
| FL("Processing remain on channel offload cmd")); |
| p2p_process_remain_on_channel_cmd(pMac, pCommand); |
| break; |
| default: |
| sms_log(pMac, LOGE, |
| FL("Wrong cmd enqueued to ScanCmdPendingList")); |
| pEntry = csr_ll_remove_head( |
| &pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_NOLOCK); |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| sme_release_command(pMac, pCommand); |
| break; |
| } |
| } |
| end: |
| csr_ll_unlock(&pMac->sme.smeScanCmdActiveList); |
| return status; |
| } |
| |
| /** |
| * sme_process_command() - processes SME commnd |
| * @mac_ctx: mac global context |
| * |
| * This function is called by sme_process_pending_queue() in a while loop |
| * |
| * Return: true indicates that caller function can proceed to next cmd |
| * false otherwise. |
| */ |
| bool sme_process_command(tpAniSirGlobal pMac) |
| { |
| bool fContinue = false; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| tListElem *pSmeEntry; |
| tSmeCmd *pSmeCommand; |
| |
| /* |
| * if the ActiveList is empty, then nothing is active so we can process |
| * a pending command... |
| * alwasy lock active list before locking pending list |
| */ |
| csr_ll_lock(&pMac->sme.smeCmdActiveList); |
| if (!csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, |
| LL_ACCESS_NOLOCK)) { |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| goto process_scan_q; |
| } |
| |
| if (csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList, |
| LL_ACCESS_LOCK)) { |
| /* No command waiting */ |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| goto process_scan_q; |
| } |
| |
| /* |
| * If scan command is pending in the smeScanCmdActive list then pick the |
| * command from smeCmdPendingList which is not matching with the scan |
| * command session id. At any point of time only one command will be |
| * allowed on a single session. |
| */ |
| if (!csr_ll_is_list_empty( |
| &pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK)) { |
| pSmeEntry = csr_ll_peek_head(&pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (pSmeEntry) { |
| pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link); |
| pEntry = csr_get_cmd_to_process(pMac, |
| &pMac->sme.smeCmdPendingList, |
| pSmeCommand->sessionId, |
| LL_ACCESS_LOCK); |
| goto sme_process_cmd; |
| } |
| } |
| |
| /* Peek the command */ |
| pEntry = csr_ll_peek_head(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK); |
| sme_process_cmd: |
| if (!pEntry) { |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| goto process_scan_q; |
| } |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| /* |
| * Allow only disconnect command in wait-for-key state until setKey is |
| * through. |
| */ |
| if (CSR_IS_WAIT_FOR_KEY(pMac, pCommand->sessionId) |
| && !CSR_IS_DISCONNECT_COMMAND(pCommand) |
| && !CSR_IS_SET_KEY_COMMAND(pCommand)) { |
| if (CSR_IS_CLOSE_SESSION_COMMAND(pCommand)) { |
| tSmeCmd *sme_cmd = NULL; |
| |
| sms_log(pMac, LOGE, |
| FL("SessionId %d: close session command issued while waiting for key, issue disconnect first"), |
| pCommand->sessionId); |
| status = csr_prepare_disconnect_command(pMac, |
| pCommand->sessionId, &sme_cmd); |
| if (status == QDF_STATUS_SUCCESS && sme_cmd) { |
| csr_ll_lock(&pMac->sme.smeCmdPendingList); |
| csr_ll_insert_head(&pMac->sme.smeCmdPendingList, |
| &sme_cmd->Link, LL_ACCESS_NOLOCK); |
| pEntry = csr_ll_peek_head( |
| &pMac->sme.smeCmdPendingList, |
| LL_ACCESS_NOLOCK); |
| csr_ll_unlock(&pMac->sme.smeCmdPendingList); |
| goto sme_process_cmd; |
| } |
| } |
| |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| sms_log(pMac, LOGE, |
| FL("SessionId %d: Can't process cmd(%d), waiting for key"), |
| pCommand->sessionId, pCommand->command); |
| fContinue = false; |
| goto process_scan_q; |
| } |
| |
| if (!csr_ll_remove_entry(&pMac->sme.smeCmdPendingList, pEntry, |
| LL_ACCESS_LOCK)) { |
| /* This is odd. Some one else pull off the command. */ |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| goto process_scan_q; |
| } |
| /* we can reuse the pCommand. Insert the command onto the ActiveList */ |
| csr_ll_insert_head(&pMac->sme.smeCmdActiveList, &pCommand->Link, |
| LL_ACCESS_NOLOCK); |
| /* .... and process the command. */ |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_COMMAND, |
| pCommand->sessionId, pCommand->command)); |
| |
| switch (pCommand->command) { |
| case eSmeCommandScan: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_process_scan_command(pMac, pCommand); |
| break; |
| case eSmeCommandRoam: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_roam_process_command(pMac, pCommand); |
| if (!QDF_IS_STATUS_SUCCESS(status) |
| && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csr_release_command_roam(pMac, pCommand); |
| break; |
| case eSmeCommandWmStatusChange: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_roam_process_wm_status_change_command(pMac, pCommand); |
| break; |
| case eSmeCommandSetKey: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_roam_process_set_key_command(pMac, pCommand); |
| if (!QDF_IS_STATUS_SUCCESS(status) |
| && csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) { |
| csr_release_command_set_key(pMac, pCommand); |
| } |
| break; |
| case eSmeCommandAddStaSession: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_add_sta_session_command(pMac, pCommand); |
| break; |
| case eSmeCommandNdpInitiatorRequest: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| if (csr_process_ndp_initiator_request(pMac, pCommand) != |
| QDF_STATUS_SUCCESS) |
| if (csr_ll_remove_entry( |
| &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csr_release_command(pMac, pCommand); |
| break; |
| case eSmeCommandNdpResponderRequest: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_process_ndp_responder_request(pMac, pCommand); |
| if (status != QDF_STATUS_SUCCESS) { |
| if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csr_release_command(pMac, pCommand); |
| } |
| break; |
| case eSmeCommandNdpDataEndInitiatorRequest: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_process_ndp_data_end_request(pMac, pCommand); |
| if (status != QDF_STATUS_SUCCESS) { |
| if (csr_ll_remove_entry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csr_release_command(pMac, pCommand); |
| } |
| break; |
| case eSmeCommandDelStaSession: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_del_sta_session_command(pMac, pCommand); |
| break; |
| case eSmeCommandRemainOnChannel: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| p2p_process_remain_on_channel_cmd(pMac, pCommand); |
| break; |
| /* |
| * Treat standby differently here because caller may not be able |
| * to handle the failure so we do our best here |
| */ |
| case eSmeCommandEnterStandby: |
| break; |
| case eSmeCommandAddTs: |
| case eSmeCommandDelTs: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| fContinue = qos_process_command(pMac, pCommand); |
| if (fContinue && csr_ll_remove_entry( |
| &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_NOLOCK)) { |
| /* The command failed, remove it */ |
| qos_release_command(pMac, pCommand); |
| } |
| #endif |
| break; |
| #ifdef FEATURE_WLAN_TDLS |
| case eSmeCommandTdlsSendMgmt: |
| case eSmeCommandTdlsAddPeer: |
| case eSmeCommandTdlsDelPeer: |
| case eSmeCommandTdlsLinkEstablish: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("sending TDLS Command 0x%x to PE"), |
| pCommand->command); |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| status = csr_tdls_process_cmd(pMac, pCommand); |
| break; |
| #endif |
| case e_sme_command_set_hw_mode: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_set_hw_mode(pMac, pCommand); |
| break; |
| case e_sme_command_nss_update: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_nss_update_req(pMac, pCommand); |
| break; |
| case e_sme_command_set_dual_mac_config: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_set_dual_mac_config(pMac, pCommand); |
| break; |
| case e_sme_command_set_antenna_mode: |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| csr_process_set_antenna_mode(pMac, pCommand); |
| break; |
| default: |
| /* something is wrong */ |
| /* remove it from the active list */ |
| sms_log(pMac, LOGE, FL("unknown command %d"), |
| pCommand->command); |
| pEntry = csr_ll_remove_head(&pMac->sme.smeCmdActiveList, |
| LL_ACCESS_NOLOCK); |
| csr_ll_unlock(&pMac->sme.smeCmdActiveList); |
| pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| sme_release_command(pMac, pCommand); |
| status = QDF_STATUS_E_FAILURE; |
| break; |
| } |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| fContinue = true; |
| process_scan_q: |
| if (!(sme_process_scan_queue(pMac))) |
| fContinue = false; |
| return fContinue; |
| } |
| |
| void sme_process_pending_queue(tpAniSirGlobal pMac) |
| { |
| while (sme_process_command(pMac)) |
| ; |
| } |
| |
| bool sme_command_pending(tpAniSirGlobal pMac) |
| { |
| return !csr_ll_is_list_empty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK) |
| || !csr_ll_is_list_empty(&pMac->sme.smeCmdPendingList, |
| LL_ACCESS_NOLOCK); |
| } |
| |
| /* Global APIs */ |
| |
| /** |
| * sme_open() - Initialze all SME modules and put them at idle state |
| * @hHal: The handle returned by mac_open |
| * |
| * The function initializes each module inside SME, PMC, CSR, etc. Upon |
| * successfully return, all modules are at idle state ready to start. |
| * smeOpen must be called before any other SME APIs can be involved. |
| * smeOpen must be called after mac_open. |
| * |
| * Return: QDF_STATUS_SUCCESS - SME is successfully initialized. |
| * Other status means SME is failed to be initialized |
| */ |
| QDF_STATUS sme_open(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pMac->sme.state = SME_STATE_STOP; |
| pMac->sme.currDeviceMode = QDF_STA_MODE; |
| if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( |
| &pMac->sme.lkSmeGlobalLock))) { |
| sms_log(pMac, LOGE, FL("sme_open failed init lock")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| status = csr_open(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, FL("csr_open failed, status=%d"), status); |
| return status; |
| } |
| |
| status = sme_ps_open(hHal); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| FL("sme_ps_open failed during initialization with status=%d"), |
| status); |
| return status; |
| } |
| #ifdef FEATURE_WLAN_TDLS |
| pMac->is_tdls_power_save_prohibited = 0; |
| #endif |
| |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| status = sme_qos_open(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, FL("Qos open, status=%d"), status); |
| return status; |
| } |
| #endif |
| status = init_sme_cmd_list(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| status = rrm_open(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, FL("rrm_open failed, status=%d"), status); |
| return status; |
| } |
| sme_p2p_open(pMac); |
| sme_trace_init(pMac); |
| return status; |
| } |
| |
| /* |
| * sme_init_chan_list, triggers channel setup based on country code. |
| */ |
| QDF_STATUS sme_init_chan_list(tHalHandle hal, uint8_t *alpha2, |
| enum country_src cc_src) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| |
| if ((cc_src == SOURCE_USERSPACE) && |
| (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) { |
| pmac->roam.configParam.Is11dSupportEnabled = false; |
| } |
| |
| return csr_init_chan_list(pmac, alpha2); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_set11dinfo() - Set the 11d information about valid channels |
| and there power using information from nvRAM |
| This function is called only for AP. |
| |
| This is a synchronous call |
| |
| \param hHal - The handle returned by mac_open. |
| \Param pSmeConfigParams - a pointer to a caller allocated object of |
| typedef struct _smeConfigParams. |
| |
| \return QDF_STATUS_SUCCESS - SME update the config parameters successfully. |
| |
| Other status means SME is failed to update the config parameters. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0)); |
| if (NULL == pSmeConfigParams) { |
| sms_log(pMac, LOGE, |
| "Empty config param structure for SME, nothing to update"); |
| return status; |
| } |
| |
| status = csr_set_channels(hHal, &pSmeConfigParams->csrConfig); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_change_default_config_param failed with status=%d", |
| status); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_scan_disable() - Dynamically enable/disable scan |
| * @h_hal: Handle to HAL |
| * |
| * This command gives the user an option to dynamically |
| * enable or disable scans. |
| * |
| * Return: None |
| */ |
| void sme_set_scan_disable(tHalHandle h_hal, int value) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); |
| mac_ctx->lim.scan_disabled = value; |
| sms_log(mac_ctx, LOG1, FL("value=%d"), value); |
| } |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_get_soft_ap_domain() - Get the current regulatory domain of softAp. |
| |
| This is a synchronous call |
| |
| \param hHal - The handle returned by HostapdAdapter. |
| \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp. |
| |
| \return QDF_STATUS_SUCCESS - SME successfully completed the request. |
| |
| Other status means, failed to get the current regulatory domain. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_get_soft_ap_domain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, |
| NO_SESSION, 0)); |
| if (NULL == domainIdSoftAp) { |
| sms_log(pMac, LOGE, "Uninitialized domain Id"); |
| return status; |
| } |
| |
| *domainIdSoftAp = pMac->scan.domainIdCurrent; |
| status = QDF_STATUS_SUCCESS; |
| |
| return status; |
| } |
| |
| QDF_STATUS sme_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0)); |
| if (NULL == apCntryCode) { |
| sms_log(pMac, LOGE, "Empty Country Code, nothing to update"); |
| return status; |
| } |
| |
| status = csr_set_reg_info(hHal, apCntryCode); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, "csr_set_reg_info failed with status=%d", |
| status); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_update_fine_time_measurement_capab() - Update the FTM capabitlies from |
| * incoming val |
| * @hal: Handle for Hal layer |
| * @val: New FTM capability value |
| * |
| * Return: None |
| */ |
| void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| mac_ctx->fine_time_meas_cap = val; |
| |
| if (val == 0) { |
| mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0; |
| ((tpRRMCaps)mac_ctx->rrm.rrmSmeContext. |
| rrmConfig.rm_capability)->fine_time_meas_rpt = 0; |
| } else { |
| mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1; |
| ((tpRRMCaps)mac_ctx->rrm.rrmSmeContext. |
| rrmConfig.rm_capability)->fine_time_meas_rpt = 1; |
| } |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_update_config() - Change configurations for all SME moduels |
| |
| The function updates some configuration for modules in SME, CSR, etc |
| during SMEs close open sequence. |
| |
| Modules inside SME apply the new configuration at the next transaction. |
| |
| This is a synchronous call |
| |
| \param hHal - The handle returned by mac_open. |
| \Param pSmeConfigParams - a pointer to a caller allocated object of |
| typedef struct _smeConfigParams. |
| |
| \return QDF_STATUS_SUCCESS - SME update the config parameters successfully. |
| |
| Other status means SME is failed to update the config parameters. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_config(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, |
| 0)); |
| if (NULL == pSmeConfigParams) { |
| sms_log(pMac, LOGE, |
| "Empty config param structure for SME, nothing to update"); |
| return status; |
| } |
| |
| status = |
| csr_change_default_config_param(pMac, &pSmeConfigParams->csrConfig); |
| |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_change_default_config_param failed with status=%d", |
| status); |
| } |
| status = |
| rrm_change_default_config_param(hHal, &pSmeConfigParams->rrmConfig); |
| |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "rrm_change_default_config_param failed with status=%d", |
| status); |
| } |
| /* For SOC, CFG is set before start */ |
| /* We don't want to apply global CFG in connect state because that may cause some side affect */ |
| if (csr_is_all_session_disconnected(pMac)) { |
| csr_set_global_cfgs(pMac); |
| } |
| |
| /* |
| * If scan offload is enabled then lim has allow the sending of |
| * scan request to firmware even in powersave mode. The firmware has |
| * to take care of exiting from power save mode |
| */ |
| status = sme_cfg_set_int(hHal, WNI_CFG_SCAN_IN_POWERSAVE, true); |
| |
| if (QDF_STATUS_SUCCESS != status) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CFG"); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_update_roam_params() - Store/Update the roaming params |
| * @hal: Handle for Hal layer |
| * @session_id: SME Session ID |
| * @roam_params_src: The source buffer to copy |
| * @update_param: Type of parameter to be updated |
| * |
| * Return: Return the status of the updation. |
| */ |
| QDF_STATUS sme_update_roam_params(tHalHandle hal, |
| uint8_t session_id, struct roam_ext_params roam_params_src, |
| int update_param) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct roam_ext_params *roam_params_dst; |
| uint8_t i; |
| |
| roam_params_dst = &mac_ctx->roam.configParam.roam_params; |
| switch (update_param) { |
| case REASON_ROAM_EXT_SCAN_PARAMS_CHANGED: |
| roam_params_dst->raise_rssi_thresh_5g = |
| roam_params_src.raise_rssi_thresh_5g; |
| roam_params_dst->drop_rssi_thresh_5g = |
| roam_params_src.drop_rssi_thresh_5g; |
| roam_params_dst->raise_factor_5g = |
| roam_params_src.raise_factor_5g; |
| roam_params_dst->drop_factor_5g = |
| roam_params_src.drop_factor_5g; |
| roam_params_dst->max_raise_rssi_5g = |
| roam_params_src.max_raise_rssi_5g; |
| roam_params_dst->max_drop_rssi_5g = |
| roam_params_src.max_drop_rssi_5g; |
| roam_params_dst->alert_rssi_threshold = |
| roam_params_src.alert_rssi_threshold; |
| roam_params_dst->is_5g_pref_enabled = true; |
| break; |
| case REASON_ROAM_SET_SSID_ALLOWED: |
| qdf_mem_set(&roam_params_dst->ssid_allowed_list, 0, |
| sizeof(tSirMacSSid) * MAX_SSID_ALLOWED_LIST); |
| roam_params_dst->num_ssid_allowed_list = |
| roam_params_src.num_ssid_allowed_list; |
| for (i = 0; i < roam_params_dst->num_ssid_allowed_list; i++) { |
| roam_params_dst->ssid_allowed_list[i].length = |
| roam_params_src.ssid_allowed_list[i].length; |
| qdf_mem_copy(roam_params_dst->ssid_allowed_list[i].ssId, |
| roam_params_src.ssid_allowed_list[i].ssId, |
| roam_params_dst->ssid_allowed_list[i].length); |
| } |
| break; |
| case REASON_ROAM_SET_FAVORED_BSSID: |
| qdf_mem_set(&roam_params_dst->bssid_favored, 0, |
| sizeof(tSirMacAddr) * MAX_BSSID_FAVORED); |
| roam_params_dst->num_bssid_favored = |
| roam_params_src.num_bssid_favored; |
| for (i = 0; i < roam_params_dst->num_bssid_favored; i++) { |
| qdf_mem_copy(&roam_params_dst->bssid_favored[i], |
| &roam_params_src.bssid_favored[i], |
| sizeof(tSirMacAddr)); |
| roam_params_dst->bssid_favored_factor[i] = |
| roam_params_src.bssid_favored_factor[i]; |
| } |
| break; |
| case REASON_ROAM_SET_BLACKLIST_BSSID: |
| qdf_mem_set(&roam_params_dst->bssid_avoid_list, 0, |
| QDF_MAC_ADDR_SIZE * MAX_BSSID_AVOID_LIST); |
| roam_params_dst->num_bssid_avoid_list = |
| roam_params_src.num_bssid_avoid_list; |
| for (i = 0; i < roam_params_dst->num_bssid_avoid_list; i++) { |
| qdf_copy_macaddr(&roam_params_dst->bssid_avoid_list[i], |
| &roam_params_src.bssid_avoid_list[i]); |
| } |
| break; |
| case REASON_ROAM_GOOD_RSSI_CHANGED: |
| roam_params_dst->good_rssi_roam = |
| roam_params_src.good_rssi_roam; |
| break; |
| default: |
| break; |
| } |
| csr_roam_offload_scan(mac_ctx, session_id, ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| update_param); |
| return 0; |
| } |
| |
| #ifdef WLAN_FEATURE_GTK_OFFLOAD |
| void sme_process_get_gtk_info_rsp(tHalHandle hHal, |
| tpSirGtkOffloadGetInfoRspParams |
| pGtkOffloadGetInfoRsp) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return; |
| } |
| if (pMac->sme.gtk_offload_get_info_cb == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: HDD callback is null", __func__); |
| return; |
| } |
| pMac->sme.gtk_offload_get_info_cb( |
| pMac->sme.gtk_offload_get_info_cb_context, |
| pGtkOffloadGetInfoRsp); |
| } |
| #endif |
| |
| /*-------------------------------------------------------------------------- |
| |
| \fn - sme_process_ready_to_suspend |
| \brief - On getting ready to suspend indication, this function calls |
| callback registered (HDD callbacks) with SME to inform |
| ready to suspend indication. |
| |
| \param hHal - Handle returned by mac_open. |
| pReadyToSuspend - Parameter received along with ready to suspend |
| indication from WMA. |
| |
| \return None |
| |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| void sme_process_ready_to_suspend(tHalHandle hHal, |
| tpSirReadyToSuspendInd pReadyToSuspend) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return; |
| } |
| |
| if (NULL != pMac->readyToSuspendCallback) { |
| pMac->readyToSuspendCallback(pMac->readyToSuspendContext, |
| pReadyToSuspend->suspended); |
| pMac->readyToSuspendCallback = NULL; |
| } |
| } |
| |
| #ifdef WLAN_FEATURE_EXTWOW_SUPPORT |
| |
| /** |
| * sme_process_ready_to_ext_wow() - inform ready to ExtWoW indication. |
| * @hHal - Handle returned by mac_open. |
| * @pReadyToExtWoW - Parameter received along with ready to Ext WoW |
| * indication from WMA. |
| * |
| * On getting ready to Ext WoW indication, this function calls callback |
| * registered (HDD callback)with SME to inform ready to ExtWoW indication. |
| * |
| * Return: None |
| */ |
| void sme_process_ready_to_ext_wow(tHalHandle hHal, |
| tpSirReadyToExtWoWInd pReadyToExtWoW) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return; |
| } |
| |
| if (NULL != pMac->readyToExtWoWCallback) { |
| pMac->readyToExtWoWCallback(pMac->readyToExtWoWContext, |
| pReadyToExtWoW->status); |
| pMac->readyToExtWoWCallback = NULL; |
| pMac->readyToExtWoWContext = NULL; |
| } |
| |
| } |
| #endif |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_change_config_params |
| \brief The SME API exposed for HDD to provide config params to SME during |
| SMEs stop -> start sequence. |
| |
| If HDD changed the domain that will cause a reset. This function will |
| provide the new set of 11d information for the new domain. Currrently this |
| API provides info regarding 11d only at reset but we can extend this for |
| other params (PMC, QoS) which needs to be initialized again at reset. |
| |
| This is a synchronous call |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \Param |
| pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that |
| currently provides 11d related information like Country code, |
| Regulatory domain, valid channel list, Tx power per channel, a |
| list with active/passive scan allowed per valid channel. |
| |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_change_config_params(tHalHandle hHal, |
| tCsrUpdateConfigParam *pUpdateConfigParam) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pUpdateConfigParam) { |
| sms_log(pMac, LOGE, |
| "Empty config param structure for SME, nothing to reset"); |
| return status; |
| } |
| |
| status = csr_change_config_params(pMac, pUpdateConfigParam); |
| |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, "csrUpdateConfigParam failed with status=%d", |
| status); |
| } |
| |
| return status; |
| |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_hdd_ready_ind() - SME sends eWNI_SME_SYS_READY_IND to PE to inform |
| that the NIC is ready tio run. |
| |
| The function is called by HDD at the end of initialization stage so PE/HAL can |
| enable the NIC to running state. |
| |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| |
| \return QDF_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE |
| successfully. |
| |
| Other status means SME failed to send the message to PE. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal) |
| { |
| tSirSmeReadyReq Msg; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0)); |
| do { |
| |
| Msg.messageType = eWNI_SME_SYS_READY_IND; |
| Msg.length = sizeof(tSirSmeReadyReq); |
| Msg.add_bssdescr_cb = csr_scan_process_single_bssdescr; |
| Msg.csr_roam_synch_cb = csr_roam_synch_callback; |
| |
| |
| if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *) &Msg)) { |
| status = QDF_STATUS_SUCCESS; |
| } else { |
| sms_log(pMac, LOGE, |
| "u_mac_post_ctrl_msg failed to send eWNI_SME_SYS_READY_IND"); |
| break; |
| } |
| |
| status = csr_ready(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_ready failed with status=%d", |
| status); |
| break; |
| } |
| |
| if (QDF_STATUS_SUCCESS != rrm_ready(hHal)) { |
| status = QDF_STATUS_E_FAILURE; |
| sms_log(pMac, LOGE, "rrm_ready failed"); |
| break; |
| } |
| pMac->sme.state = SME_STATE_READY; |
| } while (0); |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_start() - Put all SME modules at ready state. |
| |
| The function starts each module in SME, PMC, CSR, etc. . Upon |
| successfully return, all modules are ready to run. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| |
| \return QDF_STATUS_SUCCESS - SME is ready. |
| |
| Other status means SME is failed to start |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_start(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| do { |
| status = csr_start(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_start failed during smeStart with status=%d", |
| status); |
| break; |
| } |
| pMac->sme.state = SME_STATE_START; |
| } while (0); |
| |
| return status; |
| } |
| |
| /** |
| * sme_handle_scan_req() - Scan request handler |
| * @mac_ctx: MAC global context |
| * @msg: message buffer |
| * |
| * Scan request message from upper layer is handled as |
| * part of this API |
| * |
| * Return: QDF_STATUS |
| */ |
| static QDF_STATUS sme_handle_scan_req(tpAniSirGlobal mac_ctx, |
| void *msg) |
| { |
| struct ani_scan_req *scan_msg; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| uint16_t session_id; |
| csr_scan_completeCallback callback; |
| |
| scan_msg = msg; |
| session_id = scan_msg->session_id; |
| callback = scan_msg->callback; |
| status = csr_scan_request(mac_ctx, session_id, |
| scan_msg->scan_param, |
| callback, scan_msg->ctx); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac_ctx, LOGE, |
| FL("scan request failed. session_id %d"), session_id); |
| } |
| csr_scan_free_request(mac_ctx, scan_msg->scan_param); |
| qdf_mem_free(scan_msg->scan_param); |
| return status; |
| } |
| |
| /** |
| * sme_handle_roc_req() - Roc request handler |
| * @mac_ctx: MAC global context |
| * @msg: message buffer |
| * |
| * Roc request message from upper layer is handled as |
| * part of this API |
| * |
| * Return: QDF_STATUS |
| */ |
| static QDF_STATUS sme_handle_roc_req(tHalHandle hal, |
| void *msg) |
| { |
| struct ani_roc_req *roc_msg; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| remainOnChanCallback callback; |
| |
| if (msg == NULL) { |
| sms_log(mac_ctx, LOGE, FL("ROC request is NULL")); |
| return status; |
| } |
| |
| roc_msg = msg; |
| callback = roc_msg->callback; |
| status = p2p_remain_on_channel(hal, roc_msg->session_id, |
| roc_msg->channel, roc_msg->duration, callback, |
| roc_msg->ctx, roc_msg->is_p2pprobe_allowed, |
| roc_msg->scan_id); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac_ctx, LOGE, |
| FL("scan request failed. session_id %d scan_id %d"), |
| roc_msg->session_id, roc_msg->scan_id); |
| } |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_11W |
| /*------------------------------------------------------------------ |
| * |
| * Handle the unprotected management frame indication from LIM and |
| * forward it to HDD. |
| * |
| *------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_unprotected_mgmt_frm_ind(tHalHandle hHal, |
| tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrRoamInfo pRoamInfo = { 0 }; |
| uint32_t SessionId = pSmeMgmtFrm->sessionId; |
| |
| pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen; |
| pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf; |
| pRoamInfo.frameType = pSmeMgmtFrm->frameType; |
| |
| /* forward the mgmt frame to HDD */ |
| csr_roam_call_callback(pMac, SessionId, &pRoamInfo, 0, |
| eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0); |
| |
| return status; |
| } |
| #endif |
| |
| /*------------------------------------------------------------------ |
| * |
| * Handle the DFS Radar Event and indicate it to the SAP |
| * |
| *------------------------------------------------------------------*/ |
| QDF_STATUS dfs_msg_processor(tpAniSirGlobal pMac, uint16_t msgType, void *pMsgBuf) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrRoamInfo roamInfo = { 0 }; |
| tSirSmeDfsEventInd *dfs_event; |
| tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp; |
| uint32_t sessionId = 0; |
| eRoamCmdStatus roamStatus; |
| eCsrRoamResult roamResult; |
| int i; |
| |
| switch (msgType) { |
| case eWNI_SME_DFS_RADAR_FOUND: |
| { |
| /* Radar found !! */ |
| dfs_event = (tSirSmeDfsEventInd *) pMsgBuf; |
| if (NULL == dfs_event) { |
| sms_log(pMac, LOGE, |
| "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message", |
| __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| sessionId = dfs_event->sessionId; |
| roamInfo.dfs_event.sessionId = sessionId; |
| roamInfo.dfs_event.chan_list.nchannels = |
| dfs_event->chan_list.nchannels; |
| for (i = 0; i < dfs_event->chan_list.nchannels; i++) { |
| roamInfo.dfs_event.chan_list.channels[i] = |
| dfs_event->chan_list.channels[i]; |
| } |
| |
| roamInfo.dfs_event.dfs_radar_status = |
| dfs_event->dfs_radar_status; |
| roamInfo.dfs_event.use_nol = dfs_event->use_nol; |
| |
| roamStatus = eCSR_ROAM_DFS_RADAR_IND; |
| roamResult = eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Radar indication event occurred"); |
| break; |
| } |
| case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: |
| { |
| csaIeTxCompleteRsp = |
| (tSirSmeCSAIeTxCompleteRsp *) pMsgBuf; |
| if (NULL == csaIeTxCompleteRsp) { |
| sms_log(pMac, LOGE, |
| "%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND", |
| __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| sessionId = csaIeTxCompleteRsp->sessionId; |
| roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY; |
| roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]", |
| sessionId); |
| break; |
| } |
| default: |
| { |
| sms_log(pMac, LOG1, "%s: Invalid DFS message = 0x%x", |
| __func__, msgType); |
| status = QDF_STATUS_E_FAILURE; |
| return status; |
| } |
| } |
| |
| /* Indicate Radar Event to SAP */ |
| csr_roam_call_callback(pMac, sessionId, &roamInfo, 0, |
| roamStatus, roamResult); |
| return status; |
| } |
| |
| /** |
| * sme_extended_change_channel_ind()- function to indicate ECSA |
| * action frame is received in lim to SAP |
| * @mac_ctx: pointer to global mac structure |
| * @msg_buf: contain new channel and session id. |
| * |
| * This function is called to post ECSA action frame |
| * receive event to SAP. |
| * |
| * Return: success if msg indicated to SAP else return failure |
| */ |
| static QDF_STATUS sme_extended_change_channel_ind(tpAniSirGlobal mac_ctx, |
| void *msg_buf) |
| { |
| struct sir_sme_ext_cng_chan_ind *ext_chan_ind; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| uint32_t session_id = 0; |
| tCsrRoamInfo roamInfo = {0}; |
| eRoamCmdStatus roam_status; |
| eCsrRoamResult roam_result; |
| |
| |
| ext_chan_ind = msg_buf; |
| if (NULL == ext_chan_ind) { |
| sms_log(mac_ctx, LOGE, |
| FL("pMsg is NULL for eWNI_SME_EXT_CHANGE_CHANNEL_IND")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| session_id = ext_chan_ind->session_id; |
| roamInfo.target_channel = ext_chan_ind->new_channel; |
| roam_status = eCSR_ROAM_EXT_CHG_CHNL_IND; |
| roam_result = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND; |
| sms_log(mac_ctx, LOG1, |
| FL("sapdfs: Received eWNI_SME_EXT_CHANGE_CHANNEL_IND for session id [%d]"), |
| session_id); |
| |
| /* Indicate Ext Channel Change event to SAP */ |
| csr_roam_call_callback(mac_ctx, session_id, &roamInfo, 0, |
| roam_status, roam_result); |
| return status; |
| } |
| |
| /** |
| * sme_process_fw_mem_dump_rsp - process fw memory dump response from WMA |
| * |
| * @mac_ctx: pointer to MAC handle. |
| * @msg: pointer to received SME msg. |
| * |
| * This function process the received SME message and calls the corresponding |
| * callback which was already registered with SME. |
| * |
| * Return: None |
| */ |
| #ifdef WLAN_FEATURE_MEMDUMP |
| static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg) |
| { |
| if (msg->bodyptr) { |
| if (mac_ctx->sme.fw_dump_callback) |
| mac_ctx->sme.fw_dump_callback(mac_ctx->hHdd, |
| (struct fw_dump_rsp *) msg->bodyptr); |
| qdf_mem_free(msg->bodyptr); |
| } |
| } |
| #else |
| static void sme_process_fw_mem_dump_rsp(tpAniSirGlobal mac_ctx, cds_msg_t *msg) |
| { |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_ESE |
| /** |
| * sme_update_is_ese_feature_enabled() - enable/disable ESE support at runtime |
| * @hHal: HAL handle |
| * @sessionId: session id |
| * @isEseIniFeatureEnabled: ese ini enabled |
| * |
| * It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| * isEseIniFeatureEnabled. This is a synchronous call |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_update_is_ese_feature_enabled(tHalHandle hHal, |
| uint8_t sessionId, const bool isEseIniFeatureEnabled) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (pMac->roam.configParam.isEseIniFeatureEnabled == |
| isEseIniFeatureEnabled) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: ESE Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", |
| __func__, |
| pMac->roam.configParam.isEseIniFeatureEnabled, |
| isEseIniFeatureEnabled); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: EseEnabled is changed from %d to %d", __func__, |
| pMac->roam.configParam.isEseIniFeatureEnabled, |
| isEseIniFeatureEnabled); |
| pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled; |
| csr_neighbor_roam_update_fast_roaming_enabled( |
| pMac, sessionId, isEseIniFeatureEnabled); |
| |
| if (true == isEseIniFeatureEnabled) |
| sme_update_fast_transition_enabled(hHal, true); |
| |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_ESE_INI_CFG_CHANGED); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_set_plm_request() - set plm request |
| * @hHal: HAL handle |
| * @pPlmReq: Pointer to input plm request |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_plm_request(tHalHandle hHal, tpSirPlmReq pPlmReq) |
| { |
| QDF_STATUS status; |
| bool ret = false; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint8_t ch_list[WNI_CFG_VALID_CHANNEL_LIST] = { 0 }; |
| uint8_t count, valid_count = 0; |
| cds_msg_t msg; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, pPlmReq->sessionId); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| if (!pSession) { |
| sms_log(pMac, LOGE, FL("session %d not found"), |
| pPlmReq->sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pSession->sessionActive) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Invalid Sessionid")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pPlmReq->enable) |
| goto send_plm_start; |
| /* validating channel numbers */ |
| for (count = 0; count < pPlmReq->plmNumCh; count++) { |
| ret = csr_is_supported_channel(pMac, pPlmReq->plmChList[count]); |
| if (ret && pPlmReq->plmChList[count] > 14) { |
| if (CHANNEL_STATE_DFS == cds_get_channel_state( |
| pPlmReq->plmChList[count])) { |
| /* DFS channel is provided, no PLM bursts can be |
| * transmitted. Ignoring these channels. |
| */ |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_INFO, |
| FL("DFS channel %d ignored for PLM"), |
| pPlmReq->plmChList[count]); |
| continue; |
| } |
| } else if (!ret) { |
| /* Not supported, ignore the channel */ |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("Unsupported channel %d ignored for PLM"), |
| pPlmReq->plmChList[count]); |
| continue; |
| } |
| ch_list[valid_count] = pPlmReq->plmChList[count]; |
| valid_count++; |
| } /* End of for () */ |
| |
| /* Copying back the valid channel list to plm struct */ |
| qdf_mem_set((void *)pPlmReq->plmChList, |
| pPlmReq->plmNumCh, 0); |
| if (valid_count) |
| qdf_mem_copy(pPlmReq->plmChList, ch_list, |
| valid_count); |
| /* All are invalid channels, FW need to send the PLM |
| * report with "incapable" bit set. |
| */ |
| pPlmReq->plmNumCh = valid_count; |
| |
| send_plm_start: |
| /* PLM START */ |
| msg.type = WMA_SET_PLM_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = pPlmReq; |
| |
| if (!QDF_IS_STATUS_SUCCESS(cds_mq_post_message(QDF_MODULE_ID_WMA, |
| &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_SET_PLM_REQ to WMA")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_tsm_ie_ind() - sme tsm ie indication |
| * @hHal: HAL handle |
| * @pSmeTsmIeInd: Pointer to tsm ie indication |
| * |
| * Handle the tsm ie indication from LIM and forward it to HDD. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| static QDF_STATUS sme_tsm_ie_ind(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrRoamInfo pRoamInfo = { 0 }; |
| uint32_t SessionId = pSmeTsmIeInd->sessionId; |
| pRoamInfo.tsmIe.tsid = pSmeTsmIeInd->tsmIe.tsid; |
| pRoamInfo.tsmIe.state = pSmeTsmIeInd->tsmIe.state; |
| pRoamInfo.tsmIe.msmt_interval = pSmeTsmIeInd->tsmIe.msmt_interval; |
| /* forward the tsm ie information to HDD */ |
| csr_roam_call_callback(pMac, |
| SessionId, &pRoamInfo, 0, eCSR_ROAM_TSM_IE_IND, 0); |
| return status; |
| } |
| |
| /** |
| * sme_set_cckm_ie() - set cckm ie |
| * @hHal: HAL handle |
| * @sessionId: session id |
| * @pCckmIe: Pointer to CCKM Ie |
| * @cckmIeLen: Length of @pCckmIe |
| * |
| * Function to store the CCKM IE passed from supplicant and use |
| * it while packing reassociation request. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_cckm_ie(tHalHandle hHal, uint8_t sessionId, |
| uint8_t *pCckmIe, uint8_t cckmIeLen) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_set_cckm_ie(pMac, sessionId, pCckmIe, cckmIeLen); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_ese_beacon_request() - set ese beacon request |
| * @hHal: HAL handle |
| * @sessionId: session id |
| * @pEseBcnReq: Ese beacon report |
| * |
| * function to set ESE beacon request parameters |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId, |
| const tCsrEseBeaconReq *pEseBcnReq) |
| { |
| QDF_STATUS status = eSIR_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tpSirBeaconReportReqInd pSmeBcnReportReq = NULL; |
| tCsrEseBeaconReqParams *pBeaconReq = NULL; |
| uint8_t counter = 0; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; |
| |
| if (pSmeRrmContext->eseBcnReqInProgress == true) { |
| sms_log(pMac, LOGE, |
| "A Beacon Report Req is already in progress"); |
| return QDF_STATUS_E_RESOURCES; |
| } |
| |
| /* Store the info in RRM context */ |
| qdf_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq, |
| sizeof(tCsrEseBeaconReq)); |
| |
| /* Prepare the request to send to SME. */ |
| pSmeBcnReportReq = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd)); |
| if (NULL == pSmeBcnReportReq) { |
| sms_log(pMac, LOGP, |
| "Memory Allocation Failure!!! ESE BcnReq Ind to SME"); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pSmeRrmContext->eseBcnReqInProgress = true; |
| |
| sms_log(pMac, LOGE, "Sending Beacon Report Req to SME"); |
| qdf_mem_zero(pSmeBcnReportReq, sizeof(tSirBeaconReportReqInd)); |
| |
| pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; |
| pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd); |
| qdf_mem_copy(pSmeBcnReportReq->bssId, |
| pSession->connectedProfile.bssid.bytes, |
| sizeof(tSirMacAddr)); |
| pSmeBcnReportReq->channelInfo.channelNum = 255; |
| pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe; |
| pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; |
| |
| for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) { |
| pBeaconReq = |
| (tCsrEseBeaconReqParams *) &pEseBcnReq->bcnReq[counter]; |
| pSmeBcnReportReq->fMeasurementtype[counter] = |
| pBeaconReq->scanMode; |
| pSmeBcnReportReq->measurementDuration[counter] = |
| SYS_TU_TO_MS(pBeaconReq->measurementDuration); |
| pSmeBcnReportReq->channelList.channelNumber[counter] = |
| pBeaconReq->channel; |
| } |
| |
| status = sme_rrm_process_beacon_report_req_ind(pMac, pSmeBcnReportReq); |
| |
| if (status != QDF_STATUS_SUCCESS) |
| pSmeRrmContext->eseBcnReqInProgress = false; |
| |
| qdf_mem_free(pSmeBcnReportReq); |
| |
| return status; |
| } |
| |
| /** |
| * sme_get_tsm_stats() - SME get tsm stats |
| * @hHal: HAL handle |
| * @callback: SME sends back the requested stats using the callback |
| * @staId: The station ID for which the stats is requested for |
| * @bssId: bssid |
| * @pContext: user context to be passed back along with the callback |
| * @p_cds_context: CDS context |
| * @tid: Traffic id |
| * |
| * API register a callback to get TSM Stats. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_get_tsm_stats(tHalHandle hHal, |
| tCsrTsmStatsCallback callback, |
| uint8_t staId, struct qdf_mac_addr bssId, |
| void *pContext, void *p_cds_context, uint8_t tid) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_get_tsm_stats(pMac, callback, |
| staId, bssId, pContext, |
| p_cds_context, tid); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_ese_roam_scan_channel_list() - To set ese roam scan channel list |
| * @hHal: pointer HAL handle returned by mac_open |
| * @sessionId: sme session id |
| * @pChannelList: Output channel list |
| * @numChannels: Output number of channels |
| * |
| * This routine is called to set ese roam scan channel list. |
| * This is a synchronous call |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal, |
| uint8_t sessionId, |
| uint8_t *pChannelList, |
| uint8_t numChannels) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo |
| = &pMac->roam.neighborRoamInfo[sessionId]; |
| tpCsrChannelInfo curchnl_list_info |
| = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; |
| uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; |
| uint8_t newChannelList[128] = { 0 }; |
| uint8_t i = 0, j = 0; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_CHANNEL_LIST_CHANGED); |
| return status; |
| } |
| if (NULL != curchnl_list_info->ChannelList) { |
| for (i = 0; i < curchnl_list_info->numOfChannels; i++) { |
| j += snprintf(oldChannelList + j, |
| sizeof(oldChannelList) - j, "%d", |
| curchnl_list_info->ChannelList[i]); |
| } |
| } |
| status = csr_create_roam_scan_channel_list(pMac, sessionId, |
| pChannelList, numChannels, |
| csr_get_current_band(hHal)); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (NULL != curchnl_list_info->ChannelList) { |
| j = 0; |
| for (i = 0; i < curchnl_list_info->numOfChannels; i++) { |
| j += snprintf(newChannelList + j, |
| sizeof(newChannelList) - j, "%d", |
| curchnl_list_info->ChannelList[i]); |
| } |
| } |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "ESE roam scan chnl list successfully set to %s-old value is %s-roam state is %d", |
| newChannelList, oldChannelList, |
| pNeighborRoamInfo->neighborRoamState); |
| } |
| sme_release_global_lock(&pMac->sme); |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_CHANNEL_LIST_CHANGED); |
| return status; |
| } |
| |
| #endif /* FEATURE_WLAN_ESE */ |
| |
| QDF_STATUS sme_ibss_peer_info_response_handleer(tHalHandle hHal, |
| tpSirIbssGetPeerInfoRspParams |
| pIbssPeerInfoParams) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: HDD callback is null", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData, |
| &pIbssPeerInfoParams-> |
| ibssPeerInfoRspParams); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_process_dual_mac_config_resp() - Process set Dual mac config response |
| * @mac: Global MAC pointer |
| * @msg: Dual mac config response |
| * |
| * Processes the dual mac configuration response and invokes the HDD callback |
| * to process further |
| */ |
| static QDF_STATUS sme_process_dual_mac_config_resp(tpAniSirGlobal mac, |
| uint8_t *msg) |
| { |
| tListElem *entry = NULL; |
| tSmeCmd *command = NULL; |
| bool found; |
| dual_mac_cb callback = NULL; |
| struct sir_dual_mac_config_resp *param; |
| |
| param = (struct sir_dual_mac_config_resp *)msg; |
| if (!param) { |
| sms_log(mac, LOGE, FL("Dual mac config resp param is NULL")); |
| /* Not returning. Need to check if active command list |
| * needs to be freed |
| */ |
| } |
| |
| entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (!entry) { |
| sms_log(mac, LOGE, FL("No cmd found in active list")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| command = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| if (!command) { |
| sms_log(mac, LOGE, FL("Base address is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (e_sme_command_set_dual_mac_config != command->command) { |
| sms_log(mac, LOGE, FL("Command mismatch!")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| callback = command->u.set_dual_mac_cmd.set_dual_mac_cb; |
| if (callback) { |
| if (!param) { |
| sms_log(mac, LOGE, |
| FL("Callback failed-Dual mac config is NULL")); |
| } else { |
| sms_log(mac, LOG1, |
| FL("Calling HDD callback for Dual mac config")); |
| callback(param->status, |
| command->u.set_dual_mac_cmd.scan_config, |
| command->u.set_dual_mac_cmd.fw_mode_config); |
| } |
| } else { |
| sms_log(mac, LOGE, FL("Callback does not exist")); |
| } |
| |
| found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry, |
| LL_ACCESS_LOCK); |
| if (found) |
| /* Now put this command back on the available command list */ |
| sme_release_command(mac, command); |
| |
| sme_process_pending_queue(mac); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_process_antenna_mode_resp() - Process set antenna mode |
| * response |
| * @mac: Global MAC pointer |
| * @msg: antenna mode response |
| * |
| * Processes the antenna mode response and invokes the HDD |
| * callback to process further |
| */ |
| static QDF_STATUS sme_process_antenna_mode_resp(tpAniSirGlobal mac, |
| uint8_t *msg) |
| { |
| tListElem *entry; |
| tSmeCmd *command; |
| bool found; |
| antenna_mode_cb callback; |
| struct sir_antenna_mode_resp *param; |
| |
| param = (struct sir_antenna_mode_resp *)msg; |
| if (!param) { |
| sms_log(mac, LOGE, FL("set antenna mode resp is NULL")); |
| /* Not returning. Need to check if active command list |
| * needs to be freed |
| */ |
| } |
| |
| entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (!entry) { |
| sms_log(mac, LOGE, FL("No cmd found in active list")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| command = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| if (!command) { |
| sms_log(mac, LOGE, FL("Base address is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (e_sme_command_set_antenna_mode != command->command) { |
| sms_log(mac, LOGE, FL("Command mismatch!")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| callback = |
| command->u.set_antenna_mode_cmd.set_antenna_mode_resp; |
| if (callback) { |
| if (!param) { |
| sms_log(mac, LOGE, |
| FL("Set antenna mode call back is NULL")); |
| } else { |
| sms_log(mac, LOG1, |
| FL("HDD callback for set antenna mode")); |
| callback(param->status); |
| } |
| } else { |
| sms_log(mac, LOGE, FL("Callback does not exist")); |
| } |
| |
| found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry, |
| LL_ACCESS_LOCK); |
| if (found) |
| /* Now put this command back on the available command list */ |
| sme_release_command(mac, command); |
| |
| sme_process_pending_queue(mac); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_process_msg() - The main message processor for SME. |
| |
| The function is called by a message dispatcher when to process a message |
| targeted for SME. |
| |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \param pMsg - A pointer to a caller allocated object of tSirMsgQ. |
| |
| \return QDF_STATUS_SUCCESS - SME successfully process the message. |
| |
| Other status means SME failed to process the message to HAL. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (pMsg == NULL) { |
| sms_log(pMac, LOGE, "Empty message for SME"); |
| return status; |
| } |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGW, FL("Locking failed, bailing out")); |
| if (pMsg->bodyptr) |
| qdf_mem_free(pMsg->bodyptr); |
| return status; |
| } |
| if (!SME_IS_START(pMac)) { |
| sms_log(pMac, LOGW, FL("message type %d in stop state ignored"), |
| pMsg->type); |
| if (pMsg->bodyptr) |
| qdf_mem_free(pMsg->bodyptr); |
| goto release_lock; |
| } |
| switch (pMsg->type) { |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| case eWNI_SME_HO_FAIL_IND: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("LFR3: Rcvd eWNI_SME_HO_FAIL_IND")); |
| csr_process_ho_fail_ind(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #endif |
| case eWNI_PMC_SMPS_STATE_IND: |
| break; |
| case WNI_CFG_SET_CNF: |
| case WNI_CFG_DNLD_CNF: |
| case WNI_CFG_GET_RSP: |
| case WNI_CFG_ADD_GRP_ADDR_CNF: |
| case WNI_CFG_DEL_GRP_ADDR_CNF: |
| break; |
| case eWNI_SME_ADDTS_RSP: |
| case eWNI_SME_DELTS_RSP: |
| case eWNI_SME_DELTS_IND: |
| case eWNI_SME_FT_AGGR_QOS_RSP: |
| /* QoS */ |
| if (pMsg->bodyptr) { |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| status = sme_qos_msg_processor(pMac, pMsg->type, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| #endif |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_NEIGHBOR_REPORT_IND: |
| case eWNI_SME_BEACON_REPORT_REQ_IND: |
| if (pMsg->bodyptr) { |
| status = sme_rrm_msg_processor(pMac, pMsg->type, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_ADD_STA_SELF_RSP: |
| if (pMsg->bodyptr) { |
| status = csr_process_add_sta_session_rsp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_DEL_STA_SELF_RSP: |
| if (pMsg->bodyptr) { |
| status = csr_process_del_sta_session_rsp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_REMAIN_ON_CHN_RSP: |
| if (pMsg->bodyptr) { |
| status = sme_remain_on_chn_rsp(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_REMAIN_ON_CHN_RDY_IND: |
| if (pMsg->bodyptr) { |
| status = sme_remain_on_chn_ready(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #ifdef FEATURE_WLAN_SCAN_PNO |
| case eWNI_SME_PREF_NETWORK_FOUND_IND: |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMsg->bodyptr) { |
| status = sme_preferred_network_found_ind((void *)pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif /* FEATURE_WLAN_SCAN_PNO */ |
| case eWNI_SME_CHANGE_COUNTRY_CODE: |
| if (pMsg->bodyptr) { |
| status = sme_handle_change_country_code((void *)pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE: |
| if (pMsg->bodyptr) { |
| status = sme_handle_generic_change_country_code( |
| (void *)pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_SCAN_CMD: |
| if (pMsg->bodyptr) { |
| status = sme_handle_scan_req(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_ROC_CMD: |
| if (pMsg->bodyptr) { |
| status = sme_handle_roc_req(hHal, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #ifdef FEATURE_WLAN_TDLS |
| /* |
| * command rescived from PE, SME tdls msg processor shall be called |
| * to process commands recieved from PE |
| */ |
| case eWNI_SME_TDLS_SEND_MGMT_RSP: |
| case eWNI_SME_TDLS_ADD_STA_RSP: |
| case eWNI_SME_TDLS_DEL_STA_RSP: |
| case eWNI_SME_TDLS_DEL_STA_IND: |
| case eWNI_SME_TDLS_DEL_ALL_PEER_IND: |
| case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: |
| case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: |
| case eWNI_SME_TDLS_SHOULD_DISCOVER: |
| case eWNI_SME_TDLS_SHOULD_TEARDOWN: |
| case eWNI_SME_TDLS_PEER_DISCONNECTED: |
| if (pMsg->bodyptr) { |
| status = tdls_msg_processor(pMac, pMsg->type, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif |
| #ifdef WLAN_FEATURE_11W |
| case eWNI_SME_UNPROT_MGMT_FRM_IND: |
| if (pMsg->bodyptr) { |
| sme_unprotected_mgmt_frm_ind(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif |
| #ifdef FEATURE_WLAN_ESE |
| case eWNI_SME_TSM_IE_IND: |
| if (pMsg->bodyptr) { |
| sme_tsm_ie_ind(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif /* FEATURE_WLAN_ESE */ |
| case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP: |
| status = csr_roam_offload_scan_rsp_hdlr((void *)pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #ifdef WLAN_FEATURE_GTK_OFFLOAD |
| case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP: |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMsg->bodyptr) { |
| sme_process_get_gtk_info_rsp(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif |
| #ifdef FEATURE_WLAN_LPHB |
| /* LPHB timeout indication arrived, send IND to client */ |
| case eWNI_SME_LPHB_IND: |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMac->sme.pLphbIndCb) |
| pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #endif /* FEATURE_WLAN_LPHB */ |
| case eWNI_SME_IBSS_PEER_INFO_RSP: |
| if (pMsg->bodyptr) { |
| sme_ibss_peer_info_response_handleer(pMac, |
| pMsg-> |
| bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_READY_TO_SUSPEND_IND: |
| if (pMsg->bodyptr) { |
| sme_process_ready_to_suspend(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #ifdef WLAN_FEATURE_EXTWOW_SUPPORT |
| case eWNI_SME_READY_TO_EXTWOW_IND: |
| if (pMsg->bodyptr) { |
| sme_process_ready_to_ext_wow(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif |
| #ifdef FEATURE_WLAN_CH_AVOID |
| /* channel avoid message arrived, send IND to client */ |
| case eWNI_SME_CH_AVOID_IND: |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMac->sme.pChAvoidNotificationCb) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("CH avoid notification")); |
| pMac->sme.pChAvoidNotificationCb(pMac->hHdd, |
| pMsg->bodyptr); |
| } |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #endif /* FEATURE_WLAN_CH_AVOID */ |
| #ifdef FEATURE_WLAN_AUTO_SHUTDOWN |
| case eWNI_SME_AUTO_SHUTDOWN_IND: |
| if (pMac->sme.pAutoShutdownNotificationCb) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("Auto shutdown notification")); |
| pMac->sme.pAutoShutdownNotificationCb(); |
| } |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #endif |
| case eWNI_SME_DFS_RADAR_FOUND: |
| case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: |
| status = dfs_msg_processor(pMac, pMsg->type, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_CHANNEL_CHANGE_RSP: |
| if (pMsg->bodyptr) { |
| status = sme_process_channel_change_resp(pMac, |
| pMsg->type, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #ifdef WLAN_FEATURE_STATS_EXT |
| case eWNI_SME_STATS_EXT_EVENT: |
| if (pMsg->bodyptr) { |
| status = sme_stats_ext_event(hHal, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| #endif |
| case eWNI_SME_LINK_SPEED_IND: |
| if (pMac->sme.pLinkSpeedIndCb) |
| pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr, |
| pMac->sme.pLinkSpeedCbContext); |
| if (pMsg->bodyptr) |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_CSA_OFFLOAD_EVENT: |
| if (pMsg->bodyptr) { |
| csr_scan_flush_bss_entry(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } |
| break; |
| case eWNI_SME_TSF_EVENT: |
| if (pMac->sme.get_tsf_cb) { |
| pMac->sme.get_tsf_cb(pMac->sme.get_tsf_cxt, |
| (struct stsf *)pMsg->bodyptr); |
| } |
| if (pMsg->bodyptr) |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #ifdef WLAN_FEATURE_NAN |
| case eWNI_SME_NAN_EVENT: |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_WMA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMsg->bodyptr) { |
| sme_nan_event(hHal, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } |
| break; |
| #endif /* WLAN_FEATURE_NAN */ |
| case eWNI_SME_LINK_STATUS_IND: |
| { |
| tAniGetLinkStatus *pLinkStatus = |
| (tAniGetLinkStatus *) pMsg->bodyptr; |
| if (pLinkStatus) { |
| if (pMac->sme.linkStatusCallback) { |
| pMac->sme.linkStatusCallback( |
| pLinkStatus->linkStatus, |
| pMac->sme.linkStatusContext); |
| } |
| pMac->sme.linkStatusCallback = NULL; |
| pMac->sme.linkStatusContext = NULL; |
| qdf_mem_free(pLinkStatus); |
| } |
| break; |
| } |
| case eWNI_SME_MSG_GET_TEMPERATURE_IND: |
| if (pMac->sme.pGetTemperatureCb) { |
| pMac->sme.pGetTemperatureCb(pMsg->bodyval, |
| pMac->sme.pTemperatureCbContext); |
| } |
| break; |
| case eWNI_SME_SNR_IND: |
| { |
| tAniGetSnrReq *pSnrReq = (tAniGetSnrReq *) pMsg->bodyptr; |
| if (pSnrReq) { |
| if (pSnrReq->snrCallback) { |
| ((tCsrSnrCallback) |
| (pSnrReq->snrCallback)) |
| (pSnrReq->snr, pSnrReq->staId, |
| pSnrReq->pDevContext); |
| } |
| qdf_mem_free(pSnrReq); |
| } |
| break; |
| } |
| #ifdef FEATURE_WLAN_EXTSCAN |
| case eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND: |
| if (pMac->sme.pExtScanIndCb) |
| pMac->sme.pExtScanIndCb(pMac->hHdd, |
| eSIR_EXTSCAN_FULL_SCAN_RESULT_IND, |
| pMsg->bodyptr); |
| else |
| sms_log(pMac, LOGE, |
| FL("callback not registered to process %d"), |
| pMsg->type); |
| |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_EPNO_NETWORK_FOUND_IND: |
| if (pMac->sme.pExtScanIndCb) |
| pMac->sme.pExtScanIndCb(pMac->hHdd, |
| eSIR_EPNO_NETWORK_FOUND_IND, |
| pMsg->bodyptr); |
| else |
| sms_log(pMac, LOGE, |
| FL("callback not registered to process %d"), |
| pMsg->type); |
| |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| #endif |
| case eWNI_SME_FW_DUMP_IND: |
| sme_process_fw_mem_dump_rsp(pMac, pMsg); |
| break; |
| case eWNI_SME_SET_HW_MODE_RESP: |
| if (pMsg->bodyptr) { |
| status = sme_process_set_hw_mode_resp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_HW_MODE_TRANS_IND: |
| if (pMsg->bodyptr) { |
| status = sme_process_hw_mode_trans_ind(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_NSS_UPDATE_RSP: |
| if (pMsg->bodyptr) { |
| status = sme_process_nss_update_resp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_OCB_SET_CONFIG_RSP: |
| if (pMac->sme.ocb_set_config_callback) { |
| pMac->sme.ocb_set_config_callback( |
| pMac->sme.ocb_set_config_context, |
| pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL( |
| "Message error. The callback is NULL.")); |
| } |
| pMac->sme.ocb_set_config_callback = NULL; |
| pMac->sme.ocb_set_config_context = NULL; |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_OCB_GET_TSF_TIMER_RSP: |
| if (pMac->sme.ocb_get_tsf_timer_callback) { |
| pMac->sme.ocb_get_tsf_timer_callback( |
| pMac->sme.ocb_get_tsf_timer_context, |
| pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL( |
| "Message error. The callback is NULL.")); |
| } |
| pMac->sme.ocb_get_tsf_timer_callback = NULL; |
| pMac->sme.ocb_get_tsf_timer_context = NULL; |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_DCC_GET_STATS_RSP: |
| if (pMac->sme.dcc_get_stats_callback) { |
| pMac->sme.dcc_get_stats_callback( |
| pMac->sme.dcc_get_stats_context, |
| pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL( |
| "Message error. The callback is NULL.")); |
| } |
| pMac->sme.dcc_get_stats_callback = NULL; |
| pMac->sme.dcc_get_stats_context = NULL; |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_DCC_UPDATE_NDL_RSP: |
| if (pMac->sme.dcc_update_ndl_callback) { |
| pMac->sme.dcc_update_ndl_callback( |
| pMac->sme.dcc_update_ndl_context, |
| pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL( |
| "Message error. The callback is NULL.")); |
| } |
| pMac->sme.dcc_update_ndl_callback = NULL; |
| pMac->sme.dcc_update_ndl_context = NULL; |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_DCC_STATS_EVENT: |
| if (pMac->sme.dcc_stats_event_callback) { |
| pMac->sme.dcc_stats_event_callback( |
| pMac->sme.dcc_stats_event_context, |
| pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL( |
| "Message error. The callback is NULL.")); |
| } |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_SET_DUAL_MAC_CFG_RESP: |
| if (pMsg->bodyptr) { |
| status = sme_process_dual_mac_config_resp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| case eWNI_SME_SET_THERMAL_LEVEL_IND: |
| if (pMac->sme.set_thermal_level_cb) |
| pMac->sme.set_thermal_level_cb(pMac->hHdd, |
| pMsg->bodyval); |
| break; |
| case eWNI_SME_EXT_CHANGE_CHANNEL_IND: |
| status = sme_extended_change_channel_ind(pMac, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_SET_ANTENNA_MODE_RESP: |
| if (pMsg->bodyptr) { |
| status = sme_process_antenna_mode_resp(pMac, |
| pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| break; |
| case eWNI_SME_NDP_CONFIRM_IND: |
| case eWNI_SME_NDP_NEW_PEER_IND: |
| case eWNI_SME_NDP_INITIATOR_RSP: |
| case eWNI_SME_NDP_INDICATION: |
| case eWNI_SME_NDP_RESPONDER_RSP: |
| case eWNI_SME_NDP_END_RSP: |
| case eWNI_SME_NDP_END_IND: |
| case eWNI_SME_NDP_PEER_DEPARTED_IND: |
| sme_ndp_msg_processor(pMac, pMsg); |
| break; |
| default: |
| |
| if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN) |
| && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) { |
| /* CSR */ |
| if (pMsg->bodyptr) { |
| status = csr_msg_processor(hHal, pMsg->bodyptr); |
| qdf_mem_free(pMsg->bodyptr); |
| } else { |
| sms_log(pMac, LOGE, FL("Empty message for %d"), |
| pMsg->type); |
| } |
| } else { |
| sms_log(pMac, LOGW, FL("Unknown message type %d"), |
| pMsg->type); |
| if (pMsg->bodyptr) |
| qdf_mem_free(pMsg->bodyptr); |
| } |
| } /* switch */ |
| release_lock: |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_process_nss_update_resp() - Process nss update response |
| * @mac: Global MAC pointer |
| * @msg: nss update response |
| * |
| * Processes the nss update response and invokes the HDD |
| * callback to process further |
| */ |
| QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg) |
| { |
| tListElem *entry = NULL; |
| tSmeCmd *command = NULL; |
| bool found; |
| nss_update_cb callback = NULL; |
| struct sir_beacon_tx_complete_rsp *param; |
| |
| param = (struct sir_beacon_tx_complete_rsp *)msg; |
| if (!param) { |
| sms_log(mac, LOGE, FL("nss update resp param is NULL")); |
| /* Not returning. Need to check if active command list |
| * needs to be freed |
| */ |
| } |
| |
| entry = csr_ll_peek_head(&mac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (!entry) { |
| sms_log(mac, LOGE, FL("No cmd found in active list")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| command = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| if (!command) { |
| sms_log(mac, LOGE, FL("Base address is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (e_sme_command_nss_update != command->command) { |
| sms_log(mac, LOGE, FL("Command mismatch!")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| callback = command->u.nss_update_cmd.nss_update_cb; |
| if (callback) { |
| if (!param) { |
| sms_log(mac, LOGE, |
| FL("Callback failed since nss update params is NULL")); |
| } else { |
| sms_log(mac, LOGE, |
| FL("Calling HDD callback for nss update response")); |
| callback(command->u.nss_update_cmd.context, |
| param->tx_status, |
| param->session_id, |
| command->u.nss_update_cmd.next_action, |
| command->u.nss_update_cmd.reason); |
| } |
| } else { |
| sms_log(mac, LOGE, FL("Callback does not exisit")); |
| } |
| |
| found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry, |
| LL_ACCESS_LOCK); |
| if (found) { |
| /* Now put this command back on the avilable command list */ |
| sme_release_command(mac, command); |
| } |
| sme_process_pending_queue(mac); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* No need to hold the global lock here because this function can only be called */ |
| /* after sme_stop. */ |
| void sme_free_msg(tHalHandle hHal, cds_msg_t *pMsg) |
| { |
| if (pMsg) { |
| if (pMsg->bodyptr) { |
| qdf_mem_free(pMsg->bodyptr); |
| } |
| } |
| |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_stop() - Stop all SME modules and put them at idle state |
| |
| The function stops each module in SME, PMC, CSR, etc. . Upon |
| return, all modules are at idle state ready to start. |
| |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \param tHalStopType - reason for stopping |
| |
| \return QDF_STATUS_SUCCESS - SME is stopped. |
| |
| Other status means SME is failed to stop but caller should still |
| consider SME is stopped. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_stop(tHalHandle hHal, tHalStopType stopType) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| QDF_STATUS fail_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| p2p_stop(hHal); |
| |
| status = csr_stop(pMac, stopType); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_stop failed during smeStop with status=%d", status); |
| fail_status = status; |
| } |
| |
| purge_sme_cmd_list(pMac); |
| |
| if (!QDF_IS_STATUS_SUCCESS(fail_status)) { |
| status = fail_status; |
| } |
| |
| pMac->sme.state = SME_STATE_STOP; |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_close() - Release all SME modules and their resources. |
| |
| The function release each module in SME, PMC, CSR, etc. . Upon |
| return, all modules are at closed state. |
| |
| No SME APIs can be involved after smeClose except smeOpen. |
| smeClose must be called before mac_close. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| |
| \return QDF_STATUS_SUCCESS - SME is successfully close. |
| |
| Other status means SME is failed to be closed but caller still cannot |
| call any other SME functions except smeOpen. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_close(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| QDF_STATUS fail_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (!pMac) |
| return QDF_STATUS_E_FAILURE; |
| |
| /* Note: pSession will be invalid from here on, do not access */ |
| status = csr_close(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "csr_close failed during sme close with status=%d", |
| status); |
| fail_status = status; |
| } |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| status = sme_qos_close(pMac); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "Qos close failed during sme close with status=%d", |
| status); |
| fail_status = status; |
| } |
| #endif |
| status = sme_ps_close(hHal); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "sme_ps_close failed during smeClose status=%d", |
| status); |
| fail_status = status; |
| } |
| |
| status = rrm_close(hHal); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| "RRM close failed during sme close with status=%d", |
| status); |
| fail_status = status; |
| } |
| |
| sme_p2p_close(hHal); |
| |
| free_sme_cmd_list(pMac); |
| |
| if (!QDF_IS_STATUS_SUCCESS |
| (qdf_mutex_destroy(&pMac->sme.lkSmeGlobalLock))) { |
| fail_status = QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!QDF_IS_STATUS_SUCCESS(fail_status)) { |
| status = fail_status; |
| } |
| |
| pMac->sme.state = SME_STATE_STOP; |
| |
| return status; |
| } |
| |
| /** |
| * sme_remove_bssid_from_scan_list() - wrapper to remove the bssid from |
| * scan list |
| * @hal: hal context. |
| * @bssid: bssid to be removed |
| * |
| * This function remove the given bssid from scan list. |
| * |
| * Return: QDF status. |
| */ |
| QDF_STATUS sme_remove_bssid_from_scan_list(tHalHandle hal, |
| tSirMacAddr bssid) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_remove_bssid_from_scan_list(mac_ctx, bssid); |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_scan_request() - wrapper function to Request a 11d or full scan from CSR. |
| * @hal: hal global context |
| * @session_id: session id |
| * @scan_req: scan req |
| * @callback: a callback function that scan calls upon finish, will not |
| * be called if csr_scan_request returns error |
| * @ctx: a pointer passed in for the callback |
| * |
| * This is a wrapper function to Request a 11d or full scan from CSR. This is |
| * an asynchronous call |
| * |
| * Return: Status of operation |
| */ |
| QDF_STATUS sme_scan_request(tHalHandle hal, uint8_t session_id, |
| tCsrScanRequest *scan_req, |
| csr_scan_completeCallback callback, void *ctx) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct ani_scan_req *scan_msg; |
| cds_msg_t msg; |
| uint32_t scan_req_id, scan_count; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, session_id, |
| scan_req->scanType)); |
| |
| if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| sms_log(mac_ctx, LOGE, FL("Invalid session id:%d"), |
| session_id); |
| return status; |
| } |
| |
| if (!mac_ctx->scan.fScanEnable) { |
| sms_log(mac_ctx, LOGE, FL("fScanEnable false")); |
| return status; |
| } |
| |
| scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList); |
| if (scan_count >= mac_ctx->scan.max_scan_count) { |
| sms_log(mac_ctx, LOGE, FL("Max scan reached")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| wma_get_scan_id(&scan_req_id); |
| scan_req->scan_id = scan_req_id; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac_ctx, LOGE, FL("Unable to acquire lock")); |
| return status; |
| } |
| sms_log(mac_ctx, LOG1, FL(" called")); |
| scan_msg = qdf_mem_malloc(sizeof(struct ani_scan_req)); |
| if (NULL == scan_msg) { |
| sms_log(mac_ctx, LOGE, |
| " scan_req: failed to allocate mem for msg"); |
| sme_release_global_lock(&mac_ctx->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| scan_msg->msg_type = eWNI_SME_SCAN_CMD; |
| scan_msg->msg_len = (uint16_t) sizeof(struct ani_scan_req); |
| scan_msg->session_id = session_id; |
| scan_msg->callback = callback; |
| scan_msg->ctx = ctx; |
| scan_msg->scan_param = qdf_mem_malloc(sizeof(tCsrScanRequest)); |
| if (NULL == scan_msg->scan_param) { |
| sms_log(mac_ctx, LOGE, |
| "scan_req:failed to allocate mem for scanreq"); |
| sme_release_global_lock(&mac_ctx->sme); |
| qdf_mem_free(scan_msg); |
| return QDF_STATUS_E_NOMEM; |
| } |
| csr_scan_copy_request(mac_ctx, scan_msg->scan_param, scan_req); |
| msg.type = eWNI_SME_SCAN_CMD; |
| msg.bodyptr = scan_msg; |
| msg.reserved = 0; |
| msg.bodyval = 0; |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(CDS_MQ_ID_SME, &msg)) { |
| sms_log(mac_ctx, LOGE, |
| " sme_scan_req failed to post msg"); |
| csr_scan_free_request(mac_ctx, scan_msg->scan_param); |
| qdf_mem_free(scan_msg->scan_param); |
| qdf_mem_free(scan_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_get_result |
| \brief a wrapper function to request scan results from CSR. |
| This is a synchronous call |
| \param pFilter - If pFilter is NULL, all cached results are returned |
| \param phResult - an object for the result. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_scan_get_result(tHalHandle hHal, uint8_t sessionId, |
| tCsrScanResultFilter *pFilter, |
| tScanResultHandle *phResult) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId, |
| 0)); |
| sms_log(pMac, LOG2, FL("enter")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_scan_get_result(hHal, pFilter, phResult); |
| sme_release_global_lock(&pMac->sme); |
| } |
| sms_log(pMac, LOG2, FL("exit status %d"), status); |
| |
| return status; |
| } |
| |
| /** |
| * sme_get_ap_channel_from_scan_cache() - a wrapper function to get AP's |
| * channel id from CSR by filtering the |
| * result which matches our roam profile. |
| * @profile: SAP adapter |
| * @ap_chnl_id: pointer to channel id of SAP. Fill the value after finding the |
| * best ap from scan cache. |
| * |
| * This function is written to get AP's channel id from CSR by filtering |
| * the result which matches our roam profile. This is a synchronous call. |
| * |
| * Return: QDF_STATUS. |
| */ |
| QDF_STATUS sme_get_ap_channel_from_scan_cache(tHalHandle hal_handle, |
| tCsrRoamProfile *profile, |
| tScanResultHandle *scan_cache, |
| uint8_t *ap_chnl_id) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| tCsrScanResultFilter *scan_filter = NULL; |
| tScanResultHandle filtered_scan_result = NULL; |
| tSirBssDescription first_ap_profile; |
| |
| if (NULL == mac_ctx) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("mac_ctx is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); |
| if (NULL == scan_filter) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("scan_filter mem alloc failed")); |
| return QDF_STATUS_E_FAILURE; |
| } else { |
| qdf_mem_set(scan_filter, sizeof(tCsrScanResultFilter), 0); |
| qdf_mem_set(&first_ap_profile, sizeof(tSirBssDescription), 0); |
| |
| if (NULL == profile) { |
| scan_filter->EncryptionType.numEntries = 1; |
| scan_filter->EncryptionType.encryptionType[0] |
| = eCSR_ENCRYPT_TYPE_NONE; |
| } else { |
| /* Here is the profile we need to connect to */ |
| status = csr_roam_prepare_filter_from_profile(mac_ctx, |
| profile, |
| scan_filter); |
| } |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| /* Save the WPS info */ |
| if (NULL != profile) { |
| scan_filter->bWPSAssociation = |
| profile->bWPSAssociation; |
| scan_filter->bOSENAssociation = |
| profile->bOSENAssociation; |
| } else { |
| scan_filter->bWPSAssociation = 0; |
| scan_filter->bOSENAssociation = 0; |
| } |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Preparing the profile filter failed")); |
| qdf_mem_free(scan_filter); |
| return QDF_STATUS_E_FAILURE; |
| } |
| } |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| status = csr_scan_get_result(hal_handle, scan_filter, |
| &filtered_scan_result); |
| if (QDF_STATUS_SUCCESS == status) { |
| csr_get_bssdescr_from_scan_handle(filtered_scan_result, |
| &first_ap_profile); |
| *scan_cache = filtered_scan_result; |
| if (0 != first_ap_profile.channelId) { |
| *ap_chnl_id = first_ap_profile.channelId; |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_ERROR, |
| FL("Found best AP & its on chnl[%d]"), |
| first_ap_profile.channelId); |
| } else { |
| /* |
| * This means scan result is empty |
| * so set the channel to zero, caller should |
| * take of zero channel id case. |
| */ |
| *ap_chnl_id = 0; |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_ERROR, |
| FL("Scan is empty, set chnl to 0")); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to get scan get result")); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| csr_free_scan_filter(mac_ctx, scan_filter); |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Aquiring lock failed")); |
| csr_free_scan_filter(mac_ctx, scan_filter); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| qdf_mem_free(scan_filter); |
| return status; |
| } |
| |
| /** |
| * sme_store_joinreq_param() - This function will pass station's join |
| * request to store to csr. |
| * @hal_handle: pointer to hal context. |
| * @profile: pointer to station's roam profile. |
| * @scan_cache: pointer to station's scan cache. |
| * @roam_id: reference to roam_id variable being passed. |
| * @session_id: station's session id. |
| * |
| * This function will pass station's join request further down to csr |
| * to store it. this stored parameter will be used later. |
| * |
| * Return: true or false based on function's overall success. |
| **/ |
| bool sme_store_joinreq_param(tHalHandle hal_handle, |
| tCsrRoamProfile *profile, |
| tScanResultHandle scan_cache, |
| uint32_t *roam_id, |
| uint32_t session_id) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| bool ret_status = true; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_STORE_JOIN_REQ, |
| session_id, 0)); |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if (false == csr_store_joinreq_param(mac_ctx, profile, |
| scan_cache, roam_id, session_id)) { |
| ret_status = false; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| ret_status = false; |
| } |
| |
| return ret_status; |
| } |
| |
| /** |
| * sme_clear_joinreq_param() - This function will pass station's clear |
| * the join request to csr. |
| * @hal_handle: pointer to hal context. |
| * @session_id: station's session id. |
| * |
| * This function will pass station's clear join request further down to csr |
| * to cleanup. |
| * |
| * Return: true or false based on function's overall success. |
| **/ |
| bool sme_clear_joinreq_param(tHalHandle hal_handle, |
| uint32_t session_id) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| bool ret_status = true; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CLEAR_JOIN_REQ, |
| session_id, 0)); |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if (false == csr_clear_joinreq_param(mac_ctx, |
| session_id)) { |
| ret_status = false; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| ret_status = false; |
| } |
| |
| return ret_status; |
| } |
| |
| /** |
| * sme_issue_stored_joinreq() - This function will issues station's stored |
| * the join request to csr. |
| * @hal_handle: pointer to hal context. |
| * @roam_id: reference to roam_id variable being passed. |
| * @session_id: station's session id. |
| * |
| * This function will issue station's stored join request further down to csr |
| * to proceed forward. |
| * |
| * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE. |
| **/ |
| QDF_STATUS sme_issue_stored_joinreq(tHalHandle hal_handle, |
| uint32_t *roam_id, |
| uint32_t session_id) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| QDF_STATUS ret_status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ISSUE_JOIN_REQ, |
| session_id, 0)); |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if (QDF_STATUS_SUCCESS != csr_issue_stored_joinreq(mac_ctx, |
| roam_id, |
| session_id)) { |
| ret_status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| csr_clear_joinreq_param(mac_ctx, session_id); |
| ret_status = QDF_STATUS_E_FAILURE; |
| } |
| return ret_status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_flush_result |
| \brief a wrapper function to request CSR to clear scan results. |
| This is a synchronous call |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_scan_flush_result(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, |
| 0, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_scan_flush_result(hHal); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_filter_scan_results |
| \brief a wrapper function to request CSR to clear scan results. |
| This is a synchronous call |
| \param tHalHandle - HAL context handle |
| \param sessionId - session id |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_filter_scan_results(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_scan_filter_results(pMac); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| QDF_STATUS sme_scan_flush_p2p_result(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_scan_flush_selective_result(hHal, true); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_result_get_first |
| \brief a wrapper function to request CSR to returns the first element of |
| scan result. |
| This is a synchronous call |
| \param hScanResult - returned from csr_scan_get_result |
| \return tCsrScanResultInfo * - NULL if no result |
| ---------------------------------------------------------------------------*/ |
| tCsrScanResultInfo *sme_scan_result_get_first(tHalHandle hHal, |
| tScanResultHandle hScanResult) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrScanResultInfo *pRet = NULL; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, |
| NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pRet = csr_scan_result_get_first(pMac, hScanResult); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return pRet; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_result_get_next |
| \brief a wrapper function to request CSR to returns the next element of |
| scan result. It can be called without calling csr_scan_result_get_first |
| first |
| This is a synchronous call |
| \param hScanResult - returned from csr_scan_get_result |
| \return Null if no result or reach the end |
| ---------------------------------------------------------------------------*/ |
| tCsrScanResultInfo *sme_scan_result_get_next(tHalHandle hHal, |
| tScanResultHandle hScanResult) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrScanResultInfo *pRet = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pRet = csr_scan_result_get_next(pMac, hScanResult); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return pRet; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_result_purge |
| \brief a wrapper function to request CSR to remove all items(tCsrScanResult) |
| in the list and free memory for each item |
| This is a synchronous call |
| \param hScanResult - returned from csr_scan_get_result. hScanResult is |
| considered gone by |
| calling this function and even before this function reutrns. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_scan_result_purge(tHalHandle hHal, tScanResultHandle hScanResult) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, |
| NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_scan_result_purge(hHal, hScanResult); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_get_pmkid_candidate_list |
| \brief a wrapper function to return the PMKID candidate list |
| This is a synchronous call |
| \param pPmkidList - caller allocated buffer point to an array of |
| tPmkidCandidateInfo |
| \param pNumItems - pointer to a variable that has the number of |
| tPmkidCandidateInfo allocated when retruning, this is |
| either the number needed or number of items put into |
| pPmkidList |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough and pNumItems |
| has the number of tPmkidCandidateInfo. |
| \Note: pNumItems is a number of tPmkidCandidateInfo, |
| not sizeof(tPmkidCandidateInfo) * something |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_scan_get_pmkid_candidate_list(tHalHandle hHal, uint8_t sessionId, |
| tPmkidCandidateInfo *pPmkidList, |
| uint32_t *pNumItems) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = |
| csr_scan_get_pmkid_candidate_list(pMac, sessionId, |
| pPmkidList, |
| pNumItems); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| eCsrPhyMode sme_get_phy_mode(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.phyMode; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_channel_bonding_mode5_g |
| \brief get the channel bonding mode for 5G band |
| \param hHal - HAL handle |
| \return channel bonding mode for 5G |
| ---------------------------------------------------------------------------*/ |
| uint32_t sme_get_channel_bonding_mode5_g(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tSmeConfigParams smeConfig; |
| |
| sme_get_config_param(pMac, &smeConfig); |
| |
| return smeConfig.csrConfig.channelBondingMode5GHz; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_channel_bonding_mode24_g |
| \brief get the channel bonding mode for 2.4G band |
| \param hHal - HAL handle |
| \return channel bonding mode for 2.4G |
| ---------------------------------------------------------------------------*/ |
| uint32_t sme_get_channel_bonding_mode24_g(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tSmeConfigParams smeConfig; |
| |
| sme_get_config_param(pMac, &smeConfig); |
| |
| return smeConfig.csrConfig.channelBondingMode24GHz; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_connect |
| \brief a wrapper function to request CSR to inititiate an association |
| This is an asynchronous call. |
| \param sessionId - the sessionId returned by sme_open_session. |
| \param pProfile - description of the network to which to connect |
| \param hBssListIn - a list of BSS descriptor to roam to. It is returned |
| from csr_scan_get_result |
| \param pRoamId - to get back the request ID |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId, |
| tCsrRoamProfile *pProfile, uint32_t *pRoamId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (!pMac) { |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0)); |
| sms_log(pMac, LOG2, FL("enter")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_connect(pMac, sessionId, pProfile, |
| pRoamId); |
| } else { |
| sms_log(pMac, LOGE, FL("invalid sessionID %d"), |
| sessionId); |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| sms_log(pMac, LOGE, FL("sme_acquire_global_lock failed")); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_phy_mode |
| |
| \brief Changes the PhyMode. |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \param phyMode new phyMode which is to set |
| |
| \return QDF_STATUS SUCCESS. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: invalid context", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pMac->roam.configParam.phyMode = phyMode; |
| pMac->roam.configParam.uCfgDot11Mode = |
| csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL, |
| pMac->roam.configParam.phyMode, |
| pMac->roam.configParam. |
| ProprietaryRatesEnabled); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_reassoc |
| \brief a wrapper function to request CSR to inititiate a re-association |
| \param pProfile - can be NULL to join the currently connected AP. In that |
| case modProfileFields should carry the modified field(s) which could trigger |
| reassoc |
| \param modProfileFields - fields which are part of tCsrRoamConnectedProfile |
| that might need modification dynamically once STA is up & running and this |
| could trigger a reassoc |
| \param pRoamId - to get back the request ID |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_reassoc(tHalHandle hHal, uint8_t sessionId, |
| tCsrRoamProfile *pProfile, |
| tCsrRoamModifyProfileFields modProfileFields, |
| uint32_t *pRoamId, bool fForce) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0)); |
| sms_log(pMac, LOG2, FL("enter")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| if ((NULL == pProfile) && (fForce == 1)) { |
| status = |
| csr_reassoc(pMac, sessionId, |
| &modProfileFields, pRoamId, |
| fForce); |
| } else { |
| status = |
| csr_roam_reassoc(pMac, sessionId, pProfile, |
| modProfileFields, pRoamId); |
| } |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_connect_to_last_profile |
| \brief a wrapper function to request CSR to disconnect and reconnect with |
| the same profile |
| This is an asynchronous call. |
| \return QDF_STATUS. It returns fail if currently connected |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_connect_to_last_profile(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = csr_roam_connect_to_last_profile(pMac, sessionId); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_disconnect |
| \brief a wrapper function to request CSR to disconnect from a network |
| This is an asynchronous call. |
| \param reason -- To indicate the reason for disconnecting. Currently, only |
| eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_disconnect(tHalHandle hHal, uint8_t sessionId, |
| eCsrRoamDisconnectReason reason) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId, |
| reason)); |
| sms_log(pMac, LOG2, FL("enter")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = csr_roam_disconnect(pMac, sessionId, reason); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_stop_bss |
| \brief To stop BSS for Soft AP. This is an asynchronous API. |
| \param hHal - Global structure |
| \param sessionId - sessionId of SoftAP |
| \return QDF_STATUS SUCCESS Roam callback will be called to indicate actual results |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_stop_bss(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| sms_log(pMac, LOG2, FL("enter")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = csr_roam_issue_stop_bss_cmd(pMac, sessionId, true); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_roam_disconnect_sta() - disassociate a station |
| * @hHal: Global structure |
| * @sessionId: SessionId of SoftAP |
| * @p_del_sta_params: Pointer to parameters of the station to disassoc |
| * |
| * To disassociate a station. This is an asynchronous API. |
| * |
| * Return: QDF_STATUS_SUCCESS on success.Roam callback will |
| * be called to indicate actual result. |
| */ |
| QDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId, |
| struct tagCsrDelStaParams *p_del_sta_params) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_ASSERT(0); |
| return status; |
| } |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = csr_roam_issue_disassociate_sta_cmd(pMac, |
| sessionId, p_del_sta_params); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_roam_deauth_sta() - deauthenticate a station |
| * @hHal: Global structure |
| * @sessionId: SessionId of SoftAP |
| * @pDelStaParams: Pointer to parameters of the station to deauthenticate |
| * |
| * To disassociate a station. This is an asynchronous API. |
| * |
| * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS error |
| * code on error. Roam callback will be called to indicate actual |
| * result |
| */ |
| QDF_STATUS sme_roam_deauth_sta(tHalHandle hHal, uint8_t sessionId, |
| struct tagCsrDelStaParams *pDelStaParams) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_ASSERT(0); |
| return status; |
| } |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA, |
| sessionId, pDelStaParams->reason_code)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_issue_deauth_sta_cmd(pMac, sessionId, |
| pDelStaParams); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_tkip_counter_measures |
| \brief To start or stop TKIP counter measures. This is an asynchronous API. |
| \param sessionId - sessionId of SoftAP |
| \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_tkip_counter_measures(tHalHandle hHal, uint8_t sessionId, |
| bool bEnable) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_ASSERT(0); |
| return status; |
| } |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_issue_tkip_counter_measures(pMac, sessionId, |
| bEnable); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_associated_stas |
| \brief To probe the list of associated stations from various modules |
| of CORE stack. |
| \This is an asynchronous API. |
| \param sessionId - sessionId of SoftAP |
| \param modId - Module from whom list of associtated stations is |
| to be probed. If an invalid module is passed then |
| by default QDF_MODULE_ID_PE will be probed. |
| \param pUsrContext - Opaque HDD context |
| \param pfnSapEventCallback - Sap event callback in HDD |
| \param pAssocBuf - Caller allocated memory to be filled with associatd |
| stations info |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId, |
| QDF_MODULE_ID modId, void *pUsrContext, |
| void *pfnSapEventCallback, |
| uint8_t *pAssocStasBuf) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_ASSERT(0); |
| return status; |
| } |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_associated_stas(pMac, sessionId, modId, |
| pUsrContext, |
| pfnSapEventCallback, |
| pAssocStasBuf); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_wps_session_overlap |
| \brief To get the WPS PBC session overlap information. |
| \This is an asynchronous API. |
| \param sessionId - sessionId of SoftAP |
| \param pUsrContext - Opaque HDD context |
| \param pfnSapEventCallback - Sap event callback in HDD |
| \pRemoveMac - pointer to Mac address which needs to be removed from session |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_wps_session_overlap(tHalHandle hHal, uint8_t sessionId, |
| void *pUsrContext, void |
| *pfnSapEventCallback, |
| struct qdf_mac_addr pRemoveMac) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_ASSERT(0); |
| return status; |
| } |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_wps_session_overlap(pMac, sessionId, |
| pUsrContext, |
| pfnSapEventCallback, |
| pRemoveMac); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_connect_state |
| \brief a wrapper function to request CSR to return the current connect state |
| of Roaming |
| This is a synchronous call. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_connect_state(tHalHandle hHal, uint8_t sessionId, |
| eCsrConnectState *pState) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_connect_state(pMac, sessionId, pState); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_connect_profile |
| \brief a wrapper function to request CSR to return the current connect |
| profile. Caller must call csr_roam_free_connect_profile after it is done |
| and before reuse for another csr_roam_get_connect_profile call. |
| This is a synchronous call. |
| \param pProfile - pointer to a caller allocated structure |
| tCsrRoamConnectedProfile |
| \return QDF_STATUS. Failure if not connected |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_connect_profile(tHalHandle hHal, uint8_t sessionId, |
| tCsrRoamConnectedProfile *pProfile) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_connect_profile(pMac, sessionId, pProfile); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_roam_free_connect_profile - a wrapper function to request CSR to free and |
| * reinitialize the profile returned previously by csr_roam_get_connect_profile. |
| * |
| * @profile - pointer to a caller allocated structure tCsrRoamConnectedProfile |
| * |
| * Return: none |
| */ |
| void sme_roam_free_connect_profile(tCsrRoamConnectedProfile *profile) |
| { |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, |
| NO_SESSION, 0)); |
| csr_roam_free_connect_profile(profile); |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_set_pmkid_cache |
| \brief a wrapper function to request CSR to return the PMKID candidate list |
| This is a synchronous call. |
| \param pPMKIDCache - caller allocated buffer point to an array of |
| tPmkidCacheInfo |
| \param numItems - a variable that has the number of tPmkidCacheInfo |
| allocated when retruning, this is either the number needed |
| or number of items put into pPMKIDCache |
| \param update_entire_cache - this bool value specifies if the entire pmkid |
| cache should be overwritten or should it be |
| updated entry by entry. |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough and pNumItems has the number of |
| tPmkidCacheInfo. |
| \Note: pNumItems is a number of tPmkidCacheInfo, |
| not sizeof(tPmkidCacheInfo) * something |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId, |
| tPmkidCacheInfo *pPMKIDCache, |
| uint32_t numItems, bool update_entire_cache) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId, |
| numItems)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_set_pmkid_cache(pMac, sessionId, pPMKIDCache, |
| numItems, update_entire_cache); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId, |
| const uint8_t *pBSSId, bool flush_cache) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, |
| sessionId, flush_cache)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = csr_roam_del_pmkid_from_cache(pMac, sessionId, |
| pBSSId, flush_cache); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| /* --------------------------------------------------------------------------- |
| * \fn sme_roam_set_psk_pmk |
| * \brief a wrapper function to request CSR to save PSK/PMK |
| * This is a synchronous call. |
| * \param hHal - Global structure |
| * \param sessionId - SME sessionId |
| * \param pPSK_PMK - pointer to an array of Psk[]/Pmk |
| * \param pmk_len - Length could be only 16 bytes in case if LEAP |
| * connections. Need to pass this information to |
| * firmware. |
| * \return QDF_STATUS -status whether PSK/PMK is set or not |
| *--------------------------------------------------------------------------- |
| */ |
| QDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId, |
| uint8_t *pPSK_PMK, size_t pmk_len) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_set_psk_pmk(pMac, sessionId, pPSK_PMK, |
| pmk_len); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| #endif |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_security_req_ie |
| \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR |
| passes to PE to JOIN request or START_BSS request |
| This is a synchronous call. |
| \param pLen - caller allocated memory that has the length of pBuf as input. |
| Upon returned, *pLen has the needed or IE length in pBuf. |
| \param pBuf - Caller allocated memory that contain the IE field, if any, |
| upon return |
| \param secType - Specifies whether looking for WPA/WPA2/WAPI IE |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_security_req_ie(tHalHandle hHal, uint8_t sessionId, |
| uint32_t *pLen, uint8_t *pBuf, |
| eCsrSecurityType secType) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_wpa_rsn_req_ie(hHal, sessionId, pLen, pBuf); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_security_rsp_ie |
| \brief a wrapper function to request CSR to return the WPA or RSN or |
| WAPI IE from the beacon or probe rsp if connected |
| This is a synchronous call. |
| \param pLen - caller allocated memory that has the length of pBuf as input. |
| Upon returned, *pLen has the needed or IE length in pBuf. |
| \param pBuf - Caller allocated memory that contain the IE field, if any, |
| upon return |
| \param secType - Specifies whether looking for WPA/WPA2/WAPI IE |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_security_rsp_ie(tHalHandle hHal, uint8_t sessionId, |
| uint32_t *pLen, uint8_t *pBuf, |
| eCsrSecurityType secType) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_wpa_rsn_rsp_ie(pMac, sessionId, pLen, pBuf); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_num_pmkid_cache |
| \brief a wrapper function to request CSR to return number of PMKID cache |
| entries |
| This is a synchronous call. |
| \return uint32_t - the number of PMKID cache entries |
| ---------------------------------------------------------------------------*/ |
| uint32_t sme_roam_get_num_pmkid_cache(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint32_t numPmkidCache = 0; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| numPmkidCache = |
| csr_roam_get_num_pmkid_cache(pMac, sessionId); |
| status = QDF_STATUS_SUCCESS; |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return numPmkidCache; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_roam_get_pmkid_cache |
| \brief a wrapper function to request CSR to return PMKID cache from CSR |
| This is a synchronous call. |
| \param pNum - caller allocated memory that has the space of the number of |
| pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the |
| needed or actually number in tPmkidCacheInfo. |
| \param pPmkidCache - Caller allocated memory that contains PMKID cache, if |
| any, upon return |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId, |
| uint32_t *pNum, tPmkidCacheInfo *pPmkidCache) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ROAM_GET_PMKIDCACHE, sessionId, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_roam_get_pmkid_cache(pMac, sessionId, pNum, |
| pPmkidCache); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_config_param |
| \brief a wrapper function that HDD calls to get the global settings |
| currently maintained by CSR. |
| This is a synchronous call. |
| \param pParam - caller allocated memory |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_get_config_param(pMac, &pParam->csrConfig); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(pMac, LOGE, "%s csr_get_config_param failed", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| qdf_mem_copy(&pParam->rrmConfig, |
| &pMac->rrm.rrmSmeContext.rrmConfig, |
| sizeof(pMac->rrm.rrmSmeContext.rrmConfig)); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_cfg_set_int() - Sets the cfg parameter value. |
| * @hal: Handle to hal. |
| * @cfg_id: Configuration parameter ID. |
| * @value: value to be saved in the cfg parameter. |
| * |
| * This function sets the string value in cfg parameter. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_cfg_set_int(tHalHandle hal, uint16_t cfg_id, uint32_t value) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| if (eSIR_SUCCESS != cfg_set_int(pmac, cfg_id, value)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| return status; |
| } |
| |
| /** |
| * sme_cfg_set_str() - Sets the cfg parameter string. |
| * @hal: Handle to hal. |
| * @cfg_id: Configuration parameter ID. |
| * @str: Pointer to the string buffer. |
| * @length: Length of the string. |
| * |
| * This function sets the string value in cfg parameter. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_cfg_set_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str, |
| uint32_t length) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| if (eSIR_SUCCESS != cfg_set_str(pmac, cfg_id, str, length)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| return status; |
| } |
| |
| /** |
| * sme_cfg_get_int() - Gets the cfg parameter value. |
| * @hal: Handle to hal. |
| * @cfg_id: Configuration parameter ID. |
| * @cfg_value: Pointer to variable in which cfg value |
| * will be saved. |
| * |
| * This function gets the value of the cfg parameter. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_cfg_get_int(tHalHandle hal, uint16_t cfg_id, uint32_t *cfg_value) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| if (eSIR_SUCCESS != wlan_cfg_get_int(pmac, cfg_id, cfg_value)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| return status; |
| } |
| |
| /** |
| * sme_cfg_get_str() - Gets the cfg parameter string. |
| * @hal: Handle to hal. |
| * @cfg_id: Configuration parameter ID. |
| * @str: Pointer to the string buffer. |
| * @length: Pointer to length of the string. |
| * |
| * This function gets the string value of the cfg parameter. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_cfg_get_str(tHalHandle hal, uint16_t cfg_id, uint8_t *str, |
| uint32_t *length) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| if (eSIR_SUCCESS != wlan_cfg_get_str(pmac, cfg_id, str, length)) |
| status = QDF_STATUS_E_INVAL; |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_modify_profile_fields |
| \brief HDD or SME - QOS calls this function to get the current values of |
| connected profile fields, changing which can cause reassoc. |
| This function must be called after CFG is downloaded and STA is in connected |
| state. Also, make sure to call this function to get the current profile |
| fields before calling the reassoc. So that pModifyProfileFields will have |
| all the latest values plus the one(s) has been updated as part of reassoc |
| request. |
| \param pModifyProfileFields - pointer to the connected profile fields |
| changing which can cause reassoc |
| |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_modify_profile_fields(tHalHandle hHal, uint8_t sessionId, |
| tCsrRoamModifyProfileFields * |
| pModifyProfileFields) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| status = |
| csr_get_modify_profile_fields(pMac, sessionId, |
| pModifyProfileFields); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_dhcp_till_power_active_flag |
| \brief Sets/Clears DHCP related flag to disable/enable auto PS |
| \param hal - The handle returned by mac_open. |
| ---------------------------------------------------------------------------*/ |
| void sme_set_dhcp_till_power_active_flag(tHalHandle hal, uint8_t flag) |
| { |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| struct ps_global_info *ps_global_info = &mac->sme.ps_global_info; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION, |
| flag)); |
| /* Set/Clear the DHCP flag which will disable/enable auto PS */ |
| ps_global_info->remain_in_power_active_till_dhcp = flag; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_register11d_scan_done_callback |
| \brief Register a routine of type csr_scan_completeCallback which is |
| called whenever an 11d scan is done |
| \param hHal - The handle returned by mac_open. |
| \param callback - 11d scan complete routine to be registered |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_register11d_scan_done_callback(tHalHandle hHal, |
| csr_scan_completeCallback callback) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pMac->scan.callback11dScanDone = callback; |
| |
| return status; |
| } |
| |
| /** |
| * sme_deregister11d_scan_done_callback() - De-register scandone callback |
| * @h_hal: Handler return by mac_open |
| * |
| * This function De-registers the scandone callback to SME |
| * |
| * Return: None |
| */ |
| void sme_deregister11d_scan_done_callback(tHalHandle h_hal) |
| { |
| tpAniSirGlobal pmac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return; |
| } |
| |
| pmac = PMAC_STRUCT(h_hal); |
| pmac->scan.callback11dScanDone = NULL; |
| } |
| |
| |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| /** |
| * sme_register_oem_data_rsp_callback() - Register a routine of |
| * type send_oem_data_rsp_msg |
| * @h_hal: Handle returned by mac_open. |
| * @callback: Callback to send response |
| * to oem application. |
| * |
| * sme_oem_data_rsp_callback is used to register sme_send_oem_data_rsp_msg |
| * callback function. |
| * |
| * Return: QDF_STATUS. |
| */ |
| QDF_STATUS sme_register_oem_data_rsp_callback(tHalHandle h_hal, |
| sme_send_oem_data_rsp_msg callback) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pmac = PMAC_STRUCT(h_hal); |
| |
| pmac->sme.oem_data_rsp_callback = callback; |
| |
| return status; |
| |
| } |
| |
| /** |
| * sme_deregister_oem_data_rsp_callback() - De-register OEM datarsp callback |
| * @h_hal: Handler return by mac_open |
| * This function De-registers the OEM data response callback to SME |
| * |
| * Return: None |
| */ |
| void sme_deregister_oem_data_rsp_callback(tHalHandle h_hal) |
| { |
| tpAniSirGlobal pmac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return; |
| } |
| pmac = PMAC_STRUCT(h_hal); |
| |
| pmac->sme.oem_data_rsp_callback = NULL; |
| } |
| #endif |
| |
| /** |
| * sme_oem_update_capability() - update UMAC's oem related capability. |
| * @hal: Handle returned by mac_open |
| * @oem_cap: pointer to oem_capability |
| * |
| * This function updates OEM capability to UMAC. Currently RTT |
| * related capabilities are updated. More capabilities can be |
| * added in future. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_oem_update_capability(tHalHandle hal, |
| struct sme_oem_capability *cap) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| uint8_t *bytes; |
| |
| bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability; |
| |
| if (cap->ftm_rr) |
| bytes[4] |= RM_CAP_FTM_RANGE_REPORT; |
| if (cap->lci_capability) |
| bytes[4] |= RM_CAP_CIVIC_LOC_MEASUREMENT; |
| |
| return status; |
| } |
| |
| /** |
| * sme_oem_get_capability() - get oem capability |
| * @hal: Handle returned by mac_open |
| * @oem_cap: pointer to oem_capability |
| * |
| * This function is used to get the OEM capability from UMAC. |
| * Currently RTT related capabilities are received. More |
| * capabilities can be added in future. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_oem_get_capability(tHalHandle hal, |
| struct sme_oem_capability *cap) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| uint8_t *bytes; |
| |
| bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability; |
| |
| cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT; |
| cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT; |
| |
| return status; |
| } |
| |
| /** |
| * sme_register_ftm_msg_processor() - registers hdd ftm message processor |
| * function to MAC/SYS |
| * |
| * @hal: hal handle |
| * @callback: hdd function that has to be registered |
| * |
| * Return: void |
| */ |
| void sme_register_ftm_msg_processor(tHalHandle hal, |
| hdd_ftm_msg_processor callback) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| if (mac_ctx == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("mac ctx is NULL")); |
| return; |
| } |
| |
| mac_ctx->ftm_msg_processor_callback = callback; |
| return; |
| } |
| |
| /** |
| * sme_wow_add_pattern() - add a wow pattern in fw |
| * @hHal: handle returned by mac_open |
| * @pattern: pointer to input pattern |
| * |
| * Add a pattern for Pattern Byte Matching in WoW mode. Firmware will |
| * do a pattern match on these patterns when WoW is enabled during system |
| * suspend. |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_wow_add_pattern(tHalHandle hal, |
| struct wow_add_pattern *pattern, |
| uint8_t session_id) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| struct wow_add_pattern *ptrn; |
| tSirRetStatus ret_code = eSIR_SUCCESS; |
| tSirMsgQ msg_q; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, session_id, |
| 0)); |
| ptrn = qdf_mem_malloc(sizeof(*ptrn)); |
| if (NULL == ptrn) { |
| sms_log(pMac, LOGP, |
| FL("Fail to allocate memory for WoWLAN Add Bcast Pattern ")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| (void)qdf_mem_copy(ptrn, pattern, sizeof(*ptrn)); |
| |
| msg_q.type = WMA_WOW_ADD_PTRN; |
| msg_q.reserved = 0; |
| msg_q.bodyptr = ptrn; |
| msg_q.bodyval = 0; |
| |
| sms_log(pMac, LOG1, FL("Sending WMA_WOWL_ADD_BCAST_PTRN to HAL")); |
| ret_code = wma_post_ctrl_msg(pMac, &msg_q); |
| if (eSIR_SUCCESS != ret_code) { |
| sms_log(pMac, LOGE, |
| FL("Posting WMA_WOWL_ADD_BCAST_PTRN failed, reason=%X"), |
| ret_code); |
| } |
| return ret_code; |
| } |
| |
| /** |
| * sme_wow_delete_pattern() - delete user configured wow pattern in target |
| * @hHal: handle returned by mac_open. |
| * @pattern: pointer to delete pattern parameter |
| * @sessionId: session id |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_wow_delete_pattern(tHalHandle hal, |
| struct wow_delete_pattern *pattern, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| struct wow_delete_pattern *delete_ptrn; |
| tSirRetStatus ret_code = eSIR_SUCCESS; |
| tSirMsgQ msg_q; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId, |
| 0)); |
| delete_ptrn = qdf_mem_malloc(sizeof(*delete_ptrn)); |
| if (NULL == delete_ptrn) { |
| sms_log(pMac, LOGP, |
| FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern ")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| (void)qdf_mem_copy(delete_ptrn, pattern, sizeof(*delete_ptrn)); |
| msg_q.type = WMA_WOW_DEL_PTRN; |
| msg_q.reserved = 0; |
| msg_q.bodyptr = delete_ptrn; |
| msg_q.bodyval = 0; |
| |
| sms_log(pMac, LOG1, FL("Sending WMA_WOWL_DEL_BCAST_PTRN")); |
| |
| ret_code = wma_post_ctrl_msg(pMac, &msg_q); |
| if (eSIR_SUCCESS != ret_code) { |
| sms_log(pMac, LOGE, |
| FL("Posting WMA_WOWL_DEL_BCAST_PTRN failed, reason=%X"), |
| ret_code); |
| } |
| return ret_code; |
| } |
| |
| /** |
| * sme_enter_wowl(): SME API exposed to HDD to request enabling of WOWL mode. |
| * @hal_ctx - The handle returned by mac_open. |
| * @enter_wowl_callback_routine - Callback routine provided by HDD. |
| * Used for success/failure notification by SME |
| * @enter_wowl_callback_context - A cookie passed by HDD, that is passed |
| * back to HDD at the time of callback. |
| * @wake_reason_ind_cb - Callback routine provided by HDD. |
| * Used for Wake Reason Indication by SME |
| * @wake_reason_ind_cb_ctx - A cookie passed by HDD, that is passed |
| * back to HDD at the time of callback. |
| * |
| * WoWLAN works on top of BMPS mode. |
| * If the device is not in BMPS mode, |
| * SME will will cache the information that |
| * WOWL has been enabled and attempt to put the device |
| * in BMPS. On entry into BMPS, SME will enable the |
| * WOWL mode. |
| * Note 1: If we exit BMPS mode (someone requests full power), |
| * we will NOT resume WOWL when we go back to BMPS again. |
| * Request for full power (while in WOWL mode) means disable |
| * WOWL and go to full power. |
| * Note 2: Both UAPSD and WOWL work on top of BMPS. |
| * On entry into BMPS, SME will give priority to UAPSD and |
| * enable only UAPSD if both UAPSD and WOWL are required. |
| * Currently there is no requirement or use case to support |
| * UAPSD and WOWL at the same time. |
| * |
| * Return: QDF_STATUS |
| * QDF_STATUS_SUCCESS Device is already in WoWLAN mode |
| * QDF_STATUS_E_FAILURE Device cannot enter WoWLAN mode. |
| * QDF_STATUS_PMC_PENDING Request accepted. SME will enable |
| * WOWL after BMPS mode is entered. |
| */ |
| QDF_STATUS sme_enter_wowl(tHalHandle hal_ctx, |
| void (*enter_wowl_callback_routine)(void |
| *callback_context, |
| QDF_STATUS status), |
| void *enter_wowl_callback_context, |
| #ifdef WLAN_WAKEUP_EVENTS |
| void (*wakeIndicationCB)(void *callback_context, |
| tpSirWakeReasonInd |
| wake_reason_ind), |
| void *wakeIndicationCBContext, |
| #endif /* WLAN_WAKEUP_EVENTS */ |
| tpSirSmeWowlEnterParams wowl_enter_params, |
| uint8_t session_id) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx); |
| struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ENTER_WOWL, session_id, 0)); |
| |
| /* cache the WOWL information */ |
| ps_global_info->ps_params[session_id].wowl_enter_params = |
| *wowl_enter_params; |
| ps_global_info->ps_params[session_id].enter_wowl_callback_routine = |
| enter_wowl_callback_routine; |
| ps_global_info->ps_params[session_id].enter_wowl_callback_context = |
| enter_wowl_callback_context; |
| #ifdef WLAN_WAKEUP_EVENTS |
| /* Cache the Wake Reason Indication callback information */ |
| ps_global_info->ps_params[session_id].wake_reason_ind_cb = |
| wakeIndicationCB; |
| ps_global_info->ps_params[session_id].wake_reason_ind_cb_ctx = |
| wakeIndicationCBContext; |
| #endif /* WLAN_WAKEUP_EVENTS */ |
| |
| status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_ENTER); |
| return status; |
| } |
| /** |
| *sme_exit_wowl(): SME API exposed to HDD to request exit from WoWLAN mode. |
| * @hal_ctx - The handle returned by mac_open. |
| * @wowl_exit_params - Carries info on which smesession |
| * wowl exit is requested. |
| * |
| * SME will initiate exit from WoWLAN mode and device will be |
| * put in BMPS mode. |
| * Return QDF_STATUS |
| * QDF_STATUS_E_FAILURE Device cannot exit WoWLAN mode. |
| * QDF_STATUS_SUCCESS Request accepted to exit WoWLAN mode. |
| */ |
| QDF_STATUS sme_exit_wowl(tHalHandle hal_ctx, |
| tpSirSmeWowlExitParams wowl_exit_params) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx); |
| uint8_t session_id; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0)); |
| session_id = wowl_exit_params->sessionId; |
| status = sme_ps_process_command(mac_ctx, session_id, SME_PS_WOWL_EXIT); |
| return status; |
| } |
| |
| /** |
| * sme_roam_set_key() - To set encryption key. |
| * @hal: hal global context |
| * @session_id: session id |
| * @set_key: pointer to a caller allocated object of tCsrSetContextInfo |
| * @ptr_roam_id: Upon success return, this is the id caller can use to |
| * identify the request in roamcallback |
| * |
| * This function should be called only when connected. This is an asynchronous |
| * API. |
| * |
| * Return: Status of operation |
| */ |
| QDF_STATUS sme_roam_set_key(tHalHandle hal, uint8_t session_id, |
| tCsrRoamSetKey *set_key, uint32_t *ptr_roam_id) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| uint32_t roam_id; |
| uint32_t i; |
| tCsrRoamSession *session = NULL; |
| struct ps_global_info *ps_global_info = &mac_ctx->sme.ps_global_info; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_KEY, |
| session_id, 0)); |
| if (set_key->keyLength > CSR_MAX_KEY_LEN) { |
| sms_log(mac_ctx, LOGE, FL("Invalid key length %d"), |
| set_key->keyLength); |
| return QDF_STATUS_E_FAILURE; |
| } |
| /*Once Setkey is done, we can go in BMPS */ |
| if (set_key->keyLength) |
| ps_global_info->remain_in_power_active_till_dhcp = false; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| roam_id = GET_NEXT_ROAM_ID(&mac_ctx->roam); |
| if (ptr_roam_id) |
| *ptr_roam_id = roam_id; |
| |
| sms_log(mac_ctx, LOG2, FL("keyLength %d"), set_key->keyLength); |
| for (i = 0; i < set_key->keyLength; i++) |
| sms_log(mac_ctx, LOG2, FL("%02x"), set_key->Key[i]); |
| |
| sms_log(mac_ctx, LOG2, "\n session_id=%d roam_id=%d", session_id, |
| roam_id); |
| session = CSR_GET_SESSION(mac_ctx, session_id); |
| if (!session) { |
| sms_log(mac_ctx, LOGE, FL("session %d not found"), session_id); |
| sme_release_global_lock(&mac_ctx->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (CSR_IS_INFRA_AP(&session->connectedProfile) |
| && set_key->keyDirection == eSIR_TX_DEFAULT) { |
| if ((eCSR_ENCRYPT_TYPE_WEP40 == set_key->encType) |
| || (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == |
| set_key->encType)) { |
| session->pCurRoamProfile->negotiatedUCEncryptionType = |
| eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; |
| } |
| if ((eCSR_ENCRYPT_TYPE_WEP104 == set_key->encType) |
| || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == |
| set_key->encType)) { |
| session->pCurRoamProfile->negotiatedUCEncryptionType = |
| eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; |
| } |
| } |
| status = csr_roam_set_key(mac_ctx, session_id, set_key, roam_id); |
| sme_release_global_lock(&mac_ctx->sme); |
| return status; |
| } |
| |
| /** |
| * sme_roam_set_default_key_index - To set default wep key idx |
| * @hal: pointer to hal handler |
| * @session_id: session id |
| * @default_idx: default wep key index |
| * |
| * This function prepares a message and post to WMA to set wep default |
| * key index |
| * |
| * Return: Success:QDF_STATUS_SUCCESS Failure: Error value |
| */ |
| QDF_STATUS sme_roam_set_default_key_index(tHalHandle hal, uint8_t session_id, |
| uint8_t default_idx) |
| { |
| cds_msg_t msg; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct wep_update_default_key_idx *update_key; |
| |
| update_key = qdf_mem_malloc(sizeof(*update_key)); |
| if (!update_key) { |
| sms_log(mac_ctx, LOGE, |
| FL("Failed to allocate memory for update key")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| update_key->session_id = session_id; |
| update_key->default_idx = default_idx; |
| |
| msg.type = WMA_UPDATE_WEP_DEFAULT_KEY; |
| msg.reserved = 0; |
| msg.bodyptr = (void *)update_key; |
| |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| sms_log(mac_ctx, LOGE, |
| FL("Failed to post WMA_UPDATE_WEP_DEFAULT_KEY to WMA")); |
| qdf_mem_free(update_key); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_rssi |
| \brief a wrapper function that client calls to register a callback to get |
| RSSI |
| |
| \param hHal - HAL handle for device |
| \param callback - SME sends back the requested stats using the callback |
| \param staId - The station ID for which the stats is requested for |
| \param bssid - The bssid of the connected session |
| \param lastRSSI - RSSI value at time of request. In case fw cannot provide |
| RSSI, do not hold up but return this value. |
| \param pContext - user context to be passed back along with the callback |
| \param p_cds_context - cds context |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_rssi(tHalHandle hHal, |
| tCsrRssiCallback callback, |
| uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI, |
| void *pContext, void *p_cds_context) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_RSSI, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_get_rssi(pMac, callback, |
| staId, bssId, lastRSSI, |
| pContext, p_cds_context); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_snr |
| \brief a wrapper function that client calls to register a callback to |
| get SNR |
| |
| \param callback - SME sends back the requested stats using the callback |
| \param staId - The station ID for which the stats is requested for |
| \param pContext - user context to be passed back along with the callback |
| \param p_cds_context - cds context |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_snr(tHalHandle hHal, |
| tCsrSnrCallback callback, |
| uint8_t staId, struct qdf_mac_addr bssId, void *pContext) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_get_snr(pMac, callback, staId, bssId, pContext); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_statistics |
| \brief a wrapper function that client calls to register a callback to get |
| different PHY level statistics from CSR. |
| |
| \param requesterId - different client requesting for statistics, |
| HDD, UMA/GAN etc |
| \param statsMask - The different category/categories of stats requester |
| is looking for |
| \param callback - SME sends back the requested stats using the callback |
| \param periodicity - If requester needs periodic update in millisec, 0 means |
| it's an one time request |
| \param cache - If requester is happy with cached stats |
| \param staId - The station ID for which the stats is requested for |
| \param pContext - user context to be passed back along with the callback |
| \param sessionId - sme session interface |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_statistics(tHalHandle hHal, |
| eCsrStatsRequesterType requesterId, |
| uint32_t statsMask, tCsrStatsCallback callback, |
| uint32_t periodicity, bool cache, uint8_t staId, |
| void *pContext, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION, |
| periodicity)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = |
| csr_get_statistics(pMac, requesterId, statsMask, callback, |
| periodicity, cache, staId, pContext, |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| QDF_STATUS sme_get_link_status(tHalHandle hHal, |
| tCsrLinkStatusCallback callback, |
| void *pContext, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tAniGetLinkStatus *pMsg; |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMsg = qdf_mem_malloc(sizeof(tAniGetLinkStatus)); |
| if (NULL == pMsg) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for link status", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMsg->msgType = WMA_LINK_STATUS_GET_REQ; |
| pMsg->msgLen = (uint16_t) sizeof(tAniGetLinkStatus); |
| pMsg->sessionId = sessionId; |
| pMac->sme.linkStatusContext = pContext; |
| pMac->sme.linkStatusCallback = callback; |
| |
| cds_message.type = WMA_LINK_STATUS_GET_REQ; |
| cds_message.bodyptr = pMsg; |
| cds_message.reserved = 0; |
| |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_message))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post LINK STATUS MSG fail", __func__); |
| qdf_mem_free(pMsg); |
| pMac->sme.linkStatusContext = NULL; |
| pMac->sme.linkStatusCallback = NULL; |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_get_country_code |
| |
| \brief To return the current country code. If no country code is applied, |
| default country code is used to fill the buffer. |
| If 11d supported is turned off, an error is return and the last |
| applied/default country code is used. |
| This is a synchronous API. |
| |
| \param pBuf - pointer to a caller allocated buffer for returned country code. |
| |
| \param pbLen For input, this parameter indicates how big is the buffer. |
| Upon return, this parameter has the number of bytes for |
| country. If pBuf doesn't have enough space, this function |
| returns fail status and this parameter contains the number |
| that is needed. |
| |
| \return QDF_STATUS SUCCESS. |
| |
| FAILURE or RESOURCES The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_country_code(tHalHandle hHal, uint8_t *pBuf, uint8_t *pbLen) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0)); |
| |
| return csr_get_country_code(pMac, pBuf, pbLen); |
| } |
| |
| /** |
| * sme_apply_channel_power_info_to_fw() - sends channel info to fw |
| * @hHal: hal handle |
| * |
| * This function sends the channel power info to firmware |
| * |
| * Return: none |
| */ |
| void sme_apply_channel_power_info_to_fw(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| csr_apply_channel_power_info_wrapper(pMac); |
| } |
| |
| /* some support functions */ |
| bool sme_is11d_supported(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| return csr_is11d_supported(pMac); |
| } |
| |
| bool sme_is11h_supported(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| return csr_is11h_supported(pMac); |
| } |
| |
| bool sme_is_wmm_supported(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| return csr_is_wmm_supported(pMac); |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_change_country_code |
| |
| \brief Change Country code from upperlayer during WLAN driver operation. |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \param pCountry New Country Code String |
| |
| \param sendRegHint If we want to send reg hint to nl80211 |
| |
| \return QDF_STATUS SUCCESS. |
| |
| FAILURE or RESOURCES The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_change_country_code(tHalHandle hHal, |
| tSmeChangeCountryCallback callback, |
| uint8_t *pCountry, |
| void *pContext, |
| void *p_cds_context, |
| tAniBool countryFromUserSpace, |
| tAniBool sendRegHint) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg; |
| tAniChangeCountryCodeReq *pMsg; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOG1, FL(" called")); |
| |
| if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true) |
| && (!pMac->roam.configParam. |
| fSupplicantCountryCodeHasPriority)) { |
| |
| sms_log(pMac, LOGW, |
| "Set Country Code Fail since the STA is associated and userspace does not have priority "); |
| |
| sme_release_global_lock(&pMac->sme); |
| status = QDF_STATUS_E_FAILURE; |
| return status; |
| } |
| |
| pMsg = qdf_mem_malloc(sizeof(tAniChangeCountryCodeReq)); |
| if (NULL == pMsg) { |
| sms_log(pMac, LOGE, |
| " csrChangeCountryCode: failed to allocate mem for req"); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMsg->msgType = eWNI_SME_CHANGE_COUNTRY_CODE; |
| pMsg->msgLen = (uint16_t) sizeof(tAniChangeCountryCodeReq); |
| qdf_mem_copy(pMsg->countryCode, pCountry, 3); |
| pMsg->countryFromUserSpace = countryFromUserSpace; |
| pMsg->sendRegHint = sendRegHint; |
| pMsg->changeCCCallback = callback; |
| pMsg->pDevContext = pContext; |
| pMsg->p_cds_context = p_cds_context; |
| |
| msg.type = eWNI_SME_CHANGE_COUNTRY_CODE; |
| msg.bodyptr = pMsg; |
| msg.reserved = 0; |
| |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(CDS_MQ_ID_SME, &msg)) { |
| sms_log(pMac, LOGE, |
| " sme_change_country_code failed to post msg to self "); |
| qdf_mem_free((void *)pMsg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sms_log(pMac, LOG1, FL(" returned")); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \fn sme_generic_change_country_code |
| |
| \brief Change Country code from upperlayer during WLAN driver operation. |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \param pCountry New Country Code String |
| |
| \param reg_domain regulatory domain |
| |
| \return QDF_STATUS SUCCESS. |
| |
| FAILURE or RESOURCES The API finished and failed. |
| |
| -----------------------------------------------------------------------------*/ |
| QDF_STATUS sme_generic_change_country_code(tHalHandle hHal, |
| uint8_t *pCountry) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg; |
| tAniGenericChangeCountryCodeReq *pMsg; |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return status; |
| } |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOG1, FL(" called")); |
| pMsg = qdf_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq)); |
| |
| if (NULL == pMsg) { |
| sms_log(pMac, LOGE, |
| " sme_generic_change_country_code: failed to allocate mem for req"); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMsg->msgType = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; |
| pMsg->msgLen = |
| (uint16_t) sizeof(tAniGenericChangeCountryCodeReq); |
| qdf_mem_copy(pMsg->countryCode, pCountry, 2); |
| pMsg->countryCode[2] = ' '; |
| |
| msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; |
| msg.bodyptr = pMsg; |
| msg.reserved = 0; |
| |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(CDS_MQ_ID_SME, &msg)) { |
| sms_log(pMac, LOGE, |
| "sme_generic_change_country_code failed to post msg to self"); |
| qdf_mem_free(pMsg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sms_log(pMac, LOG1, FL(" returned")); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_dhcp_start_ind |
| |
| \brief API to signal the FW about the DHCP Start event. |
| |
| \param hHal - HAL handle for device. |
| |
| \param device_mode - mode(AP,SAP etc) of the device. |
| |
| \param macAddr - MAC address of the adapter. |
| |
| \param sessionId - session ID. |
| |
| \return QDF_STATUS SUCCESS. |
| |
| FAILURE or RESOURCES The API finished and failed. |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal, |
| uint8_t device_mode, |
| uint8_t *macAddr, uint8_t sessionId) |
| { |
| QDF_STATUS status; |
| QDF_STATUS qdf_status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tAniDHCPInd *pMsg; |
| tCsrRoamSession *pSession; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (!pSession) { |
| sms_log(pMac, LOGE, FL("session %d not found "), |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd)); |
| if (NULL == pMsg) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for dhcp start", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| pMsg->msgType = WMA_DHCP_START_IND; |
| pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd); |
| pMsg->device_mode = device_mode; |
| qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr, |
| QDF_MAC_ADDR_SIZE); |
| qdf_copy_macaddr(&pMsg->peerMacAddr, |
| &pSession->connectedProfile.bssid); |
| |
| cds_message.type = WMA_DHCP_START_IND; |
| cds_message.bodyptr = pMsg; |
| cds_message.reserved = 0; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post DHCP Start MSG fail", __func__); |
| qdf_mem_free(pMsg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_dhcp_stop_ind |
| |
| \brief API to signal the FW about the DHCP complete event. |
| |
| \param hHal - HAL handle for device. |
| |
| \param device_mode - mode(AP, SAP etc) of the device. |
| |
| \param macAddr - MAC address of the adapter. |
| |
| \param sessionId - session ID. |
| |
| \return QDF_STATUS SUCCESS. |
| FAILURE or RESOURCES The API finished and failed. |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal, |
| uint8_t device_mode, |
| uint8_t *macAddr, uint8_t sessionId) |
| { |
| QDF_STATUS status; |
| QDF_STATUS qdf_status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tAniDHCPInd *pMsg; |
| tCsrRoamSession *pSession; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (!pSession) { |
| sms_log(pMac, LOGE, FL("session %d not found "), |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd)); |
| if (NULL == pMsg) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for dhcp stop", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMsg->msgType = WMA_DHCP_STOP_IND; |
| pMsg->msgLen = (uint16_t) sizeof(tAniDHCPInd); |
| pMsg->device_mode = device_mode; |
| qdf_mem_copy(pMsg->adapterMacAddr.bytes, macAddr, |
| QDF_MAC_ADDR_SIZE); |
| qdf_copy_macaddr(&pMsg->peerMacAddr, |
| &pSession->connectedProfile.bssid); |
| |
| cds_message.type = WMA_DHCP_STOP_IND; |
| cds_message.bodyptr = pMsg; |
| cds_message.reserved = 0; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post DHCP Stop MSG fail", __func__); |
| qdf_mem_free(pMsg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*--------------------------------------------------------------------------- |
| |
| \fn sme_TXFailMonitorStopInd |
| |
| \brief API to signal the FW to start monitoring TX failures |
| |
| \return QDF_STATUS SUCCESS. |
| |
| FAILURE or RESOURCES The API finished and failed. |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal, uint8_t tx_fail_count, |
| void *txFailIndCallback) |
| { |
| QDF_STATUS status; |
| QDF_STATUS qdf_status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tAniTXFailMonitorInd *pMsg; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pMsg = (tAniTXFailMonitorInd *) |
| qdf_mem_malloc(sizeof(tAniTXFailMonitorInd)); |
| if (NULL == pMsg) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Failed to allocate memory", __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMsg->msgType = WMA_TX_FAIL_MONITOR_IND; |
| pMsg->msgLen = (uint16_t) sizeof(tAniTXFailMonitorInd); |
| |
| /* tx_fail_count = 0 should disable the Monitoring in FW */ |
| pMsg->tx_fail_count = tx_fail_count; |
| pMsg->txFailIndCallback = txFailIndCallback; |
| |
| cds_message.type = WMA_TX_FAIL_MONITOR_IND; |
| cds_message.bodyptr = pMsg; |
| cds_message.reserved = 0; |
| |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post TX Fail monitor Start MSG fail", |
| __func__); |
| qdf_mem_free(pMsg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_cfg_privacy |
| \brief API to set configure privacy parameters |
| \param hHal - The handle returned by mac_open. |
| \param pProfile - Pointer CSR Roam profile. |
| \param fPrivacy - This parameter indicates status of privacy |
| |
| \return void |
| ---------------------------------------------------------------------------*/ |
| void sme_set_cfg_privacy(tHalHandle hHal, |
| tCsrRoamProfile *pProfile, bool fPrivacy) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0)); |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| csr_set_cfg_privacy(pMac, pProfile, fPrivacy); |
| sme_release_global_lock(&pMac->sme); |
| } |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_neighbor_report_request |
| \brief API to request neighbor report. |
| \param hHal - The handle returned by mac_open. |
| \param pRrmNeighborReq - Pointer to a caller allocated object of type |
| tRrmNeighborReq. Caller owns the memory and is |
| responsible for freeing it. |
| \return QDF_STATUS |
| QDF_STATUS_E_FAILURE - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_neighbor_report_request(tHalHandle hHal, uint8_t sessionId, |
| tpRrmNeighborReq pRrmNeighborReq, |
| tpRrmNeighborRspCallbackInfo callbackInfo) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION, |
| 0)); |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| status = |
| sme_rrm_neighbor_report_request(hHal, sessionId, |
| pRrmNeighborReq, callbackInfo); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| void sms_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...) |
| { |
| #ifdef WLAN_DEBUG |
| /* Verify against current log level */ |
| if (loglevel > |
| pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_SMS_MODULE_ID)]) |
| return; |
| else { |
| va_list marker; |
| |
| va_start(marker, pString); /* Initialize variable arguments. */ |
| |
| log_debug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker); |
| |
| va_end(marker); /* Reset variable arguments. */ |
| } |
| #endif |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_wcnss_wlan_compiled_version |
| \brief This API returns the version of the WCNSS WLAN API with |
| which the HOST driver was built |
| \param hHal - The handle returned by mac_open. |
| \param pVersion - Points to the Version structure to be filled |
| \return QDF_STATUS |
| QDF_STATUS_E_INVAL - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_wcnss_wlan_compiled_version(tHalHandle hHal, |
| tSirVersionType *pVersion) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| if (pVersion != NULL) |
| status = QDF_STATUS_SUCCESS; |
| else |
| status = QDF_STATUS_E_INVAL; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_wcnss_wlan_reported_version |
| \brief This API returns the version of the WCNSS WLAN API with |
| which the WCNSS driver reports it was built |
| \param hHal - The handle returned by mac_open. |
| \param pVersion - Points to the Version structure to be filled |
| \return QDF_STATUS |
| QDF_STATUS_E_INVAL - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_wcnss_wlan_reported_version(tHalHandle hHal, |
| tSirVersionType *pVersion) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| if (pVersion != NULL) |
| status = QDF_STATUS_SUCCESS; |
| else |
| status = QDF_STATUS_E_INVAL; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_wcnss_software_version |
| \brief This API returns the version string of the WCNSS driver |
| \param hHal - The handle returned by mac_open. |
| \param pVersion - Points to the Version string buffer to be filled |
| \param versionBufferSize - THe size of the Version string buffer |
| \return QDF_STATUS |
| QDF_STATUS_E_INVAL - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_wcnss_software_version(tHalHandle hHal, |
| uint8_t *pVersion, |
| uint32_t versionBufferSize) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| v_CONTEXT_t cds_context = cds_get_global_context(); |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| if (pVersion != NULL) { |
| status = |
| wma_get_wcnss_software_version(cds_context, |
| pVersion, |
| versionBufferSize); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_wcnss_hardware_version |
| \brief This API returns the version string of the WCNSS hardware |
| \param hHal - The handle returned by mac_open. |
| \param pVersion - Points to the Version string buffer to be filled |
| \param versionBufferSize - THe size of the Version string buffer |
| \return QDF_STATUS |
| QDF_STATUS_E_INVAL - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_wcnss_hardware_version(tHalHandle hHal, |
| uint8_t *pVersion, |
| uint32_t versionBufferSize) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| if (pVersion != NULL) |
| status = QDF_STATUS_SUCCESS; |
| else |
| status = QDF_STATUS_E_INVAL; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| #ifdef FEATURE_WLAN_WAPI |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_scan_get_bkid_candidate_list |
| \brief a wrapper function to return the BKID candidate list |
| \param pBkidList - caller allocated buffer point to an array of |
| tBkidCandidateInfo |
| \param pNumItems - pointer to a variable that has the number of |
| tBkidCandidateInfo allocated when retruning, this is |
| either the number needed or number of items put into |
| pPmkidList |
| \return QDF_STATUS - when fail, it usually means the buffer allocated is not |
| big enough and pNumItems |
| has the number of tBkidCandidateInfo. |
| \Note: pNumItems is a number of tBkidCandidateInfo, |
| not sizeof(tBkidCandidateInfo) * something |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_scan_get_bkid_candidate_list(tHalHandle hHal, uint32_t sessionId, |
| tBkidCandidateInfo *pBkidList, |
| uint32_t *pNumItems) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = |
| csr_scan_get_bkid_candidate_list(pMac, sessionId, pBkidList, |
| pNumItems); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| #endif /* FEATURE_WLAN_WAPI */ |
| |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| /** |
| * sme_oem_data_req() - send oem data request to WMA |
| * @hal: HAL handle |
| * @hdd_oem_req: OEM data request from HDD |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_oem_data_req(tHalHandle hal, struct oem_data_req *hdd_oem_req) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct oem_data_req *oem_data_req; |
| void *wma_handle; |
| |
| sms_log(mac_ctx, LOG1, FL("enter")); |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| sms_log(mac_ctx, LOGE, FL("wma_handle is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| oem_data_req = qdf_mem_malloc(sizeof(*oem_data_req)); |
| if (!oem_data_req) { |
| sms_log(mac_ctx, LOGE, FL("mem alloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| oem_data_req->data_len = hdd_oem_req->data_len; |
| oem_data_req->data = qdf_mem_malloc(oem_data_req->data_len); |
| if (!oem_data_req->data) { |
| sms_log(mac_ctx, LOGE, FL("mem alloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_copy(oem_data_req->data, hdd_oem_req->data, |
| oem_data_req->data_len); |
| |
| status = wma_start_oem_data_req(wma_handle, oem_data_req); |
| |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac_ctx, LOGE, FL("Post oem data request msg fail")); |
| } else { |
| sms_log(mac_ctx, LOG1, |
| FL("OEM request(length: %d) sent to WMA"), |
| oem_data_req->data_len); |
| } |
| |
| if (oem_data_req->data_len) |
| qdf_mem_free(oem_data_req->data); |
| qdf_mem_free(oem_data_req); |
| |
| sms_log(mac_ctx, LOG1, FL("exit")); |
| return status; |
| } |
| #endif /*FEATURE_OEM_DATA_SUPPORT */ |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_open_session() - Open a session for scan/roam operation. |
| |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| \param callback - A pointer to the function caller specifies for |
| roam/connect status indication |
| \param pContext - The context passed with callback |
| \param pSelfMacAddr - Caller allocated memory filled with self MAC address |
| (6 bytes) |
| \param pbSessionId - pointer to a caller allocated buffer for returned session ID |
| |
| \return QDF_STATUS_SUCCESS - session is opened. sessionId returned. |
| |
| Other status means SME is failed to open the session. |
| QDF_STATUS_E_RESOURCES - no more session available. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_open_session(tHalHandle hHal, csr_roam_completeCallback callback, |
| void *pContext, |
| uint8_t *pSelfMacAddr, uint8_t *pbSessionId, |
| uint32_t type, uint32_t subType) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, |
| "%s: type=%d, subType=%d addr:%pM", |
| __func__, type, subType, pSelfMacAddr); |
| |
| if (NULL == pbSessionId) { |
| status = QDF_STATUS_E_INVAL; |
| } else { |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_open_session(pMac, callback, pContext, |
| pSelfMacAddr, |
| pbSessionId, type, |
| subType); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| } |
| if (NULL != pbSessionId) |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_OPEN_SESSION, |
| *pbSessionId, 0)); |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_close_session() - Open a session for scan/roam operation. |
| |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \param sessionId - A previous opened session's ID. |
| |
| \return QDF_STATUS_SUCCESS - session is closed. |
| |
| Other status means SME is failed to open the session. |
| QDF_STATUS_E_INVAL - session is not opened. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_close_session(tHalHandle hHal, uint8_t sessionId, |
| csr_roamSessionCloseCallback callback, |
| void *pContext) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_close_session(pMac, sessionId, false, |
| callback, pContext); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_roam_update_apwpsie |
| |
| \brief To update AP's WPS IE. This function should be called after SME AP session is created |
| This is an asynchronous API. |
| |
| \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs |
| |
| \return QDF_STATUS – SUCCESS – |
| |
| FAILURE or RESOURCES – The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_update_apwpsie(tHalHandle hHal, uint8_t sessionId, |
| tSirAPWPSIEs *pAPWPSIES) |
| { |
| |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| status = csr_roam_update_apwpsie(pMac, sessionId, pAPWPSIES); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_roam_update_apwparsni_es |
| |
| \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created |
| This is an asynchronous API. |
| |
| \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs |
| |
| \return QDF_STATUS – SUCCESS – |
| |
| FAILURE or RESOURCES – The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_update_apwparsni_es(tHalHandle hHal, uint8_t sessionId, |
| tSirRSNie *pAPSirRSNie) |
| { |
| |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| status = csr_roam_update_wparsni_es(pMac, sessionId, pAPSirRSNie); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_change_mcc_beacon_interval |
| |
| \brief To update P2P-GO beaconInterval. This function should be called after |
| disassociating all the station is done |
| This is an asynchronous API. |
| |
| \param |
| |
| \return QDF_STATUS SUCCESS |
| FAILURE or RESOURCES |
| The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_change_mcc_beacon_interval(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| sms_log(pMac, LOG1, FL("Update Beacon PARAMS ")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_send_chng_mcc_beacon_interval(pMac, sessionId); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_host_offload(): API to set the host offload feature. |
| * @hHal: The handle returned by mac_open. |
| * @sessionId: Session Identifier |
| * @request: Pointer to the offload request. |
| * |
| * Return QDF_STATUS |
| */ |
| QDF_STATUS sme_set_host_offload(tHalHandle hHal, uint8_t sessionId, |
| tpSirHostOffloadReq request) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| #ifdef WLAN_NS_OFFLOAD |
| if (SIR_IPV6_NS_OFFLOAD == request->offloadType) { |
| status = sme_set_ps_ns_offload(hHal, request, |
| sessionId); |
| } else |
| #endif /* WLAN_NS_OFFLOAD */ |
| { |
| status = sme_set_ps_host_offload(hHal, request, |
| sessionId); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_GTK_OFFLOAD |
| /** |
| * sme_set_gtk_offload(): API to set GTK offload information. |
| * @hHal: The handle returned by mac_open. |
| * @sessionId: Session Identifier |
| * @pGtkOffload: Pointer to the GTK offload request.. |
| * |
| * Return QDF_STATUS |
| */ |
| QDF_STATUS sme_set_gtk_offload(tHalHandle hHal, |
| tpSirGtkOffloadParams pGtkOffload, |
| uint8_t sessionId) |
| { |
| tpSirGtkOffloadParams request_buf; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO, |
| "%s: KeyReplayCounter: %lld", __func__, |
| pGtkOffload->ullKeyReplayCounter); |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Session not found ", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| request_buf = qdf_mem_malloc(sizeof(*request_buf)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for GTK offload request")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&pGtkOffload->bssid, |
| &pSession->connectedProfile.bssid); |
| |
| *request_buf = *pGtkOffload; |
| |
| msg.type = WMA_GTK_OFFLOAD_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, msg.type)); |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post SIR_HAL_SET_GTK_OFFLOAD message to HAL")); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_get_gtk_offload(): API to get GTK offload information |
| * @hHal: The handle returned by mac_open. |
| * @callback_routine: callback_routine. |
| * @sessionId: Session Identifier. |
| * callback_context: callback_context. |
| * |
| * Return QDF_STATUS |
| */ |
| QDF_STATUS sme_get_gtk_offload(tHalHandle hHal, |
| gtk_offload_get_info_callback callback_routine, |
| void *callback_context, uint8_t session_id) |
| { |
| tpSirGtkOffloadGetInfoRspParams request_buf; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: Entered", |
| __func__); |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Session not found", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| request_buf = qdf_mem_malloc(sizeof(*request_buf)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for Get GTK offload request")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&request_buf->bssid, |
| &pSession->connectedProfile.bssid); |
| |
| msg.type = WMA_GTK_OFFLOAD_GETINFO_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| |
| /* Cache the Get GTK Offload callback information */ |
| if (NULL != pMac->sme.gtk_offload_get_info_cb) { |
| |
| /* Do we need to check if the callback is in use? */ |
| /* Because we are not sending the same message again |
| * when it is pending, |
| * the only case when the callback is not NULL is that |
| * the previous message was timed out or failed. |
| * So, it will be safe to set the callback in this case. |
| */ |
| } |
| |
| pMac->sme.gtk_offload_get_info_cb = callback_routine; |
| pMac->sme.gtk_offload_get_info_cb_context = callback_context; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| session_id, msg.type)); |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_GTK_OFFLOAD_GETINFO_REQ message to WMA")); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* WLAN_FEATURE_GTK_OFFLOAD */ |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_keep_alive |
| \brief API to set the Keep Alive feature. |
| \param hHal - The handle returned by mac_open. |
| \param request - Pointer to the Keep Alive request. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_keep_alive(tHalHandle hHal, uint8_t session_id, |
| tpSirKeepAliveReq request) |
| { |
| tpSirKeepAliveReq request_buf; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_LOW, |
| FL("WMA_SET_KEEP_ALIVE message")); |
| |
| if (pSession == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Session not Found")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| request_buf = qdf_mem_malloc(sizeof(tSirKeepAliveReq)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for keep alive request")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&request->bssid, &pSession->connectedProfile.bssid); |
| qdf_mem_copy(request_buf, request, sizeof(tSirKeepAliveReq)); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_LOW, |
| "buff TP %d input TP %d ", request_buf->timePeriod, |
| request->timePeriod); |
| request_buf->sessionId = session_id; |
| |
| msg.type = WMA_SET_KEEP_ALIVE; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| session_id, msg.type)); |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_SET_KEEP_ALIVE message to WMA")); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef FEATURE_WLAN_SCAN_PNO |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_preferred_network_list |
| \brief API to set the Preferred Network List Offload feature. |
| \param hHal - The handle returned by mac_open. |
| \param request - Pointer to the offload request. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_preferred_network_list(tHalHandle hHal, |
| tpSirPNOScanReq request, |
| uint8_t sessionId, |
| void (*callback_routine)(void *callback_context, |
| tSirPrefNetworkFoundInd |
| *pPrefNetworkFoundInd), |
| void *callback_context) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_PREF_NET_LIST, |
| sessionId, request->ucNetworksCount)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sme_set_ps_preferred_network_list(hHal, request, sessionId, |
| callback_routine, callback_context); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| #endif /* FEATURE_WLAN_SCAN_PNO */ |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_abort_mac_scan |
| \brief API to cancel MAC scan. |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - sessionId on which we need to abort scan. |
| \param reason - Reason to abort the scan. |
| \return QDF_STATUS |
| QDF_STATUS_E_FAILURE - failure |
| QDF_STATUS_SUCCESS success |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId, |
| eCsrAbortReason reason) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_scan_abort_mac_scan(pMac, sessionId, reason); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| \fn sme_get_operation_channel |
| \brief API to get current channel on which STA is parked |
| this function gives channel information only of infra station or IBSS station |
| \param hHal, pointer to memory location and sessionId |
| \returns QDF_STATUS_SUCCESS |
| QDF_STATUS_E_FAILURE |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_operation_channel(tHalHandle hHal, uint32_t *pChannel, |
| uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession; |
| |
| if (CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if ((pSession->connectedProfile.BSSType == |
| eCSR_BSS_TYPE_INFRASTRUCTURE) |
| || (pSession->connectedProfile.BSSType == |
| eCSR_BSS_TYPE_IBSS) |
| || (pSession->connectedProfile.BSSType == |
| eCSR_BSS_TYPE_INFRA_AP) |
| || (pSession->connectedProfile.BSSType == |
| eCSR_BSS_TYPE_START_IBSS)) { |
| *pChannel = pSession->connectedProfile.operationChannel; |
| return QDF_STATUS_SUCCESS; |
| } |
| } |
| return QDF_STATUS_E_FAILURE; |
| } /* sme_get_operation_channel ends here */ |
| |
| /** |
| * sme_register_p2p_ack_ind_callback() - p2p ack indication callback |
| * @hal: hal pointer |
| * @callback: callback pointer to be registered |
| * |
| * This function is used to register a callback to PE for p2p ack |
| * indication |
| * |
| * Return: Success if msg is posted to PE else Failure. |
| */ |
| QDF_STATUS sme_register_p2p_ack_ind_callback(tHalHandle hal, |
| sir_p2p_ack_ind_callback callback) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct sir_sme_p2p_ack_ind_cb_req *msg; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| sms_log(mac_ctx, LOG1, FL(": ENTER")); |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| msg = qdf_mem_malloc(sizeof(*msg)); |
| if (NULL == msg) { |
| sms_log(mac_ctx, LOGE, |
| FL("Failed to allocate memory")); |
| sme_release_global_lock(&mac_ctx->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| qdf_mem_zero(msg, sizeof(*msg)); |
| msg->message_type = eWNI_SME_REGISTER_P2P_ACK_CB; |
| msg->length = sizeof(*msg); |
| |
| msg->callback = callback; |
| status = cds_send_mb_message_to_mac(msg); |
| sme_release_global_lock(&mac_ctx->sme); |
| return status; |
| } |
| return status; |
| } |
| |
| /** |
| * sme_register_mgmt_frame_ind_callback() - Register a callback for |
| * management frame indication to PE. |
| * |
| * @hal: hal pointer |
| * @callback: callback pointer to be registered |
| * |
| * This function is used to register a callback for management |
| * frame indication to PE. |
| * |
| * Return: Success if msg is posted to PE else Failure. |
| */ |
| QDF_STATUS sme_register_mgmt_frame_ind_callback(tHalHandle hal, |
| sir_mgmt_frame_ind_callback callback) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct sir_sme_mgmt_frame_cb_req *msg; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| sms_log(mac_ctx, LOG1, FL(": ENTER")); |
| |
| if (QDF_STATUS_SUCCESS == |
| sme_acquire_global_lock(&mac_ctx->sme)) { |
| msg = qdf_mem_malloc(sizeof(*msg)); |
| if (NULL == msg) { |
| sms_log(mac_ctx, LOGE, |
| FL("Not able to allocate memory for eWNI_SME_REGISTER_MGMT_FRAME_CB")); |
| sme_release_global_lock(&mac_ctx->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| qdf_mem_set(msg, sizeof(*msg), 0); |
| msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB; |
| msg->length = sizeof(*msg); |
| |
| msg->callback = callback; |
| status = cds_send_mb_message_to_mac(msg); |
| sme_release_global_lock(&mac_ctx->sme); |
| return status; |
| } |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_RegisterMgtFrame |
| |
| \brief To register managment frame of specified type and subtype. |
| \param frameType - type of the frame that needs to be passed to HDD. |
| \param matchData - data which needs to be matched before passing frame |
| to HDD. |
| \param matchDataLen - Length of matched data. |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_register_mgmt_frame(tHalHandle hHal, uint8_t sessionId, |
| uint16_t frameType, uint8_t *matchData, |
| uint16_t matchLen) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| tSirRegisterMgmtFrame *pMsg; |
| uint16_t len; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) { |
| sms_log(pMac, LOGE, FL(" session %d not found "), |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s Invalid Sessionid", __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| len = sizeof(tSirRegisterMgmtFrame) + matchLen; |
| |
| pMsg = qdf_mem_malloc(len); |
| if (NULL == pMsg) |
| status = QDF_STATUS_E_NOMEM; |
| else { |
| qdf_mem_set(pMsg, len, 0); |
| pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; |
| pMsg->length = len; |
| pMsg->sessionId = sessionId; |
| pMsg->registerFrame = true; |
| pMsg->frameType = frameType; |
| pMsg->matchLen = matchLen; |
| qdf_mem_copy(pMsg->matchData, matchData, matchLen); |
| status = cds_send_mb_message_to_mac(pMsg); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_DeregisterMgtFrame |
| |
| \brief To De-register managment frame of specified type and subtype. |
| \param frameType - type of the frame that needs to be passed to HDD. |
| \param matchData - data which needs to be matched before passing frame |
| to HDD. |
| \param matchDataLen - Length of matched data. |
| \return QDF_STATUS |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_deregister_mgmt_frame(tHalHandle hHal, uint8_t sessionId, |
| uint16_t frameType, uint8_t *matchData, |
| uint16_t matchLen) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| tSirRegisterMgmtFrame *pMsg; |
| uint16_t len; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (!CSR_IS_SESSION_ANY(sessionId) && !pSession) { |
| sms_log(pMac, LOGE, FL(" session %d not found "), |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!CSR_IS_SESSION_ANY(sessionId) && !pSession->sessionActive) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s Invalid Sessionid", __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| len = sizeof(tSirRegisterMgmtFrame) + matchLen; |
| |
| pMsg = qdf_mem_malloc(len); |
| if (NULL == pMsg) |
| status = QDF_STATUS_E_NOMEM; |
| else { |
| qdf_mem_set(pMsg, len, 0); |
| pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; |
| pMsg->length = len; |
| pMsg->registerFrame = false; |
| pMsg->frameType = frameType; |
| pMsg->matchLen = matchLen; |
| qdf_mem_copy(pMsg->matchData, matchData, matchLen); |
| status = cds_send_mb_message_to_mac(pMsg); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_remain_on_channel - API to request remain on channel for 'x' duration |
| * |
| * @hHal: pointer to MAC handle |
| * @session_id: Session identifier |
| * @channel: channel information |
| * @duration: duration in ms |
| * @callback: HDD registered callback to process reaminOnChannelRsp |
| * @context: HDD Callback param |
| * @scan_id: scan identifier |
| * |
| * This function process the roc request and generates scan identifier.s |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_remain_on_channel(tHalHandle hHal, uint8_t session_id, |
| uint8_t channel, uint32_t duration, |
| remainOnChanCallback callback, |
| void *pContext, uint8_t isP2PProbeReqAllowed, |
| uint32_t *scan_id) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal); |
| uint32_t san_req_id, scan_count; |
| struct ani_roc_req *roc_msg; |
| cds_msg_t msg; |
| |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, session_id, 0)); |
| |
| scan_count = csr_ll_count(&mac_ctx->sme.smeScanCmdActiveList); |
| if (scan_count >= mac_ctx->scan.max_scan_count) { |
| sms_log(mac_ctx, LOGE, FL("Max scan reached")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| wma_get_scan_id(&san_req_id); |
| *scan_id = san_req_id; |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| |
| sms_log(mac_ctx, LOG1, FL(" called")); |
| roc_msg = qdf_mem_malloc(sizeof(struct ani_roc_req)); |
| if (NULL == roc_msg) { |
| sms_log(mac_ctx, LOGE, |
| " scan_req: failed to allocate mem for msg"); |
| sme_release_global_lock(&mac_ctx->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| roc_msg->msg_type = eWNI_SME_ROC_CMD; |
| roc_msg->msg_len = (uint16_t) sizeof(struct ani_roc_req); |
| roc_msg->session_id = session_id; |
| roc_msg->callback = callback; |
| roc_msg->duration = duration; |
| roc_msg->channel = channel; |
| roc_msg->is_p2pprobe_allowed = isP2PProbeReqAllowed; |
| roc_msg->ctx = pContext; |
| roc_msg->scan_id = *scan_id; |
| msg.type = eWNI_SME_ROC_CMD; |
| msg.bodyptr = roc_msg; |
| msg.reserved = 0; |
| msg.bodyval = 0; |
| if (QDF_STATUS_SUCCESS != |
| cds_mq_post_message(CDS_MQ_ID_SME, &msg)) { |
| sms_log(mac_ctx, LOGE, |
| " sme_scan_req failed to post msg"); |
| qdf_mem_free(roc_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_report_probe_req |
| \brief API to enable/disable forwarding of probeReq to apps in p2p. |
| \param hHal - The handle returned by mac_open. |
| \param falg: to set the Probe request forarding to wpa_supplicant in listen state in p2p |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| |
| #ifndef WLAN_FEATURE_CONCURRENT_P2P |
| QDF_STATUS sme_report_probe_req(tHalHandle hHal, uint8_t flag) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| do { |
| /* acquire the lock for the sme object */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* call set in context */ |
| pMac->p2pContext.probeReqForwarding = flag; |
| /* release the lock for the sme object */ |
| sme_release_global_lock(&pMac->sme); |
| } |
| } while (0); |
| |
| sms_log(pMac, LOGW, "exiting function %s", __func__); |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_p2p_ie |
| \brief API to set the P2p Ie in p2p context |
| \param hHal - The handle returned by mac_open. |
| \param p2pIe - Ptr to p2pIe from HDD. |
| \param p2pIeLength: length of p2pIe |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_p2p_ie(tHalHandle hHal, void *p2pIe, uint32_t p2pIeLength) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_UPDATE_P2P_IE, NO_SESSION, 0)); |
| /* acquire the lock for the sme object */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (NULL != pMac->p2pContext.probeRspIe) { |
| qdf_mem_free(pMac->p2pContext.probeRspIe); |
| pMac->p2pContext.probeRspIeLength = 0; |
| } |
| |
| pMac->p2pContext.probeRspIe = qdf_mem_malloc(p2pIeLength); |
| if (NULL == pMac->p2pContext.probeRspIe) { |
| sms_log(pMac, LOGE, "%s: Unable to allocate P2P IE", |
| __func__); |
| pMac->p2pContext.probeRspIeLength = 0; |
| status = QDF_STATUS_E_NOMEM; |
| } else { |
| pMac->p2pContext.probeRspIeLength = p2pIeLength; |
| |
| sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG2, |
| pMac->p2pContext.probeRspIe, |
| pMac->p2pContext.probeRspIeLength); |
| qdf_mem_copy((uint8_t *) pMac->p2pContext.probeRspIe, |
| p2pIe, p2pIeLength); |
| } |
| |
| /* release the lock for the sme object */ |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| sms_log(pMac, LOG2, "exiting function %s", __func__); |
| |
| return status; |
| } |
| #endif |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_send_action |
| \brief API to send action frame from supplicant. |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_send_action(tHalHandle hHal, uint8_t sessionId, |
| const uint8_t *pBuf, uint32_t len, |
| uint16_t wait, bool noack, |
| uint16_t channel_freq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0)); |
| /* acquire the lock for the sme object */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| p2p_send_action(hHal, sessionId, pBuf, len, wait, noack, |
| channel_freq); |
| /* release the lock for the sme object */ |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| sms_log(pMac, LOGW, "exiting function %s", __func__); |
| |
| return status; |
| } |
| |
| QDF_STATUS sme_cancel_remain_on_channel(tHalHandle hHal, |
| uint8_t sessionId, uint32_t scan_id) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = p2p_cancel_remain_on_channel(hHal, sessionId, scan_id); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* Power Save Related */ |
| QDF_STATUS sme_p2p_set_ps(tHalHandle hHal, tP2pPsConfig *data) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = p2p_set_ps(hHal, data); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_configure_rxp_filter |
| |
| \brief |
| SME will pass this request to lower mac to set/reset the filter on RXP for |
| multicast & broadcast traffic. |
| |
| \param |
| |
| hHal - The handle returned by mac_open. |
| |
| filterMask- Currently the API takes a 1 or 0 (set or reset) as filter. |
| Basically to enable/disable the filter (to filter "all" mcbc traffic) based |
| on this param. In future we can use this as a mask to set various types of |
| filters as suggested below: |
| FILTER_ALL_MULTICAST: |
| FILTER_ALL_BROADCAST: |
| FILTER_ALL_MULTICAST_BROADCAST: |
| |
| \return QDF_STATUS |
| |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_configure_rxp_filter(tHalHandle hHal, |
| tpSirWlanSetRxpFilters wlanRxpFilterParam) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = wlanRxpFilterParam; |
| cds_message.type = WMA_CFG_RXP_FILTER_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_configure_suspend_ind |
| |
| \brief |
| SME will pass this request to lower mac to Indicate that the wlan needs to |
| be suspended |
| |
| \param |
| |
| hHal - The handle returned by mac_open. |
| |
| wlanSuspendParam- Depicts the wlan suspend params |
| |
| csr_readyToSuspendCallback - Callback to be called when ready to suspend |
| event is received. |
| callback_context - Context associated with csr_readyToSuspendCallback. |
| |
| \return QDF_STATUS |
| |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_configure_suspend_ind(tHalHandle hHal, |
| uint32_t conn_state_mask, |
| csr_readyToSuspendCallback callback, |
| void *callback_context) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION, |
| 0)); |
| |
| pMac->readyToSuspendCallback = callback; |
| pMac->readyToSuspendContext = callback_context; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| cds_message.bodyval = conn_state_mask; |
| cds_message.type = WMA_WLAN_SUSPEND_IND; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| pMac->readyToSuspendCallback = NULL; |
| pMac->readyToSuspendContext = NULL; |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_configure_resume_req |
| |
| \brief |
| SME will pass this request to lower mac to Indicate that the wlan needs to |
| be Resumed |
| |
| \param |
| |
| hHal - The handle returned by mac_open. |
| |
| wlanResumeParam- Depicts the wlan resume params |
| |
| \return QDF_STATUS |
| |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_configure_resume_req(tHalHandle hHal, |
| tpSirWlanResumeParam wlanResumeParam) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = wlanResumeParam; |
| cds_message.type = WMA_WLAN_RESUME_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_EXTWOW_SUPPORT |
| /** |
| * sme_configure_ext_wow() - configure Extr WoW |
| * @hHal - The handle returned by mac_open. |
| * @wlanExtParams - Depicts the wlan Ext params. |
| * @callback - ext_wow callback to be registered. |
| * @callback_context - ext_wow callback context |
| * |
| * SME will pass this request to lower mac to configure Extr WoW |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_configure_ext_wow(tHalHandle hHal, |
| tpSirExtWoWParams wlanExtParams, |
| csr_readyToExtWoWCallback callback, |
| void *callback_context) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tpSirExtWoWParams MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); |
| |
| if (!MsgPtr) |
| return QDF_STATUS_E_NOMEM; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_EXTWOW, NO_SESSION, 0)); |
| |
| pMac->readyToExtWoWCallback = callback; |
| pMac->readyToExtWoWContext = callback_context; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| /* serialize the req through MC thread */ |
| qdf_mem_copy(MsgPtr, wlanExtParams, sizeof(*MsgPtr)); |
| cds_message.bodyptr = MsgPtr; |
| cds_message.type = WMA_WLAN_EXT_WOW; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| pMac->readyToExtWoWCallback = NULL; |
| pMac->readyToExtWoWContext = NULL; |
| qdf_mem_free(MsgPtr); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| pMac->readyToExtWoWCallback = NULL; |
| pMac->readyToExtWoWContext = NULL; |
| qdf_mem_free(MsgPtr); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_configure_app_type1_params |
| |
| \brief |
| SME will pass this request to lower mac to configure Indoor WoW parameters. |
| |
| \param |
| |
| hHal - The handle returned by mac_open. |
| |
| wlanAppType1Params- Depicts the wlan App Type 1(Indoor) params |
| |
| \return QDF_STATUS |
| |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_configure_app_type1_params(tHalHandle hHal, |
| tpSirAppType1Params wlanAppType1Params) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tpSirAppType1Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); |
| |
| if (!MsgPtr) |
| return QDF_STATUS_E_NOMEM; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE1, NO_SESSION, |
| 0)); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| qdf_mem_copy(MsgPtr, wlanAppType1Params, sizeof(*MsgPtr)); |
| cds_message.bodyptr = MsgPtr; |
| cds_message.type = WMA_WLAN_SET_APP_TYPE1_PARAMS; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| qdf_mem_free(MsgPtr); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| qdf_mem_free(MsgPtr); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_configure_app_type2_params |
| |
| \brief |
| SME will pass this request to lower mac to configure Indoor WoW parameters. |
| |
| \param |
| |
| hHal - The handle returned by mac_open. |
| |
| wlanAppType2Params- Depicts the wlan App Type 2 (Outdoor) params |
| |
| \return QDF_STATUS |
| |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_configure_app_type2_params(tHalHandle hHal, |
| tpSirAppType2Params wlanAppType2Params) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tpSirAppType2Params MsgPtr = qdf_mem_malloc(sizeof(*MsgPtr)); |
| |
| if (!MsgPtr) |
| return QDF_STATUS_E_NOMEM; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_CONFIG_APP_TYPE2, NO_SESSION, |
| 0)); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| qdf_mem_copy(MsgPtr, wlanAppType2Params, sizeof(*MsgPtr)); |
| cds_message.bodyptr = MsgPtr; |
| cds_message.type = WMA_WLAN_SET_APP_TYPE2_PARAMS; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| qdf_mem_free(MsgPtr); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| qdf_mem_free(MsgPtr); |
| } |
| |
| return status; |
| } |
| #endif |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_get_infra_session_id |
| |
| \brief To get the session ID for infra session, if connected |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \return sessionid, -1 if infra session is not connected |
| |
| -------------------------------------------------------------------------------*/ |
| int8_t sme_get_infra_session_id(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| int8_t sessionid = -1; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| sessionid = csr_get_infra_session_id(pMac); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return sessionid; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_get_infra_operation_channel |
| |
| \brief To get the operating channel for infra session, if connected |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - the sessionId returned by sme_open_session. |
| |
| \return operating channel, 0 if infra session is not connected |
| |
| -------------------------------------------------------------------------------*/ |
| uint8_t sme_get_infra_operation_channel(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint8_t channel = 0; |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| channel = csr_get_infra_operation_channel(pMac, sessionId); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return channel; |
| } |
| |
| /* This routine will return poerating channel on which other BSS is operating to be used for concurrency mode. */ |
| /* If other BSS is not up or not connected it will return 0 */ |
| uint8_t sme_get_concurrent_operation_channel(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint8_t channel = 0; |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| channel = csr_get_concurrent_operation_channel(pMac); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_HIGH, "%s: " |
| " Other Concurrent Channel = %d", __func__, channel); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return channel; |
| } |
| |
| #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH |
| uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch, |
| eCsrPhyMode sapPhyMode, |
| uint8_t cc_switch_mode) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint16_t channel = 0; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| channel = |
| csr_check_concurrent_channel_overlap(pMac, sap_ch, sapPhyMode, |
| cc_switch_mode); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return channel; |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_SCAN_PNO |
| /** |
| * sme_update_roam_pno_channel_prediction_config() - Update PNO config |
| * @csr_config: config from SME context |
| * @hal: Global Hal handle |
| * @copy_from_to: Used to specify the source and destination |
| * |
| * Copy the PNO channel prediction configuration parameters from |
| * SME context to MAC context or vice-versa |
| * |
| * Return: None |
| */ |
| void sme_update_roam_pno_channel_prediction_config( |
| tHalHandle hal, tCsrConfigParam *csr_config, |
| uint8_t copy_from_to) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| if (copy_from_to == SME_CONFIG_TO_ROAM_CONFIG) { |
| mac_ctx->roam.configParam.pno_channel_prediction = |
| csr_config->pno_channel_prediction; |
| mac_ctx->roam.configParam.top_k_num_of_channels = |
| csr_config->top_k_num_of_channels; |
| mac_ctx->roam.configParam.stationary_thresh = |
| csr_config->stationary_thresh; |
| mac_ctx->roam.configParam.channel_prediction_full_scan = |
| csr_config->channel_prediction_full_scan; |
| mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode = |
| csr_config->pnoscan_adaptive_dwell_mode; |
| } else if (copy_from_to == ROAM_CONFIG_TO_SME_CONFIG) { |
| csr_config->pno_channel_prediction = |
| mac_ctx->roam.configParam.pno_channel_prediction; |
| csr_config->top_k_num_of_channels = |
| mac_ctx->roam.configParam.top_k_num_of_channels; |
| csr_config->stationary_thresh = |
| mac_ctx->roam.configParam.stationary_thresh; |
| csr_config->channel_prediction_full_scan = |
| mac_ctx->roam.configParam.channel_prediction_full_scan; |
| csr_config->pnoscan_adaptive_dwell_mode = |
| mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode; |
| } |
| |
| } |
| /****************************************************************************** |
| * |
| * Name: sme_preferred_network_found_ind |
| * |
| * Description: |
| * Invoke Preferred Network Found Indication |
| * |
| * Parameters: |
| * hHal - HAL handle for device |
| * pMsg - found network description |
| * |
| * Returns: QDF_STATUS |
| * |
| ******************************************************************************/ |
| QDF_STATUS sme_preferred_network_found_ind(tHalHandle hHal, void *pMsg) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tSirPrefNetworkFoundInd *pPrefNetworkFoundInd = |
| (tSirPrefNetworkFoundInd *) pMsg; |
| uint8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1]; |
| uint8_t ssIdLength = 0; |
| |
| if (NULL == pMsg) { |
| sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (pMac->pnoOffload) { |
| /* Call Preferred Network Found Indication callback routine. */ |
| if (pMac->sme.pref_netw_found_cb != NULL) { |
| pMac->sme.pref_netw_found_cb(pMac->sme. |
| preferred_network_found_ind_cb_ctx, |
| pPrefNetworkFoundInd); |
| } |
| return status; |
| } |
| |
| if (pPrefNetworkFoundInd->ssId.length > 0) { |
| ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH, |
| pPrefNetworkFoundInd->ssId.length); |
| qdf_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId, |
| ssIdLength); |
| dumpSsId[ssIdLength] = 0; |
| sms_log(pMac, LOG2, "%s:SSID=%s frame length %d", |
| __func__, dumpSsId, pPrefNetworkFoundInd->frameLength); |
| |
| /* Flush scan results, So as to avoid indication/updation of |
| * stale entries, which may not have aged out during APPS collapse |
| */ |
| sme_scan_flush_result(hHal); |
| |
| /* Save the frame to scan result */ |
| if (pPrefNetworkFoundInd->mesgLen > |
| sizeof(tSirPrefNetworkFoundInd)) { |
| /* we may have a frame */ |
| status = csr_scan_save_preferred_network_found(pMac, |
| pPrefNetworkFoundInd); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, LOGE, |
| FL(" fail to save preferred network")); |
| } |
| } else { |
| sms_log(pMac, LOGE, |
| FL(" not enough data length %d needed %zu"), |
| pPrefNetworkFoundInd->mesgLen, |
| sizeof(tSirPrefNetworkFoundInd)); |
| } |
| |
| /* Call Preferred Netowrk Found Indication callback routine. */ |
| if (QDF_IS_STATUS_SUCCESS(status) |
| && (pMac->sme.pref_netw_found_cb != NULL)) { |
| pMac->sme.pref_netw_found_cb(pMac->sme. |
| preferred_network_found_ind_cb_ctx, |
| pPrefNetworkFoundInd); |
| } |
| } else { |
| sms_log(pMac, LOGE, "%s: callback failed - SSID is NULL", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| return status; |
| } |
| |
| #endif /* FEATURE_WLAN_SCAN_PNO */ |
| |
| /** |
| * sme_set_tsfcb() - Set callback for TSF capture |
| * @h_hal: Handler return by mac_open |
| * @cb_fn: Callback function pointer |
| * @db_ctx: Callback data |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_set_tsfcb(tHalHandle h_hal, |
| int (*cb_fn)(void *cb_ctx, struct stsf *ptsf), void *cb_ctx) |
| { |
| tpAniSirGlobal mac = PMAC_STRUCT(h_hal); |
| QDF_STATUS status; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| mac->sme.get_tsf_cb = cb_fn; |
| mac->sme.get_tsf_cxt = cb_ctx; |
| sme_release_global_lock(&mac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_reset_tsfcb() - Reset callback for TSF capture |
| * @h_hal: Handler return by mac_open |
| * |
| * This function reset the tsf capture callback to SME |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_reset_tsfcb(tHalHandle h_hal) |
| { |
| tpAniSirGlobal mac; |
| QDF_STATUS status; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("h_hal is not valid")); |
| return QDF_STATUS_E_INVAL; |
| } |
| mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| mac->sme.get_tsf_cb = NULL; |
| mac->sme.get_tsf_cxt = NULL; |
| sme_release_global_lock(&mac->sme); |
| } |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_TSF |
| /* |
| * sme_set_tsf_gpio() - set gpio pin that be toggled when capture tef |
| * @h_hal: Handler return by mac_open |
| * @pinvalue: gpio pin id |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_set_tsf_gpio(tHalHandle h_hal, uint32_t pinvalue) |
| { |
| QDF_STATUS status; |
| cds_msg_t tsf_msg = {0}; |
| tpAniSirGlobal mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| tsf_msg.type = WMA_TSF_GPIO_PIN; |
| tsf_msg.reserved = 0; |
| tsf_msg.bodyval = pinvalue; |
| |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &tsf_msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, "Unable to post WMA_TSF_GPIO_PIN"); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| } |
| return status; |
| } |
| #endif |
| |
| QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels, |
| uint32_t *len) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_get_cfg_valid_channels(pMac, aValidChannels, len); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_handle_change_country_code |
| |
| \brief Change Country code, Reg Domain and channel list |
| |
| \details Country Code Priority |
| If Supplicant country code is priority than 11d is disabled. |
| If 11D is enabled, we update the country code after every scan. |
| Hence when Supplicant country code is priority, we don't need 11D info. |
| Country code from Supplicant is set as current courtry code. |
| User can send reset command XX (instead of country code) to reset the |
| country code to default values. |
| If 11D is priority, |
| Than Supplicant country code code is set to default code. But 11D code is set as current country code |
| |
| \param pMac - The handle returned by mac_open. |
| \param pMsgBuf - MSG Buffer |
| |
| \return QDF_STATUS |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_handle_change_country_code(tpAniSirGlobal pMac, void *pMsgBuf) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tAniChangeCountryCodeReq *pMsg; |
| v_REGDOMAIN_t domainIdIoctl; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| static uint8_t default_country[CDS_COUNTRY_CODE_LEN + 1]; |
| pMsg = (tAniChangeCountryCodeReq *) pMsgBuf; |
| |
| /* |
| * if the reset Supplicant country code command is triggered, |
| * enable 11D, reset the country code and return |
| */ |
| if (false == |
| qdf_mem_cmp(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2)) { |
| pMac->roam.configParam.Is11dSupportEnabled = |
| pMac->roam.configParam.Is11dSupportEnabledOriginal; |
| |
| qdf_status = cds_read_default_country(default_country); |
| |
| /* read the country code and use it */ |
| if (QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| qdf_mem_copy(pMsg->countryCode, |
| default_country, |
| WNI_CFG_COUNTRY_CODE_LEN); |
| } else { |
| status = QDF_STATUS_E_FAILURE; |
| return status; |
| } |
| /* |
| * Update the 11d country to default country so that when |
| * callback is received for this default country, driver will |
| * not disable the 11d taking it as valid country by user. |
| */ |
| sms_log(pMac, LOG1, |
| FL("Set default country code (%c%c) as invalid country received"), |
| pMsg->countryCode[0], pMsg->countryCode[1]); |
| qdf_mem_copy(pMac->scan.countryCode11d, |
| pMsg->countryCode, |
| WNI_CFG_COUNTRY_CODE_LEN); |
| } else { |
| /* if Supplicant country code has priority, disable 11d */ |
| if (pMac->roam.configParam.fSupplicantCountryCodeHasPriority && |
| pMsg->countryFromUserSpace) { |
| pMac->roam.configParam.Is11dSupportEnabled = false; |
| } |
| } |
| |
| if (pMac->roam.configParam.Is11dSupportEnabled) |
| return QDF_STATUS_SUCCESS; |
| |
| /* Set Current Country code and Current Regulatory domain */ |
| status = csr_set_country_code(pMac, pMsg->countryCode); |
| if (QDF_STATUS_SUCCESS != status) { |
| /* Supplicant country code failed. So give 11D priority */ |
| pMac->roam.configParam.Is11dSupportEnabled = |
| pMac->roam.configParam.Is11dSupportEnabledOriginal; |
| sms_log(pMac, LOGE, "Set Country Code Fail %d", status); |
| return status; |
| } |
| |
| /* overwrite the defualt country code */ |
| qdf_mem_copy(pMac->scan.countryCodeDefault, |
| pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); |
| |
| /* Get Domain ID from country code */ |
| status = csr_get_regulatory_domain_for_country(pMac, |
| pMac->scan.countryCodeCurrent, |
| (v_REGDOMAIN_t *) & |
| domainIdIoctl, |
| SOURCE_QUERY); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(pMac, LOGE, FL(" fail to get regId %d"), domainIdIoctl); |
| return status; |
| } else if (REGDOMAIN_WORLD == domainIdIoctl) { |
| /* Supplicant country code is invalid, so we are on world mode now. So |
| give 11D chance to update */ |
| pMac->roam.configParam.Is11dSupportEnabled = |
| pMac->roam.configParam.Is11dSupportEnabledOriginal; |
| sms_log(pMac, LOG1, FL("Country Code unrecognized by driver")); |
| } |
| |
| status = wma_set_reg_domain(pMac, domainIdIoctl); |
| |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(pMac, LOGE, FL(" fail to set regId %d"), domainIdIoctl); |
| return status; |
| } else { |
| /* if 11d has priority, clear currentCountryBssid & countryCode11d to get */ |
| /* set again if we find AP with 11d info during scan */ |
| if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) { |
| sms_log(pMac, LOGW, |
| FL |
| ("Clearing currentCountryBssid, countryCode11d")); |
| qdf_mem_zero(&pMac->scan.currentCountryBssid, |
| sizeof(struct qdf_mac_addr)); |
| qdf_mem_zero(pMac->scan.countryCode11d, |
| sizeof(pMac->scan.countryCode11d)); |
| } |
| } |
| |
| if (pMsg->changeCCCallback) { |
| ((tSmeChangeCountryCallback) (pMsg->changeCCCallback))((void *) |
| pMsg-> |
| pDevContext); |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_handle_generic_change_country_code() - handles country ch req |
| * @mac_ctx: mac global context |
| * @msg: request msg packet |
| * |
| * If Supplicant country code is priority than 11d is disabled. |
| * If 11D is enabled, we update the country code after every scan. |
| * Hence when Supplicant country code is priority, we don't need 11D info. |
| * Country code from Supplicant is set as current country code. |
| * |
| * Return: status of operation |
| */ |
| QDF_STATUS |
| sme_handle_generic_change_country_code(tpAniSirGlobal mac_ctx, |
| void *pMsgBuf) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| v_REGDOMAIN_t reg_domain_id = 0; |
| bool is_11d_country = false; |
| bool supplicant_priority = |
| mac_ctx->roam.configParam.fSupplicantCountryCodeHasPriority; |
| tAniGenericChangeCountryCodeReq *msg = pMsgBuf; |
| |
| sms_log(mac_ctx, LOG1, FL(" called")); |
| |
| if (memcmp(msg->countryCode, mac_ctx->scan.countryCode11d, |
| CDS_COUNTRY_CODE_LEN) == 0) { |
| is_11d_country = true; |
| } |
| /* Set the country code given by userspace when 11dOriginal is false |
| * when 11doriginal is True,is_11d_country =0 and |
| * fSupplicantCountryCodeHasPriority = 0, then revert the country code, |
| * and return failure |
| */ |
| if (mac_ctx->roam.configParam.Is11dSupportEnabledOriginal == true |
| && !is_11d_country && !supplicant_priority) { |
| sms_log(mac_ctx, LOGW, |
| FL("Incorrect country req, nullify this")); |
| |
| /* we have got a request for a country that should not have been |
| * added since the STA is associated; nullify this request. If |
| * both countryCode11d[0] and countryCode11d[1] are zero, revert |
| * it to World domain to avoid from causing cfg80211 call trace. |
| */ |
| if ((mac_ctx->scan.countryCode11d[0] == 0) |
| && (mac_ctx->scan.countryCode11d[1] == 0)) |
| status = csr_get_regulatory_domain_for_country(mac_ctx, |
| "00", (v_REGDOMAIN_t *) ®_domain_id, |
| SOURCE_11D); |
| else |
| status = csr_get_regulatory_domain_for_country(mac_ctx, |
| mac_ctx->scan.countryCode11d, |
| (v_REGDOMAIN_t *) ®_domain_id, |
| SOURCE_11D); |
| |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /* if Supplicant country code has priority, disable 11d */ |
| if (!is_11d_country && supplicant_priority) |
| mac_ctx->roam.configParam.Is11dSupportEnabled = false; |
| qdf_mem_copy(mac_ctx->scan.countryCodeCurrent, msg->countryCode, |
| WNI_CFG_COUNTRY_CODE_LEN); |
| status = wma_set_reg_domain(mac_ctx, reg_domain_id); |
| if (false == is_11d_country) { |
| /* overwrite the defualt country code */ |
| qdf_mem_copy(mac_ctx->scan.countryCodeDefault, |
| mac_ctx->scan.countryCodeCurrent, |
| WNI_CFG_COUNTRY_CODE_LEN); |
| /* set to default domain ID */ |
| mac_ctx->scan.domainIdDefault = mac_ctx->scan.domainIdCurrent; |
| } |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(mac_ctx, LOGE, FL("fail to set regId %d"), |
| reg_domain_id); |
| return status; |
| } else { |
| /* if 11d has priority, clear currentCountryBssid & |
| * countryCode11d to get set again if we find AP with 11d info |
| * during scan |
| */ |
| if (!supplicant_priority && (false == is_11d_country)) { |
| sms_log(mac_ctx, LOGW, |
| FL("Clearing currentCountryBssid, countryCode11d")); |
| qdf_mem_zero(&mac_ctx->scan.currentCountryBssid, |
| sizeof(struct qdf_mac_addr)); |
| qdf_mem_zero(mac_ctx->scan.countryCode11d, |
| sizeof(mac_ctx->scan.countryCode11d)); |
| } |
| } |
| /* get the channels based on new cc */ |
| status = csr_get_channel_and_power_list(mac_ctx); |
| |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(mac_ctx, LOGE, FL("fail to get Channels")); |
| return status; |
| } |
| /* reset info based on new cc, and we are done */ |
| csr_apply_channel_power_info_wrapper(mac_ctx); |
| |
| /* Country code Changed, Purge Only scan result |
| * which does not have channel number belong to 11d |
| * channel list |
| */ |
| csr_scan_filter_results(mac_ctx); |
| /* Do active scans after the country is set by User hints or |
| * Country IE |
| */ |
| mac_ctx->scan.curScanType = eSIR_ACTIVE_SCAN; |
| sme_disconnect_connected_sessions(mac_ctx); |
| sms_log(mac_ctx, LOG1, FL(" returned")); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| static bool |
| sme_search_in_base_ch_lst(tpAniSirGlobal mac_ctx, uint8_t curr_ch) |
| { |
| uint8_t i; |
| tCsrChannel *ch_lst_info; |
| ch_lst_info = &mac_ctx->scan.base_channels; |
| for (i = 0; i < ch_lst_info->numChannels; i++) { |
| if (ch_lst_info->channelList[i] == curr_ch) |
| return true; |
| } |
| |
| return false; |
| } |
| /** |
| * sme_disconnect_connected_sessions() - Disconnect STA and P2P client session |
| * if channel is not supported |
| * @mac_ctx: mac global context |
| * |
| * If new country code does not support the channel on which STA/P2P client |
| * is connetced, it sends the disconnect to the AP/P2P GO |
| * |
| * Return: void |
| */ |
| void sme_disconnect_connected_sessions(tpAniSirGlobal mac_ctx) |
| { |
| uint8_t session_id, found = false; |
| uint8_t curr_ch; |
| |
| for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) { |
| if (!csr_is_session_client_and_connected(mac_ctx, session_id)) |
| continue; |
| found = false; |
| /* Session is connected.Check the channel */ |
| curr_ch = csr_get_infra_operation_channel(mac_ctx, |
| session_id); |
| sms_log(mac_ctx, LOGW, |
| FL("Current Operating channel : %d, session :%d"), |
| curr_ch, session_id); |
| found = sme_search_in_base_ch_lst(mac_ctx, curr_ch); |
| if (!found) { |
| sms_log(mac_ctx, LOGW, FL("Disconnect Session :%d"), |
| session_id); |
| csr_roam_disconnect(mac_ctx, session_id, |
| eCSR_DISCONNECT_REASON_UNSPECIFIED); |
| } |
| } |
| } |
| |
| #ifdef WLAN_FEATURE_PACKET_FILTERING |
| QDF_STATUS sme_8023_multicast_list(tHalHandle hHal, uint8_t sessionId, |
| tpSirRcvFltMcAddrList pMulticastAddrs) |
| { |
| tpSirRcvFltMcAddrList request_buf; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = NULL; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: " |
| "ulMulticastAddrCnt=%d, multicastAddr[0]=%p", __func__, |
| pMulticastAddrs->ulMulticastAddrCnt, |
| pMulticastAddrs->multicastAddr[0].bytes); |
| |
| /* Find the connected Infra / P2P_client connected session */ |
| if (CSR_IS_SESSION_VALID(pMac, sessionId) && |
| (csr_is_conn_state_infra(pMac, sessionId) || |
| csr_is_ndi_started(pMac, sessionId))) { |
| pSession = CSR_GET_SESSION(pMac, sessionId); |
| } |
| |
| if (pSession == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN, |
| "%s: Unable to find the session Id: %d", __func__, |
| sessionId); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| request_buf = qdf_mem_malloc(sizeof(tSirRcvFltMcAddrList)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to " |
| "allocate memory for 8023 Multicast List request", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| if (!csr_is_conn_state_connected_infra(pMac, sessionId) && |
| !csr_is_ndi_started(pMac, sessionId)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Request ignored, session %d is not connected or started", |
| __func__, sessionId); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| qdf_mem_copy(request_buf, pMulticastAddrs, |
| sizeof(tSirRcvFltMcAddrList)); |
| |
| qdf_copy_macaddr(&request_buf->self_macaddr, &pSession->selfMacAddr); |
| qdf_copy_macaddr(&request_buf->bssid, |
| &pSession->connectedProfile.bssid); |
| |
| msg.type = WMA_8023_MULTICAST_LIST_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, msg.type)); |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to " |
| "post WMA_8023_MULTICAST_LIST message to WMA", |
| __func__); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS sme_receive_filter_set_filter(tHalHandle hHal, |
| tpSirRcvPktFilterCfgType pRcvPktFilterCfg, |
| uint8_t sessionId) |
| { |
| tpSirRcvPktFilterCfgType request_buf; |
| int32_t allocSize; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| uint8_t idx = 0; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: filterType=%d, " |
| "filterId = %d", __func__, |
| pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId); |
| |
| allocSize = sizeof(tSirRcvPktFilterCfgType); |
| |
| request_buf = qdf_mem_malloc(allocSize); |
| |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to " |
| "allocate memory for Receive Filter Set Filter request", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Session Not found ", __func__); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| qdf_copy_macaddr(&pRcvPktFilterCfg->self_macaddr, |
| &pSession->selfMacAddr); |
| qdf_copy_macaddr(&pRcvPktFilterCfg->bssid, |
| &pSession->connectedProfile.bssid); |
| qdf_mem_copy(request_buf, pRcvPktFilterCfg, allocSize); |
| |
| msg.type = WMA_RECEIVE_FILTER_SET_FILTER_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, msg.type)); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "Pkt Flt Req : " |
| "FT %d FID %d ", |
| request_buf->filterType, request_buf->filterId); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "Pkt Flt Req : " |
| "params %d CT %d", |
| request_buf->numFieldParams, request_buf->coalesceTime); |
| |
| for (idx = 0; idx < request_buf->numFieldParams; idx++) { |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "Proto %d Comp Flag %d ", |
| request_buf->paramsData[idx].protocolLayer, |
| request_buf->paramsData[idx].cmpFlag); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "Data Offset %d Data Len %d", |
| request_buf->paramsData[idx].dataOffset, |
| request_buf->paramsData[idx].dataLength); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "CData: %d:%d:%d:%d:%d:%d", |
| request_buf->paramsData[idx].compareData[0], |
| request_buf->paramsData[idx].compareData[1], |
| request_buf->paramsData[idx].compareData[2], |
| request_buf->paramsData[idx].compareData[3], |
| request_buf->paramsData[idx].compareData[4], |
| request_buf->paramsData[idx].compareData[5]); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "MData: %d:%d:%d:%d:%d:%d", |
| request_buf->paramsData[idx].dataMask[0], |
| request_buf->paramsData[idx].dataMask[1], |
| request_buf->paramsData[idx].dataMask[2], |
| request_buf->paramsData[idx].dataMask[3], |
| request_buf->paramsData[idx].dataMask[4], |
| request_buf->paramsData[idx].dataMask[5]); |
| |
| } |
| |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post " |
| "WMA_RECEIVE_FILTER_SET_FILTER message to WMA", |
| __func__); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_STATUS sme_receive_filter_clear_filter(tHalHandle hHal, |
| tpSirRcvFltPktClearParam |
| pRcvFltPktClearParam, uint8_t sessionId) |
| { |
| tpSirRcvFltPktClearParam request_buf; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, "%s: filterId = %d", |
| __func__, pRcvFltPktClearParam->filterId); |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Session Not found", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| request_buf = qdf_mem_malloc(sizeof(tSirRcvFltPktClearParam)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for Receive Filter " |
| "Clear Filter request", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&pRcvFltPktClearParam->self_macaddr, |
| &pSession->selfMacAddr); |
| qdf_copy_macaddr(&pRcvFltPktClearParam->bssid, |
| &pSession->connectedProfile.bssid); |
| |
| qdf_mem_copy(request_buf, pRcvFltPktClearParam, |
| sizeof(tSirRcvFltPktClearParam)); |
| |
| msg.type = WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| sessionId, msg.type)); |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post " |
| "WMA_RECEIVE_FILTER_CLEAR_FILTER message to WMA", |
| __func__); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* WLAN_FEATURE_PACKET_FILTERING */ |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_is_channel_valid |
| |
| \brief To check if the channel is valid for currently established domain |
| This is a synchronous API. |
| |
| \param hHal - The handle returned by mac_open. |
| \param channel - channel to verify |
| |
| \return true/false, true if channel is valid |
| |
| -------------------------------------------------------------------------------*/ |
| bool sme_is_channel_valid(tHalHandle hHal, uint8_t channel) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| bool valid = false; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| valid = csr_roam_is_channel_valid(pMac, channel); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return valid; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_freq_band |
| \brief Used to set frequency band. |
| \param hHal |
| \param sessionId - Session Identifier |
| \eBand band value to be configured |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_freq_band(tHalHandle hHal, uint8_t sessionId, eCsrBand eBand) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_set_band(hHal, sessionId, eBand); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_freq_band |
| \brief Used to get the current band settings. |
| \param hHal |
| \pBand pointer to hold band value |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_freq_band(tHalHandle hHal, eCsrBand *pBand) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| *pBand = csr_get_current_band(hHal); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_max_tx_power_per_band |
| |
| \brief Set the Maximum Transmit Power specific to band dynamically. |
| Note: this setting will not persist over reboots. |
| |
| \param band |
| \param power to set in dB |
| \- return QDF_STATUS |
| |
| ----------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_max_tx_power_per_band(eCsrBand band, int8_t dB) |
| { |
| cds_msg_t msg; |
| tpMaxTxPowerPerBandParams pMaxTxPowerPerBandParams = NULL; |
| |
| pMaxTxPowerPerBandParams = |
| qdf_mem_malloc(sizeof(tMaxTxPowerPerBandParams)); |
| if (NULL == pMaxTxPowerPerBandParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s:Not able to allocate memory for pMaxTxPowerPerBandParams", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| pMaxTxPowerPerBandParams->power = dB; |
| pMaxTxPowerPerBandParams->bandInfo = band; |
| |
| msg.type = WMA_SET_MAX_TX_POWER_PER_BAND_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = pMaxTxPowerPerBandParams; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, msg.type)); |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s:Not able to post WMA_SET_MAX_TX_POWER_PER_BAND_REQ", |
| __func__); |
| qdf_mem_free(pMaxTxPowerPerBandParams); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_max_tx_power |
| |
| \brief Set the Maximum Transmit Power dynamically. Note: this setting will |
| not persist over reboots. |
| |
| \param hHal |
| \param pBssid BSSID to set the power cap for |
| \param pBssid pSelfMacAddress self MAC Address |
| \param pBssid power to set in dB |
| \- return QDF_STATUS |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_max_tx_power(tHalHandle hHal, struct qdf_mac_addr pBssid, |
| struct qdf_mac_addr pSelfMacAddress, int8_t dB) |
| { |
| cds_msg_t msg; |
| tpMaxTxPowerParams pMaxTxParams = NULL; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0)); |
| pMaxTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams)); |
| if (NULL == pMaxTxParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for pMaxTxParams", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&pMaxTxParams->bssId, &pBssid); |
| qdf_copy_macaddr(&pMaxTxParams->selfStaMacAddr, &pSelfMacAddress); |
| pMaxTxParams->power = dB; |
| |
| msg.type = WMA_SET_MAX_TX_POWER_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = pMaxTxParams; |
| |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_SET_MAX_TX_POWER_REQ message to WMA", |
| __func__); |
| qdf_mem_free(pMaxTxParams); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_custom_mac_addr |
| |
| \brief Set the customer Mac Address. |
| |
| \param customMacAddr customer MAC Address |
| \- return QDF_STATUS |
| |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_custom_mac_addr(tSirMacAddr customMacAddr) |
| { |
| cds_msg_t msg; |
| tSirMacAddr *pBaseMacAddr; |
| |
| pBaseMacAddr = qdf_mem_malloc(sizeof(tSirMacAddr)); |
| if (NULL == pBaseMacAddr) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for pBaseMacAddr")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_copy(*pBaseMacAddr, customMacAddr, sizeof(tSirMacAddr)); |
| |
| msg.type = SIR_HAL_SET_BASE_MACADDR_IND; |
| msg.reserved = 0; |
| msg.bodyptr = pBaseMacAddr; |
| |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL |
| ("Not able to post SIR_HAL_SET_BASE_MACADDR_IND message to WMA")); |
| qdf_mem_free(pBaseMacAddr); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* ---------------------------------------------------------------------------- |
| \fn sme_set_tx_power |
| \brief Set Transmit Power dynamically. |
| \param hHal |
| \param sessionId Target Session ID |
| \pBSSId BSSID |
| \dev_mode dev_mode such as station, P2PGO, SAP |
| \param dBm power to set |
| \- return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_tx_power(tHalHandle hHal, uint8_t sessionId, |
| struct qdf_mac_addr pBSSId, |
| enum tQDF_ADAPTER_MODE dev_mode, int dBm) |
| { |
| cds_msg_t msg; |
| tpMaxTxPowerParams pTxParams = NULL; |
| int8_t power = (int8_t) dBm; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_TXPOW, sessionId, 0)); |
| |
| /* make sure there is no overflow */ |
| if ((int)power != dBm) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: error, invalid power = %d", __func__, dBm); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pTxParams = qdf_mem_malloc(sizeof(tMaxTxPowerParams)); |
| if (NULL == pTxParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for pTxParams", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_copy_macaddr(&pTxParams->bssId, &pBSSId); |
| pTxParams->power = power; /* unit is dBm */ |
| pTxParams->dev_mode = dev_mode; |
| msg.type = WMA_SET_TX_POWER_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = pTxParams; |
| |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: failed to post WMA_SET_TX_POWER_REQ to WMA", |
| __func__); |
| qdf_mem_free(pTxParams); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_hide_ssid |
| |
| \brief hide/show SSID dynamically. Note: this setting will |
| not persist over reboots. |
| |
| \param hHal |
| \param sessionId |
| \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID |
| \- return QDF_STATUS |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_hide_ssid(tHalHandle hHal, uint8_t sessionId, uint8_t ssidHidden) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint16_t len; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| tpSirUpdateParams pMsg; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (!pSession) { |
| sms_log(pMac, LOGE, FL(" session %d not found "), |
| sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pSession->sessionActive) |
| QDF_ASSERT(0); |
| |
| /* Create the message and send to lim */ |
| len = sizeof(tSirUpdateParams); |
| pMsg = qdf_mem_malloc(len); |
| if (NULL == pMsg) |
| status = QDF_STATUS_E_NOMEM; |
| else { |
| qdf_mem_set(pMsg, sizeof(tSirUpdateParams), 0); |
| pMsg->messageType = eWNI_SME_HIDE_SSID_REQ; |
| pMsg->length = len; |
| /* Data starts from here */ |
| pMsg->sessionId = sessionId; |
| pMsg->ssidHidden = ssidHidden; |
| status = cds_send_mb_message_to_mac(pMsg); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_tm_level |
| \brief Set Thermal Mitigation Level to RIVA |
| \param hHal - The handle returned by mac_open. |
| \param newTMLevel - new Thermal Mitigation Level |
| \param tmMode - Thermal Mitigation handle mode, default 0 |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_tm_level(tHalHandle hHal, uint16_t newTMLevel, uint16_t tmMode) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tAniSetTmLevelReq *setTmLevelReq = NULL; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| setTmLevelReq = |
| (tAniSetTmLevelReq *) |
| qdf_mem_malloc(sizeof(tAniSetTmLevelReq)); |
| if (NULL == setTmLevelReq) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for sme_set_tm_level", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| setTmLevelReq->tmMode = tmMode; |
| setTmLevelReq->newTmLevel = newTMLevel; |
| |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = setTmLevelReq; |
| cds_message.type = WMA_SET_TM_LEVEL_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post Set TM Level MSG fail", __func__); |
| qdf_mem_free(setTmLevelReq); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*--------------------------------------------------------------------------- |
| |
| \brief sme_feature_caps_exchange() - SME interface to exchange capabilities between |
| Host and FW. |
| |
| \param hHal - HAL handle for device |
| |
| \return NONE |
| |
| ---------------------------------------------------------------------------*/ |
| void sme_feature_caps_exchange(tHalHandle hHal) |
| { |
| MTRACE(qdf_trace |
| (QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION, |
| 0)); |
| } |
| |
| /*--------------------------------------------------------------------------- |
| |
| \brief sme_disable_feature_capablity() - SME interface to disable Active mode offload capablity |
| in Host. |
| |
| \param hHal - HAL handle for device |
| |
| \return NONE |
| |
| ---------------------------------------------------------------------------*/ |
| void sme_disable_feature_capablity(uint8_t feature_index) |
| { |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_reset_power_values_for5_g |
| \brief Reset the power values for 5G band with default power values. |
| \param hHal - HAL handle for device |
| \- return NONE |
| -------------------------------------------------------------------------*/ |
| void sme_reset_power_values_for5_g(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0)); |
| csr_save_channel_power_for_band(pMac, true); |
| csr_apply_power2_current(pMac); /* Store the channel+power info in the global place: Cfg */ |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_roam_prefer5_g_hz |
| \brief enable/disable Roam prefer 5G runtime option |
| This function is called through dynamic setConfig callback function |
| to configure the Roam prefer 5G runtime option |
| \param hHal - HAL handle for device |
| \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_roam_prefer5_g_hz(tHalHandle hHal, bool nRoamPrefer5GHz) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: gRoamPrefer5GHz is changed from %d to %d", |
| __func__, pMac->roam.configParam.nRoamPrefer5GHz, |
| nRoamPrefer5GHz); |
| pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_intra_band |
| \brief enable/disable Intra band roaming |
| This function is called through dynamic setConfig callback function |
| to configure the intra band roaming |
| \param hHal - HAL handle for device |
| \param nRoamIntraBand Enable/Disable Intra band roaming |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_intra_band(tHalHandle hHal, const bool nRoamIntraBand) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: gRoamIntraBand is changed from %d to %d", |
| __func__, pMac->roam.configParam.nRoamIntraBand, |
| nRoamIntraBand); |
| pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_roam_scan_n_probes |
| \brief function to update roam scan N probes |
| This function is called through dynamic setConfig callback function |
| to update roam scan N probes |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nProbes number of probe requests to be sent out |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_roam_scan_n_probes(tHalHandle hHal, uint8_t sessionId, |
| const uint8_t nProbes) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_N_PROBES, |
| NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: gRoamScanNProbes is changed from %d to %d", |
| __func__, pMac->roam.configParam.nProbes, nProbes); |
| pMac->roam.configParam.nProbes = nProbes; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_NPROBES_CHANGED); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_roam_scan_home_away_time |
| \brief function to update roam scan Home away time |
| This function is called through dynamic setConfig callback function |
| to update roam scan home away time |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nRoamScanAwayTime Scan home away time |
| \param bSendOffloadCmd If true then send offload command to firmware |
| If false then command is not sent to firmware |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_roam_scan_home_away_time(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint16_t nRoamScanHomeAwayTime, |
| const bool bSendOffloadCmd) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_UPDATE_ROAM_SCAN_HOME_AWAY_TIME, |
| NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: gRoamScanHomeAwayTime is changed from %d to %d", |
| __func__, |
| pMac->roam.configParam.nRoamScanHomeAwayTime, |
| nRoamScanHomeAwayTime); |
| pMac->roam.configParam.nRoamScanHomeAwayTime = |
| nRoamScanHomeAwayTime; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_HOME_AWAY_TIME_CHANGED); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_ext_change_channel()- function to post send ECSA |
| * action frame to csr. |
| * @hHal: Hal context |
| * @channel: new channel to switch |
| * @session_id: senssion it should be sent on. |
| * |
| * This function is called to post ECSA frame to csr. |
| * |
| * Return: success if msg is sent else return failure |
| */ |
| QDF_STATUS sme_ext_change_channel(tHalHandle h_hal, uint32_t channel, |
| uint8_t session_id) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); |
| uint8_t channel_state; |
| |
| sms_log(mac_ctx, LOGE, FL(" Set Channel %d "), channel); |
| channel_state = |
| cds_get_channel_state(channel); |
| |
| if (CHANNEL_STATE_DISABLE == channel_state) { |
| sms_log(mac_ctx, LOGE, FL(" Invalid channel %d "), channel); |
| return QDF_STATUS_E_INVAL; |
| } |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| /* update the channel list to the firmware */ |
| status = csr_send_ext_change_channel(mac_ctx, |
| channel, session_id); |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_roam_intra_band |
| \brief get Intra band roaming |
| \param hHal - HAL handle for device |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| bool sme_get_roam_intra_band(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0)); |
| return pMac->roam.configParam.nRoamIntraBand; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_roam_scan_n_probes |
| \brief get N Probes |
| \param hHal - HAL handle for device |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_scan_n_probes(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.nProbes; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_roam_scan_home_away_time |
| \brief get Roam scan home away time |
| \param hHal - HAL handle for device |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| uint16_t sme_get_roam_scan_home_away_time(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.nRoamScanHomeAwayTime; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_roam_rssi_diff |
| \brief Update RoamRssiDiff |
| This function is called through dynamic setConfig callback function |
| to configure RoamRssiDiff |
| Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125] |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param RoamRssiDiff - minimum rssi difference between potential |
| candidate and current AP. |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId, |
| uint8_t RoamRssiDiff) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set roam rssi diff to %d - old value is %d - roam state is %s", |
| RoamRssiDiff, |
| pMac->roam.configParam.RoamRssiDiff, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_RSSI_DIFF_CHANGED); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_fast_transition_enabled() - enable/disable Fast Transition |
| support at runtime |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| isFastTransitionEnabled. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update isFastTransitionEnabled config |
| successfully. |
| Other status means SME is failed to update isFastTransitionEnabled. |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_fast_transition_enabled(tHalHandle hHal, |
| bool isFastTransitionEnabled) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION, |
| 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: FastTransitionEnabled is changed from %d to %d", |
| __func__, |
| pMac->roam.configParam.isFastTransitionEnabled, |
| isFastTransitionEnabled); |
| pMac->roam.configParam.isFastTransitionEnabled = |
| isFastTransitionEnabled; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_wes_mode |
| \brief Update WES Mode |
| This function is called through dynamic setConfig callback function |
| to configure isWESModeEnabled |
| \param hHal - HAL handle for device |
| \param isWESModeEnabled - WES mode |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS - SME update isWESModeEnabled config successfully. |
| Other status means SME is failed to update isWESModeEnabled. |
| -------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled, |
| uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set WES Mode to %d - old value is %d - roam state is %s", |
| isWESModeEnabled, |
| pMac->roam.configParam.isWESModeEnabled, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_scan_control |
| \brief Set roam scan control |
| This function is called to set roam scan control |
| if roam scan control is set to 0, roaming scan cache is cleared |
| any value other than 0 is treated as invalid value |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS - SME update config successfully. |
| Other status means SME failure to update |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId, |
| bool roamScanControl) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set roam scan control to %d - old value is %d - roam state is %s", |
| roamScanControl, |
| pMac->roam.configParam.nRoamScanControl, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pMac->roam.configParam.nRoamScanControl = roamScanControl; |
| if (0 == roamScanControl) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully cleared roam scan cache"); |
| csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId); |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_FLUSH_CHANNEL_LIST); |
| } |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_is_fast_roam_ini_feature_enabled() - enable/disable LFR |
| support at runtime |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| isFastRoamIniFeatureEnabled. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config |
| successfully. |
| Other status means SME is failed to update isFastRoamIniFeatureEnabled. |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_is_fast_roam_ini_feature_enabled |
| (tHalHandle hHal, |
| uint8_t sessionId, const bool isFastRoamIniFeatureEnabled) { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (pMac->roam.configParam.isFastRoamIniFeatureEnabled == |
| isFastRoamIniFeatureEnabled) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", |
| __func__, |
| pMac->roam.configParam.isFastRoamIniFeatureEnabled, |
| isFastRoamIniFeatureEnabled); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "%s: FastRoamEnabled is changed from %d to %d", __func__, |
| pMac->roam.configParam.isFastRoamIniFeatureEnabled, |
| isFastRoamIniFeatureEnabled); |
| pMac->roam.configParam.isFastRoamIniFeatureEnabled = |
| isFastRoamIniFeatureEnabled; |
| csr_neighbor_roam_update_fast_roaming_enabled(pMac, sessionId, |
| isFastRoamIniFeatureEnabled); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_is_mawc_ini_feature_enabled() - |
| Enable/disable LFR MAWC support at runtime |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| isMAWCIniFeatureEnabled. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update MAWCEnabled config successfully. |
| Other status means SME is failed to update MAWCEnabled. |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_is_mawc_ini_feature_enabled(tHalHandle hHal, |
| const bool MAWCEnabled) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: MAWCEnabled is changed from %d to %d", __func__, |
| pMac->roam.configParam.MAWCEnabled, MAWCEnabled); |
| pMac->roam.configParam.MAWCEnabled = MAWCEnabled; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_stop_roaming() - Stop roaming for a given sessionId |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS on success |
| Other status on failure |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_STOP, |
| reason); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_start_roaming() - Start roaming for a given sessionId |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS on success |
| Other status on failure |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_start_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_START, |
| reason); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_enable_fast_roam_in_concurrency() - enable/disable LFR if |
| Concurrent session exists |
| This is a synchronuous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS |
| Other status means SME is failed |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_enable_fast_roam_in_concurrency(tHalHandle hHal, |
| bool |
| bFastRoamInConIniFeatureEnabled) |
| { |
| |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = |
| bFastRoamInConIniFeatureEnabled; |
| if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = |
| 0; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_config_fw_rssi_monitoring() - enable/disable firmware RSSI |
| Monitoring at runtime |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| fEnableFwRssiMonitoring. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring. |
| config successfully. |
| Other status means SME is failed to update fEnableFwRssiMonitoring. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_config_fw_rssi_monitoring(tHalHandle hHal, |
| bool fEnableFwRssiMonitoring) |
| { |
| QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; |
| |
| if (sme_cfg_set_int (hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, |
| fEnableFwRssiMonitoring) == QDF_STATUS_E_FAILURE) { |
| qdf_ret_status = QDF_STATUS_E_FAILURE; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Could not pass on WNI_CFG_PS_RSSI_MONITOR to CFG"); |
| } |
| |
| return qdf_ret_status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_opportunistic_scan_threshold_diff |
| \brief Update Opportunistic Scan threshold diff |
| This function is called through dynamic setConfig callback function |
| to configure nOpportunisticThresholdDiff |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nOpportunisticThresholdDiff - Opportunistic Scan threshold diff |
| \return QDF_STATUS_SUCCESS - SME update nOpportunisticThresholdDiff config |
| successfully. |
| else SME is failed to update nOpportunisticThresholdDiff. |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_opportunistic_scan_threshold_diff(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint8_t |
| nOpportunisticThresholdDiff) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, sessionId, |
| nOpportunisticThresholdDiff, |
| REASON_OPPORTUNISTIC_THRESH_DIFF_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nOpportunisticThresholdDiff = |
| nOpportunisticThresholdDiff; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \fn sme_get_roam_opportunistic_scan_threshold_diff() |
| \brief gets Opportunistic Scan threshold diff |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return uint8_t - nOpportunisticThresholdDiff |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_opportunistic_scan_threshold_diff(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig. |
| nOpportunisticThresholdDiff; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_rescan_rssi_diff |
| \brief Update roam rescan rssi diff |
| This function is called through dynamic setConfig callback function |
| to configure nRoamRescanRssiDiff |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nRoamRescanRssiDiff - roam rescan rssi diff |
| \return QDF_STATUS_SUCCESS - SME update nRoamRescanRssiDiff config |
| successfully. |
| else SME is failed to update nRoamRescanRssiDiff. |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_rescan_rssi_diff(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint8_t nRoamRescanRssiDiff) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, sessionId, |
| nRoamRescanRssiDiff, |
| REASON_ROAM_RESCAN_RSSI_DIFF_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nRoamRescanRssiDiff = nRoamRescanRssiDiff; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \fn sme_get_roam_rescan_rssi_diff |
| \brief gets roam rescan rssi diff |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return int8_t - nRoamRescanRssiDiff |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_rescan_rssi_diff(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig.nRoamRescanRssiDiff; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_bmiss_first_bcnt |
| \brief Update Roam count for first beacon miss |
| This function is called through dynamic setConfig callback function |
| to configure nRoamBmissFirstBcnt |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nRoamBmissFirstBcnt - Roam first bmiss count |
| \return QDF_STATUS_SUCCESS - SME update nRoamBmissFirstBcnt |
| successfully. |
| else SME is failed to update nRoamBmissFirstBcnt |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_bmiss_first_bcnt(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint8_t nRoamBmissFirstBcnt) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, sessionId, |
| nRoamBmissFirstBcnt, |
| REASON_ROAM_BMISS_FIRST_BCNT_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nRoamBmissFirstBcnt = nRoamBmissFirstBcnt; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_roam_bmiss_first_bcnt |
| \brief get neighbor roam beacon miss first count |
| \param hHal - The handle returned by mac_open. |
| \return uint8_t - neighbor roam beacon miss first count |
| -------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_bmiss_first_bcnt(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFirstBcnt; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_bmiss_final_bcnt |
| \brief Update Roam count for final beacon miss |
| This function is called through dynamic setConfig callback function |
| to configure nRoamBmissFinalBcnt |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nRoamBmissFinalBcnt - Roam final bmiss count |
| \return QDF_STATUS_SUCCESS - SME update nRoamBmissFinalBcnt |
| successfully. |
| else SME is failed to update nRoamBmissFinalBcnt |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_bmiss_final_bcnt(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint8_t nRoamBmissFinalBcnt) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, sessionId, |
| nRoamBmissFinalBcnt, |
| REASON_ROAM_BMISS_FINAL_BCNT_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nRoamBmissFinalBcnt = nRoamBmissFinalBcnt; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \fn sme_get_roam_bmiss_final_bcnt |
| \brief gets Roam count for final beacon miss |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return uint8_t - nRoamBmissFinalBcnt |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_bmiss_final_bcnt(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig.nRoamBmissFinalBcnt; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_roam_beacon_rssi_weight |
| \brief Update Roam beacon rssi weight |
| This function is called through dynamic setConfig callback function |
| to configure nRoamBeaconRssiWeight |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nRoamBeaconRssiWeight - Roam beacon rssi weight |
| \return QDF_STATUS_SUCCESS - SME update nRoamBeaconRssiWeight config |
| successfully. |
| else SME is failed to update nRoamBeaconRssiWeight |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_roam_beacon_rssi_weight(tHalHandle hHal, |
| uint8_t sessionId, |
| const uint8_t nRoamBeaconRssiWeight) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, sessionId, |
| nRoamBeaconRssiWeight, |
| REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nRoamBeaconRssiWeight = nRoamBeaconRssiWeight; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \fn sme_get_roam_beacon_rssi_weight |
| \brief gets Roam beacon rssi weight |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return uint8_t - nRoamBeaconRssiWeight |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_beacon_rssi_weight(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig.nRoamBeaconRssiWeight; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_set_neighbor_lookup_rssi_threshold() - update neighbor lookup |
| rssi threshold |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS - SME update config successful. |
| Other status means SME is failed to update |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_neighbor_lookup_rssi_threshold |
| (tHalHandle hHal, uint8_t sessionId, uint8_t neighborLookupRssiThreshold) { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_neighbor_roam_update_config(pMac, |
| sessionId, neighborLookupRssiThreshold, |
| REASON_LOOKUP_THRESH_CHANGED); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborLookupRssiThreshold = |
| neighborLookupRssiThreshold; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_set_delay_before_vdev_stop() - update delay before VDEV_STOP |
| This is a synchronous call |
| \param hal - The handle returned by macOpen. |
| \param session_id - Session Identifier |
| \param delay_before_vdev_stop - value to be set |
| \return QDF_STATUS_SUCCESS - SME update config successful. |
| Other status means SME is failed to update |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal, |
| uint8_t session_id, |
| uint8_t delay_before_vdev_stop) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_DEBUG, |
| FL("LFR param delay_before_vdev_stop changed from %d to %d"), |
| pMac->roam.configParam.neighborRoamConfig. |
| delay_before_vdev_stop, |
| delay_before_vdev_stop); |
| pMac->roam.neighborRoamInfo[session_id].cfgParams. |
| delay_before_vdev_stop = delay_before_vdev_stop; |
| pMac->roam.configParam.neighborRoamConfig. |
| delay_before_vdev_stop = delay_before_vdev_stop; |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_neighbor_lookup_rssi_threshold() - get neighbor lookup |
| rssi threshold |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update config successful. |
| Other status means SME is failed to update |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_neighbor_lookup_rssi_threshold(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig. |
| nNeighborLookupRssiThreshold; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_set_neighbor_scan_refresh_period() - set neighbor scan results |
| refresh period |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return QDF_STATUS_SUCCESS - SME update config successful. |
| Other status means SME is failed to update |
| \sa |
| --------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_neighbor_scan_refresh_period |
| (tHalHandle hHal, |
| uint8_t sessionId, uint16_t neighborScanResultsRefreshPeriod) { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pNeighborRoamConfig = |
| &pMac->roam.configParam.neighborRoamConfig; |
| pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set roam scan refresh period to %d- old value is %d - roam state is %s", |
| neighborScanResultsRefreshPeriod, |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborResultsRefreshPeriod, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pNeighborRoamConfig->nNeighborResultsRefreshPeriod = |
| neighborScanResultsRefreshPeriod; |
| pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = |
| neighborScanResultsRefreshPeriod; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_roam_scan_offload_enabled() - enable/disable roam scan |
| offload feaure |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| gRoamScanOffloadEnabled. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update config successfully. |
| Other status means SME is failed to update. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_roam_scan_offload_enabled(tHalHandle hHal, |
| bool nRoamScanOffloadEnabled) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| FL |
| ("gRoamScanOffloadEnabled is changed from %d to %d"), |
| pMac->roam.configParam.isRoamOffloadScanEnabled, |
| nRoamScanOffloadEnabled); |
| pMac->roam.configParam.isRoamOffloadScanEnabled = |
| nRoamScanOffloadEnabled; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_neighbor_scan_refresh_period() - get neighbor scan results |
| refresh period |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return uint16_t - Neighbor scan results refresh period value |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint16_t sme_get_neighbor_scan_refresh_period(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig. |
| nNeighborResultsRefreshPeriod; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_empty_scan_refresh_period() - get empty scan refresh period |
| This is a synchronuous call |
| \param hHal - The handle returned by mac_open. |
| \return QDF_STATUS_SUCCESS - SME update config successful. |
| Other status means SME is failed to update |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint16_t sme_get_empty_scan_refresh_period(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.neighborRoamConfig. |
| nEmptyScanRefreshPeriod; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_empty_scan_refresh_period |
| \brief Update nEmptyScanRefreshPeriod |
| This function is called through dynamic setConfig callback function |
| to configure nEmptyScanRefreshPeriod |
| Usage: adb shell iwpriv wlan0 setConfig |
| nEmptyScanRefreshPeriod=[0 .. 60] |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nEmptyScanRefreshPeriod - scan period following empty scan results. |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t sessionId, |
| uint16_t nEmptyScanRefreshPeriod) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pNeighborRoamConfig = |
| &pMac->roam.configParam.neighborRoamConfig; |
| pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set roam scan period to %d -old value is %d - roam state is %s", |
| nEmptyScanRefreshPeriod, |
| pMac->roam.configParam.neighborRoamConfig. |
| nEmptyScanRefreshPeriod, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pNeighborRoamConfig->nEmptyScanRefreshPeriod = |
| nEmptyScanRefreshPeriod; |
| pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = |
| nEmptyScanRefreshPeriod; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_EMPTY_SCAN_REF_PERIOD_CHANGED); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_neighbor_scan_min_chan_time |
| \brief Update nNeighborScanMinChanTime |
| This function is called through dynamic setConfig callback function |
| to configure gNeighborScanChannelMinTime |
| Usage: adb shell iwpriv wlan0 setConfig |
| gNeighborScanChannelMinTime=[0 .. 60] |
| \param hHal - HAL handle for device |
| \param nNeighborScanMinChanTime - Channel minimum dwell time |
| \param sessionId - Session Identifier |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal, |
| const uint16_t |
| nNeighborScanMinChanTime, |
| uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set channel min dwell time to %d - old value is %d - roam state is %s", |
| nNeighborScanMinChanTime, |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborScanMinChanTime, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborScanMinChanTime = nNeighborScanMinChanTime; |
| pMac->roam.neighborRoamInfo[sessionId].cfgParams. |
| minChannelScanTime = nNeighborScanMinChanTime; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_neighbor_scan_max_chan_time |
| \brief Update nNeighborScanMaxChanTime |
| This function is called through dynamic setConfig callback function |
| to configure gNeighborScanChannelMaxTime |
| Usage: adb shell iwpriv wlan0 setConfig |
| gNeighborScanChannelMaxTime=[0 .. 60] |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nNeighborScanMinChanTime - Channel maximum dwell time |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId, |
| const uint16_t |
| nNeighborScanMaxChanTime) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pNeighborRoamConfig = |
| &pMac->roam.configParam.neighborRoamConfig; |
| pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set channel max dwell time to %d - old value is %d - roam state is %s", |
| nNeighborScanMaxChanTime, |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborScanMaxChanTime, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pNeighborRoamConfig->nNeighborScanMaxChanTime = |
| nNeighborScanMaxChanTime; |
| pNeighborRoamInfo->cfgParams.maxChannelScanTime = |
| nNeighborScanMaxChanTime; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_SCAN_CH_TIME_CHANGED); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_neighbor_scan_min_chan_time |
| \brief get neighbor scan min channel time |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint16_t - channel min time value |
| -------------------------------------------------------------------------*/ |
| uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.neighborRoamInfo[sessionId].cfgParams. |
| minChannelScanTime; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_neighbor_roam_state |
| \brief get neighbor roam state |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint32_t - neighbor roam state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_current_roam_state |
| \brief get current roam state |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint32_t - current roam state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_current_roam_state(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.curState[sessionId]; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_current_roam_sub_state |
| \brief get neighbor roam sub state |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint32_t - current roam sub state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_current_roam_sub_state(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.curSubState[sessionId]; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_lim_sme_state |
| \brief get Lim Sme state |
| \param hHal - The handle returned by mac_open. |
| \return uint32_t - Lim Sme state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_lim_sme_state(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->lim.gLimSmeState; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_lim_mlm_state |
| \brief get Lim Mlm state |
| \param hHal - The handle returned by mac_open. |
| \return uint32_t - Lim Mlm state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_lim_mlm_state(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->lim.gLimMlmState; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_is_lim_session_valid |
| \brief is Lim session valid |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return bool - true or false |
| -------------------------------------------------------------------------*/ |
| bool sme_is_lim_session_valid(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (sessionId > pMac->lim.maxBssId) |
| return false; |
| |
| return pMac->lim.gpSession[sessionId].valid; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_lim_sme_session_state |
| \brief get Lim Sme session state |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint32_t - Lim Sme session state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_lim_sme_session_state(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->lim.gpSession[sessionId].limSmeState; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_lim_mlm_session_state |
| \brief get Lim Mlm session state |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint32_t - Lim Mlm session state |
| -------------------------------------------------------------------------*/ |
| uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->lim.gpSession[sessionId].limMlmState; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_neighbor_scan_max_chan_time |
| \brief get neighbor scan max channel time |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint16_t - channel max time value |
| -------------------------------------------------------------------------*/ |
| uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.neighborRoamInfo[sessionId].cfgParams. |
| maxChannelScanTime; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_neighbor_scan_period |
| \brief Update nNeighborScanPeriod |
| This function is called through dynamic setConfig callback function |
| to configure nNeighborScanPeriod |
| Usage: adb shell iwpriv wlan0 setConfig |
| nNeighborScanPeriod=[0 .. 1000] |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param nNeighborScanPeriod - neighbor scan period |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId, |
| const uint16_t nNeighborScanPeriod) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pNeighborRoamConfig = |
| &pMac->roam.configParam.neighborRoamConfig; |
| pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set neighbor scan period to %d" |
| " - old value is %d - roam state is %s", |
| nNeighborScanPeriod, |
| pMac->roam.configParam.neighborRoamConfig. |
| nNeighborScanTimerPeriod, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pNeighborRoamConfig->nNeighborScanTimerPeriod = |
| nNeighborScanPeriod; |
| pNeighborRoamInfo->cfgParams.neighborScanPeriod = |
| nNeighborScanPeriod; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_SCAN_HOME_TIME_CHANGED); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_neighbor_scan_period |
| \brief get neighbor scan period |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return uint16_t - neighbor scan period |
| -------------------------------------------------------------------------*/ |
| uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.neighborRoamInfo[sessionId].cfgParams. |
| neighborScanPeriod; |
| } |
| |
| |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_roam_rssi_diff() - get Roam rssi diff |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return uint16_t - Rssi diff value |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_roam_rssi_diff(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.RoamRssiDiff; |
| } |
| |
| /** |
| * sme_change_roam_scan_channel_list() - to change scan channel list |
| * @hHal: pointer HAL handle returned by mac_open |
| * @sessionId: sme session id |
| * @pChannelList: Output channel list |
| * @numChannels: Output number of channels |
| * |
| * This routine is called to Change roam scan channel list. |
| * This is a synchronous call |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId, |
| uint8_t *pChannelList, |
| uint8_t numChannels) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = |
| &pMac->roam.neighborRoamInfo[sessionId]; |
| uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; |
| uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; |
| uint8_t i = 0, j = 0; |
| tCsrChannelInfo *chan_info; |
| |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_CHANNEL_LIST_CHANGED); |
| return status; |
| } |
| chan_info = &pNeighborRoamInfo->cfgParams.channelInfo; |
| |
| if (NULL != chan_info->ChannelList) { |
| for (i = 0; i < chan_info->numOfChannels; i++) { |
| if (j < sizeof(oldChannelList)) |
| j += snprintf(oldChannelList + j, |
| sizeof(oldChannelList) - |
| j, "%d", |
| chan_info->ChannelList[i]); |
| else |
| break; |
| } |
| } |
| csr_flush_cfg_bg_scan_roam_channel_list(pMac, sessionId); |
| csr_create_bg_scan_roam_channel_list(pMac, sessionId, pChannelList, |
| numChannels); |
| sme_set_roam_scan_control(hHal, sessionId, 1); |
| if (NULL != chan_info->ChannelList) { |
| j = 0; |
| for (i = 0; i < chan_info->numOfChannels; i++) { |
| if (j < sizeof(newChannelList)) |
| j += snprintf(newChannelList + j, |
| sizeof(newChannelList) - |
| j, " %d", |
| chan_info->ChannelList[i]); |
| else |
| break; |
| } |
| } |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| FL("LFR runtime successfully set roam scan channels to %s - old value is %s - roam state is %d"), |
| newChannelList, oldChannelList, |
| pMac->roam.neighborRoamInfo[sessionId].neighborRoamState); |
| sme_release_global_lock(&pMac->sme); |
| |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_CHANNEL_LIST_CHANGED); |
| return status; |
| } |
| |
| /** |
| * sme_get_roam_scan_channel_list() - To get roam scan channel list |
| * @hHal: HAL pointer |
| * @pChannelList: Output channel list |
| * @pNumChannels: Output number of channels |
| * @sessionId: Session Identifier |
| * |
| * To get roam scan channel list This is a synchronous call |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal, |
| uint8_t *pChannelList, uint8_t *pNumChannels, |
| uint8_t sessionId) |
| { |
| int i = 0; |
| uint8_t *pOutPtr = pChannelList; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tpCsrNeighborRoamControlInfo pNeighborRoamInfo = |
| &pMac->roam.neighborRoamInfo[sessionId]; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN, |
| FL("Roam Scan channel list is NOT yet initialized")); |
| *pNumChannels = 0; |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| *pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; |
| for (i = 0; i < (*pNumChannels); i++) { |
| pOutPtr[i] = |
| pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]; |
| } |
| pOutPtr[i] = '\0'; |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_is_ese_feature_enabled() - get ESE feature enabled or not |
| This is a synchronuous call |
| \param hHal - The handle returned by mac_open. |
| \return true (1) - if the ESE feature is enabled |
| false (0) - if feature is disabled (compile or runtime) |
| \sa |
| --------------------------------------------------------------------------*/ |
| bool sme_get_is_ese_feature_enabled(tHalHandle hHal) |
| { |
| #ifdef FEATURE_WLAN_ESE |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return csr_roam_is_ese_ini_feature_enabled(pMac); |
| #else |
| return false; |
| #endif |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_wes_mode() - get WES Mode |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return uint8_t - WES Mode Enabled(1)/Disabled(0) |
| \sa |
| --------------------------------------------------------------------------*/ |
| bool sme_get_wes_mode(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.isWESModeEnabled; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_roam_scan_control() - get scan control |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return bool - Enabled(1)/Disabled(0) |
| \sa |
| --------------------------------------------------------------------------*/ |
| bool sme_get_roam_scan_control(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.nRoamScanControl; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_is_lfr_feature_enabled() - get LFR feature enabled or not |
| This is a synchronuous call |
| \param hHal - The handle returned by mac_open. |
| \return true (1) - if the feature is enabled |
| false (0) - if feature is disabled (compile or runtime) |
| \sa |
| --------------------------------------------------------------------------*/ |
| bool sme_get_is_lfr_feature_enabled(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.isFastRoamIniFeatureEnabled; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_is_ft_feature_enabled() - get FT feature enabled or not |
| This is a synchronuous call |
| \param hHal - The handle returned by mac_open. |
| \return true (1) - if the feature is enabled |
| false (0) - if feature is disabled (compile or runtime) |
| \sa |
| --------------------------------------------------------------------------*/ |
| bool sme_get_is_ft_feature_enabled(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.isFastTransitionEnabled; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_is_feature_supported_by_fw |
| \brief Check if an feature is enabled by FW |
| |
| \param feattEnumValue - Enumeration value from placeHolderInCapBitmap |
| \- return 1/0 (true/false) |
| -------------------------------------------------------------------------*/ |
| uint8_t sme_is_feature_supported_by_fw(uint8_t featEnumValue) |
| { |
| return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue); |
| } |
| |
| #ifdef FEATURE_WLAN_TDLS |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_send_tdls_link_establish_params |
| \brief API to send TDLS Peer Link Establishment Parameters. |
| |
| \param peerMac - peer's Mac Adress. |
| \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters |
| \- return QDF_STATUS_SUCCES |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_send_tdls_link_establish_params(tHalHandle hHal, |
| uint8_t sessionId, |
| const tSirMacAddr peerMac, |
| tCsrTdlsLinkEstablishParams * |
| tdlsLinkEstablishParams) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM, |
| sessionId, |
| tdlsLinkEstablishParams->isOffChannelSupported)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_tdls_send_link_establish_params(hHal, sessionId, |
| peerMac, tdlsLinkEstablishParams); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_send_tdls_mgmt_frame |
| \brief API to send TDLS management frames. |
| |
| \param peerMac - peer's Mac Adress. |
| \param frame_type - Type of TDLS mgmt frame to be sent. |
| \param dialog - dialog token used in the frame. |
| \param status - status to be incuded in the frame. |
| \param peerCapability - peer cpabilities |
| \param buf - additional IEs to be included |
| \param len - lenght of additional Ies |
| \param responder - Tdls request type |
| \- return QDF_STATUS_SUCCES |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_send_tdls_mgmt_frame(tHalHandle hHal, uint8_t sessionId, |
| const tSirMacAddr peerMac, |
| uint8_t frame_type, |
| uint8_t dialog, uint16_t statusCode, |
| uint32_t peerCapability, uint8_t *buf, |
| uint8_t len, uint8_t responder) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrTdlsSendMgmt sendTdlsReq = { {0} }; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME, |
| sessionId, statusCode)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| qdf_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr)); |
| sendTdlsReq.frameType = frame_type; |
| sendTdlsReq.buf = buf; |
| sendTdlsReq.len = len; |
| sendTdlsReq.dialog = dialog; |
| sendTdlsReq.statusCode = statusCode; |
| sendTdlsReq.responder = responder; |
| sendTdlsReq.peerCapability = peerCapability; |
| |
| status = csr_tdls_send_mgmt_req(hHal, sessionId, &sendTdlsReq); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_change_tdls_peer_sta |
| \brief API to Update TDLS peer sta parameters. |
| |
| \param peerMac - peer's Mac Adress. |
| \param staParams - Peer Station Parameters |
| \- return QDF_STATUS_SUCCES |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_change_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId, |
| const tSirMacAddr peerMac, |
| tCsrStaParams *pstaParams) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pstaParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s :pstaParams is NULL", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA, |
| sessionId, pstaParams->capability)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_tdls_change_peer_sta(hHal, sessionId, peerMac, |
| pstaParams); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_add_tdls_peer_sta |
| \brief API to Add TDLS peer sta entry. |
| |
| \param peerMac - peer's Mac Adress. |
| \- return QDF_STATUS_SUCCES |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_add_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId, |
| const tSirMacAddr peerMac) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_tdls_add_peer_sta(hHal, sessionId, peerMac); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_delete_tdls_peer_sta |
| \brief API to Delete TDLS peer sta entry. |
| |
| \param peerMac - peer's Mac Adress. |
| \- return QDF_STATUS_SUCCES |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_delete_tdls_peer_sta(tHalHandle hHal, uint8_t sessionId, |
| const tSirMacAddr peerMac) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA, |
| sessionId, 0)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_tdls_del_peer_sta(hHal, sessionId, peerMac); |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_tdls_power_save_prohibited |
| \API to set/reset the is_tdls_power_save_prohibited. |
| |
| \- return void |
| -------------------------------------------------------------------------*/ |
| void sme_set_tdls_power_save_prohibited(tHalHandle hHal, uint32_t sessionId, |
| bool val) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info; |
| struct ps_params *ps_param = &ps_global_info->ps_params[sessionId]; |
| ps_param->is_tdls_power_save_prohibited = val; |
| return; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_fw_tdls_state |
| |
| \brief |
| SME will send message to WMA to set TDLS state in f/w |
| |
| \param |
| |
| hHal - The handle returned by mac_open |
| |
| psmeTdlsParams - TDLS state info to update in f/w |
| |
| useSmeLock - Need to acquire SME Global Lock before state update or not |
| |
| \return QDF_STATUS |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_update_fw_tdls_state(tHalHandle hHal, void *psmeTdlsParams, |
| bool useSmeLock) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = NULL; |
| cds_msg_t cds_message; |
| |
| pMac = PMAC_STRUCT(hHal); |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("pMac is Null")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /* only acquire sme global lock before state update if asked to */ |
| if (useSmeLock) { |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS != status) |
| return status; |
| } |
| |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = psmeTdlsParams; |
| cds_message.type = WMA_UPDATE_FW_TDLS_STATE; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| /* release the lock if it was acquired */ |
| if (useSmeLock) |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_update_tdls_peer_state() - to update the state of TDLS peer |
| * @hHal: The handle returned by mac_open |
| * @peerStateParams: TDLS Peer state info to update in f/w |
| * |
| * SME will send message to WMA to set TDLS Peer state in f/w |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, |
| tSmeTdlsPeerStateParams *peerStateParams) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tTdlsPeerStateParams *pTdlsPeerStateParams = NULL; |
| tTdlsPeerCapParams *peer_cap = NULL; |
| cds_msg_t cds_message; |
| uint8_t num; |
| uint8_t peer_chan_len; |
| uint8_t chanId; |
| uint8_t i; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| pTdlsPeerStateParams = qdf_mem_malloc(sizeof(*pTdlsPeerStateParams)); |
| if (NULL == pTdlsPeerStateParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("failed to allocate mem for tdls peer state param")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams)); |
| qdf_mem_copy(&pTdlsPeerStateParams->peerMacAddr, |
| &peerStateParams->peerMacAddr, sizeof(tSirMacAddr)); |
| pTdlsPeerStateParams->vdevId = peerStateParams->vdevId; |
| pTdlsPeerStateParams->peerState = peerStateParams->peerState; |
| |
| switch (peerStateParams->peerState) { |
| case eSME_TDLS_PEER_STATE_PEERING: |
| pTdlsPeerStateParams->peerState = |
| WMA_TDLS_PEER_STATE_PEERING; |
| break; |
| |
| case eSME_TDLS_PEER_STATE_CONNECTED: |
| pTdlsPeerStateParams->peerState = |
| WMA_TDLS_PEER_STATE_CONNECTED; |
| break; |
| |
| case eSME_TDLS_PEER_STATE_TEARDOWN: |
| pTdlsPeerStateParams->peerState = |
| WMA_TDLS_PEER_STATE_TEARDOWN; |
| break; |
| |
| case eSME_TDLS_PEER_ADD_MAC_ADDR: |
| pTdlsPeerStateParams->peerState = WMA_TDLS_PEER_ADD_MAC_ADDR; |
| break; |
| |
| case eSME_TDLS_PEER_REMOVE_MAC_ADDR: |
| pTdlsPeerStateParams->peerState = WMA_TDLS_PEER_REMOVE_MAC_ADDR; |
| break; |
| |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("invalid peer state param (%d)"), |
| peerStateParams->peerState); |
| goto error_return; |
| } |
| peer_cap = &(pTdlsPeerStateParams->peerCap); |
| peer_cap->isPeerResponder = |
| peerStateParams->peerCap.isPeerResponder; |
| peer_cap->peerUapsdQueue = |
| peerStateParams->peerCap.peerUapsdQueue; |
| peer_cap->peerMaxSp = |
| peerStateParams->peerCap.peerMaxSp; |
| peer_cap->peerBuffStaSupport = |
| peerStateParams->peerCap.peerBuffStaSupport; |
| peer_cap->peerOffChanSupport = |
| peerStateParams->peerCap.peerOffChanSupport; |
| peer_cap->peerCurrOperClass = |
| peerStateParams->peerCap.peerCurrOperClass; |
| peer_cap->selfCurrOperClass = |
| peerStateParams->peerCap.selfCurrOperClass; |
| |
| num = 0; |
| peer_chan_len = peerStateParams->peerCap.peerChanLen; |
| |
| if (peer_chan_len >= 0 && |
| peer_chan_len <= SME_TDLS_MAX_SUPP_CHANNELS) { |
| for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) { |
| chanId = peerStateParams->peerCap.peerChan[i]; |
| if (csr_roam_is_channel_valid(pMac, chanId) && |
| !(cds_get_channel_state(chanId) == |
| CHANNEL_STATE_DFS) && |
| !cds_is_dsrc_channel(cds_chan_to_freq(chanId))) { |
| peer_cap->peerChan[num].chanId = chanId; |
| peer_cap->peerChan[num].pwr = |
| csr_get_cfg_max_tx_power(pMac, chanId); |
| peer_cap->peerChan[num].dfsSet = false; |
| num++; |
| } |
| } |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("invalid peer channel len (%d)"), |
| peer_chan_len); |
| goto error_return; |
| } |
| |
| peer_cap->peerChanLen = num; |
| peer_cap->peerOperClassLen = |
| peerStateParams->peerCap.peerOperClassLen; |
| for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++) { |
| peer_cap->peerOperClass[i] = |
| peerStateParams->peerCap.peerOperClass[i]; |
| } |
| |
| peer_cap->prefOffChanNum = |
| peerStateParams->peerCap.prefOffChanNum; |
| peer_cap->prefOffChanBandwidth = |
| peerStateParams->peerCap.prefOffChanBandwidth; |
| peer_cap->opClassForPrefOffChan = |
| peerStateParams->peerCap.opClassForPrefOffChan; |
| |
| cds_message.type = WMA_UPDATE_TDLS_PEER_STATE; |
| cds_message.reserved = 0; |
| cds_message.bodyptr = pTdlsPeerStateParams; |
| |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("cds_mq_post_message failed ")); |
| goto error_return; |
| } else { |
| goto success_return; |
| } |
| |
| error_return: |
| status = QDF_STATUS_E_FAILURE; |
| qdf_mem_free(pTdlsPeerStateParams); |
| success_return: |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_send_tdls_chan_switch_req() - send tdls channel switch request |
| * @hal: UMAC handler |
| * @ch_switch_params: Pointer to the chan switch parameter structure |
| * |
| * API to set tdls channel switch parameters. |
| * |
| * Return: QDF_STATUS_SUCCESS on success; another QDF_STATUS_** code otherwise |
| */ |
| QDF_STATUS sme_send_tdls_chan_switch_req(tHalHandle hal, |
| sme_tdls_chan_switch_params *ch_switch_params) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| tdls_chan_switch_params *chan_switch_params = NULL; |
| cds_msg_t cds_message; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ, |
| NO_SESSION, ch_switch_params->tdls_off_channel)); |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_STATUS_SUCCESS != status) |
| return status; |
| chan_switch_params = qdf_mem_malloc(sizeof(*chan_switch_params)); |
| if (NULL == chan_switch_params) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("fail to alloc mem for tdls chan switch param")); |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| qdf_mem_zero(chan_switch_params, sizeof(*chan_switch_params)); |
| |
| switch (ch_switch_params->tdls_off_ch_mode) { |
| case ENABLE_CHANSWITCH: |
| chan_switch_params->tdls_sw_mode = WMA_TDLS_ENABLE_OFFCHANNEL; |
| break; |
| |
| case DISABLE_CHANSWITCH: |
| chan_switch_params->tdls_sw_mode = WMA_TDLS_DISABLE_OFFCHANNEL; |
| break; |
| |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("invalid off channel command (%d)"), |
| ch_switch_params->tdls_off_ch_mode); |
| qdf_mem_free(chan_switch_params); |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| qdf_mem_copy(&chan_switch_params->peer_mac_addr, |
| &ch_switch_params->peer_mac_addr, sizeof(tSirMacAddr)); |
| chan_switch_params->vdev_id = ch_switch_params->vdev_id; |
| chan_switch_params->tdls_off_ch = ch_switch_params->tdls_off_channel; |
| chan_switch_params->tdls_off_ch_bw_offset = |
| ch_switch_params->tdls_off_ch_bw_offset; |
| chan_switch_params->is_responder = ch_switch_params->is_responder; |
| chan_switch_params->oper_class = ch_switch_params->opclass; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("Country Code=%s, Req offset=%d, Selected Operate Class=%d"), |
| mac->scan.countryCodeCurrent, |
| chan_switch_params->tdls_off_ch_bw_offset, |
| chan_switch_params->oper_class); |
| |
| cds_message.type = WMA_TDLS_SET_OFFCHAN_MODE; |
| cds_message.reserved = 0; |
| cds_message.bodyptr = chan_switch_params; |
| |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Message Post failed status=%d"), |
| qdf_status); |
| qdf_mem_free(chan_switch_params); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| #endif /* FEATURE_WLAN_TDLS */ |
| |
| QDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq, |
| void *plsContext, |
| void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, |
| void *pContext)) |
| { |
| |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if ((NULL == pCallbackfn) && |
| (NULL == pMac->sme.pLinkSpeedIndCb)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Indication Call back did not registered", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } else if (NULL != pCallbackfn) { |
| pMac->sme.pLinkSpeedCbContext = plsContext; |
| pMac->sme.pLinkSpeedIndCb = pCallbackfn; |
| } |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = lsReq; |
| cds_message.type = WMA_GET_LINK_SPEED; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post Link Speed msg fail", __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| |
| /* |
| * SME API to enable/disable WLAN driver initiated SSR |
| */ |
| void sme_update_enable_ssr(tHalHandle hHal, bool enableSSR) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "SSR level is changed %d", enableSSR); |
| /* not serializing this messsage, as this is only going |
| * to set a variable in WMA/WDI |
| */ |
| WMA_SetEnableSSR(enableSSR); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return; |
| } |
| |
| QDF_STATUS sme_check_ch_in_band(tpAniSirGlobal mac_ctx, uint8_t start_ch, |
| uint8_t ch_cnt) |
| { |
| uint8_t i; |
| for (i = 0; i < ch_cnt; i++) { |
| if (QDF_STATUS_SUCCESS != csr_is_valid_channel(mac_ctx, |
| (start_ch + i*4))) |
| return QDF_STATUS_E_FAILURE; |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /*convert the ini value to the ENUM used in csr and MAC for CB state*/ |
| ePhyChanBondState sme_get_cb_phy_state_from_cb_ini_value(uint32_t cb_ini_value) |
| { |
| return csr_convert_cb_ini_value_to_phy_cb_state(cb_ini_value); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_set_curr_device_mode() - Sets the current operating device mode. |
| \param hHal - The handle returned by mac_open. |
| \param currDeviceMode - Current operating device mode. |
| --------------------------------------------------------------------------*/ |
| |
| void sme_set_curr_device_mode(tHalHandle hHal, |
| enum tQDF_ADAPTER_MODE currDeviceMode) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| pMac->sme.currDeviceMode = currDeviceMode; |
| return; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_handoff_request() - a wrapper function to Request a handoff |
| from CSR. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \param sessionId - Session Identifier |
| \param pHandoffInfo - info provided by HDD with the handoff request (namely: |
| BSSID, channel etc.) |
| \return QDF_STATUS_SUCCESS - SME passed the request to CSR successfully. |
| Other status means SME is failed to send the request. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_handoff_request(tHalHandle hHal, |
| uint8_t sessionId, |
| tCsrHandoffRequest *pHandoffInfo) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: invoked", __func__); |
| status = csr_handoff_request(pMac, sessionId, pHandoffInfo); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| #ifdef IPA_OFFLOAD |
| /* --------------------------------------------------------------------------- |
| \fn sme_ipa_offload_enable_disable |
| \brief API to enable/disable IPA offload |
| \param hal - The handle returned by macOpen. |
| \param session_id - Session Identifier |
| \param request - Pointer to the offload request. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ipa_offload_enable_disable(tHalHandle hal, uint8_t session_id, |
| struct sir_ipa_offload_enable_disable *request) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| struct sir_ipa_offload_enable_disable *request_buf; |
| cds_msg_t msg; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| request_buf = qdf_mem_malloc(sizeof(*request_buf)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for \ |
| IPA_OFFLOAD_ENABLE_DISABLE")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| request_buf->offload_type = request->offload_type; |
| request_buf->vdev_id = request->vdev_id; |
| request_buf->enable = request->enable; |
| |
| msg.type = WMA_IPA_OFFLOAD_ENABLE_DISABLE; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(CDS_MQ_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_IPA_OFFLOAD_\ |
| ENABLE_DISABLE message to WMA")); |
| qdf_mem_free(request_buf); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* IPA_OFFLOAD */ |
| |
| /* |
| * SME API to check if there is any infra station or |
| * P2P client is connected |
| */ |
| QDF_STATUS sme_is_sta_p2p_client_connected(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| if (csr_is_infra_connected(pMac)) { |
| return QDF_STATUS_SUCCESS; |
| } |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| #ifdef FEATURE_WLAN_LPHB |
| /* --------------------------------------------------------------------------- |
| \fn sme_lphb_config_req |
| \API to make configuration LPHB within FW. |
| \param hHal - The handle returned by mac_open |
| \param lphdReq - LPHB request argument by client |
| \param pCallbackfn - LPHB timeout notification callback function pointer |
| \- return Configuration message posting status, SUCCESS or Fail |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_lphb_config_req |
| (tHalHandle hHal, |
| tSirLPHBReq *lphdReq, |
| void (*pCallbackfn)(void *pHddCtx, tSirLPHBInd * indParam) |
| ) { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ, |
| NO_SESSION, lphdReq->cmd)); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) && |
| (NULL == pCallbackfn) && (NULL == pMac->sme.pLphbIndCb)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Indication Call back did not registered", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } else if (NULL != pCallbackfn) { |
| pMac->sme.pLphbIndCb = pCallbackfn; |
| } |
| |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = lphdReq; |
| cds_message.type = WMA_LPHB_CONF_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post Config LPHB MSG fail", __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| #endif /* FEATURE_WLAN_LPHB */ |
| /*-------------------------------------------------------------------------- |
| \brief sme_enable_disable_split_scan() - a wrapper function to set the split |
| scan parameter. |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open |
| \return NONE. |
| \sa |
| --------------------------------------------------------------------------*/ |
| void sme_enable_disable_split_scan(tHalHandle hHal, uint8_t nNumStaChan, |
| uint8_t nNumP2PChan) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan; |
| pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: SCAN nNumStaChanCombinedConc : %d," |
| "nNumP2PChanCombinedConc : %d ", |
| __func__, nNumStaChan, nNumP2PChan); |
| |
| return; |
| |
| } |
| |
| /** |
| * sme_add_periodic_tx_ptrn() - Add Periodic TX Pattern |
| * @hal: global hal handle |
| * @addPeriodicTxPtrnParams: request message |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS |
| sme_add_periodic_tx_ptrn(tHalHandle hal, |
| struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| struct sSirAddPeriodicTxPtrn *req_msg; |
| cds_msg_t msg; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| |
| req_msg = qdf_mem_malloc(sizeof(*req_msg)); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("memory allocation failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *req_msg = *addPeriodicTxPtrnParams; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| msg.bodyptr = req_msg; |
| msg.type = WMA_ADD_PERIODIC_TX_PTRN_IND; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, msg.type)); |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_del_periodic_tx_ptrn() - Delete Periodic TX Pattern |
| * @hal: global hal handle |
| * @delPeriodicTxPtrnParams: request message |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS |
| sme_del_periodic_tx_ptrn(tHalHandle hal, |
| struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| struct sSirDelPeriodicTxPtrn *req_msg; |
| cds_msg_t msg; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| |
| req_msg = qdf_mem_malloc(sizeof(*req_msg)); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("memory allocation failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *req_msg = *delPeriodicTxPtrnParams; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| msg.bodyptr = req_msg; |
| msg.type = WMA_DEL_PERIODIC_TX_PTRN_IND; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, msg.type)); |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_enable_rmc() - enables RMC |
| * @hHal : Pointer to global HAL handle |
| * @sessionId : Session ID |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_enable_rmc(tHalHandle hHal, uint32_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| |
| sms_log(pMac, LOG1, FL("enable RMC")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| cds_message.bodyptr = NULL; |
| cds_message.type = WMA_RMC_ENABLE_IND; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: failed to post message to WMA", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_disable_rmc() - disables RMC |
| * @hHal : Pointer to global HAL handle |
| * @sessionId : Session ID |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_disable_rmc(tHalHandle hHal, uint32_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| |
| sms_log(pMac, LOG1, FL("disable RMC")); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| cds_message.bodyptr = NULL; |
| cds_message.type = WMA_RMC_DISABLE_IND; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: failed to post message to WMA", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_send_rmc_action_period() - sends RMC action period param to target |
| * @hHal : Pointer to global HAL handle |
| * @sessionId : Session ID |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_send_rmc_action_period(tHalHandle hHal, uint32_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| cds_message.bodyptr = NULL; |
| cds_message.type = WMA_RMC_ACTION_PERIOD_IND; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: failed to post message to WMA", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_request_ibss_peer_info() - request ibss peer info |
| * @hHal : Pointer to global HAL handle |
| * @pUserData : Pointer to user data |
| * @peerInfoCbk : Peer info callback |
| * @allPeerInfoReqd : All peer info required or not |
| * @staIdx : sta index |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_request_ibss_peer_info(tHalHandle hHal, void *pUserData, |
| pIbssPeerInfoCb peerInfoCbk, |
| bool allPeerInfoReqd, uint8_t staIdx) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk; |
| pMac->sme.peerInfoParams.pUserData = pUserData; |
| |
| pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *) |
| qdf_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams)); |
| if (NULL == pIbssInfoReqParams) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for dhcp start", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd; |
| pIbssInfoReqParams->staIdx = staIdx; |
| |
| cds_message.type = WMA_GET_IBSS_PEER_INFO_REQ; |
| cds_message.bodyptr = pIbssInfoReqParams; |
| cds_message.reserved = 0; |
| |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (QDF_STATUS_SUCCESS != qdf_status) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post WMA_GET_IBSS_PEER_INFO_REQ MSG failed", |
| __func__); |
| qdf_mem_free(pIbssInfoReqParams); |
| qdf_status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return qdf_status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_send_cesium_enable_ind |
| \brief Used to send proprietary cesium enable indication to fw |
| \param hHal |
| \param sessionId |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_send_cesium_enable_ind(tHalHandle hHal, uint32_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| cds_message.bodyptr = NULL; |
| cds_message.type = WMA_IBSS_CESIUM_ENABLE_IND; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: failed to post message to WMA", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| void sme_get_command_q_status(tHalHandle hHal) |
| { |
| tSmeCmd *pTempCmd = NULL; |
| tListElem *pEntry; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: pMac is NULL", __func__); |
| return; |
| } |
| |
| pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); |
| if (pEntry) { |
| pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| } |
| sms_log(pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)", |
| (pTempCmd) ? pTempCmd->command : eSmeNoCommand); |
| if (pTempCmd) { |
| if (eSmeCsrCommandMask & pTempCmd->command) { |
| /* CSR command is stuck. See what the reason code is for that command */ |
| dump_csr_command_info(pMac, pTempCmd); |
| } |
| } /* if(pTempCmd) */ |
| |
| sms_log(pMac, LOGE, "Currently smeCmdPendingList has %d commands", |
| csr_ll_count(&pMac->sme.smeCmdPendingList)); |
| |
| sms_log(pMac, LOGE, "Currently roamCmdPendingList has %d commands", |
| csr_ll_count(&pMac->roam.roamCmdPendingList)); |
| |
| return; |
| } |
| |
| /** |
| * sme_set_dot11p_config() - API to set the 802.11p config |
| * @hHal: The handle returned by macOpen |
| * @enable_dot11p: 802.11p config param |
| */ |
| void sme_set_dot11p_config(tHalHandle hHal, bool enable_dot11p) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| pMac->enable_dot11p = enable_dot11p; |
| } |
| |
| /** |
| * copy_sir_ocb_config() - Performs deep copy of an OCB configuration |
| * @src: the source configuration |
| * |
| * Return: pointer to the copied OCB configuration |
| */ |
| static struct sir_ocb_config *sme_copy_sir_ocb_config( |
| struct sir_ocb_config *src) |
| { |
| struct sir_ocb_config *dst; |
| uint32_t length; |
| void *cursor; |
| |
| length = sizeof(*src) + |
| src->channel_count * sizeof(*src->channels) + |
| src->schedule_size * sizeof(*src->schedule) + |
| src->dcc_ndl_chan_list_len + |
| src->dcc_ndl_active_state_list_len; |
| |
| dst = qdf_mem_malloc(length); |
| if (!dst) |
| return NULL; |
| |
| *dst = *src; |
| |
| cursor = dst; |
| cursor += sizeof(*dst); |
| dst->channels = cursor; |
| cursor += src->channel_count * sizeof(*src->channels); |
| qdf_mem_copy(dst->channels, src->channels, |
| src->channel_count * sizeof(*src->channels)); |
| dst->schedule = cursor; |
| cursor += src->schedule_size * sizeof(*src->schedule); |
| qdf_mem_copy(dst->schedule, src->schedule, |
| src->schedule_size * sizeof(*src->schedule)); |
| dst->dcc_ndl_chan_list = cursor; |
| cursor += src->dcc_ndl_chan_list_len; |
| qdf_mem_copy(dst->dcc_ndl_chan_list, src->dcc_ndl_chan_list, |
| src->dcc_ndl_chan_list_len); |
| dst->dcc_ndl_active_state_list = cursor; |
| cursor += src->dcc_ndl_active_state_list_len; |
| qdf_mem_copy(dst->dcc_ndl_active_state_list, |
| src->dcc_ndl_active_state_list, |
| src->dcc_ndl_active_state_list_len); |
| return dst; |
| } |
| |
| /** |
| * sme_ocb_set_config() - Set the OCB configuration |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * @config: the OCB configuration |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_ocb_set_config(tHalHandle hHal, void *context, |
| ocb_callback callback, |
| struct sir_ocb_config *config) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_ocb_config *msg_body; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| /* |
| * Check if there is a pending request and return an error if one |
| * exists |
| */ |
| if (pMac->sme.ocb_set_config_callback) { |
| status = QDF_STATUS_E_BUSY; |
| goto end; |
| } |
| |
| msg_body = sme_copy_sir_ocb_config(config); |
| |
| if (!msg_body) { |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| |
| msg.type = WMA_OCB_SET_CONFIG_CMD; |
| msg.bodyptr = msg_body; |
| |
| /* Set the request callback and context */ |
| pMac->sme.ocb_set_config_callback = callback; |
| pMac->sme.ocb_set_config_context = context; |
| |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Error posting message to WDA: %d"), status); |
| pMac->sme.ocb_set_config_callback = callback; |
| pMac->sme.ocb_set_config_context = context; |
| qdf_mem_free(msg_body); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_ocb_set_utc_time() - Set the OCB UTC time |
| * @hHal: reference to the HAL |
| * @utc: the UTC time struct |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_ocb_set_utc_time(tHalHandle hHal, struct sir_ocb_utc *utc) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_ocb_utc *sme_utc; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| sme_utc = qdf_mem_malloc(sizeof(*sme_utc)); |
| if (!sme_utc) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Malloc failed")); |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| *sme_utc = *utc; |
| |
| msg.type = WMA_OCB_SET_UTC_TIME_CMD; |
| msg.reserved = 0; |
| msg.bodyptr = sme_utc; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post message to WDA")); |
| qdf_mem_free(utc); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_ocb_start_timing_advert() - Start sending timing advert frames |
| * @hHal: reference to the HAL |
| * @timing_advert: the timing advertisement struct |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_ocb_start_timing_advert(tHalHandle hHal, |
| struct sir_ocb_timing_advert *timing_advert) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| void *buf; |
| struct sir_ocb_timing_advert *sme_timing_advert; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| buf = qdf_mem_malloc(sizeof(*sme_timing_advert) + |
| timing_advert->template_length); |
| if (!buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for start TA")); |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| |
| sme_timing_advert = (struct sir_ocb_timing_advert *)buf; |
| *sme_timing_advert = *timing_advert; |
| sme_timing_advert->template_value = buf + sizeof(*sme_timing_advert); |
| qdf_mem_copy(sme_timing_advert->template_value, |
| timing_advert->template_value, timing_advert->template_length); |
| |
| msg.type = WMA_OCB_START_TIMING_ADVERT_CMD; |
| msg.reserved = 0; |
| msg.bodyptr = buf; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post msg to WDA")); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_ocb_stop_timing_advert() - Stop sending timing advert frames on a channel |
| * @hHal: reference to the HAL |
| * @timing_advert: the timing advertisement struct |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_ocb_stop_timing_advert(tHalHandle hHal, |
| struct sir_ocb_timing_advert *timing_advert) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_ocb_timing_advert *sme_timing_advert; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| sme_timing_advert = qdf_mem_malloc(sizeof(*timing_advert)); |
| if (!sme_timing_advert) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for stop TA")); |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| *sme_timing_advert = *timing_advert; |
| |
| msg.type = WMA_OCB_STOP_TIMING_ADVERT_CMD; |
| msg.reserved = 0; |
| msg.bodyptr = sme_timing_advert; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post msg to WDA")); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_ocb_gen_timing_advert_frame() - generate TA frame and populate the buffer |
| * @hal_handle: reference to the HAL |
| * @self_addr: the self MAC address |
| * @buf: the buffer that will contain the frame |
| * @timestamp_offset: return for the offset of the timestamp field |
| * @time_value_offset: return for the time_value field in the TA IE |
| * |
| * Return: the length of the buffer. |
| */ |
| int sme_ocb_gen_timing_advert_frame(tHalHandle hal_handle, |
| tSirMacAddr self_addr, uint8_t **buf, |
| uint32_t *timestamp_offset, |
| uint32_t *time_value_offset) |
| { |
| int template_length; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| |
| template_length = sch_gen_timing_advert_frame(mac_ctx, self_addr, buf, |
| timestamp_offset, |
| time_value_offset); |
| return template_length; |
| } |
| /** |
| * sme_ocb_get_tsf_timer() - Get the TSF timer value |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * @request: the TSF timer request |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_ocb_get_tsf_timer(tHalHandle hHal, void *context, |
| ocb_callback callback, |
| struct sir_ocb_get_tsf_timer *request) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_ocb_get_tsf_timer *msg_body; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| /* Allocate memory for the WMI request, and copy the parameter */ |
| msg_body = qdf_mem_malloc(sizeof(*msg_body)); |
| if (!msg_body) { |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| *msg_body = *request; |
| |
| msg.type = WMA_OCB_GET_TSF_TIMER_CMD; |
| msg.bodyptr = msg_body; |
| |
| /* Set the request callback and the context */ |
| pMac->sme.ocb_get_tsf_timer_callback = callback; |
| pMac->sme.ocb_get_tsf_timer_context = context; |
| |
| /* Post the message to WDA */ |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Error posting message to WDA: %d"), status); |
| pMac->sme.ocb_get_tsf_timer_callback = NULL; |
| pMac->sme.ocb_get_tsf_timer_context = NULL; |
| qdf_mem_free(msg_body); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_dcc_get_stats() - Get the DCC stats |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * @request: the get DCC stats request |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_dcc_get_stats(tHalHandle hHal, void *context, |
| ocb_callback callback, |
| struct sir_dcc_get_stats *request) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_dcc_get_stats *msg_body; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| /* Allocate memory for the WMI request, and copy the parameter */ |
| msg_body = qdf_mem_malloc(sizeof(*msg_body) + |
| request->request_array_len); |
| if (!msg_body) { |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| *msg_body = *request; |
| msg_body->request_array = (void *)msg_body + sizeof(*msg_body); |
| qdf_mem_copy(msg_body->request_array, request->request_array, |
| request->request_array_len); |
| |
| msg.type = WMA_DCC_GET_STATS_CMD; |
| msg.bodyptr = msg_body; |
| |
| /* Set the request callback and context */ |
| pMac->sme.dcc_get_stats_callback = callback; |
| pMac->sme.dcc_get_stats_context = context; |
| |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Error posting message to WDA: %d"), status); |
| pMac->sme.dcc_get_stats_callback = callback; |
| pMac->sme.dcc_get_stats_context = context; |
| qdf_mem_free(msg_body); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_dcc_clear_stats() - Clear the DCC stats |
| * @hHal: reference to the HAL |
| * @vdev_id: vdev id for OCB interface |
| * @dcc_stats_bitmap: the entries in the stats to clear |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_dcc_clear_stats(tHalHandle hHal, uint32_t vdev_id, |
| uint32_t dcc_stats_bitmap) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_dcc_clear_stats *request; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| request = qdf_mem_malloc(sizeof(struct sir_dcc_clear_stats)); |
| if (!request) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory")); |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| |
| qdf_mem_zero(request, sizeof(*request)); |
| request->vdev_id = vdev_id; |
| request->dcc_stats_bitmap = dcc_stats_bitmap; |
| |
| msg.type = WMA_DCC_CLEAR_STATS_CMD; |
| msg.bodyptr = request; |
| |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post msg to WDA")); |
| qdf_mem_free(request); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_dcc_update_ndl() - Update the DCC settings |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * @request: the update DCC request |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_dcc_update_ndl(tHalHandle hHal, void *context, |
| ocb_callback callback, |
| struct sir_dcc_update_ndl *request) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg = {0}; |
| struct sir_dcc_update_ndl *msg_body; |
| |
| /* Lock the SME structure */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| /* Allocate memory for the WMI request, and copy the parameter */ |
| msg_body = qdf_mem_malloc(sizeof(*msg_body) + |
| request->dcc_ndl_chan_list_len + |
| request->dcc_ndl_active_state_list_len); |
| if (!msg_body) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to allocate memory")); |
| status = QDF_STATUS_E_NOMEM; |
| goto end; |
| } |
| |
| *msg_body = *request; |
| |
| msg_body->dcc_ndl_chan_list = (void *)msg_body + sizeof(*msg_body); |
| msg_body->dcc_ndl_active_state_list = msg_body->dcc_ndl_chan_list + |
| request->dcc_ndl_chan_list_len; |
| qdf_mem_copy(msg_body->dcc_ndl_chan_list, request->dcc_ndl_chan_list, |
| request->dcc_ndl_active_state_list_len); |
| qdf_mem_copy(msg_body->dcc_ndl_active_state_list, |
| request->dcc_ndl_active_state_list, |
| request->dcc_ndl_active_state_list_len); |
| |
| msg.type = WMA_DCC_UPDATE_NDL_CMD; |
| msg.bodyptr = msg_body; |
| |
| /* Set the request callback and the context */ |
| pMac->sme.dcc_update_ndl_callback = callback; |
| pMac->sme.dcc_update_ndl_context = context; |
| |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Error posting message to WDA: %d"), status); |
| pMac->sme.dcc_update_ndl_callback = NULL; |
| pMac->sme.dcc_update_ndl_context = NULL; |
| qdf_mem_free(msg_body); |
| goto end; |
| } |
| |
| end: |
| sme_release_global_lock(&pMac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_register_for_dcc_stats_event() - Register for the periodic DCC stats |
| * event |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * |
| * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure |
| */ |
| QDF_STATUS sme_register_for_dcc_stats_event(tHalHandle hHal, void *context, |
| ocb_callback callback) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| pMac->sme.dcc_stats_event_callback = callback; |
| pMac->sme.dcc_stats_event_context = context; |
| sme_release_global_lock(&pMac->sme); |
| |
| return 0; |
| } |
| |
| /** |
| * sme_deregister_for_dcc_stats_event() - De-Register for the periodic DCC stats |
| * event |
| * @h_hal: Hal Handle |
| * |
| * This function de-registers the DCC perioc stats callback |
| * |
| * Return: QDF_STATUS Enumeration |
| */ |
| QDF_STATUS sme_deregister_for_dcc_stats_event(tHalHandle h_hal) |
| { |
| tpAniSirGlobal mac; |
| QDF_STATUS status; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("h_hal is not valid")); |
| return QDF_STATUS_E_INVAL; |
| } |
| mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to acquire global lock")); |
| return status; |
| } |
| mac->sme.dcc_stats_event_callback = NULL; |
| mac->sme.dcc_stats_event_context = NULL; |
| sme_release_global_lock(&mac->sme); |
| |
| return status; |
| } |
| |
| void sme_get_recovery_stats(tHalHandle hHal) |
| { |
| uint8_t i; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Self Recovery Stats"); |
| for (i = 0; i < MAX_ACTIVE_CMD_STATS; i++) { |
| if (eSmeNoCommand != |
| g_self_recovery_stats.activeCmdStats[i].command) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "timestamp %llu: command 0x%0X: reason %d: session %d", |
| g_self_recovery_stats.activeCmdStats[i]. |
| timestamp, |
| g_self_recovery_stats.activeCmdStats[i].command, |
| g_self_recovery_stats.activeCmdStats[i].reason, |
| g_self_recovery_stats.activeCmdStats[i]. |
| sessionId); |
| } |
| } |
| } |
| |
| /** |
| * sme_save_active_cmd_stats() - To save active command stats |
| * @hHal: HAL context |
| * |
| * This routine is to save active command stats |
| * |
| * Return: None |
| */ |
| void sme_save_active_cmd_stats(tHalHandle hHal) |
| { |
| tSmeCmd *pTempCmd = NULL; |
| tListElem *pEntry; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint8_t statidx = 0; |
| tActiveCmdStats *actv_cmd_stat = NULL; |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("pMac is NULL")); |
| return; |
| } |
| |
| pEntry = csr_ll_peek_head(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); |
| if (pEntry) |
| pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); |
| |
| if (!pTempCmd) |
| return; |
| |
| if (eSmeCsrCommandMask & pTempCmd->command) { |
| statidx = g_self_recovery_stats.cmdStatsIndx; |
| actv_cmd_stat = &g_self_recovery_stats.activeCmdStats[statidx]; |
| actv_cmd_stat->command = pTempCmd->command; |
| actv_cmd_stat->sessionId = pTempCmd->sessionId; |
| actv_cmd_stat->timestamp = cds_get_monotonic_boottime(); |
| if (eSmeCommandRoam == pTempCmd->command) |
| actv_cmd_stat->reason = pTempCmd->u.roamCmd.roamReason; |
| else if (eSmeCommandScan == pTempCmd->command) |
| actv_cmd_stat->reason = pTempCmd->u.scanCmd.reason; |
| else |
| actv_cmd_stat->reason = 0xFF; |
| |
| g_self_recovery_stats.cmdStatsIndx = |
| ((g_self_recovery_stats.cmdStatsIndx + 1) & |
| (MAX_ACTIVE_CMD_STATS - 1)); |
| } |
| return; |
| } |
| |
| void active_list_cmd_timeout_handle(void *userData) |
| { |
| tHalHandle hal = (tHalHandle)userData; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| tListElem *entry; |
| tSmeCmd *temp_cmd = NULL; |
| |
| if (NULL == mac_ctx) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: mac_ctx is null", __func__); |
| return; |
| } |
| /* Return if no cmd pending in active list as |
| * in this case we should not be here. |
| */ |
| if (0 == csr_ll_count(&mac_ctx->sme.smeCmdActiveList)) |
| return; |
| sms_log(mac_ctx, LOGE, |
| FL("Active List command timeout Cmd List Count %d"), |
| csr_ll_count(&mac_ctx->sme.smeCmdActiveList)); |
| sme_get_command_q_status(hal); |
| |
| if (mac_ctx->roam.configParam.enable_fatal_event) |
| cds_flush_logs(WLAN_LOG_TYPE_FATAL, |
| WLAN_LOG_INDICATOR_HOST_DRIVER, |
| WLAN_LOG_REASON_SME_COMMAND_STUCK, |
| false, |
| mac_ctx->sme.enableSelfRecovery ? true : false); |
| else |
| qdf_trace_dump_all(mac_ctx, 0, 0, 500, 0); |
| |
| entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (entry) |
| temp_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| /* Ignore if ROC took more than 120 sec */ |
| if (temp_cmd && (eSmeCommandRemainOnChannel == temp_cmd->command)) |
| return; |
| |
| if (mac_ctx->sme.enableSelfRecovery) { |
| sme_save_active_cmd_stats(hal); |
| cds_trigger_recovery(); |
| } else { |
| if (!mac_ctx->roam.configParam.enable_fatal_event && |
| !(cds_is_load_or_unload_in_progress() || |
| cds_is_driver_recovering())) |
| QDF_BUG(0); |
| } |
| } |
| |
| QDF_STATUS sme_notify_modem_power_state(tHalHandle hHal, uint32_t value) |
| { |
| cds_msg_t msg; |
| tpSirModemPowerStateInd request_buf; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| request_buf = qdf_mem_malloc(sizeof(tSirModemPowerStateInd)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for MODEM POWER STATE IND", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| request_buf->param = value; |
| |
| msg.type = WMA_MODEM_POWER_STATE_IND; |
| msg.reserved = 0; |
| msg.bodyptr = request_buf; |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_MODEM_POWER_STATE_IND message" |
| " to WMA", __func__); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef QCA_HT_2040_COEX |
| QDF_STATUS sme_notify_ht2040_mode(tHalHandle hHal, uint16_t staId, |
| struct qdf_mac_addr macAddrSTA, |
| uint8_t sessionId, |
| uint8_t channel_type) |
| { |
| cds_msg_t msg; |
| tUpdateVHTOpMode *pHtOpMode = NULL; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pHtOpMode = qdf_mem_malloc(sizeof(tUpdateVHTOpMode)); |
| if (NULL == pHtOpMode) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for setting OP mode", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| switch (channel_type) { |
| case eHT_CHAN_HT20: |
| pHtOpMode->opMode = eHT_CHANNEL_WIDTH_20MHZ; |
| break; |
| |
| case eHT_CHAN_HT40MINUS: |
| case eHT_CHAN_HT40PLUS: |
| pHtOpMode->opMode = eHT_CHANNEL_WIDTH_40MHZ; |
| break; |
| |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Invalid OP mode", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pHtOpMode->staId = staId, |
| qdf_mem_copy(pHtOpMode->peer_mac, macAddrSTA.bytes, |
| sizeof(tSirMacAddr)); |
| pHtOpMode->smesessionId = sessionId; |
| |
| msg.type = WMA_UPDATE_OP_MODE; |
| msg.reserved = 0; |
| msg.bodyptr = pHtOpMode; |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_UPDATE_OP_MODE message" |
| " to WMA", __func__); |
| qdf_mem_free(pHtOpMode); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: Notifed FW about OP mode: %d for staId=%d", |
| __func__, pHtOpMode->opMode, staId); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_ht2040_mode |
| |
| \brief To update HT Operation beacon IE. |
| |
| \param |
| |
| \return QDF_STATUS SUCCESS |
| FAILURE or RESOURCES |
| The API finished and failed. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_ht2040_mode(tHalHandle hHal, uint8_t sessionId, |
| uint8_t channel_type, bool obssEnabled) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| ePhyChanBondState cbMode; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: Update HT operation beacon IE, channel_type=%d", |
| __func__, channel_type); |
| |
| switch (channel_type) { |
| case eHT_CHAN_HT20: |
| cbMode = PHY_SINGLE_CHANNEL_CENTERED; |
| break; |
| case eHT_CHAN_HT40MINUS: |
| cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; |
| break; |
| case eHT_CHAN_HT40PLUS: |
| cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; |
| break; |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s:Error!!! Invalid HT20/40 mode !", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_set_ht2040_mode(pMac, sessionId, |
| cbMode, obssEnabled); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| |
| \fn sme_set_phy_cb_mode24_g |
| |
| \brief Changes PHY channel bonding mode |
| |
| \param hHal - The handle returned by mac_open. |
| |
| \param cbMode new channel bonding mode which is to set |
| |
| \return QDF_STATUS SUCCESS. |
| |
| -------------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_phy_cb_mode24_g(tHalHandle hHal, ePhyChanBondState phyCBMode) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == pMac) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: invalid context", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pMac->roam.configParam.channelBondingMode24GHz = phyCBMode; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif |
| |
| /* |
| * SME API to enable/disable idle mode powersave |
| * This should be called only if powersave offload |
| * is enabled |
| */ |
| QDF_STATUS sme_set_idle_powersave_config(void *cds_context, |
| tHalHandle hHal, uint32_t value) |
| { |
| void *wmaContext = cds_get_context(QDF_MODULE_ID_WMA); |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| if (NULL == wmaContext) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: wmaContext is NULL", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| " Idle Ps Set Value %d", value); |
| |
| pMac->imps_enabled = false; |
| if (QDF_STATUS_SUCCESS != wma_set_idle_ps_config(wmaContext, value)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| " Failed to Set Idle Ps Value %d", value); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (value) |
| pMac->imps_enabled = true; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| int16_t sme_get_ht_config(tHalHandle hHal, uint8_t session_id, uint16_t ht_capab) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, session_id); |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: pSession is NULL", __func__); |
| return -EIO; |
| } |
| switch (ht_capab) { |
| case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: |
| return pSession->htConfig.ht_rx_ldpc; |
| case WNI_CFG_HT_CAP_INFO_TX_STBC: |
| return pSession->htConfig.ht_tx_stbc; |
| case WNI_CFG_HT_CAP_INFO_RX_STBC: |
| return pSession->htConfig.ht_rx_stbc; |
| case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: |
| return pSession->htConfig.ht_sgi20; |
| case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: |
| return pSession->htConfig.ht_sgi40; |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "invalid ht capability"); |
| return -EIO; |
| } |
| } |
| |
| int sme_update_ht_config(tHalHandle hHal, uint8_t sessionId, uint16_t htCapab, |
| int value) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| |
| if (NULL == pSession) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: pSession is NULL", __func__); |
| return -EIO; |
| } |
| |
| if (QDF_STATUS_SUCCESS != wma_set_htconfig(sessionId, htCapab, value)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Failed to set ht capability in target"); |
| return -EIO; |
| } |
| |
| switch (htCapab) { |
| case WNI_CFG_HT_CAP_INFO_ADVANCE_CODING: |
| pSession->htConfig.ht_rx_ldpc = value; |
| break; |
| case WNI_CFG_HT_CAP_INFO_TX_STBC: |
| pSession->htConfig.ht_tx_stbc = value; |
| break; |
| case WNI_CFG_HT_CAP_INFO_RX_STBC: |
| pSession->htConfig.ht_rx_stbc = value; |
| break; |
| case WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ: |
| pSession->htConfig.ht_sgi20 = value; |
| break; |
| case WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ: |
| pSession->htConfig.ht_sgi40 = value; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| #define HT20_SHORT_GI_MCS7_RATE 722 |
| /* --------------------------------------------------------------------------- |
| \fn sme_send_rate_update_ind |
| \brief API to Update rate |
| \param hHal - The handle returned by mac_open |
| \param rateUpdateParams - Pointer to rate update params |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_send_rate_update_ind(tHalHandle hHal, |
| tSirRateUpdateInd *rateUpdateParams) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status; |
| cds_msg_t msg; |
| tSirRateUpdateInd *rate_upd = qdf_mem_malloc(sizeof(tSirRateUpdateInd)); |
| |
| if (rate_upd == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Rate update struct alloc failed"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| *rate_upd = *rateUpdateParams; |
| |
| if (rate_upd->mcastDataRate24GHz == HT20_SHORT_GI_MCS7_RATE) |
| rate_upd->mcastDataRate24GHzTxFlag = |
| eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; |
| else if (rate_upd->reliableMcastDataRate == |
| HT20_SHORT_GI_MCS7_RATE) |
| rate_upd->reliableMcastDataRateTxFlag = |
| eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| msg.type = WMA_RATE_UPDATE_IND; |
| msg.bodyptr = rate_upd; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, msg.type)); |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able " |
| "to post WMA_SET_RMC_RATE_IND to WMA!", |
| __func__); |
| |
| sme_release_global_lock(&pMac->sme); |
| qdf_mem_free(rate_upd); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_update_access_policy_vendor_ie() - update vendor ie and access policy. |
| * @hal: Pointer to the mac context |
| * @session_id: sme session id |
| * @vendor_ie: vendor ie |
| * @access_policy: vendor ie access policy |
| * |
| * This function updates the vendor ie and access policy to lim. |
| * |
| * Return: success or failure. |
| */ |
| QDF_STATUS sme_update_access_policy_vendor_ie(tHalHandle hal, |
| uint8_t session_id, uint8_t *vendor_ie, int access_policy) |
| { |
| struct sme_update_access_policy_vendor_ie *msg; |
| uint16_t msg_len; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| |
| msg_len = sizeof(*msg); |
| |
| msg = qdf_mem_malloc(msg_len); |
| if (!msg) { |
| sms_log(mac, LOGE, |
| "failed to allocate memory for sme_update_access_policy_vendor_ie"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| qdf_mem_set(msg, msg_len, 0); |
| msg->msg_type = (uint16_t)eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE; |
| msg->length = (uint16_t)msg_len; |
| |
| qdf_mem_copy(&msg->ie[0], vendor_ie, sizeof(msg->ie)); |
| |
| msg->sme_session_id = session_id; |
| msg->access_policy = access_policy; |
| |
| sms_log(mac, LOG1, "sme_session_id %hu, access_policy %d", session_id, |
| access_policy); |
| |
| status = cds_send_mb_message_to_mac(msg); |
| |
| return status; |
| } |
| |
| /** |
| * sme_get_reg_info() - To get registration info |
| * @hHal: HAL context |
| * @chanId: channel id |
| * @regInfo1: first reg info to fill |
| * @regInfo2: second reg info to fill |
| * |
| * This routine will give you reg info |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_get_reg_info(tHalHandle hHal, uint8_t chanId, |
| uint32_t *regInfo1, uint32_t *regInfo2) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status; |
| uint8_t i; |
| bool found = false; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| *regInfo1 = 0; |
| *regInfo2 = 0; |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| |
| for (i = 0; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) { |
| if (pMac->scan.defaultPowerTable[i].chan_num == chanId) { |
| SME_SET_CHANNEL_REG_POWER(*regInfo1, |
| pMac->scan.defaultPowerTable[i].power); |
| |
| SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2, |
| pMac->scan.defaultPowerTable[i].power); |
| found = true; |
| break; |
| } |
| } |
| if (!found) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| #ifdef FEATURE_WLAN_AUTO_SHUTDOWN |
| /* --------------------------------------------------------------------------- |
| \fn sme_auto_shutdown_cb |
| \brief Used to plug in callback function for receiving auto shutdown evt |
| \param hHal |
| \param pCallbackfn : callback function pointer should be plugged in |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_auto_shutdown_cb(tHalHandle hHal, void (*pCallbackfn)(void) |
| ) { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Plug in Auto shutdown event callback", __func__); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if (NULL != pCallbackfn) { |
| pMac->sme.pAutoShutdownNotificationCb = pCallbackfn; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_auto_shutdown_timer |
| \API to set auto shutdown timer value in FW. |
| \param hHal - The handle returned by mac_open |
| \param timer_val - The auto shutdown timer value to be set |
| \- return Configuration message posting status, SUCCESS or Fail |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_auto_shutdown_timer(tHalHandle hHal, uint32_t timer_val) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tSirAutoShutdownCmdParams *auto_sh_cmd; |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| auto_sh_cmd = (tSirAutoShutdownCmdParams *) |
| qdf_mem_malloc(sizeof(tSirAutoShutdownCmdParams)); |
| if (auto_sh_cmd == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, |
| "%s Request Buffer Alloc Fail", __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| auto_sh_cmd->timer_val = timer_val; |
| |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = auto_sh_cmd; |
| cds_message.type = WMA_SET_AUTO_SHUTDOWN_TIMER_REQ; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post Auto shutdown MSG fail", __func__); |
| qdf_mem_free(auto_sh_cmd); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: Posted Auto shutdown MSG", __func__); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_CH_AVOID |
| /* --------------------------------------------------------------------------- |
| \fn sme_add_ch_avoid_callback |
| \brief Used to plug in callback function |
| Which notify channel may not be used with SAP or P2PGO mode. |
| Notification come from FW. |
| \param hHal |
| \param pCallbackfn : callback function pointer should be plugged in |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_add_ch_avoid_callback |
| (tHalHandle hHal, void (*pCallbackfn)(void *pAdapter, void *indParam) |
| ) { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Plug in CH AVOID CB", __func__); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if (NULL != pCallbackfn) { |
| pMac->sme.pChAvoidNotificationCb = pCallbackfn; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ch_avoid_update_req |
| \API to request channel avoidance update from FW. |
| \param hHal - The handle returned by mac_open |
| \param update_type - The udpate_type parameter of this request call |
| \- return Configuration message posting status, SUCCESS or Fail |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ch_avoid_update_req(tHalHandle hHal) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tSirChAvoidUpdateReq *cauReq; |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| cauReq = (tSirChAvoidUpdateReq *) |
| qdf_mem_malloc(sizeof(tSirChAvoidUpdateReq)); |
| if (NULL == cauReq) { |
| QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, |
| "%s Request Buffer Alloc Fail", __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| cauReq->reserved_param = 0; |
| |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = cauReq; |
| cds_message.type = WMA_CH_AVOID_UPDATE_REQ; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Post Ch Avoid Update MSG fail", |
| __func__); |
| qdf_mem_free(cauReq); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: Posted Ch Avoid Update MSG", __func__); |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| #endif /* FEATURE_WLAN_CH_AVOID */ |
| |
| /** |
| * sme_set_miracast() - Function to set miracast value to UMAC |
| * @hal: Handle returned by macOpen |
| * @filter_type: 0-Disabled, 1-Source, 2-sink |
| * |
| * This function passes down the value of miracast set by |
| * framework to UMAC |
| * |
| * Return: Configuration message posting status, SUCCESS or Fail |
| * |
| */ |
| QDF_STATUS sme_set_miracast(tHalHandle hal, uint8_t filter_type) |
| { |
| cds_msg_t msg; |
| uint32_t *val; |
| tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal); |
| |
| val = qdf_mem_malloc(sizeof(*val)); |
| if (NULL == val || NULL == mac_ptr) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Invalid pointer", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *val = filter_type; |
| |
| msg.type = SIR_HAL_SET_MIRACAST; |
| msg.reserved = 0; |
| msg.bodyptr = val; |
| |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!", |
| __func__); |
| qdf_mem_free(val); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| mac_ptr->sme.miracast_value = filter_type; |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_set_mas() - Function to set MAS value to UMAC |
| * @val: 1-Enable, 0-Disable |
| * |
| * This function passes down the value of MAS to the UMAC. A |
| * value of 1 will enable MAS and a value of 0 will disable MAS |
| * |
| * Return: Configuration message posting status, SUCCESS or Fail |
| * |
| */ |
| QDF_STATUS sme_set_mas(uint32_t val) |
| { |
| cds_msg_t msg; |
| uint32_t *ptr_val; |
| |
| ptr_val = qdf_mem_malloc(sizeof(*ptr_val)); |
| if (NULL == ptr_val) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: could not allocate ptr_val", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *ptr_val = val; |
| |
| msg.type = SIR_HAL_SET_MAS; |
| msg.reserved = 0; |
| msg.bodyptr = ptr_val; |
| |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WDA_SET_MAS_ENABLE_DISABLE to WMA!", |
| __func__); |
| qdf_mem_free(ptr_val); |
| return QDF_STATUS_E_FAILURE; |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_roam_channel_change_req() - Channel change to new target channel |
| * @hHal: handle returned by mac_open |
| * @bssid: mac address of BSS |
| * @ch_params: target channel information |
| * @profile: CSR profile |
| * |
| * API to Indicate Channel change to new target channel |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_roam_channel_change_req(tHalHandle hHal, |
| struct qdf_mac_addr bssid, |
| struct ch_params_s *ch_params, |
| tCsrRoamProfile *profile) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| |
| status = csr_roam_channel_change_req(pMac, bssid, ch_params, |
| profile); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* ------------------------------------------------------------------------- |
| \fn sme_process_channel_change_resp |
| \brief API to Indicate Channel change response message to SAP. |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_process_channel_change_resp(tpAniSirGlobal pMac, |
| uint16_t msg_type, void *pMsgBuf) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrRoamInfo proam_info = { 0 }; |
| eCsrRoamResult roamResult; |
| tpSwitchChannelParams pChnlParams = (tpSwitchChannelParams) pMsgBuf; |
| uint32_t SessionId = pChnlParams->peSessionId; |
| |
| proam_info.channelChangeRespEvent = |
| (tSirChanChangeResponse *) |
| qdf_mem_malloc(sizeof(tSirChanChangeResponse)); |
| if (NULL == proam_info.channelChangeRespEvent) { |
| status = QDF_STATUS_E_NOMEM; |
| sms_log(pMac, LOGE, |
| "Channel Change Event Allocation Failed: %d\n", status); |
| return status; |
| } |
| if (msg_type == eWNI_SME_CHANNEL_CHANGE_RSP) { |
| proam_info.channelChangeRespEvent->sessionId = SessionId; |
| proam_info.channelChangeRespEvent->newChannelNumber = |
| pChnlParams->channelNumber; |
| proam_info.channelChangeRespEvent->secondaryChannelOffset = |
| pChnlParams->ch_width; |
| |
| if (pChnlParams->status == QDF_STATUS_SUCCESS) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Received success eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", |
| SessionId); |
| proam_info.channelChangeRespEvent->channelChangeStatus = |
| 1; |
| roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS; |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Received failure eWNI_SME_CHANNEL_CHANGE_RSP for sessionId[%d]", |
| SessionId); |
| proam_info.channelChangeRespEvent->channelChangeStatus = |
| 0; |
| roamResult = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE; |
| } |
| |
| csr_roam_call_callback(pMac, SessionId, &proam_info, 0, |
| eCSR_ROAM_SET_CHANNEL_RSP, roamResult); |
| |
| } else { |
| status = QDF_STATUS_E_FAILURE; |
| sms_log(pMac, LOGE, "Invalid Channel Change Resp Message: %d\n", |
| status); |
| } |
| qdf_mem_free(proam_info.channelChangeRespEvent); |
| |
| return status; |
| } |
| |
| /* ------------------------------------------------------------------------- |
| \fn sme_roam_start_beacon_req |
| \brief API to Indicate LIM to start Beacon Tx |
| \after SAP CAC Wait is completed. |
| \param hHal - The handle returned by mac_open |
| \param sessionId - session ID |
| \param dfsCacWaitStatus - CAC WAIT status flag |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_roam_start_beacon_req(tHalHandle hHal, struct qdf_mac_addr bssid, |
| uint8_t dfsCacWaitStatus) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| status = sme_acquire_global_lock(&pMac->sme); |
| |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_start_beacon_req(pMac, bssid, dfsCacWaitStatus); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_roam_csa_ie_request() - request CSA IE transmission from PE |
| * @hHal: handle returned by mac_open |
| * @bssid: SAP bssid |
| * @targetChannel: target channel information |
| * @csaIeReqd: CSA IE Request |
| * @ch_params: channel information |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_roam_csa_ie_request(tHalHandle hHal, struct qdf_mac_addr bssid, |
| uint8_t targetChannel, uint8_t csaIeReqd, |
| struct ch_params_s *ch_params) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_send_chan_sw_ie_request(pMac, bssid, |
| targetChannel, csaIeReqd, ch_params); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_init_thermal_info |
| \brief SME API to initialize the thermal mitigation parameters |
| \param hHal |
| \param thermalParam : thermal mitigation parameters |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_init_thermal_info(tHalHandle hHal, tSmeThermalParams thermalParam) |
| { |
| t_thermal_mgmt *pWmaParam; |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pWmaParam = (t_thermal_mgmt *) qdf_mem_malloc(sizeof(t_thermal_mgmt)); |
| if (NULL == pWmaParam) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: could not allocate tThermalMgmt", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero((void *)pWmaParam, sizeof(t_thermal_mgmt)); |
| |
| pWmaParam->thermalMgmtEnabled = thermalParam.smeThermalMgmtEnabled; |
| pWmaParam->throttlePeriod = thermalParam.smeThrottlePeriod; |
| |
| pWmaParam->throttle_duty_cycle_tbl[0] = |
| thermalParam.sme_throttle_duty_cycle_tbl[0]; |
| pWmaParam->throttle_duty_cycle_tbl[1] = |
| thermalParam.sme_throttle_duty_cycle_tbl[1]; |
| pWmaParam->throttle_duty_cycle_tbl[2] = |
| thermalParam.sme_throttle_duty_cycle_tbl[2]; |
| pWmaParam->throttle_duty_cycle_tbl[3] = |
| thermalParam.sme_throttle_duty_cycle_tbl[3]; |
| |
| pWmaParam->thermalLevels[0].minTempThreshold = |
| thermalParam.smeThermalLevels[0].smeMinTempThreshold; |
| pWmaParam->thermalLevels[0].maxTempThreshold = |
| thermalParam.smeThermalLevels[0].smeMaxTempThreshold; |
| pWmaParam->thermalLevels[1].minTempThreshold = |
| thermalParam.smeThermalLevels[1].smeMinTempThreshold; |
| pWmaParam->thermalLevels[1].maxTempThreshold = |
| thermalParam.smeThermalLevels[1].smeMaxTempThreshold; |
| pWmaParam->thermalLevels[2].minTempThreshold = |
| thermalParam.smeThermalLevels[2].smeMinTempThreshold; |
| pWmaParam->thermalLevels[2].maxTempThreshold = |
| thermalParam.smeThermalLevels[2].smeMaxTempThreshold; |
| pWmaParam->thermalLevels[3].minTempThreshold = |
| thermalParam.smeThermalLevels[3].smeMinTempThreshold; |
| pWmaParam->thermalLevels[3].maxTempThreshold = |
| thermalParam.smeThermalLevels[3].smeMaxTempThreshold; |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| msg.type = WMA_INIT_THERMAL_INFO_CMD; |
| msg.bodyptr = pWmaParam; |
| |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_SET_THERMAL_INFO_CMD to WMA!", |
| __func__); |
| qdf_mem_free(pWmaParam); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_SUCCESS; |
| } |
| qdf_mem_free(pWmaParam); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /** |
| * sme_add_set_thermal_level_callback() - Plug in set thermal level callback |
| * @hal: Handle returned by macOpen |
| * @callback: sme_set_thermal_level_callback |
| * |
| * Plug in set thermal level callback |
| * |
| * Return: none |
| */ |
| void sme_add_set_thermal_level_callback(tHalHandle hal, |
| sme_set_thermal_level_callback callback) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| |
| pMac->sme.set_thermal_level_cb = callback; |
| } |
| |
| /** |
| * sme_set_thermal_level() - SME API to set the thermal mitigation level |
| * @hal: Handler to HAL |
| * @level: Thermal mitigation level |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_set_thermal_level(tHalHandle hal, uint8_t level) |
| { |
| cds_msg_t msg; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hal); |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| qdf_mem_set(&msg, sizeof(msg), 0); |
| msg.type = WMA_SET_THERMAL_LEVEL; |
| msg.bodyval = level; |
| |
| qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_SET_THERMAL_LEVEL to WMA!", |
| __func__); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_SUCCESS; |
| } |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_txpower_limit |
| \brief SME API to set txpower limits |
| \param hHal |
| \param psmetx : power limits for 2g/5g |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_txpower_limit(tHalHandle hHal, tSirTxPowerLimit *psmetx) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| cds_msg_t cds_message; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tSirTxPowerLimit *tx_power_limit; |
| |
| tx_power_limit = qdf_mem_malloc(sizeof(*tx_power_limit)); |
| if (!tx_power_limit) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Memory allocation for TxPowerLimit failed!", |
| __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| *tx_power_limit = *psmetx; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| cds_message.type = WMA_TX_POWER_LIMIT; |
| cds_message.reserved = 0; |
| cds_message.bodyptr = tx_power_limit; |
| |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: not able to post WMA_TX_POWER_LIMIT", |
| __func__); |
| status = QDF_STATUS_E_FAILURE; |
| qdf_mem_free(tx_power_limit); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| QDF_STATUS sme_update_connect_debug(tHalHandle hHal, uint32_t set_value) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| pMac->fEnableDebugLog = set_value; |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ap_disable_intra_bss_fwd |
| |
| \brief |
| SME will send message to WMA to set Intra BSS in txrx |
| |
| \param |
| |
| hHal - The handle returned by mac_open |
| |
| sessionId - session id ( vdev id) |
| |
| disablefwd - bool value that indicate disable intrabss fwd disable |
| |
| \return QDF_STATUS |
| --------------------------------------------------------------------------- */ |
| QDF_STATUS sme_ap_disable_intra_bss_fwd(tHalHandle hHal, uint8_t sessionId, |
| bool disablefwd) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| int status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| cds_msg_t cds_message; |
| tpDisableIntraBssFwd pSapDisableIntraFwd = NULL; |
| |
| /* Prepare the request to send to SME. */ |
| pSapDisableIntraFwd = qdf_mem_malloc(sizeof(tDisableIntraBssFwd)); |
| if (NULL == pSapDisableIntraFwd) { |
| sms_log(pMac, LOGP, "Memory Allocation Failure!!! %s", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(pSapDisableIntraFwd, sizeof(tDisableIntraBssFwd)); |
| |
| pSapDisableIntraFwd->sessionId = sessionId; |
| pSapDisableIntraFwd->disableintrabssfwd = disablefwd; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = pSapDisableIntraFwd; |
| cds_message.type = WMA_SET_SAP_INTRABSS_DIS; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| status = QDF_STATUS_E_FAILURE; |
| qdf_mem_free(pSapDisableIntraFwd); |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| #ifdef WLAN_FEATURE_STATS_EXT |
| |
| /****************************************************************************** |
| \fn sme_stats_ext_register_callback |
| |
| \brief |
| a function called to register the callback that send vendor event for stats |
| ext |
| |
| \param callback - callback to be registered |
| ******************************************************************************/ |
| void sme_stats_ext_register_callback(tHalHandle hHal, StatsExtCallback callback) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pMac->sme.StatsExtCallback = callback; |
| } |
| |
| /** |
| * sme_stats_ext_deregister_callback() - De-register ext stats callback |
| * @h_hal: Hal Handle |
| * |
| * This function is called to de initialize the HDD NAN feature. Currently |
| * the only operation required is to de-register a callback with SME. |
| * |
| * Return: None |
| */ |
| void sme_stats_ext_deregister_callback(tHalHandle h_hal) |
| { |
| tpAniSirGlobal pmac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return; |
| } |
| |
| pmac = PMAC_STRUCT(h_hal); |
| pmac->sme.StatsExtCallback = NULL; |
| } |
| |
| |
| /****************************************************************************** |
| \fn sme_stats_ext_request |
| |
| \brief |
| a function called when HDD receives STATS EXT vendor command from userspace |
| |
| \param sessionID - vdevID for the stats ext request |
| |
| \param input - Stats Ext Request structure ptr |
| |
| \return QDF_STATUS |
| ******************************************************************************/ |
| QDF_STATUS sme_stats_ext_request(uint8_t session_id, tpStatsExtRequestReq input) |
| { |
| cds_msg_t msg; |
| tpStatsExtRequest data; |
| size_t data_len; |
| |
| data_len = sizeof(tStatsExtRequest) + input->request_data_len; |
| data = qdf_mem_malloc(data_len); |
| |
| if (data == NULL) { |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(data, data_len); |
| data->vdev_id = session_id; |
| data->request_data_len = input->request_data_len; |
| if (input->request_data_len) { |
| qdf_mem_copy(data->request_data, |
| input->request_data, input->request_data_len); |
| } |
| |
| msg.type = WMA_STATS_EXT_REQUEST; |
| msg.reserved = 0; |
| msg.bodyptr = data; |
| |
| if (QDF_STATUS_SUCCESS != cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_STATS_EXT_REQUEST message to WMA", |
| __func__); |
| qdf_mem_free(data); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /****************************************************************************** |
| \fn sme_stats_ext_event |
| |
| \brief |
| a callback function called when SME received eWNI_SME_STATS_EXT_EVENT |
| response from WMA |
| |
| \param hHal - HAL handle for device |
| \param pMsg - Message body passed from WMA; includes NAN header |
| \return QDF_STATUS |
| ******************************************************************************/ |
| QDF_STATUS sme_stats_ext_event(tHalHandle hHal, void *pMsg) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| if (NULL == pMsg) { |
| sms_log(pMac, LOGE, "in %s msg ptr is NULL", __func__); |
| status = QDF_STATUS_E_FAILURE; |
| } else { |
| sms_log(pMac, LOG2, "SME: entering %s", __func__); |
| |
| if (pMac->sme.StatsExtCallback) { |
| pMac->sme.StatsExtCallback(pMac->hHdd, |
| (tpStatsExtEvent) pMsg); |
| } |
| } |
| |
| return status; |
| } |
| |
| #endif |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_update_dfs_scan_mode |
| \brief Update DFS roam scan mode |
| This function is called through dynamic setConfig callback function |
| to configure allowDFSChannelRoam. |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param allowDFSChannelRoam - DFS roaming scan mode 0 (disable), |
| 1 (passive), 2 (active) |
| \return QDF_STATUS_SUCCESS - SME update DFS roaming scan config |
| successfully. |
| Other status means SME failed to update DFS roaming scan config. |
| \sa |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId, |
| uint8_t allowDFSChannelRoam) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "LFR runtime successfully set AllowDFSChannelRoam Mode to " |
| "%d - old value is %d - roam state is %s", |
| allowDFSChannelRoam, |
| pMac->roam.configParam.allowDFSChannelRoam, |
| mac_trace_get_neighbour_roam_state(pMac->roam. |
| neighborRoamInfo |
| [sessionId]. |
| neighborRoamState)); |
| pMac->roam.configParam.allowDFSChannelRoam = |
| allowDFSChannelRoam; |
| sme_release_global_lock(&pMac->sme); |
| } |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, |
| REASON_ROAM_DFS_SCAN_MODE_CHANGED); |
| } |
| |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| \brief sme_get_dfs_scan_mode() - get DFS roam scan mode |
| This is a synchronous call |
| \param hHal - The handle returned by mac_open. |
| \return DFS roaming scan mode 0 (disable), 1 (passive), 2 (active) |
| \sa |
| --------------------------------------------------------------------------*/ |
| uint8_t sme_get_dfs_scan_mode(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| return pMac->roam.configParam.allowDFSChannelRoam; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| \fn sme_modify_add_ie |
| \brief This function sends msg to updates the additional IE buffers in PE |
| \param hHal - global structure |
| \param pModifyIE - pointer to tModifyIE structure |
| \param updateType - type of buffer |
| \- return Success or failure |
| -----------------------------------------------------------------------------*/ |
| QDF_STATUS sme_modify_add_ie(tHalHandle hHal, |
| tSirModifyIE *pModifyIE, eUpdateIEsType updateType) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| status = sme_acquire_global_lock(&pMac->sme); |
| |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_modify_add_ies(pMac, pModifyIE, updateType); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| \fn sme_update_add_ie |
| \brief This function sends msg to updates the additional IE buffers in PE |
| \param hHal - global structure |
| \param pUpdateIE - pointer to structure tUpdateIE |
| \param updateType - type of buffer |
| \- return Success or failure |
| -----------------------------------------------------------------------------*/ |
| QDF_STATUS sme_update_add_ie(tHalHandle hHal, |
| tSirUpdateIE *pUpdateIE, eUpdateIEsType updateType) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| status = sme_acquire_global_lock(&pMac->sme); |
| |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| status = csr_roam_update_add_ies(pMac, pUpdateIE, updateType); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_sta_in_middle_of_roaming |
| \brief This function returns true if STA is in the middle of roaming state |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \- return true or false |
| -------------------------------------------------------------------------*/ |
| bool sme_sta_in_middle_of_roaming(tHalHandle hHal, uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| bool ret = false; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| ret = csr_neighbor_middle_of_roaming(hHal, sessionId); |
| sme_release_global_lock(&pMac->sme); |
| } |
| return ret; |
| } |
| |
| |
| /** |
| * sme_update_dsc_pto_up_mapping() |
| * @hHal: HAL context |
| * @dscpmapping: pointer to DSCP mapping structure |
| * @sessionId: SME session id |
| * |
| * This routine is called to update dscp mapping |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_update_dsc_pto_up_mapping(tHalHandle hHal, |
| sme_QosWmmUpType *dscpmapping, |
| uint8_t sessionId) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| uint8_t i, j, peSessionId; |
| tCsrRoamSession *pCsrSession = NULL; |
| tpPESession pSession = NULL; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) |
| return status; |
| pCsrSession = CSR_GET_SESSION(pMac, sessionId); |
| if (pCsrSession == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Session lookup fails for CSR session")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (!CSR_IS_SESSION_VALID(pMac, sessionId)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Invalid session Id %u"), sessionId); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| pSession = pe_find_session_by_bssid(pMac, |
| pCsrSession->connectedProfile.bssid.bytes, |
| &peSessionId); |
| |
| if (pSession == NULL) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL(" Session lookup fails for BSSID")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| if (!pSession->QosMapSet.present) { |
| hdd_notice("QOS Mapping IE not present"); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } |
| for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) { |
| for (j = pSession->QosMapSet.dscp_range[i][0]; |
| j <= pSession->QosMapSet.dscp_range[i][1]; |
| j++) { |
| if ((pSession->QosMapSet.dscp_range[i][0] == 255) |
| && (pSession->QosMapSet.dscp_range[i][1] == |
| 255)) { |
| dscpmapping[j] = 0; |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_ERROR, |
| FL("User Priority %d isn't used"), i); |
| break; |
| } else { |
| dscpmapping[j] = i; |
| } |
| } |
| } |
| for (i = 0; i < pSession->QosMapSet.num_dscp_exceptions; i++) |
| if (pSession->QosMapSet.dscp_exceptions[i][0] != 255) |
| dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0]] = |
| pSession->QosMapSet.dscp_exceptions[i][1]; |
| |
| sme_release_global_lock(&pMac->sme); |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_abort_roam_scan |
| \brief API to abort current roam scan cycle by roam scan offload module. |
| \param hHal - The handle returned by mac_open. |
| \param sessionId - Session Identifier |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_abort_roam_scan(tHalHandle hHal, uint8_t sessionId) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| sms_log(pMac, LOGW, "entering function %s", __func__); |
| if (pMac->roam.configParam.isRoamOffloadScanEnabled) { |
| /* acquire the lock for the sme object */ |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| csr_roam_offload_scan(pMac, sessionId, |
| ROAM_SCAN_OFFLOAD_ABORT_SCAN, |
| REASON_ROAM_ABORT_ROAM_SCAN); |
| /* release the lock for the sme object */ |
| sme_release_global_lock(&pMac->sme); |
| } |
| } |
| |
| return status; |
| } |
| |
| #ifdef FEATURE_WLAN_EXTSCAN |
| /** |
| * sme_get_valid_channels_by_band() - to fetch valid channels filtered by band |
| * @hHal: HAL context |
| * @wifiBand: RF band information |
| * @aValidChannels: output array to store channel info |
| * @pNumChannels: output number of channels |
| * |
| * SME API to fetch all valid channels filtered by band |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_get_valid_channels_by_band(tHalHandle hHal, |
| uint8_t wifiBand, |
| uint32_t *aValidChannels, |
| uint8_t *pNumChannels) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| uint8_t chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0 }; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| uint8_t numChannels = 0; |
| uint8_t i = 0; |
| uint32_t totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; |
| |
| if (!aValidChannels || !pNumChannels) { |
| sms_log(pMac, QDF_TRACE_LEVEL_ERROR, |
| FL("Output channel list/NumChannels is NULL")); |
| return QDF_STATUS_E_INVAL; |
| } |
| |
| if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) { |
| sms_log(pMac, QDF_TRACE_LEVEL_ERROR, |
| FL("Invalid wifiBand (%d)"), wifiBand); |
| return QDF_STATUS_E_INVAL; |
| } |
| |
| status = sme_get_cfg_valid_channels(hHal, &chanList[0], |
| &totValidChannels); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(pMac, QDF_TRACE_LEVEL_ERROR, |
| FL("Fail to get valid channel list (err=%d)"), status); |
| return status; |
| } |
| |
| switch (wifiBand) { |
| case WIFI_BAND_UNSPECIFIED: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("Unspec Band, return all (%d) valid channels"), |
| totValidChannels); |
| numChannels = totValidChannels; |
| for (i = 0; i < totValidChannels; i++) { |
| aValidChannels[i] = cds_chan_to_freq(chanList[i]); |
| } |
| break; |
| |
| case WIFI_BAND_BG: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_BG (2.4 GHz)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if (CDS_IS_CHANNEL_24GHZ(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| case WIFI_BAND_A: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_A (5 GHz without DFS)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if (CDS_IS_CHANNEL_5GHZ(chanList[i]) && |
| !CDS_IS_DFS_CH(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| case WIFI_BAND_ABG: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if ((CDS_IS_CHANNEL_24GHZ(chanList[i]) || |
| CDS_IS_CHANNEL_5GHZ(chanList[i])) && |
| !CDS_IS_DFS_CH(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| case WIFI_BAND_A_DFS_ONLY: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_A_DFS (5 GHz DFS only)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if (CDS_IS_CHANNEL_5GHZ(chanList[i]) && |
| CDS_IS_DFS_CH(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| case WIFI_BAND_A_WITH_DFS: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if (CDS_IS_CHANNEL_5GHZ(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| case WIFI_BAND_ABG_WITH_DFS: |
| sms_log(pMac, QDF_TRACE_LEVEL_INFO, |
| FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz+5 GHz with DFS)")); |
| for (i = 0; i < totValidChannels; i++) { |
| if (CDS_IS_CHANNEL_24GHZ(chanList[i]) || |
| CDS_IS_CHANNEL_5GHZ(chanList[i])) { |
| aValidChannels[numChannels++] = |
| cds_chan_to_freq(chanList[i]); |
| } |
| } |
| break; |
| |
| default: |
| sms_log(pMac, QDF_TRACE_LEVEL_ERROR, |
| FL("Unknown wifiBand (%d))"), wifiBand); |
| return QDF_STATUS_E_INVAL; |
| break; |
| } |
| *pNumChannels = numChannels; |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ext_scan_get_capabilities |
| \brief SME API to fetch extscan capabilities |
| \param hHal |
| \param pReq: extscan capabilities structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ext_scan_get_capabilities(tHalHandle hHal, |
| tSirGetExtScanCapabilitiesReqParams * |
| pReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pReq; |
| cds_message.type = WMA_EXTSCAN_GET_CAPABILITIES_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ext_scan_start |
| \brief SME API to issue extscan start |
| \param hHal |
| \param pStartCmd: extscan start structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ext_scan_start(tHalHandle hHal, |
| tSirWifiScanCmdReqParams *pStartCmd) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pStartCmd; |
| cds_message.type = WMA_EXTSCAN_START_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ext_scan_stop |
| \brief SME API to issue extscan stop |
| \param hHal |
| \param pStopReq: extscan stop structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ext_scan_stop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pStopReq; |
| cds_message.type = WMA_EXTSCAN_STOP_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_bss_hotlist |
| \brief SME API to set BSSID hotlist |
| \param hHal |
| \param pSetHotListReq: extscan set hotlist structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_bss_hotlist(tHalHandle hHal, |
| tSirExtScanSetBssidHotListReqParams * |
| pSetHotListReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pSetHotListReq; |
| cds_message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_reset_bss_hotlist |
| \brief SME API to reset BSSID hotlist |
| \param hHal |
| \param pSetHotListReq: extscan set hotlist structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_reset_bss_hotlist(tHalHandle hHal, |
| tSirExtScanResetBssidHotlistReqParams * |
| pResetReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pResetReq; |
| cds_message.type = WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_send_wisa_params(): Pass WISA mode to WMA |
| * @hal: HAL context |
| * @wisa_params: pointer to WISA params struct |
| * @sessionId: SME session id |
| * |
| * Pass WISA params to WMA |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_set_wisa_params(tHalHandle hal, |
| struct sir_wisa_params *wisa_params) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct sir_wisa_params *cds_msg_wisa_params; |
| |
| cds_msg_wisa_params = qdf_mem_malloc(sizeof(struct sir_wisa_params)); |
| if (!cds_msg_wisa_params) |
| return QDF_STATUS_E_NOMEM; |
| |
| *cds_msg_wisa_params = *wisa_params; |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| cds_message.bodyptr = cds_msg_wisa_params; |
| cds_message.type = WMA_SET_WISA_PARAMS; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| sme_release_global_lock(&mac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_significant_change |
| \brief SME API to set significant change |
| \param hHal |
| \param pSetSignificantChangeReq: extscan set significant change structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_significant_change(tHalHandle hHal, |
| tSirExtScanSetSigChangeReqParams * |
| pSetSignificantChangeReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pSetSignificantChangeReq; |
| cds_message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_reset_significant_change |
| \brief SME API to reset significant change |
| \param hHal |
| \param pResetReq: extscan reset significant change structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_reset_significant_change(tHalHandle hHal, |
| tSirExtScanResetSignificantChangeReqParams |
| *pResetReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pResetReq; |
| cds_message.type = WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_cached_results |
| \brief SME API to get cached results |
| \param hHal |
| \param pCachedResultsReq: extscan get cached results structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_cached_results(tHalHandle hHal, |
| tSirExtScanGetCachedResultsReqParams * |
| pCachedResultsReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pCachedResultsReq; |
| cds_message.type = WMA_EXTSCAN_GET_CACHED_RESULTS_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_epno_list() - set epno network list |
| * @hal: global hal handle |
| * @input: request message |
| * |
| * This function constructs the cds message and fill in message type, |
| * bodyptr with %input and posts it to WDA queue. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_epno_list(tHalHandle hal, |
| struct wifi_epno_params *input) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct wifi_epno_params *req_msg; |
| int len, i; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| len = sizeof(*req_msg) + |
| (input->num_networks * sizeof(struct wifi_epno_network)); |
| req_msg = qdf_mem_malloc(len); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(req_msg, len); |
| req_msg->num_networks = input->num_networks; |
| req_msg->request_id = input->request_id; |
| req_msg->session_id = input->session_id; |
| for (i = 0; i < req_msg->num_networks; i++) { |
| req_msg->networks[i].rssi_threshold = |
| input->networks[i].rssi_threshold; |
| req_msg->networks[i].flags = input->networks[i].flags; |
| req_msg->networks[i].auth_bit_field = |
| input->networks[i].auth_bit_field; |
| req_msg->networks[i].ssid.length = |
| input->networks[i].ssid.length; |
| qdf_mem_copy(req_msg->networks[i].ssid.ssId, |
| input->networks[i].ssid.ssId, |
| req_msg->networks[i].ssid.length); |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = WMA_SET_EPNO_LIST_REQ; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_set_passpoint_list() - set passpoint network list |
| * @hal: global hal handle |
| * @input: request message |
| * |
| * This function constructs the cds message and fill in message type, |
| * bodyptr with @input and posts it to WDA queue. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_passpoint_list(tHalHandle hal, |
| struct wifi_passpoint_req *input) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct wifi_passpoint_req *req_msg; |
| int len, i; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| len = sizeof(*req_msg) + |
| (input->num_networks * sizeof(struct wifi_passpoint_network)); |
| req_msg = qdf_mem_malloc(len); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(req_msg, len); |
| req_msg->num_networks = input->num_networks; |
| req_msg->request_id = input->request_id; |
| req_msg->session_id = input->session_id; |
| for (i = 0; i < req_msg->num_networks; i++) { |
| req_msg->networks[i].id = |
| input->networks[i].id; |
| qdf_mem_copy(req_msg->networks[i].realm, |
| input->networks[i].realm, |
| strlen(input->networks[i].realm) + 1); |
| qdf_mem_copy(req_msg->networks[i].plmn, |
| input->networks[i].plmn, |
| SIR_PASSPOINT_PLMN_LEN); |
| qdf_mem_copy(req_msg->networks[i].roaming_consortium_ids, |
| input->networks[i].roaming_consortium_ids, |
| sizeof(req_msg->networks[i].roaming_consortium_ids)); |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = WMA_SET_PASSPOINT_LIST_REQ; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_reset_passpoint_list() - reset passpoint network list |
| * @hHal: global hal handle |
| * @input: request message |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_reset_passpoint_list(tHalHandle hal, |
| struct wifi_passpoint_req *input) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct wifi_passpoint_req *req_msg; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| req_msg = qdf_mem_malloc(sizeof(*req_msg)); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(req_msg, sizeof(*req_msg)); |
| req_msg->request_id = input->request_id; |
| req_msg->session_id = input->session_id; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = WMA_RESET_PASSPOINT_LIST_REQ; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_set_ssid_hotlist() - Set the SSID hotlist |
| * @hal: SME handle |
| * @request: set ssid hotlist request |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS |
| sme_set_ssid_hotlist(tHalHandle hal, |
| struct sir_set_ssid_hotlist_request *request) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct sir_set_ssid_hotlist_request *set_req; |
| |
| set_req = qdf_mem_malloc(sizeof(*set_req)); |
| if (!set_req) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| *set_req = *request; |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = set_req; |
| cds_message.type = WMA_EXTSCAN_SET_SSID_HOTLIST_REQ; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| sme_release_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| qdf_mem_free(set_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| } else { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(set_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| return status; |
| } |
| |
| QDF_STATUS sme_ext_scan_register_callback(tHalHandle hHal, |
| void (*pExtScanIndCb)(void *, |
| const uint16_t, |
| void *)) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->sme.pExtScanIndCb = pExtScanIndCb; |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| #endif /* FEATURE_WLAN_EXTSCAN */ |
| |
| #ifdef WLAN_FEATURE_LINK_LAYER_STATS |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ll_stats_clear_req |
| \brief SME API to clear Link Layer Statistics |
| \param hHal |
| \param pclearStatsReq: Link Layer clear stats request params structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal, |
| tSirLLStatsClearReq *pclearStatsReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tSirLLStatsClearReq *clear_stats_req; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "staId = %u", pclearStatsReq->staId); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "statsClearReqMask = 0x%X", |
| pclearStatsReq->statsClearReqMask); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "stopReq = %u", pclearStatsReq->stopReq); |
| |
| clear_stats_req = qdf_mem_malloc(sizeof(*clear_stats_req)); |
| |
| if (!clear_stats_req) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for WMA_LL_STATS_CLEAR_REQ", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *clear_stats_req = *pclearStatsReq; |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = clear_stats_req; |
| cds_message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: not able to post WMA_LL_STATS_CLEAR_REQ", |
| __func__); |
| qdf_mem_free(clear_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: " |
| "sme_acquire_global_lock error", __func__); |
| qdf_mem_free(clear_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ll_stats_set_req |
| \brief SME API to set the Link Layer Statistics |
| \param hHal |
| \param psetStatsReq: Link Layer set stats request params structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq *psetStatsReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tSirLLStatsSetReq *set_stats_req; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: MPDU Size = %u", __func__, |
| psetStatsReq->mpduSizeThreshold); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| " Aggressive Stats Collections = %u", |
| psetStatsReq->aggressiveStatisticsGathering); |
| |
| set_stats_req = qdf_mem_malloc(sizeof(*set_stats_req)); |
| |
| if (!set_stats_req) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for WMA_LL_STATS_SET_REQ", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *set_stats_req = *psetStatsReq; |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = set_stats_req; |
| cds_message.type = WMA_LINK_LAYER_STATS_SET_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: not able to post WMA_LL_STATS_SET_REQ", |
| __func__); |
| qdf_mem_free(set_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: " |
| "sme_acquire_global_lock error", __func__); |
| qdf_mem_free(set_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_ll_stats_get_req |
| \brief SME API to get the Link Layer Statistics |
| \param hHal |
| \param pgetStatsReq: Link Layer get stats request params structure |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq *pgetStatsReq) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tSirLLStatsGetReq *get_stats_req; |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "reqId = %u", pgetStatsReq->reqId); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "staId = %u", pgetStatsReq->staId); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "Stats Type = %u", pgetStatsReq->paramIdMask); |
| |
| get_stats_req = qdf_mem_malloc(sizeof(*get_stats_req)); |
| |
| if (!get_stats_req) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for WMA_LL_STATS_GET_REQ", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *get_stats_req = *pgetStatsReq; |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = get_stats_req; |
| cds_message.type = WMA_LINK_LAYER_STATS_GET_REQ; |
| MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, |
| NO_SESSION, cds_message.type)); |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: not able to post WMA_LL_STATS_GET_REQ", |
| __func__); |
| |
| qdf_mem_free(get_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: " |
| "sme_acquire_global_lock error", __func__); |
| qdf_mem_free(get_stats_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_link_layer_stats_ind_cb |
| \brief SME API to trigger the stats are available after get request |
| \param hHal |
| \param callback_routine - HDD callback which needs to be invoked after |
| getting status notification from FW |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_link_layer_stats_ind_cb |
| (tHalHandle hHal, |
| void (*callback_routine)(void *callbackCtx, int indType, void *pRsp) |
| ) { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pMac->sme.pLinkLayerStatsIndCallback = callback_routine; |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: " |
| "sme_acquire_global_lock error", __func__); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_reset_link_layer_stats_ind_cb() - SME API to reset link layer stats |
| * indication |
| * @h_hal: Hal Handle |
| * |
| * This function reset's the link layer stats indication |
| * |
| * Return: QDF_STATUS Enumeration |
| */ |
| |
| QDF_STATUS sme_reset_link_layer_stats_ind_cb(tHalHandle h_hal) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal pmac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return QDF_STATUS_E_INVAL; |
| } |
| pmac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&pmac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| pmac->sme.pLinkLayerStatsIndCallback = NULL; |
| sme_release_global_lock(&pmac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: sme_acquire_global_lock error", |
| __func__); |
| } |
| |
| return status; |
| } |
| |
| |
| #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ |
| |
| /** |
| * sme_fw_mem_dump_register_cb() - Register fw memory dump callback |
| * |
| * @hal - MAC global handle |
| * @callback_routine - callback routine from HDD |
| * |
| * This API is invoked by HDD to register its callback in SME |
| * |
| * Return: QDF_STATUS |
| */ |
| #ifdef WLAN_FEATURE_MEMDUMP |
| QDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal, |
| void (*callback_routine)(void *cb_context, |
| struct fw_dump_rsp *rsp)) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&pmac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pmac->sme.fw_dump_callback = callback_routine; |
| sme_release_global_lock(&pmac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock error")); |
| } |
| |
| return status; |
| } |
| #else |
| QDF_STATUS sme_fw_mem_dump_register_cb(tHalHandle hal, |
| void (*callback_routine)(void *cb_context, |
| struct fw_dump_rsp *rsp)) |
| { |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* WLAN_FEATURE_MEMDUMP */ |
| |
| /** |
| * sme_fw_mem_dump_unregister_cb() - Unregister fw memory dump callback |
| * |
| * @hHal - MAC global handle |
| * |
| * This API is invoked by HDD to unregister its callback in SME |
| * |
| * Return: QDF_STATUS |
| */ |
| #ifdef WLAN_FEATURE_MEMDUMP |
| QDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&pmac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| pmac->sme.fw_dump_callback = NULL; |
| sme_release_global_lock(&pmac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock error")); |
| } |
| |
| return status; |
| } |
| #else |
| QDF_STATUS sme_fw_mem_dump_unregister_cb(tHalHandle hal) |
| { |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* WLAN_FEATURE_MEMDUMP */ |
| |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| /*-------------------------------------------------------------------------- |
| \brief sme_update_roam_offload_enabled() - enable/disable roam offload feaure |
| It is used at in the REG_DYNAMIC_VARIABLE macro definition of |
| \param hHal - The handle returned by mac_open. |
| \param nRoamOffloadEnabled - The bool to update with |
| \return QDF_STATUS_SUCCESS - SME update config successfully. |
| Other status means SME is failed to update. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| QDF_STATUS sme_update_roam_offload_enabled(tHalHandle hHal, |
| bool nRoamOffloadEnabled) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: LFR3:gRoamOffloadEnabled is changed from %d to %d", |
| __func__, pMac->roam.configParam.isRoamOffloadEnabled, |
| nRoamOffloadEnabled); |
| pMac->roam.configParam.isRoamOffloadEnabled = |
| nRoamOffloadEnabled; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_update_roam_key_mgmt_offload_enabled() - enable/disable key mgmt offload |
| * This is a synchronous call |
| * @hal_ctx: The handle returned by mac_open. |
| * @session_id: Session Identifier |
| * @key_mgmt_offload_enabled: key mgmt enable/disable flag |
| * @okc_enabled: Opportunistic key caching enable/disable flag |
| * Return: QDF_STATUS_SUCCESS - SME updated config successfully. |
| * Other status means SME is failed to update. |
| */ |
| |
| QDF_STATUS sme_update_roam_key_mgmt_offload_enabled(tHalHandle hal_ctx, |
| uint8_t session_id, |
| bool key_mgmt_offload_enabled, |
| bool okc_enabled) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: LFR3: key_mgmt_offload_enabled changed to %d", |
| __func__, key_mgmt_offload_enabled); |
| status = csr_roam_set_key_mgmt_offload(mac_ctx, |
| session_id, |
| key_mgmt_offload_enabled, |
| okc_enabled); |
| } else { |
| status = QDF_STATUS_E_INVAL; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| |
| return status; |
| } |
| #endif |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_get_temperature |
| \brief SME API to get the pdev temperature |
| \param hHal |
| \param temperature context |
| \param pCallbackfn: callback fn with response (temperature) |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_get_temperature(tHalHandle hHal, |
| void *tempContext, |
| void (*pCallbackfn)(int temperature, |
| void *pContext)) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| if ((NULL == pCallbackfn) && |
| (NULL == pMac->sme.pGetTemperatureCb)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL |
| ("Indication Call back did not registered")); |
| sme_release_global_lock(&pMac->sme); |
| return QDF_STATUS_E_FAILURE; |
| } else if (NULL != pCallbackfn) { |
| pMac->sme.pTemperatureCbContext = tempContext; |
| pMac->sme.pGetTemperatureCb = pCallbackfn; |
| } |
| /* serialize the req through MC thread */ |
| cds_message.bodyptr = NULL; |
| cds_message.type = WMA_GET_TEMPERATURE_REQ; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Post Get Temperature msg fail")); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_scanning_mac_oui |
| \brief SME API to set scanning mac oui |
| \param hHal |
| \param pScanMacOui: Scanning Mac Oui (input 3 bytes) |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_scanning_mac_oui(tHalHandle hHal, tSirScanMacOui *pScanMacOui) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = pScanMacOui; |
| cds_message.type = WMA_SET_SCAN_MAC_OUI_REQ; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Msg post Set Scan Mac OUI failed")); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| |
| #ifdef DHCP_SERVER_OFFLOAD |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_dhcp_srv_offload |
| \brief SME API to set DHCP server offload info |
| \param hHal |
| \param pDhcpSrvInfo : DHCP server offload info struct |
| \- return QDF_STATUS |
| -------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_dhcp_srv_offload(tHalHandle hHal, |
| tSirDhcpSrvOffloadInfo *pDhcpSrvInfo) |
| { |
| cds_msg_t cds_message; |
| tSirDhcpSrvOffloadInfo *pSmeDhcpSrvInfo; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| |
| pSmeDhcpSrvInfo = qdf_mem_malloc(sizeof(*pSmeDhcpSrvInfo)); |
| |
| if (!pSmeDhcpSrvInfo) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for WMA_SET_DHCP_SERVER_OFFLOAD_CMD", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *pSmeDhcpSrvInfo = *pDhcpSrvInfo; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| /* serialize the req through MC thread */ |
| cds_message.type = WMA_SET_DHCP_SERVER_OFFLOAD_CMD; |
| cds_message.bodyptr = pSmeDhcpSrvInfo; |
| |
| if (!QDF_IS_STATUS_SUCCESS |
| (cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_message))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WMA_SET_DHCP_SERVER_OFFLOAD_CMD to WMA!", |
| __func__); |
| qdf_mem_free(pSmeDhcpSrvInfo); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: sme_acquire_global_lock error!", __func__); |
| qdf_mem_free(pSmeDhcpSrvInfo); |
| } |
| |
| return status; |
| } |
| #endif /* DHCP_SERVER_OFFLOAD */ |
| |
| #ifdef WLAN_FEATURE_GPIO_LED_FLASHING |
| /* --------------------------------------------------------------------------- |
| \fn sme_set_led_flashing |
| \brief API to set the Led flashing parameters. |
| \param hHal - The handle returned by mac_open. |
| \param x0, x1 - led flashing parameters |
| \return QDF_STATUS |
| ---------------------------------------------------------------------------*/ |
| QDF_STATUS sme_set_led_flashing(tHalHandle hHal, uint8_t type, |
| uint32_t x0, uint32_t x1) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t cds_message; |
| tSirLedFlashingReq *ledflashing; |
| |
| ledflashing = qdf_mem_malloc(sizeof(*ledflashing)); |
| if (!ledflashing) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL |
| ("Not able to allocate memory for WMA_LED_TIMING_REQ")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| ledflashing->pattern_id = type; |
| ledflashing->led_x0 = x0; |
| ledflashing->led_x1 = x1; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = ledflashing; |
| cds_message.type = WMA_LED_FLASHING_REQ; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| status = QDF_STATUS_E_FAILURE; |
| sme_release_global_lock(&pMac->sme); |
| } |
| return status; |
| } |
| #endif |
| |
| /** |
| * sme_handle_dfS_chan_scan() - handle DFS channel configuration |
| * @h_hal: corestack handler |
| * @dfs_flag: flag indicating dfs channel enable/disable |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_handle_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| |
| mac->scan.fEnableDFSChnlScan = dfs_flag; |
| |
| /* update the channel list to the firmware */ |
| status = csr_update_channel_list(mac); |
| |
| sme_release_global_lock(&mac->sme); |
| } |
| |
| return status; |
| } |
| |
| #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH |
| /** |
| * sme_validate_sap_channel_switch() - validate target channel switch w.r.t |
| * concurreny rules set to avoid channel interference. |
| * @hal - Hal context |
| * @sap_ch - channel to switch |
| * @sap_phy_mode - phy mode of SAP |
| * @cc_switch_mode - concurreny switch mode |
| * @session_id - sme session id. |
| * |
| * Return: true if there is no channel interference else return false |
| */ |
| bool sme_validate_sap_channel_switch(tHalHandle hal, |
| uint16_t sap_ch, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode, |
| uint8_t session_id) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id); |
| uint16_t intf_channel = 0; |
| |
| if (!session) |
| return false; |
| |
| session->ch_switch_in_progress = true; |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| intf_channel = csr_check_concurrent_channel_overlap(mac, sap_ch, |
| sap_phy_mode, |
| cc_switch_mode); |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock error!")); |
| session->ch_switch_in_progress = false; |
| return false; |
| } |
| |
| session->ch_switch_in_progress = false; |
| return (intf_channel == 0) ? true : false; |
| } |
| #endif |
| |
| /** |
| * sme_configure_stats_avg_factor() - function to config avg. stats factor |
| * @hal: hal |
| * @session_id: session ID |
| * @stats_avg_factor: average stats factor |
| * |
| * This function configures the stats avg factor in firmware |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_configure_stats_avg_factor(tHalHandle hal, uint8_t session_id, |
| uint16_t stats_avg_factor) |
| { |
| cds_msg_t msg; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| struct sir_stats_avg_factor *stats_factor; |
| |
| stats_factor = qdf_mem_malloc(sizeof(*stats_factor)); |
| |
| if (!stats_factor) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for SIR_HAL_CONFIG_STATS_FACTOR", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| |
| stats_factor->vdev_id = session_id; |
| stats_factor->stats_avg_factor = stats_avg_factor; |
| |
| /* serialize the req through MC thread */ |
| msg.type = SIR_HAL_CONFIG_STATS_FACTOR; |
| msg.bodyptr = stats_factor; |
| |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post SIR_HAL_CONFIG_STATS_FACTOR to WMA!", |
| __func__); |
| qdf_mem_free(stats_factor); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: sme_acquire_global_lock error!", |
| __func__); |
| qdf_mem_free(stats_factor); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_configure_guard_time() - function to configure guard time |
| * @hal: hal |
| * @session_id: session id |
| * @guard_time: guard time |
| * |
| * This function configures the guard time in firmware |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_configure_guard_time(tHalHandle hal, uint8_t session_id, |
| uint32_t guard_time) |
| { |
| cds_msg_t msg; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| struct sir_guard_time_request *g_time; |
| |
| g_time = qdf_mem_malloc(sizeof(*g_time)); |
| |
| if (!g_time) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to allocate memory for SIR_HAL_CONFIG_GUARD_TIME", |
| __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| |
| g_time->vdev_id = session_id; |
| g_time->guard_time = guard_time; |
| |
| /* serialize the req through MC thread */ |
| msg.type = SIR_HAL_CONFIG_GUARD_TIME; |
| msg.bodyptr = g_time; |
| |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post SIR_HAL_CONFIG_GUARD_TIME to WMA!", |
| __func__); |
| qdf_mem_free(g_time); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: sme_acquire_global_lock error!", |
| __func__); |
| qdf_mem_free(g_time); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_configure_modulated_dtim() - function to configure modulated dtim |
| * @h_hal: SME API to enable/disable modulated DTIM instantaneously |
| * @session_id: session ID |
| * @modulated_dtim: modulated dtim value |
| * |
| * This function configures the modulated dtim in firmware |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_configure_modulated_dtim(tHalHandle h_hal, uint8_t session_id, |
| uint32_t modulated_dtim) |
| { |
| cds_msg_t msg; |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(h_hal); |
| wma_cli_set_cmd_t *iwcmd; |
| |
| iwcmd = qdf_mem_malloc(sizeof(*iwcmd)); |
| if (NULL == iwcmd) { |
| QDF_TRACE(QDF_MODULE_ID_SME, |
| QDF_TRACE_LEVEL_FATAL, |
| "%s: qdf_mem_malloc failed", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| |
| qdf_mem_zero((void *)iwcmd, sizeof(*iwcmd)); |
| iwcmd->param_value = modulated_dtim; |
| iwcmd->param_vdev_id = session_id; |
| iwcmd->param_id = GEN_PARAM_MODULATED_DTIM; |
| iwcmd->param_vp_dev = GEN_CMD; |
| msg.type = WMA_CLI_SET_CMD; |
| msg.reserved = 0; |
| msg.bodyptr = (void *)iwcmd; |
| |
| if (!QDF_IS_STATUS_SUCCESS( |
| cds_mq_post_message(QDF_MODULE_ID_WMA, &msg))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post GEN_PARAM_DYNAMIC_DTIM to WMA!", |
| __func__); |
| qdf_mem_free(iwcmd); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: sme_acquire_global_lock error!", |
| __func__); |
| qdf_mem_free(iwcmd); |
| } |
| |
| return status; |
| } |
| |
| /* |
| * sme_wifi_start_logger() - Send the start/stop logging command to WMA |
| * to either start/stop logging |
| * @hal: HAL context |
| * @start_log: Structure containing the wifi start logger params |
| * |
| * This function sends the start/stop logging command to WMA |
| * |
| * Return: QDF_STATUS_SUCCESS on successful posting |
| */ |
| QDF_STATUS sme_wifi_start_logger(tHalHandle hal, |
| struct sir_wifi_start_log start_log) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct sir_wifi_start_log *req_msg; |
| uint32_t len; |
| |
| len = sizeof(*req_msg); |
| req_msg = qdf_mem_malloc(len); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(req_msg, len); |
| |
| req_msg->verbose_level = start_log.verbose_level; |
| req_msg->flag = start_log.flag; |
| req_msg->ring_id = start_log.ring_id; |
| req_msg->ini_triggered = start_log.ini_triggered; |
| req_msg->user_triggered = start_log.user_triggered; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = SIR_HAL_START_STOP_LOGGING; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_neighbor_middle_of_roaming() - Function to know if |
| * STA is in the middle of roaming states |
| * @hal: Handle returned by macOpen |
| * @sessionId: sessionId of the STA session |
| * |
| * This function is a wrapper to call |
| * csr_neighbor_middle_of_roaming to know STA is in the |
| * middle of roaming states |
| * |
| * Return: True or False |
| * |
| */ |
| bool sme_neighbor_middle_of_roaming(tHalHandle hHal, uint8_t sessionId) |
| { |
| return csr_neighbor_middle_of_roaming(PMAC_STRUCT(hHal), sessionId); |
| } |
| |
| /* |
| * sme_send_flush_logs_cmd_to_fw() - Flush FW logs |
| * @mac: MAC handle |
| * |
| * This function is used to send the command that will |
| * be used to flush the logs in the firmware |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_send_flush_logs_cmd_to_fw(tpAniSirGlobal mac) |
| { |
| QDF_STATUS status; |
| cds_msg_t message; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| message.bodyptr = NULL; |
| message.type = SIR_HAL_FLUSH_LOG_TO_FW; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_enable_uapsd_for_ac() - enable uapsd for access catagory requerst to WMA |
| * @cds_ctx: cds context |
| * @sta_id: station id |
| * @ac: access catagory |
| * @tid: tid value |
| * @pri: user priority |
| * @srvc_int: service interval |
| * @sus_int: suspend interval |
| * @dir: tspec direction |
| * @psb: PSB value |
| * @sessionId: session id |
| * @delay_interval: delay interval |
| * |
| * Return: QDF status |
| */ |
| QDF_STATUS sme_enable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id, |
| sme_ac_enum_type ac, uint8_t tid, |
| uint8_t pri, uint32_t srvc_int, |
| uint32_t sus_int, |
| sme_tspec_dir_type dir, |
| uint8_t psb, uint32_t sessionId, |
| uint32_t delay_interval) |
| { |
| void *wma_handle; |
| t_wma_trigger_uapsd_params uapsd_params; |
| enum uapsd_ac access_category; |
| |
| if (!psb) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, |
| "No need to configure auto trigger:psb is 0"); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "wma_handle is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| switch (ac) { |
| case SME_AC_BK: |
| access_category = UAPSD_BK; |
| break; |
| case SME_AC_BE: |
| access_category = UAPSD_BE; |
| break; |
| case SME_AC_VI: |
| access_category = UAPSD_VI; |
| break; |
| case SME_AC_VO: |
| access_category = UAPSD_VO; |
| break; |
| default: |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| uapsd_params.wmm_ac = access_category; |
| uapsd_params.user_priority = pri; |
| uapsd_params.service_interval = srvc_int; |
| uapsd_params.delay_interval = delay_interval; |
| uapsd_params.suspend_interval = sus_int; |
| |
| if (QDF_STATUS_SUCCESS != |
| wma_trigger_uapsd_params(wma_handle, sessionId, &uapsd_params)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Failed to Trigger Uapsd params for sessionId %d", |
| sessionId); |
| return QDF_STATUS_E_FAILURE; |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_disable_uapsd_for_ac() - disable uapsed access catagory request to WMA |
| * @cds_ctx: cds context |
| * @sta_id: station id |
| * @ac: access catagory |
| * @sessionId: session id |
| * |
| * Return: QDF status |
| */ |
| QDF_STATUS sme_disable_uapsd_for_ac(void *cds_ctx, uint8_t sta_id, |
| sme_ac_enum_type ac, |
| uint32_t sessionId) |
| { |
| void *wma_handle; |
| enum uapsd_ac access_category; |
| |
| switch (ac) { |
| case SME_AC_BK: |
| access_category = UAPSD_BK; |
| break; |
| case SME_AC_BE: |
| access_category = UAPSD_BE; |
| break; |
| case SME_AC_VI: |
| access_category = UAPSD_VI; |
| break; |
| case SME_AC_VO: |
| access_category = UAPSD_VO; |
| break; |
| default: |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "wma handle is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| if (QDF_STATUS_SUCCESS != |
| wma_disable_uapsd_per_ac(wma_handle, sessionId, access_category)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "Failed to disable uapsd for ac %d for sessionId %d", |
| ac, sessionId); |
| return QDF_STATUS_E_FAILURE; |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_update_nss() - SME API to change the number for spatial streams |
| * (1 or 2) |
| * @hal: Handle returned by mac open |
| * @nss: Number of spatial streams |
| * |
| * This function is used to update the number of spatial streams supported. |
| * |
| * Return: Success upon successfully changing nss else failure |
| * |
| */ |
| QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); |
| uint32_t i, value = 0; |
| union { |
| uint16_t cfg_value16; |
| tSirMacHTCapabilityInfo ht_cap_info; |
| } uHTCapabilityInfo; |
| tCsrRoamSession *csr_session; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| mac_ctx->roam.configParam.enable2x2 = (nss == 1) ? 0 : 1; |
| |
| /* get the HT capability info*/ |
| sme_cfg_get_int(mac_ctx, WNI_CFG_HT_CAP_INFO, &value); |
| uHTCapabilityInfo.cfg_value16 = (0xFFFF & value); |
| |
| for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { |
| if (CSR_IS_SESSION_VALID(mac_ctx, i)) { |
| csr_session = &mac_ctx->roam.roamSession[i]; |
| csr_session->htConfig.ht_tx_stbc = |
| uHTCapabilityInfo.ht_cap_info.txSTBC; |
| } |
| } |
| |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_update_user_configured_nss() - sets the nss based on user request |
| * @hal: Pointer to HAL |
| * @nss: number of streams |
| * |
| * Return: None |
| */ |
| void sme_update_user_configured_nss(tHalHandle hal, uint8_t nss) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| mac_ctx->user_configured_nss = nss; |
| } |
| |
| /** |
| * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback |
| * @h_hal: global hal handle |
| * @cb: callback function pointer |
| * |
| * This function stores the rssi threshold breached callback function. |
| * |
| * Return: QDF_STATUS enumeration. |
| */ |
| QDF_STATUS sme_set_rssi_threshold_breached_cb(tHalHandle h_hal, |
| void (*cb)(void *, struct rssi_breach_event *)) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return QDF_STATUS_E_INVAL; |
| } |
| mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| return status; |
| } |
| |
| mac->sme.rssi_threshold_breached_cb = cb; |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_set_rssi_threshold_breached_cb() - Reset rssi threshold breached callback |
| * @hal: global hal handle |
| * |
| * This function de-registers the rssi threshold breached callback function. |
| * |
| * Return: QDF_STATUS enumeration. |
| */ |
| QDF_STATUS sme_reset_rssi_threshold_breached_cb(tHalHandle hal) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| return status; |
| } |
| |
| mac->sme.rssi_threshold_breached_cb = NULL; |
| sme_release_global_lock(&mac->sme); |
| return status; |
| } |
| |
| /** |
| * sme_is_any_session_in_connected_state() - SME wrapper API to |
| * check if any session is in connected state or not. |
| * |
| * @hal: Handle returned by mac open |
| * |
| * This function is used to check if any valid sme session is in |
| * connected state or not. |
| * |
| * Return: true if any session is connected, else false. |
| * |
| */ |
| bool sme_is_any_session_in_connected_state(tHalHandle h_hal) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(h_hal); |
| QDF_STATUS status; |
| bool ret = false; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| ret = csr_is_any_session_in_connect_state(mac_ctx); |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| return ret; |
| } |
| |
| /** |
| * sme_set_rssi_monitoring() - set rssi monitoring |
| * @hal: global hal handle |
| * @input: request message |
| * |
| * This function constructs the vos message and fill in message type, |
| * bodyptr with @input and posts it to WDA queue. |
| * |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_set_rssi_monitoring(tHalHandle hal, |
| struct rssi_monitor_req *input) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct rssi_monitor_req *req_msg; |
| |
| sms_log(mac, LOG1, FL("enter")); |
| req_msg = qdf_mem_malloc(sizeof(*req_msg)); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("memory allocation failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *req_msg = *input; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = WMA_SET_RSSI_MONITOR_REQ; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| } |
| sme_release_global_lock(&mac->sme); |
| |
| return status; |
| } |
| |
| /** |
| * sme_fw_mem_dump() - Get FW memory dump |
| * @hHal: hal handle |
| * @recvd_req: received memory dump request. |
| * |
| * This API is invoked by HDD to indicate FW to start |
| * dumping firmware memory. |
| * |
| * Return: QDF_STATUS |
| */ |
| #ifdef WLAN_FEATURE_MEMDUMP |
| QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| cds_msg_t msg; |
| struct fw_dump_req *send_req; |
| struct fw_dump_seg_req seg_req; |
| int loop; |
| |
| send_req = qdf_mem_malloc(sizeof(*send_req)); |
| if (!send_req) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Memory allocation failed for WDA_FW_MEM_DUMP")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| qdf_mem_copy(send_req, recvd_req, sizeof(*send_req)); |
| |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("request_id:%d num_seg:%d"), |
| send_req->request_id, send_req->num_seg); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("Segment Information")); |
| for (loop = 0; loop < send_req->num_seg; loop++) { |
| seg_req = send_req->segment[loop]; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("seg_number:%d"), loop); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("seg_id:%d start_addr_lo:0x%x start_addr_hi:0x%x"), |
| seg_req.seg_id, seg_req.seg_start_addr_lo, |
| seg_req.seg_start_addr_hi); |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("seg_length:%d dst_addr_lo:0x%x dst_addr_hi:0x%x"), |
| seg_req.seg_length, seg_req.dst_addr_lo, |
| seg_req.dst_addr_hi); |
| } |
| |
| if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { |
| msg.bodyptr = send_req; |
| msg.type = WMA_FW_MEM_DUMP_REQ; |
| msg.reserved = 0; |
| |
| qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA, &msg); |
| if (QDF_STATUS_SUCCESS != qdf_status) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_FW_MEM_DUMP")); |
| qdf_mem_free(send_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&pMac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to acquire SME Global Lock")); |
| qdf_mem_free(send_req); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| |
| return status; |
| } |
| #else |
| QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req) |
| { |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* WLAN_FEATURE_MEMDUMP */ |
| |
| /* |
| * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA |
| * @hal: Handle returned by macOpen |
| * @msg: PCL channel list and length structure |
| * |
| * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW |
| * Return: QDF_STATUS_SUCCESS on successful posting |
| */ |
| QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, |
| struct sir_pcl_list msg) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| cds_msg_t cds_message; |
| struct wmi_pcl_chan_weights *req_msg; |
| uint32_t len, i; |
| |
| len = sizeof(*req_msg); |
| |
| req_msg = qdf_mem_malloc(len); |
| if (!req_msg) { |
| sms_log(mac, LOGE, FL("qdf_mem_malloc failed")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| qdf_mem_zero(req_msg, len); |
| |
| for (i = 0; i < msg.pcl_len; i++) { |
| req_msg->pcl_list[i] = msg.pcl_list[i]; |
| req_msg->weight_list[i] = msg.weight_list[i]; |
| } |
| |
| req_msg->pcl_len = msg.pcl_len; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (status != QDF_STATUS_SUCCESS) { |
| sms_log(mac, LOGE, |
| FL("sme_acquire_global_lock failed!(status=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| return status; |
| } |
| |
| /* Serialize the req through MC thread */ |
| cds_message.bodyptr = req_msg; |
| cds_message.type = SIR_HAL_PDEV_SET_PCL_TO_FW; |
| status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, |
| FL("cds_mq_post_message failed!(err=%d)"), |
| status); |
| qdf_mem_free(req_msg); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac->sme); |
| |
| return status; |
| } |
| |
| /* |
| * sme_pdev_set_hw_mode() - Send WMI_PDEV_SET_HW_MODE_CMDID to the WMA |
| * @hal: Handle returned by macOpen |
| * @msg: HW mode structure containing hw mode and callback details |
| * |
| * Sends the command to CSR to send WMI_PDEV_SET_HW_MODE_CMDID to FW |
| * Return: QDF_STATUS_SUCCESS on successful posting |
| */ |
| QDF_STATUS sme_pdev_set_hw_mode(tHalHandle hal, |
| struct sir_hw_mode msg) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| tSmeCmd *cmd = NULL; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, FL("Failed to acquire lock")); |
| return QDF_STATUS_E_RESOURCES; |
| } |
| |
| cmd = sme_get_command_buffer(mac); |
| if (!cmd) { |
| sms_log(mac, LOGE, FL("Get command buffer failed")); |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_E_NULL_VALUE; |
| } |
| |
| cmd->command = e_sme_command_set_hw_mode; |
| cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index; |
| cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb; |
| cmd->u.set_hw_mode_cmd.reason = msg.reason; |
| cmd->u.set_hw_mode_cmd.session_id = msg.session_id; |
| |
| sms_log(mac, LOG1, |
| FL("Queuing set hw mode to CSR, session:%d reason:%d"), |
| cmd->u.set_hw_mode_cmd.session_id, |
| cmd->u.set_hw_mode_cmd.reason); |
| csr_queue_sme_command(mac, cmd, false); |
| |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_register_hw_mode_trans_cb() - HW mode transition callback registration |
| * @hal: Handle returned by macOpen |
| * @callback: HDD callback to be registered |
| * |
| * Registers the HDD callback with SME. This callback will be invoked when |
| * HW mode transition event is received from the FW |
| * |
| * Return: None |
| */ |
| void sme_register_hw_mode_trans_cb(tHalHandle hal, |
| hw_mode_transition_cb callback) |
| { |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| |
| mac->sme.sme_hw_mode_trans_cb = callback; |
| sms_log(mac, LOG1, FL("HW mode transition callback registered")); |
| } |
| |
| /** |
| * sme_nss_update_request() - Send beacon templete update to FW with new |
| * nss value |
| * @hal: Handle returned by macOpen |
| * @vdev_id: the session id |
| * @new_nss: the new nss value |
| * @cback: hdd callback |
| * @next_action: next action to happen at policy mgr after beacon update |
| * |
| * Sends the command to CSR to send to PE |
| * Return: QDF_STATUS_SUCCESS on successful posting |
| */ |
| QDF_STATUS sme_nss_update_request(tHalHandle hHal, uint32_t vdev_id, |
| uint8_t new_nss, void *cback, uint8_t next_action, |
| void *hdd_context, |
| enum sir_conn_update_reason reason) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| tpAniSirGlobal mac = PMAC_STRUCT(hHal); |
| tSmeCmd *cmd = NULL; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| cmd = sme_get_command_buffer(mac); |
| if (!cmd) { |
| sms_log(mac, LOGE, FL("Get command buffer failed")); |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_E_NULL_VALUE; |
| } |
| cmd->command = e_sme_command_nss_update; |
| /* Sessionized modules may require this info */ |
| cmd->sessionId = vdev_id; |
| cmd->u.nss_update_cmd.new_nss = new_nss; |
| cmd->u.nss_update_cmd.session_id = vdev_id; |
| cmd->u.nss_update_cmd.nss_update_cb = cback; |
| cmd->u.nss_update_cmd.context = hdd_context; |
| cmd->u.nss_update_cmd.next_action = next_action; |
| cmd->u.nss_update_cmd.reason = reason; |
| |
| sms_log(mac, LOG1, FL("Queuing e_sme_command_nss_update to CSR")); |
| csr_queue_sme_command(mac, cmd, false); |
| sme_release_global_lock(&mac->sme); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_soc_set_dual_mac_config() - Set dual mac configurations |
| * @hal: Handle returned by macOpen |
| * @msg: Structure containing the dual mac config parameters |
| * |
| * Queues configuration information to CSR to configure |
| * WLAN firmware for the dual MAC features |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_soc_set_dual_mac_config(tHalHandle hal, |
| struct sir_dual_mac_config msg) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| tSmeCmd *cmd; |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, FL("Failed to acquire lock")); |
| return QDF_STATUS_E_RESOURCES; |
| } |
| |
| cmd = sme_get_command_buffer(mac); |
| if (!cmd) { |
| sms_log(mac, LOGE, FL("Get command buffer failed")); |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_E_NULL_VALUE; |
| } |
| |
| cmd->command = e_sme_command_set_dual_mac_config; |
| cmd->u.set_dual_mac_cmd.scan_config = msg.scan_config; |
| cmd->u.set_dual_mac_cmd.fw_mode_config = msg.fw_mode_config; |
| cmd->u.set_dual_mac_cmd.set_dual_mac_cb = msg.set_dual_mac_cb; |
| |
| sms_log(mac, LOG1, |
| FL("Queuing e_sme_command_set_dual_mac_config to CSR: %x %x"), |
| cmd->u.set_dual_mac_cmd.scan_config, |
| cmd->u.set_dual_mac_cmd.fw_mode_config); |
| csr_queue_sme_command(mac, cmd, false); |
| |
| sme_release_global_lock(&mac->sme); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| #ifdef FEATURE_LFR_SUBNET_DETECTION |
| /** |
| * sme_gateway_param_update() - to update gateway parameters with WMA |
| * @Hal: hal handle |
| * @gw_params: request parameters from HDD |
| * |
| * Return: QDF_STATUS |
| * |
| * This routine will update gateway parameters to WMA |
| */ |
| QDF_STATUS sme_gateway_param_update(tHalHandle Hal, |
| struct gateway_param_update_req *gw_params) |
| { |
| QDF_STATUS qdf_status; |
| cds_msg_t cds_message; |
| struct gateway_param_update_req *request_buf; |
| |
| request_buf = qdf_mem_malloc(sizeof(*request_buf)); |
| if (NULL == request_buf) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to allocate memory for gw param update request")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| *request_buf = *gw_params; |
| |
| cds_message.type = WMA_GW_PARAM_UPDATE_REQ; |
| cds_message.reserved = 0; |
| cds_message.bodyptr = request_buf; |
| qdf_status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Not able to post WMA_GW_PARAM_UPDATE_REQ message to HAL")); |
| qdf_mem_free(request_buf); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| #endif /* FEATURE_LFR_SUBNET_DETECTION */ |
| |
| /** |
| * sme_soc_set_antenna_mode() - set antenna mode |
| * @hal: Handle returned by macOpen |
| * @msg: Structure containing the antenna mode parameters |
| * |
| * Send the command to CSR to send |
| * WMI_SOC_SET_ANTENNA_MODE_CMDID to FW |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_soc_set_antenna_mode(tHalHandle hal, |
| struct sir_antenna_mode_param *msg) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| tSmeCmd *cmd; |
| |
| if (NULL == msg) { |
| sms_log(mac, LOGE, FL("antenna mode mesg is NULL")); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| sms_log(mac, LOGE, FL("Failed to acquire lock")); |
| return QDF_STATUS_E_RESOURCES; |
| } |
| |
| cmd = sme_get_command_buffer(mac); |
| if (!cmd) { |
| sme_release_global_lock(&mac->sme); |
| sms_log(mac, LOGE, FL("Get command buffer failed")); |
| return QDF_STATUS_E_NULL_VALUE; |
| } |
| |
| cmd->command = e_sme_command_set_antenna_mode; |
| cmd->u.set_antenna_mode_cmd = *msg; |
| |
| sms_log(mac, LOG1, |
| FL("Queuing e_sme_command_set_antenna_mode to CSR: %d %d"), |
| cmd->u.set_antenna_mode_cmd.num_rx_chains, |
| cmd->u.set_antenna_mode_cmd.num_tx_chains); |
| |
| csr_queue_sme_command(mac, cmd, false); |
| sme_release_global_lock(&mac->sme); |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_set_peer_authorized() - call peer authorized callback |
| * @peer_addr: peer mac address |
| * @auth_cb: auth callback |
| * @vdev_id: vdev id |
| * |
| * Return: QDF Status |
| */ |
| QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr, |
| sme_peer_authorized_fp auth_cb, |
| uint32_t vdev_id) |
| { |
| void *wma_handle; |
| |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "wma handle is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| wma_set_peer_authorized_cb(wma_handle, auth_cb); |
| return wma_set_peer_param(wma_handle, peer_addr, WMI_PEER_AUTHORIZE, |
| 1, vdev_id); |
| } |
| |
| /* |
| * sme_handle_set_fcc_channel() - set spec. tx power for non-fcc channel |
| * @hal: HAL pointer |
| * @fcc_constraint: flag to enable/disable the constraint |
| * @scan_pending: whether there is pending scan |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_handle_set_fcc_channel(tHalHandle hal, bool fcc_constraint, |
| bool scan_pending) |
| { |
| QDF_STATUS status; |
| tpAniSirGlobal mac_ptr = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&mac_ptr->sme); |
| |
| if (QDF_STATUS_SUCCESS == status) { |
| |
| if (fcc_constraint != mac_ptr->scan.fcc_constraint) { |
| mac_ptr->scan.fcc_constraint = fcc_constraint; |
| if (scan_pending) |
| mac_ptr->scan.defer_update_channel_list = true; |
| else |
| status = csr_update_channel_list(mac_ptr); |
| /* update the channel list in firmware */ |
| status = csr_update_channel_list(mac_ptr); |
| } |
| |
| sme_release_global_lock(&mac_ptr->sme); |
| } |
| |
| return status; |
| } |
| /** |
| * sme_setdef_dot11mode() - Updates pMac with default dot11mode |
| * @hal: Global MAC pointer |
| * |
| * Return: NULL. |
| */ |
| void sme_setdef_dot11mode(tHalHandle hal) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| csr_set_default_dot11_mode(mac_ctx); |
| } |
| |
| /** |
| * sme_update_roam_scan_hi_rssi_scan_params() - update high rssi scan |
| * params |
| * @hal_handle - The handle returned by macOpen. |
| * @session_id - Session Identifier |
| * @notify_id - Identifies 1 of the 4 parameters to be modified |
| * @val New value of the parameter |
| * |
| * Return: QDF_STATUS - SME update config successful. |
| * Other status means SME failed to update |
| */ |
| |
| QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle, |
| uint8_t session_id, |
| uint32_t notify_id, |
| int32_t val) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tCsrNeighborRoamConfig *nr_config = NULL; |
| tpCsrNeighborRoamControlInfo nr_info = NULL; |
| uint32_t reason = 0; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| nr_config = &mac_ctx->roam.configParam.neighborRoamConfig; |
| nr_info = &mac_ctx->roam.neighborRoamInfo[session_id]; |
| switch (notify_id) { |
| case eCSR_HI_RSSI_SCAN_MAXCOUNT_ID: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| "%s: gRoamScanHirssiMaxCount %d => %d", |
| __func__, nr_config->nhi_rssi_scan_max_count, |
| val); |
| nr_config->nhi_rssi_scan_max_count = val; |
| nr_info->cfgParams.hi_rssi_scan_max_count = val; |
| reason = REASON_ROAM_SCAN_HI_RSSI_MAXCOUNT_CHANGED; |
| break; |
| |
| case eCSR_HI_RSSI_SCAN_RSSI_DELTA_ID: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("gRoamScanHiRssiDelta %d => %d"), |
| nr_config->nhi_rssi_scan_rssi_delta, |
| val); |
| nr_config->nhi_rssi_scan_rssi_delta = val; |
| nr_info->cfgParams.hi_rssi_scan_rssi_delta = val; |
| reason = REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED; |
| break; |
| |
| case eCSR_HI_RSSI_SCAN_DELAY_ID: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("gRoamScanHiRssiDelay %d => %d"), |
| nr_config->nhi_rssi_scan_delay, |
| val); |
| nr_config->nhi_rssi_scan_delay = val; |
| nr_info->cfgParams.hi_rssi_scan_delay = val; |
| reason = REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED; |
| break; |
| |
| case eCSR_HI_RSSI_SCAN_RSSI_UB_ID: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("gRoamScanHiRssiUpperBound %d => %d"), |
| nr_config->nhi_rssi_scan_rssi_ub, |
| val); |
| nr_config->nhi_rssi_scan_rssi_ub = val; |
| nr_info->cfgParams.hi_rssi_scan_rssi_ub = val; |
| reason = REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED; |
| break; |
| |
| default: |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("invalid parameter notify_id %d"), |
| notify_id); |
| status = QDF_STATUS_E_INVAL; |
| break; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled && |
| status == QDF_STATUS_SUCCESS) { |
| csr_roam_offload_scan(mac_ctx, session_id, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, reason); |
| } |
| |
| return status; |
| } |
| |
| /** |
| * sme_update_tgt_services() - update the target services config. |
| * @hal: HAL pointer. |
| * @cfg: wma_tgt_services parameters. |
| * |
| * update the target services config. |
| * |
| * Return: None. |
| */ |
| void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| mac_ctx->lteCoexAntShare = cfg->lte_coex_ant_share; |
| mac_ctx->per_band_chainmask_supp = cfg->per_band_chainmask_supp; |
| mac_ctx->beacon_offload = cfg->beacon_offload; |
| mac_ctx->pmf_offload = cfg->pmf_offload; |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, |
| FL("mac_ctx->pmf_offload: %d"), mac_ctx->pmf_offload); |
| |
| return; |
| } |
| |
| /** |
| * sme_is_session_id_valid() - Check if the session id is valid |
| * @hal: Pointer to HAL |
| * @session_id: Session id |
| * |
| * Checks if the session id is valid or not |
| * |
| * Return: True is the session id is valid, false otherwise |
| */ |
| bool sme_is_session_id_valid(tHalHandle hal, uint32_t session_id) |
| { |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| if (!mac) { |
| /* Using QDF_TRACE since mac is not available for sms_log */ |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: null mac pointer", __func__); |
| return false; |
| } |
| |
| if (CSR_IS_SESSION_VALID(mac, session_id)) { |
| return true; |
| } else { |
| sms_log(mac, LOGE, |
| FL("invalid session id:%d"), session_id); |
| return false; |
| } |
| } |
| |
| #ifdef FEATURE_WLAN_TDLS |
| |
| /** |
| * sme_get_opclass() - determine operating class |
| * @hal: Pointer to HAL |
| * @channel: channel id |
| * @bw_offset: bandwidth offset |
| * @opclass: pointer to operating class |
| * |
| * Function will determine operating class from regdm_get_opclass_from_channel |
| * |
| * Return: none |
| */ |
| void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset, |
| uint8_t *opclass) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| /* redgm opclass table contains opclass for 40MHz low primary, |
| * 40MHz high primary and 20MHz. No support for 80MHz yet. So |
| * first we will check if bit for 40MHz is set and if so find |
| * matching opclass either with low primary or high primary |
| * (a channel would never be in both) and then search for opclass |
| * matching 20MHz, else for any BW. |
| */ |
| if (bw_offset & (1 << BW_40_OFFSET_BIT)) { |
| *opclass = cds_reg_dmn_get_opclass_from_channel( |
| mac_ctx->scan.countryCodeCurrent, |
| channel, BW40_LOW_PRIMARY); |
| if (!(*opclass)) { |
| *opclass = cds_reg_dmn_get_opclass_from_channel( |
| mac_ctx->scan.countryCodeCurrent, |
| channel, BW40_HIGH_PRIMARY); |
| } |
| } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { |
| *opclass = cds_reg_dmn_get_opclass_from_channel( |
| mac_ctx->scan.countryCodeCurrent, |
| channel, BW20); |
| } else { |
| *opclass = cds_reg_dmn_get_opclass_from_channel( |
| mac_ctx->scan.countryCodeCurrent, |
| channel, BWALL); |
| } |
| } |
| #endif |
| |
| #ifdef FEATURE_GREEN_AP |
| /** |
| * sme_send_egap_conf_params() - set the enhanced green ap configuration params |
| * @enable: enable/disable the enhanced green ap feature |
| * @inactivity_time: inactivity timeout value |
| * @wait_time: wait timeout value |
| * @flag: feature flag in bitmasp |
| * |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_send_egap_conf_params(uint32_t enable, uint32_t inactivity_time, |
| uint32_t wait_time, uint32_t flags) |
| { |
| cds_msg_t message; |
| QDF_STATUS status; |
| struct egap_conf_params *egap_params; |
| |
| egap_params = qdf_mem_malloc(sizeof(*egap_params)); |
| if (NULL == egap_params) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: fail to alloc egap_params", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| egap_params->enable = enable; |
| egap_params->inactivity_time = inactivity_time; |
| egap_params->wait_time = wait_time; |
| egap_params->flags = flags; |
| |
| message.type = WMA_SET_EGAP_CONF_PARAMS; |
| message.bodyptr = egap_params; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post msg to WMA!", __func__); |
| |
| qdf_mem_free(egap_params); |
| } |
| return status; |
| } |
| #endif |
| |
| /** |
| * sme_set_fw_test() - set fw test |
| * @fw_test: fw test param |
| * |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_set_fw_test(struct set_fwtest_params *fw_test) |
| { |
| void *wma_handle; |
| |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "wma handle is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| wma_process_fw_test_cmd(wma_handle, fw_test); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_ht40_stop_obss_scan() - ht40 obss stop scan |
| * @hal: mac handel |
| * @vdev_id: vdev identifier |
| * |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hal, uint32_t vdev_id) |
| { |
| void *wma_handle; |
| |
| wma_handle = cds_get_context(QDF_MODULE_ID_WMA); |
| if (!wma_handle) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "wma handle is NULL"); |
| return QDF_STATUS_E_FAILURE; |
| } |
| wma_ht40_stop_obss_scan(wma_handle, vdev_id); |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_update_mimo_power_save() - Update MIMO power save |
| * configuration |
| * @hal: The handle returned by macOpen |
| * @is_ht_smps_enabled: enable/disable ht smps |
| * @ht_smps_mode: smps mode disabled/static/dynamic |
| * @send_smps_action: flag to send smps force mode command |
| * to FW |
| * |
| * Return: QDF_STATUS if SME update mimo power save |
| * configuration sucsess else failue status |
| */ |
| QDF_STATUS sme_update_mimo_power_save(tHalHandle hal, |
| uint8_t is_ht_smps_enabled, |
| uint8_t ht_smps_mode, |
| bool send_smps_action) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| sms_log(mac_ctx, LOG1, |
| "SMPS enable: %d mode: %d send action: %d", |
| is_ht_smps_enabled, ht_smps_mode, |
| send_smps_action); |
| mac_ctx->roam.configParam.enableHtSmps = |
| is_ht_smps_enabled; |
| mac_ctx->roam.configParam.htSmps = ht_smps_mode; |
| mac_ctx->roam.configParam.send_smps_action = |
| send_smps_action; |
| |
| return QDF_STATUS_SUCCESS; |
| } |
| |
| /** |
| * sme_is_sta_smps_allowed() - check if the supported nss for |
| * the session is greater than 1x1 to enable sta SMPS |
| * @hal: The handle returned by macOpen |
| * @session_id: session id |
| * |
| * Return: bool returns true if supported nss is greater than |
| * 1x1 else false |
| */ |
| bool sme_is_sta_smps_allowed(tHalHandle hal, uint8_t session_id) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| tCsrRoamSession *csr_session; |
| |
| csr_session = CSR_GET_SESSION(mac_ctx, session_id); |
| if (NULL == csr_session) { |
| sms_log(mac_ctx, LOGE, |
| FL("SME session not valid: %d"), session_id); |
| return false; |
| } |
| |
| if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| sms_log(mac_ctx, LOGE, |
| FL("CSR session not valid: %d"), session_id); |
| return false; |
| } |
| |
| return (csr_session->supported_nss_1x1 == true) ? false : true; |
| } |
| |
| /** |
| * sme_add_beacon_filter() - set the beacon filter configuration |
| * @hal: The handle returned by macOpen |
| * @session_id: session id |
| * @ie_map: bitwise array of IEs |
| * |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_add_beacon_filter(tHalHandle hal, |
| uint32_t session_id, |
| uint32_t *ie_map) |
| { |
| cds_msg_t message; |
| QDF_STATUS qdf_status; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct beacon_filter_param *filter_param; |
| |
| if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| sms_log(mac_ctx, LOGE, |
| "CSR session not valid: %d", |
| session_id); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| filter_param = qdf_mem_malloc(sizeof(*filter_param)); |
| if (NULL == filter_param) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: fail to alloc filter_param", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| filter_param->vdev_id = session_id; |
| |
| qdf_mem_copy(filter_param->ie_map, ie_map, |
| BCN_FLT_MAX_ELEMS_IE_LIST * sizeof(uint32_t)); |
| |
| message.type = WMA_ADD_BCN_FILTER_CMDID; |
| message.bodyptr = filter_param; |
| qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA, |
| &message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post msg to WDA!", |
| __func__); |
| |
| qdf_mem_free(filter_param); |
| } |
| return qdf_status; |
| } |
| |
| /** |
| * sme_remove_beacon_filter() - set the beacon filter configuration |
| * @hal: The handle returned by macOpen |
| * @session_id: session id |
| * |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id) |
| { |
| cds_msg_t message; |
| QDF_STATUS qdf_status; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct beacon_filter_param *filter_param; |
| |
| if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| sms_log(mac_ctx, LOGE, |
| "CSR session not valid: %d", |
| session_id); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| filter_param = qdf_mem_malloc(sizeof(*filter_param)); |
| if (NULL == filter_param) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: fail to alloc filter_param", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| filter_param->vdev_id = session_id; |
| |
| message.type = WMA_REMOVE_BCN_FILTER_CMDID; |
| message.bodyptr = filter_param; |
| qdf_status = cds_mq_post_message(QDF_MODULE_ID_WMA, |
| &message); |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post msg to WDA!", |
| __func__); |
| |
| qdf_mem_free(filter_param); |
| } |
| return qdf_status; |
| } |
| |
| /** |
| * sme_send_disassoc_req_frame - send disassoc req |
| * @hal: handler to hal |
| * @session_id: session id |
| * @peer_mac: peer mac address |
| * @reason: reason for disassociation |
| * wait_for_ack: wait for acknowledgment |
| * |
| * function to send disassoc request to lim |
| * |
| * return: none |
| */ |
| void sme_send_disassoc_req_frame(tHalHandle hal, uint8_t session_id, |
| uint8_t *peer_mac, uint16_t reason, uint8_t wait_for_ack) |
| { |
| struct sme_send_disassoc_frm_req *msg; |
| QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; |
| A_UINT8 *buf; |
| A_UINT16 tmp; |
| |
| msg = qdf_mem_malloc(sizeof(struct sme_send_disassoc_frm_req)); |
| |
| if (NULL == msg) |
| qdf_status = QDF_STATUS_E_FAILURE; |
| else |
| qdf_status = QDF_STATUS_SUCCESS; |
| |
| if (!QDF_IS_STATUS_SUCCESS(qdf_status)) |
| return; |
| |
| qdf_mem_set(msg, sizeof(struct sme_send_disassoc_frm_req), 0); |
| msg->msg_type = (uint16_t) eWNI_SME_SEND_DISASSOC_FRAME; |
| |
| msg->length = (uint16_t) sizeof(struct sme_send_disassoc_frm_req); |
| |
| buf = &msg->session_id; |
| |
| /* session id */ |
| *buf = (A_UINT8) session_id; |
| buf += sizeof(A_UINT8); |
| |
| /* transaction id */ |
| *buf = 0; |
| *(buf + 1) = 0; |
| buf += sizeof(A_UINT16); |
| |
| /* Set the peer MAC address before sending the message to LIM */ |
| qdf_mem_copy(buf, peer_mac, QDF_MAC_ADDR_SIZE); |
| |
| buf += QDF_MAC_ADDR_SIZE; |
| |
| /* reasoncode */ |
| tmp = (uint16_t) reason; |
| qdf_mem_copy(buf, &tmp, sizeof(uint16_t)); |
| buf += sizeof(uint16_t); |
| |
| *buf = wait_for_ack; |
| buf += sizeof(uint8_t); |
| |
| qdf_status = cds_send_mb_message_to_mac(msg); |
| |
| if (qdf_status != QDF_STATUS_SUCCESS) |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("cds_send_mb_message Failed")); |
| } |
| |
| /** |
| * sme_get_bpf_offload_capabilities() - Get length for BPF offload |
| * @hal: Global HAL handle |
| * This function constructs the cds message and fill in message type, |
| * post the same to WDA. |
| * Return: QDF_STATUS enumeration |
| */ |
| QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| cds_msg_t cds_msg; |
| |
| sms_log(mac_ctx, LOG1, FL("enter")); |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| /* Serialize the req through MC thread */ |
| cds_msg.bodyptr = NULL; |
| cds_msg.type = WDA_BPF_GET_CAPABILITIES_REQ; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Post bpf get offload msg fail")); |
| status = QDF_STATUS_E_FAILURE; |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock error")); |
| } |
| sms_log(mac_ctx, LOG1, FL("exit")); |
| return status; |
| } |
| |
| |
| /** |
| * sme_set_bpf_instructions() - Set BPF bpf filter instructions. |
| * @hal: HAL handle |
| * @bpf_set_offload: struct to set bpf filter instructions. |
| * |
| * Return: QDF_STATUS enumeration. |
| */ |
| QDF_STATUS sme_set_bpf_instructions(tHalHandle hal, |
| struct sir_bpf_set_offload *req) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| cds_msg_t cds_msg; |
| struct sir_bpf_set_offload *set_offload; |
| |
| set_offload = qdf_mem_malloc(sizeof(*set_offload)); |
| |
| if (NULL == set_offload) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to alloc set_offload")); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| set_offload->session_id = req->session_id; |
| set_offload->filter_id = req->filter_id; |
| set_offload->current_offset = req->current_offset; |
| set_offload->total_length = req->total_length; |
| set_offload->current_length = req->current_length; |
| if (set_offload->total_length) { |
| set_offload->program = qdf_mem_malloc(sizeof(uint8_t) * |
| req->current_length); |
| if (NULL == set_offload->program) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Failed to alloc instruction memory")); |
| qdf_mem_free(set_offload); |
| return QDF_STATUS_E_NOMEM; |
| } |
| qdf_mem_copy(set_offload->program, req->program, |
| set_offload->current_length); |
| } |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| /* Serialize the req through MC thread */ |
| cds_msg.bodyptr = set_offload; |
| cds_msg.type = WDA_BPF_SET_INSTRUCTIONS_REQ; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &cds_msg); |
| |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("Post BPF set offload msg fail")); |
| status = QDF_STATUS_E_FAILURE; |
| if (set_offload->total_length) |
| qdf_mem_free(set_offload->program); |
| qdf_mem_free(set_offload); |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock failed")); |
| if (set_offload->total_length) |
| qdf_mem_free(set_offload->program); |
| qdf_mem_free(set_offload); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_bpf_offload_register_callback() - Register get bpf offload callbacK |
| * |
| * @hal - MAC global handle |
| * @callback_routine - callback routine from HDD |
| * |
| * This API is invoked by HDD to register its callback in SME |
| * |
| * Return: QDF_STATUS |
| */ |
| QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal, |
| void (*pbpf_get_offload_cb)(void *context, |
| struct sir_bpf_get_offload *)) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| mac->sme.pbpf_get_offload_cb = pbpf_get_offload_cb; |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock failed")); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_get_wni_dot11_mode() - return configured wni dot11mode |
| * @hal: hal pointer |
| * |
| * Return: wni dot11 mode. |
| */ |
| uint32_t sme_get_wni_dot11_mode(tHalHandle hal) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| |
| return csr_translate_to_wni_cfg_dot11_mode(mac_ctx, |
| mac_ctx->roam.configParam.uCfgDot11Mode); |
| } |
| |
| /** |
| * sme_bpf_offload_deregister_callback() - Register get bpf offload callbacK |
| * |
| * @h_hal - MAC global handle |
| * @callback_routine - callback routine from HDD |
| * |
| * This API is invoked by HDD to de-register its callback in SME |
| * |
| * Return: QDF_STATUS Enumeration |
| */ |
| QDF_STATUS sme_bpf_offload_deregister_callback(tHalHandle h_hal) |
| { |
| QDF_STATUS status = QDF_STATUS_SUCCESS; |
| tpAniSirGlobal mac; |
| |
| if (!h_hal) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("hHal is not valid")); |
| return QDF_STATUS_E_INVAL; |
| } |
| |
| mac = PMAC_STRUCT(h_hal); |
| |
| status = sme_acquire_global_lock(&mac->sme); |
| if (QDF_IS_STATUS_SUCCESS(status)) { |
| mac->sme.pbpf_get_offload_cb = NULL; |
| sme_release_global_lock(&mac->sme); |
| } else { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| FL("sme_acquire_global_lock failed")); |
| } |
| return status; |
| } |
| |
| |
| /** |
| * sme_create_mon_session() - post message to create PE session for monitormode |
| * operation |
| * @hal_handle: Handle to the HAL |
| * @bssid: pointer to bssid |
| * |
| * Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure. |
| */ |
| QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id) |
| { |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| struct sir_create_session *msg; |
| |
| msg = qdf_mem_malloc(sizeof(*msg)); |
| if (NULL != msg) { |
| msg->type = eWNI_SME_MON_INIT_SESSION; |
| msg->msg_len = sizeof(*msg); |
| qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE); |
| status = cds_send_mb_message_to_mac(msg); |
| } |
| return status; |
| } |
| |
| /** |
| * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration |
| * @hal: The handle returned by macOpen |
| * @params: adaptive_dwelltime_params config |
| * |
| * Return: QDF_STATUS if adaptive dwell time update |
| * configuration sucsess else failure status |
| */ |
| QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal, |
| struct adaptive_dwelltime_params *params) |
| { |
| cds_msg_t message; |
| QDF_STATUS status; |
| struct adaptive_dwelltime_params *dwelltime_params; |
| |
| dwelltime_params = qdf_mem_malloc(sizeof(*dwelltime_params)); |
| if (NULL == dwelltime_params) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: fail to alloc dwelltime_params", __func__); |
| return QDF_STATUS_E_NOMEM; |
| } |
| |
| dwelltime_params->is_enabled = params->is_enabled; |
| dwelltime_params->dwelltime_mode = params->dwelltime_mode; |
| dwelltime_params->lpf_weight = params->lpf_weight; |
| dwelltime_params->passive_mon_intval = params->passive_mon_intval; |
| dwelltime_params->wifi_act_threshold = params->wifi_act_threshold; |
| |
| message.type = WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS; |
| message.bodyptr = dwelltime_params; |
| status = cds_mq_post_message(QDF_MODULE_ID_WMA, &message); |
| if (!QDF_IS_STATUS_SUCCESS(status)) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post msg to WMA!", __func__); |
| |
| qdf_mem_free(dwelltime_params); |
| } |
| return status; |
| } |
| /** |
| * sme_set_pdev_ht_vht_ies() - sends the set pdev IE req |
| * @hal: Pointer to HAL |
| * @enable2x2: 1x1 or 2x2 mode. |
| * |
| * Sends the set pdev IE req with Nss value. |
| * |
| * Return: None |
| */ |
| void sme_set_pdev_ht_vht_ies(tHalHandle hal, bool enable2x2) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct sir_set_ht_vht_cfg *ht_vht_cfg; |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| |
| if (!mac_ctx->per_band_chainmask_supp) |
| return; |
| |
| if (!((mac_ctx->roam.configParam.uCfgDot11Mode == |
| eCSR_CFG_DOT11_MODE_AUTO) || |
| (mac_ctx->roam.configParam.uCfgDot11Mode == |
| eCSR_CFG_DOT11_MODE_11N) || |
| (mac_ctx->roam.configParam.uCfgDot11Mode == |
| eCSR_CFG_DOT11_MODE_11N_ONLY) || |
| (mac_ctx->roam.configParam.uCfgDot11Mode == |
| eCSR_CFG_DOT11_MODE_11AC) || |
| (mac_ctx->roam.configParam.uCfgDot11Mode == |
| eCSR_CFG_DOT11_MODE_11AC_ONLY))) |
| return; |
| |
| status = sme_acquire_global_lock(&mac_ctx->sme); |
| if (QDF_STATUS_SUCCESS == status) { |
| ht_vht_cfg = qdf_mem_malloc(sizeof(*ht_vht_cfg)); |
| if (NULL == ht_vht_cfg) { |
| sms_log(mac_ctx, LOGE, |
| "%s: mem alloc failed for ht_vht_cfg", |
| __func__); |
| sme_release_global_lock(&mac_ctx->sme); |
| return; |
| } |
| |
| ht_vht_cfg->pdev_id = 0; |
| if (enable2x2) |
| ht_vht_cfg->nss = 2; |
| else |
| ht_vht_cfg->nss = 1; |
| ht_vht_cfg->dot11mode = |
| (uint8_t)csr_translate_to_wni_cfg_dot11_mode(mac_ctx, |
| mac_ctx->roam.configParam.uCfgDot11Mode); |
| |
| ht_vht_cfg->msg_type = eWNI_SME_PDEV_SET_HT_VHT_IE; |
| ht_vht_cfg->len = sizeof(*ht_vht_cfg); |
| sms_log(mac_ctx, LOG1, |
| FL("SET_HT_VHT_IE with nss %d, dot11mode %d"), |
| ht_vht_cfg->nss, |
| ht_vht_cfg->dot11mode); |
| status = cds_send_mb_message_to_mac(ht_vht_cfg); |
| if (QDF_STATUS_SUCCESS != status) { |
| sms_log(mac_ctx, LOGE, FL( |
| "Send SME_PDEV_SET_HT_VHT_IE fail")); |
| qdf_mem_free(ht_vht_cfg); |
| } |
| sme_release_global_lock(&mac_ctx->sme); |
| } |
| return; |
| } |
| |
| /** |
| * sme_update_vdev_type_nss() - sets the nss per vdev type |
| * @hal: Pointer to HAL |
| * @max_supp_nss: max_supported Nss |
| * @band: 5G or 2.4G band |
| * |
| * Sets the per band Nss for each vdev type based on INI and configured |
| * chain mask value. |
| * |
| * Return: None |
| */ |
| void sme_update_vdev_type_nss(tHalHandle hal, uint8_t max_supp_nss, |
| uint32_t vdev_type_nss, eCsrBand band) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct vdev_type_nss *vdev_nss; |
| |
| if (eCSR_BAND_5G == band) |
| vdev_nss = &mac_ctx->vdev_type_nss_5g; |
| else |
| vdev_nss = &mac_ctx->vdev_type_nss_2g; |
| |
| vdev_nss->sta = QDF_MIN(max_supp_nss, CFG_STA_NSS(vdev_type_nss)); |
| vdev_nss->sap = QDF_MIN(max_supp_nss, CFG_SAP_NSS(vdev_type_nss)); |
| vdev_nss->p2p_go = QDF_MIN(max_supp_nss, |
| CFG_P2P_GO_NSS(vdev_type_nss)); |
| vdev_nss->p2p_cli = QDF_MIN(max_supp_nss, |
| CFG_P2P_CLI_NSS(vdev_type_nss)); |
| vdev_nss->p2p_dev = QDF_MIN(max_supp_nss, |
| CFG_P2P_DEV_NSS(vdev_type_nss)); |
| vdev_nss->ibss = QDF_MIN(max_supp_nss, CFG_IBSS_NSS(vdev_type_nss)); |
| vdev_nss->tdls = QDF_MIN(max_supp_nss, CFG_TDLS_NSS(vdev_type_nss)); |
| vdev_nss->ocb = QDF_MIN(max_supp_nss, CFG_OCB_NSS(vdev_type_nss)); |
| |
| sms_log(mac_ctx, LOG1, |
| "band %d NSS:sta %d sap %d cli %d go %d dev %d ibss %d tdls %d ocb %d", |
| band, vdev_nss->sta, vdev_nss->sap, vdev_nss->p2p_cli, |
| vdev_nss->p2p_go, vdev_nss->p2p_dev, vdev_nss->ibss, |
| vdev_nss->tdls, vdev_nss->ocb); |
| } |
| |
| /** |
| * sme_register_p2p_lo_event() - Register for the p2p lo event |
| * @hHal: reference to the HAL |
| * @context: the context of the call |
| * @callback: the callback to hdd |
| * |
| * This function registers the callback function for P2P listen |
| * offload stop event. |
| * |
| * Return: none |
| */ |
| void sme_register_p2p_lo_event(tHalHandle hHal, void *context, |
| p2p_lo_callback callback) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| QDF_STATUS status = QDF_STATUS_E_FAILURE; |
| |
| status = sme_acquire_global_lock(&pMac->sme); |
| pMac->sme.p2p_lo_event_callback = callback; |
| pMac->sme.p2p_lo_event_context = context; |
| sme_release_global_lock(&pMac->sme); |
| } |
| |
| /** |
| * sme_process_mac_pwr_dbg_cmd() - enable mac pwr debugging |
| * @hal: The handle returned by macOpen |
| * @session_id: session id |
| * @dbg_args: args for mac pwr debug command |
| * Return: Return QDF_STATUS, otherwise appropriate failure code |
| */ |
| QDF_STATUS sme_process_mac_pwr_dbg_cmd(tHalHandle hal, uint32_t session_id, |
| struct sir_mac_pwr_dbg_cmd* |
| dbg_args) |
| { |
| cds_msg_t message; |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| struct sir_mac_pwr_dbg_cmd *req; |
| int i; |
| |
| if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) { |
| sms_log(mac_ctx, LOGE, |
| "CSR session not valid: %d", |
| session_id); |
| return QDF_STATUS_E_FAILURE; |
| } |
| |
| req = qdf_mem_malloc(sizeof(*req)); |
| if (NULL == req) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: fail to alloc mac_pwr_dbg_args", __func__); |
| return QDF_STATUS_E_FAILURE; |
| } |
| req->module_id = dbg_args->module_id; |
| req->pdev_id = dbg_args->pdev_id; |
| req->num_args = dbg_args->num_args; |
| for (i = 0; i < req->num_args; i++) |
| req->args[i] = dbg_args->args[i]; |
| |
| message.type = SIR_HAL_POWER_DBG_CMD; |
| message.bodyptr = req; |
| |
| if (!QDF_IS_STATUS_SUCCESS(cds_mq_post_message |
| (QDF_MODULE_ID_WMA, &message))) { |
| QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, |
| "%s: Not able to post msg to WDA!", |
| __func__); |
| qdf_mem_free(req); |
| } |
| return QDF_STATUS_SUCCESS; |
| } |
| /** |
| * sme_get_vdev_type_nss() - gets the nss per vdev type |
| * @hal: Pointer to HAL |
| * @dev_mode: connection type. |
| * @nss2g: Pointer to the 2G Nss parameter. |
| * @nss5g: Pointer to the 5G Nss parameter. |
| * |
| * Fills the 2G and 5G Nss values based on connection type. |
| * |
| * Return: None |
| */ |
| void sme_get_vdev_type_nss(tHalHandle hal, enum tQDF_ADAPTER_MODE dev_mode, |
| uint8_t *nss_2g, uint8_t *nss_5g) |
| { |
| tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); |
| csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g); |
| } |