blob: a654ce9b5cbc5d86949b18758ccdb7bb6cac182f [file] [log] [blame]
/*
* Copyright (c) 2011-2017, 2019 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.
*/
/*
* This file lim ProcessMessageQueue.cc contains the code
* for processing LIM message Queue.
* Author: Chandra Modumudi
* Date: 02/11/02
* History:-
* Date Modified by Modification Information
* --------------------------------------------------------------------
*
*/
#include "palTypes.h"
#include "wniApi.h"
#include "wlan_qct_wdi_ds.h"
#include "wlan_qct_pal_packet.h"
#include "wlan_qct_wda.h"
#include "wniCfg.h"
#include "cfgApi.h"
#include "sirCommon.h"
#include "utilsApi.h"
#include "limTypes.h"
#include "limUtils.h"
#include "limAssocUtils.h"
#include "limPropExtsUtils.h"
#include "limAdmitControl.h"
#include "pmmApi.h"
#include "limIbssPeerMgmt.h"
#include "schApi.h"
#include "limSession.h"
#include "limSendMessages.h"
#if defined WLAN_FEATURE_VOWIFI
#include "rrmApi.h"
#endif
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "eseApi.h"
#endif
#if defined WLAN_FEATURE_VOWIFI_11R
#include "limFT.h"
#endif
#ifdef WMM_APSD
#include "wmmApsd.h"
#endif
#ifdef WLAN_FEATURE_RMC
#include "limRMC.h"
#endif
#include "vos_types.h"
#include "vos_packet.h"
#include "vos_memory.h"
#include "limSecurityUtils.h"
/* This value corresponds to 500 ms */
#define MAX_PROBEREQ_TIME 50
#ifdef WLAN_FEATURE_EXTSCAN
#define SIZE_OF_FIXED_PARAM 12
#endif
#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
#define IEEE80211_STATUS_SUCCESS 0
void limLogSessionStates(tpAniSirGlobal pMac);
#ifdef WLAN_FEATURE_SAE
/**
* lim_process_sae_msg() - Process SAE message
* @mac: Global MAC pointer
* @body: Buffer pointer
*
* Return: None
*/
static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
{
struct sir_sae_msg *sae_msg = body;
tpPESession session;
if (!sae_msg) {
limLog(mac, LOGE, FL("SAE msg is NULL"));
return;
}
session = pe_find_session_by_sme_session_id(mac, sae_msg->session_id);
if (session == NULL) {
limLog(mac, LOGE, FL("SAE:Unable to find session"));
return;
}
if (session->pePersona != VOS_STA_MODE) {
limLog(mac, LOGE, FL("SAE:Not supported in this mode %d"),
session->pePersona);
return;
}
limLog(mac, LOG1, FL("SAE:status %d limMlmState %d pePersona %d"),
sae_msg->sae_status, session->limMlmState,
session->pePersona);
switch (session->limMlmState) {
case eLIM_MLM_WT_SAE_AUTH_STATE:
/* SAE authentication is completed. Restore from auth state */
if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
limDeactivateAndChangeTimer(mac, eLIM_AUTH_SAE_TIMER);
/* success */
if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
limRestoreFromAuthState(mac, eSIR_SME_SUCCESS,
eSIR_MAC_SUCCESS_STATUS, session);
else
limRestoreFromAuthState(mac, eSIR_SME_AUTH_REFUSED,
eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
break;
default:
/* SAE msg is received in unexpected state */
limLog(mac, LOGE, FL("received SAE msg in state %X"),
session->limMlmState);
limPrintMlmState(mac, LOGE, session->limMlmState);
break;
}
}
#else
static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
{}
#endif
/** -------------------------------------------------------------
\fn defMsgDecision
\brief The function decides whether to defer a message or not in limProcessMessage function
\param tpAniSirGlobal pMac
\param tSirMsgQ limMsg
\param tSirMacTspecIE *ppInfo
\return none
-------------------------------------------------------------*/
tANI_U8 static
defMsgDecision(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
/* this function should not changed */
if(pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
{
// Defer processsing this message
if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
{
PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
limLogSessionStates(pMac);
limHandleDeferMsgError(pMac, limMsg);
}
return true;
}
//When defer is requested then defer all the messages except HAL responses.
if((!limIsSystemInScanState(pMac)) && (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) &&
!pMac->lim.gLimSystemInScanLearnMode)
{
if((limMsg->type != WDA_ADD_BSS_RSP) &&
(limMsg->type != WDA_DELETE_BSS_RSP) &&
(limMsg->type != WDA_ADD_STA_RSP) &&
(limMsg->type != WDA_ADD_STA_SELF_RSP) &&
(limMsg->type != WDA_DEL_STA_SELF_RSP) &&
(limMsg->type != WDA_DELETE_STA_RSP)&&
(limMsg->type != WDA_SET_BSSKEY_RSP)&&
(limMsg->type != WDA_SET_STAKEY_RSP)&&
(limMsg->type != WDA_SET_STA_BCASTKEY_RSP) &&
(limMsg->type != eWNI_SME_START_REQ) &&
(limMsg->type != WDA_AGGR_QOS_RSP) &&
(limMsg->type != WDA_REMOVE_BSSKEY_RSP) &&
(limMsg->type != WDA_REMOVE_STAKEY_RSP) &&
(limMsg->type != WDA_SET_MIMOPS_RSP)&&
(limMsg->type != WDA_ADDBA_RSP) &&
(limMsg->type != WDA_ENTER_BMPS_RSP) &&
(limMsg->type != WDA_EXIT_BMPS_RSP) &&
(limMsg->type != WDA_ENTER_IMPS_RSP) &&
(limMsg->type != WDA_EXIT_IMPS_RSP) &&
(limMsg->type != WDA_ENTER_UAPSD_RSP) &&
(limMsg->type != WDA_EXIT_UAPSD_RSP) &&
(limMsg->type != WDA_WOWL_ENTER_RSP) &&
(limMsg->type != WDA_WOWL_EXIT_RSP) &&
(limMsg->type != WDA_SWITCH_CHANNEL_RSP) &&
(limMsg->type != WDA_P2P_NOA_ATTR_IND) &&
(limMsg->type != WDA_P2P_NOA_START_IND) &&
#ifdef FEATURE_OEM_DATA_SUPPORT
(limMsg->type != WDA_START_OEM_DATA_RSP) &&
#endif
(limMsg->type != WDA_ADD_TS_RSP) &&
/* LIM won't process any defer queue commands if gLimAddtsSent is set to
TRUE. gLimAddtsSent will be set TRUE to while sending ADDTS REQ. Say,
when deferring is enabled, if SIR_LIM_ADDTS_RSP_TIMEOUT is posted
(because of not receiving ADDTS RSP) then this command will be added
to defer queue and as gLimAddtsSent is set TRUE LIM will never
process any commands from defer queue, including
SIR_LIM_ADDTS_RSP_TIMEOUT. Hence allowing SIR_LIM_ADDTS_RSP_TIMEOUT
command to be processed with deferring enabled, so that this will be
processed immediately and sets gLimAddtsSent to FALSE.
*/
(limMsg->type != SIR_LIM_ADDTS_RSP_TIMEOUT) &&
(limMsg->type != WDA_LOST_LINK_PARAMS_IND) &&
/* Allow processing of RX frames while awaiting reception of
ADD TS response over the air. This logic particularly handles the
case when host sends ADD BA request to FW after ADD TS request
is sent over the air and ADD TS response received over the air */
!(limMsg->type == SIR_BB_XPORT_MGMT_MSG && pMac->lim.gLimAddtsSent))
{
PELOG1(limLog(pMac, LOG1, FL("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode"),
limMsgStr(limMsg->type));)
// Defer processsing this message
if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
{
PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
limLogSessionStates(pMac);
limHandleDeferMsgError(pMac, limMsg);
}
return true;
}
}
return false;
}
/*
* Beacon Handling Cases:
* during scanning, when no session is active:
* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked.
* during scanning, when any session is active, but beacon/Pr does not belong to that session, psessionEntry will be null.
* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked.
* during scanning, when any session is active, and beacon/Pr belongs to one of the session, psessionEntry will not be null.
* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked.
* Not scanning, no session:
* there should not be any beacon coming, if coming, should be dropped.
* Not Scanning,
*/
static void
__limHandleBeacon(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tpPESession psessionEntry)
{
/* checking for global SME state...*/
tANI_U8 *pRxPacketInfo;
limGetBDfromRxPacket(pMac, pMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
//This function should not be called if beacon is received in scan state.
//So not doing any checks for the global state.
if(psessionEntry == NULL)
{
schBeaconProcess(pMac, pRxPacketInfo, NULL);
}
else if( (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) ||
(psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))
{
schBeaconProcess(pMac, pRxPacketInfo, psessionEntry);
}
else
limProcessBeaconFrame(pMac, pRxPacketInfo, psessionEntry);
return;
}
//Fucntion prototype
void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd);
/**
* limDeferMsg()
*
*FUNCTION:
* This function is called to defer the messages received
* during Learn mode
*
*LOGIC:
* NA
*
*ASSUMPTIONS:
* NA
*
*NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param pMsg of type tSirMsgQ - Pointer to the message structure
* @return None
*/
tANI_U32
limDeferMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
{
tANI_U32 retCode = TX_SUCCESS;
retCode = limWriteDeferredMsgQ(pMac, pMsg);
if (retCode == TX_SUCCESS)
{
limLog(pMac, LOG1,
FL("Deferred message(0x%X) limSmeState %d (prev sme state %d)"
" sysRole %d mlm state %d (prev mlm state %d)"),
pMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState,
pMac->lim.gLimPrevMlmState);
MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED));)
}
else
{
limLog(pMac, LOG1, FL("Dropped lim message (0x%X)"), pMsg->type);
MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED));)
}
return retCode;
} /*** end limDeferMsg() ***/
/**
* limHandleFramesInScanState()
*
*FUNCTION:
* This function is called to process 802.11 frames
* received by LIM in scan state.
*
*LOGIC:
* NA
*
*ASSUMPTIONS:
* NA
*
*NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param limMsg - Received message
* @param pRxPacketInfo - Pointer to Rx packet info structure
* @param deferMsg - Indicates whether the frame shall be deferred
* @return None
*/
static void
limHandleFramesInScanState(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pRxPacketInfo, tANI_U8 *deferMsg, tpPESession psessionEntry)
{
tSirMacFrameCtl fc;
tpSirMacMgmtHdr pHdr;
*deferMsg = false;
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
fc = pHdr->fc;
limLog( pMac, LOG2, FL("ProtVersion %d, Type %d, Subtype %d"),
fc.protVer, fc.type, fc.subType );
// defer all message in scan state except for Beacons and Probe Response
if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_BEACON))
{
if (psessionEntry == NULL)
limProcessBeaconFrameNoSession(pMac, pRxPacketInfo);
else
limProcessBeaconFrame(pMac, pRxPacketInfo,psessionEntry);
}
else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_RSP))
{
if (psessionEntry == NULL)
limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo);
else
limProcessProbeRspFrame(pMac, pRxPacketInfo,psessionEntry);
}
else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_REQ))
{
limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo, psessionEntry);
}
else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_ACTION))
{
if (psessionEntry != NULL)
limProcessActionFrame(pMac, pRxPacketInfo, psessionEntry);
else
limProcessActionFrameNoSession(pMac, pRxPacketInfo);
}
else
{
*deferMsg = true;
return;
}
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr);
return;
} /*** end limHandleFramesInScanState() ***/
/** ------------------------------------------------------------
\brief This function handles Unknown Unicast (A2 Index)
\ packets.
\param tpAniSirGlobal pMac Global Mac data structure
\param void *pRxPacketInfo Pointer to Buffer Descriptor
\return none
\
\ -------------------------------------------------------------- */
static void limHandleUnknownA2IndexFrames(tpAniSirGlobal pMac, void *pRxPacketInfo,tpPESession psessionEntry)
{
/* addr2 mismatch interrupt occurred this means previous
disassociation was not successful
In Volans pRxPacketInfo only contains pointer 48-bit address2 field */
/*Send disassociation message again*/
//Dinesh need one more arguement.
//limSendDisassocMgmtFrame(pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON,(tANI_U8 *) pRxPacketInfo);
//TODO: verify this
//This could be a public action frame.
if( psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE )
limProcessActionFrameNoSession(pMac, (tANI_U8 *) pRxPacketInfo);
#ifdef FEATURE_WLAN_TDLS
{
tpSirMacDataHdr3a pMacHdr;
pMacHdr = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo);
if (limIsGroupAddr(pMacHdr->addr2))
{
limLog(pMac, LOG1, FL("Ignoring A2 Invalid Packet received for MC/BC:"));
limPrintMacAddr(pMac, pMacHdr->addr2, LOG1);
return;
}
/* TDLS_hklee: move down here to reject Addr2 == Group (first checking above)
and also checking if SystemRole == STA */
if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
{
/* ADD handling of Public Action Frame */
LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
("limHandleUnknownA2IndexFrames: type=0x%x, subtype=0x%x"),pMacHdr->fc.type, pMacHdr->fc.subType));
switch (pMacHdr->fc.type)
{
case SIR_MAC_MGMT_FRAME:
{
switch (pMacHdr->fc.subType)
{
case SIR_MAC_MGMT_ACTION:
{
limProcessActionFrame(pMac, pRxPacketInfo, psessionEntry) ;
break ;
}
default:
{
break ;
}
}
}
default:
{
break ;
}
}
}
}
#endif
return;
}
/**
* limCheckMgmtRegisteredFrames()
*
*FUNCTION:
* This function is called to process to check if received frame match with
* any of the registered frame from HDD. If yes pass this frame to SME.
*
*LOGIC:
*
*ASSUMPTIONS:
*
*NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param *pBd Pointer to the received Buffer Descriptor+payload
* @param *psessionEntry Pointer to session on which packet is received
* @return None
*/
static tANI_BOOLEAN
limCheckMgmtRegisteredFrames(tpAniSirGlobal pMac, tANI_U8 *pBd,
tpPESession psessionEntry)
{
tSirMacFrameCtl fc;
tpSirMacMgmtHdr pHdr;
tANI_U8 *pBody;
tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL;
tANI_U16 frameType;
tANI_U16 framelen;
tANI_U8 type,subType;
tANI_BOOLEAN match = VOS_FALSE;
VOS_STATUS vosStatus;
pHdr = WDA_GET_RX_MAC_HEADER(pBd);
fc = pHdr->fc;
frameType = (fc.type << 2 ) | (fc.subType << 4);
pBody = WDA_GET_RX_MPDU_DATA(pBd);
framelen = WDA_GET_RX_PAYLOAD_LEN(pBd);
vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
(vos_list_node_t**)&pLimMgmtRegistration);
while(pLimMgmtRegistration != NULL)
{
type = (pLimMgmtRegistration->frameType >> 2) & 0x03;
subType = (pLimMgmtRegistration->frameType >> 4) & 0x0f;
if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME)
&& (subType == SIR_MAC_MGMT_RESERVED15) )
{
limLog( pMac, LOG3,
FL("rcvd frame match with SIR_MAC_MGMT_RESERVED15"));
match = VOS_TRUE;
break;
}
if (pLimMgmtRegistration->frameType == frameType)
{
if (pLimMgmtRegistration->matchLen > 0)
{
if (pLimMgmtRegistration->matchLen <= framelen)
{
if (vos_mem_compare(pLimMgmtRegistration->matchData,
pBody, pLimMgmtRegistration->matchLen))
{
/* found match! */
match = VOS_TRUE;
break;
}
}
}
else
{
/* found match! */
match = VOS_TRUE;
break;
}
}
vosStatus =
vos_list_peek_next ( &pMac->lim.gLimMgmtFrameRegistratinQueue,
(vos_list_node_t*) pLimMgmtRegistration,
(vos_list_node_t**) &pNext );
pLimMgmtRegistration = pNext;
pNext = NULL;
}
if (match)
{
limLog( pMac, LOG1,
FL("rcvd frame match with registered frame params"));
/* Indicate this to SME */
limSendSmeMgmtFrameInd( pMac, pLimMgmtRegistration->sessionId,
pBd, psessionEntry, WDA_GET_RX_RSSI_DB(pBd));
if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME)
&& (subType == SIR_MAC_MGMT_RESERVED15) )
{
// These packets needs to be processed by PE/SME as well as HDD.
// If it returns TRUE here, the packet is forwarded to HDD only.
match = VOS_FALSE;
}
}
return match;
} /*** end limCheckMgmtRegisteredFrames() ***/
#ifdef WLAN_FEATURE_EXTSCAN
void
limProcessEXTScanRealTimeData(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
{
tpSirMacMgmtHdr pHdr = NULL;
eHalStatus status;
void *pCallbackContext;
tANI_U8 rfBand = 0;
tANI_U8 rxChannelInBD = 0;
tSirMacFrameCtl fc;
tDot11fBeacon *pBeacon = NULL;
tDot11fProbeResponse *pProbeResponse = NULL;
tSirWifiFullScanResultEvent tEXTScanFullScanResult;
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
fc = pHdr->fc;
limLog(pMac, LOG2,
FL("Received EXTScan Real Time data with length=%d from "),
WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
limPrintMacAddr(pMac, pHdr->sa, LOG2);
vos_mem_set((tANI_U8 *) &tEXTScanFullScanResult,
sizeof(tSirWifiFullScanResultEvent), 0);
tEXTScanFullScanResult.ap.ts = vos_get_monotonic_boottime();
vos_mem_copy(&tEXTScanFullScanResult.ap.bssid,
pHdr->bssId, sizeof(tSirMacAddr));
limPrintMacAddr(pMac, pHdr->bssId, LOG2);
rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo);
rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo);
if ((!rfBand) || IS_5G_BAND(rfBand))
{
rxChannelInBD = limUnmapChannel(rxChannelInBD);
}
tEXTScanFullScanResult.ap.channel =
(tANI_U32)vos_chan_to_freq(rxChannelInBD);
tEXTScanFullScanResult.ap.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo);
if (fc.subType == SIR_MAC_MGMT_BEACON)
{
limLog( pMac, LOG2, FL("Beacon "));
pBeacon = vos_mem_malloc(sizeof(tDot11fBeacon));
if ( NULL == pBeacon ){
limLog(pMac, LOGE, FL("Failed to allocate memory\n") );
return;
}
vos_mem_set( ( tANI_U8* )pBeacon, sizeof(tDot11fBeacon), 0 );
// delegate to the framesc-generated code,
status = dot11fUnpackBeacon( pMac,
(tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo),
WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo), pBeacon );
if ( DOT11F_FAILED( status ) )
{
limLog(pMac, LOGE, FL("Failed to parse a Beacons"
"(%d)"), status);
vos_mem_free(pBeacon);
return;
}
if ( pBeacon->SSID.present )
{
vos_mem_copy(tEXTScanFullScanResult.ap.ssid,
pBeacon->SSID.ssid,
pBeacon->SSID.num_ssid);
}
//NULL Terminate the string.
tEXTScanFullScanResult.ap.ssid[pBeacon->SSID.num_ssid] = 0;
tEXTScanFullScanResult.ap.beaconPeriod =
pBeacon->BeaconInterval.interval;
tEXTScanFullScanResult.ap.capability =
*((tANI_U16 *)&pBeacon->Capabilities);
vos_mem_free(pBeacon);
}
else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP)
{
limLog( pMac, LOG2, FL("Probe rsp "));
pProbeResponse = vos_mem_malloc(sizeof(tDot11fProbeResponse));
if ( NULL == pProbeResponse ){
limLog(pMac, LOGE, FL("Failed to allocate memory\n") );
return;
}
vos_mem_set( ( tANI_U8* )pProbeResponse,
sizeof(tDot11fProbeResponse), 0);
//delegate to the framesc-generated code,
status = dot11fUnpackProbeResponse( pMac,
(tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo),
WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo), pProbeResponse );
if ( DOT11F_FAILED( status ) )
{
limLog(pMac, LOGE, FL("Failed to parse a Probe"
"Response (%d"), status);
vos_mem_free(pProbeResponse);
return;
}
if ( pProbeResponse->SSID.present )
{
vos_mem_copy(tEXTScanFullScanResult.ap.ssid,
pProbeResponse->SSID.ssid,
pProbeResponse->SSID.num_ssid);
}
//NULL Terminate the string.
tEXTScanFullScanResult.ap.ssid[pProbeResponse->SSID.num_ssid] = 0;
tEXTScanFullScanResult.ap.beaconPeriod =
pProbeResponse->BeaconInterval.interval;
tEXTScanFullScanResult.ap.capability =
*(((tANI_U16 *)&pProbeResponse->Capabilities));
vos_mem_free(pProbeResponse);
}
else
{
limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"),
fc.type, fc.subType);
VOS_ASSERT(0);
return;
}
tEXTScanFullScanResult.requestId = pMac->sme.extScanStartReqId;
tEXTScanFullScanResult.ieLength =
WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIZE_OF_FIXED_PARAM;
tEXTScanFullScanResult.ie =(tSirInformationElement *)
((tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo) + SIZE_OF_FIXED_PARAM);
pCallbackContext = pMac->sme.pEXTScanCallbackContext;
if(pMac->sme.pEXTScanIndCb)
{
pMac->sme.pEXTScanIndCb(pCallbackContext,
SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND,
(tANI_U8 *)&tEXTScanFullScanResult);
}
return;
} /*** end limProcessEXTScanRealTimeData() ***/
#endif /* WLAN_FEATURE_EXTSCAN */
#ifdef SAP_AUTH_OFFLOAD
/*
* lim_process_sap_offload_indication: function to process add sta/ del sta
* indication for SAP auth offload.
*
* @pMac: mac context
* @pRxPacketInfo: rx buffer
*
* This Function will go through buffer and if
* indication type is ADD_STA_IND, function will extract all data related to
* client and will call limAddSta
* and if indication type is DEL_STA_IND, function will call
* limSendSmeDisassocInd to do cleanup for station.
*
* Return : none
*/
static void lim_process_sap_offload_indication(tpAniSirGlobal pMac,
tANI_U8 *pRxPacketInfo)
{
int i = 0;
tSapOfldIndications *sap_offload_indication_rx_buf =
(tSapOfldIndications *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
tSapOfldInd *sap_offload_ind =
(tSapOfldInd*)sap_offload_indication_rx_buf->indications;
limLog( pMac, LOG1,
FL("Notify SME with Sap Offload ind and indication type is %d num_indication %d \n"),
sap_offload_ind->indType,
(tANI_U8) sap_offload_indication_rx_buf->num_indications);
for (i=1; i <= (tANI_U8)(sap_offload_indication_rx_buf->num_indications);
i++)
{
if (sap_offload_ind->indType == SAP_OFFLOAD_ADD_STA_IND)
{
tSapOfldAddStaIndMsg *add_sta;
limLog( pMac, LOG1,
FL("Indication type is SAP_OFFLOAD_ADD_STA_IND"));
add_sta = (tSapOfldAddStaIndMsg *)sap_offload_ind->indication;
lim_sap_offload_add_sta(pMac, add_sta);
if (sap_offload_indication_rx_buf->num_indications > 1)
sap_offload_ind =
(tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
sizeof(tSapOfldAddStaIndMsg) - sizeof(tANI_U8)+
add_sta->data_len + sizeof(tANI_U32));
}
else if (sap_offload_ind->indType == SAP_OFFLOAD_DEL_STA_IND)
{
tSapOfldDelStaIndMsg *del_sta;
limLog( pMac, LOG1,
FL("Indication type is SAP_OFFLOAD_DEL_STA_IND"));
del_sta = (tSapOfldDelStaIndMsg *)sap_offload_ind->indication;
lim_sap_offload_del_sta(pMac, del_sta);
sap_offload_ind = (tSapOfldInd *)((tANI_U8 *)sap_offload_ind +
sizeof(tSapOfldDelStaIndMsg) + sizeof(tANI_U32));
}
else
{
limLog(pMac, LOGE, FL("No Valid indication for connected station"));
}
}
}
#endif
/**
* limHandle80211Frames()
*
*FUNCTION:
* This function is called to process 802.11 frames
* received by LIM.
*
*LOGIC:
* NA
*
*ASSUMPTIONS:
* NA
*
*NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @param pMsg of type tSirMsgQ - Pointer to the message structure
* @return None
*/
static void
limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg)
{
tANI_U8 *pRxPacketInfo = NULL;
tSirMacFrameCtl fc;
tpSirMacMgmtHdr pHdr=NULL;
tpPESession psessionEntry=NULL;
tANI_U8 sessionId;
tAniBool isFrmFt = FALSE;
tANI_U16 fcOffset = WLANHAL_RX_BD_HEADER_SIZE;
tANI_S8 pe_sessionid = -1;
*pDeferMsg= false;
limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
#ifdef SAP_AUTH_OFFLOAD
if ((WDA_GET_SAP_AUTHOFFLOADIND(pRxPacketInfo) == 1) &&
pMac->sap_auth_offload)
{
lim_process_sap_offload_indication(pMac, pRxPacketInfo);
goto end;
}
#endif
#ifdef WLAN_FEATURE_EXTSCAN
if ( WDA_GET_EXTSCANFULLSCANRESIND(pRxPacketInfo))
{
limLog( pMac, LOG2, FL("Notify EXTSCAN scan results to the HDD"));
limProcessEXTScanRealTimeData(pMac, pRxPacketInfo);
goto end;
}
#endif //WLAN_FEATURE_EXTSCAN
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
isFrmFt = WDA_GET_RX_FT_DONE(pRxPacketInfo);
fcOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(pRxPacketInfo);
fc = pHdr->fc;
#ifdef WLAN_DUMP_MGMTFRAMES
limLog( pMac, LOGE, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
fc.protVer, fc.type, fc.subType,
WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, pHdr,
WDA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo));
#endif
if ((fc.type == SIR_MAC_MGMT_FRAME) &&
(fc.subType != SIR_MAC_MGMT_BEACON))
{
limLog(pMac, LOG1, FL("RX MGMT - Type %hu, SubType %hu,"
"Seq.no %d, Source mac-addr "
MAC_ADDRESS_STR), fc.type, fc.subType,
((pHdr->seqControl.seqNumHi << 4) |
(pHdr->seqControl.seqNumLo)),
MAC_ADDR_ARRAY(pHdr->sa));
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
{
if (vos_check_monitor_state())
{
limLog( pMac, LOGW, FL("Ignore raom candidate when roam started"));
goto end;
}
limLog( pMac, LOGW, FL("Notify SME with candidate ind"));
if (WDA_IF_PER_ROAMCANDIDATEIND(pRxPacketInfo) &&
IS_FEATURE_SUPPORTED_BY_FW(PER_BASED_ROAMING) &&
pMac->roam.configParam.isPERRoamEnabled)
{
tSirPerRoamScanResult *candidateChanInfo =
(tSirPerRoamScanResult *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
int chanInfoLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)
- sizeof(tANI_U32);
/* Translate network buffer into system buffer */
vos_buff_to_hl_buff((v_U8_t *)candidateChanInfo,
WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo));
/* Max candidates allowed */
if (candidateChanInfo->candidateCount >
SIR_PER_ROAM_MAX_CANDIDATE_CNT)
{
limLog(pMac, LOGE,
FL("Got maximum candidates as %d, setting count as %d"),
candidateChanInfo->candidateCount,
SIR_PER_ROAM_MAX_CANDIDATE_CNT);
candidateChanInfo->candidateCount =
SIR_PER_ROAM_MAX_CANDIDATE_CNT;
}
vos_mem_set(&pMac->candidateChannelInfo,
sizeof(tSirCandidateChanInfo) *
SIR_PER_ROAM_MAX_CANDIDATE_CNT, 0);
vos_mem_copy(&pMac->candidateChannelInfo,
candidateChanInfo->channelInfo,
(sizeof(tSirCandidateChanInfo) *
SIR_PER_ROAM_MAX_CANDIDATE_CNT) < chanInfoLen ?
(sizeof(tSirCandidateChanInfo) *
SIR_PER_ROAM_MAX_CANDIDATE_CNT):
chanInfoLen);
limLog(pMac, LOG1,
FL("PER based Roam candidates %d"),
candidateChanInfo->candidateCount);
pMac->PERroamCandidatesCnt = candidateChanInfo->candidateCount;
} else
{
/* Normal RSSI based roaming */
pMac->PERroamCandidatesCnt = 0;
}
pe_sessionid = limGetInfraSessionId(pMac);
if (pe_sessionid != -1) {
psessionEntry = peFindSessionBySessionId(pMac, pe_sessionid);
if (psessionEntry != NULL)
{
if ((psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
(psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE))
{
limLog(pMac, LOG1,
FL("Drop candidate ind as deauth/disassoc in progress"));
goto end;
}
}
}
else
limLog(pMac, LOGE,
FL("session id doesn't exist for infra"));
//send a session 0 for now - TBD
limSendSmeCandidateFoundInd(pMac, 0);
goto end;
}
if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
{
if (fc.subType == SIR_MAC_MGMT_BEACON)
{
limLog( pMac, LOG2, FL("Save this beacon in LFR cache"));
__limHandleBeacon(pMac, limMsg, NULL);
}
else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP)
{
limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache"));
limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo);
}
else
{
limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"),
fc.type, fc.subType);
}
goto end;
}
#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#ifdef FEATURE_WLAN_ESE
if (fc.type == SIR_MAC_DATA_FRAME && isFrmFt)
{
#if 0 // Ese TBD Need to PORT
tpSirMacDot3Hdr pDataFrmHdr;
pDataFrmHdr = (tpSirMacDot3Hdr)((tANI_U8 *)pBD+ WLANHAL_RX_BD_GET_MPDU_H_OFFSET(pBD));
if((psessionEntry = peFindSessionByBssid(pMac,pDataFrmHdr->sa,&sessionId))== NULL)
{
limLog( pMac, LOGE, FL("Session not found for Frm type %d, subtype %d, SA: "), fc.type, fc.subType);
limPrintMacAddr(pMac, pDataFrmHdr->sa, LOGE);
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pBD, limMsg->bodyptr);
return;
}
if (!psessionEntry->isESEconnection)
{
limLog( pMac, LOGE, FL("LIM received Type %d, Subtype %d in Non ESE connection"),
fc.type, fc.subType);
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pBD, limMsg->bodyptr);
return;
}
limLog( pMac, LOGE, FL("Processing IAPP Frm from SA:"));
limPrintMacAddr(pMac, pDataFrmHdr->sa, LOGE);
#else
printk("%s: Need to port handling of IAPP frames to PRIMA for ESE", __func__);
#endif
} else
#endif
if ((fc.type == SIR_MAC_MGMT_FRAME) &&
(fc.subType == SIR_MAC_MGMT_PROBE_RSP) &&
pMac->lim.isSpoofingEnabled)
{
limLog( pMac, LOG2, FL("Probe Rsp recieved with DA: "MAC_ADDRESS_STR
" and selfMac Addr:"MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da),
MAC_ADDR_ARRAY(pMac->lim.gSelfMacAddr));
if (VOS_TRUE == vos_mem_compare((v_VOID_t*) pHdr->da,
(v_VOID_t*) pMac->lim.spoofMacAddr, VOS_MAC_ADDRESS_LEN))
{
vos_mem_copy(pHdr->da, pMac->lim.gSelfMacAddr, VOS_MAC_ADDRESS_LEN);
}
}
/* Added For BT-AMP Support */
if((psessionEntry = peFindSessionByBssid(pMac,pHdr->bssId,&sessionId))== NULL)
{
#ifdef WLAN_FEATURE_VOWIFI_11R
if (fc.subType == SIR_MAC_MGMT_AUTH)
{
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
limLog( pMac, LOG1, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
limPrintMacAddr(pMac, pHdr->bssId, LOG1);
#endif
if (limProcessAuthFrameNoSession(pMac, pRxPacketInfo, limMsg->bodyptr) == eSIR_SUCCESS)
{
goto end;
}
}
#endif
if((fc.subType != SIR_MAC_MGMT_PROBE_RSP )&&
(fc.subType != SIR_MAC_MGMT_BEACON)&&
(fc.subType != SIR_MAC_MGMT_PROBE_REQ)
&& (fc.subType != SIR_MAC_MGMT_ACTION ) //Public action frame can be received from non-associated stations.
)
{
if((psessionEntry = peFindSessionByPeerSta(pMac,pHdr->sa,&sessionId))== NULL)
{
limLog(pMac, LOG1, FL("session does not exist for given bssId"));
goto end;
}
else
limLog(pMac,LOG1,"SessionId:%d Session Exist for given Bssid",
psessionEntry->peSessionId);
}
// For p2p resp frames search for valid session with DA as
// BSSID will be SA and session will be present with DA only
if(fc.subType == SIR_MAC_MGMT_ACTION )
{
psessionEntry = peFindSessionByBssid(pMac,pHdr->da,&sessionId);
}
}
/* Check if frame is registered by HDD */
if(limCheckMgmtRegisteredFrames(pMac, pRxPacketInfo, psessionEntry))
{
limLog( pMac, LOG1, FL("Received frame is passed to SME"));
goto end;
}
if (fc.protVer != SIR_MAC_PROTOCOL_VERSION)
{ // Received Frame with non-zero Protocol Version
limLog(pMac, LOGE, FL("Unexpected frame with protVersion %d received"),
fc.protVer);
#ifdef WLAN_DEBUG
pMac->lim.numProtErr++;
#endif
goto end;
}
if (!pMac->fScanOffload)
{
if (limIsSystemInScanState(pMac))
{
limHandleFramesInScanState(pMac, limMsg, pRxPacketInfo, pDeferMsg, psessionEntry);
return;
}
}
/* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */
#if 0
if (psessionEntry->limSystemRole == eLIM_UNKNOWN_ROLE) {
limLog( pMac, LOGW, FL( "gLimSystemRole is %d. Exiting..." ),psessionEntry->limSystemRole );
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr);
#ifdef WLAN_DEBUG
pMac->lim.numProtErr++;
#endif
return;
}
#endif //HACK to continue scanning
#ifdef WLAN_DEBUG
pMac->lim.numMAC[fc.type][fc.subType]++;
#endif
switch (fc.type)
{
case SIR_MAC_MGMT_FRAME:
{
#if 0 //TBD-RAJESH fix this
if (limIsReassocInProgress( pMac,psessionEntry) && (fc.subType != SIR_MAC_MGMT_DISASSOC) &&
(fc.subType != SIR_MAC_MGMT_DEAUTH) && (fc.subType != SIR_MAC_MGMT_REASSOC_RSP))
{
limLog(pMac, LOGE, FL("Frame with Type - %d, Subtype - %d received in ReAssoc Wait state, dropping..."),
fc.type, fc.subType);
return;
}
#endif //HACK to continue scanning
// Received Management frame
switch (fc.subType)
{
case SIR_MAC_MGMT_ASSOC_REQ:
// Make sure the role supports Association
if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
|| (psessionEntry->limSystemRole == eLIM_AP_ROLE)
)
limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_ASSOC, psessionEntry);
else
{
// Unwanted messages - Log error
limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type);
limPrintMsgName(pMac, LOGE, limMsg->type);
}
break;
case SIR_MAC_MGMT_ASSOC_RSP:
limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_ASSOC,psessionEntry);
break;
case SIR_MAC_MGMT_REASSOC_REQ:
// Make sure the role supports Reassociation
if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
|| (psessionEntry->limSystemRole == eLIM_AP_ROLE)
){
limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_REASSOC, psessionEntry);
}
else
{
// Unwanted messages - Log error
limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type);
limPrintMsgName(pMac, LOGE, limMsg->type);
}
break;
case SIR_MAC_MGMT_REASSOC_RSP:
limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_REASSOC,psessionEntry);
break;
case SIR_MAC_MGMT_PROBE_REQ:
limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo,psessionEntry);
break;
case SIR_MAC_MGMT_PROBE_RSP:
if(psessionEntry == NULL)
limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo);
else
limProcessProbeRspFrame(pMac, pRxPacketInfo, psessionEntry);
break;
case SIR_MAC_MGMT_BEACON:
__limHandleBeacon(pMac, limMsg,psessionEntry);
break;
case SIR_MAC_MGMT_DISASSOC:
limProcessDisassocFrame(pMac, pRxPacketInfo,psessionEntry);
break;
case SIR_MAC_MGMT_AUTH:
limProcessAuthFrame(pMac, pRxPacketInfo,psessionEntry);
break;
case SIR_MAC_MGMT_DEAUTH:
limProcessDeauthFrame(pMac, pRxPacketInfo,psessionEntry);
break;
case SIR_MAC_MGMT_ACTION:
if(psessionEntry == NULL)
limProcessActionFrameNoSession(pMac, pRxPacketInfo);
else
{
if (WDA_GET_RX_UNKNOWN_UCAST(pRxPacketInfo))
limHandleUnknownA2IndexFrames(pMac, pRxPacketInfo,psessionEntry);
else
limProcessActionFrame(pMac, pRxPacketInfo,psessionEntry);
}
break;
default:
// Received Management frame of 'reserved' subtype
break;
} // switch (fc.subType)
}
break;
case SIR_MAC_DATA_FRAME:
{
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
/* We accept data frame (IAPP frame) only if Session is
* present and ese connection is established on that
* session
*/
if (psessionEntry && psessionEntry->isESEconnection) {
limProcessIappFrame(pMac, pRxPacketInfo, psessionEntry);
}
#endif
}
break;
default:
// Received frame of type 'reserved'
break;
} // switch (fc.type)
end:
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr) ;
return;
} /*** end limHandle80211Frames() ***/
/**
* limSendStopScanOffloadReq()
*
*FUNCTION:
* This function will be called to abort the ongoing offloaded scan
* request.
*
*
*NOTE:
*
* @param pMac Pointer to Global MAC structure
* @return eHAL_STATUS_SUCCESS or eHAL_STATUS_FAILURE
*/
eHalStatus limSendStopScanOffloadReq(tpAniSirGlobal pMac, tANI_U8 SessionId)
{
tSirMsgQ msg;
tSirRetStatus rc = eSIR_SUCCESS;
tAbortScanParams *pAbortScanParams;
pAbortScanParams = vos_mem_malloc(sizeof(tAbortScanParams));
if (NULL == pAbortScanParams)
{
limLog(pMac, LOGP, FL("Memory allocation failed for AbortScanParams"));
return eHAL_STATUS_FAILURE;
}
pAbortScanParams->SessionId = SessionId;
msg.type = WDA_STOP_SCAN_OFFLOAD_REQ;
msg.bodyptr = pAbortScanParams;
msg.bodyval = 0;
rc = wdaPostCtrlMsg(pMac, &msg);
if (rc != eSIR_SUCCESS)
{
limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure"));
vos_mem_free(pAbortScanParams);
return eHAL_STATUS_FAILURE;
}
limLog(pMac, LOG1, FL("Abort ongoing offload scan."));
return eHAL_STATUS_SUCCESS;
}
/**
* limProcessAbortScanInd()
*
*FUNCTION:
* This function is called from HDD to abort the scan which is presently being run
*
*
*NOTE:
*
* @param pMac Pointer to Global MAC structure
* @param *pMsgBuf A pointer to the SME message buffer
* @return None
*/
void
limProcessAbortScanInd(tpAniSirGlobal pMac, tANI_U8 SessionId)
{
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, NULL, 0, 0);
#endif //FEATURE_WLAN_DIAG_SUPPORT
/* Deactivate the gLimBackgroundScanTimer as part of the abort scan.
* SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication
* to start the background scan again
*/
limLog(pMac, LOG1, FL("Processing AbortScan Ind"));
limAbortBackgroundScan(pMac);
if (pMac->fScanOffload)
{
/* send stop scan cmd to fw if scan offload is enabled. */
limSendStopScanOffloadReq(pMac, SessionId);
}
else
{
/* Abort the scan if its running, else just return */
if(limIsSystemInScanState(pMac))
{
if( (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) ||
(eLIM_HAL_START_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) ||
(eLIM_HAL_END_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) ||
(eLIM_HAL_FINISH_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) )
{
//Simply signal we need to abort
limLog( pMac, LOGW, FL(" waiting for HAL, simply signal abort gLimHalScanState = %d"), pMac->lim.gLimHalScanState );
pMac->lim.abortScan = 1;
}
else
{
//Force abort
limLog( pMac, LOGW, FL(" Force aborting scan") );
pMac->lim.abortScan = 0;
limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
//Set the resume channel to Any valid channel (invalid).
//This will instruct HAL to set it to any previous valid channel.
peSetResumeChannel(pMac, 0, 0);
limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE);
}
}
}
return;
}
/**
* limMessageProcessor
*
*FUNCTION:
* Wrapper function for limProcessMessages when handling messages received by LIM.
* Could either defer messages or process them.
* @param pMac Pointer to Global MAC structure
* @param limMsg Received LIM message
* @return None
*/
void limMessageProcessor(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
if (eLIM_MLM_OFFLINE_STATE == pMac->lim.gLimMlmState)
{
peFreeMsg(pMac, limMsg);
return;
}
if (!defMsgDecision(pMac, limMsg))
{
limProcessMessages(pMac, limMsg);
// process deferred message queue if allowed
{
if ( (! (pMac->lim.gLimAddtsSent))
&&
(! (limIsSystemInScanState(pMac)))
)
{
if (true == GET_LIM_PROCESS_DEFD_MESGS(pMac))
limProcessDeferredMessageQueue(pMac);
}
}
}
}
#ifdef FEATURE_OEM_DATA_SUPPORT
void limOemDataRspHandleResumeLinkRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* mlmOemDataRsp)
{
if(status != eHAL_STATUS_SUCCESS)
{
limLog(pMac, LOGE, FL("OEM Data Rsp failed to get the response for resume link"));
}
if(NULL != pMac->lim.gpLimMlmOemDataReq)
{
vos_mem_free(pMac->lim.gpLimMlmOemDataReq);
pMac->lim.gpLimMlmOemDataReq = NULL;
}
//"Failure" status doesn't mean that Oem Data Rsp did not happen
//and hence we need to respond to upper layers. Only Resume link is failed, but
//we got the oem data response already.
//Post the meessage to MLM
limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)(mlmOemDataRsp));
return;
}
void limProcessOemDataRsp(tpAniSirGlobal pMac, tANI_U32* body)
{
tpLimMlmOemDataRsp mlmOemDataRsp = NULL;
tpStartOemDataRsp oemDataRsp = NULL;
//Process all the messages for the lim queue
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
oemDataRsp = (tpStartOemDataRsp)(body);
mlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp));
if ( NULL == mlmOemDataRsp )
{
limLog(pMac, LOGP, FL("could not allocate memory for mlmOemDataRsp"));
return;
}
//copy the memory into tLimMlmOemDataRsp and free the tStartOemDataRsp
//the structures tStartOemDataRsp and tLimMlmOemDataRsp have the same structure
vos_mem_copy((void*)(mlmOemDataRsp), (void*)(oemDataRsp),
sizeof(tLimMlmOemDataRsp));
//Now free the incoming memory
vos_mem_free(oemDataRsp);
limResumeLink(pMac, limOemDataRspHandleResumeLinkRsp, (tANI_U32*)mlmOemDataRsp);
return;
}
#endif
static tANI_BOOLEAN limAgeOutProbeReq( tpAniSirGlobal pMac, tpSirMsgQ limMsg,
vos_pkt_t *pVosPkt )
{
tANI_U8 *pRxPacketInfo = NULL;
tSirMacFrameCtl fc;
tpSirMacMgmtHdr pHdr=NULL;
tANI_BOOLEAN match = VOS_FALSE;
limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
fc = pHdr->fc;
if ( fc.subType == SIR_MAC_MGMT_PROBE_REQ )
{
if( vos_timer_get_system_ticks() - pVosPkt->timestamp >= MAX_PROBEREQ_TIME )
{
// drop packet
limLog(pMac, LOGE,
FL("Dropping Aged Out probe requests. Peer MAC is "MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(pHdr->sa));
vos_pkt_return_packet(pVosPkt);
match = VOS_TRUE;
}
}
return match;
}
/**
* limProcessMessages
*
*FUNCTION:
* This function is called by limProcessMessageQueue function. This
* function processes messages received by LIM.
*
*LOGIC:
* Depending on the message type, corresponding function will be
* called, for example limProcessSmeMessages() will be called to
* process SME messages received from HDD/Upper layer software module.
*
*ASSUMPTIONS:
* NA
*
*NOTE:
* NA
*
* @param pMac Pointer to Global MAC structure
* @param limMsg Received LIM message
* @return None
*/
void
limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
{
tANI_U8 deferMsg = false;
tLinkStateParams *linkStateParams;
#if defined WLAN_FEATURE_VOWIFI_11R
tpPESession pSession;
#endif
#if defined(ANI_DVT_DEBUG)
tSirMsgQ msgQ;
#endif
if(pMac->gDriverType == eDRIVER_TYPE_MFG)
{
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
return;
}
#ifdef WLAN_DEBUG
pMac->lim.numTot++;
#endif
PELOG3(limLog(pMac, LOG3, FL("rcvd msgType = %s, sme state = %s, mlm state = %s"),
limMsgStr(limMsg->type), limSmeStateStr(pMac->lim.gLimSmeState),
limMlmStateStr(pMac->lim.gLimMlmState));)
/*
* MTRACE logs not captured for events received from SME
* SME enums (eWNI_SME_START_REQ) starts with 0x16xx.
* Compare received SME events with SIR_SME_MODULE_ID
*/
if (SIR_SME_MODULE_ID == (tANI_U8)MAC_TRACE_GET_MODULE_ID(limMsg->type))
{
MTRACE(macTrace(pMac, TRACE_CODE_RX_SME_MSG, NO_SESSION, limMsg->type));
}
else
{
/* Omitting below message types as these are too frequent and when crash
* happens we loose critical trace logs if these are also logged
*/
if (limMsg->type != SIR_LIM_MAX_CHANNEL_TIMEOUT &&
limMsg->type != SIR_LIM_MIN_CHANNEL_TIMEOUT &&
limMsg->type != SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT &&
limMsg->type != SIR_CFG_PARAM_UPDATE_IND &&
limMsg->type != SIR_BB_XPORT_MGMT_MSG)
MTRACE(macTraceMsgRx(pMac, NO_SESSION,
LIM_TRACE_MAKE_RXMSG(limMsg->type, LIM_MSG_PROCESSED));)
}
switch (limMsg->type)
{
case SIR_LIM_UPDATE_BEACON:
limUpdateBeacon(pMac);
break;
case SIR_CFG_PARAM_UPDATE_IND:
/// CFG parameter updated
if (limIsSystemInScanState(pMac))
{
// System is in DFS (Learn) mode
// Defer processsing this message
if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
{
if(!(pMac->lim.deferredMsgCnt & 0xF))
{
PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
}
limLogSessionStates(pMac);
limPrintMsgName(pMac, LOGE, limMsg->type);
}
}
else
{
limHandleCFGparamUpdate(pMac, limMsg->bodyval);
}
break;
case WDA_INIT_SCAN_RSP:
limProcessInitScanRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case WDA_START_SCAN_RSP:
limProcessStartScanRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case WDA_END_SCAN_RSP:
limProcessEndScanRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case WDA_FINISH_SCAN_RSP:
limProcessFinishScanRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#ifdef FEATURE_OEM_DATA_SUPPORT
case WDA_START_OEM_DATA_RSP:
limProcessOemDataRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#endif
case WDA_SWITCH_CHANNEL_RSP:
limProcessSwitchChannelRsp(pMac, limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#ifdef ANI_SIR_IBSS_PEER_CACHING
case WDA_IBSS_STA_ADD:
limIbssStaAdd(pMac, limMsg->bodyptr);
break;
#endif
case SIR_BB_XPORT_MGMT_MSG:
// These messages are from Peer MAC entity.
#ifdef WLAN_DEBUG
pMac->lim.numBbt++;
#endif
{
v_U16_t pktLen = 0;
vos_pkt_t *pVosPkt;
VOS_STATUS vosStatus;
tSirMsgQ limMsgNew;
/* The original limMsg which we were deferring have the
* bodyPointer point to 'BD' instead of 'Vos pkt'. If we don't make a copy
* of limMsg, then vos_pkt_peek_data will overwrite the limMsg->bodyPointer.
* and next time when we try to process the msg, we will try to use 'BD' as
* 'Vos Pkt' which will cause a crash
*/
vos_mem_copy((tANI_U8*)&limMsgNew, (tANI_U8*)limMsg,
sizeof(tSirMsgQ));
pVosPkt = (vos_pkt_t *)limMsgNew.bodyptr;
vos_pkt_get_packet_length(pVosPkt, &pktLen);
vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&limMsgNew.bodyptr, VOS_FALSE );
if( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
limDecrementPendingMgmtCount(pMac);
vos_pkt_return_packet(pVosPkt);
break;
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (WDA_GET_ROAMCANDIDATEIND(limMsgNew.bodyptr))
limLog(pMac, LOG1, FL("roamCandidateInd %d"),
WDA_GET_ROAMCANDIDATEIND(limMsgNew.bodyptr));
if (WDA_GET_OFFLOADSCANLEARN(limMsgNew.bodyptr))
limLog(pMac, LOG1, FL("offloadScanLearn %d"),
WDA_GET_OFFLOADSCANLEARN(limMsgNew.bodyptr));
#endif
/*
* putting a check for age out probe request frames
* such that any probe req more than 0.5 sec old can directly
* be dropped. With this, there won't be blocking of MC thread.
*/
if( limAgeOutProbeReq ( pMac, &limMsgNew, pVosPkt ))
{
limDecrementPendingMgmtCount(pMac);
break;
}
limHandle80211Frames(pMac, &limMsgNew, &deferMsg);
if ( deferMsg == true )
{
limLog(pMac, LOG2, FL("Defer message type=%X "),
limMsg->type);
if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
{
PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
limLogSessionStates(pMac);
limPrintMsgName(pMac, LOGE, limMsg->type);
limDecrementPendingMgmtCount(pMac);
vos_pkt_return_packet(pVosPkt);
}
}
else
{
/* PE is not deferring this 802.11 frame so we need to call vos_pkt_return.
* Asumption here is when Rx mgmt frame processing is done,
* voss packet could be freed here.
*/
limDecrementPendingMgmtCount(pMac);
vos_pkt_return_packet(pVosPkt);
}
}
break;
case eWNI_SME_SCAN_REQ:
case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
case eWNI_SME_DISASSOC_REQ:
case eWNI_SME_DEAUTH_REQ:
case eWNI_SME_GET_SCANNED_CHANNEL_REQ:
#ifdef FEATURE_OEM_DATA_SUPPORT
case eWNI_SME_OEM_DATA_REQ:
#endif
#ifdef FEATURE_WLAN_TDLS
case eWNI_SME_TDLS_SEND_MGMT_REQ:
case eWNI_SME_TDLS_ADD_STA_REQ:
case eWNI_SME_TDLS_DEL_STA_REQ:
case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
// tdlsoffchan
case eWNI_SME_TDLS_CHANNEL_SWITCH_REQ:
#endif
case eWNI_SME_RESET_AP_CAPS_CHANGED:
// These messages are from HDD
limProcessNormalHddMsg(pMac, limMsg, true); //need to response to hdd
break;
case eWNI_SME_SCAN_ABORT_IND:
{
tANI_U8 *pSessionId = (tANI_U8 *)limMsg->bodyptr;
limProcessAbortScanInd(pMac, *pSessionId);
vos_mem_free((v_VOID_t *)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
}
case eWNI_SME_START_REQ:
case eWNI_SME_SYS_READY_IND:
#ifndef WNI_ASKEY_NON_SUPPORT_FEATURE
case eWNI_SME_JOIN_REQ:
#endif
case eWNI_SME_AUTH_REQ:
case eWNI_SME_REASSOC_REQ:
case eWNI_SME_START_BSS_REQ:
case eWNI_SME_STOP_BSS_REQ:
case eWNI_SME_SWITCH_CHL_REQ:
case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ:
case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ:
case eWNI_SME_SETCONTEXT_REQ:
case eWNI_SME_REMOVEKEY_REQ:
#ifndef WNI_ASKEY_NON_SUPPORT_FEATURE
case eWNI_SME_PROMISCUOUS_MODE_REQ:
#endif
case eWNI_SME_DISASSOC_CNF:
case eWNI_SME_DEAUTH_CNF:
case eWNI_SME_ASSOC_CNF:
case eWNI_SME_REASSOC_CNF:
case eWNI_SME_ADDTS_REQ:
case eWNI_SME_DELTS_REQ:
case eWNI_SME_DEL_BA_PEER_IND:
case eWNI_SME_SET_TX_POWER_REQ:
case eWNI_SME_GET_TX_POWER_REQ:
case eWNI_SME_GET_NOISE_REQ:
case eWNI_SME_GET_ASSOC_STAS_REQ:
case eWNI_SME_TKIP_CNTR_MEAS_REQ:
case eWNI_SME_UPDATE_APWPSIE_REQ:
case eWNI_SME_HIDE_SSID_REQ:
case eWNI_SME_GET_WPSPBC_SESSION_REQ:
case eWNI_SME_SET_APWPARSNIEs_REQ:
case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
#if defined WLAN_FEATURE_VOWIFI
case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
#endif
#if defined FEATURE_WLAN_ESE
case eWNI_SME_ESE_ADJACENT_AP_REPORT:
#endif
#ifdef WLAN_FEATURE_VOWIFI_11R
case eWNI_SME_FT_UPDATE_KEY:
case eWNI_SME_FT_PRE_AUTH_REQ:
case eWNI_SME_FT_AGGR_QOS_REQ:
#endif
#ifdef WLAN_FEATURE_LFR_MBB
case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ:
#endif
case eWNI_SME_ADD_STA_SELF_REQ:
case eWNI_SME_DEL_STA_SELF_REQ:
case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
case eWNI_SME_UPDATE_NOA:
case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
case eWNI_SME_STA_STAT_REQ:
case eWNI_SME_AGGR_STAT_REQ:
case eWNI_SME_GLOBAL_STAT_REQ:
case eWNI_SME_STAT_SUMM_REQ:
case eWNI_SME_GET_STATISTICS_REQ:
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
case eWNI_SME_GET_ROAM_RSSI_REQ:
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
case eWNI_SME_GET_TSM_STATS_REQ:
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
case eWNI_SME_MAC_SPOOF_ADDR_IND:
case eWNI_SME_REGISTER_MGMT_FRAME_CB:
case eWNI_SME_SET_CHAN_SW_IE_REQ:
case eWNI_SME_ECSA_CHAN_CHANGE_REQ:
// These messages are from HDD
limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd
break;
//Power Save Messages From HDD
case eWNI_PMC_PWR_SAVE_CFG:
case eWNI_PMC_ENTER_BMPS_REQ:
case eWNI_PMC_EXIT_BMPS_REQ:
case eWNI_PMC_ENTER_IMPS_REQ:
case eWNI_PMC_EXIT_IMPS_REQ:
case eWNI_PMC_ENTER_UAPSD_REQ:
case eWNI_PMC_EXIT_UAPSD_REQ:
case eWNI_PMC_ENTER_WOWL_REQ:
case eWNI_PMC_EXIT_WOWL_REQ:
case eWNI_PMC_WOWL_ADD_BCAST_PTRN:
case eWNI_PMC_WOWL_DEL_BCAST_PTRN:
pmmProcessMessage(pMac, limMsg);
break;
case eWNI_PMC_SMPS_STATE_IND :
{
if(limMsg->bodyptr){
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
}
}
break;
case eWNI_SME_SEND_ACTION_FRAME_IND:
limSendP2PActionFrame(pMac, limMsg);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_ABORT_REMAIN_ON_CHAN_IND:
limAbortRemainOnChan(pMac);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_SEND_MGMT_FRAME_TX:
lim_send_mgmt_frame_tx(pMac, limMsg);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#ifdef WLAN_FEATURE_RMC
case eWNI_SME_ENABLE_RMC_REQ:
case eWNI_SME_DISABLE_RMC_REQ:
/*
* These messages are from HDD
* No need to response to hdd
*/
limProcessSmeReqMessages(pMac,limMsg);
break;
#endif /* WLAN_FEATURE_RMC */
case SIR_HAL_P2P_NOA_START_IND:
{
tpPESession psessionEntry = &pMac->lim.gpSession[0];
tANI_U8 i;
tANI_U8 p2pGOExists = 0;
limLog(pMac, LOG1, "LIM received NOA start %x", limMsg->type);
/* Since insert NOA is done and NOA start msg received, we should deactivate the Insert NOA timer */
limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER);
for(i=0; i < pMac->lim.maxBssId; i++)
{
psessionEntry = &pMac->lim.gpSession[i];
if ( (psessionEntry != NULL) && (psessionEntry->valid) &&
(psessionEntry->pePersona == VOS_P2P_GO_MODE))
{ //Save P2P NOA start attributes for P2P Go persona
p2pGOExists = 1;
vos_mem_copy(&psessionEntry->p2pGoPsNoaStartInd, limMsg->bodyptr,
sizeof(tSirP2PNoaStart));
if (psessionEntry->p2pGoPsNoaStartInd.status != eHAL_STATUS_SUCCESS)
{
limLog(pMac, LOGW, FL("GO NOA start failure status %d reported by FW."
" - still go ahead with deferred sme req. This is just info"),
psessionEntry->p2pGoPsNoaStartInd.status);
}
break;
}
}
if (p2pGOExists == 0)
{
limLog(pMac, LOGW, FL("By the time, we received NOA start, GO is already removed."
" - still go ahead with deferred sme req. This is just info"));
}
/* We received the NOA start indication. Now we can send down the SME request which requires off-channel operation */
limProcessRegdDefdSmeReqAfterNOAStart(pMac);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
}
break;
#ifdef FEATURE_WLAN_TDLS
case SIR_HAL_TDLS_IND:
{
tSirTdlsInd *pTdlsInd = (tpSirTdlsInd)limMsg->bodyptr ;
tpDphHashNode pStaDs = NULL ;
tpPESession psessionEntry = NULL;
tANI_U8 sessionId;
if((psessionEntry = peFindSessionByStaId(pMac,pTdlsInd->staIdx,&sessionId))== NULL)
{
limLog(pMac, LOG1, FL("session does not exist for given bssId\n"));
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
return;
}
if ((pStaDs = dphGetHashEntry(pMac, pTdlsInd->assocId, &psessionEntry->dph.dphHashTable)) == NULL)
{
limLog(pMac, LOG1, FL("pStaDs Does not exist for given staId\n"));
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
return;
}
if ((STA_ENTRY_TDLS_PEER == pStaDs->staType))
{
limLog(pMac, LOGE,
FL("received TDLS Indication from the Firmware with Reason Code %d "),
pTdlsInd->reasonCode);
limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry,
pTdlsInd->reasonCode);
}
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
}
break;
#endif
case SIR_HAL_P2P_NOA_ATTR_IND:
{
tpPESession psessionEntry = &pMac->lim.gpSession[0];
tANI_U8 i;
limLog(pMac, LOGW, FL("Received message Noa_ATTR %x"), limMsg->type);
for(i=0; i < pMac->lim.maxBssId; i++)
{
psessionEntry = &pMac->lim.gpSession[i];
if ( (psessionEntry != NULL) && (psessionEntry->valid) &&
(psessionEntry->pePersona == VOS_P2P_GO_MODE))
{ //Save P2P attributes for P2P Go persona
vos_mem_copy(&psessionEntry->p2pGoPsUpdate, limMsg->bodyptr,
sizeof(tSirP2PNoaAttr));
limLog(pMac, LOG2, FL(" &psessionEntry->bssId "
MAC_ADDRESS_STR " ctWin=%d oppPsFlag=%d"),
MAC_ADDR_ARRAY(psessionEntry->bssId),
psessionEntry->p2pGoPsUpdate.ctWin,
psessionEntry->p2pGoPsUpdate.oppPsFlag);
limLog(pMac, LOG2, FL(" uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d"),
psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt,
psessionEntry->p2pGoPsUpdate.uNoa1Duration,
psessionEntry->p2pGoPsUpdate.uNoa1Interval,
psessionEntry->p2pGoPsUpdate.uNoa1StartTime);
break;
}
}
}
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
/* eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER Message comes after the
* device comes out of full power for the full power request sent
* because of channel switch with switch count as 0, so call the same
* function used in timeout case(i.e SIR_LIM_CHANNEL_SWITCH_TIMEOUT)
* for switching the channel*/
case eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER:
if ( !tx_timer_running(&pMac->lim.limTimers.gLimChannelSwitchTimer) )
{
limProcessChannelSwitchTimeout(pMac);
}
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
//Power Save Related Messages From HAL
case WDA_ENTER_BMPS_RSP:
case WDA_EXIT_BMPS_RSP:
case WDA_EXIT_BMPS_IND:
case WDA_ENTER_IMPS_RSP:
case WDA_EXIT_IMPS_RSP:
case WDA_ENTER_UAPSD_RSP:
case WDA_EXIT_UAPSD_RSP:
case WDA_WOWL_ENTER_RSP:
case WDA_WOWL_EXIT_RSP:
pmmProcessMessage(pMac, limMsg);
break;
case WDA_LOW_RSSI_IND:
//limHandleLowRssiInd(pMac);
break;
case WDA_BMPS_STATUS_IND:
limHandleBmpsStatusInd(pMac);
break;
#ifdef WLAN_FEATURE_APFIND
case WDA_AP_FIND_IND:
limHandleAPFindInd(pMac);
break;
#endif
case WDA_MISSED_BEACON_IND:
limHandleMissedBeaconInd(pMac, limMsg);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case WDA_MIC_FAILURE_IND:
limMicFailureInd(pMac, limMsg);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case WDA_LOST_LINK_PARAMS_IND:
limProcessLostLinkParamsInd(pMac,limMsg);
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case SIR_LIM_ADDTS_RSP_TIMEOUT:
limProcessSmeReqMessages(pMac,limMsg);
break;
#ifdef FEATURE_WLAN_ESE
case SIR_LIM_ESE_TSM_TIMEOUT:
#ifndef FEATURE_WLAN_ESE_UPLOAD
limProcessTsmTimeoutHandler(pMac,limMsg);
#endif /* FEATURE_WLAN_ESE_UPLOAD */
break;
case WDA_TSM_STATS_RSP:
#ifdef FEATURE_WLAN_ESE_UPLOAD
limSendSmePEEseTsmRsp(pMac, (tAniGetTsmStatsRsp *)limMsg->bodyptr);
#else
limProcessHalEseTsmRsp(pMac, limMsg);
#endif /* FEATURE_WLAN_ESE_UPLOAD */
break;
#endif
case WDA_ADD_TS_RSP:
limProcessHalAddTsRsp(pMac, limMsg);
break;
case SIR_LIM_DEL_TS_IND:
limProcessDelTsInd(pMac, limMsg);
break;
case SIR_LIM_ADD_BA_IND:
limProcessAddBaInd(pMac, limMsg);
break;
case SIR_LIM_DEL_BA_ALL_IND:
limDelAllBASessions(pMac);
break;
case SIR_LIM_DEL_BA_IND:
limProcessMlmHalBADeleteInd( pMac, limMsg );
break;
case SIR_LIM_BEACON_GEN_IND: {
if( pMac->lim.gLimSystemRole != eLIM_AP_ROLE )
schProcessPreBeaconInd(pMac, limMsg);
}
break;
case SIR_LIM_DELETE_STA_CONTEXT_IND:
limDeleteStaContext(pMac, limMsg);
break;
case SIR_LIM_MIN_CHANNEL_TIMEOUT:
case SIR_LIM_MAX_CHANNEL_TIMEOUT:
case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
case SIR_LIM_JOIN_FAIL_TIMEOUT:
case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
case SIR_LIM_AUTH_FAIL_TIMEOUT:
case SIR_LIM_AUTH_RSP_TIMEOUT:
case SIR_LIM_ASSOC_FAIL_TIMEOUT:
case SIR_LIM_REASSOC_FAIL_TIMEOUT:
#ifdef WLAN_FEATURE_VOWIFI_11R
case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
#endif
case SIR_LIM_REMAIN_CHN_TIMEOUT:
case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
case SIR_LIM_DISASSOC_ACK_TIMEOUT:
case SIR_LIM_DEAUTH_ACK_TIMEOUT:
case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
case SIR_LIM_AUTH_RETRY_TIMEOUT:
case SIR_LIM_SAP_ECSA_TIMEOUT:
#ifdef WLAN_FEATURE_LFR_MBB
case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT:
case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT:
#endif
case SIR_LIM_AUTH_SAE_TIMEOUT:
// These timeout messages are handled by MLM sub module
limProcessMlmReqMessages(pMac,
limMsg);
break;
case SIR_LIM_HEART_BEAT_TIMEOUT:
/** check if heart beat failed, even if one Beacon
* is rcvd within the Heart Beat interval continue
* normal processing
*/
#if 0
PELOG1(limLog(pMac, LOG1, FL("Heartbeat timeout, SME %d, MLME %d, #bcn %d"),
pMac->lim.gLimSmeState, pMac->lim.gLimMlmState,
pMac->lim.gLimRxedBeaconCntDuringHB);)
if(pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)
limIbssHeartBeatHandle(pMac); //HeartBeat for peers.
else
/**
* Heartbeat failure occurred on STA
* This is handled by LMM sub module.
*/
limHandleHeartBeatFailure(pMac);
break;
#endif //TO SUPPORT BT-AMP
if (limIsSystemInScanState(pMac))
{
// System is in DFS (Learn) mode
// Defer processsing this message
if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
{
PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
limLogSessionStates(pMac);
}
}
else
{
if (NULL == limMsg->bodyptr)
{
limHandleHeartBeatTimeout(pMac);
}
else
{
limHandleHeartBeatTimeoutForSession(pMac, (tpPESession)limMsg->bodyptr);
}
}
break;
case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
limHandleHeartBeatFailureTimeout(pMac);
break;
case SIR_LIM_CHANNEL_SCAN_TIMEOUT:
/**
* Background scan timeout occurred on STA.
* This is handled by LMM sub module.
*/
limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
//We will do background scan even in bcnps mode
//if (pMac->sys.gSysEnableScanMode)
pMac->lim.gLimReportBackgroundScanResults = FALSE;
limTriggerBackgroundScan(pMac);
break;
case SIR_LIM_CNF_WAIT_TIMEOUT:
/*
** Does not receive CNF or dummy packet
**/
limHandleCnfWaitTimeout(pMac, (tANI_U16) limMsg->bodyval);
break;
case SIR_LIM_KEEPALIVE_TIMEOUT:
limSendKeepAliveToPeer(pMac);
break;
case SIR_LIM_RETRY_INTERRUPT_MSG:
// Message from ISR upon TFP's max retry limit interrupt
break;
case SIR_LIM_INV_KEY_INTERRUPT_MSG:
// Message from ISR upon SP's Invalid session key interrupt
break;
case SIR_LIM_KEY_ID_INTERRUPT_MSG:
// Message from ISR upon SP's Invalid key ID interrupt
break;
case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
// Message from ISR upon SP's Replay threshold interrupt
break;
case SIR_LIM_CHANNEL_SWITCH_TIMEOUT:
limProcessChannelSwitchTimeout(pMac);
break;
case SIR_LIM_QUIET_TIMEOUT:
limProcessQuietTimeout(pMac);
break;
case SIR_LIM_QUIET_BSS_TIMEOUT:
limProcessQuietBssTimeout(pMac);
break;
case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
limHandleUpdateOlbcCache(pMac);
break;
#if 0
case SIR_LIM_WPS_OVERLAP_TIMEOUT:
limProcessWPSOverlapTimeout(pMac);
break;
#endif
case WDA_ADD_BSS_RSP:
limProcessMlmAddBssRsp( pMac, limMsg );
break;
case WDA_ADD_STA_RSP:
//call a wrapper by paasing bodyptr, their get sessionID and and call proper function from there.
limProcessAddStaRsp(pMac,limMsg);
break;
case WDA_DELETE_STA_RSP:
limProcessMlmDelStaRsp(pMac, limMsg);
break;
case WDA_ADD_STA_SELF_RSP:
limProcessAddStaSelfRsp(pMac, limMsg);
break;
case WDA_DEL_STA_SELF_RSP:
limProcessDelStaSelfRsp(pMac, limMsg);
break;
case WDA_DELETE_BSS_RSP:
limHandleDeleteBssRsp(pMac,limMsg); //wrapper routine to handle delete bss response
break;
case WDA_SET_BSSKEY_RSP:
case WDA_SET_STA_BCASTKEY_RSP:
limProcessMlmSetBssKeyRsp( pMac, limMsg );
break;
case WDA_SET_STAKEY_RSP:
limProcessMlmSetStaKeyRsp( pMac, limMsg );
break;
case WDA_REMOVE_BSSKEY_RSP:
case WDA_REMOVE_STAKEY_RSP:
limProcessMlmRemoveKeyRsp( pMac, limMsg );
break;
case WDA_ADDBA_RSP:
limProcessMlmHalAddBARsp( pMac, limMsg );
break;
case WDA_STA_STAT_RSP:
case WDA_AGGR_STAT_RSP:
case WDA_GLOBAL_STAT_RSP:
case WDA_STAT_SUMM_RSP:
limSendSmeStatsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr);
break;
case WDA_GET_STATISTICS_RSP:
limSendSmePEStatisticsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr);
break;
#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
case WDA_GET_ROAM_RSSI_RSP:
limSendSmePEGetRoamRssiRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr);
break;
#endif
case WDA_SET_MIMOPS_RSP: //limProcessSetMimoRsp(pMac, limMsg);
case WDA_SET_TX_POWER_RSP: //limProcessSetTxPowerRsp(pMac, limMsg);
case WDA_GET_TX_POWER_RSP: //limProcessGetTxPowerRsp(pMac, limMsg);
case WDA_GET_NOISE_RSP:
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
//limProcessGetNoiseRsp(pMac, limMsg);
break;
case WDA_SET_MAX_TX_POWER_RSP:
#if defined WLAN_FEATURE_VOWIFI
rrmSetMaxTxPowerRsp( pMac, limMsg );
#endif
if(limMsg->bodyptr != NULL)
{
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
}
break;
case SIR_LIM_ADDR2_MISS_IND:
{
limLog(pMac, LOGE,
FL("Addr2 mismatch interrupt received %X"),
limMsg->type);
/*a message from HAL indicating addr2 mismatch interrupt occurred
limMsg->bodyptr contains only pointer to 48-bit addr2 field*/
//Dinesh fix this. the third parameter should be sessionentry.
//limHandleUnknownA2IndexFrames(pMac, (void *)limMsg->bodyptr);
/*Free message body pointer*/
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
break;
}
#ifdef WLAN_FEATURE_VOWIFI_11R
case WDA_AGGR_QOS_RSP:
limProcessFTAggrQoSRsp( pMac, limMsg );
break;
#endif
case WDA_SET_LINK_STATE_RSP:
linkStateParams = (tLinkStateParams *)limMsg->bodyptr;
#if defined WLAN_FEATURE_VOWIFI_11R
pSession = linkStateParams->session;
if(linkStateParams->ft)
{
limSendReassocReqWithFTIEsMgmtFrame(pMac,
pSession->pLimMlmReassocReq,
pSession);
}
#endif
if( linkStateParams->callback )
{
linkStateParams->callback( pMac, linkStateParams->callbackArg );
}
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
break;
#ifdef WLAN_FEATURE_PACKET_FILTERING
case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP:
pmmProcessMessage(pMac, limMsg);
break;
#endif // WLAN_FEATURE_PACKET_FILTERING
#ifdef WLAN_FEATURE_GTK_OFFLOAD
case WDA_GTK_OFFLOAD_GETINFO_RSP:
pmmProcessMessage(pMac, limMsg);
break;
#endif // WLAN_FEATURE_GTK_OFFLOAD
case eWNI_SME_SET_BCN_FILTER_REQ:
{
#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
tpPESession psessionEntry;
tANI_U8 sessionId;
tSirSetActiveModeSetBncFilterReq *bcnFilterReq =
(tSirSetActiveModeSetBncFilterReq *)limMsg->bodyptr;
psessionEntry = peFindSessionByBssid(pMac, bcnFilterReq->bssid,
&sessionId);
if(psessionEntry != NULL && IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)
{
// sending beacon filtering information down to HAL
if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS)
{
limLog(pMac, LOGE, FL("Fail to send Beacon Filter Info "));
}
}
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
#endif
}
break;
case eWNI_SME_HT40_OBSS_SCAN_IND:
{
tpPESession psessionEntry = NULL;
tANI_U8 sessionId;
tSirSmeHT40OBSSScanInd *ht40ScanInd =
(tSirSmeHT40OBSSScanInd *)limMsg->bodyptr;
psessionEntry = peFindSessionByBssid(pMac, ht40ScanInd->peerMacAddr,
&sessionId);
if (psessionEntry != NULL)
{
if( IS_HT40_OBSS_SCAN_FEATURE_ENABLE &&
psessionEntry->htSupportedChannelWidthSet ==
WNI_CFG_CHANNEL_BONDING_MODE_ENABLE )
{
VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
"OBSS Scan Start Req: session id %d"
"htSupportedChannelWidthSet %d", psessionEntry->peSessionId,
psessionEntry->htSupportedChannelWidthSet);
limSendHT40OBSSScanInd(pMac, psessionEntry);
}
else
{
VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
"OBSS Scan not started: htSupportedChannelWidthSet- %d"
" session id %d", psessionEntry->htSupportedChannelWidthSet,
psessionEntry->peSessionId);
}
}
else
{
VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO,
"OBSS Scan not started: session id is NULL");
}
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
}
break;
case eWNI_SME_HT40_STOP_OBSS_SCAN_IND:
{
tpPESession psessionEntry = NULL;
tANI_U8 sessionId;
tSirSmeHT40OBSSStopScanInd *ht40StopScanInd =
(tSirSmeHT40OBSSStopScanInd *)limMsg->bodyptr;
psessionEntry = peFindSessionByBssid(pMac,
ht40StopScanInd->bssid, &sessionId);;
/* Sending LIM STOP OBSS SCAN Indication
Stop command support is only for debugging purpose */
if (psessionEntry && IS_HT40_OBSS_SCAN_FEATURE_ENABLE)
limSendHT40OBSSStopScanInd(pMac, psessionEntry);
else
VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_ERROR,
"OBSS Scan Stop not started ");
}
vos_mem_free(limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#ifdef WLAN_FEATURE_AP_HT40_24G
case eWNI_SME_SET_HT_2040_MODE:
limProcessSmeReqMessages(pMac, limMsg);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
#endif
#ifdef FEATURE_WLAN_TDLS
case WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP:
{
tpPESession psessionEntry;
tANI_U8 sessionId;
tDphHashNode *pStaDs = NULL;
int i, aid;
tTdlsLinkEstablishParams *pTdlsLinkEstablishParams;
pTdlsLinkEstablishParams = (tTdlsLinkEstablishParams*) limMsg->bodyptr;
if((psessionEntry = peFindSessionByStaId(pMac,
pTdlsLinkEstablishParams->staIdx,
&sessionId))== NULL)
{
limLog(pMac, LOGE, FL("session %u does not exist"), sessionId);
/* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP message to SME
with session id as zero and status as FAILURE so, that message
queued in SME queue can be freed to prevent the SME cmd buffer leak */
limSendSmeTdlsLinkEstablishReqRsp(pMac,
0,
NULL,
NULL,
eSIR_FAILURE);
}
else
{
for (i = 0;
i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32);
i++) {
for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) {
if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) {
pStaDs = dphGetHashEntry(pMac,
(aid + i*(sizeof(tANI_U32) << 3)),
&psessionEntry->dph.dphHashTable);
if ((NULL != pStaDs) &&
(pTdlsLinkEstablishParams->staIdx ==
pStaDs->staIndex))
goto send_link_resp;
}
}
}
send_link_resp:
if (pStaDs)
limSendSmeTdlsLinkEstablishReqRsp(pMac,
psessionEntry->smeSessionId,
pStaDs->staAddr,
pStaDs,
pTdlsLinkEstablishParams->status) ;
else
limSendSmeTdlsLinkEstablishReqRsp(pMac,
psessionEntry->smeSessionId,
NULL, NULL,
pTdlsLinkEstablishParams->status) ;
}
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
break;
}
case WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP:
{
tpPESession psessionEntry;
tANI_U8 sessionId;
tDphHashNode *pStaDs = NULL;
int i, aid;
tTdlsChanSwitchParams *pTdlsChanSwitchParams;
pTdlsChanSwitchParams = (tTdlsChanSwitchParams*) limMsg->bodyptr;
if((psessionEntry = peFindSessionByStaId(pMac,
pTdlsChanSwitchParams->staIdx,
&sessionId))== NULL)
{
limLog(pMac, LOGE, FL("session %u does not exist"), sessionId);
/* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP message to SME
with session id as zero and status as FAILURE so, that message
queued in SME queue can be freed to prevent the SME cmd buffer leak */
limSendSmeTdlsChanSwitchReqRsp(pMac,
0,
NULL,
NULL,
eSIR_FAILURE);
}
else
{
for (i = 0;
i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32);
i++) {
for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) {
if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) {
pStaDs = dphGetHashEntry(pMac,
(aid + i*(sizeof(tANI_U32) << 3)),
&psessionEntry->dph.dphHashTable);
if ((NULL != pStaDs) &&
(pTdlsChanSwitchParams->staIdx ==
pStaDs->staIndex))
goto send_chan_switch_resp;
}
}
}
send_chan_switch_resp:
if (pStaDs)
limSendSmeTdlsChanSwitchReqRsp(pMac,
psessionEntry->smeSessionId,
pStaDs->staAddr,
pStaDs,
pTdlsChanSwitchParams->status);
else
limSendSmeTdlsChanSwitchReqRsp(pMac,
psessionEntry->smeSessionId,
NULL, NULL,
pTdlsChanSwitchParams->status);
}
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
break;
}
#endif
case WDA_RX_SCAN_EVENT:
limProcessRxScanEvent(pMac, limMsg->bodyptr);
break;
case WDA_IBSS_PEER_INACTIVITY_IND:
{
limProcessIbssPeerInactivity(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t *)(limMsg->bodyptr));
limMsg->bodyptr = NULL;
break;
}
#ifdef WLAN_FEATURE_RMC
case WDA_RMC_BECOME_RULER:
limProcessRMCMessages(pMac, eLIM_RMC_BECOME_RULER_RESP,
(void *)limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break ;
case WDA_RMC_RULER_SELECT_RESP:
limProcessRMCMessages(pMac, eLIM_RMC_RULER_SELECT_RESP,
(void *)limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break ;
case WDA_RMC_UPDATE_IND:
limProcessRMCMessages(pMac, eLIM_RMC_RULER_PICK_NEW,
(void *)limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break ;
#endif /* WLAN_FEATURE_RMC */
case WDA_SPOOF_MAC_ADDR_RSP:
limProcessMlmSpoofMacAddrRsp(pMac, (tSirRetStatus)limMsg->bodyval);
break;
case eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ:
limProcessSmeSetTdls2040BSSCoexReq(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_DEL_ALL_TDLS_PEERS:
limProcessSmeDelAllTdlsPeers(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_CAP_TSF_REQ:
lim_process_sme_cap_tsf_req(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_GET_TSF_REQ:
lim_process_sme_get_tsf_req(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_DEL_BA_SES_REQ:
lim_process_sme_del_ba_ses_req(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
case eWNI_SME_STA_DEL_BA_REQ:
limStaDelBASession(pMac);
break;
case eWNI_SME_SEND_SAE_MSG:
lim_process_sae_msg(pMac, limMsg->bodyptr);
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
break;
default:
vos_mem_free((v_VOID_t*)limMsg->bodyptr);
limMsg->bodyptr = NULL;
// Unwanted messages
// Log error
limLog(pMac, LOGE,
FL("Discarding unexpected message received %X"),
limMsg->type);
limPrintMsgName(pMac, LOGE, limMsg->type);
break;
} // switch (limMsg->type)
PELOG2(limLog(pMac, LOG2, FL("Done Processing msgType = %d, sme state = %s, mlm state = %s"),
limMsg->type, limSmeStateStr(pMac->lim.gLimSmeState),
limMlmStateStr(pMac->lim.gLimMlmState));)
} /*** end limProcessMessages() ***/
/**
* limProcessDeferredMessageQueue
*
*FUNCTION:
* This function is called by LIM while exiting from Learn
* mode. This function fetches messages posted to the LIM
* deferred message queue limDeferredMsgQ.
*
*LOGIC:
*
*ASSUMPTIONS:
* NA
*
*NOTE:
* NA
*
* @param pMac - Pointer to Global MAC structure
* @return None
*/
void
limProcessDeferredMessageQueue(tpAniSirGlobal pMac)
{
tSirMsgQ limMsg = { 0, 0, 0 };
tSirMsgQ *readMsg;
tANI_U16 size;
/*
** check any deferred messages need to be processed
**/
size = pMac->lim.gLimDeferredMsgQ.size;
if (size > 0)
{
while ((readMsg = limReadDeferredMsgQ(pMac)) != NULL)
{
vos_mem_copy((tANI_U8*) &limMsg,
(tANI_U8*) readMsg, sizeof(tSirMsgQ));
size--;
limProcessMessages(pMac, &limMsg);
if((limIsSystemInScanState(pMac)) || (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) ||
(pMac->lim.gLimSystemInScanLearnMode) || pMac->lim.gLimAddtsSent)
break;
}
}
} /*** end limProcessDeferredMessageQueue() ***/
/*
* limProcessNormalHddMsg
* Function: this function checks the current lim state and decide whether the message passed shall be deffered.
* @param pMac - Pointer to Global MAC structure
* pLimMsg -- the message need to be processed
* fRspReqd -- whether return result to hdd
* @return None
*/
void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd)
{
tANI_BOOLEAN fDeferMsg = eANI_BOOLEAN_TRUE;
/* Added For BT-AMP Support */
if ((pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_AP_ROLE )
||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_STA_ROLE)
||(pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE))
{
/** This check is required only for the AP and in 2 cases.
* 1. If we are in learn mode and we receive any of these messages,
* you have to come out of scan and process the message, hence dont
* defer the message here. In handler, these message could be defered
* till we actually come out of scan mode.
* 2. If radar is detected, you might have to defer all of these
* messages except Stop BSS request/ Switch channel request. This
* decision is also made inside its handler.
*
* Please be careful while using the flag fDeferMsg. Possibly you
* might end up in an infinite loop.
**/
if (((pLimMsg->type == eWNI_SME_START_BSS_REQ) ||
(pLimMsg->type == eWNI_SME_STOP_BSS_REQ) ||
(pLimMsg->type == eWNI_SME_SWITCH_CHL_REQ) ||
(pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ) ||
(pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ)))
{
fDeferMsg = eANI_BOOLEAN_FALSE;
}
}
/* limInsystemInscanState() refers the psessionEntry, how to get session Entry????*/
if (((pMac->lim.gLimAddtsSent) || (limIsSystemInScanState(pMac)) /*||
(LIM_IS_RADAR_DETECTED(pMac))*/) && fDeferMsg)
{
// System is in DFS (Learn) mode or awaiting addts response
// or if radar is detected, Defer processsing this message
if (limDeferMsg(pMac, pLimMsg) != TX_SUCCESS)
{
#ifdef WLAN_DEBUG
pMac->lim.numSme++;
#endif
PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"),
pLimMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
limLogSessionStates(pMac);
limPrintMsgName(pMac, LOGE, pLimMsg->type);
// Release body
vos_mem_free(pLimMsg->bodyptr);
pLimMsg->bodyptr = NULL;
}
}
else
{
if(fRspReqd)
{
// These messages are from HDD
// Since these requests may also be generated
// internally within LIM module, need to
// distinquish and send response to host
pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE;
}
#ifdef WLAN_DEBUG
pMac->lim.numSme++;
#endif
if(limProcessSmeReqMessages(pMac, pLimMsg))
{
// Release body
// limProcessSmeReqMessage consumed the buffer. We can free it.
vos_mem_free(pLimMsg->bodyptr);
pLimMsg->bodyptr = NULL;
}
}
}
void
handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessionEntry)
{
tSirMacHTCapabilityInfo macHTCapabilityInfo;
tSirMacHTParametersInfo macHTParametersInfo;
tSirMacHTInfoField1 macHTInfoField1;
tSirMacHTInfoField2 macHTInfoField2;
tSirMacHTInfoField3 macHTInfoField3;
tANI_U32 cfgValue;
tANI_U8 *ptr;
if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgValue) != eSIR_SUCCESS)
{
limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_CAP_INFO value"));
return ;
}
ptr = (tANI_U8 *) &macHTCapabilityInfo;
*((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff);
pMac->lim.gHTLsigTXOPProtection = (tANI_U8)macHTCapabilityInfo.lsigTXOPProtection;
pMac->lim.gHTMIMOPSState = (tSirMacHTMIMOPowerSaveState) macHTCapabilityInfo.mimoPowerSave;
pMac->lim.gHTGreenfield = (tANI_U8)macHTCapabilityInfo.greenField;
pMac->lim.gHTMaxAmsduLength = (tANI_U8)macHTCapabilityInfo.maximalAMSDUsize;
pMac->lim.gHTShortGI20Mhz = (tANI_U8)macHTCapabilityInfo.shortGI20MHz;
pMac->lim.gHTShortGI40Mhz = (tANI_U8)macHTCapabilityInfo.shortGI40MHz;
pMac->lim.gHTPSMPSupport = (tANI_U8)macHTCapabilityInfo.psmp;
pMac->lim.gHTDsssCckRate40MHzSupport = (tANI_U8)macHTCapabilityInfo.dsssCckMode40MHz;
if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &cfgValue) != eSIR_SUCCESS)
{
limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_PARAM_INFO value"));
return ;
}
ptr = (tANI_U8 *) &macHTParametersInfo;
*ptr = (tANI_U8) (cfgValue & 0xff);
pMac->lim.gHTAMpduDensity = (tANI_U8)macHTParametersInfo.mpduDensity;
pMac->lim.gHTMaxRxAMpduFactor = (tANI_U8)macHTParametersInfo.maxRxAMPDUFactor;
// Get HT IE Info
if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &cfgValue) != eSIR_SUCCESS)
{
limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD1 value"));
return ;
}
ptr = (tANI_U8 *) &macHTInfoField1;
*((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff);
pMac->lim.gHTServiceIntervalGranularity = (tANI_U8)macHTInfoField1.serviceIntervalGranularity;
pMac->lim.gHTControlledAccessOnly = (tANI_U8)macHTInfoField1.controlledAccessOnly;
pMac->lim.gHTRifsMode = (tANI_U8)macHTInfoField1.rifsMode;
if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD2, &cfgValue) != eSIR_SUCCESS)
{
limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD2 value"));
return ;
}
ptr = (tANI_U8 *) &macHTInfoField2;
*((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff);
pMac->lim.gHTOperMode = (tSirMacHTOperatingMode) macHTInfoField2.opMode;
if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD3, &cfgValue) != eSIR_SUCCESS)
{
limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD3 value"));
return ;
}
ptr = (tANI_U8 *) &macHTInfoField3;
*((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff);
pMac->lim.gHTPCOActive = (tANI_U8)macHTInfoField3.pcoActive;
pMac->lim.gHTPCOPhase = (tANI_U8)macHTInfoField3.pcoPhase;
pMac->lim.gHTSecondaryBeacon = (tANI_U8)macHTInfoField3.secondaryBeacon;
pMac->lim.gHTDualCTSProtection = (tANI_U8)macHTInfoField3.dualCTSProtection;
pMac->lim.gHTSTBCBasicMCS = (tANI_U8)macHTInfoField3.basicSTBCMCS;
/* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session;
* instead direct cfg is read and used when no session for transmission of mgmt frames (same as old);
* For now, we might come here during init and join with sessionEntry = NULL; in that case just fill the globals which exist
* Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below
*/
if (psessionEntry != NULL)
{
psessionEntry->htCapability =
IS_DOT11_MODE_HT(psessionEntry->dot11mode);
psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
(tANI_U8)macHTInfoField3.lsigTXOPProtectionFullSupport;
limInitOBSSScanParams(pMac, psessionEntry);
}
}
void limLogSessionStates(tpAniSirGlobal pMac)
{
#ifdef WLAN_DEBUG
int i;
for(i = 0; i < pMac->lim.maxBssId; i++)
{
if(pMac->lim.gpSession[i].valid)
{
limLog(pMac, LOG1, FL("Session[%d] sysRole(%d) limSmeState %d "
"(prev sme state %d) mlm state %d (prev mlm state %d)"),
i, pMac->lim.gpSession[i].limSystemRole,
pMac->lim.gpSession[i].limSmeState,
pMac->lim.gpSession[i].limPrevSmeState,
pMac->lim.gpSession[i].limMlmState,
pMac->lim.gpSession[i].limPrevMlmState);
}
}
#endif //ifdef WLAN_DEBUG
}