| /* |
| * Copyright (c) 2012-2017 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 |
| |
| ========================================================================*/ |
| |
| /*=========================================================================== |
| |
| EDIT HISTORY FOR FILE |
| |
| |
| This section contains comments describing changes made to the module. |
| Notice that changes are listed in reverse chronological order. |
| |
| |
| |
| when who what, where, why |
| ---------- --- -------------------------------------------------------- |
| 06/03/10 js Added support to hostapd driven |
| * deauth/disassoc/mic failure |
| |
| ===========================================================================*/ |
| |
| /*-------------------------------------------------------------------------- |
| Include Files |
| ------------------------------------------------------------------------*/ |
| |
| #include "smsDebug.h" |
| #include "sme_Api.h" |
| #include "csrInsideApi.h" |
| #include "smeInside.h" |
| #include "csrInternal.h" |
| #include "wlan_qct_wda.h" |
| #include "halMsgApi.h" |
| #include "vos_trace.h" |
| #include "sme_Trace.h" |
| #include "vos_types.h" |
| #include "vos_trace.h" |
| #include "vos_utils.h" |
| #include "sapApi.h" |
| #include "macTrace.h" |
| #ifdef WLAN_FEATURE_NAN |
| #include "nan_Api.h" |
| #endif |
| #include "regdomain_common.h" |
| #include "schApi.h" |
| #include "sme_nan_datapath.h" |
| #include "csrApi.h" |
| #include "utilsApi.h" |
| |
| extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); |
| |
| #define LOG_SIZE 256 |
| #define TL_INIT_STATE 0 |
| |
| static tSelfRecoveryStats gSelfRecoveryStats; |
| |
| |
| // TxMB Functions |
| extern eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, |
| eSmeCommandType cmdType, void *pvParam, |
| tANI_U32 size, tSmeCmd **ppCmd); |
| extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); |
| extern void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); |
| extern void csr_release_roc_req_cmd(tpAniSirGlobal mac_ctx); |
| extern eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn); |
| extern eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); |
| extern eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg); |
| extern eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd); |
| |
| static eHalStatus initSmeCmdList(tpAniSirGlobal pMac); |
| static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); |
| |
| eCsrPhyMode sme_GetPhyMode(tHalHandle hHal); |
| |
| eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); |
| |
| void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac); |
| |
| eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); |
| |
| eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal, void *pMsgBuf); |
| |
| eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal); |
| |
| #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) |
| tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId); |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, |
| tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm ); |
| #endif |
| |
| /* Message processor for events from DFS */ |
| eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, |
| v_U16_t msg_type,void *pMsgBuf); |
| |
| /* Channel Change Response Indication Handler */ |
| eHalStatus sme_ProcessChannelChangeResp(tpAniSirGlobal pMac, |
| v_U16_t msg_type,void *pMsgBuf); |
| eHalStatus sme_process_set_max_tx_power(tpAniSirGlobal pMac, |
| tSmeCmd *command); |
| eHalStatus |
| sme_process_set_max_tx_power_per_band(tpAniSirGlobal mac_ctx, |
| tSmeCmd *command); |
| |
| //Internal SME APIs |
| eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme) |
| { |
| eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; |
| |
| if(psSme) |
| { |
| if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psSme->lkSmeGlobalLock) ) ) |
| { |
| status = eHAL_STATUS_SUCCESS; |
| } |
| } |
| |
| return (status); |
| } |
| |
| |
| eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme) |
| { |
| eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; |
| |
| if(psSme) |
| { |
| if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psSme->lkSmeGlobalLock) ) ) |
| { |
| status = eHAL_STATUS_SUCCESS; |
| } |
| } |
| |
| return (status); |
| } |
| |
| /** |
| * 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++) |
| vos_mem_free(mac_ctx->sme.pSmeCmdBufAddr[idx]); |
| |
| vos_mem_free(mac_ctx->sme.pSmeCmdBufAddr); |
| mac_ctx->sme.pSmeCmdBufAddr = NULL; |
| } |
| |
| static eHalStatus initSmeCmdList(tpAniSirGlobal pMac) |
| { |
| eHalStatus status; |
| tSmeCmd *pCmd; |
| tANI_U32 cmd_idx; |
| uint32_t sme_cmd_ptr_ary_sz; |
| VOS_STATUS vosStatus; |
| vos_timer_t* cmdTimeoutTimer = NULL; |
| |
| pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND; |
| if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, |
| &pMac->sme.smeCmdActiveList))) |
| goto end; |
| |
| if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, |
| &pMac->sme.smeCmdPendingList))) |
| goto end; |
| |
| if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, |
| &pMac->sme.smeScanCmdActiveList))) |
| goto end; |
| |
| if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, |
| &pMac->sme.smeScanCmdPendingList))) |
| goto end; |
| |
| if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, |
| &pMac->sme.smeCmdFreeList))) |
| goto end; |
| |
| /* following pointer contains array of pointers for tSmeCmd* */ |
| sme_cmd_ptr_ary_sz = sizeof(void*) * pMac->sme.totalSmeCmd; |
| pMac->sme.pSmeCmdBufAddr = vos_mem_malloc(sme_cmd_ptr_ary_sz); |
| if (NULL == pMac->sme.pSmeCmdBufAddr) { |
| status = eHAL_STATUS_FAILURE; |
| goto end; |
| } |
| |
| status = eHAL_STATUS_SUCCESS; |
| vos_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] = vos_mem_malloc(sizeof(tSmeCmd)); |
| if (NULL == pMac->sme.pSmeCmdBufAddr[cmd_idx]) { |
| status = eHAL_STATUS_FAILURE; |
| free_sme_cmds(pMac); |
| goto end; |
| } |
| pCmd = (tSmeCmd*)pMac->sme.pSmeCmdBufAddr[cmd_idx]; |
| csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK); |
| } |
| |
| /* This timer is only to debug the active list command timeout */ |
| |
| cmdTimeoutTimer = (vos_timer_t*)vos_mem_malloc(sizeof(vos_timer_t)); |
| if (cmdTimeoutTimer) |
| { |
| pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer; |
| vosStatus = |
| vos_timer_init( pMac->sme.smeCmdActiveList.cmdTimeoutTimer, |
| VOS_TIMER_TYPE_SW, |
| activeListCmdTimeoutHandle, |
| (void*) pMac); |
| |
| if (!VOS_IS_STATUS_SUCCESS(vosStatus)) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "Init Timer fail for active list command process time out"); |
| vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); |
| } |
| else |
| { |
| pMac->sme.smeCmdActiveList.cmdTimeoutDuration = |
| CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; |
| } |
| } |
| |
| end: |
| if (!HAL_STATUS_SUCCESS(status)) |
| smsLog(pMac, LOGE, "failed to initialize sme command list:%d\n", |
| status); |
| |
| return (status); |
| } |
| |
| |
| void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd) |
| { |
| pCmd->command = eSmeNoCommand; |
| csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK); |
| } |
| |
| |
| |
| static void smeReleaseCmdList(tpAniSirGlobal pMac, tDblLinkList *pList) |
| { |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| |
| while((pEntry = csrLLRemoveHead(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 ); |
| smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); |
| } |
| } |
| |
| static void purgeSmeCmdList(tpAniSirGlobal pMac) |
| { |
| //release any out standing commands back to free command list |
| smeReleaseCmdList(pMac, &pMac->sme.smeCmdPendingList); |
| smeReleaseCmdList(pMac, &pMac->sme.smeCmdActiveList); |
| smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdPendingList); |
| smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdActiveList); |
| } |
| |
| void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, |
| tDblLinkList *pList) |
| { |
| //release any out standing commands back to free command list |
| tListElem *pEntry, *pNext; |
| tSmeCmd *pCommand; |
| tDblLinkList localList; |
| |
| vos_mem_zero(&localList, sizeof(tDblLinkList)); |
| if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) |
| { |
| smsLog(pMac, LOGE, FL(" failed to open list")); |
| return; |
| } |
| |
| csrLLLock(pList); |
| pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); |
| while(pEntry != NULL) |
| { |
| pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); |
| pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| if(pCommand->sessionId == sessionId) |
| { |
| if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) |
| { |
| csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); |
| } |
| } |
| pEntry = pNext; |
| } |
| csrLLUnlock(pList); |
| |
| while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) |
| { |
| pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); |
| } |
| csrLLClose(&localList); |
| } |
| |
| |
| static eHalStatus freeSmeCmdList(tpAniSirGlobal pMac) |
| { |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| purgeSmeCmdList(pMac); |
| csrLLClose(&pMac->sme.smeCmdPendingList); |
| csrLLClose(&pMac->sme.smeCmdActiveList); |
| csrLLClose(&pMac->sme.smeScanCmdPendingList); |
| csrLLClose(&pMac->sme.smeScanCmdActiveList); |
| csrLLClose(&pMac->sme.smeCmdFreeList); |
| |
| /*destroy active list command time out timer */ |
| vos_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); |
| vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); |
| pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL; |
| |
| status = vos_lock_acquire(&pMac->sme.lkSmeGlobalLock); |
| if(status != eHAL_STATUS_SUCCESS) |
| { |
| smsLog(pMac, LOGE, |
| FL("Failed to acquire the lock status = %d"), status); |
| goto done; |
| } |
| |
| free_sme_cmds(pMac); |
| |
| status = vos_lock_release(&pMac->sme.lkSmeGlobalLock); |
| if(status != eHAL_STATUS_SUCCESS) |
| { |
| smsLog(pMac, LOGE, |
| FL("Failed to release the lock status = %d"), status); |
| } |
| done: |
| return (status); |
| } |
| |
| |
| void dumpCsrCommandInfo(tpAniSirGlobal pMac, tSmeCmd *pCmd) |
| { |
| switch( pCmd->command ) |
| { |
| case eSmeCommandScan: |
| smsLog( pMac, LOGE, " scan command reason is %d", pCmd->u.scanCmd.reason ); |
| break; |
| |
| case eSmeCommandRoam: |
| smsLog( pMac, LOGE, " roam command reason is %d", pCmd->u.roamCmd.roamReason ); |
| break; |
| |
| case eSmeCommandWmStatusChange: |
| smsLog( pMac, LOGE, " WMStatusChange command type is %d", pCmd->u.wmStatusChangeCmd.Type ); |
| break; |
| |
| case eSmeCommandSetKey: |
| smsLog( pMac, LOGE, " setKey command auth(%d) enc(%d)", |
| pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType ); |
| break; |
| |
| case eSmeCommandRemoveKey: |
| smsLog( pMac, LOGE, " removeKey command auth(%d) enc(%d)", |
| pCmd->u.removeKeyCmd.authType, pCmd->u.removeKeyCmd.encType ); |
| break; |
| |
| default: |
| smsLog( pMac, LOGE, " default: Unhandled command %d", |
| pCmd->command); |
| break; |
| } |
| } |
| |
| tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac ) |
| { |
| tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL; |
| tListElem *pEntry; |
| static int smeCommandQueueFull = 0; |
| |
| pEntry = csrLLRemoveHead( &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 the message buffers). |
| */ |
| if ( pEntry ) |
| { |
| pRetCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| /* reset when free list is available */ |
| smeCommandQueueFull = 0; |
| } |
| else |
| { |
| int idx = 1; |
| |
| //Cannot change pRetCmd here since it needs to return later. |
| pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); |
| if( pEntry ) |
| { |
| pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| } |
| smsLog( 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 |
| dumpCsrCommandInfo(pMac, pTempCmd); |
| } |
| } //if(pTempCmd) |
| |
| //dump what is in the pending queue |
| csrLLLock(&pMac->sme.smeCmdPendingList); |
| pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK ); |
| while(pEntry && !smeCommandQueueFull) |
| { |
| pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| /* Print only 1st five commands from pending queue. */ |
| if (idx <= 5) |
| smsLog( 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 |
| dumpCsrCommandInfo(pMac, pTempCmd); |
| } |
| pEntry = csrLLNext( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); |
| } |
| csrLLUnlock(&pMac->sme.smeCmdPendingList); |
| |
| idx = 1; |
| //There may be some more command in CSR's own pending queue |
| csrLLLock(&pMac->roam.roamCmdPendingList); |
| pEntry = csrLLPeekHead( &pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK ); |
| while(pEntry && !smeCommandQueueFull) |
| { |
| pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| /* Print only 1st five commands from CSR pending queue */ |
| if (idx <= 5) |
| smsLog( pMac, LOGE, |
| "Out of command buffer.... CSR roamCmdPendingList command #%d (0x%X)", |
| idx, pTempCmd->command ); |
| idx++; |
| dumpCsrCommandInfo(pMac, pTempCmd); |
| pEntry = csrLLNext( &pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); |
| } |
| /* Increament static variable so that it prints pending command only once*/ |
| smeCommandQueueFull++; |
| csrLLUnlock(&pMac->roam.roamCmdPendingList); |
| |
| /* panic with out-of-command */ |
| if (pMac->roam.configParam.enable_fatal_event) { |
| vos_flush_logs(WLAN_LOG_TYPE_FATAL, |
| WLAN_LOG_INDICATOR_HOST_DRIVER, |
| WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, |
| DUMP_NO_TRACE); |
| } else { |
| /* Trigger SSR */ |
| vos_wlanRestart(); |
| } |
| } |
| |
| /* memset to zero */ |
| if (pRetCmd) { |
| vos_mem_set((tANI_U8 *)&pRetCmd->command, sizeof(pRetCmd->command), 0); |
| vos_mem_set((tANI_U8 *)&pRetCmd->sessionId, |
| sizeof(pRetCmd->sessionId), 0); |
| vos_mem_set((tANI_U8 *)&pRetCmd->u, sizeof(pRetCmd->u), 0); |
| } |
| |
| return(pRetCmd); |
| } |
| |
| |
| void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority ) |
| { |
| if (!SME_IS_START(pMac)) { |
| smsLog(pMac, LOGE, FL("Sme in stop state")); |
| return; |
| } |
| |
| if ( fHighPriority ) |
| { |
| csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); |
| } |
| else |
| { |
| csrLLInsertTail( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); |
| } |
| |
| // process the command queue... |
| smeProcessPendingQueue( pMac ); |
| |
| return; |
| } |
| |
| |
| static eSmeCommandType smeIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand ) |
| { |
| eSmeCommandType pmcCommand = eSmeNoCommand; |
| tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE; |
| tPmcState pmcState; |
| eHalStatus status; |
| |
| do |
| { |
| pmcState = pmcGetPmcState(pMac); |
| |
| status = csrIsFullPowerNeeded( pMac, pCommand, NULL, &fFullPowerNeeded ); |
| if( !HAL_STATUS_SUCCESS(status) ) |
| { |
| //PMC state is not right for the command, drop it |
| return ( eSmeDropCommand ); |
| } |
| if( fFullPowerNeeded ) break; |
| fFullPowerNeeded = ( ( eSmeCommandAddTs == pCommand->command ) || |
| ( eSmeCommandDelTs == pCommand->command ) ); |
| if( fFullPowerNeeded ) break; |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| fFullPowerNeeded = (pmcState == IMPS && |
| eSmeCommandOemDataReq == pCommand->command); |
| if(fFullPowerNeeded) break; |
| #endif |
| fFullPowerNeeded = (pmcState == IMPS && |
| eSmeCommandRemainOnChannel == pCommand->command); |
| if(fFullPowerNeeded) break; |
| } while(0); |
| |
| if( fFullPowerNeeded ) |
| { |
| switch( pmcState ) |
| { |
| case IMPS: |
| case STANDBY: |
| pmcCommand = eSmeCommandExitImps; |
| break; |
| |
| case BMPS: |
| pmcCommand = eSmeCommandExitBmps; |
| break; |
| |
| case UAPSD: |
| pmcCommand = eSmeCommandExitUapsd; |
| break; |
| |
| case WOWL: |
| pmcCommand = eSmeCommandExitWowl; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| return ( pmcCommand ); |
| } |
| |
| static eSmeCommandType smePsOffloadIsFullPowerNeeded(tpAniSirGlobal pMac, |
| tSmeCmd *pCommand) |
| { |
| eSmeCommandType pmcCommand = eSmeNoCommand; |
| tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE; |
| eHalStatus status; |
| tPmcState pmcState; |
| |
| do |
| { |
| /* Check for CSR Commands which require full power */ |
| status = csrPsOffloadIsFullPowerNeeded(pMac, pCommand, NULL, |
| &fFullPowerNeeded); |
| if(!HAL_STATUS_SUCCESS(status)) |
| { |
| /* PMC state is not right for the command, drop it */ |
| return eSmeDropCommand; |
| } |
| if(fFullPowerNeeded) break; |
| |
| /* Check for SME Commands which require Full Power */ |
| if((eSmeCommandAddTs == pCommand->command) || |
| ((eSmeCommandDelTs == pCommand->command))) |
| { |
| /* Get the PMC State */ |
| pmcState = pmcOffloadGetPmcState(pMac, pCommand->sessionId); |
| switch(pmcState) |
| { |
| case REQUEST_BMPS: |
| case BMPS: |
| case REQUEST_START_UAPSD: |
| case REQUEST_STOP_UAPSD: |
| case UAPSD: |
| fFullPowerNeeded = eANI_BOOLEAN_TRUE; |
| break; |
| case STOPPED: |
| break; |
| default: |
| break; |
| } |
| break; |
| } |
| } while(0); |
| |
| if(fFullPowerNeeded) |
| { |
| pmcCommand = eSmeCommandExitBmps; |
| } |
| |
| return pmcCommand; |
| } |
| |
| |
| //For commands that need to do extra cleanup. |
| static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) |
| { |
| if( eSmePmcCommandMask & pCommand->command ) |
| { |
| if(!pMac->psOffloadEnabled) |
| pmcAbortCommand( pMac, pCommand, fStopping ); |
| else |
| pmcOffloadAbortCommand(pMac, pCommand, fStopping); |
| } |
| else if ( eSmeCsrCommandMask & pCommand->command ) |
| { |
| csrAbortCommand( pMac, pCommand, fStopping ); |
| } |
| else |
| { |
| 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 ); |
| } |
| } |
| smeReleaseCommand( pMac, pCommand ); |
| break; |
| default: |
| smeReleaseCommand( pMac, pCommand ); |
| break; |
| } |
| } |
| } |
| |
| tListElem *csrGetCmdToProcess(tpAniSirGlobal pMac, tDblLinkList *pList, |
| tANI_U8 sessionId, tANI_BOOLEAN 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 = csrLLPeekHead( pList, LL_ACCESS_LOCK ); |
| while (pCurEntry) |
| { |
| pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link); |
| if (pCommand->sessionId != sessionId) |
| { |
| smsLog(pMac, LOG1, "selected the command with different sessionId"); |
| return pCurEntry; |
| } |
| |
| pCurEntry = csrLLNext(pList, pCurEntry, fInterlocked); |
| } |
| |
| smsLog(pMac, LOG1, "No command pending with different sessionId"); |
| return NULL; |
| } |
| |
| tANI_BOOLEAN smeProcessScanQueue(tpAniSirGlobal pMac) |
| { |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| tListElem *pSmeEntry = NULL; |
| tSmeCmd *pSmeCommand = NULL; |
| tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; |
| |
| if ((!csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ))) { |
| pSmeEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (pSmeEntry) |
| pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link) ; |
| } |
| |
| csrLLLock( &pMac->sme.smeScanCmdActiveList ); |
| if (csrLLIsListEmpty( &pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_NOLOCK )) |
| { |
| if (!csrLLIsListEmpty(&pMac->sme.smeScanCmdPendingList, |
| LL_ACCESS_LOCK)) |
| { |
| pEntry = csrLLPeekHead( &pMac->sme.smeScanCmdPendingList, |
| LL_ACCESS_LOCK ); |
| if (pEntry) { |
| pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| if (pSmeCommand != NULL) { |
| /* if there is an active SME command, do not process |
| * the pending scan cmd |
| */ |
| smsLog(pMac, LOG1, "SME scan cmd is pending on session %d", |
| pSmeCommand->sessionId); |
| status = eANI_BOOLEAN_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)) |
| { |
| smsLog(pMac, LOGE, |
| " Cannot process command(%d) while waiting for key", |
| pCommand->command); |
| status = eANI_BOOLEAN_FALSE; |
| goto end; |
| } |
| } |
| if ( csrLLRemoveEntry( &pMac->sme.smeScanCmdPendingList, |
| pEntry, LL_ACCESS_LOCK ) ) |
| { |
| csrLLInsertHead( &pMac->sme.smeScanCmdActiveList, |
| &pCommand->Link, LL_ACCESS_NOLOCK ); |
| |
| switch (pCommand->command) |
| { |
| case eSmeCommandScan: |
| smsLog(pMac, LOG1, |
| " Processing scan offload command "); |
| csrProcessScanCommand( pMac, pCommand ); |
| break; |
| case eSmeCommandRemainOnChannel: |
| smsLog(pMac, LOG1, |
| "Processing req remain on channel offload" |
| " command"); |
| p2pProcessRemainOnChannelCmd(pMac, pCommand); |
| break; |
| default: |
| smsLog(pMac, LOGE, |
| " Something wrong, wrong command enqueued" |
| " to smeScanCmdPendingList"); |
| pEntry = csrLLRemoveHead( |
| &pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_NOLOCK ); |
| pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| smeReleaseCommand( pMac, pCommand ); |
| break; |
| } |
| } |
| } |
| } |
| } |
| end: |
| csrLLUnlock(&pMac->sme.smeScanCmdActiveList); |
| return status; |
| } |
| |
| tANI_BOOLEAN smeProcessCommand( tpAniSirGlobal pMac ) |
| { |
| tANI_BOOLEAN fContinue = eANI_BOOLEAN_FALSE; |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| tListElem *pEntry; |
| tSmeCmd *pCommand; |
| tListElem *pSmeEntry; |
| tSmeCmd *pSmeCommand; |
| eSmeCommandType pmcCommand = eSmeNoCommand; |
| |
| /* |
| * If the ActiveList is empty, then nothing is active so we can process a |
| * pending command. |
| * Always lock active list before locking pending list. |
| */ |
| csrLLLock( &pMac->sme.smeCmdActiveList ); |
| if ( csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) ) |
| { |
| if(!csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK)) |
| { |
| /* 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 ((pMac->fScanOffload) && |
| (!csrLLIsListEmpty(&pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_LOCK))) |
| { |
| pSmeEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, |
| LL_ACCESS_LOCK); |
| if (pSmeEntry) |
| { |
| pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link); |
| |
| pEntry = csrGetCmdToProcess(pMac, |
| &pMac->sme.smeCmdPendingList, |
| pSmeCommand->sessionId, |
| LL_ACCESS_LOCK); |
| goto sme_process_cmd; |
| } |
| } |
| |
| //Peek the command |
| pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK ); |
| sme_process_cmd: |
| if( pEntry ) |
| { |
| 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 ) ) |
| { |
| if (CSR_IS_CLOSE_SESSION_COMMAND(pCommand)) { |
| tSmeCmd *sme_cmd = NULL; |
| |
| smsLog(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 (HAL_STATUS_SUCCESS(status) && sme_cmd) { |
| csrLLLock(&pMac->sme.smeCmdPendingList); |
| csrLLInsertHead(&pMac->sme.smeCmdPendingList, |
| &sme_cmd->Link, LL_ACCESS_NOLOCK); |
| pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, |
| LL_ACCESS_NOLOCK); |
| csrLLUnlock(&pMac->sme.smeCmdPendingList); |
| goto sme_process_cmd; |
| } |
| } |
| |
| if( !CSR_IS_SET_KEY_COMMAND( pCommand ) ) |
| { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| smsLog(pMac, LOGE, FL("SessionId %d: Cannot process " |
| "command(%d) while waiting for key"), |
| pCommand->sessionId, pCommand->command); |
| fContinue = eANI_BOOLEAN_FALSE; |
| goto sme_process_scan_queue; |
| } |
| } |
| if(pMac->psOffloadEnabled) |
| pmcCommand = smePsOffloadIsFullPowerNeeded(pMac, pCommand); |
| else |
| pmcCommand = smeIsFullPowerNeeded( pMac, pCommand ); |
| if( eSmeDropCommand == pmcCommand ) |
| { |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| //This command is not ok for current PMC state |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) |
| { |
| smeAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); |
| } |
| //tell caller to continue |
| fContinue = eANI_BOOLEAN_TRUE; |
| goto sme_process_scan_queue; |
| } |
| else if( eSmeNoCommand != pmcCommand ) |
| { |
| tExitBmpsInfo exitBmpsInfo; |
| void *pv = NULL; |
| tANI_U32 size = 0; |
| tSmeCmd *pPmcCmd = NULL; |
| |
| if( eSmeCommandExitBmps == pmcCommand ) |
| { |
| exitBmpsInfo.exitBmpsReason = eSME_REASON_OTHER; |
| pv = (void *)&exitBmpsInfo; |
| size = sizeof(tExitBmpsInfo); |
| } |
| //pmcCommand has to be one of the exit power save command |
| status = pmcPrepareCommand(pMac, pCommand->sessionId, |
| pmcCommand, pv, size, |
| &pPmcCmd); |
| if( HAL_STATUS_SUCCESS( status ) && pPmcCmd ) |
| { |
| //Force this command to wake up the chip |
| csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ); |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_COMMAND, pPmcCmd->sessionId, pPmcCmd->command)); |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| /* Handle PS Offload Case Separately */ |
| if(pMac->psOffloadEnabled) |
| { |
| fContinue = pmcOffloadProcessCommand(pMac, pPmcCmd); |
| } |
| else |
| { |
| fContinue = pmcProcessCommand( pMac, pPmcCmd ); |
| } |
| if( fContinue ) |
| { |
| //The command failed, remove it |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ) ) |
| { |
| pmcReleaseCommand( pMac, pPmcCmd ); |
| } |
| } |
| } |
| else |
| { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| smsLog( pMac, LOGE, FL( "Cannot issue command(0x%X) to wake up the chip. Status = %d"), pmcCommand, status ); |
| //Let it retry |
| fContinue = eANI_BOOLEAN_TRUE; |
| } |
| goto sme_process_scan_queue; |
| } |
| if ( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) |
| { |
| // we can reuse the pCommand |
| |
| // Insert the command onto the ActiveList... |
| csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_NOLOCK ); |
| |
| // .... and process the command. |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_COMMAND, pCommand->sessionId, pCommand->command)); |
| switch ( pCommand->command ) |
| { |
| |
| case eSmeCommandScan: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| status = csrProcessScanCommand( pMac, pCommand ); |
| break; |
| |
| case eSmeCommandRoam: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| status = csrRoamProcessCommand( pMac, pCommand ); |
| if(!HAL_STATUS_SUCCESS(status)) |
| { |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| csrReleaseCommandRoam( pMac, pCommand ); |
| } |
| } |
| break; |
| |
| case eSmeCommandWmStatusChange: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| csrRoamProcessWmStatusChangeCommand(pMac, pCommand); |
| fContinue = eANI_BOOLEAN_TRUE; |
| break; |
| |
| case eSmeCommandSetKey: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| status = csrRoamProcessSetKeyCommand( pMac, pCommand ); |
| if(!HAL_STATUS_SUCCESS(status)) |
| { |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| csrReleaseCommandSetKey( pMac, pCommand ); |
| } |
| } |
| break; |
| |
| case eSmeCommandRemoveKey: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| status = csrRoamProcessRemoveKeyCommand( pMac, pCommand ); |
| if(!HAL_STATUS_SUCCESS(status)) |
| { |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| csrReleaseCommandRemoveKey( pMac, pCommand ); |
| } |
| } |
| break; |
| |
| case eSmeCommandAddStaSession: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| csrProcessAddStaSessionCommand( pMac, pCommand ); |
| break; |
| case eSmeCommandNdpInitiatorRequest: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| if (csr_process_ndp_initiator_request(pMac, |
| pCommand) != eHAL_STATUS_SUCCESS) { |
| if (csrLLRemoveEntry( |
| &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) { |
| csrReleaseCommand(pMac, pCommand); |
| } |
| } |
| break; |
| case eSmeCommandNdpResponderRequest: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| status = |
| csr_process_ndp_responder_request(pMac, |
| pCommand); |
| if (!HAL_STATUS_SUCCESS(status)) { |
| if (csrLLRemoveEntry( |
| &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csrReleaseCommand(pMac, pCommand); |
| } |
| break; |
| case eSmeCommandNdpDataEndInitiatorRequest: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| status = csr_process_ndp_data_end_request(pMac, |
| pCommand); |
| if (!HAL_STATUS_SUCCESS(status)) { |
| if (csrLLRemoveEntry( |
| &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) |
| csrReleaseCommand(pMac, pCommand); |
| } |
| break; |
| case eSmeCommandDelStaSession: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| csrProcessDelStaSessionCommand( pMac, pCommand ); |
| break; |
| case eSmeCommandSetMaxTxPower: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| sme_process_set_max_tx_power(pMac, pCommand); |
| /* We need to re-run the command */ |
| fContinue = eANI_BOOLEAN_TRUE; |
| /* No Rsp expected, free cmd from active list */ |
| if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) { |
| csrReleaseCommand(pMac, pCommand); |
| } |
| pMac->max_power_cmd_pending = false; |
| break; |
| case eSmeCommandSetMaxTxPowerPerBand: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| sme_process_set_max_tx_power_per_band(pMac, |
| pCommand); |
| /* We need to re-run the command */ |
| fContinue = eANI_BOOLEAN_TRUE; |
| /* No Rsp expected, free cmd from active list */ |
| if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK)) { |
| csrReleaseCommand(pMac, pCommand); |
| } |
| pMac->max_power_cmd_pending = false; |
| break; |
| |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| case eSmeCommandOemDataReq: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| oemData_ProcessOemDataReqCommand(pMac, pCommand); |
| break; |
| #endif |
| case eSmeCommandRemainOnChannel: |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| p2pProcessRemainOnChannelCmd(pMac, pCommand); |
| break; |
| case eSmeCommandNoAUpdate: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| p2pProcessNoAReq(pMac,pCommand); |
| break; |
| case eSmeCommandEnterImps: |
| case eSmeCommandExitImps: |
| case eSmeCommandEnterBmps: |
| case eSmeCommandExitBmps: |
| case eSmeCommandEnterUapsd: |
| case eSmeCommandExitUapsd: |
| case eSmeCommandEnterWowl: |
| case eSmeCommandExitWowl: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| if(pMac->psOffloadEnabled) |
| { |
| fContinue = |
| pmcOffloadProcessCommand(pMac, pCommand); |
| } |
| else |
| { |
| fContinue = pmcProcessCommand(pMac, pCommand); |
| } |
| if( fContinue ) |
| { |
| //The command failed, remove it |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| pmcReleaseCommand( 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: |
| if( csrIsConnStateDisconnected( pMac, pCommand->sessionId ) ) |
| { |
| //It can continue |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| if(pMac->psOffloadEnabled) |
| { |
| fContinue = |
| pmcOffloadProcessCommand(pMac, pCommand); |
| } |
| else |
| { |
| fContinue = |
| pmcProcessCommand(pMac, pCommand); |
| } |
| if( fContinue ) |
| { |
| //The command failed, remove it |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| pmcReleaseCommand( pMac, pCommand ); |
| } |
| } |
| } |
| else |
| { |
| //Need to issue a disconnect first before processing this command |
| tSmeCmd *pNewCmd; |
| |
| //We need to re-run the command |
| fContinue = eANI_BOOLEAN_TRUE; |
| //Pull off the standby command first |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_NOLOCK ) ) |
| { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| //Need to call CSR function here because the disconnect command |
| //is handled by CSR |
| pNewCmd = csrGetCommandBuffer( pMac ); |
| if( NULL != pNewCmd ) |
| { |
| //Put the standby command to the head of the pending list first |
| csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCommand->Link, |
| LL_ACCESS_LOCK ); |
| pNewCmd->command = eSmeCommandRoam; |
| pNewCmd->u.roamCmd.roamReason = eCsrForcedDisassoc; |
| //Put the disassoc command before the standby command |
| csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pNewCmd->Link, |
| LL_ACCESS_LOCK ); |
| } |
| else |
| { |
| //Continue the command here |
| if(pMac->psOffloadEnabled) |
| { |
| fContinue = |
| pmcOffloadProcessCommand(pMac, |
| pCommand); |
| } |
| else |
| { |
| fContinue = pmcProcessCommand(pMac, |
| pCommand); |
| } |
| if( fContinue ) |
| { |
| //The command failed, remove it |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_LOCK ) ) |
| { |
| pmcReleaseCommand( pMac, pCommand ); |
| } |
| } |
| } |
| } |
| else |
| { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| smsLog( pMac, LOGE, FL(" failed to remove standby command") ); |
| VOS_ASSERT(0); |
| } |
| } |
| break; |
| |
| case eSmeCommandAddTs: |
| case eSmeCommandDelTs: |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| fContinue = qosProcessCommand( pMac, pCommand ); |
| if( fContinue ) |
| { |
| //The command failed, remove it |
| if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, |
| &pCommand->Link, LL_ACCESS_NOLOCK ) ) |
| { |
| //#ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| qosReleaseCommand( pMac, pCommand ); |
| //#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ |
| } |
| } |
| #endif |
| break; |
| #ifdef FEATURE_WLAN_TDLS |
| case eSmeCommandTdlsSendMgmt: |
| case eSmeCommandTdlsAddPeer: |
| case eSmeCommandTdlsDelPeer: |
| case eSmeCommandTdlsLinkEstablish: |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "sending TDLS Command 0x%x to PE", pCommand->command); |
| |
| csrLLUnlock(&pMac->sme.smeCmdActiveList); |
| status = csrTdlsProcessCmd(pMac, pCommand); |
| if (!HAL_STATUS_SUCCESS(status)) { |
| if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, |
| &pCommand->Link, |
| LL_ACCESS_LOCK)) { |
| vos_mem_zero(&pCommand->u.tdlsCmd, |
| sizeof(tTdlsCmd)); |
| csrReleaseCommand(pMac, pCommand); |
| } |
| } |
| } |
| break ; |
| #endif |
| |
| default: |
| //something is wrong |
| //remove it from the active list |
| smsLog(pMac, LOGE, " csrProcessCommand processes an unknown command %d", pCommand->command); |
| pEntry = csrLLRemoveHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ); |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); |
| smeReleaseCommand( pMac, pCommand ); |
| status = eHAL_STATUS_FAILURE; |
| break; |
| } |
| if(!HAL_STATUS_SUCCESS(status)) |
| { |
| fContinue = eANI_BOOLEAN_TRUE; |
| } |
| }//if(pEntry) |
| else |
| { |
| //This is odd. Some one else pull off the command. |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "Remove entry failed"); |
| } |
| } |
| else |
| { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "Get Pending command failed"); |
| } |
| } |
| else |
| { |
| //No command waiting |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| /* |
| * This is only used to restart an idle mode scan, |
| * it means at least one other idle scan has finished. |
| * Moreover Idle Scan is not supported with power |
| * save offload supported |
| */ |
| if(!pMac->psOffloadEnabled && |
| pMac->scan.fRestartIdleScan && |
| eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) |
| { |
| tANI_U32 nTime = 0; |
| |
| pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; |
| if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime))) |
| { |
| csrScanStartIdleScanTimer(pMac, nTime); |
| } |
| } |
| } |
| } |
| else { |
| csrLLUnlock( &pMac->sme.smeCmdActiveList ); |
| } |
| |
| sme_process_scan_queue: |
| if (pMac->fScanOffload && !(smeProcessScanQueue(pMac))) |
| fContinue = eANI_BOOLEAN_FALSE; |
| |
| return ( fContinue ); |
| } |
| |
| void smeProcessPendingQueue( tpAniSirGlobal pMac ) |
| { |
| while( smeProcessCommand( pMac ) ); |
| } |
| |
| |
| tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac) |
| { |
| return ( !csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) || |
| !csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK) ); |
| } |
| |
| /** |
| * sme_get_sessionid_from_activelist() - gets session id |
| * @mac: mac context |
| * |
| * This function is used to get session id from sme command |
| * active list |
| * |
| * Return: returns session id |
| */ |
| uint32_t sme_get_sessionid_from_activelist(tpAniSirGlobal mac) |
| { |
| tListElem *entry; |
| tSmeCmd *command; |
| uint32_t session_id = 0; |
| |
| entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK); |
| if (entry) { |
| command = GET_BASE_ADDR(entry, tSmeCmd, Link); |
| session_id = command->sessionId; |
| } |
| |
| return session_id; |
| } |
| |
| /** |
| * sme_state_info_dump() - prints state information of sme layer |
| * @buf: buffer pointer |
| * @size: size of buffer to be filled |
| * |
| * This function is used to dump state information of sme layer |
| * |
| * Return: None |
| */ |
| static void sme_state_info_dump(char **buf_ptr, uint16_t *size) |
| { |
| uint32_t session_id; |
| tHalHandle hal; |
| tpAniSirGlobal mac; |
| v_CONTEXT_t vos_ctx_ptr; |
| uint16_t len = 0; |
| char *buf = *buf_ptr; |
| |
| /* get the global voss context */ |
| vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); |
| |
| if (NULL == vos_ctx_ptr) { |
| VOS_ASSERT(0); |
| return; |
| } |
| |
| hal = vos_get_context(VOS_MODULE_ID_SME, vos_ctx_ptr); |
| if (NULL == hal) { |
| VOS_ASSERT(0); |
| return; |
| } |
| |
| mac = PMAC_STRUCT(hal); |
| smsLog(mac, LOG1, FL("size of buffer: %d"), *size); |
| |
| session_id = sme_get_sessionid_from_activelist(mac); |
| |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n active command sessionid %d", session_id); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n NeighborRoamState: %d", |
| mac->roam.neighborRoamInfo[session_id].neighborRoamState); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n RoamState: %d", mac->roam.curState[session_id]); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n RoamSubState: %d", mac->roam.curSubState[session_id]); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n ConnectState: %d", |
| mac->roam.roamSession[session_id].connectState); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n pmcState: %d", mac->pmc.pmcState); |
| len += vos_scnprintf(buf + len, *size - len, |
| "\n PmmState: %d", mac->pmm.gPmmState); |
| |
| *size -= len; |
| *buf_ptr += len; |
| } |
| |
| /** |
| * sme_register_debug_callback() - registration function sme layer |
| * to print sme state information |
| * |
| * Return: None |
| */ |
| static void sme_register_debug_callback(void) |
| { |
| vos_register_debug_callback(VOS_MODULE_ID_SME, &sme_state_info_dump); |
| } |
| |
| //Global APIs |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_Open() - Initialize all SME modules and put them at idle state |
| |
| The function initializes each module inside SME, PMC, CCM, 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 macOpen. |
| This is a synchronous call |
| \param hHal - The handle returned by macOpen. |
| |
| \return eHAL_STATUS_SUCCESS - SME is successfully initialized. |
| |
| Other status means SME is failed to be initialized |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_Open(tHalHandle hHal) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| do { |
| pMac->sme.state = SME_STATE_STOP; |
| pMac->sme.currDeviceMode = VOS_STA_MODE; |
| if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->sme.lkSmeGlobalLock ) ) ) |
| { |
| smsLog( pMac, LOGE, "sme_Open failed init lock" ); |
| status = eHAL_STATUS_FAILURE; |
| break; |
| } |
| |
| status = ccmOpen(hHal); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "ccmOpen failed during initialization with status=%d", status ); |
| break; |
| } |
| |
| status = csrOpen(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "csrOpen failed during initialization with status=%d", status ); |
| break; |
| } |
| |
| if(!pMac->psOffloadEnabled) |
| { |
| status = pmcOpen(hHal); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "pmcOpen failed during initialization with status=%d", |
| status ); |
| break; |
| } |
| } |
| else |
| { |
| status = pmcOffloadOpen(hHal); |
| if (! HAL_STATUS_SUCCESS(status)) { |
| smsLog( pMac, LOGE, |
| "pmcOffloadOpen failed during initialization with status=%d", |
| status ); |
| break; |
| } |
| } |
| |
| #ifdef FEATURE_WLAN_TDLS |
| pMac->isTdlsPowerSaveProhibited = 0; |
| #endif |
| |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| status = sme_QosOpen(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "Qos open failed during initialization with status=%d", status ); |
| break; |
| } |
| |
| #endif |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| status = oemData_OemDataReqOpen(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog(pMac, LOGE, |
| "oemData_OemDataReqOpen failed during initialization with status=%d", status ); |
| break; |
| } |
| #endif |
| |
| if(!HAL_STATUS_SUCCESS((status = initSmeCmdList(pMac)))) |
| break; |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| status = rrmOpen(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "rrmOpen open failed during initialization with status=%d", status ); |
| break; |
| } |
| #endif |
| |
| sme_p2pOpen(pMac); |
| smeTraceInit(pMac); |
| sme_register_debug_callback(); |
| |
| }while (0); |
| |
| return status; |
| } |
| |
| /* |
| * sme_init_chan_list, triggers channel setup based on country code. |
| */ |
| eHalStatus sme_init_chan_list(tHalHandle hal, v_U8_t *alpha2, |
| COUNTRY_CODE_SOURCE cc_src) |
| { |
| tpAniSirGlobal pmac = PMAC_STRUCT(hal); |
| |
| if ((cc_src == COUNTRY_CODE_SET_BY_USER) && |
| (pmac->roam.configParam.fSupplicantCountryCodeHasPriority)) |
| { |
| pmac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_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 macOpen. |
| \Param pSmeConfigParams - a pointer to a caller allocated object of |
| typedef struct _smeConfigParams. |
| |
| \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. |
| |
| Other status means SME is failed to update the config parameters. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| eHalStatus sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0)); |
| if (NULL == pSmeConfigParams ) { |
| smsLog( pMac, LOGE, |
| "Empty config param structure for SME, nothing to update"); |
| return status; |
| } |
| |
| status = csrSetChannels(hHal, &pSmeConfigParams->csrConfig ); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", |
| status ); |
| } |
| return status; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_getSoftApDomain() - 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 eHAL_STATUS_SUCCESS - SME successfully completed the request. |
| |
| Other status means, failed to get the current regulatory domain. |
| \sa |
| --------------------------------------------------------------------------*/ |
| |
| eHalStatus sme_getSoftApDomain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, NO_SESSION, 0)); |
| if (NULL == domainIdSoftAp ) { |
| smsLog( pMac, LOGE, "Uninitialized domain Id"); |
| return status; |
| } |
| |
| *domainIdSoftAp = pMac->scan.domainIdCurrent; |
| status = eHAL_STATUS_SUCCESS; |
| |
| return status; |
| } |
| |
| |
| eHalStatus sme_setRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0)); |
| if (NULL == apCntryCode ) { |
| smsLog( pMac, LOGE, "Empty Country Code, nothing to update"); |
| return status; |
| } |
| |
| status = csrSetRegInfo(hHal, apCntryCode ); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "csrSetRegInfo failed with status=%d", |
| status ); |
| } |
| return status; |
| } |
| |
| #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) |
| eHalStatus sme_SetPlmRequest(tHalHandle hHal, tpSirPlmReq pPlmReq) |
| { |
| eHalStatus status; |
| tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE; |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; |
| tANI_U8 count, valid_count = 0; |
| vos_msg_t msg; |
| |
| if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) |
| { |
| tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pPlmReq->sessionId ); |
| |
| if(!pSession) |
| { |
| smsLog(pMac, LOGE, FL("session %d not found"), pPlmReq->sessionId); |
| sme_ReleaseGlobalLock( &pMac->sme ); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| if( !pSession->sessionActive ) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "%s Invalid Sessionid", __func__); |
| sme_ReleaseGlobalLock( &pMac->sme ); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| if (pPlmReq->enable) { |
| |
| /* validating channel numbers */ |
| for (count = 0; count < pPlmReq->plmNumCh; count++) { |
| |
| ret = csrIsSupportedChannel(pMac, pPlmReq->plmChList[count]); |
| if (ret && pPlmReq->plmChList[count] > 14) |
| { |
| if (NV_CHANNEL_DFS == |
| vos_nv_getChannelEnabledState(pPlmReq->plmChList[count])) |
| { |
| /* DFS channel is provided, no PLM bursts can be |
| * transmitted. Ignoring these channels. |
| */ |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s DFS channel %d ignored for PLM", __func__, |
| pPlmReq->plmChList[count]); |
| continue; |
| } |
| } |
| else if (!ret) |
| { |
| /* Not supported, ignore the channel */ |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s Unsupported channel %d ignored for PLM", |
| __func__, 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 */ |
| vos_mem_set((void *)pPlmReq->plmChList, pPlmReq->plmNumCh, 0); |
| if (valid_count) |
| vos_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; |
| } /* PLM START */ |
| |
| msg.type = WDA_SET_PLM_REQ; |
| msg.reserved = 0; |
| msg.bodyptr = pPlmReq; |
| |
| if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "%s: Not able to post WDA_SET_PLM_REQ message to WDA", |
| __func__); |
| sme_ReleaseGlobalLock(&pMac->sme); |
| return eHAL_STATUS_FAILURE; |
| } |
| |
| sme_ReleaseGlobalLock(&pMac->sme); |
| } |
| return (status); |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_SCAN_PNO |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA. |
| |
| It is used at driver start up to inform RIVA of the default channel |
| configuration. |
| |
| This is a synchronous call |
| |
| \param hHal - The handle returned by macOpen. |
| |
| \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. |
| |
| Other status means SME is failed to update the channel config. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_UpdateChannelConfig(tHalHandle hHal) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, NO_SESSION, 0)); |
| pmcUpdateScanParams( pMac, &(pMac->roam.configParam), |
| &pMac->scan.base20MHzChannels, FALSE); |
| return eHAL_STATUS_SUCCESS; |
| } |
| #endif // FEATURE_WLAN_SCAN_PNLO |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_UpdateConfig() - Change configurations for all SME modules |
| |
| The function updates some configuration for modules in SME, CCM, 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 macOpen. |
| \Param pSmeConfigParams - a pointer to a caller allocated object of |
| typedef struct _smeConfigParams. |
| |
| \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. |
| |
| Other status means SME is failed to update the config parameters. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, |
| TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, 0)); |
| if (NULL == pSmeConfigParams ) { |
| smsLog( pMac, LOGE, |
| "Empty config param structure for SME, nothing to update"); |
| return status; |
| } |
| |
| status = csrChangeDefaultConfigParam(pMac, &pSmeConfigParams->csrConfig); |
| |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", |
| status ); |
| } |
| #if defined WLAN_FEATURE_VOWIFI |
| status = rrmChangeDefaultConfigParam(hHal, &pSmeConfigParams->rrmConfig); |
| |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "rrmChangeDefaultConfigParam failed with status=%d", |
| status ); |
| } |
| #endif |
| //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( |
| csrIsAllSessionDisconnected( pMac) ) |
| { |
| csrSetGlobalCfgs(pMac); |
| } |
| |
| /* update the directed scan offload setting */ |
| pMac->fScanOffload = pSmeConfigParams->fScanOffload; |
| |
| if (pMac->fScanOffload) |
| { |
| /* |
| * If scan offload is enabled then lim has allow the sending of |
| * scan request to firmware even in power save mode. The firmware has |
| * to take care of exiting from power save mode |
| */ |
| status = ccmCfgSetInt(hHal, WNI_CFG_SCAN_IN_POWERSAVE, |
| eANI_BOOLEAN_TRUE, NULL, eANI_BOOLEAN_FALSE); |
| |
| if (eHAL_STATUS_SUCCESS != status) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CCM"); |
| } |
| } |
| pMac->isCoalesingInIBSSAllowed = |
| pSmeConfigParams->csrConfig.isCoalesingInIBSSAllowed; |
| |
| /* update the p2p listen offload setting */ |
| pMac->fP2pListenOffload = pSmeConfigParams->fP2pListenOffload; |
| |
| /* update p2p offload status */ |
| pMac->pnoOffload = pSmeConfigParams->pnoOffload; |
| |
| pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog; |
| |
| /* update interface configuration */ |
| pMac->sme.max_intf_count = pSmeConfigParams->max_intf_count; |
| |
| pMac->enable5gEBT = pSmeConfigParams->enable5gEBT; |
| pMac->sme.enableSelfRecovery = pSmeConfigParams->enableSelfRecovery; |
| |
| pMac->f_sta_miracast_mcc_rest_time_val = |
| pSmeConfigParams->f_sta_miracast_mcc_rest_time_val; |
| |
| #ifdef FEATURE_AP_MCC_CH_AVOIDANCE |
| pMac->sap.sap_channel_avoidance = pSmeConfigParams->sap_channel_avoidance; |
| #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ |
| |
| pMac->f_prefer_non_dfs_on_radar = |
| pSmeConfigParams->f_prefer_non_dfs_on_radar; |
| pMac->fine_time_meas_cap = pSmeConfigParams->fine_time_meas_cap; |
| |
| pMac->snr_monitor_enabled = pSmeConfigParams->snr_monitor_enabled; |
| pMac->sub20_config_info = pSmeConfigParams->sub20_config_info; |
| pMac->sub20_channelwidth = pSmeConfigParams->sub20_channelwidth; |
| pMac->sub20_dynamic_channelwidth = |
| pSmeConfigParams->sub20_dynamic_channelwidth; |
| |
| pMac->sta_auth_retries_for_code17 = |
| pSmeConfigParams->csrConfig.sta_auth_retries_for_code17; |
| |
| return status; |
| } |
| |
| /** |
| * sme_update_roam_params - Store/Update the roaming params |
| * @hHal 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. |
| */ |
| eHalStatus sme_update_roam_params(tHalHandle hHal, |
| uint8_t session_id, struct roam_ext_params roam_params_src, |
| int update_param) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| struct roam_ext_params *roam_params_dst; |
| uint8_t i; |
| |
| roam_params_dst = &pMac->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: |
| vos_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; |
| vos_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: |
| vos_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++) { |
| vos_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: |
| vos_mem_set(&roam_params_dst->bssid_avoid_list, 0, |
| sizeof(tSirMacAddr) * 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++) { |
| vos_mem_copy(&roam_params_dst->bssid_avoid_list[i], |
| &roam_params_src.bssid_avoid_list[i], |
| sizeof(tSirMacAddr)); |
| } |
| break; |
| case REASON_ROAM_GOOD_RSSI_CHANGED: |
| roam_params_dst->good_rssi_roam = |
| roam_params_src.good_rssi_roam; |
| break; |
| default: |
| break; |
| } |
| csrRoamOffloadScan(pMac, session_id, |
| ROAM_SCAN_OFFLOAD_UPDATE_CFG, update_param); |
| return 0; |
| } |
| #ifdef WLAN_FEATURE_GTK_OFFLOAD |
| void sme_ProcessGetGtkInfoRsp( tHalHandle hHal, |
| tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (NULL == pMac) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return ; |
| } |
| if (pMac->pmc.GtkOffloadGetInfoCB == NULL) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "%s: HDD callback is null", __func__); |
| return ; |
| } |
| pMac->pmc.GtkOffloadGetInfoCB(pMac->pmc.GtkOffloadGetInfoCBContext, |
| pGtkOffloadGetInfoRsp); |
| } |
| #endif |
| |
| /*-------------------------------------------------------------------------- |
| |
| \fn - sme_ProcessReadyToSuspend |
| \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 macOpen. |
| pReadyToSuspend - Parameter received along with ready to suspend |
| indication from WMA. |
| |
| \return None |
| |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| void sme_ProcessReadyToSuspend( tHalHandle hHal, |
| tpSirReadyToSuspendInd pReadyToSuspend) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (NULL == pMac) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_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 |
| /*-------------------------------------------------------------------------- |
| |
| \fn - sme_ProcessReadyToExtWoW |
| \brief - On getting ready to Ext WoW indication, this function calls |
| callback registered (HDD callbacks) with SME to inform |
| ready to ExtWoW indication. |
| |
| \param hHal - Handle returned by macOpen. |
| pReadyToExtWoW - Parameter received along with ready to Ext WoW |
| indication from WMA. |
| |
| \return None |
| |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| void sme_ProcessReadyToExtWoW( tHalHandle hHal, |
| tpSirReadyToExtWoWInd pReadyToExtWoW) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (NULL == pMac) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_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_ChangeConfigParams |
| \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. Currently 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 macOpen. |
| |
| \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 eHalStatus |
| ---------------------------------------------------------------------------*/ |
| eHalStatus sme_ChangeConfigParams(tHalHandle hHal, |
| tCsrUpdateConfigParam *pUpdateConfigParam) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (NULL == pUpdateConfigParam ) { |
| smsLog( pMac, LOGE, |
| "Empty config param structure for SME, nothing to reset"); |
| return status; |
| } |
| |
| status = csrChangeConfigParams(pMac, pUpdateConfigParam); |
| |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "csrUpdateConfigParam failed with status=%d", |
| status ); |
| } |
| |
| return status; |
| |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform |
| that the NIC is ready to 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 macOpen. |
| |
| \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE |
| successfully. |
| |
| Other status means SME failed to send the message to PE. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_HDDReadyInd(tHalHandle hHal) |
| { |
| tSirSmeReadyReq Msg; |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tPmcPowerState powerState; |
| tPmcSwitchState hwWlanSwitchState; |
| tPmcSwitchState swWlanSwitchState; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| MTRACE(vos_trace(VOS_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 ); |
| |
| if (eSIR_FAILURE != uMacPostCtrlMsg( hHal, (tSirMbMsg*)&Msg )) |
| { |
| status = eHAL_STATUS_SUCCESS; |
| } |
| else |
| { |
| smsLog( pMac, LOGE, |
| "uMacPostCtrlMsg failed to send eWNI_SME_SYS_READY_IND"); |
| break; |
| } |
| |
| if(!pMac->psOffloadEnabled) |
| { |
| status = pmcQueryPowerState( hHal, &powerState, |
| &hwWlanSwitchState, &swWlanSwitchState ); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, "pmcQueryPowerState failed with status=%d", |
| status ); |
| break; |
| } |
| |
| if ( (ePMC_SWITCH_OFF != hwWlanSwitchState) && |
| (ePMC_SWITCH_OFF != swWlanSwitchState) ) |
| { |
| status = csrReady(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, "csrReady failed with status=%d", status ); |
| break; |
| } |
| status = pmcReady(hHal); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) |
| { |
| smsLog( pMac, LOGE, "pmcReady failed with status=%d", status ); |
| break; |
| } |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| if(VOS_STATUS_SUCCESS != rrmReady(hHal)) |
| { |
| status = eHAL_STATUS_FAILURE; |
| smsLog( pMac, LOGE, "rrmReady failed"); |
| break; |
| } |
| #endif |
| } |
| } |
| else |
| { |
| status = csrReady(pMac); |
| if (!HAL_STATUS_SUCCESS(status)) |
| { |
| smsLog( pMac, LOGE, "csrReady failed with status=%d", status ); |
| break; |
| } |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| if(VOS_STATUS_SUCCESS != rrmReady(hHal)) |
| { |
| status = eHAL_STATUS_FAILURE; |
| smsLog( pMac, LOGE, "rrmReady failed"); |
| break; |
| } |
| #endif |
| } |
| pMac->sme.state = SME_STATE_READY; |
| } while( 0 ); |
| |
| return status; |
| } |
| |
| /** |
| * sme_set_allowed_action_frames() - Set allowed action frames to wma |
| * @hal: Handler to HAL |
| * @bitmap0: bitmap to set |
| * @is_sta: boolean to indicate sta interface |
| * |
| * This function conveys the list of action frames that needs to be forwarded |
| * to driver by FW. Rest of the action frames can be dropped in FW. Bitmask is |
| * set with ALLOWED_ACTION_FRAMES_BITMAP0~7 |
| * |
| * Return: None |
| */ |
| void sme_set_allowed_action_frames(tHalHandle hal, |
| uint32_t bitmap0, bool is_sta) |
| { |
| eHalStatus status; |
| tpAniSirGlobal mac = PMAC_STRUCT(hal); |
| vos_msg_t message; |
| VOS_STATUS vos_status; |
| struct sir_allowed_action_frames *sir_allowed_action_frames; |
| |
| sir_allowed_action_frames = |
| vos_mem_malloc(sizeof(*sir_allowed_action_frames)); |
| if (!sir_allowed_action_frames) { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "Not able to allocate memory for WDA_SET_ALLOWED_ACTION_FRAMES_IND"); |
| return; |
| } |
| |
| vos_mem_zero(sir_allowed_action_frames, |
| sizeof(*sir_allowed_action_frames)); |
| sir_allowed_action_frames->operation = WOW_ACTION_WAKEUP_OPERATION_SET; |
| |
| sir_allowed_action_frames->action_category_map[0] = bitmap0; |
| sir_allowed_action_frames->action_category_map[1] = |
| (ALLOWED_ACTION_FRAMES_BITMAP1); |
| sir_allowed_action_frames->action_category_map[2] = |
| (ALLOWED_ACTION_FRAMES_BITMAP2); |
| sir_allowed_action_frames->action_category_map[3] = |
| (ALLOWED_ACTION_FRAMES_BITMAP3); |
| sir_allowed_action_frames->action_category_map[4] = |
| (ALLOWED_ACTION_FRAMES_BITMAP4); |
| sir_allowed_action_frames->action_category_map[5] = |
| (ALLOWED_ACTION_FRAMES_BITMAP5); |
| sir_allowed_action_frames->action_category_map[6] = |
| (ALLOWED_ACTION_FRAMES_BITMAP6); |
| sir_allowed_action_frames->action_category_map[7] = |
| (ALLOWED_ACTION_FRAMES_BITMAP7); |
| if (is_sta) |
| sir_allowed_action_frames-> |
| action_per_category[SIR_MAC_ACTION_SPECTRUM_MGMT] = |
| DROP_SPEC_MGMT_ACTION_FRAME_BITMAP; |
| |
| status = sme_AcquireGlobalLock(&mac->sme); |
| if (status == eHAL_STATUS_SUCCESS) { |
| /* serialize the req through MC thread */ |
| message.bodyptr = sir_allowed_action_frames; |
| message.type = SIR_HAL_SET_ALLOWED_ACTION_FRAMES; |
| |
| vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &message); |
| if (!VOS_IS_STATUS_SUCCESS(vos_status)) { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "Not able to post SIR_HAL_SET_ALLOWED_ACTION_FRAMES message to HAL"); |
| vos_mem_free(sir_allowed_action_frames); |
| } |
| |
| sme_ReleaseGlobalLock( &mac->sme ); |
| } else { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " |
| "sme_AcquireGlobalLock error", __func__); |
| vos_mem_free(sir_allowed_action_frames); |
| } |
| |
| return; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_Start() - Put all SME modules at ready state. |
| |
| The function starts each module in SME, PMC, CCM, CSR, etc. . Upon |
| successfully return, all modules are ready to run. |
| This is a synchronous call |
| \param hHal - The handle returned by macOpen. |
| |
| \return eHAL_STATUS_SUCCESS - SME is ready. |
| |
| Other status means SME is failed to start |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_Start(tHalHandle hHal) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| do |
| { |
| status = csrStart(pMac); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, "csrStart failed during smeStart with status=%d", |
| status ); |
| break; |
| } |
| |
| if(!pMac->psOffloadEnabled) |
| { |
| status = pmcStart(hHal); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "pmcStart failed during smeStart with status=%d", |
| status ); |
| break; |
| } |
| } |
| else |
| { |
| status = pmcOffloadStart(hHal); |
| if ( ! HAL_STATUS_SUCCESS( status ) ) { |
| smsLog( pMac, LOGE, |
| "pmcOffloadStart failed during smeStart with status=%d", |
| status ); |
| break; |
| } |
| } |
| |
| pMac->sme.state = SME_STATE_START; |
| }while (0); |
| |
| sme_set_allowed_action_frames(hHal, ALLOWED_ACTION_FRAMES_BITMAP0_STA, true); |
| |
| return status; |
| } |
| |
| |
| #ifdef WLAN_FEATURE_PACKET_FILTERING |
| /****************************************************************************** |
| * |
| * Name: sme_PCFilterMatchCountResponseHandler |
| * |
| * Description: |
| * Invoke Packet Coalescing Filter Match Count callback routine |
| * |
| * Parameters: |
| * hHal - HAL handle for device |
| * pMsg - Pointer to tRcvFltPktMatchRsp structure |
| * |
| * Returns: eHalStatus |
| * |
| ******************************************************************************/ |
| eHalStatus sme_PCFilterMatchCountResponseHandler(tHalHandle hHal, void* pMsg) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT(hHal); |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp = (tpSirRcvFltPktMatchRsp)pMsg; |
| |
| if (NULL == pMsg) |
| { |
| smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); |
| status = eHAL_STATUS_FAILURE; |
| } |
| else |
| { |
| smsLog(pMac, LOG2, "SME: entering " |
| "sme_FilterMatchCountResponseHandler"); |
| |
| /* Call Packet Coalescing Filter Match Count callback routine. */ |
| if (pMac->pmc.FilterMatchCountCB != NULL) |
| pMac->pmc.FilterMatchCountCB(pMac->pmc.FilterMatchCountCBContext, |
| pRcvFltPktMatchRsp); |
| |
| smsLog(pMac, LOG1, "%s: status=0x%x", __func__, |
| pRcvFltPktMatchRsp->status); |
| |
| pMac->pmc.FilterMatchCountCB = NULL; |
| pMac->pmc.FilterMatchCountCBContext = NULL; |
| } |
| |
| return(status); |
| } |
| #endif // WLAN_FEATURE_PACKET_FILTERING |
| |
| |
| #ifdef WLAN_FEATURE_11W |
| /*------------------------------------------------------------------ |
| * |
| * Handle the unprotected management frame indication from LIM and |
| * forward it to HDD. |
| * |
| *------------------------------------------------------------------*/ |
| |
| eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, |
| tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| tCsrRoamInfo pRoamInfo = {0}; |
| tANI_U32 SessionId = pSmeMgmtFrm->sessionId; |
| |
| pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen; |
| pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf; |
| pRoamInfo.frameType = pSmeMgmtFrm->frameType; |
| |
| /* forward the mgmt frame to HDD */ |
| csrRoamCallCallback(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 |
| * |
| *------------------------------------------------------------------*/ |
| eHalStatus dfsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, void *pMsgBuf) |
| { |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| tCsrRoamInfo roamInfo = {0}; |
| tSirSmeDfsEventInd *dfs_event; |
| tSirSmeCSAIeTxCompleteRsp *csaIeTxCompleteRsp; |
| tANI_U32 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) |
| { |
| smsLog(pMac, LOGE, |
| "%s: pMsg is NULL for eWNI_SME_DFS_RADAR_FOUND message", |
| __func__); |
| return eHAL_STATUS_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; |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Radar indication event occurred"); |
| break; |
| } |
| case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: |
| { |
| csaIeTxCompleteRsp = (tSirSmeCSAIeTxCompleteRsp *)pMsgBuf; |
| if (NULL == csaIeTxCompleteRsp) |
| { |
| smsLog(pMac, LOGE, |
| "%s: pMsg is NULL for eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND", |
| __func__); |
| return eHAL_STATUS_FAILURE; |
| } |
| sessionId = csaIeTxCompleteRsp->sessionId; |
| roamStatus = eCSR_ROAM_DFS_CHAN_SW_NOTIFY; |
| roamResult = eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS; |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, |
| "sapdfs: Received eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND for session id [%d]", |
| sessionId ); |
| break; |
| } |
| default: |
| { |
| smsLog(pMac, LOG1, "%s: Invalid DFS message = 0x%x", __func__, |
| msgType); |
| status = eHAL_STATUS_FAILURE; |
| return status; |
| } |
| } |
| |
| /* Indicate Radar Event to SAP */ |
| csrRoamCallCallback(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 eHalStatus sme_extended_change_channel_ind(tpAniSirGlobal mac_ctx, |
| void *msg_buf) |
| { |
| struct sir_sme_ext_cng_chan_ind *ext_chan_ind; |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| uint32_t session_id = 0; |
| tCsrRoamInfo roamInfo = {0}; |
| eRoamCmdStatus roamStatus; |
| eCsrRoamResult roamResult; |
| |
| |
| ext_chan_ind = msg_buf; |
| if (NULL == ext_chan_ind) { |
| smsLog(mac_ctx, LOGE, |
| FL("pMsg is NULL for eWNI_SME_EXT_CHANGE_CHANNEL_IND")); |
| return eHAL_STATUS_FAILURE; |
| } |
| session_id = ext_chan_ind->session_id; |
| roamInfo.target_channel = ext_chan_ind->new_channel; |
| roamStatus = eCSR_ROAM_EXT_CHG_CHNL_IND; |
| roamResult = eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND; |
| smsLog(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 */ |
| csrRoamCallCallback(mac_ctx, session_id, &roamInfo, 0, |
| roamStatus, roamResult); |
| return status; |
| } |
| |
| #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) |
| /*------------------------------------------------------------------ |
| * |
| * Handle the tsm ie indication from LIM and forward it to HDD. |
| * |
| *------------------------------------------------------------------*/ |
| eHalStatus sme_TsmIeInd(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| tCsrRoamInfo pRoamInfo = {0}; |
| tANI_U32 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 */ |
| csrRoamCallCallback(pMac, |
| SessionId, |
| &pRoamInfo, |
| 0, |
| eCSR_ROAM_TSM_IE_IND, |
| 0); |
| return status; |
| } |
| /* --------------------------------------------------------------------------- |
| \fn sme_SetCCKMIe |
| \brief function to store the CCKM IE passed from supplicant and use |
| it while packing reassociation request |
| \param hHal - HAL handle for device |
| \param sessionId - Session Identifier |
| \param pCckmIe - pointer to CCKM IE data |
| \param pCckmIeLen - length of the CCKM IE |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| eHalStatus sme_SetCCKMIe(tHalHandle hHal, tANI_U8 sessionId, |
| tANI_U8 *pCckmIe, tANI_U8 cckmIeLen) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| eHalStatus status = eHAL_STATUS_SUCCESS; |
| status = sme_AcquireGlobalLock( &pMac->sme ); |
| if ( HAL_STATUS_SUCCESS( status ) ) |
| { |
| csrSetCCKMIe(pMac, sessionId, pCckmIe, cckmIeLen); |
| sme_ReleaseGlobalLock( &pMac->sme ); |
| } |
| return status; |
| } |
| |
| /* --------------------------------------------------------------------------- |
| \fn sme_SetEseBeaconRequest |
| \brief function to set ESE beacon request parameters |
| \param hHal - HAL handle for device |
| \param sessionId - Session id |
| \param pEseBcnReq - pointer to ESE beacon request |
| \- return Success or failure |
| -------------------------------------------------------------------------*/ |
| eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId, |
| const tCsrEseBeaconReq* pEseBcnReq) |
| { |
| eHalStatus status = eSIR_SUCCESS; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| tpSirBeaconReportReqInd pSmeBcnReportReq = NULL; |
| tCsrEseBeaconReqParams *pBeaconReq = NULL; |
| tANI_U8 counter = 0; |
| tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); |
| tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; |
| |
| if (pSmeRrmContext->eseBcnReqInProgress == TRUE) |
| { |
| smsLog(pMac, LOGE, "A Beacon Report Req is already in progress"); |
| return eHAL_STATUS_RESOURCES; |
| } |
| |
| /* Store the info in RRM context */ |
| vos_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq, sizeof(tCsrEseBeaconReq)); |
| |
| //Prepare the request to send to SME. |
| pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd )); |
| if(NULL == pSmeBcnReportReq) |
| { |
| smsLog(pMac, LOGP, "Memory Allocation Failure!!! ESE BcnReq Ind to SME"); |
| return eSIR_FAILURE; |
| } |
| |
| pSmeRrmContext->eseBcnReqInProgress = TRUE; |
| |
| smsLog(pMac, LOGE, "Sending Beacon Report Req to SME"); |
| vos_mem_zero( pSmeBcnReportReq, sizeof( tSirBeaconReportReqInd )); |
| |
| pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; |
| pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ); |
| vos_mem_copy( pSmeBcnReportReq->bssId, pSession->connectedProfile.bssid, 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_RrmProcessBeaconReportReqInd(pMac, pSmeBcnReportReq); |
| |
| if(status != eHAL_STATUS_SUCCESS) |
| pSmeRrmContext->eseBcnReqInProgress = FALSE; |
| |
| vos_mem_free(pSmeBcnReportReq); |
| return status; |
| } |
| |
| #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ |
| eHalStatus sme_IbssPeerInfoResponseHandleer( tHalHandle hHal, |
| tpSirIbssGetPeerInfoRspParams pIbssPeerInfoParams) |
| { |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (NULL == pMac) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, |
| "%s: pMac is null", __func__); |
| return eHAL_STATUS_FAILURE; |
| } |
| if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "%s: HDD callback is null", __func__); |
| return eHAL_STATUS_FAILURE; |
| } |
| pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData, |
| &pIbssPeerInfoParams->ibssPeerInfoRspParams); |
| return eHAL_STATUS_SUCCESS; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| |
| \brief sme_ProcessMsg() - 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 macOpen. |
| \param pMsg - A pointer to a caller allocated object of tSirMsgQ. |
| |
| \return eHAL_STATUS_SUCCESS - SME successfully process the message. |
| |
| Other status means SME failed to process the message to HAL. |
| \sa |
| |
| --------------------------------------------------------------------------*/ |
| eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) |
| { |
| eHalStatus status = eHAL_STATUS_FAILURE; |
| tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); |
| |
| if (pMsg == NULL) { |
| smsLog( pMac, LOGE, "Empty message for SME, nothing to process"); |
| return status; |
| } |
| |
| status = sme_AcquireGlobalLock( &pMac->sme ); |
| if ( HAL_STATUS_SUCCESS( status ) ) |
| { |
| if( SME_IS_START(pMac) ) |
| { |
| switch (pMsg->type) { // TODO: Will be modified to do a range check for msgs instead of having cases for each msgs |
| #ifdef WLAN_FEATURE_ROAM_OFFLOAD |
| case eWNI_SME_HO_FAIL_IND: |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, |
| "LFR3:%s: Rcvd eWNI_SME_HO_FAIL_IND", __func__); |
| csrProcessHOFailInd(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_ROAM_OFFLOAD_SYNCH_IND: |
| csrProcessRoamOffloadSynchInd(pMac, |
| (tpSirRoamOffloadSynchInd)pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| break; |
| #endif |
| case eWNI_PMC_ENTER_BMPS_RSP: |
| case eWNI_PMC_EXIT_BMPS_RSP: |
| case eWNI_PMC_EXIT_BMPS_IND: |
| case eWNI_PMC_ENTER_IMPS_RSP: |
| case eWNI_PMC_EXIT_IMPS_RSP: |
| case eWNI_PMC_SMPS_STATE_IND: |
| case eWNI_PMC_ENTER_UAPSD_RSP: |
| case eWNI_PMC_EXIT_UAPSD_RSP: |
| case eWNI_PMC_ENTER_WOWL_RSP: |
| case eWNI_PMC_EXIT_WOWL_RSP: |
| //PMC |
| if (pMsg->bodyptr) |
| { |
| if(!pMac->psOffloadEnabled) |
| { |
| pmcMessageProcessor(hHal, pMsg->bodyptr); |
| } |
| else |
| { |
| pmcOffloadMessageProcessor(hHal, pMsg->bodyptr); |
| } |
| status = eHAL_STATUS_SUCCESS; |
| vos_mem_free(pMsg->bodyptr); |
| } else { |
| smsLog( pMac, LOGE, "Empty rsp message for PMC, nothing to process"); |
| } |
| 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: |
| //CCM |
| if (pMsg->bodyptr) |
| { |
| ccmCfgCnfMsgHandler(hHal, pMsg->bodyptr); |
| status = eHAL_STATUS_SUCCESS; |
| vos_mem_free(pMsg->bodyptr); |
| } else { |
| smsLog( pMac, LOGE, "Empty rsp message for CCM, nothing to process"); |
| } |
| break; |
| |
| case eWNI_SME_ADDTS_RSP: |
| case eWNI_SME_DELTS_RSP: |
| case eWNI_SME_DELTS_IND: |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| case eWNI_SME_FT_AGGR_QOS_RSP: |
| #endif |
| //QoS |
| if (pMsg->bodyptr) |
| { |
| #ifndef WLAN_MDM_CODE_REDUCTION_OPT |
| status = sme_QosMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| #endif |
| } else { |
| smsLog( pMac, LOGE, "Empty rsp message for QoS, nothing to process"); |
| } |
| break; |
| #if defined WLAN_FEATURE_VOWIFI |
| case eWNI_SME_NEIGHBOR_REPORT_IND: |
| case eWNI_SME_BEACON_REPORT_REQ_IND: |
| #if defined WLAN_VOWIFI_DEBUG |
| smsLog( pMac, LOGE, "Received RRM message. Message Id = %d", pMsg->type ); |
| #endif |
| if ( pMsg->bodyptr ) |
| { |
| status = sme_RrmMsgProcessor( pMac, pMsg->type, pMsg->bodyptr ); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty message for RRM, nothing to process"); |
| } |
| break; |
| #endif |
| |
| #ifdef FEATURE_OEM_DATA_SUPPORT |
| //Handle the eWNI_SME_OEM_DATA_RSP: |
| case eWNI_SME_OEM_DATA_RSP: |
| if(pMsg->bodyptr) |
| { |
| status = sme_HandleOemDataRsp(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty rsp message for oemData_ (eWNI_SME_OEM_DATA_RSP), nothing to process"); |
| } |
| smeProcessPendingQueue( pMac ); |
| break; |
| #endif |
| |
| case eWNI_SME_ADD_STA_SELF_RSP: |
| if(pMsg->bodyptr) |
| { |
| status = csrProcessAddStaSessionRsp(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ADD_STA_SELF_RSP), nothing to process"); |
| } |
| break; |
| case eWNI_SME_DEL_STA_SELF_RSP: |
| if(pMsg->bodyptr) |
| { |
| status = csrProcessDelStaSessionRsp(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_DEL_STA_SELF_RSP), nothing to process"); |
| } |
| break; |
| case eWNI_SME_REMAIN_ON_CHN_RSP: |
| if(pMsg->bodyptr) |
| { |
| status = sme_remainOnChnRsp(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RSP), nothing to process"); |
| } |
| break; |
| case eWNI_SME_REMAIN_ON_CHN_RDY_IND: |
| if(pMsg->bodyptr) |
| { |
| status = sme_remainOnChnReady(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RDY_IND), nothing to process"); |
| } |
| break; |
| |
| #ifdef FEATURE_WLAN_SCAN_PNO |
| case eWNI_SME_PREF_NETWORK_FOUND_IND: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if(pMsg->bodyptr) |
| { |
| status = sme_PreferredNetworkFoundInd((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_PREF_NETWORK_FOUND_IND), nothing to process"); |
| } |
| break; |
| #endif // FEATURE_WLAN_SCAN_PNO |
| |
| case eWNI_SME_TX_PER_HIT_IND: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMac->sme.pTxPerHitCallback) |
| { |
| pMac->sme.pTxPerHitCallback(pMac->sme.pTxPerHitCbContext); |
| } |
| break; |
| |
| case eWNI_SME_CHANGE_COUNTRY_CODE: |
| if(pMsg->bodyptr) |
| { |
| status = sme_HandleChangeCountryCode((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_CHANGE_COUNTRY_CODE), nothing to process"); |
| } |
| break; |
| |
| case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE: |
| if (pMsg->bodyptr) |
| { |
| status = sme_HandleGenericChangeCountryCode((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE), nothing to process"); |
| } |
| break; |
| |
| #ifdef WLAN_FEATURE_PACKET_FILTERING |
| case eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if(pMsg->bodyptr) |
| { |
| status = sme_PCFilterMatchCountResponseHandler((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for meas " |
| "(PACKET_COALESCING_FILTER_MATCH_COUNT_RSP), nothing to process"); |
| } |
| break; |
| #endif // WLAN_FEATURE_PACKET_FILTERING |
| case eWNI_SME_PRE_SWITCH_CHL_IND: |
| if(pMsg->bodyptr) |
| { |
| status = sme_HandlePreChannelSwitchInd(pMac,pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for meas " |
| "(eWNI_SME_PRE_SWITCH_CHL_IND), nothing to process"); |
| } |
| break; |
| case eWNI_SME_POST_SWITCH_CHL_IND: |
| { |
| status = sme_HandlePostChannelSwitchInd(pMac); |
| break; |
| } |
| |
| #ifdef WLAN_WAKEUP_EVENTS |
| case eWNI_SME_WAKE_REASON_IND: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if(pMsg->bodyptr) |
| { |
| status = sme_WakeReasonIndCallback((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_WAKE_REASON_IND), nothing to process"); |
| } |
| break; |
| #endif // WLAN_WAKEUP_EVENTS |
| |
| #ifdef FEATURE_WLAN_TDLS |
| /* |
| * command received from PE, SME tdls msg processor shall be called |
| * to process commands received 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 = tdlsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, |
| "Empty rsp message for TDLS, nothing to process"); |
| } |
| break; |
| } |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| case eWNI_SME_UNPROT_MGMT_FRM_IND: |
| if (pMsg->bodyptr) |
| { |
| sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process"); |
| } |
| break; |
| #endif |
| #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) |
| case eWNI_SME_TSM_IE_IND: |
| { |
| if (pMsg->bodyptr) |
| { |
| sme_TsmIeInd(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, |
| "Empty rsp message for (eWNI_SME_TSM_IE_IND), nothing to process"); |
| } |
| break; |
| } |
| #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ |
| #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP: |
| status = csrRoamOffloadScanRspHdlr((void *)pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| break; |
| #endif // WLAN_FEATURE_ROAM_SCAN_OFFLOAD |
| |
| #ifdef WLAN_FEATURE_GTK_OFFLOAD |
| case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMsg->bodyptr) |
| { |
| sme_ProcessGetGtkInfoRsp(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for (eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP), nothing to process"); |
| } |
| break ; |
| #endif |
| |
| #ifdef FEATURE_WLAN_LPHB |
| /* LPHB timeout indication arrived, send IND to client */ |
| case eWNI_SME_LPHB_IND: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMac->sme.pLphbIndCb) |
| { |
| pMac->sme.pLphbIndCb(pMac->hHdd, pMsg->bodyptr); |
| } |
| vos_mem_free(pMsg->bodyptr); |
| |
| break; |
| #endif /* FEATURE_WLAN_LPHB */ |
| |
| case eWNI_SME_IBSS_PEER_INFO_RSP: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMsg->bodyptr) |
| { |
| sme_IbssPeerInfoResponseHandleer(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, |
| "Empty rsp message for (eWNI_SME_IBSS_PEER_INFO_RSP)," |
| " nothing to process"); |
| } |
| break ; |
| |
| case eWNI_SME_READY_TO_SUSPEND_IND: |
| if (pMsg->bodyptr) |
| { |
| sme_ProcessReadyToSuspend(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message for (eWNI_SME_READY_TO_SUSPEND_IND), nothing to process"); |
| } |
| break ; |
| |
| #ifdef WLAN_FEATURE_EXTWOW_SUPPORT |
| case eWNI_SME_READY_TO_EXTWOW_IND: |
| if (pMsg->bodyptr) |
| { |
| sme_ProcessReadyToExtWoW(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog(pMac, LOGE, "Empty rsp message" |
| "for (eWNI_SME_READY_TO_EXTWOW_IND), nothing to process"); |
| } |
| break ; |
| #endif |
| |
| #ifdef FEATURE_WLAN_CH_AVOID |
| /* channel avoid message arrived, send IND to client */ |
| case eWNI_SME_CH_AVOID_IND: |
| MTRACE(vos_trace(VOS_MODULE_ID_SME, TRACE_CODE_SME_RX_WDA_MSG, |
| NO_SESSION, pMsg->type)); |
| if (pMac->sme.pChAvoidNotificationCb) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s: CH avoid notification", __func__); |
| pMac->sme.pChAvoidNotificationCb(pMac->hHdd, pMsg->bodyptr); |
| } |
| vos_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) |
| { |
| VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, |
| "%s: Auto shutdown notification", __func__); |
| pMac->sme.pAutoShutdownNotificationCb(); |
| } |
| vos_mem_free(pMsg->bodyptr); |
| break; |
| #endif |
| case eWNI_SME_DFS_RADAR_FOUND: |
| case eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND: |
| { |
| status = dfsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); |
| vos_mem_free( pMsg->bodyptr ); |
| } |
| break; |
| case eWNI_SME_EXT_CHANGE_CHANNEL_IND: |
| status = sme_extended_change_channel_ind(pMac, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| break; |
| case eWNI_SME_CHANNEL_CHANGE_RSP: |
| if (pMsg->bodyptr) |
| { |
| status = sme_ProcessChannelChangeResp(pMac, |
| pMsg->type, pMsg->bodyptr); |
| vos_mem_free( pMsg->bodyptr ); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, |
| "Empty rsp message for (eWNI_SME_CHANNEL_CHANGE_RSP)," |
| "nothing to process"); |
| } |
| break ; |
| |
| #ifdef WLAN_FEATURE_STATS_EXT |
| case eWNI_SME_STATS_EXT_EVENT: |
| if (pMsg->bodyptr) |
| { |
| status = sme_StatsExtEvent(hHal, pMsg->bodyptr); |
| vos_mem_free(pMsg->bodyptr); |
| } |
| else |
| { |
| smsLog( pMac, LOGE, |
| "Empty event message for eWNI_SME_STATS_EXT_EVENT, nothing to process"); |
| } |
| break; |
| #endif |
|
|