prima: WLAN Driver Release 3.1.7.9
This is the initial release of the Prima WLAN Driver
diff --git a/CORE/MAC/src/pe/lim/limAIDmgmt.c b/CORE/MAC/src/pe/lim/limAIDmgmt.c
new file mode 100644
index 0000000..7e78eb6
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limAIDmgmt.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limAIDmgmt.cc contains the functions related to
+ * AID pool management like initialization, assignment etc.
+ * Author: Chandra Modumudi
+ * Date: 03/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "palTypes.h"
+#include "wniCfgSta.h"
+#include "aniGlobal.h"
+#include "cfgApi.h"
+#include "sirParams.h"
+#include "limUtils.h"
+#include "limTimerUtils.h"
+#include "limSession.h"
+
+#define LIM_START_AID 1
+
+
+/**
+ * limInitAIDpool()
+ *
+ *FUNCTION:
+ * This function is called while starting a BSS at AP
+ * to initialize AID pool. This may also be called while
+ * starting/joining an IBSS if 'Association' is allowed
+ * in IBSS.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limInitAIDpool(tpAniSirGlobal pMac,tpPESession sessionEntry)
+{
+ tANI_U8 i;
+ tANI_U8 maxAssocSta = pMac->lim.gLimAssocStaLimit;
+
+ pMac->lim.gpLimAIDpool[0]=0;
+ pMac->lim.freeAidHead=LIM_START_AID;
+
+ for (i=pMac->lim.freeAidHead;i<maxAssocSta; i++)
+ {
+ pMac->lim.gpLimAIDpool[i] = i+1;
+ }
+ pMac->lim.gpLimAIDpool[i] = 0;
+
+ pMac->lim.freeAidTail=i;
+
+}
+
+
+/**
+ * limAssignAID()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to assign association ID (aid) to a STA.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return aid - assigned Association ID for STA
+ */
+
+tANI_U16
+limAssignAID(tpAniSirGlobal pMac)
+{
+ tANI_U16 aid;
+
+ // make sure we haven't exceeded the configurable limit on associations
+ if (pMac->lim.gLimNumOfCurrentSTAs >= pMac->lim.gLimAssocStaLimit)
+ {
+ // too many associations already active
+ return 0;
+ }
+
+ /* return head of free list */
+
+ if (pMac->lim.freeAidHead)
+ {
+ aid=pMac->lim.freeAidHead;
+ pMac->lim.freeAidHead=pMac->lim.gpLimAIDpool[pMac->lim.freeAidHead];
+ if (pMac->lim.freeAidHead==0)
+ pMac->lim.freeAidTail=0;
+ pMac->lim.gLimNumOfCurrentSTAs++;
+ //PELOG2(limLog(pMac, LOG2,FL("Assign aid %d, numSta %d, head %d tail %d \n"),aid,pMac->lim.gLimNumOfCurrentSTAs,pMac->lim.freeAidHead,pMac->lim.freeAidTail);)
+ return aid;
+ }
+
+ return 0; /* no more free aids */
+}
+
+
+/**
+ * limReleaseAID()
+ *
+ *FUNCTION:
+ * This function is called when a STA context is removed
+ * at AP (or at a STA in IBSS mode) to return association ID (aid)
+ * to free pool.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param aid - Association ID that need to return to free pool
+ *
+ * @return None
+ */
+
+void
+limReleaseAID(tpAniSirGlobal pMac, tANI_U16 aid)
+{
+ pMac->lim.gLimNumOfCurrentSTAs--;
+
+ /* insert at tail of free list */
+ if (pMac->lim.freeAidTail)
+ {
+ pMac->lim.gpLimAIDpool[pMac->lim.freeAidTail]=(tANI_U8)aid;
+ pMac->lim.freeAidTail=(tANI_U8)aid;
+ }
+ else
+ {
+ pMac->lim.freeAidTail=pMac->lim.freeAidHead=(tANI_U8)aid;
+ }
+ pMac->lim.gpLimAIDpool[(tANI_U8)aid]=0;
+ //PELOG2(limLog(pMac, LOG2,FL("Release aid %d, numSta %d, head %d tail %d \n"),aid,pMac->lim.gLimNumOfCurrentSTAs,pMac->lim.freeAidHead,pMac->lim.freeAidTail);)
+
+}
diff --git a/CORE/MAC/src/pe/lim/limAdmitControl.c b/CORE/MAC/src/pe/lim/limAdmitControl.c
new file mode 100644
index 0000000..d14e56a
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limAdmitControl.c
@@ -0,0 +1,1254 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file contains TSPEC and STA admit control related functions
+ * NOTE: applies only to AP builds
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "limDebug.h"
+#include "sysDef.h"
+#include "limApi.h"
+#include "cfgApi.h" // wlan_cfgGetInt()
+#include "limTrace.h"
+#include "limSendSmeRspMessages.h"
+#include "limTypes.h"
+
+
+#define ADMIT_CONTROL_LOGLEVEL LOG1
+#define ADMIT_CONTROL_POLICY_LOGLEVEL LOG1
+#define ADMIT_CONTROL_MIN_INTERVAL 1000 // min acceptable service interval 1mSec
+
+/* total available bandwidth in bps in each phy mode
+ * these should be defined in hal or dph - replace these later
+ */
+#define LIM_TOTAL_BW_11A 54000000
+#define LIM_MIN_BW_11A 6000000
+#define LIM_TOTAL_BW_11B 11000000
+#define LIM_MIN_BW_11B 1000000
+#define LIM_TOTAL_BW_11G LIM_TOTAL_BW_11A
+#define LIM_MIN_BW_11G LIM_MIN_BW_11B
+
+// conversion factors
+#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8)
+#define LIM_CONVERT_RATE_MBPS(rate) ((rate)/1000000)
+
+/* ANI sta's support enhanced rates, so the effective medium time used is
+ * half that of other stations. This is the same as if they were requesting
+ * half the badnwidth - so we adjust ANI sta's accordingly for bandwidth
+ * calculations. Also enhanced rates apply only in case of non 11B mode.
+ */
+#define LIM_STA_BW_ADJUST(aniPeer, phyMode, bw) \
+ (((aniPeer) && ((phyMode) != WNI_CFG_PHY_MODE_11B)) \
+ ? ((bw)/2) : (bw))
+
+
+//------------------------------------------------------------------------------
+// local protos
+
+static tSirRetStatus
+limCalculateSvcInt(tpAniSirGlobal, tSirMacTspecIE *, tANI_U32 *);
+#if 0 //only EDCA is supported now
+static tSirRetStatus
+limValidateTspecHcca(tpAniSirGlobal, tSirMacTspecIE *);
+#endif
+static tSirRetStatus
+limValidateTspecEdca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static tSirRetStatus
+limValidateTspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static void
+limComputeMeanBwUsed(tpAniSirGlobal, tANI_U32 *, tANI_U32, tpLimTspecInfo, tpPESession);
+static void
+limGetAvailableBw(tpAniSirGlobal, tANI_U32 *, tANI_U32 *, tANI_U32, tANI_U32);
+static tSirRetStatus
+limAdmitPolicyOversubscription(tpAniSirGlobal, tSirMacTspecIE *, tpLimAdmitPolicyInfo, tpLimTspecInfo, tpPESession);
+static tSirRetStatus
+limTspecFindByStaAddr(tpAniSirGlobal, tANI_U8 *, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *);
+static tSirRetStatus
+limValidateAccessPolicy(tpAniSirGlobal, tANI_U8, tANI_U16, tpPESession);
+
+
+/** -------------------------------------------------------------
+\fn limCalculateSvcInt
+\brief TSPEC validation and servcie interval determination
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\param tANI_U32 *pSvcInt
+\return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+limCalculateSvcInt(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec,
+ tANI_U32 *pSvcInt)
+{
+ tANI_U32 msduSz, dataRate;
+ *pSvcInt = 0;
+
+ // if a service interval is already specified, we are done
+ if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0))
+ {
+ *pSvcInt = (pTspec->maxSvcInterval != 0)
+ ? pTspec->maxSvcInterval : pTspec->minSvcInterval;
+ return eSIR_SUCCESS;
+ }
+
+ /* Masking off the fixed bits according to definition of MSDU size
+ * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size
+ * is defined as: Bit[0:14]=Size, Bit[15]=Fixed
+ */
+ if (pTspec->nomMsduSz != 0)
+ msduSz = (pTspec->nomMsduSz & 0x7fff);
+ else if (pTspec->maxMsduSz != 0)
+ msduSz = pTspec->maxMsduSz;
+ else
+ {
+ PELOGE(limLog(pMac, LOGE, FL("MsduSize not specified\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* need to calculate a reasonable service interval
+ * this is simply the msduSz/meanDataRate
+ */
+ if (pTspec->meanDataRate != 0) dataRate = pTspec->meanDataRate;
+ else if (pTspec->peakDataRate != 0) dataRate = pTspec->peakDataRate;
+ else if (pTspec->minDataRate != 0) dataRate = pTspec->minDataRate;
+ else
+ {
+ PELOGE(limLog(pMac, LOGE, FL("DataRate not specified\n"));)
+ return eSIR_FAILURE;
+ }
+
+ *pSvcInt = LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate);
+ return eSIR_FAILURE;
+}
+
+#if 0 //only EDCA is supported now
+/** -------------------------------------------------------------
+\fn limValidateTspecHcca
+\brief validate the parameters in the hcca tspec
+ mandatory fields are derived from 11e Annex I (Table I.1)
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+static tSirRetStatus
+limValidateTspecHcca(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec)
+{
+ tANI_U32 maxPhyRate, minPhyRate;
+ tANI_U32 phyMode;
+
+ tSirRetStatus retval = eSIR_SUCCESS;
+ /* make sure a TSID is being requested */
+ if (pTspec->tsinfo.traffic.tsid < SIR_MAC_HCCA_TSID_MIN)
+ {
+ limLog(pMac, LOGW, FL("tsid %d must be >%d)\n"),
+ pTspec->tsinfo.traffic.tsid, SIR_MAC_HCCA_TSID_MIN);
+ retval = eSIR_FAILURE;
+ }
+ /*
+ * With Polaris, there is a limitation in that the tsid cannot be arbitary
+ * but is based on the qid. Thus, we cannot have a tspec which requests
+ * a tsid of 13 and userPrio of 7, the bottom three bits of the tsid must
+ * correspond to the userPrio
+ */
+ if (pTspec->tsinfo.traffic.userPrio !=
+ (pTspec->tsinfo.traffic.tsid - SIR_MAC_HCCA_TSID_MIN))
+ {
+ limLog(pMac, LOGE, FL("TSid=0x%x, userPrio=%d: is not allowed\n"),
+ pTspec->tsinfo.traffic.tsid, pTspec->tsinfo.traffic.userPrio);
+ retval = eSIR_FAILURE;
+ }
+ // an inactivity interval is mandatory
+ if (pTspec->inactInterval == 0)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("inactInterval unspecified!\n"));)
+ retval = eSIR_FAILURE;
+ }
+ // surplus BW must be specified if a delay Bound is specified
+ if ((pTspec->delayBound != 0) && (pTspec->surplusBw == 0))
+ {
+ limLog(pMac, LOGW, FL("delayBound %d, but surplusBw unspecified!\n"),
+ pTspec->delayBound);
+ retval = eSIR_FAILURE;
+ }
+ // minPhyRate must always be specified and cannot exceed maximum supported
+ limGetPhyMode(pMac, &phyMode);
+ //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode,
+ // 1 /* bandwidth mult factor */);
+ limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode,
+ 1 /* bandwidth mult factor */);
+ if ((pTspec->minPhyRate == 0)
+ || (pTspec->minPhyRate > maxPhyRate)
+ || (pTspec->minPhyRate < minPhyRate))
+ {
+ limLog(pMac, LOGW, FL("minPhyRate (%d) invalid\n"),
+ pTspec->minPhyRate);
+ retval = eSIR_FAILURE;
+ }
+ /* NOTE: we will require all Tspec's to specify a mean data rate (and so
+ * also the min and peak data rates)
+ */
+ if ((pTspec->minDataRate == 0) ||
+ (pTspec->meanDataRate == 0) ||
+ (pTspec->peakDataRate == 0))
+ {
+ limLog(pMac, LOGW, FL("DataRate must be specified (min %d, mean %d, peak %d)\n"),
+ pTspec->minDataRate, pTspec->meanDataRate, pTspec->peakDataRate);
+ retval = eSIR_FAILURE;
+ }
+
+ // mean data rate can't be more than the min phy rate
+ if (pTspec->meanDataRate > pTspec->minPhyRate)
+ {
+ limLog(pMac, LOGW, FL("Data rate (%d) is more than Phyrate %d\n"),
+ pTspec->meanDataRate, pTspec->minPhyRate);
+ return eSIR_FAILURE;
+ }
+
+ /* if the tspec specifies a service interval, we won't accept tspec's
+ * with service interval less than our allowed minimum, also either both
+ * min and max must be specified or neither should be specified (in which
+ * case, HC determines the appropriate service interval
+ */
+ if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0))
+ {
+ // max < min is ridiculous
+ if (pTspec->maxSvcInterval < pTspec->minSvcInterval)
+ {
+ limLog(pMac, LOGW, FL("maxSvcInt %d > minSvcInterval %d!!\n"),
+ pTspec->maxSvcInterval, pTspec->minSvcInterval);
+ retval = eSIR_FAILURE;
+ }
+ if (pTspec->maxSvcInterval < ADMIT_CONTROL_MIN_INTERVAL)
+ {
+ limLog(pMac, LOGW, FL("maxSvcInt %d must be >%d\n"),
+ pTspec->maxSvcInterval, ADMIT_CONTROL_MIN_INTERVAL);
+ retval = eSIR_FAILURE;
+ }
+ }
+ else // min and max both unspecified
+ {
+ /* no service interval is specified, so make sure the parameters
+ * needed to determine one are specified in the tspec
+ * minPhyRate, meanDataRate and nomMsduSz are needed, only nomMsduSz
+ * must be checked here since the other two are already validated
+ */
+ if (pTspec->nomMsduSz == 0)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("No svcInt and no MsduSize specified\n"));)
+ retval = eSIR_FAILURE;
+ }
+ }
+
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d\n"), retval);
+ return retval;
+}
+
+#endif //only edca is supported now.
+
+/** -------------------------------------------------------------
+\fn limValidateTspecEdca
+\brief validate the parameters in the edca tspec
+ mandatory fields are derived from 11e Annex I (Table I.1)
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+static tSirRetStatus
+limValidateTspecEdca(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec,
+ tpPESession psessionEntry)
+{
+ tANI_U32 maxPhyRate, minPhyRate;
+ tANI_U32 phyMode;
+ tSirRetStatus retval = eSIR_SUCCESS;
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode,
+ // 1 /* bandwidth mult factor */);
+ limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode,
+ 1 /* bandwidth mult factor */);
+ // mandatory fields are derived from 11e Annex I (Table I.1)
+ if ((pTspec->nomMsduSz == 0) ||
+ (pTspec->meanDataRate == 0) ||
+ (pTspec->surplusBw == 0) ||
+ (pTspec->minPhyRate == 0) ||
+ (pTspec->minPhyRate > maxPhyRate))
+ {
+ limLog(pMac, LOGW, FL("Invalid EDCA Tspec: NomMsdu %d, meanDataRate %d, surplusBw %d, minPhyRate %d\n"),
+ pTspec->nomMsduSz, pTspec->meanDataRate, pTspec->surplusBw, pTspec->minPhyRate);
+ retval = eSIR_FAILURE;
+ }
+
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d\n"), retval);
+ return retval;
+}
+
+/** -------------------------------------------------------------
+\fn limValidateTspec
+\brief validate the offered tspec
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+limValidateTspec(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_SUCCESS;
+ switch (pTspec->tsinfo.traffic.accessPolicy)
+ {
+ case SIR_MAC_ACCESSPOLICY_EDCA:
+ if ((retval = limValidateTspecEdca(pMac, pTspec, psessionEntry)) != eSIR_SUCCESS)
+ PELOGW(limLog(pMac, LOGW, FL("EDCA tspec invalid\n"));)
+ break;
+
+ case SIR_MAC_ACCESSPOLICY_HCCA:
+#if 0 //Not supported right now.
+ if ((retval = limValidateTspecHcca(pMac, pTspec)) != eSIR_SUCCESS)
+ PELOGW(limLog(pMac, LOGW, FL("HCCA tspec invalid\n"));)
+ break;
+#endif
+ case SIR_MAC_ACCESSPOLICY_BOTH:
+ // TBD: should we support hybrid tspec as well?? for now, just fall through
+ default:
+ limLog(pMac, LOGW, FL("AccessType %d not supported\n"),
+ pTspec->tsinfo.traffic.accessPolicy);
+ retval = eSIR_FAILURE;
+ break;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Admit Control Policy
+
+
+/** -------------------------------------------------------------
+\fn limComputeMeanBwUsed
+\brief determime the used/allocated bandwidth
+\param tpAniSirGlobal pMac
+\param tANI_U32 *pBw
+\param tANI_U32 phyMode
+\param tpLimTspecInfo pTspecInfo
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static void
+limComputeMeanBwUsed(
+ tpAniSirGlobal pMac,
+ tANI_U32 *pBw,
+ tANI_U32 phyMode,
+ tpLimTspecInfo pTspecInfo,
+ tpPESession psessionEntry)
+{
+ tANI_U32 ctspec;
+ *pBw = 0;
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++)
+ {
+ if (pTspecInfo->inuse)
+ {
+ tpDphHashNode pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL)
+ {
+ // maybe we should delete the tspec??
+ limLog(pMac, LOGE, FL("Tspec %d (assocId %d): dphNode not found\n"),
+ ctspec, pTspecInfo->assocId);
+ continue;
+ }
+ //FIXME: need to take care of taurusPeer, titanPeer, 11npeer too.
+ *pBw += LIM_STA_BW_ADJUST(pSta->aniPeer, phyMode, pTspecInfo->tspec.meanDataRate);
+ }
+ }
+}
+
+/** -------------------------------------------------------------
+\fn limGetAvailableBw
+\brief based on the phy mode and the bw_factor, determine the total bandwidth that
+ can be supported
+\param tpAniSirGlobal pMac
+\param tANI_U32 *pMaxBw
+\param tANI_U32 *pMinBw
+\param tANI_U32 phyMode
+\param tANI_U32 bw_factor
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static void
+limGetAvailableBw(
+ tpAniSirGlobal pMac,
+ tANI_U32 *pMaxBw,
+ tANI_U32 *pMinBw,
+ tANI_U32 phyMode,
+ tANI_U32 bw_factor)
+{
+ switch (phyMode)
+ {
+ case WNI_CFG_PHY_MODE_11B:
+ *pMaxBw = LIM_TOTAL_BW_11B;
+ *pMinBw = LIM_MIN_BW_11B;
+ break;
+
+ case WNI_CFG_PHY_MODE_11A:
+ *pMaxBw = LIM_TOTAL_BW_11A;
+ *pMinBw = LIM_MIN_BW_11A;
+ break;
+
+ case WNI_CFG_PHY_MODE_11G:
+ case WNI_CFG_PHY_MODE_NONE:
+ default:
+ *pMaxBw = LIM_TOTAL_BW_11G;
+ *pMinBw = LIM_MIN_BW_11G;
+ break;
+ }
+ *pMaxBw *= bw_factor;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitPolicyOversubscription
+\brief simple admission control policy based on oversubscription
+ if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
+ reject the tspec, else admit it. The phy-bw is the peak available bw in the
+ current phy mode. The 'factor' is the configured oversubscription factor.
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\param tpLimAdmitPolicyInfo pAdmitPolicy
+\param tpLimTspecInfo pTspecInfo
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+/*
+ * simple admission control policy based on oversubscription
+ * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
+ * reject the tspec, else admit it. The phy-bw is the peak available bw in the
+ * current phy mode. The 'factor' is the configured oversubscription factor.
+ */
+static tSirRetStatus
+limAdmitPolicyOversubscription(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec,
+ tpLimAdmitPolicyInfo pAdmitPolicy,
+ tpLimTspecInfo pTspecInfo,
+ tpPESession psessionEntry)
+{
+ tANI_U32 totalbw, minbw, usedbw;
+ tANI_U32 phyMode;
+
+ // determine total bandwidth used so far
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ //limComputeMeanBwUsed(pMac, &usedbw, pMac->dph.gDphPhyMode, pTspecInfo);
+ limComputeMeanBwUsed(pMac, &usedbw, phyMode, pTspecInfo, psessionEntry);
+
+ // determine how much bandwidth is available based on the current phy mode
+ //limGetAvailableBw(pMac, &totalbw, &minbw, pMac->dph.gDphPhyMode, pAdmitPolicy->bw_factor);
+ limGetAvailableBw(pMac, &totalbw, &minbw, phyMode, pAdmitPolicy->bw_factor);
+
+ if (usedbw > totalbw) // this can't possibly happen
+ return eSIR_FAILURE;
+
+ if ((totalbw - usedbw) < pTspec->meanDataRate)
+ {
+ limLog(pMac, ADMIT_CONTROL_POLICY_LOGLEVEL,
+ FL("Total BW %d, Used %d, Tspec request %d not possible\n"),
+ totalbw, usedbw, pTspec->meanDataRate);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitPolicy
+\brief determine the current admit control policy and apply it for the offered tspec
+\param tpAniSirGlobal pMac
+\param tSirMacTspecIE *pTspec
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus limAdmitPolicy(
+ tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_FAILURE;
+ tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo;
+
+ switch (pAdmitPolicy->type)
+ {
+ case WNI_CFG_ADMIT_POLICY_ADMIT_ALL:
+ retval = eSIR_SUCCESS;
+ break;
+
+ case WNI_CFG_ADMIT_POLICY_BW_FACTOR:
+ retval = limAdmitPolicyOversubscription(pMac, pTspec,
+ &pMac->lim.admitPolicyInfo, &pMac->lim.tspecInfo[0], psessionEntry);
+ if (retval != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("rejected by BWFactor policy\n"));)
+ break;
+
+ case WNI_CFG_ADMIT_POLICY_REJECT_ALL:
+ retval = eSIR_FAILURE;
+ break;
+
+ default:
+ retval = eSIR_SUCCESS;
+ limLog(pMac, LOGE, FL("Admit Policy %d unknown, admitting all traffic\n"),
+ pAdmitPolicy->type);
+ break;
+ }
+ return retval;
+}
+
+/** -------------------------------------------------------------
+\fn limTspecDelete
+\brief delete the specified tspec
+\param tpAniSirGlobal pMac
+\param tpLimTspecInfo pInfo
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+//-----------------------------------------------------------------------------
+// delete the specified tspec
+void limTspecDelete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo)
+{
+ if (pInfo == NULL)
+ return;
+ //pierre
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tspec entry = %d\n"), pInfo->idx);
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("delete tspec %08X\n"),pInfo);
+ pInfo->inuse = 0;
+
+ // clear the hcca/parameterized queue indicator
+#if 0
+ if ((pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) ||
+ (pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR))
+ queue[pInfo->staid][pInfo->tspec.tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 0;
+#endif
+
+ return;
+}
+
+/** -------------------------------------------------------------
+\fn limTspecFindByStaAddr
+\brief Send halMsg_AddTs to HAL
+\param tpAniSirGlobal pMac
+\param \param tANI_U8 *pAddr
+\param tSirMacTspecIE *pTspecIE
+\param tpLimTspecInfo pTspecList
+\param tpLimTspecInfo *ppInfo
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+// find the specified tspec in the list
+static tSirRetStatus
+limTspecFindByStaAddr(
+ tpAniSirGlobal pMac,
+ tANI_U8 *pAddr,
+ tSirMacTspecIE *pTspecIE,
+ tpLimTspecInfo pTspecList,
+ tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
+ {
+ if ((pTspecList->inuse)
+ && (palEqualMemory( pMac->hHdd,pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr)))
+ && (palEqualMemory( pMac->hHdd,(tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, sizeof(tSirMacTspecIE))))
+ {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+\fn limTspecFindByAssocId
+\brief find tspec with matchin staid and Tspec
+\param tpAniSirGlobal pMac
+\param tANI_U32 staid
+\param tSirMacTspecIE *pTspecIE
+\param tpLimTspecInfo pTspecList
+\param tpLimTspecInfo *ppInfo
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limTspecFindByAssocId(
+ tpAniSirGlobal pMac,
+ tANI_U16 assocId,
+ tSirMacTspecIE *pTspecIE,
+ tpLimTspecInfo pTspecList,
+ tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d\n"), assocId);
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d\n"),
+ pTspecIE->tsinfo.traffic.direction, pTspecIE->tsinfo.traffic.tsid);
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
+ {
+ if ((pTspecList->inuse)
+ && (assocId == pTspecList->assocId)
+ && (palEqualMemory( pMac->hHdd,(tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, sizeof(tSirMacTspecIE))))
+ {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+\fn limFindTspec
+\brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid
+\param tANI_U16 assocId
+\param tpAniSirGlobal pMac
+\param tSirMacTSInfo *pTsInfo
+\param tpLimTspecInfo pTspecList
+\param tpLimTspecInfo *ppInfo
+\return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limFindTspec(
+ tpAniSirGlobal pMac,
+ tANI_U16 assocId,
+ tSirMacTSInfo *pTsInfo,
+ tpLimTspecInfo pTspecList,
+ tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d\n"), assocId);
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d\n"),
+ pTsInfo->traffic.direction, pTsInfo->traffic.tsid);
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
+ {
+ if ((pTspecList->inuse)
+ && (assocId == pTspecList->assocId)
+ && (pTsInfo->traffic.direction == pTspecList->tspec.tsinfo.traffic.direction)
+ && (pTsInfo->traffic.tsid == pTspecList->tspec.tsinfo.traffic.tsid))
+ {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+\fn limTspecAdd
+\brief add or update the specified tspec to the tspec list
+\param tpAniSirGlobal pMac
+\param tANI_U8 *pAddr
+\param tANI_U16 assocId
+\param tSirMacTspecIE *pTspec
+\param tANI_U32 interval
+\param tpLimTspecInfo *ppInfo
+
+\return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+tSirRetStatus limTspecAdd(
+ tpAniSirGlobal pMac,
+ tANI_U8 *pAddr,
+ tANI_U16 assocId,
+ tSirMacTspecIE *pTspec,
+ tANI_U32 interval,
+ tpLimTspecInfo *ppInfo)
+{
+ tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0];
+ *ppInfo = NULL;
+
+ // validate the assocId
+ if (assocId >= pMac->lim.maxStation)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Invalid assocId 0x%x\n"), assocId);)
+ return eSIR_FAILURE;
+ }
+
+ //decide whether to add/update
+ {
+ *ppInfo = NULL;
+
+ if(eSIR_SUCCESS == limFindTspec(pMac, assocId, &pTspec->tsinfo, pTspecList, ppInfo))
+ {
+ //update this entry.
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("updating TSPEC table entry = %d"),
+ (*ppInfo)->idx);
+ }
+ else
+ {
+ /* We didn't find one to update. So find a free slot in the
+ * LIM TSPEC list and add this new entry
+ */
+ tANI_U8 ctspec = 0;
+ for (ctspec = 0 , pTspecList = &pMac->lim.tspecInfo[0]; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
+ {
+ if (! pTspecList->inuse)
+ {
+ limLog(pMac, LOG1, FL("Found free slot in TSPEC list. Add to TSPEC table entry %d"), ctspec);
+ break;
+ }
+ }
+
+ if (ctspec >= LIM_NUM_TSPEC_MAX)
+ return eSIR_FAILURE;
+
+ //Record the new index entry
+ pTspecList->idx = ctspec;
+ }
+ }
+
+ // update the tspec info
+ pTspecList->tspec = *pTspec;
+ pTspecList->assocId = assocId;
+ palCopyMemory( pMac->hHdd, pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr));
+
+ // for edca tspec's, we are all done
+ if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)
+ {
+ pTspecList->inuse = 1;
+ *ppInfo = pTspecList;
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for EDCA AccessPolicy\n"));
+ return eSIR_SUCCESS;
+ }
+
+ /*
+ * for hcca tspec's, must set the parameterized bit in the queues
+ * the 'ts' bit in the queue data structure indicates that the queue is
+ * parameterized (hcca). When the schedule is written this bit is used
+ * in the tsid field (bit 3) and the other three bits (0-2) are simply
+ * filled in as the user priority (or qid). This applies only to uplink
+ * polls where the qos control field must contain the tsid specified in the
+ * tspec.
+ */
+#if 0
+ if ((pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) ||
+ (pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR))
+ queue[staid][pTspec->tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 1;
+#endif
+ pTspecList->inuse = 1;
+ *ppInfo = pTspecList;
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for HCCA AccessPolicy\n"));
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limValidateAccessPolicy
+\brief Validates Access policy
+\param tpAniSirGlobal pMac
+\param tANI_U8 accessPolicy
+\param tANI_U16 assocId
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+limValidateAccessPolicy(
+ tpAniSirGlobal pMac,
+ tANI_U8 accessPolicy,
+ tANI_U16 assocId,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_FAILURE;
+ tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if ((pSta == NULL) || (! pSta->valid))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("invalid station address passed\n"));)
+ return eSIR_FAILURE;
+ }
+
+ switch (accessPolicy)
+ {
+ case SIR_MAC_ACCESSPOLICY_EDCA:
+ if (pSta->wmeEnabled || pSta->lleEnabled)
+ retval = eSIR_SUCCESS;
+ break;
+
+ case SIR_MAC_ACCESSPOLICY_HCCA:
+ case SIR_MAC_ACCESSPOLICY_BOTH:
+#if 0 //only EDCA supported for now.
+ // TBD: check wsm doesn't support the hybrid access policy
+ if (pSta->wsmEnabled || pSta->lleEnabled)
+ retval = eSIR_SUCCESS;
+ break;
+#endif //only EDCA supported for now.
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Invalid accessPolicy %d\n"), accessPolicy);)
+ break;
+ }
+
+ if (retval != eSIR_SUCCESS)
+ limLog(pMac, LOGW, FL("failed (accPol %d, staId %d, lle %d, wme %d, wsm %d)\n"),
+ accessPolicy, pSta->staIndex, pSta->lleEnabled, pSta->wmeEnabled, pSta->wsmEnabled);
+
+ return retval;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitControlAddTS
+\brief Determine if STA with the specified TSPEC can be admitted. If it can,
+ a schedule element is provided
+\param tpAniSirGlobal pMac
+\param tANI_U8 *pAddr,
+\param tSirAddtsReqInfo *pAddts,
+\param tSirMacQosCapabilityIE *pQos,
+\param tANI_U16 assocId, // assocId, valid only if alloc==true
+\param tANI_U8 alloc, // true=>allocate bw for this tspec,
+ // else determine only if space is available
+\param tSirMacScheduleIE *pSch,
+\param tANI_U8 *pTspecIdx //index to the lim tspec table.
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus limAdmitControlAddTS(
+ tpAniSirGlobal pMac,
+ tANI_U8 *pAddr,
+ tSirAddtsReqInfo *pAddts,
+ tSirMacQosCapabilityStaIE *pQos,
+ tANI_U16 assocId, // assocId, valid only if alloc==true
+ tANI_U8 alloc, // true=>allocate bw for this tspec,
+ // else determine only if space is available
+ tSirMacScheduleIE *pSch,
+ tANI_U8 *pTspecIdx, //index to the lim tspec table.
+ tpPESession psessionEntry
+ )
+{
+ tpLimTspecInfo pTspecInfo;
+ tSirRetStatus retval;
+ tANI_U32 svcInterval;
+ (void) pQos;
+
+ // TBD: modify tspec as needed
+ // EDCA: need to fill in the medium time and the minimum phy rate
+ // to be consistent with the desired traffic parameters.
+
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tsid %d, directn %d, start %d, intvl %d, accPolicy %d, up %d\n"),
+ pAddts->tspec.tsinfo.traffic.tsid, pAddts->tspec.tsinfo.traffic.direction,
+ pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval,
+ pAddts->tspec.tsinfo.traffic.accessPolicy, pAddts->tspec.tsinfo.traffic.userPrio);
+
+ // check for duplicate tspec
+ retval = (alloc)
+ ? limTspecFindByAssocId(pMac, assocId, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo)
+ : limTspecFindByStaAddr(pMac, pAddr, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo);
+
+ if (retval == eSIR_SUCCESS)
+ {
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("duplicate tspec (index %d)!\n"), pTspecInfo->idx);
+ return eSIR_FAILURE;
+ }
+
+ // check that the tspec's are well formed and acceptable
+ if (limValidateTspec(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("tspec validation failed\n"));)
+ return eSIR_FAILURE;
+ }
+
+ // determine a service interval for the tspec
+ if (limCalculateSvcInt(pMac, &pAddts->tspec, &svcInterval) != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("SvcInt calculate failed\n"));)
+ return eSIR_FAILURE;
+ }
+
+ // determine if the tspec can be admitted or not based on current policy
+ if (limAdmitPolicy(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("tspec rejected by admit control policy\n"));)
+ return eSIR_FAILURE;
+ }
+
+ // fill in a schedule if requested
+ if (pSch != NULL)
+ {
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pSch, sizeof(*pSch));
+ pSch->svcStartTime = pAddts->tspec.svcStartTime;
+ pSch->svcInterval = svcInterval;
+ pSch->maxSvcDuration = (tANI_U16) pSch->svcInterval; // use SP = SI
+ pSch->specInterval = 0x1000; // fixed for now: TBD
+
+ pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction;
+ pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid;
+ pSch->info.aggregation = 0; // no support for aggregation for now: TBD
+ }
+
+ // if no allocation is requested, done
+ if (! alloc)
+ return eSIR_SUCCESS;
+
+ // check that we are in the proper mode to deal with the tspec type
+ if (limValidateAccessPolicy(pMac, (tANI_U8) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGW, FL("AccessPolicy %d is not valid in current mode\n"),
+ pAddts->tspec.tsinfo.traffic.accessPolicy);
+ return eSIR_FAILURE;
+ }
+
+ // add tspec to list
+ if (limTspecAdd(pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo)
+ != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("no space in tspec list\n"));)
+ return eSIR_FAILURE;
+ }
+
+ //passing lim tspec table index to the caller
+ *pTspecIdx = pTspecInfo->idx;
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitControlDeleteTS
+\brief Delete the specified Tspec for the specified STA
+\param tpAniSirGlobal pMac
+\param tANI_U16 assocId
+\param tSirMacTSInfo *pTsInfo
+\param tANI_U8 *pTsStatus
+\param tANI_U8 *ptspecIdx
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limAdmitControlDeleteTS(
+ tpAniSirGlobal pMac,
+ tANI_U16 assocId,
+ tSirMacTSInfo *pTsInfo,
+ tANI_U8 *pTsStatus,
+ tANI_U8 *ptspecIdx)
+{
+ tpLimTspecInfo pTspecInfo = NULL;
+
+ if (pTsStatus != NULL)
+ *pTsStatus = 0;
+
+ if (limFindTspec(pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0], &pTspecInfo) == eSIR_SUCCESS)
+ {
+ if(pTspecInfo != NULL)
+ {
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Tspec entry %d found\n"), pTspecInfo->idx);
+
+ *ptspecIdx = pTspecInfo->idx;
+ limTspecDelete(pMac, pTspecInfo);
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitControlDeleteSta
+\brief Delete all TSPEC for the specified STA
+\param tpAniSirGlobal pMac
+\param tANI_U16 assocId
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limAdmitControlDeleteSta(
+ tpAniSirGlobal pMac,
+ tANI_U16 assocId)
+{
+ tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0];
+ int ctspec;
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++)
+ {
+ if (assocId == pTspecInfo->assocId)
+ {
+ limTspecDelete(pMac, pTspecInfo);
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Deleting TSPEC %d for assocId %d\n"),
+ ctspec, assocId);
+ }
+ }
+ limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("assocId %d done\n"), assocId);
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limAdmitControlInit
+\brief init tspec table
+\param tpAniSirGlobal pMac
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac)
+{
+ palZeroMemory(pMac->hHdd, pMac->lim.tspecInfo , LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo));
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limUpdateAdmitPolicy
+\brief Set the admit control policy based on CFG parameters
+\param tpAniSirGlobal pMac
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus limUpdateAdmitPolicy(tpAniSirGlobal pMac)
+{
+ tANI_U32 val;
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_POLICY, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_POLICY\n"));
+ return eSIR_FAILURE;
+ }
+ pMac->lim.admitPolicyInfo.type = (tANI_U8) val;
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_BWFACTOR, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_BWFACTOR\n"));
+ return eSIR_FAILURE;
+ }
+ pMac->lim.admitPolicyInfo.bw_factor = (tANI_U8) val;
+
+ PELOG1(limLog(pMac, LOG1, FL("LIM: AdmitPolicy %d, bw_factor %d\n"),
+ pMac->lim.admitPolicyInfo.type, pMac->lim.admitPolicyInfo.bw_factor);)
+
+ return eSIR_SUCCESS;
+}
+
+
+/** -------------------------------------------------------------
+\fn limSendHalMsgAddTs
+\brief Send halMsg_AddTs to HAL
+\param tpAniSirGlobal pMac
+\param tANI_U16 staIdx
+\param tANI_U8 tspecIdx
+\param tSirMacTspecIE tspecIE
+\param tSirTclasInfo *tclasInfo
+\param tANI_U8 tclasProc
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limSendHalMsgAddTs(
+ tpAniSirGlobal pMac,
+ tANI_U16 staIdx,
+ tANI_U8 tspecIdx,
+ tSirMacTspecIE tspecIE,
+ tANI_U8 sessionId)
+{
+ tSirMsgQ msg;
+ tpAddTsParams pAddTsParam;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pAddTsParam, sizeof(tAddTsParams)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pAddTsParam, sizeof(tAddTsParams));
+ pAddTsParam->staIdx = staIdx;
+ pAddTsParam->tspecIdx = tspecIdx;
+ palCopyMemory(pMac->hHdd, &pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE));
+ pAddTsParam->sessionId = sessionId;
+
+ msg.type = WDA_ADD_TS_REQ;
+ msg.bodyptr = pAddTsParam;
+ msg.bodyval = 0;
+
+ /* We need to defer any incoming messages until we get a
+ * WDA_ADD_TS_RSP from HAL.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (tANI_U8*)pAddTsParam);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limSendHalMsgDelTs
+\brief Send halMsg_AddTs to HAL
+\param tpAniSirGlobal pMac
+\param tANI_U16 staIdx
+\param tANI_U8 tspecIdx
+\param tSirAddtsReqInfo addts
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limSendHalMsgDelTs(
+ tpAniSirGlobal pMac,
+ tANI_U16 staIdx,
+ tANI_U8 tspecIdx,
+ tSirDeltsReqInfo delts)
+{
+ tSirMsgQ msg;
+ tpDelTsParams pDelTsParam;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pDelTsParam, sizeof(tDelTsParams)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory() failed\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ msg.type = WDA_DEL_TS_REQ;
+ msg.bodyptr = pDelTsParam;
+ msg.bodyval = 0;
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pDelTsParam, sizeof(tDelTsParams));
+
+ //filling message parameters.
+ pDelTsParam->staIdx = staIdx;
+ pDelTsParam->tspecIdx = tspecIdx;
+
+ PELOGW(limLog(pMac, LOGW, FL("calling wdaPostCtrlMsg()\n"));)
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
+ palFreeMemory(pMac->hHdd, (tANI_U8*)pDelTsParam);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limProcessHalAddTsRsp
+\brief This function process the WDA_ADD_TS_RSP from HAL.
+\ If response is successful, then send back SME_ADDTS_RSP.
+\ Otherwise, send DELTS action frame to peer and then
+\ then send back SME_ADDTS_RSP.
+\
+\param tpAniSirGlobal pMac
+\param tpSirMsgQ limMsg
+-------------------------------------------------------------*/
+void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpAddTsParams pAddTsRspMsg = NULL;
+ tpDphHashNode pSta = NULL;
+ tANI_U16 assocId =0;
+ tSirMacAddr peerMacAddr;
+ tANI_U8 rspReqd = 1;
+ tpPESession psessionEntry = NULL;
+
+
+ /* Need to process all the deferred messages enqueued
+ * since sending the WDA_ADD_TS_REQ.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ if (NULL == limMsg->bodyptr)
+ {
+ limLog(pMac, LOGP, FL("Received WDA_ADD_TS_RSP with NULL "));
+ goto end;
+ }
+
+ pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr);
+
+ // 090803: Use peFindSessionBySessionId() to obtain the PE session context
+ // from the sessionId in the Rsp Msg from HAL
+ psessionEntry = peFindSessionBySessionId(pMac, pAddTsRspMsg->sessionId);
+
+ if(psessionEntry == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId :%d \n"), pAddTsRspMsg->sessionId);)
+ limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec,
+ pMac->lim.gLimAddtsReq.sessionId, pMac->lim.gLimAddtsReq.transactionId);
+ goto end;
+ }
+
+ if(pAddTsRspMsg->status == eHAL_STATUS_SUCCESS)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Received successful ADDTS response from HAL \n"));)
+ // Use the smesessionId and smetransactionId from the PE session context
+ limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_SUCCESS, psessionEntry, pAddTsRspMsg->tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+ goto end;
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Received failure ADDTS response from HAL \n"));)
+
+ // Send DELTS action frame to AP
+ // 090803: Get peer MAC addr from session
+#if 0
+ cfgLen = sizeof(tSirMacAddr);
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMacAddr, &cfgLen) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Fail to retrieve BSSID \n"));
+ goto end;
+ }
+#endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
+
+ // 090803: Add the SME Session ID
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &pAddTsRspMsg->tspec.tsinfo, &pAddTsRspMsg->tspec,
+ //psessionEntry->smeSessionId);
+ psessionEntry);
+
+ // Delete TSPEC
+ // 090803: Pull the hash table from the session
+ pSta = dphLookupAssocId(pMac, pAddTsRspMsg->staIdx, &assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta != NULL)
+ limAdmitControlDeleteTS(pMac, assocId, &pAddTsRspMsg->tspec.tsinfo, NULL, (tANI_U8 *)&pAddTsRspMsg->tspecIdx);
+
+ // Send SME_ADDTS_RSP
+ // 090803: Use the smesessionId and smetransactionId from the PE session context
+ limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+ goto end;
+ }
+
+end:
+ if( pAddTsRspMsg != NULL )
+ palFreeMemory( pMac->hHdd, (void *)pAddTsRspMsg );
+ return;
+}
+
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
new file mode 100644
index 0000000..9bc6c19
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -0,0 +1,2738 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limApi.cc contains the functions that are
+ * exported by LIM to other modules.
+ *
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "palTypes.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#include "wniApi.h"
+#endif
+#include "sirCommon.h"
+#include "sirDebug.h"
+#include "aniParam.h"
+#include "cfgApi.h"
+
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limApi.h"
+#include "limGlobal.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSerDesUtils.h"
+#include "limIbssPeerMgmt.h"
+#include "limAdmitControl.h"
+#include "pmmApi.h"
+#include "logDump.h"
+#include "limSendSmeRspMessages.h"
+#include "wmmApsd.h"
+#include "limTrace.h"
+#include "limSession.h"
+#include "wlan_qct_wda.h"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+
+#include <limFT.h>
+
+#ifdef VOSS_ENABLED
+#include "vos_types.h"
+#include "vos_packet.h"
+#include "wlan_qct_tl.h"
+#include "sysStartup.h"
+#endif
+
+
+static void __limInitScanVars(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimUseScanModeForLearnMode = 1;
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+
+ // Scan related globals on STA
+ pMac->lim.gLimReturnAfterFirstMatch = 0;
+ pMac->lim.gLim24Band11dScanDone = 0;
+ pMac->lim.gLim50Band11dScanDone = 0;
+ pMac->lim.gLimReturnUniqueResults = 0;
+
+ // Background Scan related globals on STA
+ pMac->lim.gLimNumOfBackgroundScanSuccess = 0;
+ pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0;
+ pMac->lim.gLimNumOfForcedBkgndScan = 0;
+ pMac->lim.gLimBackgroundScanDisable = false; //based on BG timer
+ pMac->lim.gLimForceBackgroundScanDisable = false; //debug control flag
+ pMac->lim.gLimBackgroundScanTerminate = TRUE; //controlled by SME
+ pMac->lim.gLimReportBackgroundScanResults = FALSE; //controlled by SME
+
+ pMac->lim.gLimCurrentScanChannelId = 0;
+ pMac->lim.gpLimMlmScanReq = NULL;
+ pMac->lim.gLimMlmScanResultLength = 0;
+ pMac->lim.gLimSmeScanResultLength = 0;
+
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimCachedScanHashTable,
+ sizeof(pMac->lim.gLimCachedScanHashTable));
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+ pMac->lim.gLimBackgroundScanStarted = 0;
+ pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT;
+ pMac->lim.gLimRestoreCBCount = 0;
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimLegacyBssidList, sizeof(pMac->lim.gLimLegacyBssidList));
+#endif
+
+ /* Fill in default values */
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = 0;
+
+#ifdef ANI_AP_SDK
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimScanDurationConvert, sizeof(tLimScanDurationConvert)); /* Used to store converted scan duration values in TU and TICKS */
+#endif /* ANI_AP_SDK */
+
+ // abort scan is used to abort an on-going scan
+ pMac->lim.abortScan = 0;
+ palZeroMemory(pMac->hHdd, &pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo));
+
+//WLAN_SUSPEND_LINK Related
+ pMac->lim.gpLimSuspendCallback = NULL;
+ pMac->lim.gpLimResumeCallback = NULL;
+//end WLAN_SUSPEND_LINK Related
+}
+
+
+static void __limInitBssVars(tpAniSirGlobal pMac)
+{
+
+ palZeroMemory(pMac->hHdd, (void*)pMac->lim.gpSession, sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId);
+
+
+ //pMac->lim.gpLimStartBssReq = NULL;
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimNeighborBssList, sizeof(tSirMultipleNeighborBssInfo));
+#endif
+
+
+
+/* These global variables are moved to session table and intialization is done during session creation Oct 9th Review */
+#if 0
+
+ // Place holder for BSS description that we're
+ // currently joined with
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentBssId, sizeof(tSirMacAddr));
+ pMac->lim.gLimCurrentChannelId = HAL_INVALID_CHANNEL_ID;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentSSID, sizeof(tSirMacSSid));
+ pMac->lim.gLimCurrentBssCaps = 0;
+ QosCaps is a bit map of various qos capabilities - see defn above
+ pMac->lim.gLimCurrentBssQosCaps = 0;
+ pMac->lim.gLimCurrentBssPropCap = 0;
+ pMac->lim.gLimSentCapsChangeNtf = 0;
+
+ // Place holder for BSS description that
+ // we're currently Reassociating
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocBssId, sizeof(tSirMacAddr));
+ pMac->lim.gLimReassocChannelId = 0;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocSSID, sizeof(tSirMacSSid));
+ pMac->lim.gLimReassocBssCaps = 0;
+ pMac->lim.gLimReassocBssQosCaps = 0;
+ pMac->lim.gLimReassocBssPropCap = 0;
+ #endif
+
+ /* This is for testing purposes only, be default should always be off */
+ pMac->lim.gLimForceNoPropIE = 0;
+
+ // pMac->lim.gLimBssIdx = 0;
+
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ pMac->lim.gpLimMlmRemoveKeyReq = NULL;
+ // pMac->lim.gLimStaid = 0; //TO SUPPORT BT-AMP
+
+}
+
+
+static void __limInitStatsVars(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimNumBeaconsRcvd = 0;
+ pMac->lim.gLimNumBeaconsIgnored = 0;
+
+ pMac->lim.gLimNumDeferredMsgs = 0;
+
+ /// Variable to keep track of number of currently associated STAs
+ pMac->lim.gLimNumOfCurrentSTAs = 0;
+ pMac->lim.gLimNumOfAniSTAs = 0; // count of ANI peers
+
+ /// This indicates number of RXed Beacons during HB period
+ //pMac->lim.gLimRxedBeaconCntDuringHB = 0;
+
+ // Heart-Beat interval value
+ pMac->lim.gLimHeartBeatCount = 0;
+
+ // Statistics to keep track of no. beacons rcvd in heart beat interval
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimHeartBeatBeaconStats, sizeof(pMac->lim.gLimHeartBeatBeaconStats));
+
+#ifdef WLAN_DEBUG
+ // Debug counters
+ pMac->lim.numTot = 0;
+ pMac->lim.numBbt = 0;
+ pMac->lim.numProtErr = 0;
+ pMac->lim.numLearn = 0;
+ pMac->lim.numLearnIgnore = 0;
+ pMac->lim.numSme = 0;
+ palZeroMemory(pMac->hHdd, pMac->lim.numMAC, sizeof(pMac->lim.numMAC));
+ pMac->lim.gLimNumAssocReqDropInvldState = 0;
+ pMac->lim.gLimNumAssocReqDropACRejectTS = 0;
+ pMac->lim.gLimNumAssocReqDropACRejectSta = 0;
+ pMac->lim.gLimNumReassocReqDropInvldState = 0;
+ pMac->lim.gLimNumHashMissIgnored = 0;
+ pMac->lim.gLimUnexpBcnCnt = 0;
+ pMac->lim.gLimBcnSSIDMismatchCnt = 0;
+ pMac->lim.gLimNumLinkEsts = 0;
+ pMac->lim.gLimNumRxCleanup = 0;
+ pMac->lim.gLim11bStaAssocRejectCount = 0;
+#endif
+}
+
+
+
+static void __limInitStates(tpAniSirGlobal pMac)
+{
+ // Counts Heartbeat failures
+ pMac->lim.gLimHBfailureCntInLinkEstState = 0;
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
+ pMac->lim.gLimHBfailureCntInOtherStates = 0;
+ pMac->lim.gLimRspReqd = 0;
+ pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE;
+
+ /// MLM State visible across all Sirius modules
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_IDLE_STATE));
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+
+ /// Previous MLM State
+ pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE;
+
+#ifdef GEN4_SCAN
+ // LIM to HAL SCAN Management Message Interface states
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+#endif // GEN4_SCAN
+
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+ /**
+ * Initialize state to eLIM_MLM_OFFLINE_STATE
+ */
+ pMac->lim.gLimSmeState = eLIM_MLM_OFFLINE_STATE;
+#else
+ /**
+ * Initialize state to suspended state and wait for
+ * HAL to send LIM_RESUME_ACTIVITY_NTF message.
+ */
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ pMac->lim.gLimSmeState = eLIM_SME_SUSPEND_STATE;
+#endif /* FEATURE_WLAN_INTEGRATED_SOC */
+
+ /**
+ * By default assume 'unknown' role. This will be updated
+ * when SME_START_BSS_REQ is received.
+ */
+
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlapNonGfParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams));
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimNoShortSlotParams, sizeof(tLimNoShortSlotParams));
+
+ pMac->lim.gLimPhyMode = 0;
+ pMac->lim.scanStartTime = 0; // used to measure scan time
+
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimBssid, sizeof(pMac->lim.gLimBssid));
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr));
+ pMac->lim.ackPolicy = 0;
+
+#if 0 /* Moving all these to session specific elements */
+ pMac->lim.gLimQosEnabled = 0; //11E
+ pMac->lim.gLimWmeEnabled = 0; //WME
+ pMac->lim.gLimWsmEnabled = 0; //WSM
+ pMac->lim.gLimHcfEnabled = 0;
+ pMac->lim.gLim11dEnabled = 0;
+#endif
+
+ pMac->lim.gLimProbeRespDisableFlag = 0; // control over probe response
+}
+
+static void __limInitVars(tpAniSirGlobal pMac)
+{
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimAlternateRadioList, sizeof(tSirMultipleAlternateRadioInfo));
+#endif
+
+ // Place holder for Measurement Req/Rsp/Ind related info
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ pMac->lim.gpLimMeasReq = NULL;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimMeasParams, sizeof(tLimMeasParams));
+ pMac->lim.gpLimMeasData = NULL;
+#endif
+
+ // WDS info
+ pMac->lim.gLimNumWdsInfoInd = 0;
+ pMac->lim.gLimNumWdsInfoSet = 0;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimWdsInfo, sizeof(tSirWdsInfo));
+ /* initialize some parameters */
+ limInitWdsInfoParams(pMac);
+
+ // Deferred Queue Paramters
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq));
+
+ // addts request if any - only one can be outstanding at any time
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq));
+ pMac->lim.gLimAddtsSent = 0;
+ pMac->lim.gLimAddtsRspTimerCount = 0;
+
+ //protection related config cache
+ palZeroMemory(pMac->hHdd, &pMac->lim.cfgProtection, sizeof(tCfgProtection));
+ pMac->lim.gLimProtectionControl = 0;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimAlternateRadio, sizeof(tSirAlternateRadioInfo));
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ // 11h Spectrum Management Related Flag
+ //pMac->lim.gLim11hEnable = 0;
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
+ LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
+ pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE;
+
+ // 11h Quiet Element Related Flag
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ // A count-down value, used on the AP, to send out the
+ // Quiet BSS IE in that many Beacon's
+ pMac->lim.gLimSpecMgmt.quietCount = 0;
+ pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_FALSE;
+ pMac->lim.gLimSpecMgmt.fRadarIntrConfigured = eANI_BOOLEAN_FALSE;
+
+ // WMM Related Flag
+ pMac->lim.gUapsdEnable = 0;
+ pMac->lim.gUapsdPerAcBitmask = 0;
+ pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
+ pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;
+
+ // QoS-AC Downgrade: Initially, no AC is admitted
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0;
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0;
+
+ //dialogue token List head/tail for Action frames request sent.
+ pMac->lim.pDialogueTokenHead = NULL;
+ pMac->lim.pDialogueTokenTail = NULL;
+
+ palZeroMemory(pMac->hHdd, &pMac->lim.tspecInfo, sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX);
+
+ // admission control policy information
+ palZeroMemory(pMac->hHdd, &pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo));
+
+ pMac->lim.gLastBeaconDtimCount = 0;
+ pMac->lim.gLastBeaconDtimPeriod = 0;
+
+ //Scan in Power Save Flag
+ pMac->lim.gScanInPowersave = 0;
+}
+
+static void __limInitAssocVars(tpAniSirGlobal pMac)
+{
+ palZeroMemory(pMac->hHdd, pMac->lim.gpLimAIDpool,
+ sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1));
+ pMac->lim.freeAidHead = 0;
+ pMac->lim.freeAidTail = 0;
+ pMac->lim.gLimAssocStaLimit = WNI_CFG_ASSOC_STA_LIMIT_STADEF;
+
+ // Place holder for current authentication request
+ // being handled
+ pMac->lim.gpLimMlmAuthReq = NULL;
+ pMac->lim.gpLimMlmJoinReq = NULL;
+
+ /// MAC level Pre-authentication related globals
+ pMac->lim.gLimPreAuthChannelNumber = 0;
+ pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr));
+ pMac->lim.gLimNumPreAuthContexts = 0;
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable));
+
+ // Placed holder to deauth reason
+ pMac->lim.gLimDeauthReasonCode = 0;
+
+ // Place holder for Pre-authentication node list
+ pMac->lim.pLimPreAuthList = NULL;
+
+ // Send Disassociate frame threshold parameters
+ pMac->lim.gLimDisassocFrameThreshold = LIM_SEND_DISASSOC_FRAME_THRESHOLD;
+ pMac->lim.gLimDisassocFrameCredit = 0;
+
+ //One cache for each overlap and associated case.
+ palZeroMemory(pMac->hHdd, pMac->lim.protStaOverlapCache, sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE);
+ palZeroMemory(pMac->hHdd, pMac->lim.protStaCache, sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE);
+
+ // Initialize Assoc/ReAssoc Response Data/Frame
+ //pMac->lim.gLimAssocResponseData = NULL;
+
+}
+
+
+static void __limInitTitanVars(tpAniSirGlobal pMac)
+{
+ pMac->lim.gCbMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ SET_CB_STATE_DISABLE( pMac->lim.gCbState );
+ palZeroMemory(pMac->hHdd, &pMac->lim.gLimChannelSwitch, sizeof(tLimChannelSwitchInfo));
+
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_NONE;
+
+ // Debug workaround for BEACON's
+ // State change triggered by "dump 222"
+ pMac->lim.gLimScanOverride = 1;
+ pMac->lim.gLimScanOverrideSaved = eSIR_ACTIVE_SCAN;
+
+
+ // Caches the CB State as desired by SME
+ SET_CB_STATE_DISABLE( pMac->lim.gCbStateProtected );
+
+ // TODO - This needs to be read off of a CFG variable
+
+ pMac->lim.gLimTitanStaCount = 0;
+ pMac->lim.gLimBlockNonTitanSta = 0;
+}
+
+static void __limInitHTVars(tpAniSirGlobal pMac)
+{
+ pMac->lim.htCapabilityPresentInBeacon = 0;
+ pMac->lim.htCapability = 0;
+ pMac->lim.gHTGreenfield = 0;
+ pMac->lim.gHTSupportedChannelWidthSet = 0;
+ pMac->lim.gHTShortGI40Mhz = 0;
+ pMac->lim.gHTShortGI20Mhz = 0;
+ pMac->lim.gHTMaxAmsduLength = 0;
+ pMac->lim.gHTDsssCckRate40MHzSupport = 0;
+ pMac->lim.gHTPSMPSupport = 0;
+ pMac->lim.gHTLsigTXOPProtection = 0;
+ pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC;
+ pMac->lim.gHTAMpduDensity = 0;
+
+ pMac->lim.gMaxAmsduSizeEnabled = false;
+ pMac->lim.gHTMaxRxAMpduFactor = 0;
+ pMac->lim.gHTServiceIntervalGranularity = 0;
+ pMac->lim.gHTControlledAccessOnly = 0;
+ pMac->lim.gHTRecommendedTxWidthSet = 0;
+ pMac->lim.gHTSecondaryChannelOffset = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ pMac->lim.gHTPCOActive = 0;
+
+ pMac->lim.gHTPCOPhase = 0;
+ pMac->lim.gHTSecondaryBeacon = 0;
+ pMac->lim.gHTDualCTSProtection = 0;
+ pMac->lim.gHTSTBCBasicMCS = 0;
+ pMac->lim.gAddBA_Declined = 0; // Flag to Decline the BAR if the particular bit (0-7) is being set
+}
+
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+static tSirRetStatus __limInitConfig( tpAniSirGlobal pMac )
+{
+ tANI_U32 val1, val2, val3, len;
+ tANI_U16 val16;
+ tANI_U8 val8;
+ tSirMacHTCapabilityInfo *pHTCapabilityInfo;
+ tSirMacHTInfoField1 *pHTInfoField1;
+ tpSirPowerSaveCfg pPowerSaveConfig;
+ tSirMacHTParametersInfo *pAmpduParamInfo;
+
+ /* Read all the CFGs here that were updated before peStart is called */
+
+ /* WNI_CFG_CHANNEL_BONDING_MODE */
+
+ handleCBCFGChange( pMac, WNI_CFG_CHANNEL_BONDING_MODE );
+
+ //for Secondary channel, change setupCBMode function OR the caller of that
+ //function during Join (STA) or Start BSS(AP/IBSS) Now update the HT Capability
+ //CFG based on Channel Bonding CFG
+ if(wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+
+ //channel bonding mode could be set to anything from 0 to 4(Titan had these
+ // modes But for Taurus we have only two modes: enable(>0) or disable(=0)
+ pHTCapabilityInfo->supportedChannelWidthSet = val2 ?
+ WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo)
+ != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ val8 = ( tANI_U8 ) val1;
+ pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8;
+ pHTInfoField1->recommendedTxWidthSet =
+ (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet;
+ pMac->lim.gHTRecommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet;
+ if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1)
+ != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_HEART_BEAT_THRESHOLD */
+
+ if( wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) !=
+ eSIR_SUCCESS )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ if(!val1)
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER);
+ pMac->sys.gSysEnableLinkMonitorMode = 0;
+ }
+ else
+ {
+ //No need to activate the timer during init time.
+ pMac->sys.gSysEnableLinkMonitorMode = 1;
+ }
+
+ /* WNI_CFG_SHORT_GI_20MHZ */
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2;
+ pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val3;
+
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) !=
+ eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_MAX_RX_AMPDU_FACTOR */
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG\n"));)
+ return eSIR_FAILURE;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
+ pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) !=
+ eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in
+ limHandleCFGparamUpdate do we want to update this? */
+ if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("cfg get short preamble failed\n"));
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_BSSID - this one is not updated in limHandleCFGparamUpdate do we
+ want to update this? */
+ len = 6;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, pMac->lim.gLimBssid, &len) !=
+ eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("cfg get bssid failed\n"));
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_MAX_PS_POLL */
+
+ /* Allocate and fill in power save configuration. */
+ if (palAllocateMemory(pMac->hHdd, (void **)&pPowerSaveConfig,
+ sizeof(tSirPowerSaveCfg)) != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save "
+ "configuration\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* This context should be valid if power-save configuration message has been
+ * already dispatched during initialization process. Re-using the present
+ * configuration mask
+ */
+ palCopyMemory(pMac->hHdd, pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg,
+ sizeof(tSirPowerSaveCfg));
+
+ /* Note: it is okay to do this since DAL/HAL is alrady started */
+ if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed \n"));)
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_BG_SCAN_CHANNEL_LIST_CHANNEL_LIST */
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA) || defined(ANI_AP_CLIENT_SDK)
+ PELOG1(limLog(pMac, LOG1,
+ FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel\n"));)
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+#endif
+
+ /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */
+
+ /* This was initially done after resume notification from HAL. Now, DAL is
+ started before PE so this can be done here */
+ handleCBCFGChange( pMac, ANI_IGNORE_CFG_ID );
+ handleHTCapabilityandHTInfo(pMac);
+
+ return eSIR_SUCCESS;
+}
+#endif /* FEATURE_WLAN_INTEGRATED_SOC */
+
+/*
+ limStart
+ This function is to replace the __limProcessSmeStartReq since there is no
+ eWNI_SME_START_REQ post to PE.
+*/
+tSirRetStatus limStart(tpAniSirGlobal pMac)
+{
+ tSirResultCodes retCode = eSIR_SUCCESS;
+
+ PELOG1(limLog(pMac, LOG1, FL(" enter\n"));)
+
+ if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
+ {
+ pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ // By default do not return after first scan match
+ pMac->lim.gLimReturnAfterFirstMatch = 0;
+
+ // Initialize MLM state machine
+ limInitMlm(pMac);
+
+ // By default return unique scan results
+ pMac->lim.gLimReturnUniqueResults = true;
+ pMac->lim.gLimSmeScanResultLength = 0;
+ }
+ else
+ {
+ /**
+ * Should not have received eWNI_SME_START_REQ in states
+ * other than OFFLINE. Return response to host and
+ * log error
+ */
+ limLog(pMac, LOGE, FL("Invalid SME state %X\n"),pMac->lim.gLimSmeState );
+ retCode = eSIR_FAILURE;
+ }
+
+ return retCode;
+}
+
+/**
+ * limInitialize()
+ *
+ *FUNCTION:
+ * This function is called from LIM thread entry function.
+ * LIM related global data structures are initialized in this function.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @return None
+ */
+
+tSirRetStatus
+limInitialize(tpAniSirGlobal pMac)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ __limInitAssocVars(pMac);
+ __limInitVars(pMac);
+ __limInitStates(pMac);
+ __limInitStatsVars(pMac);
+ __limInitBssVars(pMac);
+ __limInitScanVars(pMac);
+ __limInitHTVars(pMac);
+ __limInitTitanVars(pMac);
+
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+ status = limStart(pMac);
+ if(eSIR_SUCCESS != status)
+ {
+ return status;
+ }
+#endif /* FEATURE_WLAN_INTEGRATED_SOC */
+
+ /*
+ * MLM will be intitalized when 'START' request comes from SME.
+ * limInitMlm calls limCreateTimers, which actually relies on
+ * CFG to be downloaded. So it should not be called as part of
+ * peStart, as CFG download is happening after peStart.
+ */
+ //limInitMlm(pMac);
+ // Initializations for maintaining peers in IBSS
+ limIbssInit(pMac);
+
+ pmmInitialize(pMac);
+
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrmInitialize(pMac);
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R
+ limFTOpen(pMac);
+#endif
+
+#ifdef WLAN_FEATURE_P2P
+ vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue);
+#endif
+
+#if 0
+
+ vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR);
+ vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN);
+ vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL);
+
+ vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_WARN);
+ vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN);
+ vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR);
+ vos_trace_setLevel(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_SSC, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
+ vos_trace_setLevel(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR);
+
+
+ vos_trace_setLevel(VOS_MODULE_ID_BAL, VOS_TRACE_LEVEL_ERROR);
+
+ vos_trace_setLevel(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR);
+#endif
+ MTRACE(limTraceInit(pMac));
+
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+ //Initialize the configurations needed by PE
+ if( eSIR_FAILURE == __limInitConfig(pMac))
+ {
+ //We need to undo everything in limStart
+ limCleanupMlm(pMac);
+ return eSIR_FAILURE;
+ }
+
+ //initialize the TSPEC admission control table.
+ //Note that this was initially done after resume notification from HAL.
+ //Now, DAL is started before PE so this can be done here
+ limAdmitControlInit(pMac);
+ limRegisterHalIndCallBack(pMac);
+#endif /*FEATURE_WLAN_INTEGRATED_SOC*/
+
+ return status;
+
+} /*** end limInitialize() ***/
+
+
+
+/**
+ * limCleanup()
+ *
+ *FUNCTION:
+ * This function is called upon reset or persona change
+ * to cleanup LIM state
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCleanup(tpAniSirGlobal pMac)
+{
+#ifdef VOSS_ENABLED
+ v_PVOID_t pvosGCTx;
+ VOS_STATUS retStatus;
+#endif
+
+#ifdef WLAN_FEATURE_P2P
+//Before destroying the list making sure all the nodes have been deleted.
+//Which should be the normal case, but a memory leak has been reported.
+
+ tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL;
+
+ while(vos_list_remove_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
+ (vos_list_node_t**)&pLimMgmtRegistration) == VOS_STATUS_SUCCESS)
+ {
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+ FL("Fixing leak! Deallocating pLimMgmtRegistration node"));
+
+ palFreeMemory(pMac, pLimMgmtRegistration);
+ }
+
+ vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);
+#endif
+
+ limCleanupMlm(pMac);
+ limCleanupLmm(pMac);
+
+ // free up preAuth table
+ if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gLimPreAuthTimerTable.pTable);
+ pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
+ pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
+ }
+
+ if(NULL != pMac->lim.pDialogueTokenHead)
+ {
+ limDeleteDialogueTokenList(pMac);
+ }
+
+ if(NULL != pMac->lim.pDialogueTokenTail)
+ {
+ palFreeMemory(pMac->hHdd, (void *) pMac->lim.pDialogueTokenTail);
+ pMac->lim.pDialogueTokenTail = NULL;
+ }
+
+ # if 0
+ if (pMac->lim.gpLimStartBssReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimStartBssReq);
+ pMac->lim.gpLimStartBssReq = NULL;
+ }
+ #endif
+
+ if (pMac->lim.gpLimMlmSetKeysReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ }
+
+ #if 0
+ if (pMac->lim.gpLimJoinReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimJoinReq);
+ pMac->lim.gpLimJoinReq = NULL;
+ }
+ #endif
+
+ if (pMac->lim.gpLimMlmAuthReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+ }
+
+ if (pMac->lim.gpLimMlmJoinReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmJoinReq);
+ pMac->lim.gpLimMlmJoinReq = NULL;
+ }
+
+ #if 0
+ if (pMac->lim.gpLimReassocReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimReassocReq);
+ pMac->lim.gpLimReassocReq = NULL;
+ }
+ #endif
+
+ if (pMac->lim.gpLimMlmRemoveKeyReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmRemoveKeyReq);
+ pMac->lim.gpLimMlmRemoveKeyReq = NULL;
+ }
+
+ if (pMac->lim.gpLimMlmScanReq != NULL)
+ {
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmScanReq);
+ pMac->lim.gpLimMlmScanReq = NULL;
+ }
+
+#if 0
+ if(NULL != pMac->lim.beacon)
+ {
+ palFreeMemory(pMac->hHdd, (void*) pMac->lim.beacon);
+ pMac->lim.beacon = NULL;
+ }
+#endif
+ #if 0
+ if(NULL != pMac->lim.assocReq)
+ {
+ palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocReq);
+ pMac->lim.assocReq= NULL;
+ }
+ #endif
+
+#if 0
+ if(NULL != pMac->lim.assocRsp)
+ {
+ palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocRsp);
+ pMac->lim.assocRsp= NULL;
+ }
+#endif
+ // Now, finally reset the deferred message queue pointers
+ limResetDeferredMsgQ(pMac);
+
+#ifdef VOSS_ENABLED
+
+ pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
+ retStatus = WLANTL_DeRegisterMgmtFrmClient(pvosGCTx);
+
+ if ( retStatus != VOS_STATUS_SUCCESS )
+ PELOGE(limLog(pMac, LOGE, FL("DeRegistering the PE Handle with TL has failed bailing out...\n"));)
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrmCleanup(pMac);
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R
+ limFTCleanup(pMac);
+#endif
+
+} /*** end limCleanup() ***/
+
+
+/** -------------------------------------------------------------
+\fn peOpen
+\brief will be called in Open sequence from macOpen
+\param tpAniSirGlobal pMac
+\param tHalOpenParameters *pHalOpenParam
+\return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam)
+{
+ pMac->lim.maxBssId = pMacOpenParam->maxBssId;
+ pMac->lim.maxStation = pMacOpenParam->maxStation;
+
+ if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("max number of Bssid or Stations cannot be zero!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->lim.limTimers.gpLimCnfWaitTimer, sizeof(TX_TIMER)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->lim.gpLimAIDpool,
+ sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->lim.gpSession, sizeof(tPESession)* pMac->lim.maxBssId))
+ {
+ limLog(pMac, LOGE, FL("memory allocate failed!\n"));
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory(pMac->hHdd, pMac->lim.gpSession, sizeof(tPESession)*pMac->lim.maxBssId);
+
+
+ /*
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->dph.dphHashTable.pHashTable, sizeof(tpDphHashNode)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->dph.dphHashTable.pDphNodeArray, sizeof(tDphHashNode)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+ */
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!\n"));)
+ return eSIR_FAILURE;
+ }
+ palZeroMemory(pMac->hHdd, pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation);
+#endif
+
+#ifdef ANI_PRODUCT_TYPE_AP
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->pmm.gPmmTim.pStaInfo, sizeof(*pMac->pmm.gPmmTim.pStaInfo) * pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pStaInfo!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->pmm.gpPmmStaState, sizeof(tPmmStaState)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->pmm.gpPmmPSState, sizeof(tANI_U8)*pMac->lim.maxStation))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return eSIR_FAILURE;
+ }
+#endif
+
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn peClose
+\brief will be called in close sequence from macClose
+\param tpAniSirGlobal pMac
+\return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus peClose(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+
+ if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG)
+ return eSIR_SUCCESS;
+
+ palFreeMemory(pMac->hHdd, pMac->lim.limTimers.gpLimCnfWaitTimer);
+ pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
+ palFreeMemory(pMac->hHdd, pMac->lim.gpLimAIDpool);
+ pMac->lim.gpLimAIDpool = NULL;
+
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ peDeleteSession(pMac,&pMac->lim.gpSession[i]);
+ }
+ }
+
+ palFreeMemory(pMac->hHdd, pMac->lim.gpSession);
+ pMac->lim.gpSession = NULL;
+ /*
+ palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pHashTable);
+ pMac->dph.dphHashTable.pHashTable = NULL;
+ palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pDphNodeArray);
+ pMac->dph.dphHashTable.pDphNodeArray = NULL;
+ */
+#ifdef WLAN_SOFTAP_FEATURE
+ palFreeMemory(pMac->hHdd, pMac->pmm.gPmmTim.pTim);
+ pMac->pmm.gPmmTim.pTim = NULL;
+#endif
+#ifdef ANI_PRODUCT_TYPE_AP
+ palFreeMemory(pMac->hHdd, pMac->pmm.gPmmTim.pStaInfo);
+ pMac->pmm.gPmmTim.pStaInfo = NULL;
+ palFreeMemory(pMac->hHdd, pMac->pmm.gpPmmStaState);
+ pMac->pmm.gpPmmStaState = NULL;
+ palFreeMemory(pMac->hHdd, pMac->pmm.gpPmmPSState);
+ pMac->pmm.gpPmmPSState = NULL;
+#endif
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn peStart
+\brief will be called in start sequence from macStart
+\param tpAniSirGlobal pMac
+\return none
+ -------------------------------------------------------------*/
+
+tSirRetStatus peStart(tpAniSirGlobal pMac)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ status = limInitialize(pMac);
+#if defined(ANI_LOGDUMP)
+ limDumpInit(pMac);
+#endif //#if defined(ANI_LOGDUMP)
+
+ return status;
+}
+
+/** -------------------------------------------------------------
+\fn peStop
+\brief will be called in stop sequence from macStop
+\param tpAniSirGlobal pMac
+\return none
+ -------------------------------------------------------------*/
+
+void peStop(tpAniSirGlobal pMac)
+{
+ limCleanup(pMac);
+ SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE);
+ return;
+}
+
+/** -------------------------------------------------------------
+\fn peFreeMsg
+\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs)
+\ to free a given PE message on the TX and MC thread.
+\ This happens when there are messages pending in the PE
+\ queue when system is being stopped and reset.
+\param tpAniSirGlobal pMac
+\param tSirMsgQ pMsg
+\return none
+-----------------------------------------------------------------*/
+v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg)
+{
+ if (pMsg != NULL)
+ {
+ if (NULL != pMsg->bodyptr)
+ {
+ if (SIR_BB_XPORT_MGMT_MSG == pMsg->type)
+ {
+ vos_pkt_return_packet((vos_pkt_t *)pMsg->bodyptr);
+ }
+ else
+ {
+ vos_mem_free((v_VOID_t*)pMsg->bodyptr);
+ }
+ }
+ pMsg->bodyptr = 0;
+ pMsg->bodyval = 0;
+ pMsg->type = 0;
+ }
+ return;
+}
+
+
+/**
+ * The function checks if a particular timer should be allowed
+ * into LIM while device is sleeping
+ */
+tANI_U8 limIsTimerAllowedInPowerSaveState(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ tANI_U8 retStatus = TRUE;
+
+ if(!limIsSystemInActiveState(pMac))
+ {
+ switch(pMsg->type)
+ {
+ /* Don't allow following timer messages if in sleep */
+ case SIR_LIM_MIN_CHANNEL_TIMEOUT:
+ case SIR_LIM_MAX_CHANNEL_TIMEOUT:
+ case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
+ retStatus = FALSE;
+ break;
+ /* May allow following timer messages in sleep mode */
+ case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+
+ /* Safe to allow as of today, this triggers background scan
+ * which will not be started if the device is in power-save mode
+ * might need to block in the future if we decide to implement
+ * spectrum management
+ */
+ case SIR_LIM_QUIET_TIMEOUT:
+
+ /* Safe to allow as of today, this triggers background scan
+ * which will not be started if the device is in power-save mode
+ * might need to block in the future if we decide to implement
+ * spectrum management
+ */
+ case SIR_LIM_QUIET_BSS_TIMEOUT:
+
+ /* Safe to allow this timermessage, triggers background scan
+ * which is blocked in sleep mode
+ */
+ case SIR_LIM_CHANNEL_SCAN_TIMEOUT:
+
+ /* Safe to allow this timer, since, while in IMPS this timer will not
+ * be started. In case of BMPS sleep, SoftMAC handles the heart-beat
+ * when heart-beat control is handled back to PE, device would have
+ * already woken-up due to EXIT_BMPS_IND mesage from SoftMAC
+ */
+ case SIR_LIM_HEART_BEAT_TIMEOUT:
+ case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
+
+ /* Safe to allow, PE is not handling this message as of now. May need
+ * to block it, basically, free the buffer and restart the timer
+ */
+ case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+ case SIR_LIM_JOIN_FAIL_TIMEOUT:
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+ case SIR_LIM_AUTH_FAIL_TIMEOUT:
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ retStatus = TRUE;
+ break;
+
+ /* by default allow rest of messages */
+ default:
+ retStatus = TRUE;
+ break;
+
+
+ }
+ }
+
+ return retStatus;
+
+}
+
+
+
+/**
+ * limPostMsgApi()
+ *
+ *FUNCTION:
+ * This function is called from other thread while posting a
+ * message to LIM message Queue gSirLimMsgQ.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMsg - Pointer to the message structure
+ * @return None
+ */
+
+tANI_U32
+limPostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+#ifdef VOSS_ENABLED
+ return vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg);
+
+
+#elif defined(ANI_OS_TYPE_LINUX) || defined(ANI_OS_TYPE_OSX)
+ return tx_queue_send(&pMac->sys.gSirLimMsgQ, pMsg, TX_WAIT_FOREVER);
+
+#else
+ /* Check if this is a timeout message from a timer
+ * and if the timeout message is allowed if the device is in power-save state
+ */
+ if(!limIsTimerAllowedInPowerSaveState(pMac, pMsg))
+ {
+ limLog(pMac, LOGW,
+ FL("Timeout message %d is not allowed while device is in Power-Save mode\n"),
+ pMsg->type);
+
+ return TX_SUCCESS;
+ }
+ if(pMac->gDriverType != eDRIVER_TYPE_MFG)
+ {
+ limMessageProcessor(pMac, pMsg);
+ }
+
+ return TX_SUCCESS;
+
+#endif
+} /*** end limPostMsgApi() ***/
+
+
+/*--------------------------------------------------------------------------
+
+ \brief pePostMsgApi() - A wrapper function to post message to Voss msg queues
+
+ This function can be called by legacy code to post message to voss queues OR
+ legacy code may keep on invoking 'limPostMsgApi' to post the message to voss queue
+ for dispatching it later.
+
+ \param pMac - Pointer to Global MAC structure
+ \param pMsg - Pointer to the message structure
+
+ \return tANI_U32 - TX_SUCCESS for success.
+
+ --------------------------------------------------------------------------*/
+
+tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ return (tSirRetStatus)limPostMsgApi(pMac, pMsg);
+}
+
+/*--------------------------------------------------------------------------
+
+ \brief peProcessMessages() - Message Processor for PE
+
+ Voss calls this function to dispatch the message to PE
+
+ \param pMac - Pointer to Global MAC structure
+ \param pMsg - Pointer to the message structure
+
+ \return tANI_U32 - TX_SUCCESS for success.
+
+ --------------------------------------------------------------------------*/
+
+tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg)
+{
+ if(pMac->gDriverType == eDRIVER_TYPE_MFG)
+ {
+ return eSIR_SUCCESS;
+ }
+ /**
+ * If the Message to be handled is for CFG Module call the CFG Msg Handler and
+ * for all the other cases post it to LIM
+ */
+ if ( SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type))
+ cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr);
+ else
+ limMessageProcessor(pMac, pMsg);
+ return eSIR_SUCCESS;
+}
+
+
+#ifdef VOSS_ENABLED
+
+// ---------------------------------------------------------------------------
+/**
+ * peHandleMgmtFrame
+ *
+ * FUNCTION:
+ * Process the Management frames from TL
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS: TL sends the packet along with the VOS GlobalContext
+ *
+ * NOTE:
+ *
+ * @param pvosGCtx Global Vos Context
+ * @param vossBuff Packet
+ * @return None
+ */
+
+VOS_STATUS peHandleMgmtFrame( v_PVOID_t pvosGCtx, v_PVOID_t vosBuff)
+{
+ tpAniSirGlobal pMac;
+ tpSirMacMgmtHdr mHdr;
+ tSirMsgQ msg;
+ vos_pkt_t *pVosPkt;
+ VOS_STATUS vosStatus;
+ v_U8_t *pRxPacketInfo;
+
+ pVosPkt = (vos_pkt_t *)vosBuff;
+ if (NULL == pVosPkt)
+ {
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, pvosGCtx);
+ if (NULL == pMac)
+ {
+ // cannot log a failure without a valid pMac
+ vos_pkt_return_packet(pVosPkt);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (void *)&pRxPacketInfo, VOS_FALSE );
+
+ if(!VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ vos_pkt_return_packet(pVosPkt);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+
+ //
+ // The MPDU header is now present at a certain "offset" in
+ // the BD and is specified in the BD itself
+ //
+ mHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ if(mHdr->fc.type == SIR_MAC_MGMT_FRAME)
+ {
+ PELOG1(limLog( pMac, LOG1,
+ FL ( "RxBd=%p mHdr=%p Type: %d Subtype: %d Sizes:FC%d Mgmt%d\n"),
+ pRxBd, mHdr, mHdr->fc.type, mHdr->fc.subType, sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr) );)
+
+ MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT, 0,
+ LIM_TRACE_MAKE_RXMGMT(mHdr->fc.subType,
+ (tANI_U16) (((tANI_U16) (mHdr->seqControl.seqNumHi << 4)) | mHdr->seqControl.seqNumLo)));)
+ }
+
+
+ // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG
+ msg.type = SIR_BB_XPORT_MGMT_MSG;
+ msg.bodyptr = vosBuff;
+ msg.bodyval = 0;
+
+ if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac,
+ &msg,
+ mHdr->fc.type,
+ mHdr->fc.subType ))
+ {
+ vos_pkt_return_packet(pVosPkt);
+ limLog( pMac, LOGW,
+ FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG\n" ));
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ return VOS_STATUS_SUCCESS;
+}
+
+// ---------------------------------------------------------------------------
+/**
+ * peRegisterTLHandle
+ *
+ * FUNCTION:
+ * Registers the Handler which, process the Management frames from TL
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @return None
+ */
+
+void peRegisterTLHandle(tpAniSirGlobal pMac)
+{
+ v_PVOID_t pvosGCTx;
+ VOS_STATUS retStatus;
+
+ pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
+
+ retStatus = WLANTL_RegisterMgmtFrmClient(pvosGCTx, peHandleMgmtFrame);
+
+ if (retStatus != VOS_STATUS_SUCCESS)
+ limLog( pMac, LOGP, FL("Registering the PE Handle with TL has failed bailing out...\n"));
+
+}
+#endif
+
+
+/**
+ * limCheckStateForLearnMode()
+ *
+ *FUNCTION:
+ * This function is called by SCH to verify if LIM is in a state
+ * to put system into Learn mode
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return eSIR_SUCCESS - LIM is in a state to put system
+ * into Learn Mode
+ * eSIR_FAILURE - LIM is NOT in a state to put system
+ * into Learn Mode
+ */
+
+tSirRetStatus
+limCheckStateForLearnMode(tpAniSirGlobal pMac)
+{
+ switch (pMac->lim.gLimSmeState)
+ {
+ case eLIM_SME_OFFLINE_STATE:
+ case eLIM_SME_IDLE_STATE:
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ case eLIM_SME_NORMAL_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ // LIM is in a state to put system into Learn mode
+ return eSIR_SUCCESS;
+
+ default:
+ // LIM is NOT in a state to put system into Learn mode
+ return eSIR_FAILURE;
+ }
+} /*** end limCheckStateForLearnMode() ***/
+
+
+
+/**
+ * limIsSystemInScanState()
+ *
+ *FUNCTION:
+ * This function is called by various MAC software modules to
+ * determine if System is in Scan/Learn state
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return true - System is in Scan/Learn state
+ * false - System is NOT in Scan/Learn state
+ */
+
+tANI_U8
+limIsSystemInScanState(tpAniSirGlobal pMac)
+{
+ switch (pMac->lim.gLimSmeState)
+ {
+ case eLIM_SME_CHANNEL_SCAN_STATE:
+ case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+ case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+ case eLIM_SME_WT_SCAN_STATE:
+ // System is in Learn mode
+ return true;
+
+ default:
+ // System is NOT in Learn mode
+ return false;
+ }
+} /*** end limIsSystemInScanState() ***/
+
+
+
+/**
+ * limIsSystemInActiveState()
+ *
+ *FUNCTION:
+ * This function is called by various MAC software modules to
+ * determine if System is in Active/Wakeup state
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return true - System is in Active state
+ * false - System is not in Active state
+ */
+
+tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac)
+{
+ switch (pMac->pmm.gPmmState)
+ {
+ case ePMM_STATE_BMPS_WAKEUP:
+ case ePMM_STATE_IMPS_WAKEUP:
+ case ePMM_STATE_READY:
+ // System is in Active mode
+ return true;
+ default:
+ return false;
+ // System is NOT in Active mode
+ }
+}
+
+
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+/**
+ * limCheckAndQuietBSS()
+ *
+ *FUNCTION:
+ * This function is called by limSetLearnMode() to check
+ * if BSS needs to be quieted and call limQuietBSS() to
+ * send data frame to self for that purpose.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCheckAndQuietBSS(tpAniSirGlobal pMac)
+{
+ tANI_U32 dur;
+
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ // LIM is in AP role. Quiet the BSS before
+ // switching to channel to be learned
+ if (pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration >
+ LIM_MAX_QUIET_DURATION)
+ {
+ // May need to quiet BSS multiple times.
+ // Quiet for a limit of 32 msecs on Learn
+ // duration for now.
+ dur = LIM_MAX_QUIET_DURATION;
+ }
+ else
+ {
+ dur =
+ pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration;
+ }
+ PELOG3(limLog(pMac, LOG3,
+ FL("*** Going to quiet BSS for duration=%d msec\n"),
+ dur);)
+
+ limQuietBss(pMac, dur);
+ }
+} /*** end limCheckAndQuietBSS() ***/
+#endif
+
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+/**
+ * limSetLearnMode()
+ *
+ *FUNCTION:
+ * This function is called to setup system into Learn mode
+ * to collect DFS measurements.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limSetLearnMode(tpAniSirGlobal pMac)
+{
+ limSendHalInitScanReq(pMac, eLIM_HAL_INIT_LEARN_WAIT_STATE, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN);
+ return;
+} /*** end limSetLearnMode() ***/
+
+/**
+ * limContinueChannelLearn()
+ *
+ *FUNCTION:
+ * This function is called to do measurement (learn) on current channel.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+
+void
+limContinueChannelLearn(tpAniSirGlobal pMac)
+{
+ tANI_U8 chanNum;
+ tSirMacSSid ssId;
+ tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+ // Time to collect measurements
+ chanNum = limGetCurrentLearnChannel(pMac);
+
+ // Switch channel
+ pMac->lim.gLimSystemInScanLearnMode = 1;
+
+ if (pMac->lim.gpLimMeasReq->measControl.scanType == eSIR_ACTIVE_SCAN)
+ {
+ /// Prepare and send Probe Request frame
+ ssId.length = 0;
+ /* for learning channel, we don't include any additional IE */
+ limSendProbeReqMgmtFrame(pMac, &ssId, bssId, chanNum,pMac->lim.gSelfMacAddr, 0 , NULL);
+ }
+
+ // Activate Learn duration timer during which
+ // DFS measurements are made.
+ pMac->lim.gLimMeasParams.shortDurationCount++;
+ limDeactivateAndChangeTimer(pMac, eLIM_LEARN_DURATION_TIMER);
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_LEARN_DURATION_TIMER));
+ if (tx_timer_activate(&pMac->lim.gLimMeasParams.learnDurationTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not activate learn duration timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not activate learn duration timer\n"));
+
+ return;
+ }
+} /*** end limContinueChannelLearn() ***/
+
+
+/**
+ * limReEnableLearnMode()
+ *
+ *FUNCTION:
+ * This function is called by various MAC software modules to
+ * re-enable Learn mode measurements.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limReEnableLearnMode(tpAniSirGlobal pMac)
+{
+ PELOG4(limLog(pMac, LOG4, FL("quietEnabled = %d\n"),
+ pMac->lim.gLimSpecMgmt.fQuietEnabled);)
+
+ /** Stop measurement temperorily when radar is detected or channel
+ * switch is running as part of periodic DFS */
+ if (!pMac->lim.gpLimMeasReq || LIM_IS_RADAR_DETECTED(pMac) ||
+ (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING))
+ {
+ return;
+ }
+
+ if (pMac->lim.gLimSpecMgmt.fQuietEnabled)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_QUIET_BSS_TIMER));
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ * priority - HIGH
+ */
+ pMac->lim.limTimers.gLimQuietBssTimer.sessionId = sessionId;
+#endif
+ if (tx_timer_activate(
+ &pMac->lim.limTimers.gLimQuietBssTimer)
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start Quiet Bss timer\n"));
+ return;
+ }
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ }
+ else
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_LEARN_INTERVAL_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_LEARN_INTERVAL_TIMER));
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ */
+ pMac->lim.gLimMeasParams.learnIntervalTimer.sessionId = sessionId;
+#endif
+ if (tx_timer_activate(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not activate Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not start Learn Interval timer\n"));
+ return;
+ }
+ }
+
+ PELOG3(limLog(pMac, LOG3, FL("Re-enabled Learn mode Measurements\n"));)
+ pMac->lim.gLimMeasParams.disableMeasurements = 0;
+
+ return;
+} /*** end limReEnableLearnMode() ***/
+
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+
+
+/**
+*\brief limReceivedHBHandler()
+*
+* This function is called by schBeaconProcess() upon
+* receiving a Beacon on STA. This also gets called upon
+* receiving Probe Response after heat beat failure is
+* detected.
+*
+* param pMac - global mac structure
+* param channel - channel number indicated in Beacon, Probe Response
+* return - none
+*/
+
+
+void
+limReceivedHBHandler(tpAniSirGlobal pMac, tANI_U8 channelId, tpPESession psessionEntry)
+{
+ if((channelId == 0 ) || (channelId == psessionEntry->currentOperChannel) )
+ psessionEntry->LimRxedBeaconCntDuringHB++;
+
+ pMac->pmm.inMissedBeaconScenario = FALSE;
+} /*** end limReceivedHBHandler() ***/
+
+
+
+#if 0
+void limResetHBPktCount(tpPESession psessionEntry)
+{
+ psessionEntry->LimRxedBeaconCntDuringHB = 0;
+}
+#endif
+
+
+/*
+ * limProcessWdsInfo()
+ *
+ *FUNCTION:
+ * This function is called from schBeaconProcess in BP
+ *
+ *PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ * @param propIEInfo - proprietary IE info
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ *
+ *RETURNS:
+ *
+ */
+
+void limProcessWdsInfo(tpAniSirGlobal pMac,
+ tSirPropIEStruct propIEInfo)
+{
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ tpSirSmeWdsInfoInd pSirSmeWdsInfoInd;
+ tANI_U8 *pTemp;
+ tSirMsgQ mmhMsg;
+
+ if (propIEInfo.wdsLength &&
+ propIEInfo.wdsLength <= ANI_WDS_INFO_MAX_LENGTH)
+ {
+ if (pMac->lim.gLimWdsInfo.wdsLength)
+ {
+ if ((propIEInfo.wdsLength ==
+ pMac->lim.gLimWdsInfo.wdsLength) &&
+ (palEqualMemory( pMac->hHdd,propIEInfo.wdsData,
+ pMac->lim.gLimWdsInfo.wdsBytes,
+ pMac->lim.gLimWdsInfo.wdsLength) ))
+
+ return; // no difference in WDS info
+ else
+ {
+ PELOG2(limLog(pMac, LOG2,
+ FL("Cached WDS Info: length %d bytes is: "),
+ pMac->lim.gLimWdsInfo.wdsLength);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2,
+ pMac->lim.gLimWdsInfo.wdsBytes,
+ pMac->lim.gLimWdsInfo.wdsLength);)
+
+ PELOG2(limLog(pMac, LOG2, FL("New WDS Info: length %d bytes is: "),
+ propIEInfo.wdsLength);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2,
+ propIEInfo.wdsData,
+ propIEInfo.wdsLength);)
+
+ pMac->lim.gLimWdsInfo.wdsLength = propIEInfo.wdsLength;
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimWdsInfo.wdsBytes,
+ propIEInfo.wdsData,
+ propIEInfo.wdsLength);
+
+ // send IND to WSM
+ if (eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,
+ (void **) &pSirSmeWdsInfoInd,
+ sizeof(tSirSmeWdsInfoInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("memory allocate failed for WDS_INFO_IND\n"));
+
+ return;
+ }
+
+ pSirSmeWdsInfoInd->messageType = eWNI_SME_WDS_INFO_IND;
+ pSirSmeWdsInfoInd->length = sizeof(tSirSmeWdsInfoInd);
+
+ pSirSmeWdsInfoInd->wdsInfo.wdsLength =
+ pMac->lim.gLimWdsInfo.wdsLength;
+
+ palCopyMemory( pMac->hHdd, pSirSmeWdsInfoInd->wdsInfo.wdsBytes,
+ pMac->lim.gLimWdsInfo.wdsBytes,
+ pMac->lim.gLimWdsInfo.wdsLength);
+
+ pTemp = (tANI_U8 *) pSirSmeWdsInfoInd;
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("eWNI_SME_WDS_INFO_IND length %d bytes is: "),
+ pSirSmeWdsInfoInd->length);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, pTemp,
+ pSirSmeWdsInfoInd->length);)
+
+ mmhMsg.type = eWNI_SME_WDS_INFO_IND;
+ mmhMsg.bodyptr = pSirSmeWdsInfoInd;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ pMac->lim.gLimNumWdsInfoInd++;
+ }
+ }
+ else
+ {
+ // first WDS info
+ pMac->lim.gLimWdsInfo.wdsLength = propIEInfo.wdsLength;
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimWdsInfo.wdsBytes,
+ propIEInfo.wdsData,
+ propIEInfo.wdsLength);
+
+ PELOG1(limLog(pMac, LOG1, FL("First WDS Info: length %d bytes is:\n"),
+ pMac->lim.gLimWdsInfo.wdsLength);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1,
+ pMac->lim.gLimWdsInfo.wdsBytes,
+ pMac->lim.gLimWdsInfo.wdsLength);)
+
+ }
+ }
+ else
+ {
+ PELOG2(limLog(pMac, LOG2,
+ FL("Illegal WDS length = %d\n"),
+ propIEInfo.wdsLength);)
+ }
+#endif
+}
+
+
+
+/**
+ * limInitWdsInfoParams()
+ *
+ *FUNCTION:
+ * This function is called while processing
+ * START_BSS/JOIN/REASSOC_REQ to initialize WDS info
+ * ind/set related parameters.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limInitWdsInfoParams(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimWdsInfo.wdsLength = 0;
+ pMac->lim.gLimNumWdsInfoInd = 0;
+ pMac->lim.gLimNumWdsInfoSet = 0;
+} /*** limInitWdsInfoParams() ***/
+
+
+/** -------------------------------------------------------------
+\fn limUpdateOverlapStaParam
+\brief Updates overlap cache and param data structure
+\param tpAniSirGlobal pMac
+\param tSirMacAddr bssId
+\param tpLimProtStaParams pStaParams
+\return None
+ -------------------------------------------------------------*/
+void
+limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams)
+{
+ int i;
+ if (!pStaParams->numSta)
+ {
+ palCopyMemory( pMac->hHdd, pMac->lim.protStaOverlapCache[0].addr,
+ bssId,
+ sizeof(tSirMacAddr));
+ pMac->lim.protStaOverlapCache[0].active = true;
+
+ pStaParams->numSta = 1;
+
+ return;
+ }
+
+ for (i=0; i<LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.protStaOverlapCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,pMac->lim.protStaOverlapCache[i].addr,
+ bssId,
+ sizeof(tSirMacAddr))) {
+ return; }
+ }
+ else
+ break;
+ }
+
+ if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Overlap cache is full\n"));)
+ }
+ else
+ {
+ palCopyMemory( pMac->hHdd, pMac->lim.protStaOverlapCache[i].addr,
+ bssId,
+ sizeof(tSirMacAddr));
+ pMac->lim.protStaOverlapCache[i].active = true;
+
+ pStaParams->numSta++;
+ }
+}
+
+
+/**
+ * limHandleIBSScoalescing()
+ *
+ *FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pRxPacketInfo - Pointer to RX packet info structure
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+tSirRetStatus
+limHandleIBSScoalescing(
+ tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon,
+ tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tSirRetStatus retCode;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ if ( (!pBeacon->capabilityInfo.ibss) || (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) )
+ /* Received SSID does not match => Ignore received Beacon frame. */
+ retCode = eSIR_LIM_IGNORE_BEACON;
+ else
+ {
+ tANI_U32 ieLen;
+ tANI_U16 tsfLater;
+ tANI_U8 *pIEs;
+ ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ tsfLater = WDA_GET_RX_TSF_LATER(pRxPacketInfo);
+ pIEs = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ PELOG3(limLog(pMac, LOG3, FL("BEFORE Coalescing tsfLater val :%d"), tsfLater);)
+ retCode = limIbssCoalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,psessionEntry);
+ }
+ return retCode;
+} /*** end limHandleIBSScoalescing() ***/
+
+
+
+/**
+ * limDetectChangeInApCapabilities()
+ *
+ *FUNCTION:
+ * This function is called while SCH is processing
+ * received Beacon from AP on STA to detect any
+ * change in AP's capabilities. If there any change
+ * is detected, Roaming is informed of such change
+ * so that it can trigger reassociation.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * Notification is enabled for STA product only since
+ * it is not a requirement on BP side.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBeacon Pointer to parsed Beacon structure
+ * @return None
+ */
+
+void
+limDetectChangeInApCapabilities(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBeacon,
+ tpPESession psessionEntry)
+{
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ tANI_U8 len;
+ tSirSmeApNewCaps apNewCaps;
+ tANI_U8 newChannel;
+ apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
+ newChannel = (tANI_U8) pBeacon->channelNumber;
+
+ if ((psessionEntry->limSentCapsChangeNtf == false) &&
+ (((!limIsNullSsid(&pBeacon->ssId)) && (limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) == false)) ||
+ ((SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) != SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) != SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) != SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) != SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps)) ||
+ (newChannel != psessionEntry->currentOperChannel)
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ || (LIM_BSS_CAPS_GET(HCF, psessionEntry->limCurrentBssQosCaps) !=
+ pBeacon->propIEinfo.hcfEnabled)
+#endif
+ )))
+ {
+
+ /**
+ * BSS capabilities have changed.
+ * Inform Roaming.
+ */
+ len = sizeof(tSirMacCapabilityInfo) +
+ sizeof(tSirMacAddr) + sizeof(tANI_U8) +
+ 3 * sizeof(tANI_U8) + // reserved fields
+ pBeacon->ssId.length + 1;
+
+ palCopyMemory( pMac->hHdd, apNewCaps.bssId,
+ psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ if (newChannel != psessionEntry->currentOperChannel)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Channel Change from %d --> %d - "
+ "Ignoring beacon!\n"),
+ psessionEntry->currentOperChannel, newChannel);)
+ return;
+ }
+ else
+ apNewCaps.channelId = psessionEntry->currentOperChannel;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &apNewCaps.ssId,
+ (tANI_U8 *) &pBeacon->ssId,
+ pBeacon->ssId.length + 1);
+
+ psessionEntry->limSentCapsChangeNtf = true;
+ limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_AP_CAPS_CHANGED,
+ (tANI_U32 *) &apNewCaps,
+ len, psessionEntry->smeSessionId);
+ }
+#endif
+} /*** limDetectChangeInApCapabilities() ***/
+
+
+
+
+// ---------------------------------------------------------------------
+/**
+ * limUpdateShortSlot
+ *
+ * FUNCTION:
+ * Enable/Disable short slot
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable Flag to enable/disable short slot
+ * @return None
+ */
+
+tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, tpSirProbeRespBeacon pBeacon, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+
+ tSirSmeApNewCaps apNewCaps;
+ tANI_U32 cShortSlot, nShortSlot;
+
+ apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, &cShortSlot) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("unable to get short slot time\n"));
+
+ // Earlier implementation: determine the appropriate short slot mode based on AP advertised modes
+ // when erp is present, apply short slot always unless, prot=on && shortSlot=off
+ // if no erp present, use short slot based on current ap caps
+
+ // Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4);
+
+ //Resolution : always use the shortSlot setting the capability info to decide slot time.
+ // The difference between the earlier implementation and the new one is only Case4.
+ /*
+ ERP IE Present | useProtection | shortSlot = QC STA Short Slot
+ Case1 1 1 1 1 //AP should not advertise this combination.
+ Case2 1 1 0 0
+ Case3 1 0 1 1
+ Case4 1 0 0 0
+ Case5 0 1 1 1
+ Case6 0 1 0 0
+ Case7 0 0 1 1
+ Case8 0 0 0 0
+ */
+ nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);
+
+ if (nShortSlot != cShortSlot)
+ {
+ // Short slot time capability of AP has changed. Adopt to it.
+ PELOG1(limLog(pMac, LOG1, FL("Shortslot capability of AP changed: %d\n"), nShortSlot);)
+ ((tpSirMacCapabilityInfo)&psessionEntry->limCurrentBssCaps)->shortSlotTime = (tANI_U16)nShortSlot;
+ pBeaconParams->fShortSlotTime = (tANI_U8) nShortSlot;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
+
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, nShortSlot) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
+ }
+ return eSIR_SUCCESS;
+}
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+
+/**
+ * limUpdateQuietIEInBeacons()
+ *
+ *FUNCTION:
+ * This function is called by specialBeaconProcessing(),
+ * when it is time to generate the next beacon.
+ * If gLimQuietState is not in the INIT state, then it
+ * means that the next beacon may need to include some
+ * information about the Quiet BSS IE.
+ * This function makes that decision based on the current
+ * state of gLimQuietState
+ *
+ *LOGIC:
+ * This routine invokes schSetFixedBeaconFields() only
+ * if necessary, as it is expensive to update the fixed
+ * beacon fields during each beacon interval.
+ *
+ *ASSUMPTIONS:
+ * This Quiet BSS IE will be sent out as part of
+ * Proprietary IE's. If 802.11H is enabled, this IE
+ * will be sent out as defined in the 11H spec
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return true, if the beacon fields need updating
+ * false, if not
+ */
+tANI_BOOLEAN limUpdateQuietIEInBeacons( tpAniSirGlobal pMac )
+{
+ tANI_BOOLEAN fUpdateBeaconFields = eANI_BOOLEAN_TRUE;
+
+ limLog( pMac, LOG2, FL("Quiet BSS State = %d\n"),
+ pMac->lim.gLimSpecMgmt.quietState );
+ switch( pMac->lim.gLimSpecMgmt.quietState )
+ {
+ case eLIM_QUIET_BEGIN:
+ // We need to start broadcasting the Quiet BSS IE
+ // Transition to eLIM_QUIET_RUNNING
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_RUNNING;
+ break;
+
+ case eLIM_QUIET_RUNNING:
+ // Start down-counting...
+ pMac->lim.gLimSpecMgmt.quietCount--;
+ if( pMac->lim.gLimSpecMgmt.quietCount == 0 )
+ {
+ //
+ // We no longer need to broadcast the Quiet BSS IE
+ //
+ // NOTE - We still need to call schSetFixedBeaconFields()
+ // one last time, just to remove the Quiet BSS IE from
+ // the list of fixed beacon fields
+ //
+ // Transition to eLIM_QUIET_END
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
+ limProcessLearnIntervalTimeout(pMac);
+ }
+ break;
+
+ case eLIM_QUIET_CHANGED:
+ //
+ // State possibly changed via setupQuietBss().
+ // This means, gLimQuietCount has been changed!!
+ //
+ // NOTE - We still need to call schSetFixedBeaconFields()
+ // one last time, just to remove the Quiet BSS IE from
+ // the list of fixed beacon fields
+ //
+
+ // Transition to eLIM_QUIET_END
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
+ break;
+
+ case eLIM_QUIET_INIT:
+ case eLIM_QUIET_END:
+ // Transition to eLIM_QUIET_INIT
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ // Fall thru'...
+ default:
+ fUpdateBeaconFields = eANI_BOOLEAN_FALSE;
+ break;
+ }
+
+ return fUpdateBeaconFields;
+}
+
+#endif
+
+#if ((defined ANI_PRODUCT_TYPE_AP) && (defined ANI_AP_SDK))
+void limConvertScanDuration(tpAniSirGlobal pMac)
+{
+ tpSirSmeMeasurementReq pMeasReq = pMac->lim.gpLimMeasReq;
+ tpLimScanDurationConvert scanDurConv = &pMac->lim.gLimScanDurationConvert;
+
+ /* This is not a good idea to convert {long}shortChannelScanDuration from mS to TICKS *
+ * The reason is that {long}shortChannelScanDuration is used all over and a lot of code *
+ * that assumes the old mS definition was never changed to accommodate this new change to TICKS. *
+ * If optimization is needed, create another set of shadow variables to store the converted *
+ * values in Ticks, and TU. */
+ scanDurConv->shortChannelScanDuration_tick =
+ SYS_MS_TO_TICKS(pMeasReq->measDuration.shortChannelScanDuration +SYS_TICK_DUR_MS-1);
+
+ /* convert shortChannelScanDuration to TU also for CB scan, used to set gLimQuietDuration */
+ /* (shortChanneScanDuration * 1000) / 2^10 */
+ scanDurConv->shortChannelScanDuration_TU = (pMeasReq->measDuration.shortChannelScanDuration * 1000) >> 10;
+
+ scanDurConv->longChannelScanDuration_tick =
+ SYS_MS_TO_TICKS(pMeasReq->measDuration.longChannelScanDuration +SYS_TICK_DUR_MS-1);
+
+ /* convert shortChannelScanDuration to TU also for CB scan, used to set gLimQuietDuration */
+ /* (longChanneScanDuration * 1000) / 2^10 */
+ scanDurConv->longChannelScanDuration_TU = (pMeasReq->measDuration.longChannelScanDuration * 1000) >> 10;
+}
+#endif /* ((defined ANI_PRODUCT_TYPE_AP) && (defined ANI_AP_SDK)) */
+
+
+#ifdef ANI_PRODUCT_TYPE_AP
+/**-------------------------------------------------
+\fn limIsRadarEnabled
+
+\brief Checks if radar is enabled
+\param pMac
+\return true - if Both 11h and radar enabled
+ false - if either is not enabled.
+ --------------------------------------------------*/
+tANI_BOOLEAN limIsRadarEnabled(tpAniSirGlobal pMac)
+{
+ tANI_U32 fEnabled;
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &fEnabled) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("HAL: could not retrieve radar config from CFG"));
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ if (!fEnabled)
+ return eANI_BOOLEAN_FALSE;
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_RDET_FLAG, &fEnabled) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("HAL: could not retrieve radar config from CFG"));
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ if (fEnabled)
+ return eANI_BOOLEAN_TRUE;
+
+ return eANI_BOOLEAN_FALSE;
+}
+
+/**---------------------------------------
+\fn limRadarInit
+\brief Initialize Radar Interrupt.
+
+\param pMac
+\return None
+ ----------------------------------------*/
+void limRadarInit(tpAniSirGlobal pMac)
+{
+ tANI_U32 status;
+ tSirMsgQ msg;
+
+ PELOG3(limLog(pMac, LOG3, FL("Radar Interrupt Already configured? %s\n"),
+ pMac->lim.gLimSpecMgmt.fRadarIntrConfigured?"Yes":"No");)
+ /** To avoid configuring the radar multiple times */
+ if (pMac->lim.gLimSpecMgmt.fRadarIntrConfigured)
+ return;
+
+ if (!limIsRadarEnabled(pMac))
+ return;
+ // Prepare and post message to HAL Message Queue
+ msg.type = WDA_INIT_RADAR_IND;
+ msg.bodyptr = NULL;
+ msg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+ status = wdaPostCtrlMsg(pMac, &msg);
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("posting to HAL failed, reason=%d\n"), status);
+ return;
+ }
+ pMac->lim.gLimSpecMgmt.fRadarIntrConfigured = eANI_BOOLEAN_TRUE;
+} /****** end limRadarInit() ******/
+
+#endif
+
+
+/** -----------------------------------------------------------------
+ \brief limHandleLowRssiInd() - handles low rssi indication
+
+ This function process the SIR_HAL_LOW_RSSI_IND message from
+ HAL, and sends a eWNI_SME_LOW_RSSI_IND to CSR.
+
+ \param pMac - global mac structure
+
+ \return
+
+ \sa
+ ----------------------------------------------------------------- */
+void limHandleLowRssiInd(tpAniSirGlobal pMac)
+{
+#if 0 //RSSI related indications will now go to TL and not PE
+ if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
+ (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
+ (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Sending LOW_RSSI_IND to SME \n"));)
+ limSendSmeRsp(pMac, eWNI_SME_LOW_RSSI_IND, eSIR_SME_SUCCESS, 0, 0);
+ }
+ else
+ {
+ limLog(pMac, LOGE,
+ FL("Received SIR_HAL_LOW_RSSI_IND while in incorrect state: %d\n"),
+ pMac->pmm.gPmmState);
+ }
+ return;
+#endif
+}
+
+
+/** -----------------------------------------------------------------
+ \brief limHandleBmpsStatusInd() - handles BMPS status indication
+
+ This function process the SIR_HAL_BMPS_STATUS_IND message from HAL,
+ and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
+ to SME with reason code 'eSME_EXIT_BMPS_IND_RCVD'.
+
+ HAL sends this message when Firmware fails to enter BMPS mode 'AFTER'
+ HAL had already send PE a SIR_HAL_ENTER_BMPS_RSP with status
+ code "success". Hence, HAL needs to notify PE to get out of BMPS mode.
+ This message can also come from FW anytime after we have entered BMPS.
+ This means we should handle it in WoWL and UAPSD states as well
+
+ \param pMac - global mac structure
+ \return - none
+ \sa
+ ----------------------------------------------------------------- */
+void limHandleBmpsStatusInd(tpAniSirGlobal pMac)
+{
+ switch(pMac->pmm.gPmmState)
+ {
+ case ePMM_STATE_BMPS_SLEEP:
+ case ePMM_STATE_UAPSD_WT_SLEEP_RSP:
+ case ePMM_STATE_UAPSD_SLEEP:
+ case ePMM_STATE_UAPSD_WT_WAKEUP_RSP:
+ case ePMM_STATE_WOWLAN:
+ PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME \n"));)
+ limSendExitBmpsInd(pMac, eSME_BMPS_STATUS_IND_RCVD);
+ break;
+
+ default:
+ limLog(pMac, LOGE,
+ FL("Received SIR_HAL_BMPS_STATUS_IND while in incorrect state: %d\n"),
+ pMac->pmm.gPmmState);
+ break;
+ }
+ return;
+}
+
+
+/** -----------------------------------------------------------------
+ \brief limHandleMissedBeaconInd() - handles missed beacon indication
+
+ This function process the SIR_HAL_MISSED_BEACON_IND message from HAL,
+ and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
+ to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'.
+
+ \param pMac - global mac structure
+ \return - none
+ \sa
+ ----------------------------------------------------------------- */
+void limHandleMissedBeaconInd(tpAniSirGlobal pMac)
+{
+ if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
+ (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
+ (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
+ {
+ pMac->pmm.inMissedBeaconScenario = TRUE;
+ PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME \n"));)
+ limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD);
+ }
+ else
+ {
+ limLog(pMac, LOGE,
+ FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d\n"),
+ pMac->pmm.gPmmState);
+ }
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief limMicFailureInd() - handles mic failure indication
+
+ This function process the SIR_HAL_MIC_FAILURE_IND message from HAL,
+
+ \param pMac - global mac structure
+ \return - none
+ \sa
+ ----------------------------------------------------------------- */
+void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ tpSirSmeMicFailureInd pSirSmeMicFailureInd;
+ tpSirSmeMicFailureInd pSirMicFailureInd = (tpSirSmeMicFailureInd)pMsg->bodyptr;
+ tSirMsgQ mmhMsg;
+ tpPESession psessionEntry ;
+ tANI_U8 sessionId;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pSirMicFailureInd->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,
+ FL("session does not exist for given BSSId\n"));
+ return;
+ }
+
+ if (eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,
+ (void **) &pSirSmeMicFailureInd,
+ sizeof(tSirSmeMicFailureInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND\n"));
+ return;
+ }
+
+ pSirSmeMicFailureInd->messageType = eWNI_SME_MIC_FAILURE_IND;
+ pSirSmeMicFailureInd->length = sizeof(pSirSmeMicFailureInd);
+ pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId;
+
+ vos_mem_copy(pSirSmeMicFailureInd->bssId,
+ pSirMicFailureInd->bssId,
+ sizeof(tSirMacAddr));
+
+ vos_mem_copy(pSirSmeMicFailureInd->info.srcMacAddr,
+ pSirMicFailureInd->info.srcMacAddr,
+ sizeof(tSirMacAddr));
+
+ vos_mem_copy(pSirSmeMicFailureInd->info.taMacAddr,
+ pSirMicFailureInd->info.taMacAddr,
+ sizeof(tSirMacAddr));
+
+ vos_mem_copy(pSirSmeMicFailureInd->info.dstMacAddr,
+ pSirMicFailureInd->info.dstMacAddr,
+ sizeof(tSirMacAddr));
+
+ vos_mem_copy(pSirSmeMicFailureInd->info.rxMacAddr,
+ pSirMicFailureInd->info.rxMacAddr,
+ sizeof(tSirMacAddr));
+
+ pSirSmeMicFailureInd->info.multicast =
+ pSirMicFailureInd->info.multicast;
+
+ pSirSmeMicFailureInd->info.keyId=
+ pSirMicFailureInd->info.keyId;
+
+ pSirSmeMicFailureInd->info.IV1=
+ pSirMicFailureInd->info.IV1;
+
+ vos_mem_copy(pSirSmeMicFailureInd->info.TSC,
+ pSirMicFailureInd->info.TSC,SIR_CIPHER_SEQ_CTR_SIZE);
+
+ mmhMsg.type = eWNI_SME_MIC_FAILURE_IND;
+ mmhMsg.bodyptr = pSirSmeMicFailureInd;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+
+/** -----------------------------------------------------------------
+ \brief limIsPktCandidateForDrop() - decides whether to drop the frame or not
+
+ This function is called before enqueuing the frame to PE queue for further processing.
+ This prevents unnecessary frames getting into PE Queue and drops them right away.
+ Frames will be droped in the following scenarios:
+
+ - In Scan State, drop the frames which are not marked as scan frames
+ - In non-Scan state, drop the frames which are marked as scan frames.
+ - Drop INFRA Beacons and Probe Responses in IBSS Mode
+ - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
+
+ \param pMac - global mac structure
+ \return - none
+ \sa
+ ----------------------------------------------------------------- */
+
+tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType)
+{
+ tANI_U32 framelen;
+ tANI_U8 *pBody;
+ tSirMacCapabilityInfo capabilityInfo;
+
+ /*
+ *
+ * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames.
+ * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames.
+ * Allow other mgmt frames, they must be from our own AP, as we don't allow
+ * other than beacons or probe responses in scan state.
+ */
+ if( (subType == SIR_MAC_MGMT_BEACON) ||
+ (subType == SIR_MAC_MGMT_PROBE_RSP))
+ {
+ if(pMac->pmm.inMissedBeaconScenario)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Do not drop beacon and probe response - Missed beacon sceanrio"));)
+ return eMGMT_DROP_NO_DROP;
+ }
+ if (limIsSystemInScanState(pMac))
+ {
+ if( WDA_IS_RX_IN_SCAN(pRxPacketInfo) )
+ return eMGMT_DROP_NO_DROP;
+ else
+ return eMGMT_DROP_NON_SCAN_MODE_FRAME;
+ }
+ else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo))
+ {
+ return eMGMT_DROP_SCAN_MODE_FRAME;
+ }
+ }
+
+ framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ /* Note sure if this is sufficient, basically this condition allows all probe responses and
+ * beacons from an infrastructure network
+ */
+ *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);
+ if(!capabilityInfo.ibss)
+ return eMGMT_DROP_NO_DROP;
+#if 0
+ //Allow the mgmt frames to be queued if STA not in IBSS mode.
+ if (pMac->lim.gLimSystemRole != eLIM_STA_IN_IBSS_ROLE)
+ return eMGMT_DROP_NO_DROP;
+#endif
+
+ //Drop INFRA Beacons and Probe Responses in IBSS Mode
+ if( (subType == SIR_MAC_MGMT_BEACON) ||
+ (subType == SIR_MAC_MGMT_PROBE_RSP))
+ {
+ //drop the frame if length is less than 12
+ if(framelen < LIM_MIN_BCN_PR_LENGTH)
+ return eMGMT_DROP_INVALID_SIZE;
+
+ *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);
+
+ //This can be enhanced to even check the SSID before deciding to enque the frame.
+ if(capabilityInfo.ess)
+ return eMGMT_DROP_INFRA_BCN_IN_IBSS;
+ }
+ else if( (subType == SIR_MAC_MGMT_PROBE_REQ) &&
+ (!WDA_GET_RX_BEACON_SENT(pRxPacketInfo)))
+ {
+ //Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
+ //In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq
+ return eMGMT_DROP_NOT_LAST_IBSS_BCN;
+ }
+
+ return eMGMT_DROP_NO_DROP;
+}
+
+
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c
new file mode 100644
index 0000000..9402dda
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -0,0 +1,3799 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limAssocUtils.cc contains the utility functions
+ * LIM uses while processing (Re) Association messages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "palTypes.h"
+#include "aniGlobal.h"
+#include "wniApi.h"
+#include "sirCommon.h"
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "pmmApi.h"
+#include "cfgApi.h"
+
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limStaHashApi.h"
+#include "limAdmitControl.h"
+#include "limSendMessages.h"
+#include "limIbssPeerMgmt.h"
+#include "limSession.h"
+
+#include "vos_types.h"
+#include "wlan_qct_wda.h"
+
+/*
+ * fill up the rate info properly based on what is actually supported by the peer
+ * TBD TBD TBD
+ */
+void
+limFillSupportedRatesInfo(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tpSirSupportedRates pRates,
+ tpPESession psessionEntry)
+{
+ //pSta will be NULL for self entry, so get the opRateMode based on the self mode.
+ //For the peer entry get it from the peer Capabilities present in hash table
+ if(pSta == NULL)
+ pRates->opRateMode = limGetStaRateMode((tANI_U8)psessionEntry->dot11mode);
+ else
+ pRates->opRateMode = limGetStaPeerType(pMac, pSta, psessionEntry);
+
+}
+
+
+/**
+ * limCmpSSid()
+ *
+ *FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether received SSid is same as SSID in use.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *prxSSid - pointer to SSID structure
+ *
+ * @return status - true for SSID match else false.
+ */
+
+tANI_U8
+limCmpSSid(tpAniSirGlobal pMac, tSirMacSSid *prxSSid,tpPESession psessionEntry)
+{
+
+ if( palEqualMemory( pMac->hHdd, (tANI_U8* ) prxSSid, (tANI_U8 *) &psessionEntry->ssId,
+ (tANI_U8) (psessionEntry->ssId.length + 1)))
+ return true;
+ else
+ return false;
+
+} /****** end limCmpSSid() ******/
+
+
+
+/**
+ * limCompareCapabilities()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received capabilities
+ * match with local capabilities or not.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAssocReq - Pointer to received Assoc Req frame
+ * @param pLocalCapabs - Pointer to local capabilities
+ *
+ * @return status - true for Capabilitity match else false.
+ */
+
+tANI_U8
+limCompareCapabilities(tpAniSirGlobal pMac,
+ tSirAssocReq *pAssocReq,
+ tSirMacCapabilityInfo *pLocalCapabs,tpPESession psessionEntry)
+{
+ tANI_U32 val;
+
+
+ if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) &&
+ (pAssocReq->capabilityInfo.ibss) )
+ {
+ // Requesting STA asserting IBSS capability.
+ return false;
+ }
+
+ // Compare CF capabilities
+ if (pAssocReq->capabilityInfo.cfPollable ||
+ pAssocReq->capabilityInfo.cfPollReq)
+ {
+ // AP does not support PCF functionality
+ return false;
+ }
+
+#if 0 //See CR24696 for analysis
+ // Compare privacy capability
+ if (pAssocReq->capabilityInfo.privacy != pLocalCapabs->privacy)
+ {
+ // AP does not support privacy
+ return false;
+ }
+#endif
+
+ // Compare short preamble capability
+ if (pAssocReq->capabilityInfo.shortPreamble &&
+ (pAssocReq->capabilityInfo.shortPreamble !=
+ pLocalCapabs->shortPreamble))
+ {
+ PELOG1(limLog(pMac, LOG1,
+ FL("Allowing a STA requesting short preamble while AP does not support it\n"));)
+#if 0
+ // AP does not support short preamable
+ return false;
+#endif
+ }
+
+
+ limLog(pMac, LOGW, "QoS in AssocReq: %d, local ShortP: %d\n",
+ pAssocReq->capabilityInfo.qos,
+ pLocalCapabs->qos);
+
+ // Compare QoS capability
+ if (pAssocReq->capabilityInfo.qos &&
+ (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos))
+ {
+ /*Temporary hack for UPF to skip 11e capability check in order to interop with
+ CSR - proper fix needs to be put in place*/
+ if ( 0 != vos_get_skip_11e_check())
+ {
+ limLog(pMac, LOG1, FL("Received unmatched QOS but cfg to suppress - continuing\n"));
+ }
+ else
+ {
+ // AP does not support QoS capability
+ return false;
+ }
+ }
+
+
+ /*
+ * If AP supports shortSlot and if apple user has
+ * enforced association only from shortSlot station,
+ * then AP must reject any station that does not support
+ * shortSlot
+ */
+ if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && (pLocalCapabs->shortSlotTime == 1) )
+
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY \n"));
+ return false;
+ }
+ if(val)
+ {
+ if (pAssocReq->capabilityInfo.shortSlotTime != pLocalCapabs->shortSlotTime)
+ return false;
+ }
+ }
+
+ return true;
+} /****** end limCompareCapabilities() ******/
+
+
+/**
+ * limCheckRxBasicRates()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received rates in
+ * Assoc/Reassoc request frames include all BSS basic rates
+ * or not.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param rxRateSet - pointer to SSID structure
+ *
+ * @return status - true if ALL BSS basic rates are present in the
+ * received rateset else false.
+ */
+
+tANI_U8
+limCheckRxBasicRates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,tpPESession psessionEntry)
+{
+ tSirMacRateSet *pRateSet, basicRate;
+ tANI_U8 i, j, k, match;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pRateSet, sizeof(tSirMacRateSet)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for RATESET\n"));
+
+ return false;
+ }
+
+
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pRateSet->rate,
+ (tANI_U32 *) &cfgLen) != eSIR_SUCCESS)
+ {
+ /// Could not get Operational rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve Operational rateset\n"));
+
+ // Free up memory allocated for rateset
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pRateSet);
+
+ return false;
+ }
+ #endif //TO SUPPORT BT-AMP
+
+ /* Copy operational rate set from session Entry */
+ palCopyMemory(pMac->hHdd, pRateSet->rate, (psessionEntry->rateSet.rate), psessionEntry->rateSet.numRates);
+
+ pRateSet->numRates = psessionEntry->rateSet.numRates;
+
+ // Extract BSS basic rateset from operational rateset
+ for (i = 0, j = 0; i < pRateSet->numRates; i++)
+ {
+ if ((pRateSet->rate[i] & 0x80) == 0x80)
+ {
+ // msb is set, so this is a basic rate
+ basicRate.rate[j++] = pRateSet->rate[i];
+ }
+ }
+
+ /*
+ * For each BSS basic rate, find if it is present in the
+ * received rateset.
+ */
+ for (k = 0; k < j; k++)
+ {
+ match = 0;
+ for (i = 0; i < rxRateSet.numRates; i++)
+ {
+ if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k])
+ match = 1;
+ }
+
+ if (!match)
+ {
+ // Free up memory allocated for rateset
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pRateSet);
+
+ return false;
+ }
+ }
+
+ // Free up memory allocated for rateset
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pRateSet);
+
+ return true;
+} /****** end limCheckRxBasicRates() ******/
+
+
+
+/**
+ * limCheckMCSSet()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received MCS rates in
+ * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param supportedMCSSet - pointer to Supported MCS Rate Set
+ *
+ * @return status - true if ALL MCS Basic Rate Set rates are present in the
+ * received rateset else false.
+ */
+
+tANI_U8
+limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet)
+{
+ tANI_U8 basicMCSSet[SIZE_OF_BASIC_MCS_SET] = {0};
+ tANI_U32 cfgLen = 0;
+ tANI_U8 i;
+ tANI_U8 validBytes;
+ tANI_U8 lastByteMCSMask = 0x1f;
+
+
+ cfgLen = WNI_CFG_BASIC_MCS_SET_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BASIC_MCS_SET,
+ (tANI_U8 *) basicMCSSet,
+ (tANI_U32 *) &cfgLen) != eSIR_SUCCESS)
+ {
+ /// Could not get Basic MCS rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve Basic MCS rateset\n"));
+ return false;
+ }
+
+ validBytes = VALID_MCS_SIZE/8;
+
+ //check if all the Basic MCS Bits are set in supported MCS bitmap
+ for(i=0; i<validBytes; i++)
+ {
+ if( (basicMCSSet[i] & supportedMCSSet[i]) != basicMCSSet[i])
+ {
+ PELOGW(limLog(pMac, LOGW, FL("One of Basic MCS Set Rates is not supported by the Station."));)
+ return false;
+ }
+ }
+
+ //check the last 5 bits of the valid MCS bitmap
+ if( ((basicMCSSet[i] & lastByteMCSMask) & (supportedMCSSet[i] & lastByteMCSMask)) !=
+ (basicMCSSet[i] & lastByteMCSMask))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("One of Basic MCS Set Rates is not supported by the Station."));)
+ return false;
+ }
+
+ return true;
+}
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+#define SECURITY_SUITE_TYPE_MASK 0xFF
+#define SECURITY_SUITE_TYPE_WEP40 0x1
+#define SECURITY_SUITE_TYPE_TKIP 0x2
+#define SECURITY_SUITE_TYPE_CCMP 0x4
+#define SECURITY_SUITE_TYPE_WEP104 0x4
+
+/**
+ * limCheckRxRSNIeMatch()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param rxRSNIe - received RSN IE in (Re)Assco req
+ *
+ * @return status - true if ALL BSS basic rates are present in the
+ * received rateset else false.
+ */
+
+tANI_U8
+limCheckRxRSNIeMatch(tpAniSirGlobal pMac, tDot11fIERSN rxRSNIe,tpPESession pSessionEntry, tANI_U8 staIsHT)
+{
+ tDot11fIERSN *pRSNIe;
+ tANI_U8 i, j, match, onlyNonHtCipher = 1;
+
+
+ //RSN IE should be received from PE
+ pRSNIe = &pSessionEntry->gStartBssRSNIe;
+
+ // Check groupwise cipher suite
+ for (i = 0; i < sizeof(rxRSNIe.gp_cipher_suite); i++)
+ {
+ if (pRSNIe->gp_cipher_suite[i] != rxRSNIe.gp_cipher_suite[i])
+ {
+ return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+ }
+ }
+
+ /*
+ * For each Pairwise cipher suite check whether we support
+ * received pairwise
+ */
+ match = 0;
+ for (i = 0; i < rxRSNIe.pwise_cipher_suite_count; i++)
+ {
+ for(j = 0; j < pRSNIe->pwise_cipher_suite_count; j++)
+ {
+ if(palEqualMemory(pMac,&rxRSNIe.pwise_cipher_suites[i],
+ &pRSNIe->pwise_cipher_suites[j],
+ sizeof(pRSNIe->pwise_cipher_suites[j])))
+ {
+ match = 1;
+ break;
+ }
+ }
+
+ if ((staIsHT)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+ &&( (rxRSNIe.pwise_cipher_suites[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
+#else
+ &&( (rxRSNIe.pwise_cipher_suites[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
+#endif
+ {
+ onlyNonHtCipher=0;
+ }
+
+ }
+
+ if ((!match) || ((staIsHT) && onlyNonHtCipher))
+ {
+ return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
+ }
+ /* Check RSN capabilities */
+ if(rxRSNIe.preauth == true) //this is supported by AP only
+ {
+ return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
+ }
+
+ return eSIR_SUCCESS;
+} /****** end limCheckRxRSNIeMatch() ******/
+
+/**
+ * limCheckRxWPAIeMatch()
+ *
+ *FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param rxWPAIe - Received WPA IE in (Re)Assco req
+ *
+ * @return status - true if ALL BSS basic rates are present in the
+ * received rateset else false.
+ */
+
+tANI_U8
+limCheckRxWPAIeMatch(tpAniSirGlobal pMac, tDot11fIEWPA rxWPAIe,tpPESession pSessionEntry, tANI_U8 staIsHT)
+{
+ tDot11fIEWPA *pWPAIe;
+ tANI_U8 i, j, match, onlyNonHtCipher = 1;
+
+ // WPA IE should be received from PE
+ pWPAIe = &pSessionEntry->gStartBssWPAIe;
+
+ // Check groupwise cipher suite
+ for (i = 0; i < 4; i++)
+ {
+ if (pWPAIe->multicast_cipher[i] != rxWPAIe.multicast_cipher[i])
+ {
+ return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+ }
+ }
+
+ /*
+ * For each Pairwise cipher suite check whether we support
+ * received pairwise
+ */
+ match = 0;
+ for (i = 0; i < rxWPAIe.unicast_cipher_count; i++)
+ {
+ for(j = 0; j < pWPAIe->unicast_cipher_count; j++)
+ {
+ if(palEqualMemory(pMac,rxWPAIe.unicast_ciphers[i],
+ pWPAIe->unicast_ciphers[j],
+ 4))
+ {
+ match = 1;
+ break;
+ }
+ }
+
+ if ((staIsHT)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+ &&( (rxWPAIe.unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
+#else
+ &&( (rxWPAIe.unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP))
+#endif
+ {
+ onlyNonHtCipher=0;
+ }
+
+ }
+
+ if ((!match) || ((staIsHT) && onlyNonHtCipher))
+ {
+ return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
+ }
+
+ return eSIR_SUCCESS;
+} /****** end limCheckRxWPAIeMatch() ******/
+
+#endif /* WLAN_SOFTAP_FEATURE */
+
+/**
+ * limCleanupRxPath()
+ *
+ *FUNCTION:
+ * This function is called to cleanup STA state at SP & RFP.
+ *
+ *LOGIC:
+ * To circumvent RFP's handling of dummy packet when it does not
+ * have an incomplete packet for the STA to be deleted, a packet
+ * with 'more framgents' bit set will be queued to RFP's WQ before
+ * queuing 'dummy packet'.
+ * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010
+ * (Disassociation frame) and routing flags in BD set to eCPU's
+ * Low Priority WQ.
+ * RFP cleans up its local context for the STA id mentioned in the
+ * BD and then pushes BD to eCPU's low priority WQ.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pStaDs Pointer to the per STA data structure
+ * initialized by LIM and maintained at DPH
+ *
+ * @return None
+ */
+
+tSirRetStatus
+limCleanupRxPath(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+
+ PELOGE(limLog( pMac, LOGE, FL("**Initiate cleanup\n"));)
+
+ limAbortBackgroundScan( pMac );
+
+ if (pMac->lim.gLimAddtsSent)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_ADDTS_RSP_TIMER));
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
+ }
+
+ if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE)
+ {
+ limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER,
+ pStaDs->assocId);
+
+ if (!pStaDs->mlmStaContext.updateContext)
+ {
+ /**
+ * There is no context at Polaris to delete.
+ * Release our assigned AID back to the free pool
+ */
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
+ {
+ limReleaseAID(pMac, pStaDs->assocId);
+ }
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry);
+
+ return retCode;
+ }
+ }
+
+ //delete all tspecs associated with this sta.
+ limAdmitControlDeleteSta(pMac, pStaDs->assocId);
+
+#if (WNI_POLARIS_FW_PRODUCT==AP)
+ // Reset PMM state for this STA if it exists
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+ pmmUpdatePMMode(pMac, pStaDs->assocId, 0);
+#endif
+
+ /**
+ * Make STA hash entry invalid at eCPU so that DPH
+ * does not process any more data packets and
+ * releases those BDs
+ */
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+ psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+ /* Deactivating probe after heart beat timer */
+ limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+ limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER);
+ pMac->lim.gLastBeaconDtimCount = 0;
+ pMac->lim.gLastBeaconDtimPeriod = 0;
+
+#ifdef FEATURE_WLAN_CCX
+ limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
+#endif
+
+ /**
+ * Update the status for PMM module
+ */
+ pmmResetPmmState(pMac);
+ }
+#ifdef WLAN_DEBUG
+ // increment a debug count
+ pMac->lim.gLimNumRxCleanup++;
+#endif
+
+ if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
+ retCode = limDelBss( pMac, pStaDs, psessionEntry->bssIdx, psessionEntry);
+ }
+ else
+ retCode = limDelSta( pMac, pStaDs, true, psessionEntry);
+
+ return retCode;
+
+} /*** end limCleanupRxPath() ***/
+
+
+/**
+ * limSendDelStaCnf()
+ *
+ *FUNCTION:
+ * This function is called to send appropriate CNF message to SME
+ *
+ *LOGIC:
+ *
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tpAniSirGlobal pMac,
+ * @param tSirMacAddr staDsAddr,
+ * @param tANI_U16 staDsAssocId,
+ * @param tLimMlmStaContext mlmStaContext,
+ * @param tSirResultCodes statusCode
+ *
+ * @return None
+ */
+
+void
+limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr,
+ tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry)
+{
+
+ tLimMlmDisassocCnf mlmDisassocCnf;
+ tLimMlmDeauthCnf mlmDeauthCnf;
+ tLimMlmPurgeStaInd mlmPurgeStaInd;
+
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ // Set BSSID at CFG to null
+ tSirMacAddr nullAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) &nullAddr,
+ sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ /// Could not update BSSID at CFG. Log error.
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+
+ return;
+ }
+ #endif//TO SUPPORT BT-AMP
+
+ sirCopyMacAddr(nullAddr,psessionEntry->bssId);
+
+ // Free up buffer allocated for JoinReq held by
+ // MLM state machine
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ psessionEntry->limAID = 0;
+
+
+ }
+
+ if ((mlmStaContext.cleanupTrigger ==
+ eLIM_HOST_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_LINK_MONITORING_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_PROMISCUOUS_MODE_DISASSOC))
+ {
+ /**
+ * Host or LMM driven Disassociation.
+ * Issue Disassoc Confirm to SME.
+ */
+ limLog( pMac, LOGW, FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %X\n"), mlmStaContext.cleanupTrigger);
+
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &mlmDisassocCnf.peerMacAddr,
+ (tANI_U8 *) staDsAddr,
+ sizeof(tSirMacAddr));
+ mlmDisassocCnf.resultCode = statusCode;
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmDisassocCnf.aid = staDsAssocId;
+#endif
+ mlmDisassocCnf.disassocTrigger =
+ mlmStaContext.cleanupTrigger;
+ /* Update PE session Id*/
+ mlmDisassocCnf.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DISASSOC_CNF,
+ (tANI_U32 *) &mlmDisassocCnf);
+ }
+ else if ((mlmStaContext.cleanupTrigger ==
+ eLIM_HOST_DEAUTH) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_LINK_MONITORING_DEAUTH))
+ {
+ /**
+ * Host or LMM driven Deauthentication.
+ * Issue Deauth Confirm to SME.
+ */
+ limLog( pMac, LOGW, FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %X\n"), mlmStaContext.cleanupTrigger);
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthCnf.peerMacAddr,
+ (tANI_U8 *) staDsAddr,
+ sizeof(tSirMacAddr));
+ mlmDeauthCnf.resultCode = statusCode;
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmDeauthCnf.aid = staDsAssocId;
+#endif
+ mlmDeauthCnf.deauthTrigger =
+ mlmStaContext.cleanupTrigger;
+ /* PE session Id */
+ mlmDeauthCnf.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DEAUTH_CNF,
+ (tANI_U32 *) &mlmDeauthCnf);
+ }
+ else if ((mlmStaContext.cleanupTrigger ==
+ eLIM_PEER_ENTITY_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_PEER_ENTITY_DEAUTH))
+ {
+ /**
+ * Received Disassociation/Deauthentication from peer.
+ * Issue Purge Ind to SME.
+ */
+ limLog( pMac, LOGW, FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %X\n"), mlmStaContext.cleanupTrigger) ;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmPurgeStaInd.peerMacAddr,
+ (tANI_U8 *) staDsAddr,
+ sizeof(tSirMacAddr));
+ mlmPurgeStaInd.reasonCode = (tANI_U8) mlmStaContext.disassocReason;
+ mlmPurgeStaInd.aid = staDsAssocId;
+ mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
+ mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_PURGE_STA_IND,
+ (tANI_U32 *) &mlmPurgeStaInd);
+ }
+ else if(mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE)
+ {
+ //PE setup the peer entry in HW upfront, right after join is completed.
+ //If there is a failure during rest of the assoc sequence, this context needs to be cleaned up.
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimJoinReq);
+ psessionEntry->pLimJoinReq = NULL;
+
+ if(mlmStaContext.resultCode != eSIR_SME_SUCCESS)
+ {
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+
+ limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, mlmStaContext.resultCode, mlmStaContext.protStatusCode,
+ psessionEntry, smesessionId, smetransactionId);
+
+ }
+
+ if((NULL != psessionEntry)
+#ifdef WLAN_SOFTAP_FEATURE
+ && (eLIM_AP_ROLE != psessionEntry->limSystemRole )
+#endif
+ )
+ {
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+}
+
+/**
+ * limRejectAssociation()
+ *
+ *FUNCTION:
+ * This function is called whenever Re/Association Request need
+ * to be rejected due to failure in assigning an AID or failure
+ * in adding STA context at Polaris or reject by applications.
+ *
+ *LOGIC:
+ * Resources allocated if any are freedup and (Re) Association
+ * Response frame is sent to requesting STA. Pre-Auth context
+ * will be added for this STA if it does not exist already
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param *pBd - A pointer to Buffer descriptor + associated PDUs
+ * @param subType - Indicates whether it is Association Request (=0) or
+ * Reassociation Request (=1) frame
+ * @param addPreAuthContext - Indicates whether pre-auth context
+ * to be added for this STA
+ * @param authType - Indicates auth type to be added
+ * @param staId - Indicates staId of the STA being rejected
+ * association
+ * @param deleteSta - Indicates whether to delete STA context
+ * at Polaris
+ * @param rCode - Indicates what reasonCode to be sent in
+ * Re/Assoc response to STA
+ *
+ * @return None
+ */
+
+void
+limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType,
+ tANI_U8 addPreAuthContext, tAniAuthType authType,
+ tANI_U16 staId, tANI_U8 deleteSta, tSirResultCodes rCode, tpPESession psessionEntry )
+{
+ tpDphHashNode pStaDs;
+
+ if (addPreAuthContext)
+ {
+ // Create entry for this STA in pre-auth list
+ struct tLimPreAuthNode *pAuthNode;
+
+ pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
+
+ if (pAuthNode)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAuthNode->peerMacAddr,
+ peerAddr,
+ sizeof(tSirMacAddr));
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+ pAuthNode->authType = (tAniAuthType) authType;
+ limAddPreAuthNode(pMac, pAuthNode);
+ }
+ }
+
+ if (deleteSta == true)
+ {
+ pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ limLog(pMac, LOGW,
+ FL("No STA context, yet rejecting Association\n"));
+
+ return;
+ }
+
+ /**
+ * Polaris has state for this STA.
+ * Trigger cleanup.
+ */
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;
+
+ // Receive path cleanup
+ limCleanupRxPath(pMac, pStaDs, psessionEntry);
+
+ // Send Re/Association Response with
+ // status code to requesting STA.
+ limSendAssocRspMgmtFrame(pMac,
+ rCode,
+ 0,
+ peerAddr,
+ subType, 0,psessionEntry);
+
+ if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL)
+ {
+ // Assoction confirmation is complete, free the copy of association request frame
+ if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame)
+ {
+ palFreeMemory(pMac->hHdd,((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame);
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL;
+ }
+ palFreeMemory(pMac->hHdd, psessionEntry->parsedAssocReq[pStaDs->assocId]);
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
+ }
+ }
+ else
+ {
+ limSendAssocRspMgmtFrame(pMac,
+ eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
+ 1,
+ peerAddr,
+ subType, 0,psessionEntry);
+ // Log error
+ limLog(pMac, LOGW,
+ FL("received Re/Assoc req when max associated STAs reached from \n"));
+ limPrintMacAddr(pMac, peerAddr, LOGW);
+ limSendSmeMaxAssocExceededNtf(pMac, peerAddr, psessionEntry->smeSessionId);
+ }
+} /*** end limRejectAssociation() ***/
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+/** -------------------------------------------------------------
+\fn limDecideApProtectionOnHt20Delete
+\brief protection related function while HT20 station is getting deleted.
+\param tpAniSirGlobal pMac
+\param tpDphHashNode pStaDs
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+static void
+limDecideApProtectionOnHt20Delete(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ tANI_U32 i = 0;
+ PELOG1( limLog(pMac, LOG1, FL("(%d) A HT 20 STA is disassociated. Addr is "),
+ psessionEntry->gLimHt20Params.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLimHt20Params.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLimHt20Params.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLimHt20Params.numSta == 0)
+ {
+ // disable protection
+ limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+}
+/** -------------------------------------------------------------
+\fn limDecideApProtectionOnDelete
+\brief Decides about protection related settings when a station is getting deleted.
+\param tpAniSirGlobal pMac
+\param tpDphHashNode pStaDs
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+void
+limDecideApProtectionOnDelete(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ tANI_U32 phyMode;
+ tHalBitVal erpEnabled = eHAL_CLEAR;
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 i;
+
+ if(NULL == pStaDs)
+ return;
+
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ if(SIR_BAND_5_GHZ == rfBand)
+ {
+ //we are HT. if we are 11A, then protection is not required.
+ if(true == psessionEntry->htCapabality)
+ {
+ //we are HT and 11A station is leaving.
+ //protection consideration required.
+ //HT station leaving ==> this case is commonly handled between both the bands below.
+ if((psessionEntry->beaconParams.llaCoexist) &&
+ (false == pStaDs->mlmStaContext.htCapability))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A 11A STA is disassociated. Addr is "),
+ psessionEntry->gLim11aParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLim11aParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLim11aParams.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if(psessionEntry->gLim11aParams.numSta == 0)
+ {
+ // disable protection
+ limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ }
+ else if(SIR_BAND_2_4_GHZ == rfBand)
+ {
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ erpEnabled = pStaDs->erpEnabled;
+ //we are HT or 11G and 11B station is getting deleted.
+ if (((phyMode == WNI_CFG_PHY_MODE_11G) ||
+ psessionEntry->htCapabality) &&
+ (erpEnabled == eHAL_CLEAR))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A legacy STA is disassociated. Addr is "),
+ psessionEntry->gLim11bParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLim11bParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLim11bParams.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLim11bParams.numSta == 0)
+ {
+ // disable protection
+ PELOG1(limLog(pMac, LOG1, FL("No 11B STA exists\n"));)
+ limEnable11gProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+ }
+ //(non-11B station is leaving) or (we are not 11G or HT AP)
+ else if(psessionEntry->htCapabality)
+ { //we are HT AP and non-11B station is leaving.
+
+ //11g station is leaving
+ if(!pStaDs->mlmStaContext.htCapability)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A 11g STA is disassociated. Addr is "),
+ psessionEntry->gLim11bParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLim11gParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLim11gParams.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLim11gParams.numSta == 0)
+ {
+ // disable protection
+ limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ }
+
+ //LSIG TXOP not supporting staiton leaving. applies to 2.4 as well as 5 GHZ.
+ if((true == psessionEntry->htCapabality) &&
+ (true == pStaDs->mlmStaContext.htCapability))
+ {
+ //HT non-GF leaving
+ if(!pStaDs->htGreenfield)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A non-GF STA is disassociated. Addr is "),
+ psessionEntry->gLimNonGfParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLimNonGfParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLimNonGfParams.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLimNonGfParams.numSta == 0)
+ {
+ // disable protection
+ limEnableHTNonGfProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+ }
+ //HT 20Mhz station leaving.
+ if(psessionEntry->beaconParams.ht20Coexist &&
+ (eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet))
+ {
+ limDecideApProtectionOnHt20Delete(pMac, pStaDs, pBeaconParams,psessionEntry);
+ }
+
+ if(false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport &&
+ (false == pStaDs->htLsigTXOPProtection))
+ {
+ PELOG1( limLog(pMac, LOG1, FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is "),
+ psessionEntry->gLimLsigTxopParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLimLsigTxopParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,psessionEntry->protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLimLsigTxopParams.numSta--;
+ psessionEntry->protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLimLsigTxopParams.numSta == 0)
+ {
+ // disable protection
+ limEnableHTLsigTxopProtection(pMac, true, false, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+}
+
+#endif
+
+
+/** -------------------------------------------------------------
+\fn limDecideShortPreamble
+\brief Decides about any short preamble reated change because of new station joining.
+\param tpAniSirGlobal pMac
+\param tpDphHashNode pStaDs
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+void limDecideShortPreamble(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry )
+{
+ tANI_U32 i;
+
+ if (pStaDs->shortPreambleEnabled == eHAL_CLEAR)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short preamble STA is disassociated. Addr is "),
+ psessionEntry->gLimNoShortParams.numNonShortPreambleSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->gLimNoShortParams.staNoShortCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd, psessionEntry->gLimNoShortParams.staNoShortCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLimNoShortParams.numNonShortPreambleSta--;
+ psessionEntry->gLimNoShortParams.staNoShortCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta == 0)
+ {
+ // enable short preamble
+ PELOG1(limLog(pMac, LOG1, FL("All associated STAs have short preamble support now.\n"));)
+ //reset the cache
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)&psessionEntry->gLimNoShortParams , sizeof(tLimNoShortParams));
+ if (limEnableShortPreamble(pMac, true, pBeaconParams, psessionEntry) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Cannot enable short preamble\n"));)
+ }
+ }
+}
+
+/** -------------------------------------------------------------
+\fn limDecideShortSlot
+\brief Decides about any short slot time related change because of station leaving the BSS.
+\param tpAniSirGlobal pMac
+\param tpDphHashNode pStaDs
+\return None
+ -------------------------------------------------------------*/
+
+void
+limDecideShortSlot(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tANI_U32 i, val;
+ if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short slottime STA is disassociated. Addr is "),
+ pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta> 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd, psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta--;
+ psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+ else
+#endif
+ {
+ if (pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta> 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd, pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta--;
+ pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta == 0))
+ {
+ // enable short slot time
+ PELOG1(limLog(pMac, LOG1, FL("All associated STAs have short slot time support now.\n"));)
+ //reset the cache
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)&psessionEntry->gLimNoShortSlotParams , sizeof(tLimNoShortSlotParams));
+ // in case of AP set SHORT_SLOT_TIME to enable
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ pBeaconParams->fShortSlotTime = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
+
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, true) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
+ }
+ }
+ else
+#endif
+ {
+ if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta == 0)
+ {
+ // enable short slot time
+ PELOG1(limLog(pMac, LOG1, FL("All associated STAs have short slot time support now.\n"));)
+ //reset the cache
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)&pMac->lim.gLimNoShortSlotParams , sizeof(tLimNoShortSlotParams));
+ // in case of AP set SHORT_SLOT_TIME to enable
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ pBeaconParams->fShortSlotTime = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
+
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, true) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
+ }
+ }
+ }
+ }
+}
+
+/**
+ * limRestorePreReassocState()
+ *
+ *FUNCTION:
+ * This function is called on STA role whenever Reasociation
+ * Response with a reject code is received from AP.
+ *
+ *LOGIC:
+ * Reassociation failure timer is stopped, Old (or current) AP's
+ * context is restored both at Polaris & software
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param resultCode - Result code that specifies why Reassociation
+ * attemp failed
+ *
+ * @return None
+ */
+
+void
+limRestorePreReassocState(tpAniSirGlobal pMac,
+ tSirResultCodes resultCode,
+ tANI_U16 protStatusCode,tpPESession psessionEntry)
+{
+ tANI_U8 chanNum;
+ tLimMlmReassocCnf mlmReassocCnf;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_LINK_ESTABLISHED_STATE));
+ psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+ // 'Change' timer for future activations
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ // Update BSSID at CFG database
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_BSSID,
+ pMac->lim.gLimCurrentBssId,
+ sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ /// Could not update BSSID at CFG. Log error.
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+ return;
+ }
+ #endif
+
+ // chanNum = pMac->lim.gLimCurrentChannelId;
+
+ /* To support BT-AMP */
+ chanNum = psessionEntry->currentOperChannel;
+
+ limSetChannel(pMac, psessionEntry->limCurrentTitanHtCaps, chanNum, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+
+ /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */
+
+ mlmReassocCnf.resultCode = resultCode;
+ mlmReassocCnf.protStatusCode = protStatusCode;
+ /* Update PE session Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ limPostSmeMessage(pMac,
+ LIM_MLM_REASSOC_CNF,
+ (tANI_U32 *) &mlmReassocCnf);
+} /*** end limRestorePreReassocState() ***/
+
+
+
+/**
+ * limIsReassocInProgress()
+ *
+ *FUNCTION:
+ * This function is called to see if STA is in wt-reassoc-rsp state.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return eANI_BOOLEAN_TRUE When STA is waiting for Reassoc response from AP \n
+ * else eANI_BOOLEAN_FALSE
+ */
+
+eAniBoolean
+limIsReassocInProgress(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ if(((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
+ ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_LINK_FAIL_STATE)))
+ return eANI_BOOLEAN_TRUE;
+
+ return eANI_BOOLEAN_FALSE;
+} /*** end limIsReassocInProgress() ***/
+
+
+
+/**
+ * limPopulateOwnRateSet
+ *
+ * FUNCTION:
+ * This function is called by limProcessAssocRsp() or
+ * limAddStaInIBSS()
+ * - It creates a combined rate set of 12 rates max which
+ * comprises the basic and extended rates read from CFG
+ * - It sorts the combined rate Set and copy it in the
+ * rate array of the pSTA descriptor
+ * - It sets the erpEnabled bit of the STA descriptor
+ *
+ * NOTE:
+ * ERP bit is set iff the dph PHY mode is 11G and there is at least
+ * an A rate in the supported or extended rate sets
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param basicOnly - When passed value is true, only basic
+ * rates are copied to DPH node else
+ * all supported rates are copied
+ * @return eSIR_SUCCESS or eSIR_FAILURE
+ *
+ */
+
+tSirRetStatus
+limPopulateOwnRateSet(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ tANI_U8* pSupportedMCSSet,
+ tANI_U8 basicOnly,
+ tpPESession psessionEntry)
+{
+ tSirMacRateSet tempRateSet;
+ tSirMacRateSet tempRateSet2;
+ tANI_U32 i,j,val,min,isArate;
+ tANI_U32 phyMode = 0;
+
+ isArate = 0;
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ // Get own rate set
+ #if 0
+ val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &tempRateSet.rate,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve rateset\n"));
+ }
+ #endif // TO SUPPORT BT-AMP
+
+ /* copy operational rate set from psessionEntry */
+ palCopyMemory(pMac->hHdd,(tANI_U8 *)tempRateSet.rate,(tANI_U8*)(psessionEntry->rateSet.rate), psessionEntry->rateSet.numRates);
+ tempRateSet.numRates = psessionEntry->rateSet.numRates;
+
+ if (phyMode == WNI_CFG_PHY_MODE_11G)
+ {
+
+ // get own extended rate set
+ #if 0
+ val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &tempRateSet2.rate,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get extended rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve extended rateset\n"));
+ }
+ tempRateSet2.numRates = (tANI_U8) val;
+ #endif
+
+ palCopyMemory(pMac->hHdd,(tANI_U8 *)tempRateSet2.rate, (tANI_U8*)(psessionEntry->extRateSet.rate), psessionEntry->extRateSet.numRates);
+ tempRateSet2.numRates = psessionEntry->extRateSet.numRates;
+
+ }
+ else
+ tempRateSet2.numRates = 0;
+
+
+ if ((tempRateSet.numRates + tempRateSet2.numRates) > 12)
+ {
+ //we are in big trouble
+ limLog(pMac, LOGP, FL("more than 12 rates in CFG\n"));
+ //panic
+ goto error;
+ }
+
+
+ //copy all rates in tempRateSet, there are 12 rates max
+ for (i = 0;i < tempRateSet2.numRates; i++)
+ tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i];
+ tempRateSet.numRates += tempRateSet2.numRates;
+
+ /**
+ * Sort rates in tempRateSet (they are likely to be already sorted)
+ * put the result in pSupportedRates
+ */
+ {
+ tANI_U8 aRateIndex = 0;
+ tANI_U8 bRateIndex = 0;
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pRates, sizeof(tSirSupportedRates));
+ for(i = 0;i < tempRateSet.numRates; i++)
+ {
+ min = 0;
+ val = 0xff;
+ isArate = 0;
+ for(j = 0;j < tempRateSet.numRates; j++)
+ {
+ if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
+ {
+ val = tempRateSet.rate[j] & 0x7f;
+ min = j;
+ }
+ }
+
+ if (sirIsArate(tempRateSet.rate[min] & 0x7f))
+ isArate = 1;
+
+ /*
+ * HAL needs to know whether the rate is basic rate or not, as it needs to
+ * update the response rate table accordingly. e.g. if one of the 11a rates is
+ * basic rate, then that rate can be used for sending control frames.
+ * HAL updates the response rate table whenever basic rate set is changed.
+ */
+ if (basicOnly)
+ {
+ if (tempRateSet.rate[min] & 0x80)
+ {
+ if (isArate)
+ pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
+ else
+ pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
+ }
+ }
+ else
+ {
+ if (isArate)
+ pRates->llaRates[aRateIndex++] = tempRateSet.rate[min];
+ else
+ pRates->llbRates[bRateIndex++] = tempRateSet.rate[min];
+ }
+ tempRateSet.rate[min] = 0xff;
+ }
+
+ }
+
+
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode))
+ {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
+ pRates->supportedMCSSet,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get rateset from CFG. Log error.
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet\n"));)
+ goto error;
+ }
+
+
+ //if supported MCS Set of the peer is passed in, then do the intersection
+ //else use the MCS set from local CFG.
+
+ if(pSupportedMCSSet != NULL)
+ {
+ for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ pRates->supportedMCSSet[i] &= pSupportedMCSSet[i];
+
+ }
+
+ PELOG2(limLog(pMac, LOG2, FL("MCS Rate Set Bitmap: \n"));)
+ for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ PELOGW(limLog(pMac, LOG2,FL("%x ") , pRates->supportedMCSSet[i]);)
+ }
+
+
+
+
+ return eSIR_SUCCESS;
+
+ error:
+
+ return eSIR_FAILURE;
+} /*** limPopulateOwnRateSet() ***/
+
+
+
+/**
+ * limPopulateMatchingRateSet
+ * FUNCTION:
+ * This is called at the time of Association Request
+ * processing on AP and while adding peer's context
+ * in IBSS role to process the CFG rate sets and
+ * the rate sets received in the Assoc request on AP
+ * or Beacon/Probe Response from peer in IBSS.
+ *
+ * LOGIC:
+ * 1. It makes the intersection between our own rate Sat
+ * and extemcded rate set and the ones received in the
+ * association request.
+ * 2. It creates a combined rate set of 12 rates max which
+ * comprised the basic and extended rates
+ * 3. It sorts the combined rate Set and copy it in the
+ * rate array of the pSTA descriptor
+ *
+ * ASSUMPTION:
+ * The parser has already ensured unicity of the rates in the
+ * association request structure
+ *
+ * @param: pMac - Pointer to Global MAC structure
+ * pStaDs - Pointer to DPH node
+ * pOperRateSet - Pointer to peer's supported rateset
+ * pExtRateSet - Pointer to peer's extended rateset
+ *
+ * @return: eSIR_SUCCESS or eSIR_FAILURE
+ */
+
+tSirRetStatus
+limPopulateMatchingRateSet(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tSirMacRateSet *pOperRateSet,
+ tSirMacRateSet *pExtRateSet,
+ tANI_U8* pSupportedMCSSet,
+ tSirMacPropRateSet *pAniLegRateSet,
+ tpPESession psessionEntry)
+{
+ tSirMacRateSet tempRateSet;
+ tSirMacRateSet tempRateSet2;
+ tANI_U32 i,j,val,min,isArate;
+ tANI_U32 phyMode;
+ tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
+
+ isArate=0;
+
+ // limGetPhyMode(pMac, &phyMode);
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ // get own rate set
+ // val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &tempRateSet.rate,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve rateset\n"));
+ }
+
+ #endif // TO SUPPORT BT-AMP
+
+ /* copy operational rate set from psessionEntry */
+ palCopyMemory(pMac->hHdd,(tempRateSet.rate),(psessionEntry->rateSet.rate),psessionEntry->rateSet.numRates);
+ tempRateSet.numRates = (tANI_U8) psessionEntry->rateSet.numRates;
+
+ if (phyMode == WNI_CFG_PHY_MODE_11G)
+ {
+
+ #if 0
+ // get own extended rate set
+ val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &tempRateSet2.rate,
+ &val) != eSIR_SUCCESS)
+ #endif
+ palCopyMemory(pMac->hHdd,(tempRateSet2.rate),(psessionEntry->extRateSet.rate),psessionEntry->extRateSet.numRates);
+ tempRateSet2.numRates = (tANI_U8) psessionEntry->extRateSet.numRates;
+ }
+ else
+ tempRateSet2.numRates = 0;
+
+ if ((tempRateSet.numRates + tempRateSet2.numRates) > 12)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG\n"));)
+ goto error;
+ }
+
+ /**
+ * Handling of the rate set IEs is the following:
+ * - keep only rates that we support and that the station supports
+ * - sort and the rates into the pSta->rate array
+ */
+
+ // Copy all rates in tempRateSet, there are 12 rates max
+ for(i = 0; i < tempRateSet2.numRates; i++)
+ tempRateSet.rate[i + tempRateSet.numRates] =
+ tempRateSet2.rate[i];
+
+ tempRateSet.numRates += tempRateSet2.numRates;
+
+ /**
+ * Sort rates in tempRateSet (they are likely to be already sorted)
+ * put the result in tempRateSet2
+ */
+ tempRateSet2.numRates = 0;
+
+ for(i = 0;i < tempRateSet.numRates; i++)
+ {
+ min = 0;
+ val = 0xff;
+
+ for(j = 0;j < tempRateSet.numRates; j++)
+ if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
+ {
+ val = tempRateSet.rate[j] & 0x7f;
+ min = j;
+ }
+
+ tempRateSet2.rate[tempRateSet2.numRates++] =
+ tempRateSet.rate[min];
+ tempRateSet.rate[min] = 0xff;
+ }
+
+
+ /**
+ * Copy received rates in tempRateSet, the parser has ensured
+ * unicity of the rates so there cannot be more than 12
+ */
+ for(i = 0; i < pOperRateSet->numRates; i++)
+ {
+ tempRateSet.rate[i] = pOperRateSet->rate[i];
+ }
+
+ tempRateSet.numRates = pOperRateSet->numRates;
+
+ if (pExtRateSet->numRates)
+ {
+ if((tempRateSet.numRates + pExtRateSet->numRates) > 12 )
+ {
+ limLog( pMac, LOG2,
+ "Sum of SUPPORTED and EXTENDED Rate Set (%1d) exceeds 12!",
+ tempRateSet.numRates + pExtRateSet->numRates );
+
+ if( tempRateSet.numRates < 12 )
+ {
+ int found = 0;
+ int tail = tempRateSet.numRates;
+
+ for( i = 0; i < pExtRateSet->numRates; i++ )
+ {
+ found = 0;
+ for( j = 0; j < (tANI_U32) tail; j++ )
+ {
+ if((tempRateSet.rate[j] & 0x7F) ==
+ (pExtRateSet->rate[i] & 0x7F))
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ if( !found )
+ {
+ tempRateSet.rate[tempRateSet.numRates++] =
+ pExtRateSet->rate[i];
+
+ if( tempRateSet.numRates >= 12 )
+ break;
+ }
+ }
+ }
+ else
+ limLog( pMac, LOG2,
+ "Relying only on the SUPPORTED Rate Set IE..." );
+ }
+ else
+ {
+ for(j = 0; j < pExtRateSet->numRates; j++)
+ tempRateSet.rate[i+j] = pExtRateSet->rate[j];
+
+ tempRateSet.numRates += pExtRateSet->numRates;
+ }
+ }
+
+ {
+ tpSirSupportedRates rates = &pStaDs->supportedRates;
+ tANI_U8 aRateIndex = 0;
+ tANI_U8 bRateIndex = 0;
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rates, sizeof(tSirSupportedRates));
+ for(i = 0;i < tempRateSet2.numRates; i++)
+ {
+ for(j = 0;j < tempRateSet.numRates; j++)
+ {
+ if ((tempRateSet2.rate[i] & 0x7F) ==
+ (tempRateSet.rate[j] & 0x7F))
+ {
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+ if ((bRateIndex > HAL_NUM_11B_RATES) || (aRateIndex > HAL_NUM_11A_RATES))
+ {
+ limLog(pMac, LOGE, FL("Invalid number of rates (11b->%d, 11a->%d)\n"),
+ bRateIndex, aRateIndex);
+ return eSIR_FAILURE;
+ }
+#endif
+ if (sirIsArate(tempRateSet2.rate[i] & 0x7f))
+ {
+ isArate=1;
+ rates->llaRates[aRateIndex++] = tempRateSet2.rate[i];
+ }
+ else
+ rates->llbRates[bRateIndex++] = tempRateSet2.rate[i];
+ break;
+ }
+ }
+ }
+
+
+ //Now add the Polaris rates only when Proprietary rates are enabled.
+ val = 0;
+ if(wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_RATES_ENABLED, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve prop rate enabled flag from CFG\n"));
+ }
+ else if(val)
+ {
+ for(i=0; i<pAniLegRateSet->numPropRates; i++)
+ rates->aniLegacyRates[i] = pAniLegRateSet->propRate[i];
+ }
+
+ }
+
+
+ //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ (pStaDs->mlmStaContext.htCapability))
+ {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
+ mcsSet,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet\n"));
+ goto error;
+ }
+
+ for(i=0; i<val; i++)
+ pStaDs->supportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i];
+
+ PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from CFG and DPH : \n"));)
+ for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ {
+ PELOG2(limLog(pMac, LOG2,FL("%x %x "), mcsSet[i], pStaDs->supportedRates.supportedMCSSet[i]);)
+ }
+ }
+
+ /**
+ * Set the erpEnabled bit iff the phy is in G mode and at least
+ * one A rate is supported
+ */
+ if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate)
+ pStaDs->erpEnabled = eHAL_SET;
+
+
+
+ return eSIR_SUCCESS;
+
+ error:
+
+ return eSIR_FAILURE;
+} /*** limPopulateMatchingRateSet() ***/
+
+
+
+/**
+ * limAddSta()
+ *
+ *FUNCTION:
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+limAddSta(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMacAddr staMac, *pStaAddr;
+ tANI_U8 i;
+#ifdef WLAN_FEATURE_P2P
+ tpSirAssocReq pAssocReq;
+ tANI_U8 *p2pIe = NULL;
+#endif
+ #if 0
+ retCode = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, staMac, &cfg);
+ if (retCode != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve STA MAC\n"));
+ #endif //To SUPPORT BT-AMP
+
+
+ sirCopyMacAddr(staMac,psessionEntry->selfMacAddr);
+
+ if( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **) &pAddStaParams, sizeof( tAddStaParams )))
+ {
+ limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA\n" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams, sizeof(tAddStaParams));
+
+ if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||
+ (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) ||
+ (limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) )
+ pStaAddr = &pStaDs->staAddr;
+ else
+ pStaAddr = &staMac;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->staMac,
+ (tANI_U8 *) *pStaAddr, sizeof(tSirMacAddr));
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry);
+
+ //Copy legacy rates
+ palCopyMemory(pMac->hHdd, (tANI_U8*)&pAddStaParams->supportedRates,
+ (tANI_U8*)&pStaDs->supportedRates, sizeof(tSirSupportedRates));
+
+ pAddStaParams->assocId = pStaDs->assocId;
+
+ pAddStaParams->wmmEnabled = pStaDs->qosMode;
+ pAddStaParams->listenInterval = pStaDs->mlmStaContext.listenInterval;
+ pAddStaParams->shortPreambleSupported = pStaDs->shortPreambleEnabled;
+#ifdef WLAN_SOFTAP_FEATURE
+ if((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) && (pStaDs->mlmStaContext.subType == LIM_REASSOC))
+ {
+ /* TBD - need to remove this REASSOC check after fixinf rmmod issue */
+ pAddStaParams->updateSta = pStaDs->mlmStaContext.updateContext;
+ }
+#endif
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+ // This will indicate HAL to "allocate" a new STA index
+ pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+ pAddStaParams->staType = pStaDs->staType;
+
+ pAddStaParams->status = eHAL_STATUS_SUCCESS;
+ pAddStaParams->respReqd = 1;
+ //Update HT Capability
+
+ if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||(limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) || (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE))
+ pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability;
+ else
+ pAddStaParams->htCapable = psessionEntry->htCapabality;
+
+ pAddStaParams->greenFieldCapable = pStaDs->htGreenfield;
+ pAddStaParams->maxAmpduDensity= pStaDs->htAMpduDensity;
+ pAddStaParams->maxAmpduSize = pStaDs->htMaxRxAMpduFactor;
+ pAddStaParams->fDsssCckMode40Mhz = pStaDs->htDsssCckRate40MHzSupport;
+ pAddStaParams->fShortGI20Mhz = pStaDs->htShortGI20Mhz;
+ pAddStaParams->fShortGI40Mhz = pStaDs->htShortGI40Mhz;
+ pAddStaParams->lsigTxopProtection = pStaDs->htLsigTXOPProtection;
+ pAddStaParams->maxAmsduSize = pStaDs->htMaxAmsduLength;
+ pAddStaParams->txChannelWidthSet = pStaDs->htSupportedChannelWidthSet;
+ pAddStaParams->mimoPS = pStaDs->htMIMOPSState;
+ /* Update PE session ID*/
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
+
+ if (psessionEntry->parsedAssocReq != NULL)
+ {
+#ifdef WLAN_FEATURE_P2P
+ // Get a copy of the already parsed Assoc Request
+ pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId];
+ if ( pAssocReq && pAssocReq->addIEPresent && pAssocReq->addIE.length ) {
+ p2pIe = limGetP2pIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
+ }
+ pAddStaParams->p2pCapableSta = (p2pIe != NULL);
+#endif
+ }
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < STACFG_MAX_TC; i++ )
+ {
+ pAddStaParams->staTCParams[i].txUseBA = eBA_DISABLE;
+ pAddStaParams->staTCParams[i].rxUseBA = eBA_DISABLE;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(pStaDs->wmeEnabled && (eLIM_AP_ROLE == psessionEntry->limSystemRole))
+ {
+ pAddStaParams->uAPSD = 0;
+ /* update UAPSD and send it to LIM to add STA */
+ // bitmap MSB <- LSB MSB 4 bits are for
+ // trigger enabled AC setting and LSB 4 bits
+ // are for delivery enabled AC setting
+ // 7 6 5 4 3 2 1 0
+ // BE BK VI VO BE BK VI VO
+ pAddStaParams->uAPSD |= pStaDs->qos.capability.qosInfo.acvo_uapsd;
+ pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acvi_uapsd << 1);
+ pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbk_uapsd << 2);
+ pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbe_uapsd << 3);
+ //making delivery enabled and trigger enabled setting the same.
+ pAddStaParams->uAPSD |= pAddStaParams->uAPSD << 4;
+
+ pAddStaParams->maxSPLen = pStaDs->qos.capability.qosInfo.maxSpLen;
+ limLog( pMac, LOGE, FL( "uAPSD = 0x%x, maxSpLen = %d" ),
+ pAddStaParams->uAPSD, pAddStaParams->maxSPLen);
+ }
+#endif
+ //we need to defer the message until we get the response back from HAL.
+ if (pAddStaParams->respReqd)
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ msgQ.type = WDA_ADD_STA_REQ;
+
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddStaParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGE, FL( "Sending SIR_HAL_ADD_STA_REQ for assocId %d\n" ),
+ pStaDs->assocId);
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ limLog( pMac, LOGE, FL("ADD_STA_REQ for aId %d failed (reason %X)\n"),
+ pStaDs->assocId, retCode );
+ palFreeMemory(pMac->hHdd, (void*)pAddStaParams);
+ }
+
+ return retCode;
+}
+
+
+/**
+ * limDelSta()
+ *
+ *FUNCTION:
+ * This function is called to delete an STA context at hardware
+ * whenever a STA is disassociated
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @param fRespReqd - flag to indicate whether the delete is synchronous (true)
+ * or not (false)
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+limDelSta(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tANI_BOOLEAN fRespReqd,
+ tpPESession psessionEntry)
+{
+ tpDeleteStaParams pDelStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **) &pDelStaParams, sizeof( tDeleteStaParams )))
+ {
+ limLog( pMac, LOGP, FL( "Unable to PAL allocate memory during ADD_STA\n" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pDelStaParams, sizeof(tDeleteStaParams));
+
+ //
+ // DPH contains the STA index only for "peer" STA entries.
+ // LIM global contains "self" STA index
+ // Thus,
+ // if( STA role )
+ // get STA index from LIM global
+ // else
+ // get STA index from DPH
+ //
+
+#if 0
+ /* Since we have not created any STA, no need to send msg to delete
+ * STA to HAL */
+ if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
+ pDelStaParams->staIdx = 1; /* TODO : This is workaround. Need to find right STA Index before sending to HAL */
+ //return retCode;
+ }
+#endif
+
+ if( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ||(eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) )
+ pDelStaParams->staIdx= psessionEntry->staId;
+
+ else
+ pDelStaParams->staIdx= pStaDs->staIndex;
+
+ pDelStaParams->assocId = pStaDs->assocId;
+ pStaDs->valid = 0;
+
+ if (! fRespReqd)
+ pDelStaParams->respReqd = 0;
+ else
+ {
+ //when limDelSta is called from processSmeAssocCnf then mlmState is already set properly.
+ if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+ SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, eLIM_MLM_WT_DEL_STA_RSP_STATE);
+ }
+ if ( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ||
+ (eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) )
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ }
+ pDelStaParams->respReqd = 1;
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ }
+
+ /* Update PE session ID*/
+ pDelStaParams->sessionId = psessionEntry->peSessionId;
+
+ pDelStaParams->status = eHAL_STATUS_SUCCESS;
+ msgQ.type = WDA_DELETE_STA_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pDelStaParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGE, FL( "Sending SIR_HAL_DELETE_STA_REQ for STAID: %X and AssocID: %d\n" ),
+ pDelStaParams->staIdx, pDelStaParams->assocId);
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ limLog( pMac, LOGE, FL("Posting DELETE_STA_REQ to HAL failed, reason=%X\n"),
+ retCode );
+ palFreeMemory(pMac->hHdd, (void*)pDelStaParams);
+ }
+
+ return retCode;
+}
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+/*------------------------------------------------------------------------
+ * limAddFTStaSelf()
+ *
+ * FUNCTION:
+ *
+ * This function is called to add a STA once we have connected with a new
+ * AP, that we have performed an FT to.
+ *
+ * The Add STA Response is created and now after the ADD Bss Is Successful
+ * we add the self sta. We update with the association id from the reassoc
+ * response from the AP.
+ *------------------------------------------------------------------------
+ */
+tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ pAddStaParams = pMac->ft.ftPEContext.pAddStaReq;
+ pAddStaParams->assocId = assocId;
+
+ msgQ.type = SIR_HAL_ADD_STA_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddStaParams;
+ msgQ.bodyval = 0;
+
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL( "Sending SIR_HAL_ADD_STA_REQ... (aid %d)" ), pAddStaParams->assocId);
+#endif
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE, FL("Posting ADD_STA_REQ to HAL failed, reason=%X\n"), retCode );
+ palFreeMemory(pMac->hHdd, (void*)pAddStaParams);
+ }
+ //
+ // Dont need it any more
+ pMac->ft.ftPEContext.pAddStaReq = NULL;
+ return retCode;
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+/**
+ * limAddStaSelf()
+ *
+ *FUNCTION:
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+limAddStaSelf(tpAniSirGlobal pMac,tANI_U16 staIdx, tANI_U8 updateSta, tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMacAddr staMac;
+ tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ #if 0
+ retCode =wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, staMac, &cfg);
+ if (retCode != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve STA MAC\n"));
+ return retCode;
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(staMac,psessionEntry->selfMacAddr);
+
+ if( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **) &pAddStaParams, sizeof( tAddStaParams )))
+ {
+ limLog( pMac, LOGP, FL( "Unable to PAL allocate memory during ADD_STA\n" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams, sizeof(tAddStaParams));
+
+ /// Add STA context at MAC HW (BMU, RHP & TFP)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->staMac,
+ (tANI_U8 *) staMac, sizeof(tSirMacAddr));
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ pAddStaParams->assocId = psessionEntry->limAID;
+ pAddStaParams->staType = STA_ENTRY_SELF;
+ pAddStaParams->status = eHAL_STATUS_SUCCESS;
+ pAddStaParams->respReqd = 1;
+
+ /* Update PE session ID */
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
+
+ // This will indicate HAL to "allocate" a new STA index
+ pAddStaParams->staIdx = staIdx;
+ pAddStaParams->updateSta = updateSta;
+
+ pAddStaParams->shortPreambleSupported = psessionEntry->beaconParams.fShortPreamble;
+ limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry);
+
+ if( psessionEntry->htCapabality)
+ {
+ pAddStaParams->htCapable = psessionEntry->htCapabality;
+#ifdef DISABLE_GF_FOR_INTEROP
+ /*
+ * To resolve the interop problem with Broadcom AP,
+ * where TQ STA could not pass traffic with GF enabled,
+ * TQ STA will do Greenfield only with TQ AP, for
+ * everybody else it will be turned off.
+ */
+ if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator))
+ {
+ limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry"));
+ pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ }
+ else
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
+ pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
+ pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
+ pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
+ pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry );
+ pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry );
+ pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry );
+ pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry);
+ pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry );
+ pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry);
+ pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry);
+ pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry);
+#else
+ pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD );
+ pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET );
+ pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE );
+ pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE );
+ pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION );
+ pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA );
+ pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY );
+ pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR);
+ pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH );
+ pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ);
+ pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ);
+ pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ);
+#endif
+ }
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL\n"));
+ pAddStaParams->listenInterval = (tANI_U16)listenInterval;
+
+#ifdef WLAN_FEATURE_P2P
+ if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona)
+ {
+ pAddStaParams->p2pCapableSta = 1;
+ }
+#endif
+
+ limFillSupportedRatesInfo(pMac, NULL, &pAddStaParams->supportedRates,psessionEntry);
+
+ msgQ.type = WDA_ADD_STA_REQ;
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddStaParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW, FL( "Sending SIR_HAL_ADD_STA_REQ... (aid %d)" ),
+ pAddStaParams->assocId);
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE, FL("Posting ADD_STA_REQ to HAL failed, reason=%X\n"), retCode );
+ palFreeMemory(pMac->hHdd, (void*)pAddStaParams);
+ }
+ return retCode;
+}
+
+
+/**
+ * limTeardownInfraBSS()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to teardown
+ * an established Infrastructure BSS
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limTeardownInfraBss(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+ /**
+ * Send Broadcast Disassociate frame with
+ * 'leaving BSS' reason.
+ */
+ limSendDisassocMgmtFrame(pMac,
+ eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
+ bcAddr,psessionEntry);
+} /*** end limTeardownInfraBss() ***/
+
+
+/**
+ * limHandleCnfWaitTimeout()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue to handle
+ * various confirmation failure cases.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to a sta descriptor
+ * @return None
+ */
+
+void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId)
+{
+ tpDphHashNode pStaDs;
+ tLimSystemRole systemRole;
+ tpPESession psessionEntry = NULL;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ systemRole = limGetSystemRole(psessionEntry);
+ pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT.\n"));)
+ return;
+ }
+
+ switch (pStaDs->mlmStaContext.mlmState) {
+ case eLIM_MLM_WT_ASSOC_CNF_STATE:
+ PELOGW(limLog(pMac, LOGW, FL("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d\n"), pStaDs->assocId);)
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOGW);
+
+ if ( (systemRole == eLIM_AP_ROLE)|| (systemRole == eLIM_BT_AMP_AP_ROLE) )
+ {
+ limRejectAssociation(
+ pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true,
+ pStaDs->mlmStaContext.authType,
+ pStaDs->assocId,
+ true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ }
+ break;
+
+ default:
+ limLog(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d\n"),
+ pStaDs->mlmStaContext.mlmState);
+ }
+}
+
+
+/**
+ * limDeleteDphHashEntry()
+ *
+ *FUNCTION:
+ * This function is called whenever we need to delete
+ * the dph hash entry
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tANI_U16 staId
+ * @return None
+ */
+
+void
+limDeleteDphHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId,tpPESession psessionEntry)
+{
+ tANI_U16 aid;
+ tpDphHashNode pStaDs;
+ tUpdateBeaconParams beaconParams;
+ tLimSystemRole systemRole;
+
+ beaconParams.paramChangeBitmap = 0;
+ limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, staId);
+ if (NULL == psessionEntry)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));)
+ return;
+ }
+ systemRole = limGetSystemRole(psessionEntry);
+ beaconParams.bssIdx = psessionEntry->bssIdx;
+ pStaDs = dphLookupHashEntry(pMac, staAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X\n "), staId);)
+ // update the station count and perform associated actions
+ // do this before deleting the dph hash entry
+ limUtilCountStaDel(pMac, pStaDs, psessionEntry);
+
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole) ||
+ (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole))
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){
+ if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE){
+ limDecideApProtectionOnDelete(pMac, pStaDs, &beaconParams,psessionEntry);
+ }
+ }
+#endif
+
+ if(eLIM_STA_IN_IBSS_ROLE == systemRole)
+ limIbssDecideProtectionOnDelete(pMac, pStaDs, &beaconParams, psessionEntry);
+
+ limDecideShortPreamble(pMac, pStaDs, &beaconParams, psessionEntry);
+ limDecideShortSlot(pMac, pStaDs, &beaconParams, psessionEntry);
+
+ //Send message to HAL about beacon parameter change.
+ PELOGW(limLog(pMac, LOGW, FL("param bitmap = %d \n"), beaconParams.paramChangeBitmap);)
+ if(beaconParams.paramChangeBitmap)
+ {
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry );
+ }
+ }
+ if (dphDeleteHashEntry(pMac, staAddr, staId, &psessionEntry->dph.dphHashTable) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("error deleting hash entry\n"));
+ }
+}
+
+
+
+/**
+ * limCheckAndAnnounceJoinSuccess()
+ *
+ *FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * frame in WT_JOIN_BEACON_STATE to check if the received
+ * Beacon/Probe Response is from the BSS that we're attempting
+ * to join.
+ *
+ *LOGIC:
+ * If the Beacon/Probe Response is indeed from the BSS we're
+ * attempting to join, join success is sent to SME.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBPR Pointer to received Beacon/Probe Response
+ * @param pHdr Pointer to received Beacon/Probe Response
+ * MAC header
+ * @return None
+ */
+
+void
+limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac,
+ tSirProbeRespBeacon *pBPR,
+ tpSirMacMgmtHdr pHdr,tpPESession psessionEntry)
+{
+ tSirMacSSid currentSSID;
+ tLimMlmJoinCnf mlmJoinCnf;
+
+ palCopyMemory( pMac->hHdd, currentSSID.ssId,
+ psessionEntry->ssId.ssId,
+ psessionEntry->ssId.length);
+
+ currentSSID.length = (tANI_U8)psessionEntry->ssId.length ;
+
+ if (
+ /* Check for SSID only in probe response. Beacons may not carry
+ SSID information in hidden SSID case */
+ ( (SIR_MAC_MGMT_FRAME == pHdr->fc.type) &&
+ (SIR_MAC_MGMT_PROBE_RSP == pHdr->fc.subType) ) &&
+ currentSSID.length &&
+ (!palEqualMemory( pMac->hHdd,(tANI_U8 *) &pBPR->ssId,
+ (tANI_U8 *) ¤tSSID,
+ (tANI_U8) (1 + currentSSID.length)) ))
+ {
+ /**
+ * Received SSID does not match with the one we've.
+ * Ignore received Beacon frame
+ */
+ PELOG1(limLog(pMac, LOG1, FL("SSID received in Beacon does not match\n"));)
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimBcnSSIDMismatchCnt++;
+#endif
+ return;
+ }
+
+ if( (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_STA_ROLE))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Received Beacon/PR with matching BSSID\n"));)
+
+ // Deactivate Join Failure timer
+ limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
+
+ // Update Beacon Interval at CFG database
+
+ if ( pBPR->HTCaps.present )
+ limUpdateStaRunTimeHTCapability( pMac, &pBPR->HTCaps );
+ if ( pBPR->HTInfo.present )
+ limUpdateStaRunTimeHTInfo( pMac, &pBPR->HTInfo, psessionEntry);
+ psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_JOINED_STATE));
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ // In case of BP, we need to adopt to all rates
+ // advertised by AP. Update the operational rates at CFG
+ if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pBPR->supportedRates.rate,
+ pBPR->supportedRates.numRates)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update Oper.rates at CFG\n"));
+
+#endif
+
+ /**
+ * Announce join success by sending
+ * Join confirm to SME.
+ */
+ mlmJoinCnf.resultCode = eSIR_SME_SUCCESS;
+ mlmJoinCnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
+ /* Update PE sessionId*/
+ mlmJoinCnf.sessionId = psessionEntry->peSessionId;
+ limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
+ } // if ((pMac->lim.gLimSystemRole == IBSS....
+}
+
+/**
+ * limExtractApCapabilities()
+ *
+ *FUNCTION:
+ * This function is called to extract all of the AP's capabilities
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ *LOGIC:
+ * This routine mimics the limExtractApCapability() API. The difference here
+ * is that this API returns the entire tSirProbeRespBeacon info as is. It is
+ * left to the caller of this API to use this info as required
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pIE Pointer to starting IE in Beacon/Probe Response
+ * @param ieLen Length of all IEs combined
+ * @param beaconStruct A pointer to tSirProbeRespBeacon that needs to be
+ * populated
+ * @return status A status reporting eSIR_SUCCESS or eSIR_FAILURE
+ */
+tSirRetStatus limExtractApCapabilities( tpAniSirGlobal pMac,
+ tANI_U8 *pIE,
+ tANI_U16 ieLen,
+ tpSirProbeRespBeacon beaconStruct )
+{
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) beaconStruct, sizeof( tSirProbeRespBeacon ));
+
+ PELOG3(limLog( pMac, LOG3,
+ FL( "In limExtractApCapabilities: The IE's being received are:\n" ));
+ sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );)
+
+ // Parse the Beacon IE's, Don't try to parse if we dont have anything in IE
+ if (ieLen > 0) {
+ if( eSIR_SUCCESS != sirParseBeaconIE( pMac, beaconStruct, pIE, (tANI_U32)ieLen ))
+ {
+ limLog( pMac, LOGE, FL("APCapExtract: Beacon parsing error!\n"));
+ return eSIR_FAILURE;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+
+/**
+ * limDelBss()
+ *
+ *FUNCTION:
+ * This function is called to delete BSS context at hardware
+ * whenever a STA is disassociated
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+limDelBss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tANI_U16 bssIdx,tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBssParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ if( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **) &pDelBssParams, sizeof( tDeleteBssParams )))
+ {
+ limLog( pMac, LOGP, FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pDelBssParams, sizeof(tDeleteBssParams));
+
+
+ pDelBssParams->sessionId = psessionEntry->peSessionId; //update PE session Id
+
+ //DPH was storing the AssocID in staID field,
+ //staID is actually assigned by HAL when AddSTA message is sent.
+ if (pStaDs != NULL)
+ {
+ pDelBssParams->bssIdx= pStaDs->bssId;
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ }
+ else
+ pDelBssParams->bssIdx = bssIdx;
+ psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+ pDelBssParams->status= eHAL_STATUS_SUCCESS;
+ pDelBssParams->respReqd = 1;
+ PELOGW(limLog( pMac, LOGW, FL("Sending HAL_DELETE_BSS_REQ for BSSID: %X\n"),
+ pDelBssParams->bssIdx);)
+
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WDA_DELETE_BSS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pDelBssParams;
+ msgQ.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE, FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X\n"), retCode );
+ palFreeMemory(pMac->hHdd, (void*)pDelBssParams);
+ }
+
+ return retCode;
+}
+
+
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+
+/**
+ * limSendAddBss()
+ *
+ *FUNCTION:
+ *
+ *LOGIC:
+ * 1) LIM receives eWNI_SME_JOIN_REQ
+ * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends
+ * SIR_HAL_ADD_BSS_REQ to HAL
+ *
+ *ASSUMPTIONS:
+ * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq
+ * ADD BSS parameters can be obtained from two sources:
+ * 1) pMac->lim.gLimMlmJoinReq
+ * 2) beaconStruct, passed as paramter
+ * So, if a reqd parameter is found in bssDescriptions
+ * then it is given preference over beaconStruct
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * pAssocRsp contains the structured assoc/reassoc Response got from AP
+ * beaconstruct Has the ProbeRsp/Beacon structured details
+ * bssDescription bssDescription passed to PE from the SME
+ * @return None
+ */
+
+tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry,
+ tpPESession psessionEntry)
+
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ tANI_U32 retCode;
+ tANI_U8 i;
+ tpDphHashNode pStaDs = NULL;
+ tANI_U8 chanWidthSupp = 0;
+ // Package SIR_HAL_ADD_BSS_REQ message parameters
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBssParams,
+ sizeof( tAddBssParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+ else
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ));
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->bssId,bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+ // Fill in tAddBssParams selfMacAddr
+ palCopyMemory( pMac->hHdd, pAddBssParams->selfMacAddr,
+ psessionEntry->selfMacAddr,
+ sizeof( tSirMacAddr ));
+
+ if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ pAddBssParams->bssType = eSIR_BTAMP_AP_MODE;
+ }
+ else
+ {
+ pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
+ }
+
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ /* Update PE session ID */
+ pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+
+ pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+ pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
+ palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
+ pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates );
+
+ pAddBssParams->nwType = bssDescription->nwType;
+
+ pAddBssParams->shortSlotTimeSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist;
+
+
+ // Use the advertised capabilities from the received beacon/PR
+
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present ))
+ {
+ pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
+
+ if ( pBeaconStruct->HTInfo.present )
+ {
+ pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pAssocRsp->HTInfo.opMode;
+ pAddBssParams->dualCTSProtection = ( tANI_U8 ) pAssocRsp->HTInfo.dualCTSProtection;
+#ifdef WLAN_SOFTAP_FEATURE
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
+#else
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET);
+#endif
+ if( (pAssocRsp->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet;
+ pAddBssParams->currentExtChannel = pAssocRsp->HTInfo.secondaryChannelOffset;
+ }
+ else
+ {
+ pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ pAddBssParams->currentExtChannel = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+ }
+ pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+
+ // Populate the STA-related parameters here
+ // Note that the STA here refers to the AP
+ {
+ /* staType = PEER*/
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->staContext.bssId,
+ bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+ pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;
+
+ /* Fill Assoc id from the dph table */
+ pStaDs = dphLookupHashEntry(pMac, pAddBssParams->staContext.bssId,
+ &pAddBssParams->staContext.assocId, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Couldn't get assoc id for"
+ "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x"),
+ pAddBssParams->staContext.staMac[0],
+ pAddBssParams->staContext.staMac[1],
+ pAddBssParams->staContext.staMac[2],
+ pAddBssParams->staContext.staMac[3],
+ pAddBssParams->staContext.staMac[4],
+ pAddBssParams->staContext.staMac[5]
+ );)
+ }
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present ))
+ {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 )pAssocRsp->HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 )pAssocRsp->HTCaps.lsigTXOPProtection;
+ if( (pAssocRsp->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet;
+ }
+ else
+ {
+ pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ }
+ pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave;
+ pAddBssParams->staContext.delBASupport = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA;
+ pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 )pAssocRsp->HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity = pAssocRsp->HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz;
+ pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
+ pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
+ pAddBssParams->staContext.maxAmpduSize= pAssocRsp->HTCaps.maxRxAMPDUFactor;
+
+ if( pBeaconStruct->HTInfo.present )
+ pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode;
+ }
+
+ if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
+ (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ //Update the rates
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry);
+ palCopyMemory(pMac->hHdd, (tANI_U8*)&pAddBssParams->staContext.supportedRates,
+ (tANI_U8*)&pStaDs->supportedRates,
+ sizeof(tSirSupportedRates));
+ }
+ else
+ PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates.\n"));)
+
+ }
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < STACFG_MAX_TC; i++ )
+ {
+ pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
+ pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
+ }
+
+ pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+#endif
+ // FIXME_GEN4 - Any other value that can be used for initialization?
+ pAddBssParams->status = eHAL_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona
+
+#ifdef WLAN_FEATURE_P2P
+ if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona)
+ {
+ pAddBssParams->staContext.p2pCapableSta = 1;
+ }
+#endif
+
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+#endif
+
+ // Set a new state for MLME
+ if( eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState )
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
+ else
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WDA_ADD_BSS_REQ;
+ /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ palFreeMemory(pMac->hHdd, pAddBssParams);
+ limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
+ retCode );
+ goto returnFailure;
+
+ }
+ else
+ return retCode;
+
+ returnFailure:
+ // Clean-up will be done by the caller...
+ return retCode;
+}
+
+
+
+
+tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ tANI_U32 retCode;
+ tANI_U8 i;
+ tSchBeaconStruct beaconStruct;
+ tANI_U8 chanWidthSupp = 0;
+ tpSirBssDescription bssDescription = &psessionEntry->pLimJoinReq->bssDescription;
+
+
+ // Package SIR_HAL_ADD_BSS_REQ message parameters
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBssParams,
+ sizeof( tAddBssParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ));
+
+
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) bssDescription->ieFields,
+ limGetIElenFromBssDescription( bssDescription ),
+ &beaconStruct );
+
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideStaProtectionOnAssoc(pMac, &beaconStruct, psessionEntry);
+ palCopyMemory( pMac->hHdd, pAddBssParams->bssId,bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+
+ // Fill in tAddBssParams selfMacAddr
+ palCopyMemory( pMac->hHdd, pAddBssParams->selfMacAddr,
+ psessionEntry->selfMacAddr,
+ sizeof( tSirMacAddr ));
+
+ /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on
+ * top of an already established Infra link. This lead to issues in
+ * concurrent data transfer.
+ */
+
+ pAddBssParams->bssType = psessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE;
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = beaconStruct.tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+
+ pAddBssParams->cfParamSet.cfpCount = beaconStruct.cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod = beaconStruct.cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration = beaconStruct.cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining = beaconStruct.cfParamSet.cfpDurRemaining;
+
+
+ pAddBssParams->rateSet.numRates = beaconStruct.supportedRates.numRates;
+ palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
+ beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
+
+ pAddBssParams->nwType = bssDescription->nwType;
+
+ pAddBssParams->shortSlotTimeSupported = (tANI_U8)beaconStruct.capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist;
+
+ // Use the advertised capabilities from the received beacon/PR
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
+ {
+ pAddBssParams->htCapable = beaconStruct.HTCaps.present;
+
+ if ( beaconStruct.HTInfo.present )
+ {
+ pAddBssParams->htOperMode = (tSirMacHTOperatingMode)beaconStruct.HTInfo.opMode;
+ pAddBssParams->dualCTSProtection = ( tANI_U8 ) beaconStruct.HTInfo.dualCTSProtection;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
+#else
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET);
+#endif
+ if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->txChannelWidthSet = ( tANI_U8 ) beaconStruct.HTInfo.recommendedTxWidthSet;
+ pAddBssParams->currentExtChannel = beaconStruct.HTInfo.secondaryChannelOffset;
+ }
+ else
+ {
+ pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ pAddBssParams->currentExtChannel = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+ }
+ pAddBssParams->llnNonGFCoexist = (tANI_U8)beaconStruct.HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)beaconStruct.HTInfo.lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode = beaconStruct.HTInfo.rifsMode;
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+
+ // Populate the STA-related parameters here
+ // Note that the STA here refers to the AP
+ {
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->staContext.bssId,
+ bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+ pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this?
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)beaconStruct.capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
+ {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) beaconStruct.HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) beaconStruct.HTCaps.lsigTXOPProtection;
+ if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )beaconStruct.HTInfo.recommendedTxWidthSet;
+ }
+ else
+ {
+ pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ }
+ pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)beaconStruct.HTCaps.mimoPowerSave;
+ pAddBssParams->staContext.delBASupport = ( tANI_U8 ) beaconStruct.HTCaps.delayedBA;
+ pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) beaconStruct.HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity = beaconStruct.HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)beaconStruct.HTCaps.dsssCckMode40MHz;
+ pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI20MHz;
+ pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI40MHz;
+ pAddBssParams->staContext.maxAmpduSize= beaconStruct.HTCaps.maxRxAMPDUFactor;
+
+ if( beaconStruct.HTInfo.present )
+ pAddBssParams->staContext.rifsMode = beaconStruct.HTInfo.rifsMode;
+ }
+
+ if ((psessionEntry->limWmeEnabled && beaconStruct.wmeEdcaPresent) ||
+ (psessionEntry->limQosEnabled && beaconStruct.edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ //Update the rates
+
+ limPopulateOwnRateSet(pMac, &pAddBssParams->staContext.supportedRates,
+ beaconStruct.HTCaps.supportedMCSSet, false,psessionEntry);
+ limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,psessionEntry);
+
+ }
+
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < STACFG_MAX_TC; i++ )
+ {
+ pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
+ pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
+ }
+
+ pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+#endif
+
+ pAddBssParams->status = eHAL_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
+ pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+ pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona
+
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+#endif
+
+ // Set a new state for MLME
+
+ //pMac->lim.gLimMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WDA_ADD_BSS_REQ;
+ /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ palFreeMemory(pMac->hHdd, pAddBssParams);
+ limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
+ retCode );
+ goto returnFailure;
+
+ }
+ else
+ return retCode;
+
+ returnFailure:
+ // Clean-up will be done by the caller...
+ return retCode;
+}
+
+
+
+
+
+#elif defined(ANI_AP_CLIENT_SDK)
+tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSirNeighborBssInfo neighborBssInfo, tANI_U8 updateEntry,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ tANI_U32 retCode;
+ tANI_U8 i;
+ tpDphHashNode pStaDs = NULL;
+
+ // Package SIR_HAL_ADD_BSS_REQ message parameters
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBssParams,
+ sizeof( tAddBssParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+ else
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ));
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->bssId,neighborBssInfo->bssId,
+ sizeof( tSirMacAddr ));
+
+#ifdef WLAN_SOFTAP_FEATURE
+ // Fill in tAddBssParams selfMacAddr
+ palCopyMemory( pMac->hHdd, pAddBssParams->selfMacAddr, psessionEntry->selfMacAddr,
+ sizeof( tSirMacAddr ));
+#endif
+
+ pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+ pAddBssParams->beaconInterval = (tANI_U16) neighborBssInfo->beaconInterval;
+ pAddBssParams->dtimPeriod = neighborBssInfo->dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+
+ /* The following parameters are commented since the information is not available from the
+ * neighborBssInfo. This needs to be fixed later */
+#if 0
+
+ pAddBssParams->cfParamSet.cfpCount = beaconStruct.cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod = beaconStruct.cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration = beaconStruct.cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining = beaconStruct.cfParamSet.cfpDurRemaining;
+#endif
+ pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
+ palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
+ pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates );
+
+ /* Update PE session ID */
+ pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+ pAddBssParams->nwType = neighborBssInfo->nwType;
+
+ pAddBssParams->shortSlotTimeSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist;
+
+ // Use the advertised capabilities from the received beacon/PR
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( neighborBssInfo->HTCapsPresent ))
+ {
+ pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
+
+ if ( neighborBssInfo->HTInfoPresent )
+ {
+ pAddBssParams->htOperMode = pAssocRsp->HTInfo.opMode;
+ pAddBssParams->dualCTSProtection = ( tANI_U8 )pAssocRsp->HTInfo.dualCTSProtection;
+
+ if(pAssocRsp->HTCaps.supportedChannelWidthSet)
+ {
+ pAddBssParams->txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet;
+ pAddBssParams->currentExtChannel = pAssocRsp->HTInfo.secondaryChannelOffset;
+ }
+ else
+ {
+ pAddBssParams->txChannelWidthSet = (tANI_U8)pAssocRsp->HTCaps.supportedChannelWidthSet;
+ pAddBssParams->currentExtChannel = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+ }
+ pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;
+ }
+ }
+
+ pAddBssParams->currentOperChannel = neighborBssInfo->channelId;
+
+ // Populate the STA-related parameters here
+ // Note that the STA here refers to the AP
+ {
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->staContext.bssId,
+ neighborBssInfo->bssId,
+ sizeof( tSirMacAddr ));
+ pAddBssParams->staContext.listenInterval = (tANI_U8) neighborBssInfo->beaconInterval;
+
+ pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this?
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present ))
+ {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 )pAssocRsp->HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 )pAssocRsp->HTCaps.lsigTXOPProtection;
+ pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )(pAssocRsp->HTCaps.supportedChannelWidthSet ?
+ pAssocRsp->HTInfo.recommendedTxWidthSet :
+ pAssocRsp->HTCaps.supportedChannelWidthSet );
+ pAddBssParams->staContext.mimoPS = pAssocRsp->HTCaps.mimoPowerSave;
+ pAddBssParams->staContext.delBASupport = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA;
+ pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 )pAssocRsp->HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity = pAssocRsp->HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz;
+ pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
+ pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
+ pAddBssParams->staContext.maxAmpduSize= pAssocRsp->HTCaps.maxRxAMPDUFactor;
+
+ if( pAssocRsp->HTInfo.present )
+ pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode;
+ }
+
+ if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
+ (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ //Update the rates
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry);
+ palCopyMemory(pMac->hHdd, (tANI_U8*)&pAddBssParams->staContext.supportedRates,
+ (tANI_U8*)&pStaDs->supportedRates,
+ sizeof(tSirSupportedRates));
+ }
+ else
+ PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates.\n"));)
+
+ }
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < SMAC_STACFG_MAX_TC; i++ )
+ {
+ pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
+ pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+#endif
+ // FIXME_GEN4 - Any other value that can be used for initialization?
+ pAddBssParams->status = eHAL_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+#endif
+
+ // Set a new state for MLME
+ if( eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState )
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
+ else
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = SIR_HAL_ADD_BSS_REQ;
+ /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = halPostMsgApi( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ palFreeMemory(pMac->hHdd, pAddBssParams);
+ limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
+ retCode );
+ }
+ else
+ return retCode;
+
+ returnFailure:
+ // Clean-up will be done by the caller...
+ return retCode;
+}
+
+#endif // ANI_PRODUCT_TYPE_CLIENT
+
+/** -------------------------------------------------------------
+\fn limPrepareAndSendDelStaCnf
+\brief deletes DPH entry
+ changes the MLM mode for station.
+ calls limSendDelStaCnf
+\param tpAniSirGlobal pMac
+\param tpDphHashNode pStaDs
+\return none
+ -------------------------------------------------------------*/
+
+
+void
+limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession psessionEntry)
+{
+ tANI_U16 staDsAssocId = 0;
+ tSirMacAddr staDsAddr;
+ tLimMlmStaContext mlmStaContext;
+
+ if(pStaDs == NULL)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("pStaDs is NULL\n"));)
+ return;
+ }
+ staDsAssocId = pStaDs->assocId;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)staDsAddr,
+ pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+
+ mlmStaContext = pStaDs->mlmStaContext;
+ if(eSIR_SME_SUCCESS == statusCode)
+ {
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
+ {
+ limReleaseAID(pMac, pStaDs->assocId);
+ }
+
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry);
+ }
+ if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ }
+
+ limSendDelStaCnf(pMac, staDsAddr, staDsAssocId, mlmStaContext, statusCode,psessionEntry);
+}
+
+/** -------------------------------------------------------------
+\fn limGetStaRateMode
+\brief Gets the Station Rate Mode.
+\param tANI_U8 dot11Mode
+\return none
+ -------------------------------------------------------------*/
+tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode)
+{
+ switch(dot11Mode)
+ {
+ case WNI_CFG_DOT11_MODE_11A:
+ return eSTA_11a;
+ case WNI_CFG_DOT11_MODE_11B:
+ return eSTA_11b;
+ case WNI_CFG_DOT11_MODE_11G:
+ return eSTA_11bg;
+ case WNI_CFG_DOT11_MODE_11N:
+ return eSTA_11n;
+ case WNI_CFG_DOT11_MODE_ALL:
+ default:
+ return eSTA_11n;
+
+ }
+}
+
+/** -------------------------------------------------------------
+\fn limInitPreAuthTimerTable
+\brief Initialize the Pre Auth Tanle and creates the timer for
+ each node for the timeout value got from cfg.
+\param tpAniSirGlobal pMac
+\param tpLimPreAuthTable pPreAuthTimerTable
+\return none
+ -------------------------------------------------------------*/
+void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable)
+{
+ tANI_U32 cfgValue;
+ tANI_U32 authNodeIdx;
+ tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable;
+
+ // Get AUTH_RSP Timers value
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /*
+ ** Could not get AUTH_RSP timeout value
+ ** from CFG. Log error.
+ **/
+ limLog(pMac, LOGP,
+ FL("could not retrieve AUTH_RSP timeout value\n"));
+ return;
+ }
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ for(authNodeIdx=0; authNodeIdx<pPreAuthTimerTable->numEntry; authNodeIdx++, pAuthNode++)
+ {
+ if (tx_timer_create(&pAuthNode->timer,
+ "AUTH RESPONSE TIMEOUT",
+ limAuthResponseTimerHandler,
+ authNodeIdx,
+ cfgValue,
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Cannot create timer. Log error.
+ limLog(pMac, LOGP, FL("Cannot create Auth Rsp timer of Index :%d.\n"), authNodeIdx);
+ return;
+ }
+ pAuthNode->authNodeIdx = (tANI_U8)authNodeIdx;
+ pAuthNode->fFree = 1;
+ }
+
+}
+
+/** -------------------------------------------------------------
+\fn limAcquireFreePreAuthNode
+\brief Retrives a free Pre Auth node from Pre Auth Table.
+\param tpAniSirGlobal pMac
+\param tpLimPreAuthTable pPreAuthTimerTable
+\return none
+ -------------------------------------------------------------*/
+tLimPreAuthNode * limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable)
+{
+ tANI_U32 i;
+ tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable;
+ for (i=0; i<pPreAuthTimerTable->numEntry; i++,pTempNode++)
+ {
+ if (pTempNode->fFree == 1)
+ {
+ pTempNode->fFree = 0;
+ return pTempNode;
+ }
+ }
+
+ return NULL;
+}
+
+/** -------------------------------------------------------------
+\fn limGetPreAuthNodeFromIndex
+\brief Depending on the Index this retrives the pre auth node.
+\param tpAniSirGlobal pMac
+\param tpLimPreAuthTable pAuthTable
+\param tANI_U32 authNodeIdx
+\return none
+ -------------------------------------------------------------*/
+tLimPreAuthNode * limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx)
+{
+ if ((authNodeIdx >= pAuthTable->numEntry) || (pAuthTable->pTable == NULL))
+ {
+ limLog(pMac, LOGE, FL("Invalid Auth Timer Index : %d NumEntry : %d\n"),
+ authNodeIdx, pAuthTable->numEntry);
+ return NULL;
+ }
+
+ return pAuthTable->pTable + authNodeIdx;
+}
+
+/* Util API to check if the channels supported by STA is within range */
+tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc)
+{
+ /*
+ * Allow all the stations to join with us.
+ * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs
+ * as an input into an algorithm used to select a new channel for the BSS.
+ * The specification of the algorithm is beyond the scope of this amendment.
+ */
+
+ return (eSIR_SUCCESS);
+}
+
+/* Util API to check if the txpower supported by STA is within range */
+tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession psessionEntry)
+{
+ tPowerdBm localMaxTxPower;
+ tANI_U32 localPwrConstraint;
+
+ localMaxTxPower = cfgGetRegulatoryMaxTransmitPower(pMac, psessionEntry->currentOperChannel);
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
+ limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg\n" ));
+ return eSIR_FAILURE;
+ }
+ localMaxTxPower -= (tPowerdBm)localPwrConstraint;
+
+ /**
+ * The min Tx Power of the associating station should not be greater than (regulatory
+ * max tx power - local power constraint configured on AP).
+ */
+ if(assoc->powerCapability.minTxPower > localMaxTxPower)
+ {
+ limLog(pMac, LOGW, FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d\n"),
+ assoc->powerCapability.minTxPower, localMaxTxPower);
+ return (eSIR_FAILURE);
+ }
+
+ return (eSIR_SUCCESS);
+}
+
+/** -------------------------------------------------------------
+\fn limFillRxHighestSupportedRate
+\brief Fills in the Rx Highest Supported Data Rate field from
+\ the 'supported MCS set' field in HT capability element.
+\param tpAniSirGlobal pMac
+\param tpSirSupportedRates pRates
+\param tANI_U8* pSupportedMCSSet
+\return none
+ -------------------------------------------------------------*/
+void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet)
+{
+ tSirMacRxHighestSupportRate *pRxHighestRate;
+ tANI_U8 *pBuf;
+ tANI_U16 rate=0;
+
+ pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
+ rate = limGetU16(pBuf);
+
+ pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
+ *rxHighestRate = pRxHighestRate->rate;
+
+ return;
+}
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.h b/CORE/MAC/src/pe/lim/limAssocUtils.h
new file mode 100644
index 0000000..a46f7ab
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 limAssocUtils.h contains the utility definitions
+ * LIM uses while processing Re/Association messages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+#ifndef __LIM_ASSOC_UTILS_H
+#define __LIM_ASSOC_UTILS_H
+
+#include "sirApi.h"
+#include "sirDebug.h"
+#include "cfgApi.h"
+
+#include "limTypes.h"
+
+
+tANI_U8 limCmpSSid(tpAniSirGlobal, tSirMacSSid *,tpPESession);
+tANI_U8 limCompareCapabilities(tpAniSirGlobal,
+ tSirAssocReq *,
+ tSirMacCapabilityInfo *,tpPESession);
+tANI_U8 limCheckRxBasicRates(tpAniSirGlobal, tSirMacRateSet,tpPESession);
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_U8 limCheckRxRSNIeMatch(tpAniSirGlobal, tDot11fIERSN, tpPESession, tANI_U8);
+tANI_U8 limCheckRxWPAIeMatch(tpAniSirGlobal, tDot11fIEWPA, tpPESession, tANI_U8);
+#endif
+tANI_U8 limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet);
+void limPostDummyToTmRing(tpAniSirGlobal, tpDphHashNode);
+void limPostPacketToTdRing(tpAniSirGlobal,
+ tpDphHashNode,
+ tANI_U8);
+tSirRetStatus limCleanupRxPath(tpAniSirGlobal, tpDphHashNode,tpPESession);
+void limRejectAssociation(tpAniSirGlobal , tSirMacAddr, tANI_U8,
+ tANI_U8 , tAniAuthType,
+ tANI_U16, tANI_U8, tSirResultCodes, tpPESession);
+
+tSirRetStatus limPopulateOwnRateSet(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ tANI_U8* pSupportedMCSSet,
+ tANI_U8 basicOnly,
+ tpPESession psessionEntry);
+
+tSirRetStatus limPopulateMatchingRateSet(tpAniSirGlobal,
+ tpDphHashNode,
+ tSirMacRateSet *,
+ tSirMacRateSet *,
+ tANI_U8* pSupportedMCSSet,
+ tSirMacPropRateSet *, tpPESession);
+tSirRetStatus limAddSta(tpAniSirGlobal, tpDphHashNode,tpPESession);
+tSirRetStatus limDelBss(tpAniSirGlobal, tpDphHashNode, tANI_U16, tpPESession);
+tSirRetStatus limDelSta(tpAniSirGlobal, tpDphHashNode, tANI_BOOLEAN, tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId,
+ tpPESession psessionEntry);
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+tSirRetStatus limAddStaSelf(tpAniSirGlobal, tANI_U16, tANI_U8, tpPESession);
+tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode);
+
+
+void limTeardownInfraBss(tpAniSirGlobal,tpPESession);
+void limRestorePreReassocState(tpAniSirGlobal,
+ tSirResultCodes,
+ tANI_U16,tpPESession);
+eAniBoolean limIsReassocInProgress(tpAniSirGlobal,tpPESession);
+void
+limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr,
+ tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry);
+
+void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId);
+void limDeleteDphHashEntry(tpAniSirGlobal, tSirMacAddr, tANI_U16,tpPESession);
+void limCheckAndAnnounceJoinSuccess(tpAniSirGlobal,
+ tSirProbeRespBeacon *,
+ tpSirMacMgmtHdr,tpPESession);
+void limUpdateReAssocGlobals(tpAniSirGlobal pMac,
+ tpSirAssocRsp pAssocRsp,tpPESession psessionEntry);
+
+void limUpdateAssocStaDatas(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,tpSirAssocRsp pAssocRsp,tpPESession psessionEntry);
+void
+limFillSupportedRatesInfo(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tpSirSupportedRates pRates,
+ tpPESession psessionEntry);
+
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+//make non-conditional until the caller is #ifdefed
+tSirRetStatus limStaSendAddBss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry, tpPESession psessionEntry);
+tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry);
+
+
+
+#elif defined(ANI_AP_CLIENT_SDK)
+tSirRetStatus limStaSendAddBss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSirNeighborBssInfo neighborBssInfo,tANI_U8 updateEntry,
+ tpPESession psessionEntry);
+#endif
+
+void limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession);
+tSirRetStatus limExtractApCapabilities(tpAniSirGlobal pMac, tANI_U8 * pIE, tANI_U16 ieLen, tpSirProbeRespBeacon beaconStruct);
+void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable);
+tpLimPreAuthNode limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable);
+tpLimPreAuthNode limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac, tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx);
+
+/* Util API to check if the channels supported by STA is within range */
+tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc);
+
+/* Util API to check if the txpower supported by STA is within range */
+tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession);
+
+/* API to re-add the same BSS during re-association */
+void limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry);
+
+/* API to fill in RX Highest Supported data Rate */
+void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet);
+
+
+#endif /* __LIM_ASSOC_UTILS_H */
+
diff --git a/CORE/MAC/src/pe/lim/limDebug.c b/CORE/MAC/src/pe/lim/limDebug.c
new file mode 100644
index 0000000..bece3ae
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limDebug.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/**=========================================================================
+
+ \file limDebug.c
+
+ \brief implementation for log Debug related APIs
+
+ \author Sunit Bhatia
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+
+ Qualcomm Confidential and Proprietary.
+
+ ========================================================================*/
+
+#include "limDebug.h"
+
+void limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...)
+{
+#ifdef WLAN_DEBUG
+ // Verify against current log level
+ if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_LIM_MODULE_ID )] )
+ return;
+ else
+ {
+ va_list marker;
+
+ va_start( marker, pString ); /* Initialize variable arguments. */
+
+ logDebug(pMac, SIR_LIM_MODULE_ID, loglevel, pString, marker);
+
+ va_end( marker ); /* Reset variable arguments. */
+ }
+#endif
+}
diff --git a/CORE/MAC/src/pe/lim/limDebug.h b/CORE/MAC/src/pe/lim/limDebug.h
new file mode 100644
index 0000000..9715fb6
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limDebug.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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 limDebug.h contains log function called by LIM module.
+ *
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_DEBUG_H__
+#define __LIM_DEBUG_H__
+
+#include "utilsApi.h"
+#include "sirDebug.h"
+
+
+void limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) ;
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limFT.c b/CORE/MAC/src/pe/lim/limFT.c
new file mode 100644
index 0000000..37cf607
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limFT.c
@@ -0,0 +1,1424 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/**=========================================================================
+
+ \brief implementation for PE 11r VoWiFi FT Protocol
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+
+ Qualcomm Confidential and Proprietary.
+
+ ========================================================================*/
+
+/* $Header$ */
+
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include <limSendMessages.h>
+#include <limTypes.h>
+#include <limFT.h>
+#include <limFTDefs.h>
+#include <limUtils.h>
+#include <limPropExtsUtils.h>
+#include <limAssocUtils.h>
+#include <limSession.h>
+#include <limAdmitControl.h>
+#include "wmmApsd.h"
+
+#define LIM_FT_RIC_BA_SSN 1
+#define LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 248
+#define LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA 1
+
+/*--------------------------------------------------------------------------
+ Initialize the FT variables.
+ ------------------------------------------------------------------------*/
+void limFTOpen(tpAniSirGlobal pMac)
+{
+ pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
+ pMac->ft.ftPEContext.psavedsessionEntry = NULL;
+}
+
+/*--------------------------------------------------------------------------
+ Cleanup FT variables.
+ ------------------------------------------------------------------------*/
+void limFTCleanup(tpAniSirGlobal pMac)
+{
+ if (pMac->ft.ftPEContext.pFTPreAuthReq)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p\n",
+ __FUNCTION__, pMac->ft.ftPEContext.pFTPreAuthReq);)
+#endif
+ vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq);
+ pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ // This is the old session, should be deleted else where.
+ // We should not be cleaning it here, just set it to NULL.
+ if (pMac->ft.ftPEContext.psavedsessionEntry)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
+ __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
+#endif
+ pMac->ft.ftPEContext.psavedsessionEntry = NULL;
+ }
+
+ // This is the extra session we added as part of Auth resp
+ // clean it up.
+ if (pMac->ft.ftPEContext.pftSessionEntry)
+ {
+ if ((((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->valid) &&
+ (((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->limSmeState == eLIM_SME_WT_REASSOC_STATE))
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: Deleting Preauth Session %d\n", __func__, ((tpPESession)pMac->ft.ftPEContext.pftSessionEntry)->peSessionId);)
+ peDeleteSession(pMac, pMac->ft.ftPEContext.pftSessionEntry);
+ }
+ pMac->ft.ftPEContext.pftSessionEntry = NULL;
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
+ __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
+#endif
+ }
+
+ if (pMac->ft.ftPEContext.pAddBssReq)
+ {
+ vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
+ pMac->ft.ftPEContext.pAddBssReq = NULL;
+ }
+
+ if (pMac->ft.ftPEContext.pAddStaReq)
+ {
+ vos_mem_free(pMac->ft.ftPEContext.pAddStaReq);
+ pMac->ft.ftPEContext.pAddStaReq = NULL;
+ }
+
+ pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_SUCCESS;
+
+}
+
+/*--------------------------------------------------------------------------
+ Init FT variables.
+ ------------------------------------------------------------------------*/
+void limFTInit(tpAniSirGlobal pMac)
+{
+ if (pMac->ft.ftPEContext.pFTPreAuthReq)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p\n",
+ __FUNCTION__, pMac->ft.ftPEContext.pFTPreAuthReq);)
+#endif
+ vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq);
+ pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ // This is the old session, should be deleted else where.
+ // We should not be cleaning it here, just set it to NULL.
+ if (pMac->ft.ftPEContext.psavedsessionEntry)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
+ __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
+#endif
+ pMac->ft.ftPEContext.psavedsessionEntry = NULL;
+ }
+
+ // This is the extra session we added as part of Auth resp
+ // clean it up.
+ if (pMac->ft.ftPEContext.pftSessionEntry)
+ {
+ /* Cannot delete sessions across associations */
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Deleting session = %p \n",
+ __FUNCTION__, pMac->ft.ftPEContext.pftSessionEntry);)
+#endif
+ pMac->ft.ftPEContext.pftSessionEntry = NULL;
+ }
+
+ if (pMac->ft.ftPEContext.pAddBssReq)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Freeing AddBssReq = %p \n",
+ __FUNCTION__, pMac->ft.ftPEContext.pAddBssReq);)
+#endif
+ vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
+ pMac->ft.ftPEContext.pAddBssReq = NULL;
+ }
+
+
+ if (pMac->ft.ftPEContext.pAddStaReq)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Freeing AddStaReq = %p \n",
+ __FUNCTION__, pMac->ft.ftPEContext.pAddStaReq);)
+#endif
+ vos_mem_free(pMac->ft.ftPEContext.pAddStaReq);
+ pMac->ft.ftPEContext.pAddStaReq = NULL;
+ }
+
+ pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_SUCCESS;
+
+}
+
+/*------------------------------------------------------------------
+ *
+ * This is the handler after suspending the link.
+ * We suspend the link and then now proceed to switch channel.
+ *
+ *------------------------------------------------------------------*/
+void FTPreAuthSuspendLinkHandler(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
+{
+ tpPESession psessionEntry;
+
+ // The link is suspended of not ?
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: Returning \n", __FUNCTION__);)
+ // Post the FT Pre Auth Response to SME
+ limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, (tpPESession)data);
+
+ return;
+ }
+
+ psessionEntry = (tpPESession)data;
+ // Suspended, now move to a different channel.
+ // Perform some sanity check before proceeding.
+ if ((pMac->ft.ftPEContext.pFTPreAuthReq) && psessionEntry)
+ {
+ limChangeChannelWithCallback(pMac,
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
+ limPerformFTPreAuth, NULL, psessionEntry);
+ return;
+ }
+
+ // Else return error.
+ limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
+}
+
+
+/*--------------------------------------------------------------------------
+ In this function, we process the FT Pre Auth Req.
+ We receive Pre-Auth
+ Suspend link
+ Register a call back
+ In the call back, we will need to accept frames from the new bssid
+ Send out the auth req to new AP.
+ Start timer and when the timer is done or if we receive the Auth response
+ We change channel
+ Resume link
+ ------------------------------------------------------------------------*/
+int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ int bufConsumed = FALSE;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+ // Now we are starting fresh make sure all's cleanup.
+ limFTInit(pMac);
+ pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE; // Can set it only after sending auth
+
+ // We need information from the Pre-Auth Req. Lets save that
+ pMac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)pMsg->bodyptr;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: PE Auth ft_ies_length=%02x%02x%02x\n", __FUNCTION__,
+ pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[0],
+ pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[1],
+ pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[2]);)
+#endif
+
+ // Get the current session entry
+ psessionEntry = peFindSessionByBssid(pMac,
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &sessionId);
+ if (psessionEntry == NULL)
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: Unable to find session for the following bssid\n",
+ __FUNCTION__);)
+ limPrintMacAddr( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE );
+ // Post the FT Pre Auth Response to SME
+ limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, NULL);
+ return TRUE;
+ }
+
+ // Dont need to suspend if APs are in same channel
+ if (psessionEntry->currentOperChannel != pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum)
+ {
+ // Need to suspend link only if the channels are different
+ limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, FTPreAuthSuspendLinkHandler,
+ (tANI_U32 *)psessionEntry);
+ }
+ else
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: Performing pre-auth on same channel\n",
+ __FUNCTION__);)
+ // We are in the same channel. Perform pre-auth
+ limPerformFTPreAuth(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry);
+ }
+
+ return bufConsumed;
+}
+
+/*------------------------------------------------------------------
+ * Send the Auth1
+ * Receive back Auth2
+ *------------------------------------------------------------------*/
+void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
+ tpPESession psessionEntry)
+{
+ tSirMacAuthFrameBody authFrame;
+
+ if (psessionEntry->is11Rconnection)
+ {
+ // Only 11r assoc has FT IEs.
+ if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies == NULL)
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: FTIEs for Auth Req Seq 1 is absent\n");)
+ return;
+ }
+ }
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog( pMac, LOGE, "%s: Change channel not successful for FT pre-auth\n");)
+ return;
+ }
+ pMac->ft.ftPEContext.psavedsessionEntry = psessionEntry;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Entered wait auth2 state for FT\n");)
+#endif
+
+
+ if (psessionEntry->is11Rconnection)
+ {
+ // Now we are on the right channel and need to send out Auth1 and
+ // receive Auth2.
+ authFrame.authAlgoNumber = eSIR_FT_AUTH; // Set the auth type to FT
+ }
+#if defined FEATURE_WLAN_CCX
+ else
+ {
+ // Will need to make isCCXconnection a enum may be for further
+ // improvements to this to match this algorithm number
+ authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; // For now if its CCX and 11r FT.
+ }
+#endif
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrame.authStatusCode = 0;
+
+ // Start timer here to come back to operating channel.
+ pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = psessionEntry->peSessionId;
+ if(TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer))
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: FT Auth Rsp Timer Start Failed\n", __FUNCTION__);)
+#endif
+ }
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: FT Auth Rsp Timer Started\n", __FUNCTION__);)
+#endif
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ LIM_NO_WEP_IN_FC, psessionEntry);
+
+ return;
+}
+
+
+/*------------------------------------------------------------------
+ *
+ * Create the new Add Bss Req to the new AP.
+ * This will be used when we are ready to FT to the new AP.
+ * The newly created ft Session entry is passed to this function
+ *
+ *------------------------------------------------------------------*/
+tSirRetStatus limFTPrepareAddBssReq( tpAniSirGlobal pMac,
+ tANI_U8 updateEntry, tpPESession pftSessionEntry,
+ tpSirBssDescription bssDescription )
+{
+ tpAddBssParams pAddBssParams = NULL;
+ tANI_U8 i;
+ tANI_U8 chanWidthSupp = 0;
+ tSchBeaconStruct beaconStruct;
+
+
+ // Package SIR_HAL_ADD_BSS_REQ message parameters
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBssParams, sizeof( tAddBssParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory for creating ADD_BSS\n" ));
+ return (eSIR_MEM_ALLOC_FAILED);
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ));
+
+
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) bssDescription->ieFields,
+ limGetIElenFromBssDescription( bssDescription ), &beaconStruct );
+
+ if (pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideStaProtectionOnAssoc(pMac, &beaconStruct, pftSessionEntry);
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->bssId, bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+
+ // Fill in tAddBssParams selfMacAddr
+ palCopyMemory( pMac->hHdd, pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr,
+ sizeof( tSirMacAddr ));
+
+ pAddBssParams->bssType = pftSessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE;
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = beaconStruct.tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+
+ pAddBssParams->cfParamSet.cfpCount = beaconStruct.cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod = beaconStruct.cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration = beaconStruct.cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining = beaconStruct.cfParamSet.cfpDurRemaining;
+
+
+ pAddBssParams->rateSet.numRates = beaconStruct.supportedRates.numRates;
+ palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
+ beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
+
+ pAddBssParams->nwType = bssDescription->nwType;
+
+ pAddBssParams->shortSlotTimeSupported = (tANI_U8)beaconStruct.capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist = (tANI_U8) pftSessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist = (tANI_U8) pftSessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist = (tANI_U8) pftSessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist = (tANI_U8) pftSessionEntry->beaconParams.ht20Coexist;
+
+ // Use the advertised capabilities from the received beacon/PR
+ if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
+ {
+ pAddBssParams->htCapable = beaconStruct.HTCaps.present;
+
+ if ( beaconStruct.HTInfo.present )
+ {
+ pAddBssParams->htOperMode = (tSirMacHTOperatingMode)beaconStruct.HTInfo.opMode;
+ pAddBssParams->dualCTSProtection = ( tANI_U8 ) beaconStruct.HTInfo.dualCTSProtection;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, pftSessionEntry);
+#else
+ chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET);
+#endif
+ if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->txChannelWidthSet = ( tANI_U8 ) beaconStruct.HTInfo.recommendedTxWidthSet;
+ pAddBssParams->currentExtChannel = beaconStruct.HTInfo.secondaryChannelOffset;
+ }
+ else
+ {
+ pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ pAddBssParams->currentExtChannel = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+ }
+ pAddBssParams->llnNonGFCoexist = (tANI_U8)beaconStruct.HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)beaconStruct.HTInfo.lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode = beaconStruct.HTInfo.rifsMode;
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL( "SIR_HAL_ADD_BSS_REQ with channel = %d..." ),
+ pAddBssParams->currentOperChannel);
+#endif
+
+
+ // Populate the STA-related parameters here
+ // Note that the STA here refers to the AP
+ {
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA
+
+ palCopyMemory( pMac->hHdd, pAddBssParams->staContext.bssId,
+ bssDescription->bssId,
+ sizeof( tSirMacAddr ));
+ pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this?
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)beaconStruct.capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+ pAddBssParams->staContext.encryptType = pftSessionEntry->encryptType;
+
+ if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
+ {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) beaconStruct.HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) beaconStruct.HTCaps.lsigTXOPProtection;
+ if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp) )
+ {
+ pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )beaconStruct.HTInfo.recommendedTxWidthSet;
+ }
+ else
+ {
+ pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ }
+ pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)beaconStruct.HTCaps.mimoPowerSave;
+ pAddBssParams->staContext.delBASupport = ( tANI_U8 ) beaconStruct.HTCaps.delayedBA;
+ pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) beaconStruct.HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity = beaconStruct.HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)beaconStruct.HTCaps.dsssCckMode40MHz;
+ pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI20MHz;
+ pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI40MHz;
+ pAddBssParams->staContext.maxAmpduSize= beaconStruct.HTCaps.maxRxAMPDUFactor;
+
+ if( beaconStruct.HTInfo.present )
+ pAddBssParams->staContext.rifsMode = beaconStruct.HTInfo.rifsMode;
+ }
+
+ if ((pftSessionEntry->limWmeEnabled && beaconStruct.wmeEdcaPresent) ||
+ (pftSessionEntry->limQosEnabled && beaconStruct.edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ //Update the rates
+
+ limPopulateOwnRateSet(pMac, &pAddBssParams->staContext.supportedRates,
+ beaconStruct.HTCaps.supportedMCSSet, false,pftSessionEntry);
+ limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,pftSessionEntry);
+
+ }
+
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < STACFG_MAX_TC; i++ )
+ {
+ pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
+ pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
+ pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;
+#endif
+
+ pAddBssParams->status = eHAL_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId;
+ pAddBssParams->sessionId = pftSessionEntry->peSessionId;
+
+ // Set a new state for MLME
+
+ pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
+
+ pAddBssParams->halPersona=(tANI_U8)pftSessionEntry->pePersona; //pass on the session persona to hal
+
+ pMac->ft.ftPEContext.pAddBssReq = pAddBssParams;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL( "Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..." ));
+#endif
+
+ return 0;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Setup the new session for the pre-auth AP.
+ * Return the newly created session entry.
+ *
+ *------------------------------------------------------------------*/
+tpPESession limFillFTSession(tpAniSirGlobal pMac,
+ tpSirBssDescription pbssDescription, tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry;
+ tANI_U8 currentBssUapsd;
+ tANI_U8 sessionId;
+ tPowerdBm localPowerConstraint;
+ tPowerdBm regMax;
+ tSchBeaconStruct beaconStruct;
+
+ if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId,
+ &sessionId, pMac->lim.maxStation)) == NULL)
+ {
+ limLog(pMac, LOGE, FL("Session Can not be created for pre-auth 11R AP\n"));
+ return NULL;
+ }
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX
+ limPrintMacAddr(pMac, pbssDescription->bssId, LOGE);
+#endif
+
+ /* Store PE session Id in session Table */
+ pftSessionEntry->peSessionId = sessionId;
+
+ pftSessionEntry->dot11mode = psessionEntry->dot11mode;
+ pftSessionEntry->htCapabality = psessionEntry->htCapabality;
+
+ pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled;
+ pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled;
+ pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled;
+ pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable;
+
+ // Fields to be filled later
+ pftSessionEntry->pLimJoinReq = NULL;
+ pftSessionEntry->smeSessionId = 0;
+ pftSessionEntry->transactionId = 0;
+
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) pbssDescription->ieFields,
+ limGetIElenFromBssDescription( pbssDescription ),
+ &beaconStruct );
+
+ pftSessionEntry->rateSet.numRates = beaconStruct.supportedRates.numRates;
+ palCopyMemory( pMac->hHdd, pftSessionEntry->rateSet.rate,
+ beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
+
+ pftSessionEntry->extRateSet.numRates = beaconStruct.extendedRates.numRates;
+ palCopyMemory(pMac->hHdd, pftSessionEntry->extRateSet.rate,
+ beaconStruct.extendedRates.rate, pftSessionEntry->extRateSet.numRates);
+
+
+ pftSessionEntry->ssId.length = beaconStruct.ssId.length;
+ palCopyMemory( pMac->hHdd, pftSessionEntry->ssId.ssId, beaconStruct.ssId.ssId,
+ pftSessionEntry->ssId.length);
+
+
+ // Self Mac
+ sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr);
+ sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId);
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX
+ limPrintMacAddr(pMac, pftSessionEntry->limReAssocbssId, LOGE);
+#endif
+
+ /* Store beaconInterval */
+ pftSessionEntry->beaconParams.beaconInterval = pbssDescription->beaconInterval;
+ pftSessionEntry->bssType = psessionEntry->bssType;
+
+ pftSessionEntry->statypeForBss = STA_ENTRY_PEER;
+ pftSessionEntry->nwType = pbssDescription->nwType;
+
+ /* Copy The channel Id to the session Table */
+ pftSessionEntry->limReassocChannelId = pbssDescription->channelId;
+ pftSessionEntry->currentOperChannel = pbssDescription->channelId;
+
+
+ if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
+ {
+ pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+ }
+ else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ }
+ else
+ {
+ /* Throw an error and return and make sure to delete the session.*/
+ limLog(pMac, LOGE, FL("Invalid bss type\n"));
+ }
+
+ pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo;
+ pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo;
+
+ pftSessionEntry->limCurrentTitanHtCaps=
+ pbssDescription->titanHtCaps;
+ pftSessionEntry->limReassocTitanHtCaps=
+ pftSessionEntry->limCurrentTitanHtCaps;
+
+ regMax = cfgGetRegulatoryMaxTransmitPower( pMac, pftSessionEntry->currentOperChannel );
+ localPowerConstraint = regMax;
+ limExtractApCapability( pMac, (tANI_U8 *) pbssDescription->ieFields,
+ limGetIElenFromBssDescription(pbssDescription),
+ &pftSessionEntry->limCurrentBssQosCaps,
+ &pftSessionEntry->limCurrentBssPropCap,
+ ¤tBssUapsd , &localPowerConstraint);
+
+ pftSessionEntry->limReassocBssQosCaps =
+ pftSessionEntry->limCurrentBssQosCaps;
+ pftSessionEntry->limReassocBssPropCap =
+ pftSessionEntry->limCurrentBssPropCap;
+
+
+ pftSessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) );
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, "%s: Regulatory max = %d, local power constraint = %d, max tx = %d",
+ __FUNCTION__, regMax, localPowerConstraint, pftSessionEntry->maxTxPower );
+#endif
+
+ pftSessionEntry->limRFBand = limGetRFBand(pftSessionEntry->currentOperChannel);
+
+ pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+ pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+ pftSessionEntry->encryptType = psessionEntry->encryptType;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Created session with the id = %d\n",
+ __FUNCTION__, pftSessionEntry->peSessionId);)
+#endif
+
+ return pftSessionEntry;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Setup the session and the add bss req for the pre-auth AP.
+ *
+ *------------------------------------------------------------------*/
+void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry;
+
+ // Prepare the session right now with as much as possible.
+ pftSessionEntry = limFillFTSession(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription, psessionEntry);
+
+ if (pftSessionEntry)
+ {
+ pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection;
+#ifdef FEATURE_WLAN_CCX
+ pftSessionEntry->isCCXconnection = psessionEntry->isCCXconnection;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX
+ pftSessionEntry->isFastTransitionEnabled = psessionEntry->isFastTransitionEnabled;
+#endif
+ limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry,
+ pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription );
+ pMac->ft.ftPEContext.pftSessionEntry = pftSessionEntry;
+ }
+}
+
+/*------------------------------------------------------------------
+ * Resume Link Call Back
+ *------------------------------------------------------------------*/
+void limFTProcessPreAuthResult(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
+{
+ tpPESession psessionEntry;
+
+ psessionEntry = (tpPESession)data;
+
+ if (pMac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS)
+ {
+ limFTSetupAuthSession(pMac, psessionEntry);
+ }
+
+ // Post the FT Pre Auth Response to SME
+ limPostFTPreAuthRsp(pMac, pMac->ft.ftPEContext.ftPreAuthStatus,
+ pMac->ft.ftPEContext.saved_auth_rsp,
+ pMac->ft.ftPEContext.saved_auth_rsp_length, psessionEntry);
+
+}
+
+/*------------------------------------------------------------------
+ * Resume Link Call Back
+ *------------------------------------------------------------------*/
+void limPerformPostFTPreAuthAndChannelChange(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
+ tpPESession psessionEntry)
+{
+ //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);
+ limResumeLink(pMac, limFTProcessPreAuthResult, (tANI_U32 *)psessionEntry);
+}
+
+tSirRetStatus limCreateRICBlockAckIE(tpAniSirGlobal pMac, tANI_U8 tid, tCfgTrafficClass *pTrafficClass,
+ tANI_U8 *ric_ies, tANI_U32 *ieLength)
+{
+ tDot11fIERICDataDesc ricIe;
+ tDot11fFfBAStartingSequenceControl baSsnControl;
+ tDot11fFfAddBAParameterSet baParamSet;
+ tDot11fFfBATimeout baTimeout;
+
+ vos_mem_zero(&ricIe, sizeof(tDot11fIERICDataDesc));
+ vos_mem_zero(&baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
+ vos_mem_zero(&baParamSet, sizeof(tDot11fFfAddBAParameterSet));
+ vos_mem_zero(&baTimeout, sizeof(tDot11fFfBATimeout));
+
+ ricIe.present = 1;
+ ricIe.RICData.present = 1;
+ ricIe.RICData.resourceDescCount = 1;
+ ricIe.RICData.Identifier = LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 + tid;
+ ricIe.RICDescriptor.present = 1;
+ ricIe.RICDescriptor.resourceType = LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA;
+ baParamSet.tid = tid;
+ baParamSet.policy = pTrafficClass->fTxBApolicy; // Immediate Block Ack
+ baParamSet.bufferSize = pTrafficClass->txBufSize;
+ vos_mem_copy((v_VOID_t *)&baTimeout, (v_VOID_t *)&pTrafficClass->tuTxBAWaitTimeout, sizeof(baTimeout));
+ baSsnControl.fragNumber = 0;
+ baSsnControl.ssn = LIM_FT_RIC_BA_SSN;
+
+ dot11fPackFfAddBAParameterSet(pMac, &baParamSet, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
+ //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baParamSet, sizeof(tDot11fFfAddBAParameterSet));
+ ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfAddBAParameterSet);
+
+ dot11fPackFfBATimeout(pMac, &baTimeout, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
+ //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baTimeout, sizeof(tDot11fFfBATimeout));
+ ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBATimeout);
+
+ dot11fPackFfBAStartingSequenceControl(pMac, &baSsnControl, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
+ //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
+ ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBAStartingSequenceControl);
+
+ return (tSirRetStatus) dot11fPackIeRICDataDesc(pMac, &ricIe, ric_ies, sizeof(tDot11fIERICDataDesc), ieLength);
+}
+
+tSirRetStatus limFTFillRICBlockAckInfo(tpAniSirGlobal pMac, tANI_U8 *ric_ies, tANI_U32 *ric_ies_length)
+{
+ tANI_U8 tid = 0;
+ tpDphHashNode pSta;
+ tANI_U16 numBA = 0, aid = 0;
+ tpPESession psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry;
+ tANI_U32 offset = 0, ieLength = 0;
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ // First, extract the DPH entry
+ pSta = dphLookupHashEntry( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &aid, &psessionEntry->dph.dphHashTable);
+ if( NULL == pSta )
+ {
+ PELOGE(limLog( pMac, LOGE,
+ FL( "STA context not found for saved session's BSSID %02x:%02x:%02x:%02x:%02x:%02x\n" ),
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[0],
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[1],
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[2],
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[3],
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[4],
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[5] );)
+ return eSIR_FAILURE;
+ }
+
+ for (tid = 0; tid < STACFG_MAX_TC; tid++)
+ {
+ if (pSta->tcCfg[tid].fUseBATx)
+ {
+ status = limCreateRICBlockAckIE(pMac, tid, &pSta->tcCfg[tid], ric_ies + offset, &ieLength);
+ if (eSIR_SUCCESS == status)
+ {
+ offset += ieLength;
+ *ric_ies_length += ieLength;
+ numBA++;
+ }
+ else
+ {
+ PELOGE(limLog(pMac, LOGE, FL("BA RIC IE creation for TID %d failed with status %d"), tid, status);)
+ }
+ }
+ }
+
+ PELOGE(limLog(pMac, LOGE, FL("Number of BA RIC IEs created = %d: Total length = %d\n"), numBA, *ric_ies_length);)
+ return status;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Will post pre auth response to SME.
+ *
+ *------------------------------------------------------------------*/
+void limPostFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
+ tpPESession psessionEntry)
+{
+ tpSirFTPreAuthRsp pFTPreAuthRsp;
+ tSirMsgQ mmhMsg;
+ tANI_U16 rspLen = sizeof(tSirFTPreAuthRsp);
+ tSirRetStatus sirStatus = eSIR_SUCCESS;
+
+ pFTPreAuthRsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rspLen);
+ if(NULL == pFTPreAuthRsp)
+ {
+ PELOGE(limLog( pMac, LOGE, "Failed to allocate memory\n");)
+ VOS_ASSERT(pFTPreAuthRsp != NULL);
+ return;
+ }
+ vos_mem_zero( pFTPreAuthRsp, rspLen);
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "%s: Auth Rsp = %p\n", pFTPreAuthRsp);)
+#endif
+
+ palZeroMemory(pMac, (tANI_U8*)pFTPreAuthRsp, rspLen);
+ pFTPreAuthRsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
+ pFTPreAuthRsp->length = (tANI_U16) rspLen;
+ pFTPreAuthRsp->status = status;
+ if (psessionEntry)
+ pFTPreAuthRsp->smeSessionId = psessionEntry->smeSessionId;
+
+ // The bssid of the AP we are sending Auth1 to.
+ if (pMac->ft.ftPEContext.pFTPreAuthReq)
+ sirCopyMacAddr(pFTPreAuthRsp->preAuthbssId,
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
+
+ // Attach the auth response now back to SME
+ pFTPreAuthRsp->ft_ies_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
+ {
+ // Only 11r assoc has FT IEs.
+ vos_mem_copy(pFTPreAuthRsp->ft_ies, auth_rsp, auth_rsp_length);
+ pFTPreAuthRsp->ft_ies_length = auth_rsp_length;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if ((psessionEntry) && (psessionEntry->is11Rconnection))
+ {
+ /* Fill in the Block Ack RIC IEs in the preAuthRsp */
+ sirStatus = limFTFillRICBlockAckInfo(pMac, pFTPreAuthRsp->ric_ies,
+ (tANI_U32 *)&pFTPreAuthRsp->ric_ies_length);
+ if (eSIR_SUCCESS != sirStatus)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Fill RIC BA Info failed with status %d"), sirStatus);)
+ }
+ }
+#endif
+
+ mmhMsg.type = pFTPreAuthRsp->messageType;
+ mmhMsg.bodyptr = pFTPreAuthRsp;
+ mmhMsg.bodyval = 0;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME\n");)
+#endif
+ PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME with status of %d\n", status);)
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+/*------------------------------------------------------------------
+ *
+ * Send the FT Pre Auth Response to SME when ever we have a status
+ * ready to be sent to SME
+ *
+ * SME will be the one to send it up to the supplicant to receive
+ * FTIEs which will be required for Reassoc Req.
+ *
+ *------------------------------------------------------------------*/
+void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
+ tpPESession psessionEntry)
+{
+
+ // Save the status of pre-auth
+ pMac->ft.ftPEContext.ftPreAuthStatus = status;
+
+ // Save the auth rsp, so we can send it to
+ // SME once we resume link.
+ pMac->ft.ftPEContext.saved_auth_rsp_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
+ {
+ vos_mem_copy(pMac->ft.ftPEContext.saved_auth_rsp,
+ auth_rsp, auth_rsp_length);
+ pMac->ft.ftPEContext.saved_auth_rsp_length = auth_rsp_length;
+ }
+
+ if (psessionEntry->currentOperChannel !=
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum)
+ {
+ // Need to move to the original AP channel
+ limChangeChannelWithCallback(pMac, psessionEntry->currentOperChannel,
+ limPerformPostFTPreAuthAndChannelChange, NULL, psessionEntry);
+ }
+ else
+ {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Pre auth on same channel as connected AP channel %d\n",
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);)
+#endif
+ limFTProcessPreAuthResult(pMac, status, (tANI_U32 *)psessionEntry);
+ }
+}
+
+/*------------------------------------------------------------------
+ *
+ * This function handles the 11R Reassoc Req from SME
+ *
+ *------------------------------------------------------------------*/
+void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf,
+ tpPESession psessionEntry)
+{
+ tANI_U8 smeSessionId = 0;
+ tANI_U16 transactionId = 0;
+ tANI_U8 chanNum = 0;
+ tLimMlmReassocReq *pMlmReassocReq;
+ tANI_U16 caps;
+ tANI_U32 val;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ tANI_U32 teleBcnEn = 0;
+
+ chanNum = psessionEntry->currentOperChannel;
+ limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
+ psessionEntry->smeSessionId = smeSessionId;
+ psessionEntry->transactionId = transactionId;
+
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmReassocReq,
+ sizeof(tLimMlmReassocReq)))
+ {
+ // Log error
+ limLog(pMac, LOGE, FL("call to palAllocateMemory failed for mlmReassocReq\n"));
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, pMlmReassocReq->peerMacAddr,
+ psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE, FL("could not retrieve ReassocFailureTimeout value\n"));
+ return;
+ }
+
+ if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE, FL("could not retrieve Capabilities value\n"));
+ return;
+ }
+ pMlmReassocReq->capabilityInfo = caps;
+
+ /* Update PE sessionId*/
+ pMlmReassocReq->sessionId = psessionEntry->peSessionId;
+
+ /* If telescopic beaconing is enabled, set listen interval to WNI_CFG_TELE_BCN_MAX_LI */
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
+ eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN\n"));
+
+ if(teleBcnEn)
+ {
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != eSIR_SUCCESS)
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
+ return;
+ }
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
+ return;
+ }
+ }
+ if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ return;
+ }
+
+ if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ return;
+ }
+
+ if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ return;
+ }
+
+ pMlmReassocReq->listenInterval = (tANI_U16) val;
+
+ psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
+
+
+ //we need to defer the message until we get the response back from HAL.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = SIR_HAL_ADD_BSS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMac->ft.ftPEContext.pAddBssReq;
+ msgQ.bodyval = 0;
+
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
+#endif
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if( eSIR_SUCCESS != retCode)
+ {
+ vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
+ limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
+ retCode );
+ }
+ // Dont need this anymore
+ pMac->ft.ftPEContext.pAddBssReq = NULL;
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * This function is called if preauth response is not received from the AP
+ * within this timeout while FT in progress
+ *
+ *------------------------------------------------------------------*/
+void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac)
+{
+ tpPESession psessionEntry;
+
+ // We have failed pre auth. We need to resume link and get back on
+ // home channel.
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ // Ok, so attempted at Pre-Auth and failed. If we are off channel. We need
+ // to get back.
+ limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
+}
+
+
+/*------------------------------------------------------------------
+ *
+ * This function is called to process the update key request from SME
+ *
+ *------------------------------------------------------------------*/
+tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
+{
+ tAddBssParams * pAddBssParams;
+ tSirFTUpdateKeyInfo * pKeyInfo;
+ tANI_U32 val = 0;
+
+ /* Sanity Check */
+ if( pMac == NULL || pMsgBuf == NULL )
+ {
+ return TRUE;
+ }
+
+ pAddBssParams = pMac->ft.ftPEContext.pAddBssReq;
+ pKeyInfo = (tSirFTUpdateKeyInfo *)pMsgBuf;
+
+ /* Store the key information in the ADD BSS parameters */
+ pAddBssParams->extSetStaKeyParamValid = 1;
+ pAddBssParams->extSetStaKeyParam.encType = pKeyInfo->keyMaterial.edType;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pAddBssParams->extSetStaKeyParam.key,
+ (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof( tSirKeys ));
+ if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val))
+ {
+ limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC\n" ));
+ }
+
+ pAddBssParams->extSetStaKeyParam.singleTidRc = val;
+
+ return TRUE;
+}
+
+tSirRetStatus
+limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
+{
+ tSirMsgQ msg;
+ tSirAggrQosReq * aggrQosReq = (tSirAggrQosReq *)pMsgBuf;
+ tpAggrAddTsParams pAggrAddTsParam;
+ tpPESession psessionEntry = NULL;
+ tpLimTspecInfo tspecInfo;
+ tANI_U8 ac;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+ int i;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **)&pAggrAddTsParam,
+ sizeof(tAggrAddTsParams)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory() failed\n"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ psessionEntry = peFindSessionByBssid(pMac, aggrQosReq->bssId, &sessionId);
+
+ if (psessionEntry == NULL) {
+ PELOGE(limLog(pMac, LOGE, FL("psession Entry Null for sessionId = %d\n"), aggrQosReq->sessionId);)
+ return eSIR_FAILURE;
+ }
+
+ pSta = dphLookupHashEntry(pMac, aggrQosReq->bssId, &aid, &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pAggrAddTsParam,
+ sizeof(tAggrAddTsParams));
+ pAggrAddTsParam->staIdx = psessionEntry->staId;
+ // Fill in the sessionId specific to PE
+ pAggrAddTsParam->sessionId = sessionId;
+ pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
+
+ for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
+ {
+ if (aggrQosReq->aggrInfo.tspecIdx & (1<<i))
+ {
+ tSirMacTspecIE *pTspec = &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+ /* Since AddTS response was successful, check for the PSB flag
+ * and directional flag inside the TS Info field.
+ * An AC is trigger enabled AC if the PSB subfield is set to 1
+ * in the uplink direction.
+ * An AC is delivery enabled AC if the PSB subfield is set to 1
+ * in the downlink direction.
+ * An AC is trigger and delivery enabled AC if the PSB subfield
+ * is set to 1 in the bi-direction field.
+ */
+ if (pTspec->tsinfo.traffic.psb == 1)
+ {
+ limSetTspecUapsdMask(pMac, &pTspec->tsinfo, SET_UAPSD_MASK);
+ }
+ else
+ {
+ limSetTspecUapsdMask(pMac, &pTspec->tsinfo, CLEAR_UAPSD_MASK);
+ }
+ /* ADDTS success, so AC is now admitted. We shall now use the default
+ * EDCA parameters as advertised by AP and send the updated EDCA params
+ * to HAL.
+ */
+ ac = upToAc(pTspec->tsinfo.traffic.userPrio);
+ if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
+ }
+ else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
+ }
+ else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
+ }
+
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ if (pSta->aniPeer == eANI_BOOLEAN_TRUE)
+ {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_TRUE);
+ }
+ else
+ {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_FALSE);
+ }
+
+ if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, pTspec, 0, &tspecInfo))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
+ pMac->lim.gLimAddtsSent = false;
+ return eSIR_FAILURE; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
+ }
+
+ // Copy the TSPEC paramters
+ pAggrAddTsParam->tspec[i] = aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+ }
+ }
+
+ msg.type = WDA_AGGR_QOS_REQ;
+ msg.bodyptr = pAggrAddTsParam;
+ msg.bodyval = 0;
+
+ /* We need to defer any incoming messages until we get a
+ * WDA_AGGR_QOS_RSP from HAL.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (tANI_U8*)pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+void
+limFTSendAggrQosRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd,
+ tpAggrAddTsParams aggrQosRsp, tANI_U8 smesessionId)
+{
+ tpSirAggrQosRsp rsp;
+ int i = 0;
+
+ if (! rspReqd)
+ {
+ return;
+ }
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp,
+ sizeof(tSirAggrQosRsp)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for tSirAggrQosRsp"));
+ return;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
+ rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
+ rsp->sessionId = smesessionId;
+ rsp->length = sizeof(*rsp);
+ rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
+
+ for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ )
+ {
+ if( (1 << i) & aggrQosRsp->tspecIdx )
+ {
+ rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i];
+ rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
+ }
+ }
+
+ limSendSmeAggrQosRsp(pMac, rsp, smesessionId);
+ return;
+}
+
+
+void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpAggrAddTsParams pAggrQosRspMsg = NULL;
+ //tpAggrQosParams pAggrQosRspMsg = NULL;
+ tAddTsParams addTsParam = {0};
+ tpDphHashNode pSta = NULL;
+ tANI_U16 assocId =0;
+ tSirMacAddr peerMacAddr;
+ tANI_U8 rspReqd = 1;
+ tpPESession psessionEntry = NULL;
+ int i = 0;
+
+ PELOG1(limLog(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL\n"));)
+
+ /* Need to process all the deferred messages enqueued since sending the
+ SIR_HAL_AGGR_ADD_TS_REQ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr);
+ if (NULL == pAggrQosRspMsg)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("NULL pAggrQosRspMsg"));)
+ return;
+ }
+
+ psessionEntry = peFindSessionBySessionId(pMac, pAggrQosRspMsg->sessionId);
+ if (NULL == psessionEntry)
+ {
+ // Cant find session entry
+ PELOGE(limLog(pMac, LOGE, FL("Cant find session entry for %s\n"), __FUNCTION__);)
+ if( pAggrQosRspMsg != NULL )
+ {
+ palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
+ }
+ return;
+ }
+
+ for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
+ {
+ if((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
+ (pAggrQosRspMsg->status[i] != eHAL_STATUS_SUCCESS))
+ {
+ /* send DELTS to the station */
+ sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
+
+ addTsParam.staIdx = pAggrQosRspMsg->staIdx;
+ addTsParam.sessionId = pAggrQosRspMsg->sessionId;
+ addTsParam.tspec = pAggrQosRspMsg->tspec[i];
+ addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx;
+
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd,
+ &addTsParam.tspec.tsinfo,
+ &addTsParam.tspec, psessionEntry);
+
+ pSta = dphLookupAssocId(pMac, addTsParam.staIdx, &assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta != NULL)
+ {
+ limAdmitControlDeleteTS(pMac, assocId, &addTsParam.tspec.tsinfo,
+ NULL, (tANI_U8 *)&addTsParam.tspecIdx);
+ }
+ }
+ }
+
+ /* Send the Aggr QoS response to SME */
+
+ limFTSendAggrQosRsp(pMac, rspReqd, pAggrQosRspMsg,
+ psessionEntry->smeSessionId);
+ if( pAggrQosRspMsg != NULL )
+ {
+ palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
+ }
+ return;
+}
+
+
+/*--------------------------------------------------------------------------
+ Determines if a session with ccx or 11r assoc is present.
+ If present it will return TRUE else FALSE
+ ------------------------------------------------------------------------*/
+int limisFastTransitionRequired(tpAniSirGlobal pMac, int sessionId)
+{
+ if(pMac->lim.gpSession[sessionId].valid == TRUE)
+ {
+ // If ccx or 11r connection is found we need to return TRUE
+ if((pMac->lim.gpSession[sessionId].bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (((pMac->lim.gpSession[sessionId].is11Rconnection)
+#ifdef FEATURE_WLAN_CCX
+ || (pMac->lim.gpSession[sessionId].isCCXconnection)
+#endif
+ )&&
+ pMac->lim.gpSession[sessionId].isFastTransitionEnabled))
+ {
+ // Make sure we have 11r/CCX and FT enabled only then we need
+ // the values to be altered from cfg for FW RSSI Period alteration.
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
diff --git a/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c
new file mode 100644
index 0000000..e98aeae
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c
@@ -0,0 +1,1669 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limIbssPeerMgmt.cc contains the utility functions
+ * LIM uses to maintain peers in IBSS.
+ * Author: Chandra Modumudi
+ * Date: 03/12/04
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#include "palTypes.h"
+#include "aniGlobal.h"
+#include "sirCommon.h"
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limStaHashApi.h"
+#include "schApi.h" // schSetFixedBeaconFields for IBSS coalesce
+#include "limSecurityUtils.h"
+#include "limSendMessages.h"
+#include "limSession.h"
+#include "limIbssPeerMgmt.h"
+
+
+/**
+ * ibss_peer_find
+ *
+ *FUNCTION:
+ * This function is called while adding a context at
+ * DPH & Polaris for a peer in IBSS.
+ * If peer is found in the list, capabilities from the
+ * returned BSS description are used at DPH node & Polaris.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param macAddr - MAC address of the peer
+ *
+ * @return Pointer to peer node if found, else NULL
+ */
+
+static tLimIbssPeerNode *
+ibss_peer_find(
+ tpAniSirGlobal pMac,
+ tSirMacAddr macAddr)
+{
+ tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList;
+
+ while (pTempNode != NULL)
+ {
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
+ (tANI_U8 *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ break;
+ pTempNode = pTempNode->next;
+ }
+ return pTempNode;
+} /*** end ibss_peer_find() ***/
+
+/**
+ * ibss_peer_add
+ *
+ *FUNCTION:
+ * This is called on a STA in IBSS upon receiving Beacon/
+ * Probe Response from a peer.
+ *
+ *LOGIC:
+ * Node is always added to the front of the list
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pPeerNode - Pointer to peer node to be added to the list.
+ *
+ * @return None
+ */
+
+static tSirRetStatus
+ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode)
+{
+#ifdef ANI_SIR_IBSS_PEER_CACHING
+ tANI_U32 numIbssPeers = (2 * pMac->lim.maxStation);
+
+ if (pMac->lim.gLimNumIbssPeers >= numIbssPeers)
+ {
+ /**
+ * Reached max number of peers to be maintained.
+ * Delete last entry & add new entry at the beginning.
+ */
+ tLimIbssPeerNode *pTemp, *pPrev;
+ pTemp = pPrev = pMac->lim.gLimIbssPeerList;
+ while (pTemp->next != NULL)
+ {
+ pPrev = pTemp;
+ pTemp = pTemp->next;
+ }
+ if(pTemp->beacon)
+ {
+ palFreeMemory(pMac->hHdd, pTemp->beacon);
+ }
+
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pTemp);
+ pPrev->next = NULL;
+ }
+ else
+#endif
+ pMac->lim.gLimNumIbssPeers++;
+
+ pPeerNode->next = pMac->lim.gLimIbssPeerList;
+ pMac->lim.gLimIbssPeerList = pPeerNode;
+
+ return eSIR_SUCCESS;
+
+} /*** end limAddIbssPeerToList() ***/
+
+/**
+ * ibss_peer_collect
+ *
+ *FUNCTION:
+ * This is called to collect IBSS peer information
+ * from received Beacon/Probe Response frame from it.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pBD - Pointer to received BD
+ * @param pPeer - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_peer_collect(
+ tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon,
+ tpSirMacMgmtHdr pHdr,
+ tLimIbssPeerNode *pPeer,
+ tpPESession psessionEntry)
+{
+ palCopyMemory( pMac->hHdd, pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
+
+ pPeer->capabilityInfo = pBeacon->capabilityInfo;
+ pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent;
+ pPeer->edcaPresent = pBeacon->edcaPresent;
+ pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent;
+ pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent;
+
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ (pBeacon->HTCaps.present))
+ {
+ pPeer->htCapable = pBeacon->HTCaps.present;
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)pPeer->supportedMCSSet,
+ (tANI_U8 *)pBeacon->HTCaps.supportedMCSSet,
+ sizeof(pPeer->supportedMCSSet));
+ pPeer->htGreenfield = (tANI_U8)pBeacon->HTCaps.greenField;
+ pPeer->htSupportedChannelWidthSet = ( tANI_U8 ) pBeacon->HTCaps.supportedChannelWidthSet;
+ pPeer->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pBeacon->HTCaps.mimoPowerSave;
+ pPeer->htMaxAmsduLength = ( tANI_U8 ) pBeacon->HTCaps.maximalAMSDUsize;
+ pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity;
+ pPeer->htDsssCckRate40MHzSupport = (tANI_U8)pBeacon->HTCaps.dsssCckMode40MHz;
+ pPeer->htShortGI20Mhz = (tANI_U8)pBeacon->HTCaps.shortGI20MHz;
+ pPeer->htShortGI40Mhz = (tANI_U8)pBeacon->HTCaps.shortGI40MHz;
+ pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor;
+ }
+
+ pPeer->erpIePresent = pBeacon->erpPresent;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pPeer->supportedRates,
+ (tANI_U8 *) &pBeacon->supportedRates,
+ pBeacon->supportedRates.numRates + 1);
+ if (pPeer->extendedRatesPresent)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pPeer->extendedRates,
+ (tANI_U8 *) &pBeacon->extendedRates,
+ pBeacon->extendedRates.numRates + 1);
+ else
+ pPeer->extendedRates.numRates = 0;
+
+ // TBD copy EDCA parameters
+ // pPeer->edcaParams;
+
+ pPeer->next = NULL;
+} /*** end ibss_peer_collect() ***/
+
+// handle change in peer qos/wme capabilities
+static void
+ibss_sta_caps_update(
+ tpAniSirGlobal pMac,
+ tLimIbssPeerNode *pPeerNode,
+ tpPESession psessionEntry)
+{
+ tANI_U16 aid;
+ tpDphHashNode pStaDs;
+
+ pPeerNode->beaconHBCount++; //Update beacon count.
+
+ // if the peer node exists, update its qos capabilities
+ if ((pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable)) == NULL)
+ return;
+
+
+ //Update HT Capabilities
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode))
+ {
+ pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable;
+ if (pPeerNode->htCapable)
+ {
+ pStaDs->htGreenfield = pPeerNode->htGreenfield;
+ pStaDs->htSupportedChannelWidthSet = pPeerNode->htSupportedChannelWidthSet;
+ pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState;
+ pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength;
+ pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport = pPeerNode->htDsssCckRate40MHzSupport;
+ pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz;
+ pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz;
+ pStaDs->htMaxRxAMpduFactor = pPeerNode->htMaxRxAMpduFactor;
+ // In the future, may need to check for "delayedBA"
+ // For now, it is IMMEDIATE BA only on ALL TID's
+ pStaDs->baPolicyFlag = 0xFF;
+ }
+ }
+
+ if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode) &&
+ pPeerNode->aniIndicator)
+ {
+ pStaDs->aniPeer = pPeerNode->aniIndicator;
+ pStaDs->propCapability = pPeerNode->propCapability;
+ }
+
+
+ // peer is 11e capable but is not 11e enabled yet
+ // some STA's when joining Airgo IBSS, assert qos capability even when
+ // they don't suport qos. however, they do not include the edca parameter
+ // set. so let's check for edcaParam in addition to the qos capability
+ if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled) && pPeerNode->edcaPresent)
+ {
+ pStaDs->qosMode = 1;
+ pStaDs->wmeEnabled = 0;
+ if (! pStaDs->lleEnabled)
+ {
+ pStaDs->lleEnabled = 1;
+ //dphSetACM(pMac, pStaDs);
+ }
+ return;
+ }
+ // peer is not 11e capable now but was 11e enabled earlier
+ else if (pStaDs->lleEnabled)
+ {
+ pStaDs->qosMode = 0;
+ pStaDs->lleEnabled = 0;
+ }
+
+ // peer is wme capable but is not wme enabled yet
+ if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled)
+ {
+ pStaDs->qosMode = 1;
+ pStaDs->lleEnabled = 0;
+ if (! pStaDs->wmeEnabled)
+ {
+ pStaDs->wmeEnabled = 1;
+ //dphSetACM(pMac, pStaDs);
+ }
+ return;
+ }
+ /* When the peer device supports EDCA parameters, then we were not
+ considering. Added this code when we saw that one of the Peer Device
+ was advertising WMM param where we were not honouring that. CR# 210756
+ */
+ if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) {
+ pStaDs->qosMode = 1;
+ pStaDs->lleEnabled = 0;
+ if (! pStaDs->wmeEnabled) {
+ pStaDs->wmeEnabled = 1;
+ }
+ return;
+ }
+
+ // peer is not wme capable now but was wme enabled earlier
+ else if (pStaDs->wmeEnabled)
+ {
+ pStaDs->qosMode = 0;
+ pStaDs->wmeEnabled = 0;
+ }
+
+}
+
+static void
+ibss_sta_rates_update(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tLimIbssPeerNode *pPeer,
+ tpPESession psessionEntry)
+{
+ // Populate supported rateset
+ limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates,
+ &pPeer->extendedRates, pPeer->supportedMCSSet,
+ &pStaDs->mlmStaContext.propRateSet,psessionEntry);
+
+ pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
+} /*** end ibss_sta_info_update() ***/
+
+/**
+ * ibss_sta_info_update
+ *
+ *FUNCTION:
+ * This is called to program both SW & Polaris context
+ * for peer in IBSS.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to DPH node
+ * @param pPeer - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_sta_info_update(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tLimIbssPeerNode *pPeer,
+ tpPESession psessionEntry)
+{
+ pStaDs->staType = STA_ENTRY_PEER;
+ ibss_sta_caps_update(pMac, pPeer,psessionEntry);
+ ibss_sta_rates_update(pMac, pStaDs, pPeer,psessionEntry);
+} /*** end ibss_sta_info_update() ***/
+
+static void
+ibss_coalesce_free(
+ tpAniSirGlobal pMac)
+{
+ if (pMac->lim.ibssInfo.pHdr != NULL)
+ palFreeMemory(pMac->hHdd, pMac->lim.ibssInfo.pHdr);
+ if (pMac->lim.ibssInfo.pBeacon != NULL)
+ palFreeMemory(pMac->hHdd, pMac->lim.ibssInfo.pBeacon);
+
+ pMac->lim.ibssInfo.pHdr = NULL;
+ pMac->lim.ibssInfo.pBeacon = NULL;
+}
+
+/*
+ * save the beacon params for use when adding the bss
+ */
+static void
+ibss_coalesce_save(
+ tpAniSirGlobal pMac,
+ tpSirMacMgmtHdr pHdr,
+ tpSchBeaconStruct pBeacon)
+{
+ eHalStatus status;
+
+ // get rid of any saved info
+ ibss_coalesce_free(pMac);
+
+ status = palAllocateMemory(pMac->hHdd, (void **) &pMac->lim.ibssInfo.pHdr,
+ sizeof(*pHdr));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pHdr\n"));)
+ return;
+ }
+ status = palAllocateMemory(pMac->hHdd, (void **) &pMac->lim.ibssInfo.pBeacon,
+ sizeof(*pBeacon));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pBeacon\n"));)
+ ibss_coalesce_free(pMac);
+ return;
+ }
+
+ palCopyMemory(pMac->hHdd, pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr));
+ palCopyMemory(pMac->hHdd, pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon));
+}
+
+/*
+ * tries to add a new entry to dph hash node
+ * if necessary, an existing entry is eliminated
+ */
+static tSirRetStatus
+ibss_dph_entry_add(
+ tpAniSirGlobal pMac,
+ tSirMacAddr peerAddr,
+ tpDphHashNode *ppSta,
+ tpPESession psessionEntry)
+{
+ tANI_U16 aid;
+ tpDphHashNode pStaDs;
+
+ *ppSta = NULL;
+
+ pStaDs = dphLookupHashEntry(pMac, peerAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ /* Trying to add context for already existing STA in IBSS */
+ PELOGE(limLog(pMac, LOGE, FL("STA exists already "));)
+ limPrintMacAddr(pMac, peerAddr, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ /**
+ * Assign an AID, delete context existing with that
+ * AID and then add an entry to hash table maintained
+ * by DPH module.
+ */
+ aid = limAssignAID(pMac);
+
+ pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs)
+ {
+ (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry);
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid,psessionEntry);
+ }
+
+ pStaDs = dphAddHashEntry(pMac, peerAddr, aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ // Could not add hash table entry
+ PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for aid=%d MACaddr:\n"), aid);)
+ limPrintMacAddr(pMac, peerAddr, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ *ppSta = pStaDs;
+ return eSIR_SUCCESS;
+}
+
+// send a status change notification
+static void
+ibss_status_chg_notify(
+ tpAniSirGlobal pMac,
+ tSirMacAddr peerAddr,
+ tANI_U16 staIndex,
+ tANI_U8 ucastSig,
+ tANI_U8 bcastSig,
+ tANI_U16 status,
+ tANI_U8 sessionId)
+{
+
+ tLimIbssPeerNode *peerNode;
+ tANI_U8 *beacon = NULL;
+ tANI_U16 bcnLen = 0;
+
+
+ peerNode = ibss_peer_find(pMac,peerAddr);
+ if(peerNode != NULL)
+ {
+ if(peerNode->beacon == NULL) peerNode->beaconLen = 0;
+ beacon = peerNode->beacon;
+ bcnLen = peerNode->beaconLen;
+ peerNode->beacon = NULL;
+ peerNode->beaconLen = 0;
+ }
+
+ limSendSmeIBSSPeerInd(pMac,peerAddr, staIndex, ucastSig, bcastSig,
+ beacon, bcnLen, status, sessionId);
+
+ if(beacon != NULL)
+ {
+ palFreeMemory(pMac->hHdd, beacon);
+ }
+}
+
+
+static void
+ibss_bss_add(
+ tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tLimMlmStartReq mlmStartReq;
+ tANI_U32 cfg;
+ tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+ tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+ tANI_U8 numExtRates = 0;
+
+ if ((pHdr == NULL) || (pBeacon == NULL))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to add BSS (no cached BSS info)\n"));)
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, psessionEntry->bssId, pHdr->bssId,
+ sizeof(tSirMacAddr));
+
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pHdr->bssId, sizeof(tSirMacAddr))
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+ #endif //TO SUPPORT BT-AMP
+
+ sirCopyMacAddr(pHdr->bssId,psessionEntry->bssId);
+ /* We need not use global Mac address since per seesion BSSID is available */
+ //limSetBssid(pMac, pHdr->bssId);
+
+#if 0
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &cfg) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Can't read beacon interval\n"));
+#endif //TO SUPPORT BT-AMP
+ /* Copy beacon interval from sessionTable */
+ cfg = psessionEntry->beaconParams.beaconInterval;
+ if (cfg != pBeacon->beaconInterval)
+ #if 0
+ if (cfgSetInt(pMac, WNI_CFG_BEACON_INTERVAL, pBeacon->beaconInterval)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Can't update beacon interval\n"));
+ #endif//TO SUPPORT BT-AMP
+ psessionEntry->beaconParams.beaconInterval = pBeacon->beaconInterval;
+
+ /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to
+ * adapt to peer's capability with respect to short slot time. Changes have been made to limApplyConfiguration()
+ * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt
+ * to peer's short slot using code below.
+ */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, &cfg)
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_SLOT_TIME failed\n"));
+ return;
+ }
+ /* If cfg is already set to current peer's capability then no need to set it again */
+ if (cfg != pBeacon->capabilityInfo.shortSlotTime)
+ {
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, pBeacon->capabilityInfo.shortSlotTime) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not update short slot time at CFG\n"));
+ return;
+ }
+ }
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &psessionEntry->pLimStartBssReq->operationalRateSet,
+ (tANI_U8 *) &pBeacon->supportedRates,
+ pBeacon->supportedRates.numRates);
+
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate,
+ pMac->lim.gpLimStartBssReq->operationalRateSet.numRates)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update OperRateset at CFG\n"));
+ #endif //TO SUPPORT BT-AMP
+
+ /**
+ * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when
+ * there is no extended rate IE present in beacon. This is especially important when
+ * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce.
+ * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to
+ * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile.
+ * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued.
+ * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12.
+ */
+
+ if(pBeacon->extendedRatesPresent)
+ numExtRates = pBeacon->extendedRates.numRates;
+ if (cfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pBeacon->extendedRates.rate, numExtRates) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not update ExtendedOperRateset at CFG\n"));
+ return;
+ }
+
+
+ /*
+ * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities
+ * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities
+ * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode
+ * even though all the nodes are capable of doing CB.
+ * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop.
+ */
+ palZeroMemory(pMac->hHdd, (void *) &mlmStartReq, sizeof(mlmStartReq));
+
+ palCopyMemory(pMac->hHdd, mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr));
+ mlmStartReq.rateSet.numRates = psessionEntry->pLimStartBssReq->operationalRateSet.numRates;
+ palCopyMemory(pMac->hHdd, &mlmStartReq.rateSet.rate[0],
+ &psessionEntry->pLimStartBssReq->operationalRateSet.rate[0],
+ mlmStartReq.rateSet.numRates);
+ mlmStartReq.bssType = eSIR_IBSS_MODE;
+ mlmStartReq.beaconPeriod = pBeacon->beaconInterval;
+ mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; //psessionEntry->nwType is also OK????
+ mlmStartReq.htCapable = psessionEntry->htCapabality;
+ mlmStartReq.htOperMode = pMac->lim.gHTOperMode;
+ mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection;
+ mlmStartReq.txChannelWidthSet = pMac->lim.gHTRecommendedTxWidthSet;
+
+ #if 0
+ if (wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_CHANNEL, &cfg) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("CurrentChannel CFG get fialed!\n"));
+ #endif
+
+ //mlmStartReq.channelNumber = (tSirMacChanNum) cfg;
+
+ /* reading the channel num from session Table */
+ mlmStartReq.channelNumber = psessionEntry->currentOperChannel;
+
+ mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode;
+
+ // Copy the SSID for RxP filtering based on SSID.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmStartReq.ssId,
+ (tANI_U8 *) &psessionEntry->pLimStartBssReq->ssId,
+ psessionEntry->pLimStartBssReq->ssId.length + 1);
+
+ PELOG1(limLog(pMac, LOG1, FL("invoking ADD_BSS as part of coalescing!\n"));)
+ if (limMlmAddBss(pMac, &mlmStartReq,psessionEntry) != eSIR_SME_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("AddBss failure\n"));)
+ return;
+ }
+
+ // Update fields in Beacon
+ if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("*** Unable to set fixed Beacon fields ***\n"));)
+ return;
+ }
+
+}
+
+
+
+/* delete the current BSS */
+static void
+ibss_bss_delete(
+ tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus status;
+ PELOGW(limLog(pMac, LOGW, FL("Initiating IBSS Delete BSS\n"));)
+ if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE)
+ {
+ limLog(pMac, LOGW, FL("Incorrect LIM MLM state for delBss (%d)\n"),
+ psessionEntry->limMlmState);
+ return;
+ }
+ status = limDelBss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
+ if (status != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d\n"), psessionEntry->bssIdx);)
+}
+
+/**
+ * limIbssInit
+ *
+ *FUNCTION:
+ * This function is called while starting an IBSS
+ * to initialize list used to maintain IBSS peers.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limIbssInit(
+ tpAniSirGlobal pMac)
+{
+ //pMac->lim.gLimIbssActive = 0;
+ pMac->lim.gLimIbssCoalescingHappened = 0;
+ pMac->lim.gLimIbssPeerList = NULL;
+ pMac->lim.gLimNumIbssPeers = 0;
+
+ // ibss info - params for which ibss to join while coalescing
+ palZeroMemory(pMac->hHdd, &pMac->lim.ibssInfo, sizeof(tAniSirLimIbss));
+} /*** end limIbssInit() ***/
+
+/**
+ * limIbssDeleteAllPeers
+ *
+ *FUNCTION:
+ * This function is called to delete all peers.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void limIbssDeleteAllPeers( tpAniSirGlobal pMac ,tpPESession psessionEntry)
+{
+ tLimIbssPeerNode *pCurrNode, *pTempNode;
+ tpDphHashNode pStaDs;
+ tANI_U16 aid;
+
+ pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList;
+
+ while (pCurrNode != NULL)
+ {
+ if (!pMac->lim.gLimNumIbssPeers)
+ {
+ limLog(pMac, LOGP,
+ FL("Number of peers in the list is zero and node present"));
+ return;
+ }
+ /* Delete the dph entry for the station
+ * Since it is called to remove all peers, just delete from dph,
+ * no need to do any beacon related params i.e., dont call limDeleteDphHashEntry
+ */
+ pStaDs = dphLookupHashEntry(pMac, pCurrNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if( pStaDs )
+ {
+
+ ibss_status_chg_notify( pMac, pCurrNode->peerMacAddr, pStaDs->staIndex,
+ pStaDs->ucUcastSig, pStaDs->ucBcastSig,
+ eWNI_SME_IBSS_PEER_DEPARTED_IND, psessionEntry->smeSessionId );
+ dphDeleteHashEntry(pMac, pStaDs->staAddr, aid, &psessionEntry->dph.dphHashTable);
+ }
+
+ pTempNode = pCurrNode->next;
+
+ /* TODO :Sessionize this code */
+ /* Fix CR 227642: PeerList should point to the next node since the current node is being
+ * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this
+ * peer list to find the next peer. So this list needs to be updated with the no of peers left
+ * after each iteration in this while loop since one by one peers are deleted (freed) in this
+ * loop causing the lim.gLimIbssPeerList to point to some freed memory.
+ */
+ pMac->lim.gLimIbssPeerList = pTempNode;
+
+ if(pCurrNode->beacon)
+ {
+ palFreeMemory(pMac->hHdd, pCurrNode->beacon);
+ }
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pCurrNode);
+ if (pMac->lim.gLimNumIbssPeers > 0) // be paranoid
+ pMac->lim.gLimNumIbssPeers--;
+ pCurrNode = pTempNode;
+ }
+
+ if (pMac->lim.gLimNumIbssPeers)
+ limLog(pMac, LOGP, FL("Number of peers[%d] in the list is non-zero"),
+ pMac->lim.gLimNumIbssPeers);
+
+ pMac->lim.gLimNumIbssPeers = 0;
+ pMac->lim.gLimIbssPeerList = NULL;
+
+}
+/**
+ * limIbssDelete
+ *
+ *FUNCTION:
+ * This function is called while tearing down an IBSS.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limIbssDelete(
+ tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ limIbssDeleteAllPeers(pMac,psessionEntry);
+
+ ibss_coalesce_free(pMac);
+} /*** end limIbssDelete() ***/
+
+/** Commenting this Code as from no where it is being invoked */
+#if 0
+/**
+ * limIbssPeerDelete
+ *
+ *FUNCTION:
+ * This may be called on a STA in IBSS to delete a peer
+ * from the list.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param peerMacAddr - MAC address of the peer STA that
+ * need to be deleted from peer list.
+ *
+ * @return None
+ */
+
+void
+limIbssPeerDelete(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+ tLimIbssPeerNode *pPrevNode, *pTempNode;
+
+ pTempNode = pPrevNode = pMac->lim.gLimIbssPeerList;
+
+ if (pTempNode == NULL)
+ return;
+
+ while (pTempNode != NULL)
+ {
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
+ (tANI_U8 *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ {
+ // Found node to be deleted
+ if (pMac->lim.gLimIbssPeerList == pTempNode) /** First Node to be deleted*/
+ pMac->lim.gLimIbssPeerList = pTempNode->next;
+ else
+ pPrevNode->next = pTempNode->next;
+
+ if(pTempNode->beacon)
+ {
+ palFreeMemory(pMac->hHdd, pTempNode->beacon);
+ pTempNode->beacon = NULL;
+ }
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pTempNode);
+ pMac->lim.gLimNumIbssPeers--;
+ return;
+ }
+
+ pPrevNode = pTempNode;
+ pTempNode = pTempNode->next;
+ }
+
+ // Should not be here
+ PELOGE(limLog(pMac, LOGE, FL("peer not found in the list, addr= "));)
+ limPrintMacAddr(pMac, macAddr, LOGE);
+} /*** end limIbssPeerDelete() ***/
+
+#endif
+
+
+/** -------------------------------------------------------------
+\fn limIbssSetProtection
+\brief Decides all the protection related information.
+\
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+static void
+limIbssSetProtection(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+
+ if(!pMac->lim.cfgProtection.fromllb)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled\n"));)
+ return;
+ }
+
+ if (enable)
+ {
+ psessionEntry->gLim11bParams.protectionEnabled = true;
+ if(false == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("=> IBSS: Enable Protection \n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ else if (true == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/)
+ {
+ psessionEntry->gLim11bParams.protectionEnabled = false;
+ PELOGE(limLog(pMac, LOGE, FL("===> IBSS: Disable protection \n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ return;
+}
+
+
+/** -------------------------------------------------------------
+\fn limIbssUpdateProtectionParams
+\brief Decides all the protection related information.
+\
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+static void
+limIbssUpdateProtectionParams(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType,
+ tpPESession psessionEntry)
+{
+ tANI_U32 i;
+
+ PELOG1(limLog(pMac,LOG1, FL("A STA is associated:"));
+ limLog(pMac,LOG1, FL("Addr : "));
+ limPrintMacAddr(pMac, peerMacAddr, LOG1);)
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.protStaCache[i].active)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Addr: "));)
+ PELOG1(limPrintMacAddr(pMac, pMac->lim.protStaCache[i].addr, LOG1);)
+
+ if (palEqualMemory( pMac->hHdd,
+ pMac->lim.protStaCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active.\n"), i);)
+ return;
+ }
+ }
+ }
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (!pMac->lim.protStaCache[i].active)
+ break;
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache\n"));)
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, pMac->lim.protStaCache[i].addr,
+ peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType;
+ pMac->lim.protStaCache[i].active = true;
+ if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType)
+ {
+ psessionEntry->gLim11bParams.numSta++;
+ }
+ else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType)
+ {
+ psessionEntry->gLim11gParams.numSta++;
+ }
+}
+
+
+/** -------------------------------------------------------------
+\fn limIbssDecideProtection
+\brief Decides all the protection related information.
+\
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+static void
+limIbssDecideProtection(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 phyMode;
+ tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID;
+
+ pBeaconParams->paramChangeBitmap = 0;
+
+ if(NULL == pStaDs)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("pStaDs is NULL\n"));)
+ return;
+ }
+
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ if(SIR_BAND_2_4_GHZ== rfBand)
+ {
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ //We are 11G or 11n. Check if we need protection from 11b Stations.
+ if ((phyMode == WNI_CFG_PHY_MODE_11G) || (pMac->lim.htCapability))
+ {
+ /* As we found in the past, it is possible that a 11n STA sends
+ * Beacon with HT IE but not ERP IE. So the absense of ERP IE
+ * in the Beacon is not enough to conclude that STA is 11b.
+ */
+ if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+ (!pStaDs->mlmStaContext.htCapability))
+ {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ PELOGE(limLog(pMac, LOGE, FL("Enable protection from 11B\n"));)
+ limIbssSetProtection(pMac, true, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ limIbssUpdateProtectionParams(pMac, pStaDs->staAddr, protStaCacheType, psessionEntry);
+ return;
+}
+
+
+/**
+ * limIbssStaAdd()
+ *
+ *FUNCTION:
+ * This function is called to add an STA context in IBSS role
+ * whenever a data frame is received from/for a STA that failed
+ * hash lookup at DPH.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerAdddr MAC address of the peer being added
+ * @return retCode Indicates success or failure return code
+ * @return
+ */
+
+tSirRetStatus
+limIbssStaAdd(
+ tpAniSirGlobal pMac,
+ void *pBody,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tpDphHashNode pStaDs;
+ tLimIbssPeerNode *pPeerNode;
+ tLimMlmStates prevState;
+ tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody;
+ tUpdateBeaconParams beaconParams;
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams));
+
+ if (pBody == 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Invalid IBSS AddSta\n"));)
+ return eSIR_FAILURE;
+ }
+
+ PELOGE(limLog(pMac, LOGE, FL("Rx Add-Ibss-Sta for MAC:\n"));)
+ limPrintMacAddr(pMac, *pPeerAddr, LOGE);
+
+ pPeerNode = ibss_peer_find(pMac, *pPeerAddr);
+ if(NULL != pPeerNode)
+ {
+ retCode = ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs,psessionEntry);
+ if (eSIR_SUCCESS == retCode)
+ {
+ prevState = pStaDs->mlmStaContext.mlmState;
+ pStaDs->erpEnabled = pPeerNode->erpIePresent;
+
+ ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry);
+ PELOGW(limLog(pMac, LOGW, FL("initiating ADD STA for the IBSS peer.\n"));)
+ retCode = limAddSta(pMac, pStaDs,psessionEntry);
+ if(retCode != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("ibss-sta-add failed (reason %x)\n"), retCode);)
+ limPrintMacAddr(pMac, *pPeerAddr, LOGE);
+ if(NULL != pStaDs)
+ {
+ pStaDs->mlmStaContext.mlmState = prevState;
+ dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable);
+ }
+ }
+ else
+ {
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limIbssDecideProtection(pMac, pStaDs, &beaconParams , psessionEntry);
+
+ if(beaconParams.paramChangeBitmap)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("---> Update Beacon Params \n"));)
+ schSetFixedBeaconFields(pMac, psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry );
+ }
+ }
+ }
+ else
+ {
+ PELOGE(limLog(pMac, LOGE, FL("hashTblAdd failed (reason %x)\n"), retCode);)
+ limPrintMacAddr(pMac, *pPeerAddr, LOGE);
+ }
+ }
+ else
+ {
+ retCode = eSIR_FAILURE;
+ }
+
+ return retCode;
+}
+
+/* handle the response from HAL for an ADD STA request */
+tSirRetStatus
+limIbssAddStaRsp(
+ tpAniSirGlobal pMac,
+ void *msg,tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs;
+ tANI_U16 aid;
+ tpAddStaParams pAddStaParams = (tpAddStaParams) msg;
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (pAddStaParams == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP with no body!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP for unknown MAC addr "));)
+ limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE);
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ return eSIR_FAILURE;
+ }
+
+ if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP error (%x) "), pAddStaParams->status);)
+ limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE);
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ return eSIR_FAILURE;
+ }
+
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
+ pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
+ pStaDs->valid = 1;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+
+ PELOGW(limLog(pMac, LOGW, FL("IBSS: sending IBSS_NEW_PEER msg to SME!\n"));)
+
+ ibss_status_chg_notify(pMac, pAddStaParams->staMac, pStaDs->staIndex,
+ pStaDs->ucUcastSig, pStaDs->ucBcastSig,
+ eWNI_SME_IBSS_NEW_PEER_IND,
+ psessionEntry->smeSessionId);
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+
+ return eSIR_SUCCESS;
+}
+
+
+
+void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg,tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+
+ PELOGW(limLog(pMac, LOGW, FL("IBSS: DEL_BSS_RSP Rcvd during coalescing!\n"));)
+
+ if (pDelBss == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) with no body!\n"));)
+ goto end;
+ }
+
+ if (pDelBss->status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ goto end;
+ }
+ //Delete peer entries.
+ limIbssDeleteAllPeers(pMac,psessionEntry);
+
+ /* add the new bss */
+ ibss_bss_add(pMac,psessionEntry);
+
+ end:
+ if(pDelBss != NULL)
+ palFreeMemory( pMac->hHdd, (void *) pDelBss );
+}
+
+
+
+void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg, tpPESession pSessionEntry)
+{
+ tANI_U8 infoLen;
+ tSirSmeNewBssInfo newBssInfo;
+
+ tpAddBssParams pAddBss = (tpAddBssParams) msg;
+
+ tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+ tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+
+ if ((pHdr == NULL) || (pBeacon == NULL))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)\n"));)
+ goto end;
+ }
+
+ // Inform Host of IBSS coalescing
+ infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) +
+ sizeof(tANI_U8) + pBeacon->ssId.length + 1;
+
+ palZeroMemory(pMac->hHdd, (void *) &newBssInfo, sizeof(newBssInfo));
+ palCopyMemory( pMac->hHdd, newBssInfo.bssId, pHdr->bssId, sizeof(tSirMacAddr));
+ newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &newBssInfo.ssId,
+ (tANI_U8 *) &pBeacon->ssId, pBeacon->ssId.length + 1);
+
+ PELOGW(limLog(pMac, LOGW, FL("Sending JOINED_NEW_BSS notification to SME.\n"));)
+
+ limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_JOINED_NEW_BSS,
+ (tANI_U32 *) &newBssInfo,
+ infoLen,pSessionEntry->smeSessionId);
+#ifdef WLAN_SOFTAP_FEATURE
+ {
+ //Configure beacon and send beacons to HAL
+ limSendBeaconInd(pMac, pSessionEntry);
+ }
+#endif
+
+
+ end:
+ ibss_coalesce_free(pMac);
+}
+
+
+
+void
+limIbssDelBssRsp(
+ tpAniSirGlobal pMac,
+ void *msg,tpPESession psessionEntry)
+{
+ tSirResultCodes rc = eSIR_SME_SUCCESS;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (pDelBss == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP with no body!\n"));)
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ goto end;
+ }
+
+
+ /*
+ * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true.
+ * BSS has to be added again in this scenario, so this case needs to be handled separately.
+ * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to
+ * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME.
+ */
+ if(true == pMac->lim.gLimIbssCoalescingHappened)
+ {
+
+ limIbssDelBssRspWhenCoalescing(pMac,msg,psessionEntry);
+ return;
+ }
+
+
+
+ if (pDelBss->status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);)
+ rc = eSIR_SME_STOP_BSS_FAILURE;
+ goto end;
+ }
+
+
+
+ if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP setLinkState failed\n"));)
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);
+ limDeletePreAuthList(pMac);
+
+ limIbssDelete(pMac,psessionEntry);
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ psessionEntry->limSystemRole = eLIM_STA_ROLE;
+
+ /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra
+ * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from limApplyConfiguration
+ */
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, WNI_CFG_SHORT_SLOT_TIME_STADEF) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not update short slot time at CFG\n"));
+ return;
+ }
+
+ end:
+ if(pDelBss != NULL)
+ palFreeMemory( pMac->hHdd, (void *) pDelBss );
+ /* Delete PE session once BSS is deleted */
+ if (NULL != psessionEntry) {
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,psessionEntry->smeSessionId,psessionEntry->transactionId);
+ peDeleteSession(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+}
+
+/**
+ * limIbssCoalesce()
+ *
+ *FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pBD - Pointer to received BD
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+tSirRetStatus
+limIbssCoalesce(
+ tpAniSirGlobal pMac,
+ tpSirMacMgmtHdr pHdr,
+ tpSchBeaconStruct pBeacon,
+ tANI_U8 *pIEs,
+ tANI_U32 ieLen,
+ tANI_U16 fTsfLater,
+ tpPESession psessionEntry)
+{
+ tANI_U16 aid;
+ tSirMacAddr currentBssId;
+ tLimIbssPeerNode *pPeerNode;
+ tpDphHashNode pStaDs;
+ tUpdateBeaconParams beaconParams;
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams));
+
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ /* Check for IBSS Coalescing only if Beacon is from different BSS */
+ if ( !palEqualMemory( pMac->hHdd, currentBssId, pHdr->bssId, sizeof( tSirMacAddr ) ) )
+ {
+ if (! fTsfLater) // No Coalescing happened.
+ return eSIR_LIM_IGNORE_BEACON;
+ /*
+ * IBSS Coalescing happened.
+ * save the received beacon, and delete the current BSS. The rest of the
+ * processing will be done in the delBss response processing
+ */
+ pMac->lim.gLimIbssCoalescingHappened = true;
+ PELOGW(limLog(pMac, LOGW, FL("IBSS Coalescing happened\n"));)
+ ibss_coalesce_save(pMac, pHdr, pBeacon);
+ ibss_bss_delete(pMac,psessionEntry);
+ return eSIR_SUCCESS;
+ }
+
+ // STA in IBSS mode and SSID matches with ours
+ pPeerNode = ibss_peer_find(pMac, pHdr->sa);
+ if (pPeerNode == NULL)
+ {
+ /* Peer not in the list - Collect BSS description & add to the list */
+ tANI_U32 frameLen;
+ tSirRetStatus retCode;
+ PELOGW(limLog(pMac, LOGW, FL("IBSS Peer node does not exist, adding it***\n"));)
+
+#ifndef ANI_SIR_IBSS_PEER_CACHING
+ /** Limit the Max number of IBSS Peers allowed as the max number of STA's allowed
+ */
+ if (pMac->lim.gLimNumIbssPeers >= pMac->lim.maxStation)
+ return eSIR_LIM_MAX_STA_REACHED_ERROR;
+#endif
+ frameLen = sizeof(tLimIbssPeerNode) + ieLen - sizeof(tANI_U32);
+
+ if (eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd, (void **) &pPeerNode, (tANI_U16)frameLen))
+ {
+ limLog(pMac, LOGP, FL("alloc fail (%d bytes) storing IBSS peer info\n"),
+ frameLen);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pPeerNode->beacon = NULL;
+ pPeerNode->beaconLen = 0;
+
+ ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,psessionEntry);
+ if(eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd, (void**)&pPeerNode->beacon, ieLen))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));)
+ }
+ else
+ {
+ palCopyMemory(pMac->hHdd, pPeerNode->beacon, pIEs, ieLen);
+ pPeerNode->beaconLen = (tANI_U16)ieLen;
+ }
+ ibss_peer_add(pMac, pPeerNode);
+
+ pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ /// DPH node already exists for the peer
+ PELOGW(limLog(pMac, LOGW, FL("DPH Node present for just learned peer\n"));)
+ PELOG1(limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOG1);)
+ ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry);
+ }
+ retCode = limIbssStaAdd(pMac, pPeerNode->peerMacAddr,psessionEntry);
+ if (retCode != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("lim-ibss-sta-add failed (reason %x)\n"), retCode);)
+ limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOGE);
+ return retCode;
+ }
+
+ // Decide protection mode
+ pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limIbssDecideProtection(pMac, pStaDs, &beaconParams, psessionEntry);
+
+ if(beaconParams.paramChangeBitmap)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params \n"));)
+ schSetFixedBeaconFields(pMac, psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry );
+ }
+ }
+ else
+ ibss_sta_caps_update(pMac, pPeerNode,psessionEntry);
+
+ if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
+ return eSIR_SUCCESS;
+
+ // Received Beacon from same IBSS we're
+ // currently part of. Inform Roaming algorithm
+ // if not already that IBSS is active.
+ if (psessionEntry->limIbssActive == false)
+ {
+ limResetHBPktCount(psessionEntry);
+ PELOGW(limLog(pMac, LOGW, FL("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME\n"));)
+ psessionEntry->limIbssActive = true;
+ limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0, psessionEntry->smeSessionId);
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if (limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("could not activate Heartbeat timer\n"));
+ }
+
+ return eSIR_SUCCESS;
+} /*** end limHandleIBSScoalescing() ***/
+
+
+void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ tLimIbssPeerNode *pTempNode, *pPrevNode;
+ tLimIbssPeerNode *pTempNextNode = NULL;
+ tANI_U16 aid;
+ tpDphHashNode pStaDs;
+ tANI_U32 threshold;
+ tANI_U16 staIndex;
+ tANI_U8 ucUcastSig;
+ tANI_U8 ucBcastSig;
+
+ /** MLM BSS is started and if PE in scanmode then MLM state will be waiting for probe resp.
+ * If Heart beat timeout triggers during this corner case then we need to reactivate HeartBeat timer
+ */
+ if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
+ /******
+ * Note: Use this code once you have converted all
+ * limReactivateHeartBeatTimer() calls to
+ * limReactivateTimer() calls.
+ *
+ ******/
+ //limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER, psessionEntry);
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+ return;
+ }
+ /** If LinkMonitor is Disabled */
+ if(!pMac->sys.gSysEnableLinkMonitorMode)
+ return;
+
+ pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList;
+ threshold = (pMac->lim.gLimNumIbssPeers / 4 ) + 1;
+
+ /** Monitor the HeartBeat with the Individual PEERS in the IBSS */
+ while (pTempNode != NULL)
+ {
+ pTempNextNode = pTempNode->next;
+ if(pTempNode->beaconHBCount) //There was a beacon for this peer during heart beat.
+ {
+ pTempNode->beaconHBCount = 0;
+ pTempNode->heartbeatFailure = 0;
+ }
+ else //There wasnt any beacon received during heartbeat timer.
+ {
+ pTempNode->heartbeatFailure++;
+ PELOGE(limLog(pMac, LOGE, FL("Heartbeat fail = %d thres = %d"), pTempNode->heartbeatFailure, pMac->lim.gLimNumIbssPeers);)
+ if(pTempNode->heartbeatFailure >= threshold )
+ {
+ //Remove this entry from the list.
+ pStaDs = dphLookupHashEntry(pMac, pTempNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs)
+ {
+ staIndex = pStaDs->staIndex;
+ ucUcastSig = pStaDs->ucUcastSig;
+ ucBcastSig = pStaDs->ucBcastSig;
+
+ (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry);
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid,psessionEntry);
+
+ //Send indication.
+ ibss_status_chg_notify( pMac, pTempNode->peerMacAddr, staIndex,
+ ucUcastSig, ucBcastSig,
+ eWNI_SME_IBSS_PEER_DEPARTED_IND,
+ psessionEntry->smeSessionId );
+ }
+ if(pTempNode == pMac->lim.gLimIbssPeerList)
+ {
+ pMac->lim.gLimIbssPeerList = pTempNode->next;
+ pPrevNode = pMac->lim.gLimIbssPeerList;
+ }
+ else
+ pPrevNode->next = pTempNode->next;
+
+ palFreeMemory(pMac->hHdd,pTempNode);
+ pMac->lim.gLimNumIbssPeers--;
+
+ pTempNode = pTempNextNode; //Since we deleted current node, prevNode remains same.
+ continue;
+ }
+ }
+
+ pPrevNode = pTempNode;
+ pTempNode = pTempNextNode;
+ }
+
+ /** General IBSS Activity Monitor, check if in IBSS Mode we are received any Beacons */
+ if(pMac->lim.gLimNumIbssPeers)
+ {
+ if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
+ pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++;
+ else
+ pMac->lim.gLimHeartBeatBeaconStats[0]++;
+
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+
+ // Reset number of beacons received
+ limResetHBPktCount(psessionEntry);
+ return;
+ }
+ else
+ {
+
+ PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure\n"));)
+ pMac->lim.gLimHBfailureCntInLinkEstState++;
+
+ if (psessionEntry->limIbssActive == true)
+ {
+ // We don't receive Beacon frames from any
+ // other STA in IBSS. Announce IBSS inactive
+ // to Roaming algorithm
+ PELOGW(limLog(pMac, LOGW, FL("Alone in IBSS\n"));)
+ psessionEntry->limIbssActive = false;
+
+ limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_INACTIVE,
+ NULL, 0, psessionEntry->smeSessionId);
+ }
+ }
+}
+
+
+/** -------------------------------------------------------------
+\fn limIbssDecideProtectionOnDelete
+\brief Decides all the protection related information.
+\
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+void
+limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tANI_U32 phyMode;
+ tHalBitVal erpEnabled = eHAL_CLEAR;
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 i;
+
+ if(NULL == pStaDs)
+ return;
+
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ if(SIR_BAND_2_4_GHZ == rfBand)
+ {
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+ erpEnabled = pStaDs->erpEnabled;
+ //we are HT or 11G and 11B station is getting deleted.
+ if ( ((phyMode == WNI_CFG_PHY_MODE_11G) || pMac->lim.htCapability)
+ && (erpEnabled == eHAL_CLEAR))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("(%d) A legacy STA is disassociated. Addr is "),
+ psessionEntry->gLim11bParams.numSta);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOGE);)
+ if (psessionEntry->gLim11bParams.numSta > 0)
+ {
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.protStaCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,pMac->lim.protStaCache[i].addr,
+ pStaDs->staAddr, sizeof(tSirMacAddr)))
+ {
+ psessionEntry->gLim11bParams.numSta--;
+ pMac->lim.protStaCache[i].active = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (psessionEntry->gLim11bParams.numSta == 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("No more 11B STA exists. Disable protection. \n"));)
+ limIbssSetProtection(pMac, false, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+}
diff --git a/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h
new file mode 100644
index 0000000..4b3a39f
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limIbssPeerMgmt.h contains prototypes for
+ * the utility functions LIM uses to maintain peers in IBSS.
+ * Author: Chandra Modumudi
+ * Date: 03/12/04
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "sirCommon.h"
+#include "limUtils.h"
+
+void limIbssInit(tpAniSirGlobal);
+void limIbssDelete(tpAniSirGlobal,tpPESession psessionEntry);
+tSirRetStatus limIbssCoalesce(tpAniSirGlobal, tpSirMacMgmtHdr, tpSchBeaconStruct, tANI_U8*,tANI_U32, tANI_U16,tpPESession);
+tSirRetStatus limIbssStaAdd(tpAniSirGlobal, void *,tpPESession);
+tSirRetStatus limIbssAddStaRsp( tpAniSirGlobal, void *,tpPESession);
+void limIbssDelBssRsp( tpAniSirGlobal, void *,tpPESession);
+void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal, void *,tpPESession);
+void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void * msg, tpPESession pSessionEntry);
+void limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession pSessionEntry);
+void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry);
+
diff --git a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
new file mode 100644
index 0000000..f9c103b
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limLinkMonitoringAlgo.cc contains the code for
+ * Link monitoring algorithm on AP and heart beat failure
+ * handling on STA.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "aniGlobal.h"
+#include "wniCfgAp.h"
+#include "cfgApi.h"
+
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#include "halCommonApi.h"
+#endif
+
+#include "schApi.h"
+#include "pmmApi.h"
+#include "utilsApi.h"
+#include "limAssocUtils.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limPropExtsUtils.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+#include "vos_diag_core_log.h"
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+#include "limSession.h"
+#include "limSerDesUtils.h"
+
+
+/**
+ * limSendKeepAliveToPeer()
+ *
+ *FUNCTION:
+ * This function is called to send Keep alive message to peer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limSendKeepAliveToPeer(tpAniSirGlobal pMac)
+{
+
+#ifdef ANI_PRODUCT_TYPE_AP //oct 3rd review
+
+ tpDphHashNode pStaDs;
+ //fetch the sessionEntry based on the sessionId
+ tpPESession psessionEntry;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimKeepaliveTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ // If keep live has been disabled, exit
+ if (pMac->sch.keepAlive == 0)
+ return;
+
+ if ( (limIsSystemInScanState(pMac) == false) &&
+ (psessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+ tANI_U16 i;
+ tANI_U32 len = SIR_MAC_MAX_SSID_LENGTH;
+ tAniSSID ssId;
+
+ /*
+ ** send keepalive NULL data frame for each
+ ** associated STA;
+ */
+
+ for (i=2; i<pMac->lim.maxStation; i++)
+ {
+ pStaDs = dphGetHashEntry(pMac, i, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs && pStaDs->added &&
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))
+ {
+ // SP-Tx hangs at times when a zero-lenght packet is transmitted
+ // To avoid any interoperability issue with third party clinet
+ // instead of sending a non-zero data-null packet, AP sends a
+ // probe response as a keep alive packet.
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SSID,
+ (tANI_U8 *) &ssId.ssId,
+ (tANI_U32 *) &len) != eSIR_SUCCESS)
+ {
+ /// Could not get SSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve SSID\n"));
+ }
+ ssId.length = (tANI_U8) len;
+
+ PELOG2(limLog(pMac, LOG2, FL("Sending keepalive Probe Rsp Msg to "));
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG2);)
+ limSendProbeRspMgmtFrame(pMac,
+ pStaDs->staAddr,
+ &ssId,
+ i,
+ DPH_KEEPALIVE_FRAME, 0);
+ }
+ }
+ }
+ #endif
+} /*** limSendKeepAliveToPeer() ***/
+
+
+/** ---------------------------------------------------------
+\fn limDeleteStaContext
+\brief This function handles the message from HAL:
+\ WDA_DELETE_STA_CONTEXT_IND. This function
+\ validates that the given station id exist, and if so,
+\ deletes the station by calling limTriggerSTAdeletion.
+\param tpAniSirGlobal pMac
+\param tpSirMsgQ limMsg
+\return none
+ -----------------------------------------------------------*/
+void
+limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpDeleteStaContext pMsg = (tpDeleteStaContext)limMsg->bodyptr;
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry ;
+ tANI_U8 sessionId;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId,&sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));)
+ palFreeMemory(pMac->hHdd, pMsg);
+ return;
+ }
+
+ if (NULL != pMsg)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ switch(pMsg->reasonCode)
+ {
+ case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
+ case HAL_DEL_STA_REASON_CODE_TIM_BASED:
+ PELOGE(limLog(pMac, LOGE, FL(" Deleting station: staId = %d, reasonCode = %d\n"), pMsg->staId, pMsg->reasonCode);)
+#endif
+ pStaDs = dphGetHashEntry(pMac, pMsg->assocId, &psessionEntry->dph.dphHashTable);
+ if (! pStaDs)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Skip STA deletion (invalid STA)\n"));)
+ palFreeMemory(pMac->hHdd, pMsg);
+ return;
+ }
+
+ /* check and see if same staId. This is to avoid the scenario
+ * where we're trying to delete a staId we just added.
+ */
+ if (pStaDs->staIndex != pMsg->staId)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("staid mismatch: %d vs %d \n"), pStaDs->staIndex, pMsg->staId);)
+ palFreeMemory(pMac->hHdd, pMsg);
+ return;
+ }
+
+ if((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) ||
+ (eLIM_AP_ROLE == psessionEntry->limSystemRole))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("SAP:lim Delete Station Context (staId: %d, assocId: %d) \n"),
+ pMsg->staId, pMsg->assocId);)
+ limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
+ }
+ else
+ {
+ //TearDownLink with AP
+ tLimMlmDeauthInd mlmDeauthInd;
+ PELOG1(limLog(pMac, LOG1, FL("lim Delete Station Context (staId: %d, assocId: %d) \n"),
+ pMsg->staId, pMsg->assocId);)
+
+ pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON;
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH;
+
+ // Issue Deauth Indication to SME.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthInd.peerMacAddr,
+ pStaDs->staAddr, sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason;
+ mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger;
+
+ limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd);
+
+ limSendSmeDeauthInd(pMac, pStaDs, psessionEntry);
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ break;
+
+ case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2:
+ PELOGE(limLog(pMac, LOGE, FL(" Deleting Unknown station \n"));)
+ limPrintMacAddr(pMac, pMsg->addr2, LOGE);
+
+ limSendDeauthMgmtFrame( pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMsg->addr2, psessionEntry);
+ break;
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL(" Unknown reason code \n"));)
+ break;
+
+ }
+#endif
+ }
+
+ palFreeMemory(pMac->hHdd, pMsg);
+ return;
+}
+
+
+/**
+ * limTriggerSTAdeletion()
+ *
+ *FUNCTION:
+ * This function is called to trigger STA context deletion
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param pStaDs - Pointer to internal STA Datastructure
+ * @return None
+ */
+void
+limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+ tSirSmeDeauthReq *pSmeDeauthReq;
+ tANI_U8 *pBuf;
+ tANI_U8 *pLen;
+ tANI_U16 msgLength = 0;
+
+ if (! pStaDs)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Skip STA deletion (invalid STA)\n"));)
+ return;
+ }
+ /**
+ * MAC based Authentication was used. Trigger
+ * Deauthentication frame to peer since it will
+ * take care of disassociation as well.
+ */
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSmeDeauthReq, sizeof(tSirSmeDeauthReq)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_DEAUTH_REQ \n"));
+ return;
+ }
+
+ pBuf = (tANI_U8 *) &pSmeDeauthReq->messageType;
+
+ //messageType
+#ifdef WLAN_SOFTAP_FEATURE
+ limCopyU16((tANI_U8*)pBuf, eWNI_SME_DISASSOC_REQ);
+#else
+ limCopyU16((tANI_U8*)pBuf, eWNI_SME_DEAUTH_REQ);
+#endif
+ pBuf += sizeof(tANI_U16);
+ msgLength += sizeof(tANI_U16);
+
+ //length
+ pLen = pBuf;
+ pBuf += sizeof(tANI_U16);
+ msgLength += sizeof(tANI_U16);
+
+ //sessionId
+ *pBuf = psessionEntry->peSessionId;
+ pBuf++;
+ msgLength++;
+
+ //transactionId
+ limCopyU16((tANI_U8*)pBuf, psessionEntry->transactionId);
+ pBuf += sizeof(tANI_U16);
+ msgLength += sizeof(tANI_U16);
+
+ //bssId
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr) );
+ pBuf += sizeof(tSirMacAddr);
+ msgLength += sizeof(tSirMacAddr);
+
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pStaDs->staAddr, sizeof(tSirMacAddr) );
+ pBuf += sizeof(tSirMacAddr);
+ msgLength += sizeof(tSirMacAddr);
+
+ //reasonCode
+#ifdef WLAN_SOFTAP_FEATURE
+ limCopyU16((tANI_U8*)pBuf, (tANI_U16)eLIM_LINK_MONITORING_DISASSOC);
+#else
+ limCopyU16((tANI_U8*)pBuf, (tANI_U16)eLIM_LINK_MONITORING_DEAUTH);
+#endif
+ pBuf += sizeof(tANI_U16);
+ msgLength += sizeof(tANI_U16);
+
+ //Do not send disassoc OTA
+ //pBuf[0] = 1 means do not send the disassoc frame over the air
+ //pBuf[0] = 0 means send the disassoc frame over the air
+ pBuf[0]= 0;
+ pBuf += sizeof(tANI_U8);
+ msgLength += sizeof(tANI_U8);
+
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ //aid
+ limCopyU16((tANI_U8*)pBuf, pStaDs->assocId);
+ pBuf += sizeof(tANI_U16);
+ msgLength += sizeof(tANI_U16);
+#endif
+
+ //Fill in length
+ limCopyU16((tANI_U8*)pLen, msgLength);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ limPostSmeMessage(pMac, eWNI_SME_DISASSOC_REQ, (tANI_U32 *) pSmeDeauthReq);
+#else
+ limPostSmeMessage(pMac, eWNI_SME_DEAUTH_REQ, (tANI_U32 *) pSmeDeauthReq);
+#endif
+ palFreeMemory( pMac->hHdd, pSmeDeauthReq );
+
+} /*** end limTriggerSTAdeletion() ***/
+
+
+
+/**
+ * limTearDownLinkWithAp()
+ *
+ *FUNCTION:
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limTearDownLinkWithAp(tpAniSirGlobal pMac, tANI_U8 sessionId, tSirMacReasonCodes reasonCode)
+{
+ tpDphHashNode pStaDs = NULL;
+
+ //tear down the following sessionEntry
+ tpPESession psessionEntry;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ /**
+ * Heart beat failed for upto threshold value
+ * and AP did not respond for Probe request.
+ * Trigger link tear down.
+ */
+
+ pMac->pmm.inMissedBeaconScenario = FALSE;
+ limLog(pMac, LOGW,
+ FL("No ProbeRsp from AP after HB failure. Tearing down link\n"));
+
+ // Deactivate heartbeat timer
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+
+ // Announce loss of link to Roaming algorithm
+ // and cleanup by sending SME_DISASSOC_REQ to SME
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+
+
+ if (pStaDs != NULL)
+ {
+ tLimMlmDeauthInd mlmDeauthInd;
+
+ pStaDs->mlmStaContext.disassocReason = reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH;
+
+ /// Issue Deauth Indication to SME.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthInd.peerMacAddr,
+ pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason;
+ mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger;
+
+ limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd);
+
+ limSendSmeDeauthInd(pMac, pStaDs, psessionEntry);
+ }
+} /*** limTearDownLinkWithAp() ***/
+
+
+
+
+/**
+ * limHandleHeartBeatFailure()
+ *
+ *FUNCTION:
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void limHandleHeartBeatFailure(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ vos_log_beacon_update_pkt_type *log_ptr = NULL;
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ /* If gLimHeartBeatTimer fires between the interval of sending WDA_ENTER_BMPS_REQUEST
+ * to the HAL and receiving WDA_ENTER_BMPS_RSP from the HAL, then LIM (PE) tries to Process the
+ * SIR_LIM_HEAR_BEAT_TIMEOUT message but The PE state is ePMM_STATE_BMPS_SLEEP so PE dont
+ * want to handle heartbeat timeout in the BMPS, because Firmware handles it in BMPS.
+ * So just return from heartbeatfailure handler
+ */
+
+ if(!limIsSystemInActiveState(pMac))
+ return;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_beacon_update_pkt_type, LOG_WLAN_BEACON_UPDATE_C);
+ if(log_ptr)
+ log_ptr->bcn_rx_cnt = psessionEntry->LimRxedBeaconCntDuringHB;
+ WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ /* Ensure HB Status for the session has been reseted */
+ psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE;
+ /** Re Activate Timer if the system is Waiting for ReAssoc Response*/
+ if(((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
+ (LIM_IS_CONNECTION_ACTIVE(psessionEntry) ||
+ (limIsReassocInProgress(pMac, psessionEntry))))
+ {
+ if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
+ pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++;
+ else
+ pMac->lim.gLimHeartBeatBeaconStats[0]++;
+
+ /******
+ * Note: Use this code once you have converted all
+ * limReactivateHeartBeatTimer() calls to
+ * limReactivateTimer() calls.
+ *
+ ******/
+ //limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER, psessionEntry);
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+
+ // Reset number of beacons received
+ limResetHBPktCount(psessionEntry);
+ return;
+ }
+ if (((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
+ (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))
+ {
+ if (!pMac->sys.gSysEnableLinkMonitorMode)
+ return;
+
+ /**
+ * Beacon frame not received within heartbeat timeout.
+ */
+ PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure\n"));)
+ pMac->lim.gLimHBfailureCntInLinkEstState++;
+
+ /**
+ * Check if connected on the DFS channel, if not connected on
+ * DFS channel then only send the probe request otherwise tear down the link
+ */
+ if(!limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel))
+ {
+ /*** Detected continuous Beacon Misses ***/
+ psessionEntry->LimHBFailureStatus= eANI_BOOLEAN_TRUE;
+ /**
+ * Send Probe Request frame to AP to see if
+ * it is still around. Wait until certain
+ * timeout for Probe Response from AP.
+ */
+ PELOGW(limLog(pMac, LOGW, FL("Heart Beat missed from AP. Sending Probe Req\n"));)
+ /* for searching AP, we don't include any additional IE */
+ limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId,
+ psessionEntry->currentOperChannel,psessionEntry->selfMacAddr,
+ psessionEntry->dot11mode, 0, NULL);
+ }
+ else
+ {
+ /* Connected on DFS channel so should not send the probe request
+ * tear down the link directly */
+ limTearDownLinkWithAp(pMac, psessionEntry->peSessionId, eSIR_MAC_UNSPEC_FAILURE_REASON);
+ }
+ }
+ else
+ {
+ /**
+ * Heartbeat timer may have timed out
+ * while we're doing background scanning/learning
+ * or in states other than link-established state.
+ * Log error.
+ */
+ PELOG1(limLog(pMac, LOG1, FL("received heartbeat timeout in state %X\n"),
+ psessionEntry->limMlmState);)
+ limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState);
+ pMac->lim.gLimHBfailureCntInOtherStates++;
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+ }
+} /*** limHandleHeartBeatFailure() ***/
diff --git a/CORE/MAC/src/pe/lim/limLogDump.c b/CORE/MAC/src/pe/lim/limLogDump.c
new file mode 100644
index 0000000..8271119
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limLogDump.c
@@ -0,0 +1,2386 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*============================================================================
+limLogDump.c
+
+Implements the dump commands specific to the lim module.
+
+Copyright (c) 2007 QUALCOMM Incorporated.
+All Rights Reserved.
+Qualcomm Confidential and Proprietary
+ ============================================================================*/
+
+#include "vos_types.h"
+#include "limApi.h"
+
+#if defined(ANI_LOGDUMP)
+
+
+#include "limUtils.h"
+#include "limSecurityUtils.h"
+#include "schApi.h"
+#include "limSerDesUtils.h"
+#include "limAssocUtils.h"
+#include "limSendMessages.h"
+#include "logDump.h"
+#include "limTrace.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include <limFT.h>
+#endif
+#include "smeInside.h"
+
+static char *getRole( tLimSystemRole role )
+{
+ switch (role)
+ {
+ case eLIM_UNKNOWN_ROLE:
+ return "eLIM_UNKNOWN_ROLE";
+ case eLIM_AP_ROLE:
+ return "eLIM_AP_ROLE";
+ case eLIM_STA_IN_IBSS_ROLE:
+ return "eLIM_STA_IN_IBSS_ROLE";
+ case eLIM_STA_ROLE:
+ return "eLIM_STA_ROLE";
+ case eLIM_BT_AMP_STA_ROLE:
+ return "eLIM_BT_AMP_STA_ROLE";
+ case eLIM_BT_AMP_AP_ROLE:
+ return "eLIM_BT_AMP_AP_ROLE";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+static char *
+dumpMacAddr(tpAniSirGlobal pMac, char *p, tANI_U8 *addr)
+{
+ p += log_sprintf( pMac,p, "%2x:%2x:%2x:%2x:%2x:%2x",
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+ return p;
+}
+#endif
+
+
+char *dumpLim( tpAniSirGlobal pMac, char *p )
+{
+ #ifdef FIXME_GEN6
+ //iterate through the sessionTable and dump sta entries for each session.
+ //Keep this code under 'WLAN_DEBUG' compile flag.
+
+ tANI_U16 i, j;
+
+
+ p += log_sprintf( pMac,p, "\n ----- LIM Debug Information ----- \n");
+ p += log_sprintf( pMac,p, "LIM Role = (%d) %s\n",
+ pMac->lim.gLimSystemRole, getRole(pMac->lim.gLimSystemRole));
+ p += log_sprintf( pMac,p, "SME State = (%d) %s",
+ pMac->lim.gLimSmeState, limSmeStateStr(pMac->lim.gLimSmeState));
+ p += log_sprintf( pMac,p, "MLM State = (%d) %s",
+ pMac->lim.gLimMlmState, limMlmStateStr(pMac->lim.gLimMlmState));
+
+ p += log_sprintf( pMac,p, "CHANNEL BONDING Mode (%1d) and State (X|X|X|AU|CS|U/D|O|A) (0x%1x)\n",
+ pMac->lim.gCbMode, pMac->lim.gCbState);
+ p += log_sprintf( pMac,p, "802.11n HT Capability: %s\n",
+ (pMac->lim.htCapability == 1) ? "Enabled" : "Disabled");
+ p += log_sprintf( pMac,p, "gLimProcessDefdMsgs: %s\n",
+ (pMac->lim.gLimProcessDefdMsgs == 1) ? "Enabled" : "Disabled");
+
+ if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ {
+ p += log_sprintf( pMac,p, "AID = %X\t\t\n", pMac->lim.gLimAID);
+ p += log_sprintf( pMac,p, "SSID mismatch in Beacon Count = %d\n",
+ pMac->lim.gLimBcnSSIDMismatchCnt);
+ p += log_sprintf( pMac,p, "Number of link establishments = %d\n",
+ pMac->lim.gLimNumLinkEsts);
+ }
+ else if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ p += log_sprintf( pMac,p, "Num of STAs associated = %d\n",
+ pMac->lim.gLimNumOfCurrentSTAs);
+
+ p += log_sprintf( pMac,p, "Num of Pre-auth contexts = %d\n",
+ pMac->lim.gLimNumPreAuthContexts);
+
+ p += log_sprintf( pMac,p, "Num of AssocReq dropped in invalid State = %d\n",
+ pMac->lim.gLimNumAssocReqDropInvldState);
+
+ p += log_sprintf( pMac,p, "Num of ReassocReq dropped in invalid State = %d\n",
+ pMac->lim.gLimNumReassocReqDropInvldState);
+
+ p += log_sprintf( pMac,p, "Num of Hash Miss Event ignored = %d\n",
+ pMac->lim.gLimNumHashMissIgnored);
+
+
+
+
+ }
+
+ p += log_sprintf( pMac,p, "Num of RxCleanup Count = %d\n",
+ pMac->lim.gLimNumRxCleanup);
+ p += log_sprintf( pMac,p, "Unexpected Beacon Count = %d\n",
+ pMac->lim.gLimUnexpBcnCnt);
+ p += log_sprintf( pMac,p, "Number of Re/Assoc rejects of 11b STAs = %d\n",
+ pMac->lim.gLim11bStaAssocRejectCount);
+ p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n",
+ pMac->lim.gLimHBfailureCntInLinkEstState);
+ p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n",
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt);
+ p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n",
+ pMac->lim.gLimHBfailureCntInOtherStates);
+ p += log_sprintf( pMac,p, "No. of Beacons Rxed During HB Interval = %d\n",
+ pMac->lim.gLimRxedBeaconCntDuringHB);
+ p += log_sprintf( pMac,p, "Self Operating Mode = %s\n", limDot11ModeStr(pMac, (tANI_U8)pMac->lim.gLimDot11Mode));
+
+
+
+
+
+ p += log_sprintf( pMac,p, "\n");
+
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ i = 2;
+ else
+ i = 1;
+
+
+ for (; i< pMac->lim.maxStation; i++)
+ {
+ tpDphHashNode pSta = dphGetHashEntry(pMac, (unsigned short)i);
+ if (pSta && pSta->added)
+ {
+ p += log_sprintf( pMac,p, "\nSTA AID: %d STA ID: %d Valid: %d AuthType: %d MLM State: %s",
+ i, pSta->staIndex, pSta->valid,
+ pSta->mlmStaContext.authType,
+ limMlmStateStr(pSta->mlmStaContext.mlmState));
+
+ p += log_sprintf( pMac,p, "\tAID:%-2d OpRateMode:%s ShPrmbl:%d HT:%d GF:%d TxChWidth:%d MimoPS:%d LsigProt:%d\n",
+ pSta->assocId, limStaOpRateModeStr(pSta->supportedRates.opRateMode),
+ pSta->shortPreambleEnabled, pSta->mlmStaContext.htCapability,
+ pSta->htGreenfield, pSta->htSupportedChannelWidthSet,
+ pSta->htMIMOPSState, pSta->htLsigTXOPProtection);
+
+ p += log_sprintf( pMac,p, "\tAMPDU [MaxSz(Factor):%d, Dens: %d] AMSDU-MaxLen: %d\n",
+ pSta->htMaxRxAMpduFactor, pSta->htAMpduDensity,pSta->htMaxAmsduLength);
+ p += log_sprintf( pMac,p, "\tDSSCCkMode40Mhz: %d, SGI20: %d, SGI40: %d\n",
+ pSta->htDsssCckRate40MHzSupport, pSta->htShortGI20Mhz,
+ pSta->htShortGI40Mhz);
+
+ p += log_sprintf( pMac,p, "\t11b Rates: ");
+ for(j=0; j<SIR_NUM_11B_RATES; j++)
+ if(pSta->supportedRates.llbRates[j] > 0)
+ p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llbRates[j]);
+
+ p += log_sprintf( pMac,p, "\n\t11a Rates: ");
+ for(j=0; j<SIR_NUM_11A_RATES; j++)
+ if(pSta->supportedRates.llaRates[j] > 0)
+ p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llaRates[j]);
+
+ p += log_sprintf( pMac,p, "\n\tPolaris Rates: ");
+ for(j=0; j<SIR_NUM_POLARIS_RATES; j++)
+ if(pSta->supportedRates.aniLegacyRates[j] > 0)
+ p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.aniLegacyRates[j]);
+
+ p += log_sprintf( pMac,p, "\n\tTitan and Taurus Proprietary Rate Bitmap: %08x\n",
+ pSta->supportedRates.aniEnhancedRateBitmap);
+ p += log_sprintf( pMac,p, "\tMCS Rate Set Bitmap: ");
+ for(j=0; j<SIR_MAC_MAX_SUPPORTED_MCS_SET; j++)
+ p += log_sprintf( pMac,p, "%x ", pSta->supportedRates.supportedMCSSet[j]);
+
+ }
+ }
+ p += log_sprintf( pMac,p, "\nProbe response disable = %d\n",
+ pMac->lim.gLimProbeRespDisableFlag);
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA)
+ p += log_sprintf( pMac,p, "Scan mode enable = %d\n",
+ pMac->sys.gSysEnableScanMode);
+ p += log_sprintf( pMac,p, "BackgroundScanDisable = %d\n",
+ pMac->lim.gLimBackgroundScanDisable);
+ p += log_sprintf( pMac,p, "ForceBackgroundScanDisable = %d\n",
+ pMac->lim.gLimForceBackgroundScanDisable);
+ p += log_sprintf( pMac,p, "LinkMonitor mode enable = %d\n",
+ pMac->sys.gSysEnableLinkMonitorMode);
+ p += log_sprintf( pMac,p, "Qos Capable = %d\n",
+ SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps));
+ p += log_sprintf( pMac,p, "Wme Capable = %d\n",
+ LIM_BSS_CAPS_GET(WME, pMac->lim.gLimCurrentBssQosCaps));
+ p += log_sprintf( pMac,p, "Wsm Capable = %d\n",
+ LIM_BSS_CAPS_GET(WSM, pMac->lim.gLimCurrentBssQosCaps));
+ if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ {
+ p += log_sprintf( pMac,p, "Number of peers in IBSS = %d\n",
+ pMac->lim.gLimNumIbssPeers);
+ if (pMac->lim.gLimNumIbssPeers)
+ {
+ tLimIbssPeerNode *pTemp;
+ pTemp = pMac->lim.gLimIbssPeerList;
+ p += log_sprintf( pMac,p, "MAC-Addr Ani Edca WmeInfo HT Caps #S,#E(Rates)\n");
+ while (pTemp != NULL)
+ {
+ p += log_sprintf( pMac,p, "%02X:%02X:%02X:%02X:%02X:%02X ",
+ pTemp->peerMacAddr[0],
+ pTemp->peerMacAddr[1],
+ pTemp->peerMacAddr[2],
+ pTemp->peerMacAddr[3],
+ pTemp->peerMacAddr[4],
+ pTemp->peerMacAddr[5]);
+ p += log_sprintf( pMac,p, " %d %d,%d %d %d %04X %d,%d\n",
+ pTemp->aniIndicator,
+ pTemp->edcaPresent, pTemp->wmeEdcaPresent,
+ pTemp->wmeInfoPresent,
+ pTemp->htCapable,
+ pTemp->capabilityInfo,
+ pTemp->supportedRates.numRates,
+ pTemp->extendedRates.numRates);
+ pTemp = pTemp->next;
+ }
+ }
+ }
+#else
+ p += log_sprintf( pMac,p, "Measurements enabled = %d\n",
+ pMac->sys.gSysEnableLearnMode);
+ p += log_sprintf( pMac,p, "Scan Mode for Learn Mode enable = %d\n",
+ pMac->lim.gLimUseScanModeForLearnMode);
+#endif
+ p += log_sprintf( pMac,p, "System Scan/Learn Mode bit = %d\n",
+ pMac->lim.gLimSystemInScanLearnMode);
+ p += log_sprintf( pMac,p, "Scan override = %d\n",
+ pMac->lim.gLimScanOverride);
+ p += log_sprintf( pMac,p, "CB State protection = %d\n",
+ pMac->lim.gLimCBStateProtection);
+ p += log_sprintf( pMac,p, "Count of Titan STA's = %d\n",
+ pMac->lim.gLimTitanStaCount);
+
+ //current BSS capability
+ p += log_sprintf( pMac,p, "**********Current BSS Capability********\n");
+ p += log_sprintf( pMac,p, "Ess = %d, ", SIR_MAC_GET_ESS(pMac->lim.gLimCurrentBssCaps));
+ p += log_sprintf( pMac,p, "Privacy = %d, ", SIR_MAC_GET_PRIVACY(pMac->lim.gLimCurrentBssCaps));
+ p += log_sprintf( pMac,p, "Short Preamble = %d, ", SIR_MAC_GET_SHORT_PREAMBLE(pMac->lim.gLimCurrentBssCaps));
+ p += log_sprintf( pMac,p, "Short Slot = %d, ", SIR_MAC_GET_SHORT_SLOT_TIME(pMac->lim.gLimCurrentBssCaps));
+ p += log_sprintf( pMac,p, "Qos = %d\n", SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps));
+
+ //Protection related information
+ p += log_sprintf( pMac,p, "*****Protection related information******\n");
+ p += log_sprintf( pMac,p, "Protection %s\n", pMac->lim.gLimProtectionControl ? "Enabled" : "Disabled");
+
+ p += log_sprintf( pMac,p, "OBSS MODE = %d\n", pMac->lim.gHTObssMode);
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+
+ p += log_sprintf( pMac,p, "\nNumber of active OLBC detected = %d\n",
+ pMac->lim.gLimOlbcParams.numSta);
+ if (pMac->lim.gLimOlbcParams.protectionEnabled)
+ p += log_sprintf( pMac,p, "Protection due to OLBC is ON\n");
+ else
+ p += log_sprintf( pMac,p, "Protection due to OLBC is OFF\n");
+
+ p += log_sprintf( pMac,p, "Content of OLBC cache: \n");
+ for (i=0; i<LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.protStaOverlapCache[i].active)
+ {
+ p = dumpMacAddr(pMac, p, pMac->lim.protStaOverlapCache[i].addr);
+ p += log_sprintf( pMac,p, "\n");
+ }
+ }
+
+ p += log_sprintf( pMac,p, "Content of Protection cache: \n");
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.protStaCache[i].active)
+ {
+ p = dumpMacAddr(pMac, p, pMac->lim.protStaCache[i].addr);
+ if(pMac->lim.protStaCache[i].protStaCacheType == eLIM_PROT_STA_CACHE_TYPE_HT20)
+ p += log_sprintf( pMac,p, " Type: HT20\n");
+ else if(pMac->lim.protStaCache[i].protStaCacheType == eLIM_PROT_STA_CACHE_TYPE_llB)
+ p += log_sprintf( pMac,p, " Type: 11B\n");
+ else if(pMac->lim.protStaCache[i].protStaCacheType == eLIM_PROT_STA_CACHE_TYPE_llG)
+ p += log_sprintf( pMac,p, " Type: 11G\n");
+
+ p += log_sprintf( pMac,p, "\n");
+ }
+ }
+ p += log_sprintf( pMac,p, "Count of different type sta associated\n");
+ p += log_sprintf( pMac,p, "11B = %d, Protection: %d\n", pMac->lim.gLim11bParams.numSta, pMac->lim.gLim11bParams.protectionEnabled);
+ p += log_sprintf( pMac,p, "11G = %d, Protection: %d\n", pMac->lim.gLim11gParams.numSta, pMac->lim.gLim11gParams.protectionEnabled);
+ p += log_sprintf( pMac,p, "nonGF = %d, Protection: %d\n", pMac->lim.gLimNonGfParams.numSta, pMac->lim.gLimNonGfParams.protectionEnabled);
+ p += log_sprintf( pMac,p, "!LsigTxop = %d, Protection: %d\n", pMac->lim.gLimLsigTxopParams.numSta, pMac->lim.gLimLsigTxopParams.protectionEnabled);
+ p += log_sprintf( pMac,p, "ht20 = %d Protection: %d\n", pMac->lim.gLimHt20Params.numSta, pMac->lim.gLimHt20Params.protectionEnabled);
+
+ p += log_sprintf( pMac,p, "\nNumber of STA do not support short preamble = %d\n",
+ pMac->lim.gLimNoShortParams.numNonShortPreambleSta);
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.gLimNoShortParams.staNoShortCache[i].active)
+ {
+ p = dumpMacAddr(pMac, p, pMac->lim.gLimNoShortParams.staNoShortCache[i].addr);
+ p += log_sprintf( pMac,p, "\n");
+ }
+ }
+
+ p += log_sprintf( pMac,p, "\nNumber of STA do not support short slot time = %d\n",
+ pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta);
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ {
+ p = dumpMacAddr(pMac, p, pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr);
+ p += log_sprintf( pMac,p, "\n");
+ }
+ }
+
+
+#endif
+ p += log_sprintf( pMac, p, "HT operating Mode = %d, llbCoexist = %d, llgCoexist = %d, ht20Coexist = %d, nonGfPresent = %d, RifsMode = %d, lsigTxop = %d\n",
+ pMac->lim.gHTOperMode, pMac->lim.llbCoexist, pMac->lim.llgCoexist,
+ pMac->lim.ht20MhzCoexist, pMac->lim.gHTNonGFDevicesPresent,
+ pMac->lim.gHTRifsMode, pMac->lim.gHTLSigTXOPFullSupport);
+
+ p += log_sprintf(pMac, p, "2nd Channel offset = %d\n",
+ pMac->lim.gHTSecondaryChannelOffset);
+#endif
+ return p;
+}
+
+/*******************************************
+ * FUNCTION: triggerBeaconGen()
+ *
+ * This logdump sends SIR_SCH_BEACON_GEN_IND to SCH.
+ * SCH then proceeds to generate a beacon template
+ * and copy it to the Host/SoftMAC shared memory
+ *
+ * TODO - This routine can safely be deleted once
+ * beacon generation is working
+ ******************************************/
+char *triggerBeaconGen( tpAniSirGlobal pMac, char *p )
+{
+ tSirMsgQ mesg = { (tANI_U16) SIR_LIM_BEACON_GEN_IND, (tANI_U16) 0, (tANI_U32) 0 };
+
+ pMac->lim.gLimSmeState = eLIM_SME_NORMAL_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ pMac->lim.gLimSystemRole = eLIM_AP_ROLE;
+
+ p += log_sprintf( pMac, p,
+ "Posted SIR_LIM_BEACON_GEN_IND with result = %s\n",
+ (eSIR_SUCCESS == limPostMsgApi( pMac, &mesg ))?
+ "Success": "Failure" );
+
+ return p;
+}
+
+
+/*******************************************
+ * FUNCTION: testLimSendProbeRsp()
+ *
+ * This logdump sends SIR_MAC_MGMT_PROBE_RSP
+ *
+ * TODO - This routine can safely be deleted once
+ * the MGMT frame transmission is working
+ ******************************************/
+char *testLimSendProbeRsp( tpAniSirGlobal pMac, char *p )
+{
+ tSirMacAddr peerMacAddr = { 0, 1, 2, 3, 4, 5 };
+ tAniSSID ssId;
+ tANI_U32 len = SIR_MAC_MAX_SSID_LENGTH;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+
+
+ if( eSIR_SUCCESS != wlan_cfgGetStr( pMac,
+ WNI_CFG_SSID,
+ (tANI_U8 *) &ssId.ssId,
+ (tANI_U32 *) &len ))
+ {
+ // Could not get SSID from CFG. Log error.
+ p += log_sprintf( pMac, p, "Unable to retrieve SSID\n" );
+ return p;
+ }
+ else
+ ssId.length = (tANI_U8) len;
+
+ p += log_sprintf( pMac, p, "Calling limSendProbeRspMgmtFrame...\n" );
+ limSendProbeRspMgmtFrame( pMac, peerMacAddr, &ssId, -1, 1, psessionEntry , 0);
+
+ return p;
+}
+
+
+static char *sendSmeScanReq(tpAniSirGlobal pMac, char *p)
+{
+ tSirMsgQ msg;
+ tSirSmeScanReq scanReq, *pScanReq;
+
+ p += log_sprintf( pMac,p, "sendSmeScanReq: Preparing eWNI_SME_SCAN_REQ message\n");
+
+ pScanReq = (tSirSmeScanReq *) &scanReq;
+
+ if (palAllocateMemory(pMac->hHdd, (void **)&pScanReq, sizeof(tSirSmeScanReq)) != eHAL_STATUS_SUCCESS)
+ {
+ p += log_sprintf( pMac,p,"sendSmeScanReq: palAllocateMemory() failed \n");
+ return p;
+ }
+
+ pScanReq->messageType = eWNI_SME_SCAN_REQ;
+ pScanReq->minChannelTime = 30;
+ pScanReq->maxChannelTime = 130;
+ pScanReq->bssType = eSIR_INFRASTRUCTURE_MODE;
+ limGetMyMacAddr(pMac, pScanReq->bssId);
+ pScanReq->numSsid = 1;
+ palCopyMemory(pMac->hHdd, (void *) &pScanReq->ssId[0].ssId, (void *)"Ivan", 4);
+ pScanReq->ssId[0].length = 4;
+ pScanReq->scanType = eSIR_ACTIVE_SCAN;
+ pScanReq->returnAfterFirstMatch = 0;
+ pScanReq->returnUniqueResults = 0;
+ pScanReq->returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS;
+ pScanReq->channelList.numChannels = 1;
+ pScanReq->channelList.channelNumber[0] = 6;
+ pScanReq->uIEFieldLen = 0;
+ pScanReq->uIEFieldOffset = sizeof(tSirSmeScanReq);
+ pScanReq->sessionId = 0;
+
+ msg.type = eWNI_SME_SCAN_REQ;
+ msg.bodyptr = pScanReq;
+ msg.bodyval = 0;
+ p += log_sprintf( pMac,p, "sendSmeScanReq: limPostMsgApi(eWNI_SME_SCAN_REQ) \n");
+ limPostMsgApi(pMac, &msg);
+
+ return p;
+}
+
+static char *sendSmeDisAssocReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1 ,tANI_U32 arg2)
+{
+
+ tpDphHashNode pStaDs;
+ tSirMsgQ msg;
+ tSirSmeDisassocReq *pDisAssocReq;
+ tpPESession psessionEntry;
+
+ //arg1 - assocId
+ //arg2 - sessionId
+ if( arg1 < 1 )
+ {
+ p += log_sprintf( pMac,p,"Invalid session OR Assoc ID \n");
+ return p;
+ }
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL)
+ {
+ p += log_sprintf( pMac,p,"Session does not exist for given session Id \n");
+ return p;
+ }
+
+ pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable);
+
+ if(NULL == pStaDs)
+ {
+ p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1);
+ return p;
+ }
+
+ if (palAllocateMemory(pMac->hHdd, (void **)&pDisAssocReq, sizeof(tSirSmeDisassocReq)) != eHAL_STATUS_SUCCESS)
+ {
+ p += log_sprintf( pMac,p,"sendSmeDisAssocReq: palAllocateMemory() failed \n");
+ return p;
+ }
+
+ if( ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
+ (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) &&
+ (psessionEntry->statypeForBss == STA_ENTRY_PEER))
+ {
+ sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId);
+ sirCopyMacAddr(pDisAssocReq->peerMacAddr,psessionEntry->bssId);
+ }
+ if((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ )
+ {
+ sirCopyMacAddr(pDisAssocReq->peerMacAddr,pStaDs->staAddr);
+ sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId);
+ }
+
+ pDisAssocReq->messageType = eWNI_SME_DISASSOC_REQ;
+
+ pDisAssocReq->length = sizeof(tSirSmeDisassocReq);
+
+ pDisAssocReq->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+
+ pDisAssocReq->sessionId = 0;
+
+ pDisAssocReq->transactionId = 0;
+
+ msg.type = eWNI_SME_DISASSOC_REQ;
+ msg.bodyptr = pDisAssocReq;
+ msg.bodyval = 0;
+
+ p += log_sprintf( pMac,p, "sendSmeDisAssocReq: limPostMsgApi(eWNI_SME_DISASSOC_REQ) \n");
+ limPostMsgApi(pMac, &msg);
+
+ return p;
+}
+
+
+static char *sendSmeStartBssReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1)
+{
+ tSirMsgQ msg;
+ tSirSmeStartBssReq *pStartBssReq;
+ unsigned char *pBuf;
+ tAniCBSecondaryMode cbMode;
+ tSirNwType nwType;
+
+ p += log_sprintf( pMac,p, "sendSmeStartBssReq: Preparing eWNI_SME_START_BSS_REQ message\n");
+
+ if(arg1 > 2)
+ {
+ p += log_sprintf( pMac,p,"Invalid Argument1 \n");
+ return p;
+ }
+
+ if (palAllocateMemory(pMac->hHdd, (void **)&pStartBssReq, sizeof(tSirSmeStartBssReq)) != eHAL_STATUS_SUCCESS)
+ {
+ p += log_sprintf( pMac,p,"sendSmeStartBssReq: palAllocateMemory() failed \n");
+ return p;
+ }
+
+ pStartBssReq->messageType = eWNI_SME_START_BSS_REQ;
+ pStartBssReq->length = 29; // 0x1d
+
+ if(arg1 == 0) //BTAMP STATION
+ {
+ pStartBssReq->bssType = eSIR_BTAMP_STA_MODE;
+
+ pStartBssReq->ssId.length = 5;
+ palCopyMemory(pMac->hHdd, (void *) &pStartBssReq->ssId.ssId, (void *)"BTSTA", 5);
+ }
+ else if(arg1 == 1) //BTAMP AP
+ {
+ pStartBssReq->bssType = eSIR_BTAMP_AP_MODE;
+ pStartBssReq->ssId.length = 4;
+ palCopyMemory(pMac->hHdd, (void *) &pStartBssReq->ssId.ssId, (void *)"BTAP", 4);
+ }
+ else //IBSS
+ {
+ pStartBssReq->bssType = eSIR_IBSS_MODE;
+ pStartBssReq->ssId.length = 4;
+ palCopyMemory(pMac->hHdd, (void *) &pStartBssReq->ssId.ssId, (void *)"Ibss", 4);
+ }
+
+ // Filling in channel ID 6
+ pBuf = &(pStartBssReq->ssId.ssId[pStartBssReq->ssId.length]);
+ *pBuf = 6;
+ pBuf++;
+
+ // Filling in CB mode
+ cbMode = eANI_CB_SECONDARY_NONE;
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *)&cbMode, sizeof(tAniCBSecondaryMode) );
+ pBuf += sizeof(tAniCBSecondaryMode);
+
+ // Filling in RSN IE Length to zero
+ palZeroMemory( pMac->hHdd, pBuf, sizeof(tANI_U16) ); //tSirRSNie->length
+ pBuf += sizeof(tANI_U16);
+
+ // Filling in NW Type
+ nwType = eSIR_11G_NW_TYPE;
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *)&nwType, sizeof(tSirNwType) );
+ pBuf += sizeof(tSirNwType);
+
+ /* ---- To be filled by LIM later ----
+ pStartBssReq->operationalRateSet
+ pStartBssReq->extendedRateSet
+ pStartBssReq->dot11mode
+ pStartBssReq->bssId
+ pStartBssReq->selfMacAddr
+ pStartBssReq->beaconInterval
+ pStartBssReq->sessionId = 0;
+ pStartBssReq->transactionId = 0;
+ * ------------------------------------ */
+
+ msg.type = eWNI_SME_START_BSS_REQ;
+ msg.bodyptr = pStartBssReq;
+ msg.bodyval = 0;
+ p += log_sprintf( pMac,p, "sendSmeStartBssReq: limPostMsgApi(eWNI_SME_START_BSS_REQ) \n");
+ limPostMsgApi(pMac, &msg);
+
+ return p;
+}
+
+static char *sendSmeStopBssReq(tpAniSirGlobal pMac, char *p, tANI_U32 sessionId)
+{
+ tSirMsgQ msg;
+ tSirSmeStopBssReq stopBssReq, *pStopBssReq;
+ tANI_U16 msgLen = 0;
+ tpPESession psessionEntry;
+
+ psessionEntry = peFindSessionBySessionId(pMac, (tANI_U8)sessionId);
+ if ( psessionEntry == NULL )
+ {
+ limLog(pMac, LOGP, FL("Session entry does not exist for given sessionID \n"));
+ return p;
+ }
+
+ p += log_sprintf( pMac,p, "sendSmeStopBssReq: Preparing eWNI_SME_STOP_BSS_REQ message\n");
+ pStopBssReq = (tSirSmeStopBssReq *) &stopBssReq;
+
+ if (palAllocateMemory(pMac->hHdd, (void **)&pStopBssReq, sizeof(tSirSmeStopBssReq)) != eHAL_STATUS_SUCCESS)
+ {
+ p += log_sprintf( pMac,p,"sendSmeStopBssReq: palAllocateMemory() failed \n");
+ return p;
+ }
+
+ pStopBssReq->messageType = eWNI_SME_STOP_BSS_REQ;
+ msgLen += sizeof(tANI_U32); // msgType + length
+
+ pStopBssReq->reasonCode = eSIR_SME_SUCCESS;
+ msgLen += sizeof(tSirResultCodes);
+
+ palCopyMemory(pMac->hHdd, (void *) &pStopBssReq->bssId, (void *)psessionEntry->bssId, 6);
+ msgLen += sizeof(tSirMacAddr);
+
+ pStopBssReq->sessionId = (tANI_U8)sessionId;
+ msgLen += sizeof(tANI_U8);
+
+ pStopBssReq->transactionId = 0;
+ msgLen += sizeof(tANI_U16);
+
+ pStopBssReq->length = msgLen;
+
+ msg.type = eWNI_SME_STOP_BSS_REQ;
+ msg.bodyptr = pStopBssReq;
+ msg.bodyval = 0;
+ p += log_sprintf( pMac,p, "sendSmeStopBssReq: limPostMsgApi(eWNI_SME_STOP_BSS_REQ) \n");
+ limPostMsgApi(pMac, &msg);
+
+ return p;
+}
+
+static char *sendSmeJoinReq(tpAniSirGlobal pMac, char *p)
+{
+ tSirMsgQ msg;
+ tSirSmeJoinReq *pJoinReq;
+ unsigned char *pBuf;
+ tANI_U16 msgLen = 307;
+
+ tANI_U8 msgDump[307] = {
+ 0x06, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00,
+ 0xDE, 0xAD, 0xBA, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x21, 0x04, 0x02, 0x00, 0x00,
+ 0x00, 0x01, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x00, 0x00, 0x00, 0xA8, 0x85, 0x4F, 0x7A, 0x00, 0x06, 0x41,
+ 0x6E, 0x69, 0x4E, 0x65, 0x74, 0x01, 0x04, 0x82, 0x84, 0x8B,
+ 0x96, 0x03, 0x01, 0x06, 0x07, 0x06, 0x55, 0x53, 0x49, 0x01,
+ 0x0E, 0x1E, 0x2A, 0x01, 0x00, 0x32, 0x08, 0x0C, 0x12, 0x18,
+ 0x24, 0x30, 0x48, 0x60, 0x6C, 0x2D, 0x1A, 0xEE, 0x11, 0x03,
+ 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3D, 0x16, 0x06, 0x07, 0x11, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x18, 0x00,
+ 0x50, 0xF2, 0x02, 0x01, 0x01, 0x01, 0x00, 0x03, 0xA4, 0x00,
+ 0x00, 0x27, 0xA4, 0x00, 0x00, 0x42, 0x43, 0x5E, 0x00, 0x62,
+ 0x32, 0x2F, 0x00, 0xDD, 0x14, 0x00, 0x0A, 0xF5, 0x00, 0x03,
+ 0x01, 0x03, 0x05, 0x0A, 0x02, 0x80, 0xC0, 0x12, 0x06, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xB6, 0x0D, 0xDD, 0x6E, 0x00, 0x50, 0xF2,
+ 0x04, 0x10, 0x4A, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01,
+ 0x01, 0x10, 0x3B, 0x00, 0x01, 0x03, 0x10, 0x47, 0x00, 0x10,
+ 0xDB, 0xC6, 0x77, 0x28, 0xB9, 0xF3, 0xD8, 0x58, 0x86, 0xFF,
+ 0xFC, 0x6B, 0xB6, 0xB9, 0x27, 0x79, 0x10, 0x21, 0x00, 0x08,
+ 0x51, 0x75, 0x61, 0x6C, 0x63, 0x6F, 0x6D, 0x6D, 0x10, 0x23,
+ 0x00, 0x07, 0x57, 0x46, 0x52, 0x34, 0x30, 0x33, 0x31, 0x10,
+ 0x24, 0x00, 0x06, 0x4D, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10,
+ 0x42, 0x00, 0x06, 0x53, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10,
+ 0x54, 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xF2, 0x04, 0x00,
+ 0x01, 0x10, 0x11, 0x00, 0x06, 0x31, 0x31, 0x6E, 0x2D, 0x41,
+ 0x50, 0x10, 0x08, 0x00, 0x02, 0x01, 0x8E
+ };
+
+ if (palAllocateMemory(pMac->hHdd, (void **)&pJoinReq, msgLen) != eHAL_STATUS_SUCCESS)
+ {
+ p += log_sprintf( pMac,p,"sendSmeJoinReq: palAllocateMemory() failed \n");
+ return p;
+ }
+
+ pBuf = (unsigned char *)pJoinReq;
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *)msgDump, msgLen );
+
+ msg.type = eWNI_SME_JOIN_REQ;
+ msg.bodyptr = pJoinReq;
+ msg.bodyval = 0;
+ limPostMsgApi(pMac, &msg);
+
+ return p;
+}
+
+
+static char *printSessionInfo(tpAniSirGlobal pMac, char *p)
+{
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];
+ tANI_U8 i;
+
+ p += log_sprintf( pMac, p, "Dump PE Session \n");
+
+ for(i=0; i < pMac->lim.maxBssId; i++)
+ {
+ if( pMac->lim.gpSession[i].valid )
+ {
+ psessionEntry = &pMac->lim.gpSession[i];
+ p += log_sprintf( pMac,p, "*****************************************\n");
+ p += log_sprintf( pMac,p, " PE Session [%d] \n", i);
+ p += log_sprintf( pMac,p, "available: %d \n", psessionEntry->available);
+ p += log_sprintf( pMac,p, "peSessionId: %d, smeSessionId: %d, transactionId: %d \n",
+ psessionEntry->peSessionId, psessionEntry->smeSessionId, psessionEntry->smeSessionId);
+ p += log_sprintf( pMac,p, "bssId: %02X:%02X:%02X:%02X:%02X:%02X \n",
+ psessionEntry->bssId[0], psessionEntry->bssId[1], psessionEntry->bssId[2],
+ psessionEntry->bssId[3], psessionEntry->bssId[4], psessionEntry->bssId[5]);
+ p += log_sprintf( pMac,p, "selfMacAddr: %02X:%02X:%02X:%02X:%02X:%02X \n",
+ psessionEntry->selfMacAddr[0], psessionEntry->selfMacAddr[1], psessionEntry->selfMacAddr[2],
+ psessionEntry->selfMacAddr[3], psessionEntry->selfMacAddr[4], psessionEntry->selfMacAddr[5]);
+ p += log_sprintf( pMac,p, "bssIdx: %d \n", psessionEntry->bssIdx);
+ p += log_sprintf( pMac,p, "valid: %d \n", psessionEntry->valid);
+ p += log_sprintf( pMac,p, "limMlmState: (%d) %s ", psessionEntry->limMlmState, limMlmStateStr(psessionEntry->limMlmState) );
+ p += log_sprintf( pMac,p, "limPrevMlmState: (%d) %s ", psessionEntry->limPrevMlmState, limMlmStateStr(psessionEntry->limMlmState) );
+ p += log_sprintf( pMac,p, "limSmeState: (%d) %s ", psessionEntry->limSmeState, limSmeStateStr(psessionEntry->limSmeState) );
+ p += log_sprintf( pMac,p, "limPrevSmeState: (%d) %s ", psessionEntry->limPrevSmeState, limSmeStateStr(psessionEntry->limPrevSmeState) );
+ p += log_sprintf( pMac,p, "limSystemRole: (%d) %s \n", psessionEntry->limSystemRole, getRole(psessionEntry->limSystemRole) );
+ p += log_sprintf( pMac,p, "bssType: (%d) %s \n", psessionEntry->bssType, limBssTypeStr(psessionEntry->bssType));
+ p += log_sprintf( pMac,p, "operMode: %d \n", psessionEntry->operMode);
+ p += log_sprintf( pMac,p, "dot11mode: %d \n", psessionEntry->dot11mode);
+ p += log_sprintf( pMac,p, "htCapabality: %d \n", psessionEntry->htCapabality);
+ p += log_sprintf( pMac,p, "limRFBand: %d \n", psessionEntry->limRFBand);
+ p += log_sprintf( pMac,p, "limIbssActive: %d \n", psessionEntry->limIbssActive);
+ p += log_sprintf( pMac,p, "limCurrentAuthType: %d \n", psessionEntry->limCurrentAuthType);
+ p += log_sprintf( pMac,p, "limCurrentBssCaps: %d \n", psessionEntry->limCurrentBssCaps);
+ p += log_sprintf( pMac,p, "limCurrentBssQosCaps: %d \n", psessionEntry->limCurrentBssQosCaps);
+ p += log_sprintf( pMac,p, "limCurrentBssPropCap: %d \n", psessionEntry->limCurrentBssPropCap);
+ p += log_sprintf( pMac,p, "limSentCapsChangeNtf: %d \n", psessionEntry->limSentCapsChangeNtf);
+ p += log_sprintf( pMac,p, "LimAID: %d \n", psessionEntry->limAID);
+ p += log_sprintf( pMac,p, "ReassocbssId: %02X:%02X:%02X:%02X:%02X:%02X \n",
+ psessionEntry->limReAssocbssId[0], psessionEntry->limReAssocbssId[1], psessionEntry->limReAssocbssId[2],
+ psessionEntry->limReAssocbssId[3], psessionEntry->limReAssocbssId[4], psessionEntry->limReAssocbssId[5]);
+ p += log_sprintf( pMac,p, "limReassocChannelId: %d \n", psessionEntry->limReassocChannelId);
+ p += log_sprintf( pMac,p, "limReassocBssCaps: %d \n", psessionEntry->limReassocBssCaps);
+ p += log_sprintf( pMac,p, "limReassocBssQosCaps: %d \n", psessionEntry->limReassocBssQosCaps);
+ p += log_sprintf( pMac,p, "limReassocBssPropCap: %d \n", psessionEntry->limReassocBssPropCap);
+ p += log_sprintf( pMac,p, "limReassocTitanHtCaps: %d \n", psessionEntry->limReassocTitanHtCaps);
+ p += log_sprintf( pMac,p, "********************************************\n");
+ }
+ }
+ return p;
+}
+
+void
+limSetEdcaBcastACMFlag(tpAniSirGlobal pMac, tANI_U32 ac, tANI_U32 acmFlag)
+{
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ psessionEntry->gLimEdcaParamsBC[ac].aci.acm = (tANI_U8)acmFlag;
+ psessionEntry->gLimEdcaParamSetCount++;
+ schSetFixedBeaconFields(pMac,psessionEntry);
+}
+
+static char *
+limDumpEdcaParams(tpAniSirGlobal pMac, char *p)
+{
+ tANI_U8 i = 0;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ p += log_sprintf( pMac,p, "EDCA parameter set count = %d\n", psessionEntry->gLimEdcaParamSetCount);
+ p += log_sprintf( pMac,p, "Broadcast parameters\n");
+ p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n");
+ for(i = 0; i < MAX_NUM_AC; i++)
+ {
+ //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters.
+ p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i,
+ psessionEntry->gLimEdcaParamsBC[i].aci.aci, psessionEntry->gLimEdcaParamsBC[i].aci.acm,
+ psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, psessionEntry->gLimEdcaParamsBC[i].cw.max,
+ psessionEntry->gLimEdcaParamsBC[i].cw.min, psessionEntry->gLimEdcaParamsBC[i].txoplimit);
+ }
+
+ p += log_sprintf( pMac,p, "\nLocal parameters\n");
+ p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n");
+ for(i = 0; i < MAX_NUM_AC; i++)
+ {
+ //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters.
+ p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i,
+ psessionEntry->gLimEdcaParams[i].aci.aci, psessionEntry->gLimEdcaParams[i].aci.acm,
+ psessionEntry->gLimEdcaParams[i].aci.aifsn, psessionEntry->gLimEdcaParams[i].cw.max,
+ psessionEntry->gLimEdcaParams[i].cw.min, psessionEntry->gLimEdcaParams[i].txoplimit);
+ }
+
+ return p;
+}
+
+
+static char* limDumpTspecEntry(tpAniSirGlobal pMac, char *p, tANI_U32 tspecEntryNo)
+{
+ tpLimTspecInfo pTspecList;
+ if(tspecEntryNo >= LIM_NUM_TSPEC_MAX)
+ {
+ p += log_sprintf( pMac,p, "Tspec Entry no. %d is out of allowed range(0 .. %d)\n",
+ tspecEntryNo, (LIM_NUM_TSPEC_MAX - 1));
+ return p;
+ }
+ pTspecList = &pMac->lim.tspecInfo[tspecEntryNo];
+ if (pTspecList->inuse)
+ p += log_sprintf( pMac,p, "Entry %d is VALID\n", tspecEntryNo);
+ else
+ {
+ p += log_sprintf( pMac,p, "Entry %d is UNUSED\n", tspecEntryNo);
+ return p;
+ }
+ p += log_sprintf( pMac,p, "\tSta %0x:%0x:%0x:%0x:%0x:%0x, AID %d, Index %d\n",
+ pTspecList->staAddr[0], pTspecList->staAddr[1],
+ pTspecList->staAddr[2], pTspecList->staAddr[3],
+ pTspecList->staAddr[4], pTspecList->staAddr[5],
+ pTspecList->assocId, pTspecList->idx);
+ p += log_sprintf( pMac,p, "\tType %d, Length %d, ackPolicy %d, userPrio %d, accessPolicy = %d, Dir %d, tsid %d\n",
+ pTspecList->tspec.type, pTspecList->tspec.length,
+ pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio,
+ pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction,
+ pTspecList->tspec.tsinfo.traffic.tsid);
+ p += log_sprintf( pMac,p, "\tPsb %d, Agg %d, TrafficType %d, schedule %d; msduSz: nom %d, max %d\n",
+ pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation,
+ pTspecList->tspec.tsinfo.traffic.trafficType, pTspecList->tspec.tsinfo.schedule.schedule,
+ pTspecList->tspec.nomMsduSz, pTspecList->tspec.maxMsduSz);
+ p += log_sprintf( pMac,p, "\tSvcInt: Min %d, Max %d; dataRate: Min %d, mean %d, peak %d\n",
+ pTspecList->tspec.minSvcInterval, pTspecList->tspec.maxSvcInterval,
+ pTspecList->tspec.minDataRate, pTspecList->tspec.meanDataRate,
+ pTspecList->tspec.peakDataRate);
+ p += log_sprintf( pMac,p, "\tmaxBurstSz %d, delayBound %d, minPhyRate %d, surplusBw %d, mediumTime %d\n",
+ pTspecList->tspec.maxBurstSz, pTspecList->tspec.delayBound,
+ pTspecList->tspec.minPhyRate, pTspecList->tspec.surplusBw,
+ pTspecList->tspec.mediumTime);
+
+ return p;
+}
+
+static char* dumpTspecTableSummary(tpAniSirGlobal pMac, tpLimTspecInfo pTspecList, char *p, int ctspec)
+{
+ p += log_sprintf( pMac, p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+ ctspec, pTspecList->idx, pTspecList->assocId,
+ pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio,
+ pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation,
+ pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction,
+ pTspecList->tspec.tsinfo.traffic.tsid, pTspecList->tspec.tsinfo.traffic.trafficType);
+
+ return p;
+}
+
+
+static char* limDumpDphTableSummary(tpAniSirGlobal pMac,char *p)
+{
+ tANI_U8 i, j;
+ p += log_sprintf( pMac,p, "DPH Table dump\n");
+
+ for(j=0; j < pMac->lim.maxBssId; j++)
+ {
+ /* Find first free room in session table */
+ if(pMac->lim.gpSession[j].valid)
+ {
+ p += log_sprintf( pMac,p, "aid staId bssid encPol qosMode wme 11e wsm staaddr\n");
+ for(i = 0; i < pMac->lim.gpSession[j].dph.dphHashTable.size; i++)
+ {
+ if (pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].added)
+ {
+ p += log_sprintf( pMac,p, "%d %d %d %d %d %d %d %d %x:%x:%x:%x:%x:%x\n",
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].assocId,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staIndex,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].bssId,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].encPolicy,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].qosMode,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wmeEnabled,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].lleEnabled,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wsmEnabled,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAuthenticated,
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[0],
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[1],
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[2],
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[3],
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[4],
+ pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[5]);
+ }
+ }
+ }
+ }
+ return p;
+}
+
+// add the specified tspec to the tspec list
+static char* limDumpTsecTable( tpAniSirGlobal pMac, char* p)
+{
+ int ctspec;
+ tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0];
+
+ p += log_sprintf( pMac,p, "=======LIM TSPEC TABLE DUMP\n");
+ p += log_sprintf( pMac,p, "Num\tIdx\tAID\tAckPol\tUP\tPSB\tAgg\tAccessPol\tDir\tTSID\ttraffic\n");
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++)
+ {
+ if (pTspecList->inuse)
+ p = dumpTspecTableSummary(pMac, pTspecList, p, ctspec);
+ }
+ return p;
+}
+
+static char *
+dump_lim_tspec_table( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = limDumpTsecTable(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_tspec_entry( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ p = limDumpTspecEntry(pMac, p, arg1);
+ return p;
+}
+
+static char *
+dump_lim_dph_table_summary( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ p = limDumpDphTableSummary(pMac, p);
+ return p;
+}
+
+
+static char *
+dump_lim_link_monitor_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tANI_U32 ind, val;
+
+ (void) arg2; (void) arg3; (void) arg4;
+ p += log_sprintf( pMac,p, "\n ----- LIM Heart Beat Stats ----- \n");
+ p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n",
+ pMac->lim.gLimHBfailureCntInLinkEstState);
+ p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n",
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt);
+ p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n",
+ pMac->lim.gLimHBfailureCntInOtherStates);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val) == eSIR_SUCCESS)
+ p += log_sprintf( pMac,p, "Cfg HeartBeat Threshold = %d\n", val);
+
+ p += log_sprintf( pMac,p, "# Beacons Rcvd in HB interval # of times\n");
+
+ for (ind = 1; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++)
+ {
+ p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d\t\t\t\t\t\t\t\t\t\t\t%8d\n", ind,
+ pMac->lim.gLimHeartBeatBeaconStats[ind]);
+ }
+ p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d>\t\t\t\t\t\t\t\t\t\t%8d\n",
+ MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL-1,
+ pMac->lim.gLimHeartBeatBeaconStats[0]);
+
+ if (arg1 != 0)
+ {
+ for (ind = 0; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++)
+ pMac->lim.gLimHeartBeatBeaconStats[ind] = 0;
+
+ pMac->lim.gLimHBfailureCntInLinkEstState = 0;
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
+ pMac->lim.gLimHBfailureCntInOtherStates = 0;
+
+ p += log_sprintf( pMac,p, "\nReset HeartBeat Statistics\n");
+ }
+ return p;
+}
+
+static char *
+dump_lim_edca_params( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = limDumpEdcaParams(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_acm_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg3; (void) arg4;
+ limSetEdcaBcastACMFlag(pMac, arg1 /*ac(0..3)*/, arg2 /*(acmFlag = 1 to set ACM*/);
+ return p;
+}
+
+static char *
+dump_lim_bgscan_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ pMac->lim.gLimForceBackgroundScanDisable = (arg1 == 0) ? 1 : 0;
+ p += log_sprintf( pMac,p, "Bgnd scan is now %s\n",
+ (pMac->lim.gLimForceBackgroundScanDisable) ? "Disabled" : "On");
+ return p;
+}
+
+static char *
+dump_lim_linkmonitor_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ pMac->sys.gSysEnableLinkMonitorMode = (arg1 == 0) ? 0 : 1;
+ p += log_sprintf( pMac,p, "LinkMonitor mode enable = %s\n",
+ (pMac->sys.gSysEnableLinkMonitorMode) ? "On" : "Off");
+ return p;
+}
+
+static char *
+dump_lim_proberesp_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ pMac->lim.gLimProbeRespDisableFlag = (arg1 == 0) ? 0 : 1;
+ p += log_sprintf( pMac,p, "ProbeResponse mode disable = %s\n",
+ (pMac->lim.gLimProbeRespDisableFlag) ? "On" : "Off");
+ return p;
+}
+
+static char *
+dump_lim_add_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+#ifdef FIXME_GEN6
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ tSirMacAddr staMac = {0};
+ tANI_U16 aid;
+ if(arg2 > 5)
+ goto addStaFail;
+ aid = limAssignAID(pMac);
+ pStaDs = dphGetHashEntry(pMac, aid);
+ if(NULL == pStaDs)
+ {
+ staMac[5] = (tANI_U8) arg1;
+ pStaDs = dphAddHashEntry(pMac, staMac, aid, &psessionEntry->dph.dphHashTable);
+ if(NULL == pStaDs)
+ goto addStaFail;
+
+ pStaDs->staType = STA_ENTRY_PEER;
+ switch(arg2)
+ {
+ //11b station
+ case 0:
+ {
+ pStaDs->mlmStaContext.htCapability = 0;
+ pStaDs->erpEnabled = 0;
+ p += log_sprintf( pMac,p, "11b");
+ }
+ break;
+ //11g station
+ case 1:
+ {
+ pStaDs->mlmStaContext.htCapability = 0;
+ pStaDs->erpEnabled = 1;
+ p += log_sprintf( pMac,p, "11g");
+ }
+ break;
+ //ht20 station non-GF
+ case 2:
+ {
+ pStaDs->mlmStaContext.htCapability = 1;
+ pStaDs->erpEnabled = 1;
+ pStaDs->htSupportedChannelWidthSet = 0;
+ pStaDs->htGreenfield = 0;
+ p += log_sprintf( pMac,p, "HT20 non-GF");
+ }
+ break;
+ //ht20 station GF
+ case 3:
+ {
+ pStaDs->mlmStaContext.htCapability = 1;
+ pStaDs->erpEnabled = 1;
+ pStaDs->htSupportedChannelWidthSet = 0;
+ pStaDs->htGreenfield = 1;
+ p += log_sprintf( pMac,p, "HT20 GF");
+ }
+ break;
+ //ht40 station non-GF
+ case 4:
+ {
+ pStaDs->mlmStaContext.htCapability = 1;
+ pStaDs->erpEnabled = 1;
+ pStaDs->htSupportedChannelWidthSet = 1;
+ pStaDs->htGreenfield = 0;
+ p += log_sprintf( pMac,p, "HT40 non-GF");
+ }
+ break;
+ //ht40 station GF
+ case 5:
+ {
+ pStaDs->mlmStaContext.htCapability = 1;
+ pStaDs->erpEnabled = 1;
+ pStaDs->htSupportedChannelWidthSet = 1;
+ pStaDs->htGreenfield = 1;
+ p += log_sprintf( pMac,p, "HT40 GF");
+ }
+ break;
+ default:
+ {
+ p += log_sprintf( pMac,p, "arg2 not in range [0..3]. Station not added.\n");
+ goto addStaFail;
+ }
+ break;
+ }
+
+ pStaDs->added = 1;
+ p += log_sprintf( pMac,p, " station with mac address 00:00:00:00:00:%x added.\n", (tANI_U8)arg1);
+ limAddSta(pMac, pStaDs,psessionEntry);
+ }
+ else
+ {
+addStaFail:
+ p += log_sprintf( pMac,p, "Could not add station\n");
+ p += log_sprintf( pMac,p, "arg1: 6th byte of the station MAC address\n");
+ p += log_sprintf( pMac,p, "arg2[0..5] : station type as described below\n");
+ p += log_sprintf( pMac,p, "\t 0: 11b, 1: 11g, 2: HT20 non-GF, 3: HT20 GF, 4: HT40 non-GF, 5: HT40 GF\n");
+ }
+#endif
+ return p;
+}
+
+static char *
+dump_lim_del_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+
+ tpDphHashNode pStaDs;
+ tLimMlmDisassocInd mlmDisassocInd;
+ tpPESession psessionEntry;
+ tANI_U8 reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL)
+ {
+ p += log_sprintf( pMac,p,"Session does not exist for given session Id \n");
+ return p;
+ }
+
+ pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable);
+
+ if(NULL == pStaDs)
+ {
+ p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1);
+ return p;
+ }
+
+ if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ p += log_sprintf( pMac,p, "received Disassoc frame from peer that is in state %X \n", pStaDs->mlmStaContext.mlmState);
+ return p;
+ }
+
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
+
+ // Issue Disassoc Indication to SME.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDisassocInd.peerMacAddr,
+ (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
+ mlmDisassocInd.reasonCode = reasonCode;
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmDisassocInd.aid = pStaDs->assocId;
+#endif
+ mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
+
+ mlmDisassocInd.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, (tANI_U32 *) &mlmDisassocInd);
+ // Receive path cleanup
+ limCleanupRxPath(pMac, pStaDs,psessionEntry);
+ return p;
+}
+
+
+
+
+static char *
+set_lim_prot_cfg( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+
+/**********************************
+* Protection Enable
+*
+*LOWER byte for associated stations
+*UPPER byte for overlapping stations.
+*11g ==> protection from 11g
+*11b ==> protection from 11b
+*each byte will have the following info
+*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+*reserved reserved RIFS Lsig n-GF ht20 11g 11b
+**********************************
+WNI_CFG_PROTECTION_ENABLED I 4 9
+V RW NP RESTART
+LIM
+0 0xff 0xff
+V RW NP RESTART
+LIM
+0 0xffff 0xffff
+
+#ENUM FROM_llB 0
+#ENUM FROM_llG 1
+#ENUM HT_20 2
+#ENUM NON_GF 3
+#ENUM LSIG_TXOP 4
+#ENUM RIFS 5
+#ENUM OLBC_FROM_llB 8
+#ENUM OLBC_FROM_llG 9
+#ENUM OLBC_HT20 10
+#ENUM OLBC_NON_GF 11
+#ENUM OLBC_LSIG_TXOP 12
+#ENUM OLBC_RIFS 13
+******************************************/
+ if(1 == arg1)
+ dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, 0xff, arg3, arg4, p);
+ else if(2 == arg1)
+ dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, arg2 & 0xff, arg3, arg4, p);
+ else
+ {
+ p += log_sprintf( pMac,p, "To set protection config:\n");
+ p += log_sprintf( pMac,p, "arg1: operation type(1 -> set to Default 0xff, 2-> set to a arg2, else print help)\n");
+ }
+ return p;
+}
+
+
+static char *
+dump_lim_set_protection_control( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ dump_cfg_set(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, arg1, arg2, arg3, p);
+#ifdef WLAN_SOFTAP_FEATURE
+ limSetCfgProtection(pMac, NULL);
+#else
+ limSetCfgProtection(pMac);
+#endif
+ return p;
+}
+
+
+static char *
+dump_lim_send_SM_Power_Mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tSirMsgQ msg;
+ tpSirMbMsg pMBMsg;
+ tSirMacHTMIMOPowerSaveState state;
+
+ p += log_sprintf( pMac,p, "%s: Verifying the Arguments\n", __FUNCTION__);
+ if ((arg1 > 3) || (arg1 == 2))
+ {
+ p += log_sprintf( pMac,p, "Invalid Argument , enter one of the valid states\n");
+ return p;
+ }
+
+ state = (tSirMacHTMIMOPowerSaveState) arg1;
+
+ palAllocateMemory(pMac->hHdd, (void **)&pMBMsg, WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState));
+ if(NULL == pMBMsg)
+ {
+ p += log_sprintf( pMac,p, "pMBMsg is NULL\n");
+ return p;
+ }
+ pMBMsg->type = eWNI_PMC_SMPS_STATE_IND;
+ pMBMsg->msgLen = (tANI_U16)(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState));
+ palCopyMemory(pMac->hHdd, pMBMsg->data, &state, sizeof(tSirMacHTMIMOPowerSaveState));
+
+ msg.type = eWNI_PMC_SMPS_STATE_IND;
+ msg.bodyptr = pMBMsg;
+ msg.bodyval = 0;
+
+ if (limPostMsgApi(pMac, &msg) != TX_SUCCESS)
+ {
+ p += log_sprintf( pMac,p, "Updating the SMPower Request has failed \n");
+ palFreeMemory(pMac->hHdd, pMBMsg);
+ }
+ else
+ {
+ p += log_sprintf( pMac,p, "Updating the SMPower Request is Done \n");
+ }
+
+ return p;
+}
+
+
+
+
+static char *
+dump_lim_addba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+tSirRetStatus status;
+tpDphHashNode pSta;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+
+
+ (void) arg4;
+
+ // Get DPH Sta entry for this ASSOC ID
+ pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable);
+ if( NULL == pSta )
+ {
+ p += log_sprintf( pMac, p,
+ "\n%s: Could not find entry in DPH table for assocId = %d\n",
+ __FUNCTION__,
+ arg1 );
+ }
+ else
+ {
+ status = limPostMlmAddBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U16) arg3,psessionEntry);
+ p += log_sprintf( pMac, p,
+ "\n%s: Attempted to send an ADDBA Req to STA Index %d, for TID %d. Send Status = %s\n",
+ __FUNCTION__,
+ pSta->staIndex,
+ arg2,
+ limResultCodeStr( status ));
+ }
+
+ return p;
+}
+
+static char *
+dump_lim_delba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+tSirRetStatus status;
+tpDphHashNode pSta;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+
+ // Get DPH Sta entry for this ASSOC ID
+ pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable );
+ if( NULL == pSta )
+ {
+ p += log_sprintf( pMac, p,
+ "\n%s: Could not find entry in DPH table for assocId = %d\n",
+ __FUNCTION__,
+ arg1 );
+ }
+ else
+ {
+ status = limPostMlmDelBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U8) arg3, (tANI_U16) arg4 ,psessionEntry);
+ p += log_sprintf( pMac, p,
+ "\n%s: Attempted to send a DELBA Ind to STA Index %d, "
+ "as the BA \"%s\" for TID %d, with Reason code %d. "
+ "Send Status = %s\n",
+ __FUNCTION__,
+ pSta->staIndex,
+ (arg2 == 1)? "Initiator": "Recipient",
+ arg3, // TID
+ arg4, // Reason Code
+ limResultCodeStr( status ));
+ }
+
+ return p;
+}
+
+static char *
+dump_lim_ba_timeout( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+
+/* FIXME: NO HAL IN UMAC for PRIMA */
+#if !defined( FEATURE_WLAN_INTEGRATED_SOC )
+ // Call HAL API to trigger deletion of BA due to timeout
+ (void)halMsg_PostBADeleteInd( pMac, (tANI_U16) arg1, (tANI_U8) arg2, (tANI_U8) arg3,
+ HAL_BA_ERR_TIMEOUT );
+#endif
+
+ p += log_sprintf( pMac, p,
+ "\n%s: Attempted to trigger a BA Timeout Ind to STA Index %d, for TID %d, Direction %d\n",
+ __FUNCTION__,
+ arg1, // STA index
+ arg2, // TID
+ arg3 ); // BA Direction
+
+ return p;
+}
+
+static char *
+dump_lim_list_active_ba( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+tANI_U32 i;
+tpDphHashNode pSta;
+
+//TBD-RAJESH HOW TO GET sessionEntry?????
+
+tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH
+
+ (void) arg2; (void) arg3; (void) arg4;
+
+ // Get DPH Sta entry for this ASSOC ID
+ pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable);
+ if( NULL == pSta )
+ {
+ p += log_sprintf( pMac, p,
+ "\n%s: Could not find entry in DPH table for assocId = %d\n",
+ __FUNCTION__,
+ arg1 );
+ }
+ else
+ {
+ p += log_sprintf( pMac, p,
+ "\nList of Active BA sessions for STA Index %d with Assoc ID %d\n",
+ pSta->staIndex,
+ arg1 );
+
+ p += log_sprintf( pMac, p, "TID\tRxBA\tTxBA\tRxBufferSize\tTxBufferSize\tRxBATimeout\tTxBATimeout\n");
+ for( i = 0; i < STACFG_MAX_TC; i ++ )
+ p += log_sprintf( pMac, p,
+ "%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+ i, // TID
+ pSta->tcCfg[i].fUseBARx,
+ pSta->tcCfg[i].fUseBATx,
+ pSta->tcCfg[i].rxBufSize,
+ pSta->tcCfg[i].txBufSize,
+ pSta->tcCfg[i].tuRxBAWaitTimeout,
+ pSta->tcCfg[i].tuTxBAWaitTimeout );
+ }
+
+ return p;
+}
+
+
+static char *
+dump_lim_AddBA_DeclineStat( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+
+ int Tid, Enable=(arg1 & 0x1);
+ tANI_U8 val;
+
+ if (arg1 > 1) {
+ log_sprintf( pMac,p, "%s:Invalid Value is entered for Enable/Disable \n", __FUNCTION__ );
+ arg1 &= 1;
+ }
+
+ val = pMac->lim.gAddBA_Declined;
+
+ if (arg2 > 7) {
+ log_sprintf( pMac,p, "%s:Invalid Value is entered for Tid \n", __FUNCTION__ );
+ Tid = arg2 & 0x7;
+ } else
+ Tid = arg2;
+
+
+ if ( Enable)
+ val |= Enable << Tid;
+ else
+ val &= ~(0x1 << Tid);
+
+ if (cfgSetInt(pMac, (tANI_U16)WNI_CFG_ADDBA_REQ_DECLINE, (tANI_U32) val) != eSIR_SUCCESS)
+ log_sprintf( pMac,p, "%s:Config Set for ADDBA REQ Decline has failed \n", __FUNCTION__ );
+
+ log_sprintf( pMac,p, "%s:Decline value %d is being set for TID %d ,\n \tAddBA_Decline Cfg value is %d \n", __FUNCTION__ , arg1, Tid, (int) val);
+
+ return p;
+}
+static char *
+dump_lim_set_dot11_mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+
+ tpPESession psessionEntry =&pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ dump_cfg_set(pMac, WNI_CFG_DOT11_MODE, arg1, arg2, arg3, p);
+ if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||
+ (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE))
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ p += log_sprintf( pMac,p, "The Dot11 Mode is set to %s", limDot11ModeStr(pMac, (tANI_U8)psessionEntry->dot11mode));
+ return p;
+}
+
+
+static char* dump_lim_update_cb_Mode(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tANI_U32 localPwrConstraint;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+
+ if ( !pMac->lim.htCapability )
+ {
+ p += log_sprintf( pMac,p, "Error: Dot11 mode is non-HT, can not change the CB mode.\n");
+ return p;
+ }
+
+ pMac->lim.gHTSecondaryChannelOffset = arg1;
+ setupCBState(pMac, limGetAniCBState(pMac->lim.gHTSecondaryChannelOffset));
+
+ if(eSIR_SUCCESS != cfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE,
+ arg1 ? WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE))
+ p += log_sprintf(pMac,p, "cfgSetInt failed for WNI_CFG_CHANNEL_BONDING_MODE\n");
+
+ wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint);
+
+ limSendSwitchChnlParams(pMac, psessionEntry->currentOperChannel, pMac->lim.gHTSecondaryChannelOffset,
+ (tPowerdBm) localPwrConstraint, psessionEntry->peSessionId);
+ if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||
+ (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE))
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ return p;
+
+}
+
+static char* dump_lim_abort_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ //csrScanAbortMacScan(pMac);
+ return p;
+
+}
+
+static char* dump_lim_start_stop_bg_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+ }
+
+ if(arg1 == 1)
+ {
+ if (tx_timer_activate(
+ &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ {
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+ }
+ else
+ {
+ pMac->lim.gLimBackgroundScanTerminate = FALSE;
+ pMac->lim.gLimBackgroundScanDisable = false;
+ pMac->lim.gLimForceBackgroundScanDisable = false;
+ }
+ }
+ else
+ {
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+ pMac->lim.gLimBackgroundScanDisable = true;
+ pMac->lim.gLimForceBackgroundScanDisable = true;
+ }
+ return p;
+
+}
+
+static char*
+dump_lim_get_pe_statistics(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniGetPEStatsReq pReq;
+ tANI_U32 statsMask;
+
+ (void) arg2; (void) arg3; (void) arg4;
+
+
+ switch(arg1)
+ {
+ case 1:
+ statsMask = PE_SUMMARY_STATS_INFO;
+ break;
+ case 2:
+ statsMask = PE_GLOBAL_CLASS_A_STATS_INFO;
+ break;
+ case 3:
+ statsMask = PE_GLOBAL_CLASS_B_STATS_INFO;
+ break;
+ case 4:
+ statsMask = PE_GLOBAL_CLASS_C_STATS_INFO;
+ break;
+ case 5:
+ statsMask = PE_PER_STA_STATS_INFO;
+ break;
+ default:
+ return p;
+ }
+
+
+ if( eHAL_STATUS_SUCCESS != (status = palAllocateMemory (pMac->hHdd, (void**) &pReq, sizeof(tAniGetPEStatsReq))))
+ {
+ p += log_sprintf( pMac,p, "Error: Unable to allocate memory.\n");
+ return p;
+ }
+
+ palZeroMemory( pMac, pReq, sizeof(*pReq));
+
+ pReq->msgType = eWNI_SME_GET_STATISTICS_REQ;
+ pReq->statsMask = statsMask;
+ pReq->staId = (tANI_U16)arg2;
+
+ pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE;
+ limPostSmeMessage(pMac, eWNI_SME_GET_STATISTICS_REQ, (tANI_U32 *) pReq);
+
+ return p;
+
+}
+
+extern char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level );
+static char *
+dump_lim_set_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ p = setLOGLevel(pMac, p, arg1, arg2);
+ return p;
+}
+
+static char *
+dump_lim_update_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ vos_trace_setLevel( arg1, arg2 );
+ return p;
+}
+
+static char *
+dump_lim_scan_req_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = sendSmeScanReq(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_send_start_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = sendSmeStartBssReq(pMac, p,arg1);
+ return p;
+}
+
+static char *
+dump_lim_send_join_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = sendSmeJoinReq(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_send_disassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+
+ p = sendSmeDisAssocReq(pMac, p, arg1 ,arg2);
+ return p;
+}
+
+static char *
+dump_lim_stop_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+ p = sendSmeStopBssReq(pMac, p, arg1);
+ return p;
+}
+
+
+static char *
+dump_lim_session_print( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = printSessionInfo(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_sme_reassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tANI_U32 sessionId = arg1;
+ tCsrRoamModifyProfileFields modifyProfileFields;
+ tANI_U32 roamId;
+
+ (void) arg2; (void) arg3; (void) arg4;
+
+ if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
+ {
+ if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme )))
+ {
+ csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields);
+ csrReassoc( pMac, sessionId, &modifyProfileFields, &roamId, 0);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+ }
+ else
+ {
+ p += log_sprintf( pMac,p, "Invalid session = %d\n", sessionId);
+ }
+
+ return p;
+}
+
+static char *
+dump_lim_dot11h_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ unsigned int i;
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+
+ p += log_sprintf(pMac, p, "11h Enabled = %s\n", pMac->lim.gLim11hEnable? "TRUE": "FALSE");
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ p += log_sprintf(pMac, p, "Measurement request issued by WSM = %s\n",
+ (pMac->lim.gpLimMeasReq != NULL)? "ISSUED": "NOT ISSUED");
+ p += log_sprintf(pMac, p, "Measurement request details...\n");
+ if (pMac->lim.gpLimMeasReq != NULL)
+ {
+ p += log_sprintf(pMac, p, "numChannels = %d, periodicMeasEnabled = %d, measIndPeriod = %d,"
+ "shortTermPeriod = %d, averagingPeriod = %d, shortChannelScanDuration = %d,"
+ "longChannelScanDuration = %d, SYS_TICK_DUR_MS = %d\n",
+ pMac->lim.gpLimMeasReq->channelList.numChannels, pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled,
+ pMac->lim.gpLimMeasReq->measIndPeriod, pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod,
+ pMac->lim.gpLimMeasReq->measDuration.averagingPeriod,
+ pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration,
+ pMac->lim.gpLimMeasReq->measDuration.longChannelScanDuration, SYS_TICK_DUR_MS );
+
+ p += log_sprintf(pMac, p, "Measurement channels...\n");
+ for (i = 0; i < pMac->lim.gpLimMeasReq->channelList.numChannels; i++)
+ {
+ p += log_sprintf(pMac, p, "%d ", pMac->lim.gpLimMeasReq->channelList.channelNumber[i]);
+ }
+ p += log_sprintf(pMac, p, "\n");
+ p += log_sprintf(pMac, p, "Total Number of BSS learned = %d\n", pMac->lim.gpLimMeasData->numBssWds);
+ p += log_sprintf(pMac, p, "Total Number of Channels learned = %d\n", pMac->lim.gpLimMeasData->numMatrixNodes);
+ p += log_sprintf(pMac, p, "Duration of learning = %d\n", pMac->lim.gpLimMeasData->duration);
+ p += log_sprintf(pMac, p, "Is measurement Indication timer active = %s\n",
+ (pMac->lim.gLimMeasParams.isMeasIndTimerActive)?"YES": "NO");
+ p += log_sprintf(pMac, p, "Next learn channel Id = %d\n", pMac->lim.gLimMeasParams.nextLearnChannelId);
+ }
+ p += log_sprintf(pMac, p, "Measurement running = %s\n",
+ pMac->sys.gSysEnableLearnMode?"TRUE": "FALSE");
+#endif
+ p += log_sprintf(pMac, p, "Is system in learn mode = %s\n",
+ pMac->lim.gLimSystemInScanLearnMode?"YES": "NO");
+
+ p += log_sprintf(pMac, p, "Quiet Enabled = %s\n", (pMac->lim.gLimSpecMgmt.fQuietEnabled)?"YES": "NO");
+ p += log_sprintf(pMac, p, "Quiet state = %d\n", pMac->lim.gLimSpecMgmt.quietState);
+ p += log_sprintf(pMac, p, "Quiet Count = %d\n", pMac->lim.gLimSpecMgmt.quietCount);
+ p += log_sprintf(pMac, p, "Quiet Duration in ticks = %d\n", pMac->lim.gLimSpecMgmt.quietDuration);
+ p += log_sprintf(pMac, p, "Quiet Duration in TU = %d\n", pMac->lim.gLimSpecMgmt.quietDuration_TU);
+
+ p += log_sprintf(pMac, p, "Channel switch state = %d\n", pMac->lim.gLimSpecMgmt.dot11hChanSwState);
+ p += log_sprintf(pMac, p, "Channel switch mode = %s\n",
+ (pMac->lim.gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT)?"SILENT": "NORMAL");
+ p += log_sprintf(pMac, p, "Channel switch primary channel = %d\n",
+ pMac->lim.gLimChannelSwitch.primaryChannel);
+ p += log_sprintf(pMac, p, "Channel switch secondary sub band = %d\n",
+ pMac->lim.gLimChannelSwitch.secondarySubBand);
+ p += log_sprintf(pMac, p, "Channel switch switch count = %d\n",
+ pMac->lim.gLimChannelSwitch.switchCount);
+ p += log_sprintf(pMac, p, "Channel switch switch timeout value = %d\n",
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue);
+
+ p += log_sprintf(pMac, p, "Radar interrupt configured = %s\n",
+ pMac->lim.gLimSpecMgmt.fRadarIntrConfigured?"YES": "NO");
+ p += log_sprintf(pMac, p, "Radar detected in current operating channel = %s\n",
+ pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan?"YES": "NO");
+ p += log_sprintf(pMac, p, "Radar detected channels...\n");
+ for (i = 0; i < pMac->sys.radarDetectCount; i++)
+ {
+ p += log_sprintf(pMac, p, "%d ", pMac->sys.detRadarChIds[i]);
+ }
+ p += log_sprintf(pMac, p, "\n");
+
+ return p;
+}
+
+static char *
+dump_lim_enable_measurement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+
+ if (arg1)
+ {
+ pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE;
+ p += log_sprintf(pMac, p, "Measurement enabled\n");
+ }
+ else
+ {
+ pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_FALSE;
+ p += log_sprintf(pMac, p, "Measurement disabled\n");
+ }
+
+ return p;
+}
+
+static char *
+dump_lim_enable_quietIE( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+
+ if (arg1)
+ {
+ pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_TRUE;
+ p += log_sprintf(pMac, p, "QuietIE enabled\n");
+ }
+ else
+ {
+ pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_FALSE;
+ p += log_sprintf(pMac, p, "QuietIE disabled\n");
+ }
+
+ return p;
+}
+
+static char *
+dump_lim_disable_enable_scan( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg2; (void) arg3; (void) arg4;
+
+ if (arg1)
+ {
+ pMac->lim.fScanDisabled = 1;
+ p += log_sprintf(pMac, p, "Scan disabled\n");
+ }
+ else
+ {
+ pMac->lim.fScanDisabled = 0;
+ p += log_sprintf(pMac, p, "scan enabled\n");
+ }
+
+ return p;
+}
+
+static char *finishScan(tpAniSirGlobal pMac, char *p)
+{
+ tSirMsgQ msg;
+
+ p += log_sprintf( pMac,p, "logDump finishScan \n");
+
+ msg.type = SIR_LIM_MIN_CHANNEL_TIMEOUT;
+ msg.bodyval = 0;
+ msg.bodyptr = NULL;
+
+ limPostMsgApi(pMac, &msg);
+ return p;
+}
+
+
+static char *
+dump_lim_info( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = dumpLim( pMac, p );
+ return p;
+}
+
+static char *
+dump_lim_finishscan_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = finishScan(pMac, p);
+ return p;
+}
+
+static char *
+dump_lim_prb_rsp_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = testLimSendProbeRsp( pMac, p );
+ return p;
+}
+
+static char *
+dump_sch_beacon_trigger( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ (void) arg1; (void) arg2; (void) arg3; (void) arg4;
+ p = triggerBeaconGen(pMac, p);
+ return p;
+}
+
+
+static char* dump_lim_trace_cfg(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ MTRACE(macTraceCfg(pMac, arg1, arg2, arg3, arg4);)
+ return p;
+}
+
+static char* dump_lim_trace_dump(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ MTRACE(macTraceDumpAll(pMac, (tANI_U8)arg1, (tANI_U8)arg2, arg3);)
+ return p;
+}
+
+static char* dump_lim_set_scan_in_powersave( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ p += log_sprintf( pMac,p, "logDump set scan in powersave to %d \n", arg1);
+ dump_cfg_set(pMac, WNI_CFG_SCAN_IN_POWERSAVE, arg1, arg2, arg3, p);
+ return p;
+}
+
+#if defined WLAN_FEATURE_VOWIFI
+static char *
+dump_lim_send_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tpPESession psessionEntry;
+ tSirMacRadioMeasureReport pRRMReport[4];
+ tANI_U8 num = (tANI_U8)(arg4 > 4 ? 4 : arg4);
+ tANI_U8 i;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL)
+ {
+ p += log_sprintf( pMac,p,"Session does not exist for given session Id \n");
+ return p;
+ }
+ switch (arg3)
+ {
+ case 0:
+ /* send two reports with incapable bit set */
+ pRRMReport[0].type = 6;
+ pRRMReport[1].type = 7;
+ limSendRadioMeasureReportActionFrame( pMac, 1, 2, &pRRMReport[0], psessionEntry->bssId, psessionEntry );
+ break;
+ case 1:
+ for ( i = 0 ; i < num ; i++ )
+ {
+ pRRMReport[i].type = 5;
+ if ( i == 3 )
+ pRRMReport[i].refused = 1;
+ else
+ pRRMReport[i].refused = 0;
+
+ pRRMReport[i].report.beaconReport.regClass = 32;
+ pRRMReport[i].report.beaconReport.channel = i;
+ pRRMReport[i].report.beaconReport.measDuration = 23;
+ pRRMReport[i].report.beaconReport.phyType = i << 4; //some value.
+ pRRMReport[i].report.beaconReport.bcnProbeRsp = 1;
+ pRRMReport[i].report.beaconReport.rsni = 10;
+ pRRMReport[i].report.beaconReport.rcpi = 40;
+
+ pRRMReport[i].report.beaconReport.bssid[0] = 0x00;
+ pRRMReport[i].report.beaconReport.bssid[1] = 0xAA;
+ pRRMReport[i].report.beaconReport.bssid[2] = 0xBB;
+ pRRMReport[i].report.beaconReport.bssid[3] = 0xCC;
+ pRRMReport[i].report.beaconReport.bssid[4] = 0x00;
+ pRRMReport[i].report.beaconReport.bssid[5] = 0x01 << i;
+
+
+ pRRMReport[i].report.beaconReport.antennaId = 10;
+ pRRMReport[i].report.beaconReport.parentTSF = 0x1234;
+
+ pRRMReport[i].report.beaconReport.numIes = i * 10;
+ {
+ tANI_U8 j;
+ for( j = 0; j < pRRMReport[i].report.beaconReport.numIes ; j++ )
+ {
+ pRRMReport[i].report.beaconReport.Ies[j] = j + i; //Junk values.
+ }
+ }
+
+ }
+ limSendRadioMeasureReportActionFrame( pMac, 1, num, &pRRMReport[0], psessionEntry->bssId, psessionEntry );
+ break;
+ case 2:
+ //send Neighbor request.
+ {
+ tSirMacNeighborReportReq neighbor;
+ neighbor.dialogToken = 2;
+ neighbor.ssid_present = (tANI_U8) arg4;
+ neighbor.ssid.length = 5;
+ palCopyMemory( pMac->hHdd, neighbor.ssid.ssId, "abcde", 5);
+
+ limSendNeighborReportRequestFrame( pMac, &neighbor, psessionEntry->bssId, psessionEntry );
+
+ }
+
+ break;
+ case 3:
+ //send Link measure report.
+ {
+ tSirMacLinkReport link;
+ link.dialogToken = 4;
+ link.txPower = 34;
+ link.rxAntenna = 2;
+ link.txAntenna = 1;
+ link.rcpi = 9;
+ link.rsni = 3;
+ limSendLinkReportActionFrame( pMac, &link, psessionEntry->bssId, psessionEntry );
+ }
+ break;
+ default:
+ break;
+ }
+ return p;
+}
+
+static char *
+dump_lim_unpack_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ tpPESession psessionEntry;
+ tANI_U32 status;
+
+ tANI_U8 size[] = {
+ 0x2C,
+ 0x2F,
+ 0x25,
+ 0x2C,
+ 0x1C,
+ 0x05
+ };
+
+ tANI_U8 pBody[][100] = {
+ {
+ /*Beacon Request 0*/
+ 0x05, 0x00, 0x01, 0x00, 0x00,
+ //Measurement request IE
+ 0x26, 0x25, 0x01, 0x00,
+ //Beacon request type
+ 0x05,
+ //Beacon request starts here
+ 0x0C, 0x01, 0x30, 0x00, 0x14, 0x00, 0x01,
+ //BSSID
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF,
+ //SSID
+ 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31,
+ //Reporting Condition
+ 0x01, 0x02, 0x00, 0x00,
+ //Reporting Detail
+ 0x02, 0x01, 0x1,
+ //Request IE
+ 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD
+ },
+ {
+ /*Beacon Request 1*/
+ 0x05, 0x00, 0x01, 0x00, 0x00,
+ //Measurement request IE
+ 0x26, 0x28, 0x01, 0x00,
+ //Beacon request type
+ 0x05,
+ //Beacon request starts here
+ 0x0C, 0xFF, 0x30, 0x00, 0x14, 0x00, 0x01,
+ //BSSID
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF,
+ //SSID
+/* 0x00, 0x08, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, */
+ //Reporting Condition
+ 0x01, 0x02, 0x00, 0x00,
+ //Reporting Detail
+ 0x02, 0x01, 0x1,
+ //Request IE
+ 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD,
+ //AP channel report
+ 0x33, 0x03, 0x0C, 0x01, 0x06,
+ 0x33, 0x03, 0x0C, 0x24, 0x30,
+ },
+ {
+ /*Beacon Request 2*/
+ 0x05, 0x00, 0x01, 0x00, 0x00,
+ //Measurement request IE
+ 0x26, 0x1E, 0x01, 0x00,
+ //Beacon request type
+ 0x05,
+ //Beacon request starts here
+ 0x0C, 0x00, 0x30, 0x00, 0x14, 0x00, 0x02,
+ //BSSID
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF,
+ //SSID
+ 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31,
+ //0x00, 0x08, 0x41, 0x53, 0x54, 0x2D, 0x57, 0x41, 0x50, 0x49,
+ //Reporting Condition
+ 0x01, 0x02, 0x00, 0x00,
+ //Reporting Detail
+ 0x02, 0x01, 0x0
+ //Request IE
+ },
+ {
+ /*Beacon Request 3*/
+ 0x05, 0x00, 0x01, 0x00, 0x00,
+ //Measurement request IE
+ 0x26, 0x25, 0x01, 0x00,
+ //Beacon request type
+ 0x05,
+ //Beacon request starts here
+ 0x0C, 0x01, 0x30, 0x00, 0x69, 0x00, 0x00,
+ //BSSID
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF,
+ //SSID
+ 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31,
+ //Reporting Condition
+ 0x01, 0x02, 0x00, 0x00,
+ //Reporting Detail
+ 0x02, 0x01, 0x1,
+ //Request IE
+ 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD
+ },
+ {
+ /*Neighbor report*/
+ 0x05, 0x05, 0x01,
+ //Measurement request IE
+ 0x34, 0x17,
+ //BSSID
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF,
+ //BSSID INFOo
+ 0xED, 0x01, 0x00, 0x00,
+ //Reg class, channel, Phy type
+ 0x20, 0x01, 0x02,
+ //TSF Info
+ 0x01, 0x04, 0x02, 0x00, 0x60, 0x00,
+ //Condensed country
+ 0x02, 0x02, 0x62, 0x63
+ },
+ {
+ /* Link measurement request */
+ 0x05, 0x02, 0x00,
+ //Txpower used
+ 0x00,
+ //Max Tx Power
+ 0x00
+ }
+ };
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL)
+ {
+ p += log_sprintf( pMac,p,"Session does not exist for given session Id \n");
+ return p;
+ }
+ switch (arg2)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ {
+ tDot11fRadioMeasurementRequest frm;
+ if( (status = dot11fUnpackRadioMeasurementRequest( pMac, &pBody[arg2][0], size[arg2], &frm )) != 0 )
+ p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status);
+ else
+ rrmProcessRadioMeasurementRequest( pMac, psessionEntry->bssId, &frm, psessionEntry );
+ }
+ break;
+ case 4:
+ {
+ tDot11fNeighborReportResponse frm;
+ pBody[arg2][2] = (tANI_U8)arg3; //Dialog Token
+ if( (status = dot11fUnpackNeighborReportResponse( pMac, &pBody[arg2][0], size[arg2], &frm )) != 0 )
+ p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status);
+ else
+ rrmProcessNeighborReportResponse( pMac, &frm, psessionEntry );
+
+ }
+ break;
+ case 5:
+ {
+// FIXME.
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+ tDot11fLinkMeasurementRequest frm;
+ tHalBufDesc Bd;
+ pBody[arg2][3] = (tANI_U8)arg3; //TxPower used
+ pBody[arg2][4] = (tANI_U8)arg4; //Max Tx power
+
+ Bd.phyStats0 = 0;
+ Bd.phyStats1 = 0;
+ if( (status = dot11fUnpackLinkMeasurementRequest( pMac, &pBody[arg2][0], size[arg2], &frm )) != 0 )
+ p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status);
+ else
+ rrmProcessLinkMeasurementRequest( pMac, (tANI_U8*)&Bd, &frm, psessionEntry );
+#endif
+ }
+ break;
+ case 6:
+ {
+ tPowerdBm localConstraint = (tPowerdBm) arg3;
+ tPowerdBm maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );
+ maxTxPower = VOS_MIN( maxTxPower, maxTxPower-localConstraint );
+ if( maxTxPower != psessionEntry->maxTxPower )
+ {
+ rrmSendSetMaxTxPowerReq( pMac, maxTxPower, psessionEntry );
+ psessionEntry->maxTxPower = maxTxPower;
+ }
+ }
+ break;
+ default:
+ p += log_sprintf( pMac, p, "Invalid option" );
+ break;
+ }
+ return p;
+}
+#endif
+
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+#ifdef RSSI_HACK
+/* This dump command is needed to set the RSSI values in TL while testing handoff. Handoff code was tested
+ * using this dump command. Whatever the value gives as the first parameter will be considered as the average
+ * RSSI by TL and invokes corresponding callback registered by the clients */
+extern int dumpCmdRSSI;
+static char *
+dump_lim_set_tl_data_pkt_rssi( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ dumpCmdRSSI = arg1;
+ limLog(pMac, LOGE, FL("Setting TL data packet RSSI to %d"), dumpCmdRSSI);
+ return p;
+}
+#endif
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+/* This command is used to trigger FT Preauthentication with the AP with BSSID below */
+static char *
+dump_lim_ft_event( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p)
+{
+ static tANI_U8 macAddr[6] = {0x00, 0xde, 0xad, 0xaf, 0xaf, 0x04};
+ tpPESession psessionEntry;
+ tSirMsgQ msg;
+ tpSirFTPreAuthReq pftPreAuthReq;
+ tANI_U16 auth_req_len = 0;
+ tCsrRoamConnectedProfile Profile;
+
+ csrRoamCopyConnectProfile(pMac, arg2, &Profile);
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL)
+ {
+ p += log_sprintf( pMac,
+ p,"Session does not exist usage: 363 <0> sessionid channel \n");
+ return p;
+ }
+
+ switch (arg1)
+ {
+ case 0:
+ // Send Pre-auth event
+ {
+ /*----------------*/
+ p += log_sprintf( pMac,p, "Preparing Pre Auth Req message\n");
+ auth_req_len = sizeof(tSirFTPreAuthReq);
+
+ pftPreAuthReq = vos_mem_malloc(auth_req_len);
+ if (pftPreAuthReq == NULL)
+ {
+ p += log_sprintf( pMac,p,"Pre auth dump: palAllocateMemory() failed \n");
+ return p;
+ }
+ pftPreAuthReq->pbssDescription = vos_mem_malloc(sizeof(Profile.pBssDesc->length)+
+ Profile.pBssDesc->length);
+
+ pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ;
+ pftPreAuthReq->length = auth_req_len + sizeof(Profile.pBssDesc->length) +
+ Profile.pBssDesc->length;
+ pftPreAuthReq->preAuthchannelNum = 6;
+
+ palCopyMemory(pMac->hHdd, (void *) &pftPreAuthReq->currbssId,
+ (void *)psessionEntry->bssId, 6);
+ palCopyMemory(pMac->hHdd, (void *) &pftPreAuthReq->preAuthbssId,
+ (void *)macAddr, 6);
+ pftPreAuthReq->ft_ies_length = (tANI_U16)pMac->ft.ftSmeContext.auth_ft_ies_length;
+
+ // Also setup the mac address in sme context.
+ palCopyMemory(pMac->hHdd, pMac->ft.ftSmeContext.preAuthbssId, macAddr, 6);
+
+ vos_mem_copy(pftPreAuthReq->ft_ies, pMac->ft.ftSmeContext.auth_ft_ies,
+ pMac->ft.ftSmeContext.auth_ft_ies_length);
+
+ vos_mem_copy(Profile.pBssDesc->bssId, macAddr, 6);
+
+ p += log_sprintf( pMac,p, "\n ----- LIM Debug Information ----- \n");
+ p += log_sprintf( pMac, p, "%s: length = %d\n", __FUNCTION__,
+ (int)pMac->ft.ftSmeContext.auth_ft_ies_length);
+ p += log_sprintf( pMac, p, "%s: length = %02x\n", __FUNCTION__,
+ (int)pMac->ft.ftSmeContext.auth_ft_ies[0]);
+ p += log_sprintf( pMac, p, "%s: Auth Req %02x %02x %02x\n",
+ __FUNCTION__, pftPreAuthReq->ft_ies[0],
+ pftPreAuthReq->ft_ies[1], pftPreAuthReq->ft_ies[2]);
+
+ p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x\n", __FUNCTION__,
+ psessionEntry->bssId[0],
+ psessionEntry->bssId[1], psessionEntry->bssId[2]);
+ p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x %p\n", __FUNCTION__,
+ pftPreAuthReq->currbssId[0],
+ pftPreAuthReq->currbssId[1],
+ pftPreAuthReq->currbssId[2], pftPreAuthReq);
+
+ Profile.pBssDesc->channelId = (tANI_U8)arg3;
+ vos_mem_copy((void *)pftPreAuthReq->pbssDescription, (void *)Profile.pBssDesc,
+ Profile.pBssDesc->length);
+
+ msg.type = eWNI_SME_FT_PRE_AUTH_REQ;
+ msg.bodyptr = pftPreAuthReq;
+ msg.bodyval = 0;
+
+ p += log_sprintf( pMac, p, "limPostMsgApi(eWNI_SME_FT_PRE_AUTH_REQ) \n");
+ limPostMsgApi(pMac, &msg);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return p;
+}
+#endif
+
+static tDumpFuncEntry limMenuDumpTable[] = {
+ {0, "PE (300-499)", NULL},
+ {300, "LIM: Dump state(s)/statistics", dump_lim_info},
+ {301, "PE.LIM: dump TSPEC Table", dump_lim_tspec_table},
+ {302, "PE.LIM: dump specified TSPEC entry (id)", dump_lim_tspec_entry},
+ {303, "PE.LIM: dump EDCA params", dump_lim_edca_params},
+ {304, "PE.LIM: dump DPH table summary", dump_lim_dph_table_summary},
+ {305, "PE.LIM: dump link monitor stats", dump_lim_link_monitor_stats},
+ {306, "PE.LIM:dump Set the BAR Decline stat(arg1= 1/0 (enable/disable) arg2 =TID", dump_lim_AddBA_DeclineStat},
+ {307, "PE: LIM: dump CSR Send ReAssocReq", dump_lim_sme_reassoc_req},
+ {308, "PE:LIM: dump all 11H related data", dump_lim_dot11h_stats},
+ {309, "PE:LIM: dump to enable Measurement on AP", dump_lim_enable_measurement},
+ {310, "PE:LIM: dump to enable QuietIE on AP", dump_lim_enable_quietIE},
+ {311, "PE:LIM: disable/enable scan 1(disable)", dump_lim_disable_enable_scan},
+ {320, "PE.LIM: send sme scan request", dump_lim_scan_req_send},
+
+
+ /*FIXME_GEN6*/
+ /* This dump command is more of generic dump cmd and hence it should
+ * be moved to logDump.c
+ */
+ {321, "PE:LIM: Set Log Level <VOS Module> <VOS Log Level>", dump_lim_update_log_level},
+ {322, "PE.LIM: Enable/Disable PE Tracing", dump_lim_trace_cfg},
+ {323, "PE.LIM: Trace Dump if enabled", dump_lim_trace_dump},
+ {331, "PE.LIM: Send finish scan to LIM", dump_lim_finishscan_send},
+ {332, "PE.LIM: force probe rsp send from LIM", dump_lim_prb_rsp_send},
+ {333, "PE.SCH: Trigger to generate a beacon", dump_sch_beacon_trigger},
+ {335, "PE.LIM: set ACM flag (0..3)", dump_lim_acm_set},
+ {336, "PE.LIM: Send an ADDBA Req to peer MAC arg1=aid,arg2=tid, arg3=ssn", dump_lim_addba_req},
+ {337, "PE.LIM: Send a DELBA Ind to peer MAC arg1=aid,arg2=recipient(0)/initiator(1),arg3=tid,arg4=reasonCode", dump_lim_delba_req},
+ {338, "PE.LIM: Trigger a BA timeout for STA index", dump_lim_ba_timeout},
+ {339, "PE.LIM: List active BA session(s) for AssocID", dump_lim_list_active_ba},
+ {340, "PE.LIM: Set background scan flag (0-disable, 1-enable)",dump_lim_bgscan_toggle},
+ {341, "PE.LIM: Set link monitoring mode", dump_lim_linkmonitor_toggle},
+ {342, "PE.LIM: AddSta <6th byte of station Mac>", dump_lim_add_sta},
+ {343, "PE.LIM: DelSta <aid>", dump_lim_del_sta},
+ {344, "PE.LIM: Set probe respond flag", dump_lim_proberesp_toggle},
+ {345, "PE.LIM: set protection config bitmap", set_lim_prot_cfg},
+ {346, "PE:LIM: Set the Dot11 Mode", dump_lim_set_dot11_mode},
+ {347, "PE:Enable or Disable Protection", dump_lim_set_protection_control},
+ {348, "PE:LIM: Send SM Power Mode Action frame", dump_lim_send_SM_Power_Mode},
+ {349, "PE: LIM: Change CB Mode", dump_lim_update_cb_Mode},
+ {350, "PE: LIM: abort scan", dump_lim_abort_scan},
+ {351, "PE: LIM: Start stop BG scan", dump_lim_start_stop_bg_scan},
+ {352, "PE: LIM: PE statistics <scanmask>", dump_lim_get_pe_statistics},
+ {353, "PE: LIM: Set MAC log level <Mac Module ID> <Log Level>", dump_lim_set_log_level},
+ {354, "PE: LIM: Set Scan in Power Save <0-disable, 1-enable>", dump_lim_set_scan_in_powersave},
+ {355, "PE.LIM: send sme start BSS request", dump_lim_send_start_bss_req},
+ {356, "PE.LIM: dump pesession info ", dump_lim_session_print},
+ {357, "PE.LIM: send DisAssocRequest", dump_lim_send_disassoc_req},
+ {358, "PE.LIM: send sme stop bss request <session ID>", dump_lim_stop_bss_req},
+ {359, "PE.LIM: send sme join request", dump_lim_send_join_req},
+#if defined WLAN_FEATURE_VOWIFI
+ {360, "PE.LIM: send an RRM action frame", dump_lim_send_rrm_action},
+ {361, "PE.LIM: unpack an RRM action frame", dump_lim_unpack_rrm_action},
+#endif
+#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
+#ifdef RSSI_HACK
+ {362, "TL Set current RSSI", dump_lim_set_tl_data_pkt_rssi},
+#endif
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ {363, "PE.LIM: trigger pre auth/reassoc event", dump_lim_ft_event},
+#endif
+
+};
+
+
+
+void limDumpInit(tpAniSirGlobal pMac)
+{
+ logDumpRegisterTable( pMac, &limMenuDumpTable[0],
+ sizeof(limMenuDumpTable)/sizeof(limMenuDumpTable[0]) );
+}
+
+
+#endif //#if defined(ANI_LOGDUMP)
+
diff --git a/CORE/MAC/src/pe/lim/limP2P.c b/CORE/MAC/src/pe/lim/limP2P.c
new file mode 100644
index 0000000..6f4d465
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limP2P.c
@@ -0,0 +1,901 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*===========================================================================
+ L I M _ P 2 P . C
+
+ OVERVIEW:
+
+ This software unit holds the implementation of the WLAN Protocol Engine for
+ P2P.
+
+ Copyright (c) 2011 QUALCOMM Incorporated.
+ All Rights Reserved.
+ Qualcomm Confidential and Proprietary
+===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+
+ $Header$$DateTime$$Author$
+
+
+ when who what, where, why
+---------- --- --------------------------------------------------------
+2011-05-02 djindal Corrected file indentation and changed remain on channel
+ handling for concurrency.
+===========================================================================*/
+
+
+#ifdef WLAN_FEATURE_P2P
+#include "limUtils.h"
+#include "limSessionUtils.h"
+#include "wlan_qct_wda.h"
+
+#define PROBE_RSP_IE_OFFSET 36
+#define BSSID_OFFSET 16
+#define ADDR2_OFFSET 10
+#define ACTION_OFFSET 24
+
+
+
+void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data);
+void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry);
+void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry);
+void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data);
+extern tSirRetStatus limSetLinkState(
+ tpAniSirGlobal pMac, tSirLinkState state,
+ tSirMacAddr bssId, tSirMacAddr selfMacAddr,
+ tpSetLinkStateCallback callback, void *callbackArg);
+
+static tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession);
+
+/*------------------------------------------------------------------
+ *
+ * Below function is callback function, it is called when
+ * WDA_SET_LINK_STATE_RSP is received from WDI. callback function for
+ * P2P of limSetLinkState
+ *
+ *------------------------------------------------------------------*/
+void limSetLinkStateP2PCallback(tpAniSirGlobal pMac, void *callbackArg)
+{
+ //Send Ready on channel indication to SME
+ if(pMac->lim.gpLimRemainOnChanReq)
+ {
+ limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RDY_IND, eHAL_STATUS_SUCCESS,
+ pMac->lim.gpLimRemainOnChanReq->sessionId, 0);
+ }
+ else
+ {
+ //This is possible in case remain on channel is aborted
+ limLog( pMac, LOGE, FL(" NULL pointer of gpLimRemainOnChanReq") );
+ }
+}
+
+/*------------------------------------------------------------------
+ *
+ * Remain on channel req handler. Initiate the INIT_SCAN, CHN_CHANGE
+ * and SET_LINK Request from SME, chnNum and duration to remain on channel.
+ *
+ *------------------------------------------------------------------*/
+
+
+int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg)
+{
+ tANI_U8 i;
+ tpPESession psessionEntry;
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+ tpPESession pP2pSession;
+#endif
+
+ tSirRemainOnChnReq *MsgBuff = (tSirRemainOnChnReq *)pMsg;
+ pMac->lim.gpLimRemainOnChanReq = MsgBuff;
+
+ for (i =0; i < pMac->lim.maxBssId;i++)
+ {
+ psessionEntry = peFindSessionBySessionId(pMac,i);
+
+ if ( (psessionEntry != NULL) )
+ {
+ if (psessionEntry->currentOperChannel == MsgBuff->chnNum)
+ {
+ tANI_U32 val;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+ /* get the duration from the request */
+ val = SYS_MS_TO_TICKS(MsgBuff->duration);
+
+ limLog( pMac, LOGE, "Start listen duration = %d", val);
+ if (tx_timer_change(
+ &pMac->lim.limTimers.gLimRemainOnChannelTimer, val, 0)
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to change remain on channel Timer val\n"));
+ goto error;
+ }
+ else if(TX_SUCCESS != tx_timer_activate(
+ &pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to activate remain on channel Timer\n"));
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+ goto error;
+ }
+
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+ //Session is needed to send probe rsp
+ if(eSIR_SUCCESS != limCreateSessionForRemainOnChn(pMac, &pP2pSession))
+ {
+ limLog( pMac, LOGE, "Unable to create session");
+ goto error;
+ }
+#endif
+
+ if ((limSetLinkState(pMac, eSIR_LINK_LISTEN_STATE,
+ nullBssid, pMac->lim.gSelfMacAddr,
+ limSetLinkStateP2PCallback, NULL)) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGE, "Unable to change link state");
+ goto error;
+ }
+ return FALSE;
+ }
+ }
+ }
+
+ pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
+ pMac->lim.gLimMlmState = eLIM_MLM_P2P_LISTEN_STATE;
+
+ pMac->lim.gTotalScanDuration = MsgBuff->duration;
+
+ /* 1st we need to suspend link with callback to initiate change channel */
+ limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN,
+ limRemainOnChnlSuspendLinkHdlr, NULL);
+ return FALSE;
+
+error:
+ limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);
+ /* pMsg is freed by the caller */
+ return FALSE;
+}
+
+
+tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession)
+{
+ tSirRetStatus nSirStatus = eSIR_FAILURE;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tANI_U32 val;
+
+ if(pMac->lim.gpLimRemainOnChanReq && ppP2pSession)
+ {
+ if((psessionEntry = peCreateSession(pMac,
+ pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId, 1)) == NULL)
+ {
+ limLog(pMac, LOGE, FL("Session Can not be created \n"));
+ /* send remain on chn failure */
+ return nSirStatus;
+ }
+ /* Store PE sessionId in session Table */
+ psessionEntry->peSessionId = sessionId;
+
+ psessionEntry->limSystemRole = eLIM_P2P_DEVICE_ROLE;
+ CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A,
+ psessionEntry->rateSet.rate, val , SIR_MAC_MAX_NUMBER_OF_RATES );
+ psessionEntry->rateSet.numRates = val;
+
+ CFG_GET_STR( nSirStatus, pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ psessionEntry->extRateSet.rate, val,
+ WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN );
+ psessionEntry->extRateSet.numRates = val;
+
+ sirCopyMacAddr(psessionEntry->selfMacAddr,
+ pMac->lim.gpLimRemainOnChanReq->selfMacAddr);
+
+ psessionEntry->currentOperChannel = pMac->lim.gpLimRemainOnChanReq->chnNum;
+ nSirStatus = eSIR_SUCCESS;
+ *ppP2pSession = psessionEntry;
+ }
+
+ return nSirStatus;
+}
+
+
+/*------------------------------------------------------------------
+ *
+ * limSuspenLink callback, on success link suspend, trigger change chn
+ *
+ *
+ *------------------------------------------------------------------*/
+
+tSirRetStatus limRemainOnChnlChangeChnReq(tpAniSirGlobal pMac,
+ eHalStatus status, tANI_U32 *data)
+{
+ tpPESession psessionEntry;
+ tANI_U8 sessionId = 0;
+ tSirRetStatus nSirStatus = eSIR_FAILURE;
+
+ if( NULL == pMac->lim.gpLimRemainOnChanReq )
+ {
+ //RemainOnChannel may have aborted
+ PELOGE(limLog( pMac, LOGE, FL(" gpLimRemainOnChanReq is NULL") );)
+ return nSirStatus;
+ }
+
+ /* The link is not suspended */
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog( pMac, LOGE, FL(" Suspend link Failure ") );)
+ goto error;
+ }
+
+
+ if((psessionEntry = peFindSessionByBssid(
+ pMac,pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId)) != NULL)
+ {
+ goto change_channel;
+ }
+ else /* Session Entry does not exist for given BSSId */
+ {
+ /* Try to Create a new session */
+ if(eSIR_SUCCESS != limCreateSessionForRemainOnChn(pMac, &psessionEntry))
+ {
+ limLog(pMac, LOGE, FL("Session Can not be created \n"));
+ /* send remain on chn failure */
+ goto error;
+ }
+ }
+
+change_channel:
+ /* change channel to the requested by RemainOn Chn*/
+ limChangeChannelWithCallback(pMac,
+ pMac->lim.gpLimRemainOnChanReq->chnNum,
+ limRemainOnChnlSetLinkStat, NULL, psessionEntry);
+ return eSIR_SUCCESS;
+
+error:
+ limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);
+ return eSIR_FAILURE;
+}
+
+void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data)
+{
+ limRemainOnChnlChangeChnReq(pMac, status, data);
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Set the LINK state to LISTEN to allow only PROBE_REQ and Action frames
+ *
+ *------------------------------------------------------------------*/
+void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry)
+{
+ tANI_U32 val;
+ tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog( pMac, LOGE, "%s: Change channel not successful\n");
+ goto error1;
+ }
+
+ // Start timer here to come back to operating channel.
+ pMac->lim.limTimers.gLimRemainOnChannelTimer.sessionId =
+ psessionEntry->peSessionId;
+
+ /* get the duration from the request */
+ val = SYS_MS_TO_TICKS(MsgRemainonChannel->duration);
+
+ limLog( pMac, LOGE, "Start listen duration = %d", val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ /**
+ * Could not change Remain on channel Timer. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("Unable to change remain on channel Timer val\n"));
+ goto error;
+ }
+
+ if(TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ limLog( pMac, LOGE,
+ "%s: remain on channel Timer Start Failed\n", __FUNCTION__);
+ goto error;
+ }
+
+ if ((limSetLinkState(pMac, eSIR_LINK_LISTEN_STATE,nullBssid,
+ pMac->lim.gSelfMacAddr, limSetLinkStateP2PCallback,
+ NULL)) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGE, "Unable to change link state");
+ goto error;
+ }
+
+ return;
+error:
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+error1:
+ limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * limchannelchange callback, on success channel change, set the
+ * link_state to LISTEN
+ *
+ *------------------------------------------------------------------*/
+
+void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac)
+{
+ tpPESession psessionEntry;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+
+ if (NULL == pMac->lim.gpLimRemainOnChanReq)
+ {
+ limLog( pMac, LOGE, "No Remain on channel pending");
+ return;
+ }
+
+ /* get the previous valid LINK state */
+ if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ pMac->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGE, "Unable to change link state");
+ return;
+ }
+
+ if (pMac->lim.gLimMlmState != eLIM_MLM_P2P_LISTEN_STATE )
+ {
+ limRemainOnChnRsp(pMac,eHAL_STATUS_SUCCESS, NULL);
+ }
+ else
+ {
+ /* get the session */
+ if((psessionEntry = peFindSessionBySessionId(pMac,
+ pMac->lim.limTimers.gLimRemainOnChannelTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,
+ FL("Session Does not exist for given sessionID\n"));
+ goto error;
+ }
+
+ limExitRemainOnChannel(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry);
+ return;
+error:
+ limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);
+ }
+ return;
+}
+
+
+/*------------------------------------------------------------------
+ *
+ * limchannelchange callback, on success channel change, set the link_state
+ * to LISTEN
+ *
+ *------------------------------------------------------------------*/
+
+void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry)
+{
+
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog( pMac, LOGE, "Remain on Channel Failed\n");)
+ goto error;
+ }
+ //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);
+ limResumeLink(pMac, limRemainOnChnRsp, NULL);
+ return;
+error:
+ limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL);
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Send remain on channel respone: Success/ Failure
+ *
+ *------------------------------------------------------------------*/
+void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
+{
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ if ( NULL == MsgRemainonChannel )
+ {
+ PELOGE(limLog( pMac, LOGP,
+ "%s: No Pointer for Remain on Channel Req\n", __FUNCTION__);)
+ return;
+ }
+
+ //Incase of the Remain on Channel Failure Case
+ //Cleanup Everything
+ if(eHAL_STATUS_FAILURE == status)
+ {
+ //Deactivate Remain on Channel Timer
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+
+ //Set the Link State to Idle
+ /* get the previous valid LINK state */
+ if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ pMac->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGE, "Unable to change link state");
+ }
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ }
+
+ /* delete the session */
+ if((psessionEntry = peFindSessionByBssid(pMac,
+ MsgRemainonChannel->selfMacAddr,&sessionId)) != NULL)
+ {
+ if ( eLIM_P2P_DEVICE_ROLE == psessionEntry->limSystemRole )
+ {
+ peDeleteSession( pMac, psessionEntry);
+ }
+ }
+ /* Post the meessage to Sme */
+ limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, status,
+ MsgRemainonChannel->sessionId, 0);
+
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimRemainOnChanReq );
+ pMac->lim.gpLimRemainOnChanReq = NULL;
+
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Indicate the Mgmt Frame received to SME to HDD callback
+ * handle Probe_req/Action frame currently
+ *
+ *------------------------------------------------------------------*/
+void limSendSmeMgmtFrameInd(
+ tpAniSirGlobal pMac, tANI_U8 frameType,
+ tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId,
+ tANI_U32 rxChannel)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL;
+ tANI_U16 length;
+
+ length = sizeof(tSirSmeMgmtFrameInd) + frameLen;
+
+ if( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **)&pSirSmeMgmtFrame, length ))
+ {
+ limLog(pMac, LOGP,
+ FL("palAllocateMemory failed for eWNI_SME_LISTEN_RSP\n"));
+ return;
+ }
+ palZeroMemory(pMac->hHdd, (void*)pSirSmeMgmtFrame, length);
+
+ pSirSmeMgmtFrame->mesgType = eWNI_SME_MGMT_FRM_IND;
+ pSirSmeMgmtFrame->mesgLen = length;
+ pSirSmeMgmtFrame->sessionId = sessionId;
+ pSirSmeMgmtFrame->frameType = frameType;
+ pSirSmeMgmtFrame->rxChan = rxChannel;
+
+ vos_mem_zero(pSirSmeMgmtFrame->frameBuf,frameLen);
+ vos_mem_copy(pSirSmeMgmtFrame->frameBuf,frame,frameLen);
+
+ mmhMsg.type = eWNI_SME_MGMT_FRM_IND;
+ mmhMsg.bodyptr = pSirSmeMgmtFrame;
+ mmhMsg.bodyval = 0;
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end limSendSmeListenRsp() ***/
+
+
+eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess)
+{
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL),
+ pMac->lim.actionFrameSessionId, 0);
+
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+void limSetHtCaps(tpAniSirGlobal pMac,tANI_U8 *pIeStartPtr,tANI_U32 nBytes)
+{
+ v_U8_t *pIe=NULL;
+ tDot11fIEHTCaps dot11HtCap;
+
+ PopulateDot11fHTCaps(pMac,&dot11HtCap);
+ pIe = limGetIEPtr(pMac,pIeStartPtr, nBytes,
+ DOT11F_EID_HTCAPS,ONE_BYTE);
+ limLog( pMac, LOGE, FL("pIe 0x%x dot11HtCap.supportedMCSSet[0]=0x%x"),
+ (tANI_U32)pIe,dot11HtCap.supportedMCSSet[0]);
+ if(pIe)
+ {
+ tHtCaps *pHtcap = (tHtCaps *)&pIe[2]; //convert from unpacked to packed structure
+ pHtcap->advCodingCap = dot11HtCap.advCodingCap;
+ pHtcap->supportedChannelWidthSet = dot11HtCap.supportedChannelWidthSet;
+ pHtcap->mimoPowerSave = dot11HtCap.mimoPowerSave;
+ pHtcap->greenField = dot11HtCap.greenField;
+ pHtcap->shortGI20MHz = dot11HtCap.shortGI20MHz;
+ pHtcap->shortGI40MHz = dot11HtCap.shortGI40MHz;
+ pHtcap->txSTBC = dot11HtCap.txSTBC;
+ pHtcap->rxSTBC = dot11HtCap.rxSTBC;
+ pHtcap->delayedBA = dot11HtCap.delayedBA ;
+ pHtcap->maximalAMSDUsize = dot11HtCap.maximalAMSDUsize;
+ pHtcap->dsssCckMode40MHz = dot11HtCap.dsssCckMode40MHz;
+ pHtcap->psmp = dot11HtCap.psmp;
+ pHtcap->stbcControlFrame = dot11HtCap.stbcControlFrame;
+ pHtcap->lsigTXOPProtection = dot11HtCap.lsigTXOPProtection;
+ pHtcap->maxRxAMPDUFactor = dot11HtCap.maxRxAMPDUFactor;
+ pHtcap->mpduDensity = dot11HtCap.mpduDensity;
+ palCopyMemory( pMac->hHdd, (void *)pHtcap->supportedMCSSet,
+ (void *)(dot11HtCap.supportedMCSSet),
+ sizeof(pHtcap->supportedMCSSet));
+ pHtcap->pco = dot11HtCap.pco;
+ pHtcap->transitionTime = dot11HtCap.transitionTime;
+ pHtcap->mcsFeedback = dot11HtCap.mcsFeedback;
+ pHtcap->txBF = dot11HtCap.txBF;
+ pHtcap->rxStaggeredSounding = dot11HtCap.rxStaggeredSounding;
+ pHtcap->txStaggeredSounding = dot11HtCap.txStaggeredSounding;
+ pHtcap->rxZLF = dot11HtCap.rxZLF;
+ pHtcap->txZLF = dot11HtCap.txZLF;
+ pHtcap->implicitTxBF = dot11HtCap.implicitTxBF;
+ pHtcap->calibration = dot11HtCap.calibration;
+ pHtcap->explicitCSITxBF = dot11HtCap.explicitCSITxBF;
+ pHtcap->explicitUncompressedSteeringMatrix =
+ dot11HtCap.explicitUncompressedSteeringMatrix;
+ pHtcap->explicitBFCSIFeedback = dot11HtCap.explicitBFCSIFeedback;
+ pHtcap->explicitUncompressedSteeringMatrixFeedback =
+ dot11HtCap.explicitUncompressedSteeringMatrixFeedback;
+ pHtcap->explicitCompressedSteeringMatrixFeedback =
+ dot11HtCap.explicitCompressedSteeringMatrixFeedback;
+ pHtcap->csiNumBFAntennae = dot11HtCap.csiNumBFAntennae;
+ pHtcap->uncompressedSteeringMatrixBFAntennae =
+ dot11HtCap.uncompressedSteeringMatrixBFAntennae;
+ pHtcap->compressedSteeringMatrixBFAntennae =
+ dot11HtCap.compressedSteeringMatrixBFAntennae;
+ pHtcap->antennaSelection = dot11HtCap.antennaSelection;
+ pHtcap->explicitCSIFeedbackTx = dot11HtCap.explicitCSIFeedbackTx;
+ pHtcap->antennaIndicesFeedbackTx = dot11HtCap.antennaIndicesFeedbackTx;
+ pHtcap->explicitCSIFeedback = dot11HtCap.explicitCSIFeedback;
+ pHtcap->antennaIndicesFeedback = dot11HtCap.antennaIndicesFeedback;
+ pHtcap->rxAS = dot11HtCap.rxAS;
+ pHtcap->txSoundingPPDUs = dot11HtCap.txSoundingPPDUs;
+ }
+}
+
+
+void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ tSirMbMsgP2p *pMbMsg = (tSirMbMsgP2p *)pMsg->bodyptr;
+ tANI_U32 nBytes;
+ tANI_U8 *pFrame;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+ tpSirMacFrameCtl pFc = (tpSirMacFrameCtl ) pMbMsg->data;
+ tANI_U8 noaLen = 0;
+ tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+ tANI_U8 origLen = 0;
+ tANI_U8 sessionId = 0;
+ v_U8_t *pP2PIe = NULL;
+ tpPESession psessionEntry;
+ v_U8_t *pPresenceRspNoaAttr = NULL;
+ v_U8_t *pNewP2PIe = NULL;
+ v_U16_t remainLen = 0;
+
+ nBytes = pMbMsg->msgLen - sizeof(tSirMbMsg);
+
+ limLog( pMac, LOG1, FL("sending pFc->type=%d pFc->subType=%d"),
+ pFc->type, pFc->subType);
+
+ psessionEntry = peFindSessionByBssid(pMac,
+ (tANI_U8*)pMbMsg->data + BSSID_OFFSET, &sessionId);
+
+ /* Check for session corresponding to ADDR2 As Supplicant is filling
+ ADDR2 with BSSID */
+ if( NULL == psessionEntry )
+ {
+ psessionEntry = peFindSessionByBssid(pMac,
+ (tANI_U8*)pMbMsg->data + ADDR2_OFFSET, &sessionId);
+ }
+
+ if( NULL == psessionEntry )
+ {
+ tANI_U8 isSessionActive = 0;
+ tANI_U8 i;
+
+ /* If we are not able to find psessionEntry entry, then try to find
+ active session, if found any active sessions then send the
+ action frame, If no active sessions found then drop the frame */
+ for (i =0; i < pMac->lim.maxBssId;i++)
+ {
+ psessionEntry = peFindSessionBySessionId(pMac,i);
+ if ( NULL != psessionEntry)
+ {
+ isSessionActive = 1;
+ break;
+ }
+ }
+ if( !isSessionActive )
+ {
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0);
+ return;
+ }
+ }
+
+ if ((SIR_MAC_MGMT_FRAME == pFc->type)&&
+ ((SIR_MAC_MGMT_PROBE_RSP == pFc->subType)||
+ (SIR_MAC_MGMT_ACTION == pFc->subType)))
+ {
+ //if this is a probe RSP being sent from wpa_supplicant
+ if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType)
+ {
+ //get proper offset for Probe RSP
+ pP2PIe = limGetP2pIEPtr(pMac,
+ (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET,
+ nBytes - PROBE_RSP_IE_OFFSET);
+ while ((NULL != pP2PIe) && (SIR_MAC_MAX_IE_LENGTH == pP2PIe[1]))
+ {
+ remainLen = nBytes - (pP2PIe - (tANI_U8*)pMbMsg->data);
+ if (remainLen > 2)
+ {
+ pNewP2PIe = limGetP2pIEPtr(pMac,
+ pP2PIe+SIR_MAC_MAX_IE_LENGTH + 2, remainLen);
+ }
+ if (pNewP2PIe)
+ {
+ pP2PIe = pNewP2PIe;
+ pNewP2PIe = NULL;
+ }
+ else
+ {
+ break;
+ }
+ } //end of while
+ }
+ else
+ {
+ if (SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY ==
+ *((v_U8_t *)pMbMsg->data+ACTION_OFFSET))
+ {
+ tpSirMacP2PActionFrameHdr pActionHdr =
+ (tpSirMacP2PActionFrameHdr)((v_U8_t *)pMbMsg->data +
+ ACTION_OFFSET);
+ if ( palEqualMemory( pMac->hHdd, pActionHdr->Oui,
+ SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE ) &&
+ (SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP ==
+ pActionHdr->OuiSubType))
+ { //In case of Presence RSP response
+ pP2PIe = limGetP2pIEPtr(pMac,
+ (v_U8_t *)pMbMsg->data + ACTION_OFFSET +
+ sizeof(tSirMacP2PActionFrameHdr),
+ (nBytes - ACTION_OFFSET -
+ sizeof(tSirMacP2PActionFrameHdr)));
+ if( NULL != pP2PIe )
+ {
+ //extract the presence of NoA attribute inside P2P IE
+ pPresenceRspNoaAttr =
+ limGetIEPtr(pMac,pP2PIe + SIR_P2P_IE_HEADER_LEN,
+ pP2PIe[1], SIR_P2P_NOA_ATTR,TWO_BYTE);
+ }
+ }
+ }
+ }
+
+ if (pP2PIe != NULL)
+ {
+ //get NoA attribute stream P2P IE
+ noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry);
+ //need to append NoA attribute in P2P IE
+ if (noaLen > 0)
+ {
+ origLen = pP2PIe[1];
+ //if Presence Rsp has NoAttr
+ if (pPresenceRspNoaAttr)
+ {
+ v_U16_t noaAttrLen = pPresenceRspNoaAttr[1] |
+ (pPresenceRspNoaAttr[2]<<8);
+ /*One byte for attribute, 2bytes for length*/
+ origLen -= (noaAttrLen + 1 + 2);
+ //remove those bytes to copy
+ nBytes -= (noaAttrLen + 1 + 2);
+ //remove NoA from original Len
+ pP2PIe[1] = origLen;
+ }
+ if ((pP2PIe[1] + (tANI_U16)noaLen)> SIR_MAC_MAX_IE_LENGTH)
+ {
+ //Form the new NoA Byte array in multiple P2P IEs
+ noaLen = limGetNoaAttrStreamInMultP2pIes(pMac, noaStream,
+ noaLen,((pP2PIe[1] + (tANI_U16)noaLen)-
+ SIR_MAC_MAX_IE_LENGTH));
+ pP2PIe[1] = SIR_MAC_MAX_IE_LENGTH;
+ }
+ else
+ {
+ pP2PIe[1] += noaLen; //increment the length of P2P IE
+ }
+ nBytes += noaLen;
+ limLog( pMac, LOGE,
+ FL("noaLen=%d origLen=%d pP2PIe=0x%x"
+ " nBytes=%d nBytesToCopy=%d \n"),
+ noaLen,origLen,pP2PIe,nBytes,
+ ((pP2PIe + origLen + 2) - (v_U8_t *)pMbMsg->data));
+ }
+ }
+
+ if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType)
+ {
+ limSetHtCaps( pMac,(tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET,
+ nBytes);
+ }
+ }
+
+
+ // Ok-- try to allocate some memory:
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ (tANI_U16)nBytes, ( void** ) &pFrame, (void**) &pPacket);
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to allocate %d bytes for a Probe"
+ " Request.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ if (noaLen > 0)
+ {
+ // Add 2 bytes for length and Arribute field
+ v_U32_t nBytesToCopy = ((pP2PIe + origLen + 2 ) -
+ (v_U8_t *)pMbMsg->data);
+ palCopyMemory( pMac->hHdd, pFrame, pMbMsg->data, nBytesToCopy);
+ palCopyMemory( pMac->hHdd, (pFrame + nBytesToCopy), noaStream, noaLen);
+ palCopyMemory( pMac->hHdd, (pFrame + nBytesToCopy + noaLen),
+ pMbMsg->data + nBytesToCopy, nBytes - nBytesToCopy - noaLen);
+
+ }
+ else
+ {
+ palCopyMemory(pMac->hHdd, pFrame, pMbMsg->data, nBytes);
+ }
+
+ /* Use BD rate 2 for all P2P related frames. As these frames need to go
+ * at OFDM rates. And BD rate2 we configured at 6Mbps.
+ */
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+ if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType)
+ {
+ halstatus = halTxFrame( pMac, pPacket, (tANI_U16)nBytes,
+ HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+ 7,/*SMAC_SWBD_TX_TID_MGMT_HIGH */ limTxComplete, pFrame,
+ txFlag );
+
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ halstatus, pMbMsg->sessionId, 0);
+ }
+ else
+ {
+ halstatus = halTxFrameWithTxComplete( pMac, pPacket, (tANI_U16)nBytes,
+ HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+ 7,/*SMAC_SWBD_TX_TID_MGMT_HIGH */ limTxComplete, pFrame,
+ limP2PActionCnf, txFlag );
+
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("could not send action frame!\n" ));
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, halstatus,
+ pMbMsg->sessionId, 0);
+ }
+ else
+ {
+ pMac->lim.actionFrameSessionId = pMbMsg->sessionId;
+ }
+ }
+
+ return;
+}
+
+
+void limAbortRemainOnChan(tpAniSirGlobal pMac)
+{
+ if(VOS_TRUE == tx_timer_running(
+ &pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ //TODO check for state and take appropriate actions
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+ limProcessRemainOnChnTimeout(pMac);
+ }
+ return;
+}
+
+/* Power Save Related Functions */
+tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpP2pPsConfig pNoA;
+ tpP2pPsParams pMsgNoA;
+ tSirMsgQ msg;
+
+ pNoA = (tpP2pPsConfig) pMsgBuf;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory(
+ pMac->hHdd, (void **) &pMsgNoA, sizeof( tP2pPsConfig )))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to allocate memory during NoA Update\n" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig));
+ pMsgNoA->opp_ps = pNoA->opp_ps;
+ pMsgNoA->ctWindow = pNoA->ctWindow;
+ pMsgNoA->duration = pNoA->duration;
+ pMsgNoA->interval = pNoA->interval;
+ pMsgNoA->count = pNoA->count;
+ pMsgNoA->single_noa_duration = pNoA->single_noa_duration;
+ pMsgNoA->psSelection = pNoA->psSelection;
+
+ msg.type = SIR_HAL_SET_P2P_GO_NOA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = pMsgNoA;
+ msg.bodyval = 0;
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGE, FL("halPostMsgApi failed\n"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} /*** end __limProcessSmeGoNegReq() ***/
+
+#endif
+
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
new file mode 100644
index 0000000..4c89a87
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -0,0 +1,2091 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessActionFrame.cc contains the code
+ * for processing Action Frame.
+ * Author: Michael Lui
+ * Date: 05/23/03
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "palTypes.h"
+#include "wniApi.h"
+#include "sirApi.h"
+#include "aniGlobal.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#endif
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limSendSmeRspMessages.h"
+#include "parserApi.h"
+#include "limAdmitControl.h"
+#include "wmmApsd.h"
+#include "limSendMessages.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+
+#if defined FEATURE_WLAN_CCX
+#include "ccxApi.h"
+#endif
+#include "wlan_qct_wda.h"
+
+
+#define BA_DEFAULT_TX_BUFFER_SIZE 64
+
+typedef enum
+{
+ LIM_ADDBA_RSP = 0,
+ LIM_ADDBA_REQ = 1
+}tLimAddBaValidationReqType;
+
+/* Note: The test passes if the STAUT stops sending any frames, and no further
+ frames are transmitted on this channel by the station when the AP has sent
+ the last 6 beacons, with the channel switch information elements as seen
+ with the sniffer.*/
+#define SIR_CHANSW_TX_STOP_MAX_COUNT 6
+/**-----------------------------------------------------------------
+\fn limStopTxAndSwitchChannel
+\brief Stops the transmission if channel switch mode is silent and
+ starts the channel switch timer.
+
+\param pMac
+\return NONE
+-----------------------------------------------------------------*/
+void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId)
+{
+ tANI_U8 isFullPowerRequested = 0;
+
+ PELOG1(limLog(pMac, LOG1, FL("Channel switch Mode == %d\n"),
+ pMac->lim.gLimChannelSwitch.switchMode);)
+
+ if (pMac->lim.gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT ||
+ pMac->lim.gLimChannelSwitch.switchCount <= SIR_CHANSW_TX_STOP_MAX_COUNT)
+ {
+ /* Freeze the transmission */
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX);
+
+ /*Request for Full power only if the device is in powersave*/
+ if(!limIsSystemInActiveState(pMac))
+ {
+ /* Request Full Power */
+ limSendSmePreChannelSwitchInd(pMac);
+ isFullPowerRequested = 1;
+ }
+ }
+ else
+ {
+ /* Resume the transmission */
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+ }
+
+ /* change the channel immediatly only if the channel switch count is 0 and the
+ * device is not in powersave
+ * If the device is in powersave channel switch should happen only after the
+ * device comes out of the powersave */
+ if (pMac->lim.gLimChannelSwitch.switchCount == 0)
+ {
+ if(limIsSystemInActiveState(pMac))
+ {
+ limProcessChannelSwitchTimeout(pMac);
+ }
+ else if(!isFullPowerRequested)
+ {
+ /* If the Full power is already not requested
+ * Request Full Power so the channel switch happens
+ * after device comes to full power */
+ limSendSmePreChannelSwitchInd(pMac);
+ }
+ return;
+ }
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_CHANNEL_SWITCH_TIMER));
+
+ pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId;
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_activate failed\n"));
+ }
+ return;
+}
+
+/**------------------------------------------------------------
+\fn limStartChannelSwitch
+\brief Switches the channel if switch count == 0, otherwise
+ starts the timer for channel switch and stops BG scan
+ and heartbeat timer tempororily.
+
+\param pMac
+\param psessionEntry
+\return NONE
+------------------------------------------------------------*/
+tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ PELOG1(limLog(pMac, LOG1, FL("Starting the channel switch\n"));)
+ /* Deactivate and change reconfigure the timeout value */
+ limDeactivateAndChangeTimer(pMac, eLIM_CHANNEL_SWITCH_TIMER);
+
+ /* Follow the channel switch, forget about the previous quiet. */
+ //If quiet is running, chance is there to resume tx on its timeout.
+ //so stop timer for a safer side.
+ if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_QUIET_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_deactivate failed\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ else if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_QUIET_BSS_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_deactivate failed\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ /* Prepare for 11h channel switch */
+ limPrepareFor11hChannelSwitch(pMac, psessionEntry);
+
+ /** Dont add any more statements here as we posted finish scan request
+ * to HAL, wait till we get the response
+ */
+ return eSIR_SUCCESS;
+}
+
+
+/**
+ * __limProcessChannelSwitchActionFrame
+ *
+ *FUNCTION:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to packet info structure
+ * @return None
+ */
+
+static void
+
+__limProcessChannelSwitchActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+
+ tpSirMacMgmtHdr pHdr;
+ tANI_U8 *pBody;
+ tDot11fChannelSwitch *pChannelSwitchFrame;
+ tANI_U16 beaconPeriod;
+ tANI_U32 val;
+ tANI_U32 frameLen;
+ tANI_U32 nStatus;
+ eHalStatus status;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ PELOG3(limLog(pMac, LOG3, FL("Received Channel switch action frame\n"));)
+ if (!psessionEntry->lim11hEnable)
+ return;
+
+ status = palAllocateMemory( pMac->hHdd, (void **)&pChannelSwitchFrame, sizeof(*pChannelSwitchFrame));
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ limLog(pMac, LOGE,
+ FL("palAllocateMemory failed, status = %d \n"), status);
+ return;
+ }
+
+ /* Unpack channel switch frame */
+ nStatus = dot11fUnpackChannelSwitch(pMac, pBody, frameLen, pChannelSwitchFrame);
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen);
+ palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
+ return;
+ }
+ else if(DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen);
+ }
+
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) &psessionEntry->bssId,
+ (tANI_U8 *) &pHdr->sa,
+ sizeof(tSirMacAddr)))
+ {
+ #if 0
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &val) != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
+ limLog(pMac, LOGP, FL("could not retrieve Beacon interval\n"));
+ return;
+ }
+ #endif// TO SUPPORT BT-AMP
+
+ /* copy the beacon interval from psessionEntry*/
+ val = psessionEntry->beaconParams.beaconInterval;
+
+ beaconPeriod = (tANI_U16) val;
+
+ pMac->lim.gLimChannelSwitch.primaryChannel = pChannelSwitchFrame->ChanSwitchAnn.newChannel;
+ pMac->lim.gLimChannelSwitch.switchCount = pChannelSwitchFrame->ChanSwitchAnn.switchCount;
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue = SYS_MS_TO_TICKS(beaconPeriod) *
+ pMac->lim.gLimChannelSwitch.switchCount;
+ pMac->lim.gLimChannelSwitch.switchMode = pChannelSwitchFrame->ChanSwitchAnn.switchMode;
+
+ PELOG3(limLog(pMac, LOG3, FL("Rcv Chnl Swtch Frame: Timeout in %d ticks\n"),
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue);)
+
+ /* Only primary channel switch element is present */
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_NONE;
+
+ if(GET_CB_ADMIN_STATE(pMac->lim.gCbState))
+ {
+ switch(pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset)
+ {
+ case eHT_SECONDARY_CHANNEL_OFFSET_UP:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_UP;
+ break;
+
+ case eHT_SECONDARY_CHANNEL_OFFSET_DOWN:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_DOWN;
+ break;
+
+ case eHT_SECONDARY_CHANNEL_OFFSET_NONE:
+ default:
+ /* Nothing to be done here */
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("LIM: Received action frame not from our BSS, dropping..."));)
+ }
+
+ if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Could not start channel switch\n"));)
+ }
+
+ palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
+ return;
+} /*** end limProcessChannelSwitchActionFrame() ***/
+
+
+static void
+__limProcessAddTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+
+ tSirAddtsReqInfo addts;
+ tSirRetStatus retval;
+ tpSirMacMgmtHdr pHdr;
+ tSirMacScheduleIE schedule;
+ tpDphHashNode pSta;
+ tANI_U16 status;
+ tANI_U16 aid;
+ tANI_U32 frameLen;
+ tANI_U8 *pBody;
+ tANI_U8 tspecIdx = 0; //index in the sch tspec table.
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+
+ if ((psessionEntry->limSystemRole != eLIM_AP_ROLE)||(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("AddTs request at non-AP: ignoring\n"));)
+ return;
+ }
+
+ pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTs\n"));)
+ return;
+ }
+
+ PELOGW(limLog(pMac, LOGW, "AddTs Request from STA %d\n", aid);)
+ retval = sirConvertAddtsReq2Struct(pMac, pBody, frameLen, &addts);
+ if (retval != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("AddTs parsing failed (error %d)\n"), retval);)
+ return;
+ }
+
+ status = eSIR_MAC_SUCCESS_STATUS;
+
+
+ if (addts.wmeTspecPresent)
+ {
+ if ((! psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wme not enabled/capable\n"));)
+ status = eSIR_MAC_WME_REFUSED_STATUS;
+ }
+ else
+ {
+ PELOG2(limLog(pMac, LOG2, FL("WME Addts received\n"));)
+ }
+ }
+ else if (addts.wsmTspecPresent)
+ {
+ if ((! psessionEntry->limWsmEnabled) || (! pSta->wsmEnabled))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wsm not enabled/capable\n"));)
+ status = eSIR_MAC_REQ_DECLINED_STATUS;
+ }
+ else
+ {
+ PELOG2(limLog(pMac, LOG2, FL("WSM Addts received\n"));)
+ }
+ }
+ else if ((! psessionEntry->limQosEnabled) || (! pSta->lleEnabled))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: qos not enabled/capable\n"));)
+ status = eSIR_MAC_REQ_DECLINED_STATUS;
+ }
+ else
+ {
+ PELOG2(limLog(pMac, LOG2, FL("11e QoS Addts received\n"));)
+ }
+
+ // for edca, if no Admit Control, ignore the request
+ if ((status == eSIR_MAC_SUCCESS_STATUS) &&
+ (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) &&
+ (! psessionEntry->gLimEdcaParamsBC[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm))
+ {
+ limLog(pMac, LOGW, FL("AddTs with UP %d has no ACM - ignoring request\n"),
+ addts.tspec.tsinfo.traffic.userPrio);
+ status = (addts.wmeTspecPresent) ?
+ eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+
+ if (status != eSIR_MAC_SUCCESS_STATUS)
+ {
+ limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
+ return;
+ }
+
+ // try to admit the STA and send the appropriate response
+ retval = limAdmitControlAddTS(pMac, &pSta->staAddr[0], &addts, NULL, pSta->assocId, true, &schedule, &tspecIdx, psessionEntry);
+ if (retval != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Unable to admit TS\n"));)
+ status = (addts.wmeTspecPresent) ?
+ eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+ else if (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)
+ {
+ if(eSIR_SUCCESS != limSendHalMsgAddTs(pMac, pSta->staIndex, tspecIdx, addts.tspec, psessionEntry->peSessionId))
+ {
+ limLog(pMac, LOGW, FL("AddTs with UP %d failed in limSendHalMsgAddTs - ignoring request\n"),
+ addts.tspec.tsinfo.traffic.userPrio);
+ status = (addts.wmeTspecPresent) ?
+ eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecIdx);
+ }
+ if (status != eSIR_MAC_SUCCESS_STATUS)
+ {
+ limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
+ return;
+ }
+ }
+#if 0 //only EDCA is supported now.
+ else if (addts.numTclas > 1)
+ {
+ limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
+ aid, addts.numTclas);
+ status = (addts.wmeTspecPresent) ?
+ eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+ else if (addts.numTclas == 1)
+ {
+ limLog(pMac, LOGW, "AddTs Request from STA %d: tsid %d, UP %d, OK!\n", aid,
+ addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
+ status = eSIR_MAC_SUCCESS_STATUS;
+ }
+#endif
+
+ limLog(pMac, LOGW, "AddTs Request from STA %d: Sending AddTs Response with status %d\n",
+ aid, status);
+
+ limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, &schedule,psessionEntry);
+#endif
+}
+
+
+static void
+__limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tSirAddtsRspInfo addts;
+ tSirRetStatus retval;
+ tpSirMacMgmtHdr pHdr;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+ tANI_U32 frameLen;
+ tANI_U8 *pBody;
+ tpLimTspecInfo tspecInfo;
+ tANI_U8 ac;
+ tpDphHashNode pStaDs = NULL;
+ tANI_U8 rspReqd = 1;
+ tANI_U32 cfgLen;
+ tSirMacAddr peerMacAddr;
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+
+ PELOGW(limLog(pMac, LOGW, "Recv AddTs Response\n");)
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("AddTsRsp recvd at AP: ignoring\n"));)
+ return;
+ }
+
+ pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
+ return;
+ }
+
+ retval = sirConvertAddtsRsp2Struct(pMac, pBody, frameLen, &addts);
+ if (retval != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("AddTsRsp parsing failed (error %d)\n"), retval);)
+ return;
+ }
+
+ // don't have to check for qos/wme capabilities since we wouldn't have this
+ // flag set otherwise
+ if (! pMac->lim.gLimAddtsSent)
+ {
+ // we never sent an addts request!
+ PELOGW(limLog(pMac, LOGW, "Recvd AddTsRsp but no request was ever sent - ignoring\n");)
+ return;
+ }
+
+ if (pMac->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken)
+ {
+ limLog(pMac, LOGW, "AddTsRsp: token mismatch (got %d, exp %d) - ignoring\n",
+ addts.dialogToken, pMac->lim.gLimAddtsReq.req.dialogToken);
+ return;
+ }
+
+ /*
+ * for successful addts reponse, try to add the classifier.
+ * if this fails for any reason, we should send a delts request to the ap
+ * for now, its ok not to send a delts since we are going to add support for
+ * multiple tclas soon and until then we won't send any addts requests with
+ * multiple tclas elements anyway.
+ * In case of addClassifier failure, we just let the addts timer run out
+ */
+ if (((addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
+ (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) &&
+ (addts.status == eSIR_MAC_SUCCESS_STATUS))
+ {
+ // add the classifier - this should always succeed
+ if (addts.numTclas > 1) // currently no support for multiple tclas elements
+ {
+ limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
+ aid, addts.numTclas);
+ return;
+ }
+ else if (addts.numTclas == 1)
+ {
+ limLog(pMac, LOGW, "AddTs Response from STA %d: tsid %d, UP %d, OK!\n", aid,
+ addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
+ }
+ }
+ limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
+ addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
+ addts.status);
+
+ // deactivate the response timer
+ limDeactivateAndChangeTimer(pMac, eLIM_ADDTS_RSP_TIMER);
+
+ if (addts.status != eSIR_MAC_SUCCESS_STATUS)
+ {
+ limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
+ addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
+ addts.status);
+ limSendSmeAddtsRsp(pMac, true, addts.status, psessionEntry, addts.tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+
+ // clear the addts flag
+ pMac->lim.gLimAddtsSent = false;
+
+ return;
+ }
+#ifdef FEATURE_WLAN_CCX
+ if (addts.tsmPresent)
+ {
+ limLog(pMac, LOGW, "TSM IE Present\n");
+ psessionEntry->ccxContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio;
+ vos_mem_copy(&psessionEntry->ccxContext.tsm.tsmInfo,
+ &addts.tsmIE,sizeof(tSirMacCCXTSMIE));
+ limActivateTSMStatsTimer(pMac, psessionEntry);
+ }
+#endif
+ /* Since AddTS response was successful, check for the PSB flag
+ * and directional flag inside the TS Info field.
+ * An AC is trigger enabled AC if the PSB subfield is set to 1
+ * in the uplink direction.
+ * An AC is delivery enabled AC if the PSB subfield is set to 1
+ * in the downlink direction.
+ * An AC is trigger and delivery enabled AC if the PSB subfield
+ * is set to 1 in the bi-direction field.
+ */
+ if (addts.tspec.tsinfo.traffic.psb == 1)
+ limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, SET_UAPSD_MASK);
+ else
+ limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, CLEAR_UAPSD_MASK);
+
+
+ /* ADDTS success, so AC is now admitted. We shall now use the default
+ * EDCA parameters as advertised by AP and send the updated EDCA params
+ * to HAL.
+ */
+ ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
+ if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
+ }
+ else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
+ }
+ else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
+ }
+
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ else
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ }
+ else
+ limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
+
+
+ sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
+
+ //if schedule is not present then add TSPEC with svcInterval as 0.
+ if(!addts.schedulePresent)
+ addts.schedule.svcInterval = 0;
+ if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, &addts.tspec, addts.schedule.svcInterval, &tspecInfo))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
+ psessionEntry);
+ pMac->lim.gLimAddtsSent = false;
+ return; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
+ }
+ if((addts.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA) ||
+ ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC) &&
+ (psessionEntry->gLimEdcaParams[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm)))
+ {
+ retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId);
+ if(eSIR_SUCCESS != retval)
+ {
+ limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx);
+
+ // Send DELTS action frame to AP
+ cfgLen = sizeof(tSirMacAddr);
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
+ psessionEntry);
+ limSendSmeAddtsRsp(pMac, true, retval, psessionEntry, addts.tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+ pMac->lim.gLimAddtsSent = false;
+ return;
+ }
+ PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
+ addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
+ }
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
+ addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
+ PELOGW(limLog(pMac, LOGW, FL("no ACM: Bypass sending WDA_ADD_TS_REQ to HAL \n"));)
+ // Use the smesessionId and smetransactionId from the PE session context
+ limSendSmeAddtsRsp(pMac, true, eSIR_SME_SUCCESS, psessionEntry, addts.tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+ }
+
+ // clear the addts flag
+ pMac->lim.gLimAddtsSent = false;
+ return;
+}
+
+
+static void
+__limProcessDelTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tSirRetStatus retval;
+ tSirDeltsReqInfo delts;
+ tpSirMacMgmtHdr pHdr;
+ tpDphHashNode pSta;
+ tANI_U32 frameLen;
+ tANI_U16 aid;
+ tANI_U8 *pBody;
+ tANI_U8 tsStatus;
+ tSirMacTSInfo *tsinfo;
+ tANI_U8 tspecIdx;
+ tANI_U8 ac;
+ tpDphHashNode pStaDs = NULL;
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring DelTs\n"));)
+ return;
+ }
+
+ // parse the delts request
+ retval = sirConvertDeltsReq2Struct(pMac, pBody, frameLen, &delts);
+ if (retval != eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("DelTs parsing failed (error %d)\n"), retval);)
+ return;
+ }
+
+ if (delts.wmeTspecPresent)
+ {
+ if ((!psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: wme not enabled/capable\n"));)
+ return;
+ }
+ PELOG2(limLog(pMac, LOG2, FL("WME Delts received\n"));)
+ }
+ else if ((psessionEntry->limQosEnabled) && pSta->lleEnabled)
+ {
+ PELOG2(limLog(pMac, LOG2, FL("11e QoS Delts received\n"));)
+ }
+ else if ((psessionEntry->limWsmEnabled) && pSta->wsmEnabled)
+ {
+ PELOG2(limLog(pMac, LOG2, FL("WSM Delts received\n"));)
+ }
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: qos not enabled/capable\n"));)
+ return;
+ }
+
+ tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
+
+ // if no Admit Control, ignore the request
+ if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA))
+ {
+
+#if(defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE &&
+ (! psessionEntry->gLimEdcaParamsBC[upToAc(tsinfo->traffic.userPrio)].aci.acm)) ||
+ (psessionEntry->limSystemRole != eLIM_AP_ROLE &&
+ (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm)))
+#else
+ if ((upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) || (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm))
+#endif
+ {
+ limLog(pMac, LOGW, FL("DelTs with UP %d has no AC - ignoring request\n"),
+ tsinfo->traffic.userPrio);
+ return;
+ }
+ }
+
+ // try to delete the TS
+ if (eSIR_SUCCESS != limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Unable to Delete TS\n"));)
+ return;
+ }
+
+ else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
+ (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))
+ {
+ //Edca only for now.
+ }
+ else
+ {
+ //send message to HAL to delete TS
+ if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, pSta->staIndex, tspecIdx, delts))
+ {
+ limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request\n"),
+ tsinfo->traffic.userPrio);
+ return;
+ }
+ }
+
+ /* We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
+ * The AC for this TSPEC is no longer trigger enabled if this Tspec
+ * was set-up in uplink direction only.
+ * The AC for this TSPEC is no longer delivery enabled if this Tspec
+ * was set-up in downlink direction only.
+ * The AC for this TSPEC is no longer triiger enabled and delivery
+ * enabled if this Tspec was a bidirectional TSPEC.
+ */
+ limSetTspecUapsdMask(pMac, tsinfo, CLEAR_UAPSD_MASK);
+
+
+ /* We're deleting the TSPEC.
+ * The AC for this TSPEC is no longer admitted in uplink/downlink direction
+ * if this TSPEC was set-up in uplink/downlink direction only.
+ * The AC for this TSPEC is no longer admitted in both uplink and downlink
+ * directions if this TSPEC was a bi-directional TSPEC.
+ * If ACM is set for this AC and this AC is admitted only in downlink
+ * direction, PE needs to downgrade the EDCA parameter
+ * (for the AC for which TS is being deleted) to the
+ * next best AC for which ACM is not enabled, and send the
+ * updated values to HAL.
+ */
+ ac = upToAc(tsinfo->traffic.userPrio);
+
+ if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
+ }
+ else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
+ }
+ else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
+ }
+
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ else
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ }
+ else
+ limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
+
+ PELOG1(limLog(pMac, LOG1, FL("DeleteTS succeeded\n"));)
+ if((psessionEntry->limSystemRole != eLIM_AP_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
+ limSendSmeDeltsInd(pMac, &delts, aid,psessionEntry);
+
+#ifdef FEATURE_WLAN_CCX
+ limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
+#endif
+
+}
+
+
+#ifdef ANI_SUPPORT_11H
+/**
+ * limProcessBasicMeasReq
+ *
+ *FUNCTION:
+ * This function is called by limProcessMeasurementRequestFrame()
+ * when it received a Basic measurement Request action frame.
+ * Station/BP receiving this should perform basic measurements
+ * and then send Basic Measurement Report. AP should not perform
+ * any measurements, and send report indicating refusal.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMeasReqFrame - A pointer to Basic Meas. Req structure
+ * @return None
+ */
+static void
+__limProcessBasicMeasReq(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr)
+{
+ // TBD - Station shall perform basic measurements
+
+ if (limSendMeasReportFrame(pMac,
+ pMeasReqFrame,
+ peerMacAddr) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("fail to send Basic Meas report \n"));)
+ return;
+ }
+}
+
+
+/**
+ * limProcessCcaMeasReq
+ *
+ *FUNCTION:
+ * This function is called by limProcessMeasurementRequestFrame()
+ * when it received a CCA measurement Request action frame.
+ * Station/BP receiving this should perform CCA measurements
+ * and then send CCA Measurement Report. AP should not perform
+ * any measurements, and send report indicating refusal.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMeasReqFrame - A pointer to CCA Meas. Req structure
+ * @return None
+ */
+static void
+__limProcessCcaMeasReq(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr)
+{
+ // TBD - Station shall perform cca measurements
+
+ if (limSendMeasReportFrame(pMac,
+ pMeasReqFrame,
+ peerMacAddr) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("fail to send CCA Meas report \n"));)
+ return;
+ }
+}
+
+
+/**
+ * __limProcessRpiMeasReq
+ *
+ *FUNCTION:
+ * This function is called by limProcessMeasurementRequestFrame()
+ * when it received a RPI measurement Request action frame.
+ * Station/BP/AP receiving this shall not perform any measurements,
+ * and send report indicating refusal.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMeasReqFrame - A pointer to RPI Meas. Req structure
+ * @return None
+ */
+static void
+__limProcessRpiMeasReq(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr)
+{
+ if (limSendMeasReportFrame(pMac,
+ pMeasReqFrame,
+ peerMacAddr) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("fail to send RPI Meas report \n"));)
+ return;
+ }
+}
+
+
+/**
+ * __limProcessMeasurementRequestFrame
+ *
+ *FUNCTION:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to packet info structure
+ * @return None
+ */
+
+static void
+__limProcessMeasurementRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
+{
+ tpSirMacMgmtHdr pHdr;
+ tANI_U8 *pBody;
+ tpSirMacMeasReqActionFrame pMeasReqFrame;
+ tANI_U32 frameLen;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if ( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **)&pMeasReqFrame, sizeof( tSirMacMeasReqActionFrame ) ) )
+ {
+ limLog(pMac, LOGE,
+ FL("limProcessMeasurementRequestFrame: palAllocateMemory failed \n"));
+ return;
+ }
+
+ if (sirConvertMeasReqFrame2Struct(pMac, pBody, pMeasReqFrame, frameLen) !=
+ eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Rcv invalid Measurement Request Action Frame \n"));)
+ return;
+ }
+
+
+ switch(pMeasReqFrame->measReqIE.measType)
+ {
+ case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+ __limProcessBasicMeasReq(pMac, pMeasReqFrame, pHdr->sa);
+ break;
+
+ case SIR_MAC_CCA_MEASUREMENT_TYPE:
+ __limProcessCcaMeasReq(pMac, pMeasReqFrame, pHdr->sa);
+ break;
+
+ case SIR_MAC_RPI_MEASUREMENT_TYPE:
+ __limProcessRpiMeasReq(pMac, pMeasReqFrame, pHdr->sa);
+ break;
+
+ default:
+ PELOG1(limLog(pMac, LOG1, FL("Unknown Measurement Type %d \n"),
+ pMeasReqFrame->measReqIE.measType);)
+ break;
+ }
+
+} /*** end limProcessMeasurementRequestFrame ***/
+
+
+/**
+ * limProcessTpcRequestFrame
+ *
+ *FUNCTION:
+ * This function is called upon receiving Tpc Request frame.
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to packet info structure
+ * @return None
+ */
+
+static void
+__limProcessTpcRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
+{
+ tpSirMacMgmtHdr pHdr;
+ tANI_U8 *pBody;
+ tpSirMacTpcReqActionFrame pTpcReqFrame;
+ tANI_U32 frameLen;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ PELOG1(limLog(pMac, LOG1, FL("****LIM: Processing TPC Request from peer ****"));)
+
+ if ( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **)&pTpcReqFrame, sizeof( tSirMacTpcReqActionFrame ) ) )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed \n"));)
+ return;
+ }
+
+ if (sirConvertTpcReqFrame2Struct(pMac, pBody, pTpcReqFrame, frameLen) !=
+ eSIR_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Rcv invalid TPC Req Action Frame \n"));)
+ return;
+ }
+
+ if (limSendTpcReportFrame(pMac,
+ pTpcReqFrame,
+ pHdr->sa) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("fail to send TPC Report Frame. \n"));)
+ return;
+ }
+}
+#endif
+
+
+/**
+ * \brief Validate an ADDBA Req from peer with respect
+ * to our own BA configuration
+ *
+ * \sa __limValidateAddBAParameterSet
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param baParameterSet The ADDBA Parameter Set.
+ *
+ * \param pDelBAFlag this parameter is NULL except for call from processAddBAReq
+ * delBAFlag is set when entry already exists.
+ *
+ * \param reqType ADDBA Req v/s ADDBA Rsp
+ * 1 - ADDBA Req
+ * 0 - ADDBA Rsp
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+
+static tSirMacStatusCodes
+__limValidateAddBAParameterSet( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tDot11fFfAddBAParameterSet baParameterSet,
+ tANI_U8 dialogueToken,
+ tLimAddBaValidationReqType reqType ,
+ tANI_U8* pDelBAFlag /*this parameter is NULL except for call from processAddBAReq*/)
+{
+ if(baParameterSet.tid >= STACFG_MAX_TC)
+ {
+ return eSIR_MAC_WME_INVALID_PARAMS_STATUS;
+ }
+
+ //check if there is already a BA session setup with this STA/TID while processing AddBaReq
+ if((true == pSta->tcCfg[baParameterSet.tid].fUseBARx) &&
+ (LIM_ADDBA_REQ == reqType))
+ {
+ //There is already BA session setup for STA/TID.
+ limLog( pMac, LOGW,
+ FL( "AddBAReq rcvd when there is already a session for this StaId = %d, tid = %d\n " ),
+ pSta->staIndex, baParameterSet.tid);
+ limPrintMacAddr( pMac, pSta->staAddr, LOGW );
+
+ if(pDelBAFlag)
+ *pDelBAFlag = true;
+ }
+ return eSIR_MAC_SUCCESS_STATUS;
+}
+
+/**
+ * \brief Validate a DELBA Ind from peer with respect
+ * to our own BA configuration
+ *
+ * \sa __limValidateDelBAParameterSet
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param baParameterSet The DELBA Parameter Set.
+ *
+ * \param pSta Runtime, STA-related configuration cached
+ * in the HashNode object
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+static tSirMacStatusCodes
+__limValidateDelBAParameterSet( tpAniSirGlobal pMac,
+ tDot11fFfDelBAParameterSet baParameterSet,
+ tpDphHashNode pSta )
+{
+tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS;
+
+ // Validate if a BA is active for the requested TID
+ if( pSta->tcCfg[baParameterSet.tid].fUseBATx ||
+ pSta->tcCfg[baParameterSet.tid].fUseBARx )
+ {
+ statusCode = eSIR_MAC_SUCCESS_STATUS;
+
+ limLog( pMac, LOGW,
+ FL("Valid DELBA Ind received. Time to send WDA_DELBA_IND to HAL...\n"));
+ }
+ else
+ limLog( pMac, LOGW,
+ FL("Received an INVALID DELBA Ind for TID %d...\n"),
+ baParameterSet.tid );
+
+ return statusCode;
+}
+
+/**
+ * \brief Process an ADDBA REQ
+ *
+ * \sa limProcessAddBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pRxPacketInfo Handle to the Rx packet info from HDD
+ *
+ * \return none
+ *
+ */
+static void
+__limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tDot11fAddBAReq frmAddBAReq;
+ tpSirMacMgmtHdr pHdr;
+ tpDphHashNode pSta;
+ tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;
+ tANI_U16 aid;
+ tANI_U32 frameLen, nStatus;
+ tANI_U8 *pBody;
+ tANI_U8 delBAFlag =0;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ // Unpack the received frame
+ nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq );
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL("Failed to unpack and parse an ADDBA Request (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+
+ // Without an unpacked request we cannot respond, so silently ignore the request
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while unpacking an ADDBA Request (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
+ if( pSta == NULL )
+ {
+ limLog( pMac, LOGE,
+ FL( "STA context not found - ignoring ADDBA from \n" ));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+
+ // FIXME - Should we do this?
+ status = eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS;
+ goto returnAfterError;
+ }
+
+ limLog( pMac, LOGW,
+ FL( "ADDBA Req from STA with AID %d, tid = %d\n" ),
+ aid, frmAddBAReq.AddBAParameterSet.tid);
+
+#ifdef WLAN_SOFTAP_VSTA_FEATURE
+ // we can only do BA on "hard" STAs
+ if (!(IS_HWSTA_IDX(pSta->staIndex)))
+ {
+ status = eSIR_MAC_REQ_DECLINED_STATUS;
+ goto returnAfterError;
+ }
+#endif //WLAN_SOFTAP_VSTA_FEATURE
+
+
+ // Now, validate the ADDBA Req
+ if( eSIR_MAC_SUCCESS_STATUS !=
+ (status = __limValidateAddBAParameterSet( pMac, pSta,
+ frmAddBAReq.AddBAParameterSet,
+ 0, //dialogue token is don't care in request validation.
+ LIM_ADDBA_REQ, &delBAFlag)))
+ goto returnAfterError;
+
+ //BA already set, so we need to delete it before adding new one.
+ if(delBAFlag)
+ {
+ if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
+ pSta,
+ (tANI_U8)frmAddBAReq.AddBAParameterSet.tid,
+ eBA_RECIPIENT,psessionEntry))
+ {
+ status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto returnAfterError;
+ }
+ }
+
+ // Check if the ADD BA Declined configuration is Disabled
+ if ((pMac->lim.gAddBA_Declined & ( 1 << frmAddBAReq.AddBAParameterSet.tid ) )) {
+ limLog( pMac, LOGE, FL( "Declined the ADDBA Req for the TID %d \n" ),
+ frmAddBAReq.AddBAParameterSet.tid);
+ status = eSIR_MAC_REQ_DECLINED_STATUS;
+ goto returnAfterError;
+ }
+
+ //
+ // Post WDA_ADDBA_REQ to HAL.
+ // If HAL/HDD decide to allow this ADDBA Req session,
+ // then this BA session is termed active
+ //
+
+ // Change the Block Ack state of this STA to wait for
+ // ADDBA Rsp from HAL
+ LIM_SET_STA_BA_STATE(pSta, frmAddBAReq.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
+
+ if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
+ pSta,
+ (tANI_U8) frmAddBAReq.DialogToken.token,
+ (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
+ (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
+ frmAddBAReq.AddBAParameterSet.bufferSize,
+ frmAddBAReq.BATimeout.timeout,
+ (tANI_U16) frmAddBAReq.BAStartingSequenceControl.ssn,
+ eBA_RECIPIENT,psessionEntry))
+ status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ else
+ return;
+
+returnAfterError:
+
+ //
+ // Package LIM_MLM_ADDBA_RSP to MLME, with proper
+ // status code. MLME will then send an ADDBA RSP
+ // over the air to the peer MAC entity
+ //
+ if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac,
+ pHdr->sa,
+ status,
+ frmAddBAReq.DialogToken.token,
+ (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
+ (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
+ frmAddBAReq.AddBAParameterSet.bufferSize,
+ frmAddBAReq.BATimeout.timeout,psessionEntry))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to post LIM_MLM_ADDBA_RSP to " ));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+ }
+
+}
+
+/**
+ * \brief Process an ADDBA RSP
+ *
+ * \sa limProcessAddBARsp
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pRxPacketInfo Handle to the packet info structure from HDD
+ *
+ * \return none
+ *
+ */
+static void
+__limProcessAddBARsp( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+tDot11fAddBARsp frmAddBARsp;
+tpSirMacMgmtHdr pHdr;
+tpDphHashNode pSta;
+tSirMacReasonCodes reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+tANI_U16 aid;
+tANI_U32 frameLen, nStatus;
+tANI_U8 *pBody;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
+ if( pSta == NULL )
+ {
+ limLog( pMac, LOGE,
+ FL( "STA context not found - ignoring ADDBA from \n" ));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+ return;
+ }
+
+#ifdef WLAN_SOFTAP_VSTA_FEATURE
+ // We can only do BA on "hard" STAs. We should not have issued an ADDBA
+ // Request, so we should never be processing a ADDBA Response
+ if (!(IS_HWSTA_IDX(pSta->staIndex)))
+ {
+ return;
+ }
+#endif //WLAN_SOFTAP_VSTA_FEATURE
+
+ // Unpack the received frame
+ nStatus = dot11fUnpackAddBARsp( pMac, pBody, frameLen, &frmAddBARsp );
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to unpack and parse an ADDBA Response (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ goto returnAfterError;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while unpacking an ADDBA Response (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ limLog( pMac, LOGW,
+ FL( "ADDBA Rsp from STA with AID %d, tid = %d, status = %d\n" ),
+ aid, frmAddBARsp.AddBAParameterSet.tid, frmAddBARsp.Status.status);
+
+ //if there is no matchin dialougue token then ignore the response.
+
+ if(eSIR_SUCCESS != limSearchAndDeleteDialogueToken(pMac, frmAddBARsp.DialogToken.token,
+ pSta->assocId, frmAddBARsp.AddBAParameterSet.tid))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("dialogueToken in received addBARsp did not match with outstanding requests\n"));)
+ return;
+ }
+
+ // Check first if the peer accepted the ADDBA Req
+ if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
+ {
+ //if peer responded with buffer size 0 then we should pick the default.
+ if(0 == frmAddBARsp.AddBAParameterSet.bufferSize)
+ frmAddBARsp.AddBAParameterSet.bufferSize = BA_DEFAULT_TX_BUFFER_SIZE;
+
+ // Now, validate the ADDBA Rsp
+ if( eSIR_MAC_SUCCESS_STATUS !=
+ __limValidateAddBAParameterSet( pMac, pSta,
+ frmAddBARsp.AddBAParameterSet,
+ (tANI_U8)frmAddBARsp.DialogToken.token,
+ LIM_ADDBA_RSP, NULL))
+ goto returnAfterError;
+ }
+ else
+ goto returnAfterError;
+
+ // Change STA state to wait for ADDBA Rsp from HAL
+ LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
+
+ //
+ // Post WDA_ADDBA_REQ to HAL.
+ // If HAL/HDD decide to allow this ADDBA Rsp session,
+ // then this BA session is termed active
+ //
+
+ if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
+ pSta,
+ (tANI_U8) frmAddBARsp.DialogToken.token,
+ (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
+ (tANI_U8) frmAddBARsp.AddBAParameterSet.policy,
+ frmAddBARsp.AddBAParameterSet.bufferSize,
+ frmAddBARsp.BATimeout.timeout,
+ 0,
+ eBA_INITIATOR,psessionEntry))
+ reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+ else
+ return;
+
+returnAfterError:
+
+ // TODO: Do we need to signal an error status to SME,
+ // if status != eSIR_MAC_SUCCESS_STATUS
+
+ // Restore STA "BA" State
+ LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_IDLE);
+ //
+ // Need to send a DELBA IND to peer, who
+ // would have setup a BA session with this STA
+ //
+ if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
+ {
+ //
+ // Package LIM_MLM_DELBA_REQ to MLME, with proper
+ // status code. MLME will then send a DELBA IND
+ // over the air to the peer MAC entity
+ //
+ if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac,
+ pSta,
+ eBA_INITIATOR,
+ (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
+ reasonCode, psessionEntry))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to post LIM_MLM_DELBA_REQ to " ));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+ }
+ }
+}
+
+/**
+ * \brief Process a DELBA Indication
+ *
+ * \sa limProcessDelBAInd
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pRxPacketInfo Handle to the Rx packet info from HDD
+ *
+ * \return none
+ *
+ */
+static void
+__limProcessDelBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+tDot11fDelBAInd frmDelBAInd;
+tpSirMacMgmtHdr pHdr;
+tpDphHashNode pSta;
+tANI_U16 aid;
+tANI_U32 frameLen, nStatus;
+tANI_U8 *pBody;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
+ if( pSta == NULL )
+ {
+ limLog( pMac, LOGE, FL( "STA context not found - ignoring DELBA from \n"));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+ return;
+ }
+
+ limLog( pMac, LOG1, FL( "DELBA Ind from STA with AID %d\n" ), aid );
+
+ // Unpack the received frame
+ nStatus = dot11fUnpackDelBAInd( pMac, pBody, frameLen, &frmDelBAInd );
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to unpack and parse a DELBA Indication (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while unpacking a DELBA Indication (0x%08x, %d bytes):\n"),
+ nStatus,
+ frameLen );
+
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Received DELBA for TID %d, Reason code %d\n" ),
+ frmDelBAInd.DelBAParameterSet.tid,
+ frmDelBAInd.Reason.code );
+
+ // Now, validate the DELBA Ind
+ if( eSIR_MAC_SUCCESS_STATUS != __limValidateDelBAParameterSet( pMac,
+ frmDelBAInd.DelBAParameterSet,
+ pSta ))
+ return;
+
+ //
+ // Post WDA_DELBA_IND to HAL and delete the
+ // existing BA session
+ //
+ // NOTE - IEEE 802.11-REVma-D8.0, Section 7.3.1.16
+ // is kind of confusing...
+ //
+ if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
+ pSta,
+ (tANI_U8) frmDelBAInd.DelBAParameterSet.tid,
+ (eBA_RECIPIENT == frmDelBAInd.DelBAParameterSet.initiator)?
+ eBA_INITIATOR: eBA_RECIPIENT,psessionEntry))
+ limLog( pMac, LOGE, FL( "Posting WDA_DELBA_IND to HAL failed \n"));
+
+ return;
+
+}
+
+static void
+__limProcessSMPowerSaveUpdate(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry)
+{
+
+#if 0
+ tpSirMacMgmtHdr pHdr;
+ tDot11fSMPowerSave frmSMPower;
+ tSirMacHTMIMOPowerSaveState state;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+ tANI_U32 frameLen, nStatus;
+ tANI_U8 *pBody;
+
+ pHdr = SIR_MAC_BD_TO_MPDUHEADER( pBd );
+ pBody = SIR_MAC_BD_TO_MPDUDATA( pBd );
+ frameLen = SIR_MAC_BD_TO_PAYLOAD_LEN( pBd );
+
+ pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
+ if( pSta == NULL ) {
+ limLog( pMac, LOGE,FL( "STA context not found - ignoring UpdateSM PSave Mode from \n" ));
+ limPrintMacAddr( pMac, pHdr->sa, LOGW );
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus = dot11fUnpackSMPowerSave( pMac, pBody, frameLen, &frmSMPower);
+
+ if( DOT11F_FAILED( nStatus )) {
+ limLog( pMac, LOGE, FL( "Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ return;
+ }else if ( DOT11F_WARNED( nStatus ) ) {
+ limLog(pMac, LOGW, FL( "There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with PS_Enable:%d"
+ "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En,
+ frmSMPower.SMPowerModeSet.Mode);
+
+ /** Update in the DPH Table about the Update in the SM Power Save mode*/
+ if (frmSMPower.SMPowerModeSet.PowerSave_En && frmSMPower.SMPowerModeSet.Mode)
+ state = eSIR_HT_MIMO_PS_DYNAMIC;
+ else if ((frmSMPower.SMPowerModeSet.PowerSave_En) && (frmSMPower.SMPowerModeSet.Mode ==0))
+ state = eSIR_HT_MIMO_PS_STATIC;
+ else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0) && (frmSMPower.SMPowerModeSet.Mode == 0))
+ state = eSIR_HT_MIMO_PS_NO_LIMIT;
+ else {
+ PELOGW(limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with invalid mode"));)
+ return;
+ }
+
+ if (state == pSta->htMIMOPSState) {
+ PELOGE(limLog(pMac, LOGE, FL("The PEER is already set in the same mode"));)
+ return;
+ }
+
+ /** Update in the HAL Station Table for the Update of the Protection Mode */
+ pSta->htMIMOPSState = state;
+ limPostSMStateUpdate(pMac,pSta->staIndex, pSta->htMIMOPSState);
+
+#endif
+
+}
+
+#if defined WLAN_FEATURE_VOWIFI
+
+static void
+__limProcessRadioMeasureRequest( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fRadioMeasurementRequest frm;
+ tANI_U32 frameLen, nStatus;
+ tANI_U8 *pBody;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ if( psessionEntry == NULL )
+ {
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus = dot11fUnpackRadioMeasurementRequest( pMac, pBody, frameLen, &frm );
+
+ if( DOT11F_FAILED( nStatus )) {
+ limLog( pMac, LOGE, FL( "Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ return;
+ }else if ( DOT11F_WARNED( nStatus ) ) {
+ limLog(pMac, LOGW, FL( "There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ // Call rrm function to handle the request.
+
+ rrmProcessRadioMeasurementRequest( pMac, pHdr->sa, &frm, psessionEntry );
+}
+
+static void
+__limProcessLinkMeasurementReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fLinkMeasurementRequest frm;
+ tANI_U32 frameLen, nStatus;
+ tANI_U8 *pBody;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ if( psessionEntry == NULL )
+ {
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus = dot11fUnpackLinkMeasurementRequest( pMac, pBody, frameLen, &frm );
+
+ if( DOT11F_FAILED( nStatus )) {
+ limLog( pMac, LOGE, FL( "Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ return;
+ }else if ( DOT11F_WARNED( nStatus ) ) {
+ limLog(pMac, LOGW, FL( "There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ // Call rrm function to handle the request.
+
+ rrmProcessLinkMeasurementRequest( pMac, pRxPacketInfo, &frm, psessionEntry );
+
+}
+
+static void
+__limProcessNeighborReport( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fNeighborReportResponse frm;
+ tANI_U32 frameLen, nStatus;
+ tANI_U8 *pBody;
+
+ pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
+ pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
+ frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
+
+ if( psessionEntry == NULL )
+ {
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus = dot11fUnpackNeighborReportResponse( pMac, pBody, frameLen, &frm );
+
+ if( DOT11F_FAILED( nStatus )) {
+ limLog( pMac, LOGE, FL( "Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ return;
+ }else if ( DOT11F_WARNED( nStatus ) ) {
+ limLog(pMac, LOGW, FL( "There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):\n"),
+ nStatus, frameLen );
+ PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
+ }
+
+ //Call rrm function to handle the request.
+ rrmProcessNeighborReportResponse( pMac, &frm, psessionEntry );
+
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * limProcessActionFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessActionFrame() upon
+ * SA query request Action frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pBd - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+static void __limProcessSAQueryRequestActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tANI_U8 *pBody;
+ tANI_U16 transId = 0;
+
+ /* Prima --- Below Macro not available in prima
+ pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
+ pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ /*Extract 11w trsansId from SA query request action frame
+ In SA query response action frame we will send same transId
+ In SA query request action frame:
+ Category : 1 byte
+ Action : 1 byte
+ Transaction ID : 2 bbytes */
+
+ transId = pBody[2];
+ transId = transId << 8;
+ transId |= pBody[3];
+
+ //Send 11w SA query response action frame
+ if (limSendSaQueryResponseFrame(pMac,
+ transId,
+ pHdr->sa,psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("fail to send SA query response action frame. \n"));)
+ return;
+ }
+}
+
+#endif
+
+/**
+ * limProcessActionFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to packet info structure
+ * @return None
+ */
+
+void
+limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ tpSirMacActionFrameHdr pActionHdr = (tpSirMacActionFrameHdr) pBody;
+
+
+ switch (pActionHdr->category)
+ {
+ case SIR_MAC_ACTION_QOS_MGMT:
+ if (psessionEntry->limQosEnabled)
+ {
+ switch (pActionHdr->actionID)
+ {
+ case SIR_MAC_QOS_ADD_TS_REQ:
+ __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_QOS_ADD_TS_RSP:
+ __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_QOS_DEL_TS_REQ:
+ __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Qos action %d not handled\n"), pActionHdr->actionID);)
+ break;
+ }
+ break ;
+ }
+
+ break;
+
+ case SIR_MAC_ACTION_SPECTRUM_MGMT:
+ switch (pActionHdr->actionID)
+ {
+#ifdef ANI_SUPPORT_11H
+ case SIR_MAC_ACTION_MEASURE_REQUEST_ID:
+ if(psessionEntry->lim11hEnable)
+ {
+ __limProcessMeasurementRequestFrame(pMac, pRxPacketInfo);
+ }
+ break;
+
+ case SIR_MAC_ACTION_TPC_REQUEST_ID:
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
+ (pessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+ if(psessionEntry->lim11hEnable)
+ {
+ __limProcessTpcRequestFrame(pMac, pRxPacketInfo);
+ }
+ }
+ break;
+
+#endif
+ case SIR_MAC_ACTION_CHANNEL_SWITCH_ID:
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ {
+ __limProcessChannelSwitchActionFrame(pMac, pRxPacketInfo,psessionEntry);
+ }
+ break;
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Spectrum mgmt action id %d not handled\n"), pActionHdr->actionID);)
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_WME:
+ if (! psessionEntry->limWmeEnabled)
+ {
+ limLog(pMac, LOGW, FL("WME mode disabled - dropping action frame %d\n"),
+ pActionHdr->actionID);
+ break;
+ }
+ switch(pActionHdr->actionID)
+ {
+ case SIR_MAC_QOS_ADD_TS_REQ:
+ __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_QOS_ADD_TS_RSP:
+ __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_QOS_DEL_TS_REQ:
+ __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("WME action %d not handled\n"), pActionHdr->actionID);)
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_BLKACK:
+ // Determine the "type" of BA Action Frame
+ switch(pActionHdr->actionID)
+ {
+ case SIR_MAC_BLKACK_ADD_REQ:
+ __limProcessAddBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_BLKACK_ADD_RSP:
+ __limProcessAddBARsp( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ case SIR_MAC_BLKACK_DEL:
+ __limProcessDelBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+ case SIR_MAC_ACTION_HT:
+ /** Type of HT Action to be performed*/
+ switch(pActionHdr->actionID) {
+ case SIR_MAC_SM_POWER_SAVE:
+ __limProcessSMPowerSaveUpdate(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
+ break;
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Action ID %d not handled in HT Action category\n"), pActionHdr->actionID);)
+ break;
+ }
+ break;
+
+#if defined WLAN_FEATURE_VOWIFI
+ case SIR_MAC_ACTION_RRM:
+ if( pMac->rrm.rrmPEContext.rrmEnable )
+ {
+ switch(pActionHdr->actionID) {
+ case SIR_MAC_RRM_RADIO_MEASURE_REQ:
+ __limProcessRadioMeasureRequest( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
+ break;
+ case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
+ __limProcessLinkMeasurementReq( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
+ break;
+ case SIR_MAC_RRM_NEIGHBOR_RPT:
+ __limProcessNeighborReport( pMac, (tANI_U8*) pRxPacketInfo, psessionEntry );
+ break;
+ default:
+ PELOGE( limLog( pMac, LOGE, FL("Action ID %d not handled in RRM\n"), pActionHdr->actionID);)
+ break;
+
+ }
+ }
+ else
+ {
+ // Else we will just ignore the RRM messages.
+ PELOGE( limLog( pMac, LOGE, FL("RRM Action frame ignored as RRM is disabled in cfg\n"));)
+ }
+ break;
+#endif
+#if defined WLAN_FEATURE_P2P
+ case SIR_MAC_ACTION_PUBLIC_USAGE:
+ switch(pActionHdr->actionID) {
+ case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+ {
+ tpSirMacVendorSpecificPublicActionFrameHdr pPubAction = (tpSirMacVendorSpecificPublicActionFrameHdr) pActionHdr;
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+ tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ //Check if it is a P2P public action frame.
+ if( palEqualMemory( pMac->hHdd, pPubAction->Oui, P2POui, 4 ) )
+ {
+ /* Forward to the SME to HDD to wpa_supplicant */
+ // type is ACTION
+ limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
+ (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
+ WDA_GET_RX_CH( pRxPacketInfo ));
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
+ pPubAction->Oui[0], pPubAction->Oui[1], pPubAction->Oui[2], pPubAction->Oui[3] );
+ }
+ }
+ break;
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
+ break;
+ }
+ break;
+#endif
+
+#ifdef WLAN_FEATURE_11W
+ case SIR_MAC_ACTION_SA_QUERY:
+ {
+ /**11w SA query request action frame received**/
+ __limProcessSAQueryRequestActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry );
+ break;
+ }
+#endif
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Action category %d not handled\n"), pActionHdr->category);)
+ break;
+ }
+}
+
+#if defined WLAN_FEATURE_P2P
+/**
+ * limProcessActionFrameNoSession
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception and no session.
+ * Currently only public action frames can be received from
+ * a non-associated station.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pBd - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+void
+limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd)
+{
+ tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
+ tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr = (tpSirMacVendorSpecificPublicActionFrameHdr) pBody;
+
+ limLog( pMac, LOGE, "Received a Action frame -- no session");
+
+ switch ( pActionHdr->category )
+ {
+ case SIR_MAC_ACTION_PUBLIC_USAGE:
+ switch(pActionHdr->actionID) {
+ case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+ {
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+ tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pBd);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
+
+ //Check if it is a P2P public action frame.
+ if( palEqualMemory( pMac->hHdd, pActionHdr->Oui, P2POui, 4 ) )
+ {
+ /* Forward to the SME to HDD to wpa_supplicant */
+ // type is ACTION
+ limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
+ (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
+ WDA_GET_RX_CH( pBd ));
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
+ pActionHdr->Oui[0], pActionHdr->Oui[1], pActionHdr->Oui[2], pActionHdr->Oui[3] );
+ }
+ }
+ break;
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
+ break;
+ }
+ break;
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("Unhandled action frame without session -- %x \n"), pActionHdr->category);)
+ break;
+
+ }
+}
+#endif
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
new file mode 100644
index 0000000..6ee945d
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
@@ -0,0 +1,1648 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessAssocReqFrame.cc contains the code
+ * for processing Re/Association Request Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+#include "palTypes.h"
+#include "aniGlobal.h"
+#include "wniCfgAp.h"
+#include "sirApi.h"
+#include "cfgApi.h"
+
+#include "schApi.h"
+#include "pmmApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limStaHashApi.h"
+#include "limAdmitControl.h"
+#include "palApi.h"
+
+
+#include "vos_types.h"
+/**
+ * limConvertSupportedChannels
+ *
+ *FUNCTION:
+ * This function is called by limProcessAssocReqFrame() to
+ * parse the channel support IE in the Assoc/Reassoc Request
+ * frame, and send relevant information in the SME_ASSOC_IND
+ *
+ *NOTE:
+ *
+ * @param pMac - A pointer to Global MAC structure
+ * @param pMlmAssocInd - A pointer to SME ASSOC/REASSOC IND
+ * @param assocReq - A pointer to ASSOC/REASSOC Request frame
+ *
+ * @return None
+ */
+static void
+limConvertSupportedChannels(tpAniSirGlobal pMac,
+ tpLimMlmAssocInd pMlmAssocInd,
+ tSirAssocReq *assocReq)
+{
+
+ tANI_U16 i, j, index=0;
+ tANI_U8 firstChannelNumber;
+ tANI_U8 numberOfChannel;
+ tANI_U8 nextChannelNumber;
+
+ if(assocReq->supportedChannels.length >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ limLog(pMac, LOG1, FL("Number of supported channels:%d is more than MAX\n"),
+ assocReq->supportedChannels.length);
+ pMlmAssocInd->supportedChannels.numChnl = 0;
+ return;
+ }
+
+ for(i=0; i < (assocReq->supportedChannels.length); i++)
+ {
+ // Get First Channel Number
+ firstChannelNumber = assocReq->supportedChannels.supportedChannels[i];
+ pMlmAssocInd->supportedChannels.channelList[index] = firstChannelNumber;
+ i++;
+ index++;
+ if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ pMlmAssocInd->supportedChannels.numChnl = 0;
+ return;
+ }
+ // Get Number of Channels in a Subband
+ numberOfChannel = assocReq->supportedChannels.supportedChannels[i];
+ PELOG2(limLog(pMac, LOG2, FL("Rcv AssocReq: chnl=%d, numOfChnl=%d \n"),
+ firstChannelNumber, numberOfChannel);)
+
+ if (numberOfChannel > 1)
+ {
+ nextChannelNumber = firstChannelNumber;
+ if(SIR_BAND_5_GHZ == limGetRFBand(firstChannelNumber))
+ {
+ for (j=1; j < numberOfChannel; j++)
+ {
+ nextChannelNumber += SIR_11A_FREQUENCY_OFFSET;
+ pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber;
+ index++;
+ if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ pMlmAssocInd->supportedChannels.numChnl = 0;
+ return;
+ }
+ }
+ }
+ else if(SIR_BAND_2_4_GHZ == limGetRFBand(firstChannelNumber))
+ {
+ for (j=1; j < numberOfChannel; j++)
+ {
+ nextChannelNumber += SIR_11B_FREQUENCY_OFFSET;
+ pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber;
+ index++;
+ if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ pMlmAssocInd->supportedChannels.numChnl = 0;
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ pMlmAssocInd->supportedChannels.numChnl = (tANI_U8) index;
+ PELOG2(limLog(pMac, LOG2,
+ FL("Send AssocInd to WSM: spectrum ON, minPwr %d, maxPwr %d, numChnl %d\n"),
+ pMlmAssocInd->powerCap.minTxPower,
+ pMlmAssocInd->powerCap.maxTxPower,
+ pMlmAssocInd->supportedChannels.numChnl);)
+}
+
+
+/**---------------------------------------------------------------
+\fn limProcessAssocReqFrame
+\brief This function is called by limProcessMessageQueue()
+\ upon Re/Association Request frame reception in
+\ BTAMP AP or Soft AP role.
+\
+\param pMac
+\param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
+\param subType - Indicates whether it is Association Request(=0)
+\ or Reassociation Request(=1) frame
+\return None
+------------------------------------------------------------------*/
+void
+limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,
+ tANI_U8 subType, tpPESession psessionEntry)
+{
+ tANI_U8 updateContext;
+ tANI_U8 *pBody;
+ tANI_U16 aid, temp;
+ tANI_U32 val;
+ tANI_S32 framelen;
+ tSirRetStatus status;
+ tpSirMacMgmtHdr pHdr;
+ struct tLimPreAuthNode *pStaPreAuthContext;
+ tAniAuthType authType;
+ tSirMacCapabilityInfo localCapabilities;
+ tpDphHashNode pStaDs = NULL;
+ tpSirAssocReq pAssocReq;
+#ifdef WLAN_SOFTAP_FEATURE
+ tLimMlmStates mlmPrevState;
+ tDot11fIERSN Dot11fIERSN;
+ tDot11fIEWPA Dot11fIEWPA;
+#endif
+ tANI_U32 phyMode;
+ tHalBitVal qosMode;
+ tHalBitVal wsmMode, wmeMode;
+ tANI_U8 *wpsIe = NULL;
+ tSirMacRateSet basicRates;
+ tANI_U8 i = 0, j = 0;
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ limGetQosMode(psessionEntry, &qosMode);
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE )
+ {
+ limLog(pMac, LOGE, FL("received unexpected ASSOC REQ subType=%d for role=%d, radioId=%d from \n"),
+ subType, psessionEntry->limSystemRole, pMac->sys.gSirRadioId);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3,
+ WDA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen);
+ return;
+ }
+
+ // Get pointer to Re/Association Request frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (limIsGroupAddr(pHdr->sa))
+ {
+ // Received Re/Assoc Req frame from a BC/MC address
+ // Log error and ignore it
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOG1, FL("received Assoc frame from a BC/MC address\n"));
+ else
+ limLog(pMac, LOG1, FL("received ReAssoc frame from a BC/MC address\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ return;
+ }
+ limLog(pMac, LOG2, FL("Received AssocReq Frame: "));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, (tANI_U8 *) pBody, framelen);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ // If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON
+ if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+ limSendAssocRspMgmtFrame(pMac,
+ eSIR_MAC_MIC_FAILURE_REASON,
+ 1,
+ pHdr->sa,
+ subType, 0, psessionEntry);
+ return;
+ }
+#endif
+
+ // Allocate memory for the Assoc Request frame
+ if ( palAllocateMemory(pMac->hHdd, (void **)&pAssocReq, sizeof(*pAssocReq)) != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("PAL Allocate Memory failed in AssocReq\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (void *)pAssocReq , sizeof(*pAssocReq));
+
+ // Parse Assoc Request frame
+ if (subType == LIM_ASSOC)
+ status = sirConvertAssocReqFrame2Struct(pMac, pBody, framelen, pAssocReq);
+ else
+ status = sirConvertReassocReqFrame2Struct(pMac, pBody, framelen, pAssocReq);
+
+ if (status != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGW, FL("Parse error AssocRequest, length=%d from \n"),framelen);
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, pHdr->sa, subType, 0, psessionEntry);
+ goto error;
+ }
+
+ if ( palAllocateMemory(pMac->hHdd, (void **)&pAssocReq->assocReqFrame, framelen) != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("Unable to allocate memory for the assoc req, length=%d from \n"),framelen);
+ goto error;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAssocReq->assocReqFrame,
+ (tANI_U8 *) pBody, framelen);
+ pAssocReq->assocReqFrameLength = framelen;
+
+ if (cfgGetCapabilityInfo(pMac, &temp,psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve Capabilities\n"));
+ goto error;
+ }
+#if defined(ANI_PRODUCT_TYPE_AP) && defined(ANI_LITTLE_BYTE_ENDIAN)
+ *(tANI_U16*)&localCapabilities=(tANI_U16)(temp);
+#else
+ limCopyU16((tANI_U8 *) &localCapabilities, temp);
+#endif
+
+ if (limCompareCapabilities(pMac,
+ pAssocReq,
+ &localCapabilities,psessionEntry) == false)
+ {
+ /**
+ * Capabilities of requesting STA does not match with
+ * local capabilities. Respond with 'unsupported capabilities'
+ * status code.
+ */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOG1, FL("local caps 0x%x received 0x%x\n"), localCapabilities, pAssocReq->capabilityInfo);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOG1,
+ FL("received Assoc req with unsupported capabilities from\n"));
+ else
+ limLog(pMac, LOG1,
+ FL("received ReAssoc req with unsupported capabilities from\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ goto error;
+ }
+
+ updateContext = false;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // Check if multiple SSID feature is not enabled
+ if (psessionEntry->pLimStartBssReq->ssId.length)
+ {
+ if (limCmpSSid(pMac, &pAssocReq->ssId, psessionEntry) == false)
+ {
+ /*Temp hack for UPF35 - skip SSID check in order to be able to interop
+ with Marvel - they send their own SSID instead of ours*/
+ if ( 0 != vos_get_skip_ssid_check())
+ {
+ limLog(pMac, LOG1, FL("Received unmatched SSID but cfg to suppress - continuing\n"));
+ }
+ else
+ {
+ /**
+ * Received Re/Association Request with either
+ * Broadcast SSID OR with SSID that does not
+ * match with local one.
+ * Respond with unspecified status code.
+ */
+ limSendAssocRspMgmtFrame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW, FL("received Assoc req with unmatched SSID from \n"));
+ else
+ limLog(pMac, LOGW, FL("received ReAssoc req with unmatched SSID from \n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+ }
+ }
+ }
+ else
+ limLog(pMac, LOG1, FL("Suppressed SSID, App is going to check SSID\n"));
+#else
+ if (limCmpSSid(pMac, &pAssocReq->ssId, psessionEntry) == false)
+ {
+ /**
+ * Received Re/Association Request with either
+ * Broadcast SSID OR with SSID that does not
+ * match with local one.
+ * Respond with unspecified status code.
+ */
+ limSendAssocRspMgmtFrame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW,
+ FL("received Assoc req with unmatched SSID from \n"));
+ else
+ limLog(pMac, LOGW,
+ FL("received ReAssoc req with unmatched SSID from \n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+ }
+#endif
+
+ /***************************************************************
+ ** Verify if the requested rates are available in supported rate
+ ** set or Extended rate set. Some APs are adding basic rates in
+ ** Extended rateset IE
+ ***************************************************************/
+ basicRates.numRates = 0;
+
+ for(i = 0; i < pAssocReq->supportedRates.numRates; i++)
+ {
+ basicRates.rate[i] = pAssocReq->supportedRates.rate[i];
+ basicRates.numRates++;
+ }
+
+ for(j = 0; (j < pAssocReq->extendedRates.numRates) && (i < SIR_MAC_RATESET_EID_MAX); i++,j++)
+ {
+ basicRates.rate[i] = pAssocReq->extendedRates.rate[j];
+ basicRates.numRates++;
+ }
+ if (limCheckRxBasicRates(pMac, basicRates, psessionEntry) == false)
+ {
+ /**
+ * Requesting STA does not support ALL BSS basic
+ * rates. Respond with 'basic rates not supported'
+ * status code.
+ */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW,
+ FL("received Assoc req with unsupported rates from \n"));
+ else
+ limLog(pMac, LOGW,
+ FL("received ReAssoc req with unsupported rates from\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
+ ((!pAssocReq->extendedRatesPresent ) || (pAssocReq->HTCaps.present)))
+ {
+ limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1, pHdr->sa, subType, 0, psessionEntry );
+ limLog(pMac, LOGE, FL("SOFTAP was in 11G only mode, rejecting legacy STA's\n"));
+ goto error;
+
+ }//end if phyMode == 11G_only
+
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
+ (!pAssocReq->HTCaps.present))
+ {
+ limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1, pHdr->sa, subType, 0, psessionEntry );
+ limLog(pMac, LOGE, FL("SOFTAP was in 11N only mode, rejecting legacy STA's\n"));
+ goto error;
+ }//end if PhyMode == 11N_only
+
+#endif
+
+ /* Spectrum Management (11h) specific checks */
+ if (localCapabilities.spectrumMgt)
+ {
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ /* If station is 11h capable, then it SHOULD send all mandatory
+ * IEs in assoc request frame. Let us verify that
+ */
+ if (pAssocReq->capabilityInfo.spectrumMgt)
+ {
+ if (!((pAssocReq->powerCapabilityPresent) && (pAssocReq->supportedChannelsPresent)))
+ {
+ /* One or more required information elements are missing, log the peers error */
+ if (!pAssocReq->powerCapabilityPresent)
+ {
+ if(subType == LIM_ASSOC)
+ limLog(pMac, LOG1, FL("LIM Info: Missing Power capability IE in assoc request\n"));
+ else
+ limLog(pMac, LOG1, FL("LIM Info: Missing Power capability IE in Reassoc request\n"));
+ }
+ if (!pAssocReq->supportedChannelsPresent)
+ {
+ if(subType == LIM_ASSOC)
+ limLog(pMac, LOG1, FL("LIM Info: Missing Supported channel IE in assoc request\n"));
+ else
+ limLog(pMac, LOG1, FL("LIM Info: Missing Supported channel IE in Reassoc request\n"));
+ }
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ }
+ else
+ {
+ /* Assoc request has mandatory fields */
+ status = limIsDot11hPowerCapabilitiesInRange(pMac, pAssocReq, psessionEntry);
+ if (eSIR_SUCCESS != status)
+ {
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW, FL("LIM Info: Association MinTxPower(STA) > MaxTxPower(AP)\n"));
+ else
+ limLog(pMac, LOGW, FL("LIM Info: Reassociation MinTxPower(STA) > MaxTxPower(AP)\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ }
+ status = limIsDot11hSupportedChannelsValid(pMac, pAssocReq);
+ if (eSIR_SUCCESS != status)
+ {
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW, FL("LIM Info: Association wrong supported channels (STA)\n"));
+ else
+ limLog(pMac, LOGW, FL("LIM Info: Reassociation wrong supported channels (STA)\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ }
+ /* IEs are valid, use them if needed */
+ }
+ } //if(assoc.capabilityInfo.spectrumMgt)
+ else
+ {
+ /* As per the capabiities, the spectrum management is not enabled on the station
+ * The AP may allow the associations to happen even if spectrum management is not
+ * allowed, if the transmit power of station is below the regulatory maximum
+ */
+
+ /* TODO: presently, this is not handled. In the current implemetation, the AP would
+ * allow the station to associate even if it doesn't support spectrum management.
+ */
+ }
+ }// end of spectrum management related processing
+
+ if ( (pAssocReq->HTCaps.present) && (limCheckMCSSet(pMac, pAssocReq->HTCaps.supportedMCSSet) == false))
+ {
+ /**
+ * Requesting STA does not support ALL BSS MCS basic Rate set rates.
+ * Spec does not define any status code for this scenario.
+ */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOGW,
+ FL("received Assoc req with unsupported MCS Rate Set from \n"));
+ else
+ limLog(pMac, LOGW,
+ FL("received ReAssoc req with unsupported MCS Rate Set from\n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+ }
+
+ //if (pMac->dph.gDphPhyMode == WNI_CFG_PHY_MODE_11G)
+ if (phyMode == WNI_CFG_PHY_MODE_11G)
+ {
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_11G_ONLY_POLICY, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve 11g-only flag\n"));
+ goto error;
+ }
+
+ if (!pAssocReq->extendedRatesPresent && val)
+ {
+ /**
+ * Received Re/Association Request from
+ * 11b STA when 11g only policy option
+ * is set.
+ * Reject with unspecified status code.
+ */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from 11b STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+#ifdef WLAN_DEBUG
+ pMac->lim.gLim11bStaAssocRejectCount++;
+#endif
+ goto error;
+ }
+ }
+
+#ifdef WMM_APSD
+ // Save the QOS info element in assoc request..
+ limGetWmeMode(pMac, &wmeMode);
+ if (wmeMode == eHAL_SET)
+ {
+ tpQosInfoSta qInfo;
+
+ qInfo = (tpQosInfoSta) (pAssocReq->qosCapability.qosInfo);
+
+ if ((pMac->lim.gWmmApsd.apsdEnable == 0) && (qInfo->ac_be || qInfo->ac_bk || qInfo->ac_vo || qInfo->ac_vi))
+ {
+
+ /**
+ * Received Re/Association Request from
+ * 11b STA when 11g only policy option
+ * is set.
+ * Reject with unspecified status code.
+ */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_WME_REFUSED_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW,
+ FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ limLog(pMac, LOGE, FL("APSD not enabled, qosInfo - 0x%x\n"), *qInfo);
+ goto error;
+ }
+ }
+#endif
+
+ // Check for 802.11n HT caps compatibility; are HT Capabilities
+ // turned on in lim?
+ if ( psessionEntry->htCapabality )
+ {
+ // There are; are they turned on in the STA?
+ if ( pAssocReq->HTCaps.present )
+ {
+ // The station *does* support 802.11n HT capability...
+
+ limLog( pMac, LOG1, FL( "AdvCodingCap:%d ChaWidthSet:%d "
+ "PowerSave:%d greenField:%d "
+ "shortGI20:%d shortGI40:%d\n"
+ "txSTBC:%d rxSTBC:%d delayBA:%d"
+ "maxAMSDUsize:%d DSSS/CCK:%d "
+ "PSMP:%d stbcCntl:%d lsigTXProt:%d\n"),
+ pAssocReq->HTCaps.advCodingCap,
+ pAssocReq->HTCaps.supportedChannelWidthSet,
+ pAssocReq->HTCaps.mimoPowerSave,
+ pAssocReq->HTCaps.greenField,
+ pAssocReq->HTCaps.shortGI20MHz,
+ pAssocReq->HTCaps.shortGI40MHz,
+ pAssocReq->HTCaps.txSTBC,
+ pAssocReq->HTCaps.rxSTBC,
+ pAssocReq->HTCaps.delayedBA,
+ pAssocReq->HTCaps.maximalAMSDUsize,
+ pAssocReq->HTCaps.dsssCckMode40MHz,
+ pAssocReq->HTCaps.psmp,
+ pAssocReq->HTCaps.stbcControlFrame,
+ pAssocReq->HTCaps.lsigTXOPProtection );
+
+ // Make sure the STA's caps are compatible with our own:
+ //11.15.2 Support of DSSS/CCK in 40 MHz
+ //the AP shall refuse association requests from an HT STA that has the DSSS/CCK
+ //Mode in 40 MHz subfield set to 1;
+
+ //FIXME_BTAMP_AP : Need to be enabled
+ /*
+ if ( !pMac->lim.gHTDsssCckRate40MHzSupport && pAssocReq->HTCaps.dsssCckMode40MHz )
+ {
+ statusCode = eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS;
+ limLog( pMac, LOGW, FL( "AP DSSS/CCK is disabled; "
+ "STA rejected.\n" ) );
+ // Reject association
+ limSendAssocRspMgmtFrame( pMac, statusCode, 1, pHdr->sa, subType, 0,psessionEntry);
+ goto error;
+ }
+ */
+ }
+ } // End if on HT caps turned on in lim.
+
+#ifdef WLAN_SOFTAP_FEATURE
+ /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&Dot11fIERSN, sizeof( Dot11fIERSN ) );
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&Dot11fIEWPA, sizeof( Dot11fIEWPA ) );
+
+ /* if additional IE is present, check if it has WscIE */
+ if( pAssocReq->addIEPresent && pAssocReq->addIE.length )
+ wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
+ /* when wpsIe is present, RSN/WPA IE is ignored */
+ if( wpsIe == NULL )
+ {
+ /** check whether as RSN IE is present */
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE
+ && psessionEntry->pLimStartBssReq->privacy
+ && psessionEntry->pLimStartBssReq->rsnIE.length)
+ {
+ limLog(pMac, LOGE,
+ FL("AP supports RSN enabled authentication\n"));
+
+ if(pAssocReq->rsnPresent)
+ {
+ if(pAssocReq->rsn.length)
+ {
+ // Unpack the RSN IE
+ dot11fUnpackIeRSN(pMac,
+ &pAssocReq->rsn.info[0],
+ pAssocReq->rsn.length,
+ &Dot11fIERSN);
+
+ /* Check RSN version is supported or not */
+ if(SIR_MAC_OUI_VERSION_1 == Dot11fIERSN.version)
+ {
+ /* check the groupwise and pairwise cipher suites */
+ if(eSIR_SUCCESS != (status = limCheckRxRSNIeMatch(pMac, Dot11fIERSN, psessionEntry, pAssocReq->HTCaps.present) ) )
+ {
+ /* some IE is not properly sent */
+ /* received Association req frame with RSN IE but length is 0 */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ status,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+
+ }
+ }
+ else
+ {
+ /* received Association req frame with RSN IE version wrong */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+
+ }
+ }
+ else
+ {
+ /* received Association req frame with RSN IE but length is 0 */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+
+ }
+ } /* end - if(pAssocReq->rsnPresent) */
+ if((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent)
+ {
+ // Unpack the WPA IE
+ if(pAssocReq->wpa.length)
+ {
+ dot11fUnpackIeWPA(pMac,
+ &pAssocReq->wpa.info[4], //OUI is not taken care
+ pAssocReq->wpa.length,
+ &Dot11fIEWPA);
+ /* check the groupwise and pairwise cipher suites */
+ if(eSIR_SUCCESS != (status = limCheckRxWPAIeMatch(pMac, Dot11fIEWPA, psessionEntry, pAssocReq->HTCaps.present)))
+ {
+ /* received Association req frame with WPA IE but mismatch */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ status,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+
+ }
+ }
+ else
+ {
+ /* received Association req frame with invalid WPA IE */
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+
+ limLog(pMac, LOGW, FL("Rejecting Re/Assoc req from STA: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ goto error;
+ }/* end - if(pAssocReq->wpa.length) */
+ } /* end - if(pAssocReq->wpaPresent) */
+ } /* end of if(psessionEntry->pLimStartBssReq->privacy
+ && psessionEntry->pLimStartBssReq->rsnIE->length) */
+
+ } /* end of if( ! pAssocReq->wscInfo.present ) */
+#endif //WLAN_SOFTAP_FEATURE
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
+
+ /// Extract pre-auth context for the STA, if any.
+ pStaPreAuthContext = limSearchPreAuthList(pMac, pHdr->sa);
+
+ if (pStaDs == NULL)
+ {
+ /// Requesting STA is not currently associated
+ if (pMac->lim.gLimNumOfCurrentSTAs == pMac->lim.maxStation)
+ {
+ /**
+ * Maximum number of STAs that AP can handle reached.
+ * Send Association response to peer MAC entity
+ */
+ limRejectAssociation(pMac, pHdr->sa,
+ subType, false,
+ (tAniAuthType) 0, 0,
+ false,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ goto error;
+ }
+
+ /// Check if STA is pre-authenticated.
+ if ((pStaPreAuthContext == NULL) ||
+ (pStaPreAuthContext &&
+ (pStaPreAuthContext->mlmState !=
+ eLIM_MLM_AUTHENTICATED_STATE)))
+ {
+ /**
+ * STA is not pre-authenticated yet requesting
+ * Re/Association before Authentication.
+ * OR STA is in the process of getting authenticated
+ * and sent Re/Association request.
+ * Send Deauthentication frame with 'prior
+ * authentication required' reason code.
+ */
+ limSendDeauthMgmtFrame(
+ pMac,
+ eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, //=9
+ pHdr->sa,psessionEntry);
+
+ // Log error
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOG1,
+ FL("received Assoc req from STA that does not have pre-auth context, MAC addr is: \n"));
+ else
+ limLog(pMac, LOG1,
+ FL("received ReAssoc req from STA that does not have pre-auth context, MAC addr is: \n"));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ goto error;
+ }
+
+ /// Delete 'pre-auth' context of STA
+ authType = pStaPreAuthContext->authType;
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ // All is well. Assign AID (after else part)
+
+ } // if (pStaDs == NULL)
+ else
+ {
+ // STA context does exist for this STA
+
+ if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ /**
+ * Requesting STA is in some 'transient' state?
+ * Ignore the Re/Assoc Req frame by incrementing
+ * debug counter & logging error.
+ */
+ if (subType == LIM_ASSOC)
+ {
+
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropInvldState++;
+#endif
+ limLog(pMac, LOG1, FL("received Assoc req in state %X from "), pStaDs->mlmStaContext.mlmState);
+ }
+ else
+ {
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumReassocReqDropInvldState++;
+#endif
+ limLog(pMac, LOG1, FL("received ReAssoc req in state %X from "), pStaDs->mlmStaContext.mlmState);
+ }
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ limPrintMlmState(pMac, LOG1, (tLimMlmStates) pStaDs->mlmStaContext.mlmState);
+ goto error;
+ } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
+
+ /**
+ * STA sent Re/Association Request frame while already in
+ * 'associated' state. Update STA capabilities and
+ * send Association response frame with same AID
+ */
+
+ pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;
+
+ if (pStaPreAuthContext &&
+ (pStaPreAuthContext->mlmState ==
+ eLIM_MLM_AUTHENTICATED_STATE))
+ {
+ /// STA has triggered pre-auth again
+ authType = pStaPreAuthContext->authType;
+ limDeletePreAuthNode(pMac, pHdr->sa);
+ }
+ else
+ authType = pStaDs->mlmStaContext.authType;
+
+ updateContext = true;
+
+ if (dphInitStaState(pMac, pHdr->sa, aid, true, &psessionEntry->dph.dphHashTable) == NULL)
+ {
+ limLog(pMac, LOGE, FL("could not Init STAid=%d\n"), aid);
+ goto error;
+ }
+
+
+ goto sendIndToSme;
+ } // end if (lookup for STA in perStaDs fails)
+
+
+
+ // check if sta is allowed per QoS AC rules
+ //if (pMac->dph.gDphQosEnabled || pMac->dph.gDphWmeEnabled)
+ limGetWmeMode(psessionEntry, &wmeMode);
+ if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET))
+ {
+ // for a qsta, check if the requested Traffic spec
+ // is admissible
+ // for a non-qsta check if the sta can be admitted
+ if (pAssocReq->addtsPresent)
+ {
+ tANI_U8 tspecIdx = 0; //index in the sch tspec table.
+ if (limAdmitControlAddTS(pMac, pHdr->sa, &(pAssocReq->addtsReq),
+ &(pAssocReq->qosCapability), 0, false, NULL, &tspecIdx, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGW, FL("AdmitControl: TSPEC rejected\n"));
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropACRejectTS++;
+#endif
+ goto error;
+ }
+ }
+ else if (limAdmitControlAddSta(pMac, pHdr->sa, false)
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGW, FL("AdmitControl: Sta rejected\n"));
+ limSendAssocRspMgmtFrame(
+ pMac,
+ eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
+ 1,
+ pHdr->sa,
+ subType, 0,psessionEntry);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropACRejectSta++;
+#endif
+ goto error;
+ }
+
+ // else all ok
+ limLog(pMac, LOG1, FL("AdmitControl: Sta OK!\n"));
+ }
+
+ /**
+ * STA is Associated !
+ */
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOG1, FL("received Assoc req successful from "));
+ else
+ limLog(pMac, LOG1, FL("received ReAssoc req successful from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+
+ /**
+ * Assign unused/least recently used AID from perStaDs.
+ * This will 12-bit STAid used by MAC HW.
+ * NOTE: limAssignAID() assigns AID values ranging between 1 - 255
+ */
+
+ aid = limAssignAID(pMac);
+
+ if (!aid)
+ {
+ // Could not assign AID
+ // Reject association
+ limRejectAssociation(pMac, pHdr->sa,
+ subType, true, authType,
+ aid, false,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ goto error;
+ }
+
+ /**
+ * Add an entry to hash table maintained by DPH module
+ */
+
+ pStaDs = dphAddHashEntry(pMac, pHdr->sa, aid, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ // Could not add hash table entry at DPH
+ limLog(pMac, LOGE,
+ FL("could not add hash entry at DPH for aid=%d, MacAddr:\n"),
+ aid);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ // Release AID
+ limReleaseAID(pMac, aid);
+
+ limRejectAssociation(pMac, pHdr->sa,
+ subType, true, authType, aid, false,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ goto error;
+ }
+
+
+sendIndToSme:
+
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
+
+ pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present;
+ pStaDs->qos.addtsPresent = (pAssocReq->addtsPresent==0) ? false : true;
+ pStaDs->qos.addts = pAssocReq->addtsReq;
+ pStaDs->qos.capability = pAssocReq->qosCapability;
+ pStaDs->versionPresent = 0;
+ /* short slot and short preamble should be updated before doing limaddsta */
+ pStaDs->shortPreambleEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortPreamble;
+ pStaDs->shortSlotTimeEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortSlotTime;
+
+ if (pAssocReq->propIEinfo.versionPresent) //update STA version info
+ {
+ pStaDs->versionPresent = 1;
+ pStaDs->version = pAssocReq->propIEinfo.version;
+ }
+ pStaDs->propCapability = 0;
+ if (pAssocReq->propIEinfo.capabilityPresent)
+ {
+ if (sirGetCfgPropCaps(pMac, &pStaDs->propCapability))
+ pStaDs->propCapability &= pAssocReq->propIEinfo.capability;
+ }
+
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.authType = authType;
+ pStaDs->staType = STA_ENTRY_PEER;
+
+ //TODO: If listen interval is more than certain limit, reject the association.
+ //Need to check customer requirements and then implement.
+ pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval;
+ pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;
+
+ /* The following count will be used to knock-off the station if it doesn't
+ * come back to receive the buffered data. The AP will wait for numTimSent number
+ * of beacons after sending TIM information for the station, before assuming that
+ * the station is no more associated and disassociates it
+ */
+
+ /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
+ pStaDs->timWaitCount = (tANI_U8)GET_TIM_WAIT_COUNT(pAssocReq->listenInterval);
+
+ /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */
+ pStaDs->curTxMpduCnt = 0;
+
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ (pAssocReq->HTCaps.present))
+ {
+ pStaDs->htGreenfield = (tANI_U8)pAssocReq->HTCaps.greenField;
+ pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocReq->HTCaps.dsssCckMode40MHz;
+ pStaDs->htLsigTXOPProtection = (tANI_U8)pAssocReq->HTCaps.lsigTXOPProtection;
+ pStaDs->htMaxAmsduLength = (tANI_U8)pAssocReq->HTCaps.maximalAMSDUsize;
+ pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor;
+ pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave;
+ pStaDs->htShortGI20Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI20MHz;
+ pStaDs->htShortGI40Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI40MHz;
+ pStaDs->htSupportedChannelWidthSet = (tANI_U8)pAssocReq->HTCaps.supportedChannelWidthSet;
+ pStaDs->baPolicyFlag = 0xFF;
+ }
+
+
+
+ if (limPopulateMatchingRateSet(pMac,
+ pStaDs,
+ &(pAssocReq->supportedRates),
+ &(pAssocReq->extendedRates),
+ pAssocReq->HTCaps.supportedMCSSet,
+ &(pAssocReq->propIEinfo.propRates), psessionEntry) != eSIR_SUCCESS)
+ {
+ // Could not update hash table entry at DPH with rateset
+ limLog(pMac, LOGE,
+ FL("could not update hash entry at DPH for aid=%d, MacAddr:\n"),
+ aid);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ // Release AID
+ limReleaseAID(pMac, aid);
+
+
+ limRejectAssociation(pMac, pHdr->sa,
+ subType, true, authType, aid, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ /*return it from here rather than goto error statement.This is done as the memory is getting free twice*/
+ return;
+ //goto error;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pStaDs->mlmStaContext.propRateSet,
+ (tANI_U8 *) &(pAssocReq->propIEinfo.propRates),
+ pAssocReq->propIEinfo.propRates.numPropRates + 1);
+
+ /// Add STA context at MAC HW (BMU, RHP & TFP)
+
+ pStaDs->qosMode = eANI_BOOLEAN_FALSE;
+ pStaDs->lleEnabled = eANI_BOOLEAN_FALSE;
+ if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET))
+ {
+ pStaDs->lleEnabled = eANI_BOOLEAN_TRUE;
+ pStaDs->qosMode = eANI_BOOLEAN_TRUE;
+ }
+
+ pStaDs->wmeEnabled = eANI_BOOLEAN_FALSE;
+ pStaDs->wsmEnabled = eANI_BOOLEAN_FALSE;
+ limGetWmeMode(psessionEntry, &wmeMode);
+ //if ((! pStaDs->lleEnabled) && assoc.wmeInfoPresent && pMac->dph.gDphWmeEnabled)
+ if ((! pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent && (wmeMode == eHAL_SET))
+ {
+ pStaDs->wmeEnabled = eANI_BOOLEAN_TRUE;
+ pStaDs->qosMode = eANI_BOOLEAN_TRUE;
+ limGetWsmMode(psessionEntry, &wsmMode);
+ /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD
+ can coexist */
+#ifdef WLAN_SOFTAP_FEATURE
+ if( pAssocReq->WMMInfoStation.present)
+ {
+ /* check whether AP supports or not */
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ && (psessionEntry->apUapsdEnable == 0) && (pAssocReq->WMMInfoStation.acbe_uapsd
+ || pAssocReq->WMMInfoStation.acbk_uapsd
+ || pAssocReq->WMMInfoStation.acvo_uapsd
+ || pAssocReq->WMMInfoStation.acvi_uapsd))
+ {
+
+ /**
+ * Received Re/Association Request from
+ * STA when UPASD is not supported.
+ */
+ limLog( pMac, LOGE, FL( "AP do not support UPASD REASSOC Failed\n" ));
+ limRejectAssociation(pMac, pHdr->sa,
+ subType, true, authType, aid, true,
+ (tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry);
+
+
+ /*return it from here rather than goto error statement.This is done as the memory is getting free twice in this uapsd scenario*/
+ return;
+ //goto error;
+ }
+ else
+ {
+ /* update UAPSD and send it to LIM to add STA */
+ pStaDs->qos.capability.qosInfo.acbe_uapsd = pAssocReq->WMMInfoStation.acbe_uapsd;
+ pStaDs->qos.capability.qosInfo.acbk_uapsd = pAssocReq->WMMInfoStation.acbk_uapsd;
+ pStaDs->qos.capability.qosInfo.acvo_uapsd = pAssocReq->WMMInfoStation.acvo_uapsd;
+ pStaDs->qos.capability.qosInfo.acvi_uapsd = pAssocReq->WMMInfoStation.acvi_uapsd;
+ pStaDs->qos.capability.qosInfo.maxSpLen = pAssocReq->WMMInfoStation.max_sp_length;
+ }
+ }
+#endif
+ //if (assoc.wsmCapablePresent && pMac->dph.gDphWsmEnabled)
+ if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET))
+ pStaDs->wsmEnabled = eANI_BOOLEAN_TRUE;
+
+ }
+
+ // Re/Assoc Response frame to requesting STA
+ pStaDs->mlmStaContext.subType = subType;
+
+ if (pAssocReq->propIEinfo.aniIndicator)
+ pStaDs->aniPeer = 1;
+
+ // BTAMP: Storing the parsed assoc request in the psessionEntry array
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
+
+ /* BTAMP: If STA context already exist (ie. updateContext = 1)
+ * for this STA, then we should delete the old one, and add
+ * the new STA. This is taken care of in the limDelSta() routine.
+ *
+ * Prior to BTAMP, we were setting this flag so that when
+ * PE receives SME_ASSOC_CNF, and if this flag is set, then
+ * PE shall delete the old station and then add. But now in
+ * BTAMP, we're directly adding station before waiting for
+ * SME_ASSOC_CNF, so we can do this now.
+ */
+ if (!updateContext)
+ {
+ pStaDs->mlmStaContext.updateContext = 0;
+
+ // BTAMP: Add STA context at HW - issue WDA_ADD_STA_REQ to HAL
+ if (limAddSta(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("could not Add STA with assocId=%d\n"), pStaDs->assocId);
+ limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType, pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ /*return it from here rather than goto error statement.This is done as the memory is getting free twice*/
+ return;
+ //goto error;
+ }
+ }
+ else
+ {
+ pStaDs->mlmStaContext.updateContext = 1;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ mlmPrevState = pStaDs->mlmStaContext.mlmState;
+
+ /* As per the HAL/FW needs the reassoc req need not be calling limDelSta */
+ if(subType != LIM_REASSOC)
+ {
+ //we need to set the mlmState here in order differentiate in limDelSta.
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
+ if(limDelSta(pMac, pStaDs, true, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("could not DEL STA with assocId=%d staId %d\n"), pStaDs->assocId, pStaDs->staIndex);
+ limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ //Restoring the state back.
+ pStaDs->mlmStaContext.mlmState = mlmPrevState;
+ goto error;
+ }
+ }
+ else
+ {
+ /* mlmState is changed in limAddSta context */
+ /* use the same AID, already allocated */
+ if (limAddSta(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGE, FL( "AP do not support UPASD REASSOC Failed\n" ));
+ limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry);
+
+ //Restoring the state back.
+ pStaDs->mlmStaContext.mlmState = mlmPrevState;
+ goto error;
+ }
+
+ }
+#endif
+
+ }
+
+ return;
+
+error:
+ if (pAssocReq != NULL)
+ {
+ if ( pAssocReq->assocReqFrame )
+ {
+ palFreeMemory(pMac->hHdd, pAssocReq->assocReqFrame);
+ pAssocReq->assocReqFrame = NULL;
+ }
+
+ if (palFreeMemory(pMac->hHdd, pAssocReq) != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("PalFree Memory failed \n"));
+ return;
+ }
+ }
+
+ if(pStaDs!= NULL)
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
+ return;
+
+} /*** end limProcessAssocReqFrame() ***/
+
+
+
+/**---------------------------------------------------------------
+\fn limSendMlmAssocInd
+\brief This function sends either LIM_MLM_ASSOC_IND
+\ or LIM_MLM_REASSOC_IND to SME.
+\
+\param pMac
+\param *pStaDs - Station DPH hash entry
+\param psessionEntry - PE session entry
+\return None
+
+ * ?????? How do I get
+ * - subtype =====> psessionEntry->parsedAssocReq.reassocRequest
+ * - aid =====> pStaDs->assocId
+ * - pHdr->sa =====> pStaDs->staAddr
+ * - authType
+ * - pHdr->seqControl =====> no longer needed
+ * - pStaDs
+------------------------------------------------------------------*/
+void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+ tpLimMlmAssocInd pMlmAssocInd = NULL;
+ tpLimMlmReassocInd pMlmReassocInd;
+ tpSirAssocReq pAssocReq;
+ tANI_U16 temp;
+ tANI_U32 phyMode;
+ tANI_U8 subType;
+#ifdef WLAN_SOFTAP_FEATURE
+ tANI_U8 *wpsIe = NULL;
+#endif
+ tANI_U32 tmp;
+// tANI_U16 statusCode;
+ tANI_U16 i, j=0;
+
+ // Get a copy of the already parsed Assoc Request
+ pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId];
+
+ // Get the phyMode
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ // Extract pre-auth context for the peer BTAMP-STA, if any.
+
+ // Determiine if its Assoc or ReAssoc Request
+ if (pAssocReq->reassocRequest == 1)
+ subType = LIM_REASSOC;
+ else
+ subType = LIM_ASSOC;
+#ifdef WLAN_SOFTAP_FEATURE
+ if (subType == LIM_ASSOC || subType == LIM_REASSOC)
+#else
+ if (subType == LIM_ASSOC )
+#endif
+ {
+ temp = sizeof(tLimMlmAssocInd);
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ temp += pAssocReq->propIEinfo.numBss * sizeof(tSirNeighborBssInfo);
+#endif
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmAssocInd, temp))
+ {
+ limReleaseAID(pMac, pStaDs->assocId);
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for pMlmAssocInd\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, pMlmAssocInd, temp);
+
+ palCopyMemory( pMac->hHdd,(tANI_U8 *)pMlmAssocInd->peerMacAddr,(tANI_U8 *)pStaDs->staAddr,sizeof(tSirMacAddr));
+
+ pMlmAssocInd->aid = pStaDs->assocId;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)&pMlmAssocInd->ssId,(tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1);
+ pMlmAssocInd->sessionId = psessionEntry->peSessionId;
+ pMlmAssocInd->authType = pStaDs->mlmStaContext.authType;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // Note for BTAMP: no need to fill in pMlmAssocInd->seqNum
+ pMlmAssocInd->wniIndicator = (tAniBool) pAssocReq->propIEinfo.aniIndicator;
+ pMlmAssocInd->bpIndicator = (tAniBool) pAssocReq->propIEinfo.bpIndicator;
+ pMlmAssocInd->bpType = (tSirBpIndicatorType) pAssocReq->propIEinfo.bpType;
+ if (pAssocReq->extendedRatesPresent)
+ {
+ pMlmAssocInd->nwType = eSIR_11G_NW_TYPE;
+ limSetStaHashErpMode(pMac, pStaDs->assocId, eHAL_SET);
+ }
+ else
+ {
+ if (phyMode == WNI_CFG_PHY_MODE_11A)
+ pMlmAssocInd->nwType = eSIR_11A_NW_TYPE;
+ else
+ {
+ pMlmAssocInd->nwType = eSIR_11B_NW_TYPE;
+ limSetStaHashErpMode(pMac, pStaDs->assocId, eHAL_CLEAR);
+ }
+ }
+ pMlmAssocInd->assocType = (tSirAssocType)pAssocReq->propIEinfo.assocType;
+ pMlmAssocInd->load.numStas = pMac->lim.gLimNumOfCurrentSTAs;
+ pMlmAssocInd->load.channelUtilization =(pMac->lim.gpLimMeasData) ? pMac->lim.gpLimMeasData->avgChannelUtilization : 0;
+ pMlmAssocInd->numBss = (tANI_U32) pAssocReq->propIEinfo.numBss;
+ if (pAssocReq->propIEinfo.numBss)
+ {
+ palCopyMemory( pMac->hHdd,(tANI_U8 *) pMlmAssocInd->neighborList,(tANI_U8 *)pAssocReq->propIEinfo.pBssList,
+ (sizeof(tSirNeighborBssInfo) * pAssocReq->propIEinfo.numBss));
+ }
+#endif
+ pMlmAssocInd->capabilityInfo = pAssocReq->capabilityInfo;
+
+ // Fill in RSN IE information
+ pMlmAssocInd->rsnIE.length = 0;
+#ifdef WLAN_SOFTAP_FEATURE
+ // if WPS IE is present, ignore RSN IE
+ if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) {
+ wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
+ }
+ if (pAssocReq->rsnPresent && (NULL == wpsIe))
+#else
+ if (pAssocReq->rsnPresent)
+#endif
+ {
+ limLog(pMac, LOG2, FL("Assoc Req RSN IE len = %d\n"), pAssocReq->rsn.length);
+ pMlmAssocInd->rsnIE.length = 2 + pAssocReq->rsn.length;
+ pMlmAssocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
+ pMlmAssocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length;
+ palCopyMemory( pMac->hHdd,
+ &pMlmAssocInd->rsnIE.rsnIEdata[2],
+ pAssocReq->rsn.info,
+ pAssocReq->rsn.length);
+ }
+
+ //FIXME: we need to have the cb information seprated between HT and Titan later.
+ if(pAssocReq->HTCaps.present)
+ limGetHtCbAdminState(pMac, pAssocReq->HTCaps, &pMlmAssocInd->titanHtCaps);
+
+ // Fill in 802.11h related info
+ if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent)
+ {
+ pMlmAssocInd->spectrumMgtIndicator = eSIR_TRUE;
+ pMlmAssocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower;
+ pMlmAssocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower;
+ limConvertSupportedChannels(pMac, pMlmAssocInd, pAssocReq);
+ }
+ else
+ pMlmAssocInd->spectrumMgtIndicator = eSIR_FALSE;
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ /* This check is to avoid extra Sec IEs present incase of WPS */
+ if (pAssocReq->wpaPresent && (NULL == wpsIe))
+#else
+ if ((pAssocReq->wpaPresent) && (pMlmAssocInd->rsnIE.length < SIR_MAC_MAX_IE_LENGTH))
+#endif
+ {
+ if((pMlmAssocInd->rsnIE.length + pAssocReq->wpa.length) >= SIR_MAC_MAX_IE_LENGTH)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("rsnIEdata index out of bounds %d\n"), pMlmAssocInd->rsnIE.length);)
+ return;
+ }
+ pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length] = SIR_MAC_WPA_EID;
+ pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 1] = pAssocReq->wpa.length;
+ palCopyMemory( pMac->hHdd,
+ &pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 2],
+ pAssocReq->wpa.info,
+ pAssocReq->wpa.length);
+ pMlmAssocInd->rsnIE.length += 2 + pAssocReq->wpa.length;
+ }
+
+
+ pMlmAssocInd->addIE.length = 0;
+ if (pAssocReq->addIEPresent)
+ {
+ palCopyMemory( pMac->hHdd,
+ &pMlmAssocInd->addIE.addIEdata,
+ pAssocReq->addIE.addIEdata,
+ pAssocReq->addIE.length);
+
+ pMlmAssocInd->addIE.length = pAssocReq->addIE.length;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(pAssocReq->wmeInfoPresent)
+ {
+
+ if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d\n"), WNI_CFG_WME_ENABLED );
+
+ /* check whether AP is enabled with WMM */
+ if(tmp)
+ {
+ pMlmAssocInd->WmmStaInfoPresent = 1;
+ }
+ else
+ {
+ pMlmAssocInd->WmmStaInfoPresent= 0;
+ }
+ /* Note: we are not rejecting association here because IOT will fail */
+
+ }
+#endif
+
+ // Required for indicating the frames to upper layer
+ pMlmAssocInd->assocReqLength = pAssocReq->assocReqFrameLength;
+ pMlmAssocInd->assocReqPtr = pAssocReq->assocReqFrame;
+
+ pMlmAssocInd->beaconPtr = psessionEntry->beacon;
+ pMlmAssocInd->beaconLength = psessionEntry->bcnLen;
+
+ limPostSmeMessage(pMac, LIM_MLM_ASSOC_IND, (tANI_U32 *) pMlmAssocInd);
+ palFreeMemory( pMac->hHdd, pMlmAssocInd);
+ }
+ else
+ {
+ // If its of Reassociation Request, then post LIM_MLM_REASSOC_IND
+ temp = sizeof(tLimMlmReassocInd);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ temp += pAssocReq->propIEinfo.numBss * sizeof(tSirNeighborBssInfo);
+#endif
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmReassocInd, temp))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for pMlmReassocInd\n"));
+ limReleaseAID(pMac, pStaDs->assocId);
+ return;
+ }
+ palZeroMemory( pMac->hHdd, pMlmReassocInd, temp);
+
+ palCopyMemory( pMac->hHdd,(tANI_U8 *) pMlmReassocInd->peerMacAddr, (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr));
+ palCopyMemory( pMac->hHdd,(tANI_U8 *) pMlmReassocInd->currentApAddr, (tANI_U8 *)&(pAssocReq->currentApAddr), sizeof(tSirMacAddr));
+ pMlmReassocInd->aid = pStaDs->assocId;
+ pMlmReassocInd->authType = pStaDs->mlmStaContext.authType;
+ palCopyMemory( pMac->hHdd,(tANI_U8 *)&pMlmReassocInd->ssId, (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // Note for BTAMP: no need to fill in pMlmAssocInd->seqNum
+ pMlmReassocInd->wniIndicator = (tAniBool) pAssocReq->propIEinfo.aniIndicator;
+ pMlmReassocInd->bpIndicator = (tAniBool) pAssocReq->propIEinfo.bpIndicator;
+ pMlmReassocInd->bpType = (tSirBpIndicatorType) pAssocReq->propIEinfo.bpType;
+ if (pAssocReq->extendedRatesPresent)
+ {
+ pMlmReassocInd->nwType = eSIR_11G_NW_TYPE;
+ limSetStaHashErpMode(pMac, pStaDs->assocId, eHAL_SET);
+ }
+ else
+ {
+ if (phyMode == WNI_CFG_PHY_MODE_11A)
+ pMlmReassocInd->nwType = eSIR_11A_NW_TYPE;
+ else
+ {
+ pMlmReassocInd->nwType = eSIR_11B_NW_TYPE;
+ limSetStaHashErpMode(pMac, pStaDs->assocId, eHAL_CLEAR);
+ }
+ }
+
+ pMlmReassocInd->reassocType = (tSirAssocType)pAssocReq->propIEinfo.assocType;
+ pMlmReassocInd->load.numStas = pMac->lim.gLimNumOfCurrentSTAs;
+ pMlmReassocInd->load.channelUtilization = (pMac->lim.gpLimMeasData) ?
+ pMac->lim.gpLimMeasData->avgChannelUtilization : 0;
+ pMlmReassocInd->numBss = (tANI_U32) pAssocReq->propIEinfo.numBss;
+ if (pAssocReq->propIEinfo.numBss)
+ {
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pMlmReassocInd->neighborList,
+ (tANI_U8 *) pAssocReq->propIEinfo.pBssList,
+ (sizeof(tSirNeighborBssInfo) * pAssocReq->propIEinfo.numBss));
+ }
+#endif
+ if (pAssocReq->propIEinfo.aniIndicator)
+ pStaDs->aniPeer = 1;
+
+ pMlmReassocInd->capabilityInfo = pAssocReq->capabilityInfo;
+ pMlmReassocInd->rsnIE.length = 0;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if (pAssocReq->addIEPresent && pAssocReq->addIE.length )
+ wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length);
+
+ if (pAssocReq->rsnPresent && (NULL == wpsIe))
+#else
+ if (pAssocReq->rsnPresent)
+#endif
+ {
+ limLog(pMac, LOG2, FL("Assoc Req: RSN IE length = %d\n"), pAssocReq->rsn.length);
+ pMlmReassocInd->rsnIE.length = 2 + pAssocReq->rsn.length;
+ pMlmReassocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
+ pMlmReassocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length;
+ palCopyMemory( pMac->hHdd, &pMlmReassocInd->rsnIE.rsnIEdata[2], pAssocReq->rsn.info, pAssocReq->rsn.length);
+ }
+
+ if(pAssocReq->HTCaps.present)
+ limGetHtCbAdminState(pMac, pAssocReq->HTCaps, &pMlmReassocInd->titanHtCaps );
+
+ // 802.11h support
+ if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent)
+ {
+ pMlmReassocInd->spectrumMgtIndicator = eSIR_TRUE;
+ pMlmReassocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower;
+ pMlmReassocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower;
+ pMlmReassocInd->supportedChannels.numChnl = (tANI_U8)(pAssocReq->supportedChannels.length / 2);
+
+ limLog(pMac, LOG1,
+ FL("Sending Reassoc Ind: spectrum ON, minPwr %d, maxPwr %d, numChnl %d\n"),
+ pMlmReassocInd->powerCap.minTxPower,
+ pMlmReassocInd->powerCap.maxTxPower,
+ pMlmReassocInd->supportedChannels.numChnl);
+
+ for(i=0; i < pMlmReassocInd->supportedChannels.numChnl; i++)
+ {
+ pMlmReassocInd->supportedChannels.channelList[i] = pAssocReq->supportedChannels.supportedChannels[j];
+ limLog(pMac, LOG1, FL("Sending ReassocInd: chn[%d] = %d \n"),
+ i, pMlmReassocInd->supportedChannels.channelList[i]);
+ j+=2;
+ }
+ }
+ else
+ pMlmReassocInd->spectrumMgtIndicator = eSIR_FALSE;
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ /* This check is to avoid extra Sec IEs present incase of WPS */
+ if (pAssocReq->wpaPresent && (NULL == wpsIe))
+#else
+ if (pAssocReq->wpaPresent)
+#endif
+ {
+ limLog(pMac, LOG2, FL("Received WPA IE length in Assoc Req is %d\n"), pAssocReq->wpa.length);
+ pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length] = SIR_MAC_WPA_EID;
+ pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 1] = pAssocReq->wpa.length;
+ palCopyMemory( pMac->hHdd,
+ &pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 2],
+ pAssocReq->wpa.info,
+ pAssocReq->wpa.length);
+ pMlmReassocInd->rsnIE.length += 2 + pAssocReq->wpa.length;
+ }
+
+ pMlmReassocInd->addIE.length = 0;
+ if (pAssocReq->addIEPresent)
+ {
+ palCopyMemory( pMac->hHdd,
+ &pMlmReassocInd->addIE.addIEdata,
+ pAssocReq->addIE.addIEdata,
+ pAssocReq->addIE.length);
+
+ pMlmReassocInd->addIE.length = pAssocReq->addIE.length;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(pAssocReq->wmeInfoPresent)
+ {
+
+ if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d\n"), WNI_CFG_WME_ENABLED );
+
+ /* check whether AP is enabled with WMM */
+ if(tmp)
+ {
+ pMlmReassocInd->WmmStaInfoPresent = 1;
+ }
+ else
+ {
+ pMlmReassocInd->WmmStaInfoPresent = 0;
+ }
+ /* Note: we are not rejecting Re-association here because IOT will fail */
+
+ }
+#endif
+
+ // Required for indicating the frames to upper layer
+ pMlmReassocInd->assocReqLength = pAssocReq->assocReqFrameLength;
+ pMlmReassocInd->assocReqPtr = pAssocReq->assocReqFrame;
+
+ pMlmReassocInd->beaconPtr = psessionEntry->beacon;
+ pMlmReassocInd->beaconLength = psessionEntry->bcnLen;
+
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_IND, (tANI_U32 *) pMlmReassocInd);
+ palFreeMemory( pMac->hHdd, pMlmReassocInd);
+ }
+
+ return;
+
+} /*** end limSendMlmAssocInd() ***/
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
new file mode 100644
index 0000000..954ff1e
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
@@ -0,0 +1,786 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessAssocRspFrame.cc contains the code
+ * for processing Re/Association Response Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wniApi.h"
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#include "cfgApi.h"
+
+#include "utilsApi.h"
+#include "pmmApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limStaHashApi.h"
+#include "limSendMessages.h"
+
+#ifdef FEATURE_WLAN_CCX
+#include "ccxApi.h"
+#endif
+
+extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
+
+
+/**
+ * @function : limUpdateAssocStaDatas
+ *
+ * @brief : This function is called to Update the Station Descriptor (dph) Details from
+ * Association / ReAssociation Response Frame
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Station Descriptor in DPH
+ * @param pAssocRsp - Pointer to Association Response Structure
+ *
+ * @return None
+ */
+void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry)
+{
+ tANI_U32 prop;
+ tANI_U32 phyMode;
+ tANI_U32 val;
+ //tpSirBoardCapabilities pBoardCaps;
+ tANI_BOOLEAN qosMode;
+ tANI_U16 rxHighestRate = 0;
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ pStaDs->staType= STA_ENTRY_SELF;
+
+ limGetQosMode(psessionEntry, &qosMode);
+ // set the ani peer bit, if self mode is one of the proprietary modes
+ if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode))
+ {
+ wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, &prop);
+
+ if (prop)
+ {
+ pStaDs->aniPeer = eHAL_SET;
+ pStaDs->propCapability = pAssocRsp->propIEinfo.capability;
+ }
+ }
+
+ //pMac->lim.gLimMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ pStaDs->mlmStaContext.authType = psessionEntry->limCurrentAuthType;
+
+ // Add capabilities information, rates and AID
+ pStaDs->mlmStaContext.capabilityInfo = pAssocRsp->capabilityInfo;
+ pStaDs->shortPreambleEnabled= (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble;
+
+ //Update HT Capabilites only when the self mode supports HT
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
+ pStaDs->mlmStaContext.htCapability = pAssocRsp->HTCaps.present;
+
+ if ( pAssocRsp->HTCaps.present ) {
+ pStaDs->htGreenfield = ( tANI_U8 ) pAssocRsp->HTCaps.greenField;
+ pStaDs->htSupportedChannelWidthSet = ( tANI_U8 ) (pAssocRsp->HTCaps.supportedChannelWidthSet ?
+ pAssocRsp->HTInfo.recommendedTxWidthSet :
+ pAssocRsp->HTCaps.supportedChannelWidthSet );
+ pStaDs->htLsigTXOPProtection = ( tANI_U8 ) pAssocRsp->HTCaps.lsigTXOPProtection;
+ pStaDs->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave;
+ pStaDs->htMaxAmsduLength = ( tANI_U8 ) pAssocRsp->HTCaps.maximalAMSDUsize;
+ pStaDs->htAMpduDensity = pAssocRsp->HTCaps.mpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz;
+ pStaDs->htShortGI20Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
+ pStaDs->htShortGI40Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
+ pStaDs->htMaxRxAMpduFactor = pAssocRsp->HTCaps.maxRxAMPDUFactor;
+ limFillRxHighestSupportedRate(pMac, &rxHighestRate, pAssocRsp->HTCaps.supportedMCSSet);
+ pStaDs->supportedRates.rxHighestDataRate = rxHighestRate;
+
+ //FIXME_AMPDU
+ // In the future, may need to check for "assoc.HTCaps.delayedBA"
+ // For now, it is IMMEDIATE BA only on ALL TID's
+ pStaDs->baPolicyFlag = 0xFF;
+ }
+ }
+
+ if (limPopulateOwnRateSet(pMac, &pStaDs->supportedRates, pAssocRsp->HTCaps.supportedMCSSet, false,psessionEntry) != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("could not get rateset and extended rate set\n"));
+ return;
+ }
+
+ //If one of the rates is 11g rates, set the ERP mode.
+ if ((phyMode == WNI_CFG_PHY_MODE_11G) && sirIsArate(pStaDs->supportedRates.llaRates[0] & 0x7f))
+ pStaDs->erpEnabled = eHAL_SET;
+
+
+ val = WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pStaDs->mlmStaContext.propRateSet.propRate,
+ &val) != eSIR_SUCCESS) {
+ /// Could not get prop rateset from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve prop rateset\n"));
+ return;
+ }
+ pStaDs->mlmStaContext.propRateSet.numPropRates = (tANI_U8) val;
+
+ pStaDs->qosMode = 0;
+ pStaDs->lleEnabled = 0;
+
+ // update TSID to UP mapping
+ //if (pMac->lim.gLimQosEnabled)
+ if (qosMode) {
+ if (pAssocRsp->edcaPresent) {
+ tSirRetStatus status;
+ status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry);
+ PELOG2(limLog(pMac, LOG2, "Edca set update based on AssocRsp: status %d\n",
+ status);)
+ if (status != eSIR_SUCCESS) {
+ PELOGE(limLog(pMac, LOGE, FL("Edca error in AssocResp \n"));)
+ } else { // update default tidmap based on ACM
+ pStaDs->qosMode = 1;
+ pStaDs->lleEnabled = 1;
+ }
+ }
+ }
+
+ pStaDs->wmeEnabled = 0;
+ pStaDs->wsmEnabled = 0;
+ if (psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent)
+ {
+ tSirRetStatus status;
+ status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry);
+ PELOGW(limLog(pMac, LOGW, "WME Edca set update based on AssocRsp: status %d\n", status);)
+
+ if (status != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("WME Edca error in AssocResp - ignoring\n"));)
+ else { // update default tidmap based on HashACM
+ pStaDs->qosMode = 1;
+ pStaDs->wmeEnabled = 1;
+ }
+ }
+ else {
+ /* We received assoc rsp from a legacy AP. So fill in the default
+ * local EDCA params. This is needed (refer to bug #14989) as we'll
+ * be passing the gLimEdcaParams to HAL in limProcessStaMlmAddBssRsp().
+ */
+ schSetDefaultEdcaParams(pMac, psessionEntry);
+ }
+
+
+}
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+/**
+ * @function : limUpdateReAssocGlobals
+ *
+ * @brief : This function is called to Update the Globals (LIM) during ReAssoc.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAssocRsp - Pointer to Association Response Structure
+ *
+ * @return None
+ */
+
+void limUpdateReAssocGlobals(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry)
+{
+ /**
+ * Update the status for PMM module
+ */
+ pmmResetPmmState(pMac);
+
+ // Update the current Bss Information
+ palCopyMemory( pMac->hHdd, psessionEntry->bssId,
+ psessionEntry->limReAssocbssId, sizeof(tSirMacAddr));
+ psessionEntry->currentOperChannel = psessionEntry->limReassocChannelId;
+ psessionEntry->limCurrentBssCaps = psessionEntry->limReassocBssCaps;
+ psessionEntry->limCurrentBssQosCaps = psessionEntry->limReassocBssQosCaps;
+ psessionEntry->limCurrentBssPropCap = psessionEntry->limReassocBssPropCap;
+ psessionEntry->limCurrentTitanHtCaps = psessionEntry->limReassocTitanHtCaps;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &psessionEntry->ssId,
+ (tANI_U8 *) &psessionEntry->limReassocSSID,
+ psessionEntry->limReassocSSID.length+1);
+
+ // Store assigned AID for TIM processing
+ psessionEntry->limAID = pAssocRsp->aid & 0x3FFF;
+ /** Set the State Back to ReAssoc Rsp*/
+ psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+
+}
+#endif
+
+/**
+ * @function : limProcessAssocRspFrame
+ *
+ * @brief : This function is called by limProcessMessageQueue() upon
+ * Re/Association Response frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Rx packet info structure
+ * @param subType - Indicates whether it is Association Response (=0) or
+ * Reassociation Response (=1) frame
+ *
+ * @return None
+ */
+
+void
+limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 subType,tpPESession psessionEntry)
+{
+ tANI_U8 *pBody;
+ tANI_U16 caps;
+ tANI_U32 frameLen;
+ tSirMacAddr currentBssId;
+ tpSirMacMgmtHdr pHdr;
+ tSirMacCapabilityInfo localCapabilities;
+ tpDphHashNode pStaDs;
+ tpSirAssocRsp pAssocRsp;
+ tLimMlmAssocCnf mlmAssocCnf;
+
+ #ifdef ANI_PRODUCT_TYPE_CLIENT
+ tSchBeaconStruct beaconStruct;
+#endif
+
+ //Initialize status code to success.
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ mlmAssocCnf.resultCode = eSIR_SME_SUCCESS;
+ /* Update PE session Id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+
+
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE )
+ {
+ // Should not have received Re/Association Response
+ // frame on AP. Log error
+ limLog(pMac, LOGE,
+ FL("received Re/Assoc response frame on role %d \n"),
+ psessionEntry->limSystemRole);
+
+ return;
+ }
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if (((subType == LIM_ASSOC) &&
+ (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) ||
+ ((subType == LIM_REASSOC) &&
+ ((psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE)
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
+ && (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
+#endif
+ )))
+ {
+ /// Received unexpected Re/Association Response frame
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(limLog(pMac, LOG1, FL("mlm state is set to %d session=%d\n"),
+ psessionEntry->limMlmState, psessionEntry->peSessionId);)
+#endif
+ // Log error
+ if (!pHdr->fc.retry)
+ {
+ limLog(pMac, LOGE,
+ FL("received Re/Assoc rsp frame in unexpected state\n"));
+ limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
+ }
+
+ return;
+ }
+#if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ return;
+ }
+#endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ if (subType == LIM_ASSOC)
+ {
+ if (!palEqualMemory( pMac->hHdd,pHdr->sa, currentBssId, sizeof(tSirMacAddr)) )
+ {
+ /**
+ * Received Association Response frame from an entity
+ * other than one to which request was initiated.
+ * Ignore this and wait until Association Failure Timeout.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received AssocRsp frame from unexpected peer "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ }
+ else
+ {
+ if ( !palEqualMemory( pMac->hHdd,pHdr->sa, psessionEntry->limReAssocbssId, sizeof(tSirMacAddr)) )
+ {
+ /**
+ * Received Reassociation Response frame from an entity
+ * other than one to which request was initiated.
+ * Ignore this and wait until Reassociation Failure Timeout.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received ReassocRsp frame from unexpected peer "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ }
+
+ if ( palAllocateMemory(pMac->hHdd, (void **)&pAssocRsp, sizeof(*pAssocRsp)) != eHAL_STATUS_SUCCESS) {
+ limLog(pMac, LOGP, FL("Pal Allocate Memory failed in AssocRsp\n"));
+ return;
+ }
+
+ // Get pointer to Re/Association Response frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ // parse Re/Association Response frame.
+ if (sirConvertAssocRespFrame2Struct(
+ pMac, pBody, frameLen, pAssocRsp) == eSIR_FAILURE)
+ {
+ if (palFreeMemory(pMac->hHdd, pAssocRsp) != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("PalFree Memory failed \n"));
+ return;
+ }
+ PELOGE(limLog(pMac, LOGE, FL("Parse error Assoc resp subtype %d, length=%d\n"), frameLen,subType);)
+ return;
+ }
+
+ if(!pAssocRsp->suppRatesPresent)
+ {
+ PELOGE(limLog(pMac, LOGW, FL("assoc response does not have supported rate set"));)
+ palCopyMemory(pMac->hHdd, &pAssocRsp->supportedRates,
+ &psessionEntry->rateSet, sizeof(tSirMacRateSet));
+ }
+
+ mlmAssocCnf.protStatusCode = pAssocRsp->statusCode;
+
+ if( psessionEntry->assocRsp != NULL )
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->assocRsp);
+ psessionEntry->assocRsp = NULL;
+ }
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->assocRsp, frameLen)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response, len = %d"), frameLen);)
+ }
+ else
+ {
+ //Store the Assoc response. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->assocRsp, pBody, frameLen);
+ psessionEntry->assocRspLen = frameLen;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (psessionEntry->ricData != NULL)
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->ricData);
+ psessionEntry->ricData = NULL;
+ }
+ if(pAssocRsp->ricPresent)
+ {
+ psessionEntry->RICDataLen = pAssocRsp->num_RICData * sizeof(tDot11fIERICDataDesc);
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->ricData, psessionEntry->RICDataLen)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));)
+ psessionEntry->RICDataLen = 0;
+ }
+ else
+ {
+ palCopyMemory(pMac->hHdd, psessionEntry->ricData, &pAssocRsp->RICData[0], psessionEntry->RICDataLen);
+ }
+ }
+ else
+ {
+ psessionEntry->RICDataLen = 0;
+ psessionEntry->ricData = NULL;
+ }
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ if (psessionEntry->tspecIes != NULL)
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->tspecIes);
+ psessionEntry->tspecIes = NULL;
+ }
+ if(pAssocRsp->tspecPresent)
+ {
+ psessionEntry->tspecLen = pAssocRsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC);
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->tspecIes, psessionEntry->tspecLen)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));)
+ psessionEntry->tspecLen = 0;
+ }
+ else
+ {
+ palCopyMemory(pMac->hHdd, psessionEntry->tspecIes, &pAssocRsp->TSPECInfo[0], psessionEntry->tspecLen);
+ }
+ PELOG1(limLog(pMac, LOG1, FL(" Tspec EID present in assoc rsp "));)
+ }
+ else
+ {
+ psessionEntry->tspecLen = 0;
+ psessionEntry->tspecIes = NULL;
+ PELOG1(limLog(pMac, LOG1, FL(" Tspec EID *NOT* present in assoc rsp "));)
+ }
+#endif
+
+ if (pAssocRsp->capabilityInfo.ibss)
+ {
+ /**
+ * Received Re/Association Response from peer
+ * with IBSS capability set.
+ * Ignore the frame and wait until Re/assoc
+ * failure timeout.
+ */
+
+ // Log error
+ limLog(pMac, LOGE,
+ FL("received Re/AssocRsp frame with IBSS capability\n"));
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+ }
+
+ if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ limLog(pMac, LOGP, FL("could not retrieve Capabilities value\n"));
+ return;
+ }
+ limCopyU16((tANI_U8 *) &localCapabilities, caps);
+
+ if (subType == LIM_ASSOC) // Stop Association failure timer
+ limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
+ else // Stop Reassociation failure timer
+ limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS)
+ {
+ // Re/Association response was received
+ // either with failure code.
+ // Log error.
+ PELOGE(limLog(pMac, LOGE, FL("received Re/AssocRsp frame failure code %d\n"), pAssocRsp->statusCode);)
+ // Need to update 'association failure' error counter
+ // along with STATUS CODE
+
+ // Return Assoc confirm to SME with received failure code
+
+ if (pAssocRsp->propIEinfo.loadBalanceInfoPresent)
+ {
+ mlmAssocCnf.resultCode = eSIR_SME_TRANSFER_STA;
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimAlternateRadio.bssId,
+ pAssocRsp->propIEinfo.alternateRadio.bssId, sizeof(tSirMacAddr));
+ pMac->lim.gLimAlternateRadio.channelId =
+ pAssocRsp->propIEinfo.alternateRadio.channelId;
+ }else
+ mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+
+ // Delete Pre-auth context for the associated BSS
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ goto assocReject;
+ }
+ else if ((pAssocRsp->aid & 0x3FFF) > 2007)
+ {
+ // Re/Association response was received
+ // with invalid AID value
+ // Log error
+ PELOGW(limLog(pMac, LOGW, FL("received Re/AssocRsp frame with invalid aid %X \n"), pAssocRsp->aid);)
+ mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ // Send advisory Disassociation frame to AP
+ limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, pHdr->sa,psessionEntry);
+
+ goto assocReject;
+ }
+ // Association Response received with success code
+
+ if (subType == LIM_REASSOC)
+ {
+ // Log success
+ PELOG1(limLog(pMac, LOG1, FL("Successfully Reassociated with BSS\n"));)
+#ifdef FEATURE_WLAN_CCX
+ {
+ tANI_U8 cnt = 0;
+ if (pAssocRsp->tsmPresent)
+ {
+ limLog(pMac, LOGW, "TSM IE Present in Reassoc Rsp\n");
+ // Start the TSM timer only if the TSPEC Ie is present in the reassoc rsp
+ if (pAssocRsp->tspecPresent) {
+ // Find the TSPEC IE with VO user priority
+ for (cnt=0; cnt<pAssocRsp->num_tspecs; cnt++) {
+ if ( upToAc(pAssocRsp->TSPECInfo[cnt].user_priority) == EDCA_AC_VO) {
+ psessionEntry->ccxContext.tsm.tid = pAssocRsp->TSPECInfo[cnt].user_priority;
+ vos_mem_copy(&psessionEntry->ccxContext.tsm.tsmInfo,
+ &pAssocRsp->tsmIE, sizeof(tSirMacCCXTSMIE));
+ limActivateTSMStatsTimer(pMac, psessionEntry);
+ if(psessionEntry->ccxContext.tsm.tsmInfo.state) {
+ psessionEntry->ccxContext.tsm.tsmMetrics.RoamingCount++;
+ }
+ break;
+ }
+ }
+ } else {
+ limLog(pMac, LOGE, "TSM present but TSPEC IE not present in Reassoc Rsp\n");
+ }
+ }
+ }
+#endif
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ psessionEntry->limAssocResponseData = (void *) pAssocRsp; /** Store the ReAssocRsp Frame in DphTable to be used
+ during processing DelSta nd DelBss to send AddBss again*/
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+
+ if(!pStaDs)
+ {
+ PELOGE(limLog(pMac, LOG1, FL("could not get hash entry at DPH for \n"));)
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+ mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ // Send advisory Disassociation frame to AP
+ limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, pHdr->sa,psessionEntry);
+
+ goto assocReject;
+ }
+
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
+ if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
+ {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog(pMac, LOGE, FL("Sending self sta\n"));)
+#endif
+ pmmResetPmmState(pMac);
+
+ limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry);
+
+ // Store assigned AID for TIM processing
+ psessionEntry->limAID = pAssocRsp->aid & 0x3FFF;
+
+ limAddFTStaSelf(pMac, (pAssocRsp->aid & 0x3FFF), psessionEntry);
+
+ return;
+ }
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+ /* If we're re-associating to the same BSS, we don't want to invoke delete
+ * STA, delete BSS, as that would remove the already established TSPEC.
+ * Just go ahead and re-add the BSS, STA with new capability information.
+ * However, if we're re-associating to a different BSS, then follow thru
+ * with del STA, del BSS, add BSS, add STA.
+ */
+ if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId))
+ limHandleAddBssInReAssocContext(pMac, pStaDs, psessionEntry);
+ else
+ {
+ // reset the uapsd mask settings since we're re-associating to new AP
+ pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;
+ pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
+
+ if (limCleanupRxPath(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ goto assocReject;
+ }
+ return;
+ }
+
+ // Log success
+ PELOG1(limLog(pMac, LOG1, FL("Successfully Associated with BSS\n"));)
+#ifdef FEATURE_WLAN_CCX
+ if(psessionEntry->ccxContext.tsm.tsmInfo.state)
+ {
+ psessionEntry->ccxContext.tsm.tsmMetrics.RoamingCount = 0;
+ }
+#endif
+ /**
+ * Update the status for PMM module
+ */
+ pmmResetPmmState(pMac);
+
+ // Store assigned AID for TIM processing
+ psessionEntry->limAID = pAssocRsp->aid & 0x3FFF;
+
+
+ //STA entry was created during pre-assoc state.
+ if ((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL)
+ {
+ // Could not add hash table entry
+ PELOGE(limLog(pMac, LOGE, FL("could not get hash entry at DPH for \n"));)
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmAssocCnf.protStatusCode = eSIR_SME_SUCCESS;
+
+
+ limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF,
+ (tANI_U32 *) &mlmAssocCnf);
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+ }
+
+ // Delete Pre-auth context for the associated BSS
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry);
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ // Extract the AP capabilities from the beacon that was received earlier
+ // TODO - Watch out for an error response!
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields,
+ limGetIElenFromBssDescription( &psessionEntry->pLimJoinReq->bssDescription ),
+ &beaconStruct );
+
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideStaProtectionOnAssoc(pMac, &beaconStruct, psessionEntry);
+
+ if(beaconStruct.erpPresent) {
+ if (beaconStruct.erpIEInfo.barkerPreambleMode)
+ psessionEntry->beaconParams.fShortPreamble = false;
+ else
+ psessionEntry->beaconParams.fShortPreamble = true;
+ }
+
+
+ //Update the BSS Entry, this entry was added during preassoc.
+ if( eSIR_SUCCESS == limStaSendAddBss( pMac, pAssocRsp, &beaconStruct,
+ &psessionEntry->pLimJoinReq->bssDescription, true, psessionEntry))
+ {
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+ }
+ else
+ {
+ mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+
+#elif defined(ANI_AP_CLIENT_SDK)
+ if( eSIR_SUCCESS == limStaSendAddBss( pMac, *pAssocRsp,
+ &psessionEntry->pLimJoinReq->neighborBssList.bssList[0], true))
+ {
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+ }
+ else
+ {
+ mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+#else
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+#endif
+
+
+assocReject:
+ if ((subType == LIM_ASSOC)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ || ((subType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))
+#endif
+ ) {
+ PELOGE(limLog(pMac, LOGE, FL("Assoc Rejected by the peer. Reason: %d\n"), mlmAssocCnf.resultCode);)
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+ if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+ if (subType == LIM_ASSOC)
+ {
+ limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ else
+ {
+ mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
+ }
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+ } else {
+ limRestorePreReassocState( pMac,
+ eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry);
+ }
+
+ /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */
+ /* notify TL that association is failed so that TL can flush the cached frame */
+ WLANTL_AssocFailed (psessionEntry->staId);
+
+
+ palFreeMemory(pMac->hHdd, pAssocRsp);
+ return;
+} /*** end limProcessAssocRspFrame() ***/
+
diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
new file mode 100644
index 0000000..08fd818
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -0,0 +1,1742 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessAuthFrame.cc contains the code
+ * for processing received Authentication Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/12/2010 js To support Shared key authentication at AP side
+ *
+ */
+
+#include "wniApi.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#endif
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#include "cfgApi.h"
+
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "limFT.h"
+#endif
+#include "vos_utils.h"
+
+
+/**
+ * isAuthValid
+ *
+ *FUNCTION:
+ * This function is called by limProcessAuthFrame() upon Authentication
+ * frame reception.
+ *
+ *LOGIC:
+ * This function is used to test validity of auth frame:
+ * - AUTH1 and AUTH3 must be received in AP mode
+ * - AUTH2 and AUTH4 must be received in STA mode
+ * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to
+ * SIR_MAC_CHALLENGE_TEXT_EID by parser
+ * -
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param *auth - Pointer to extracted auth frame body
+ *
+ * @return 0 or 1 (Valid)
+ */
+
+
+static inline unsigned int isAuthValid(tpAniSirGlobal pMac, tpSirMacAuthFrameBody auth,tpPESession sessionEntry) {
+ unsigned int valid;
+ valid=1;
+
+ if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_1)||
+ (auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)) &&
+ ((sessionEntry->limSystemRole == eLIM_STA_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))
+ valid=0;
+
+ if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_2)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&&
+ ((sessionEntry->limSystemRole == eLIM_AP_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)))
+ valid=0;
+
+ if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&&
+ (auth->type!=SIR_MAC_CHALLENGE_TEXT_EID)&&(auth->authAlgoNumber != eSIR_SHARED_KEY))
+ valid=0;
+
+ return valid;
+}
+
+
+/**
+ * limProcessAuthFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon Authentication
+ * frame reception.
+ *
+ *LOGIC:
+ * This function processes received Authentication frame and responds
+ * with either next Authentication frame in sequence to peer MAC entity
+ * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * 1. Authentication failures are reported to SME with same status code
+ * received from the peer MAC entity.
+ * 2. Authentication frame2/4 received with alogirthm number other than
+ * one requested in frame1/3 are logged with an error and auth confirm
+ * will be sent to SME only after auth failure timeout.
+ * 3. Inconsistency in the spec:
+ * On receiving Auth frame2, specs says that if WEP key mapping key
+ * or default key is NULL, Auth frame3 with a status code 15 (challenge
+ * failure to be returned to peer entity. However, section 7.2.3.10,
+ * table 14 says that status code field is 'reserved' for frame3 !
+ * In the current implementation, Auth frame3 is returned with status
+ * code 15 overriding section 7.2.3.10.
+ * 4. If number pre-authentications reach configrable max limit,
+ * Authentication frame with 'unspecified failure' status code is
+ * returned to requesting entity.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Rx packet info structure
+ * @return None
+ */
+
+void
+limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
+{
+ tANI_U8 *pBody, keyId, cfgPrivacyOptImp,
+ defaultKey[SIR_MAC_KEY_LENGTH],
+ encrAuthFrame[LIM_ENCR_AUTH_BODY_LEN],
+ plainBody[256];
+ tANI_U16 frameLen;
+ //tANI_U32 authRspTimeout, maxNumPreAuth, val;
+ tANI_U32 maxNumPreAuth, val;
+ tSirMacAuthFrameBody *pRxAuthFrameBody, rxAuthFrame, authFrame;
+ tpSirMacMgmtHdr pHdr;
+ tCfgWepKeyEntry *pKeyMapEntry = NULL;
+ struct tLimPreAuthNode *pAuthNode;
+ tLimMlmAuthInd mlmAuthInd;
+ tANI_U8 decryptResult;
+ tANI_U8 *pChallenge;
+ tANI_U32 key_length=8;
+ tANI_U8 challengeTextArray[SIR_MAC_AUTH_CHALLENGE_LENGTH];
+#ifdef WLAN_SOFTAP_FEATURE
+ tpDphHashNode pStaDs = NULL;
+ tANI_U16 assocId = 0;
+#endif
+ /* Added For BT -AMP support */
+ // Get pointer to Authentication frame header and body
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+
+ if (!frameLen)
+ {
+ // Log error
+ limLog(pMac, LOGE,
+ FL("received Authentication frame with no body from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+
+ if (limIsGroupAddr(pHdr->sa))
+ {
+ // Received Auth frame from a BC/MC address
+ // Log error and ignore it
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame from a BC/MC address - "));)
+ PELOG1( limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, (tANI_U8*)pBd, ((tpHalBufDesc) pBd)->mpduDataOffset + frameLen);)
+
+
+
+ /// Determine if WEP bit is set in the FC or received MAC header
+ if (pHdr->fc.wep)
+ {
+ /**
+ * WEP bit is set in FC of MAC header.
+ */
+
+#ifdef WLAN_SOFTAP_FEATURE
+ // If TKIP counter measures enabled issue Deauth frame to station
+ if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+ PELOGE( limLog(pMac, LOGE,
+ FL("Tkip counter measures Enabled, sending Deauth frame to")); )
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ limSendDeauthMgmtFrame( pMac, eSIR_MAC_MIC_FAILURE_REASON,
+ pHdr->sa, psessionEntry );
+ return;
+ }
+#endif
+
+ // Extract key ID from IV (most 2 bits of 4th byte of IV)
+
+ keyId = (*(pBody + 3)) >> 6;
+
+ /**
+ * On STA in infrastructure BSS, Authentication frames received
+ * with WEP bit set in the FC must be rejected with challenge
+ * failure status code (wierd thing in the spec - this should have
+ * been rejected with unspecified failure or unexpected assertion
+ * of wep bit (this status code does not exist though) or
+ * Out-of-sequence-Authentication-Frame status code.
+ */
+
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)
+ {
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode = eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame with wep bit set on role=%d from "),
+ psessionEntry->limSystemRole );
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if (frameLen < LIM_ENCR_AUTH_BODY_LEN)
+ {
+ // Log error
+ limLog(pMac, LOGE,
+ FL("Not enough size [%d] to decrypt received Auth frame"),
+ frameLen);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ val = psessionEntry->privacy;
+ }
+ else
+#endif
+ // Accept Authentication frame only if Privacy is implemented
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve Privacy option\n"));
+ }
+
+ cfgPrivacyOptImp = (tANI_U8)val;
+ if (cfgPrivacyOptImp)
+ {
+ /**
+ * Privacy option is implemented.
+ * Check if the received frame is Authentication
+ * frame3 and there is a context for requesting STA.
+ * If not, reject with unspecified failure status code
+ */
+ pAuthNode = limSearchPreAuthList(pMac, pHdr->sa);
+
+ if (pAuthNode == NULL)
+ {
+ /**
+ * No 'pre-auth' context exists for this STA that sent
+ * an Authentication frame with FC bit set.
+ * Send Auth frame4 with 'out of sequence' status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame from peer that has no preauth context with WEP bit set. Addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ else
+ {
+ /// Change the auth-response timeout
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->authNodeIdx);
+
+ /// 'Pre-auth' status exists for STA
+ if ((pAuthNode->mlmState !=
+ eLIM_MLM_WT_AUTH_FRAME3_STATE) &&
+ (pAuthNode->mlmState !=
+ eLIM_MLM_AUTH_RSP_TIMEOUT_STATE))
+ {
+ /**
+ * Should not have received Authentication frame
+ * with WEP bit set in FC in other states.
+ * Reject by sending Authenticaton frame with
+ * out of sequence Auth frame status code.
+ */
+
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame from peer that is in state %d. Addr "),
+ pAuthNode->mlmState);)
+ PELOG1( limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ }
+
+ /**
+ * Check if there exists a key mappping key
+ * for the STA that sent Authentication frame
+ */
+ pKeyMapEntry = limLookUpKeyMappings(pHdr->sa);
+
+ if (pKeyMapEntry)
+ {
+ if (!pKeyMapEntry->wepOn)
+ {
+ /**
+ * Key Mapping entry has null key.
+ * Send Authentication frame
+ * with challenge failure status code
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame3 from peer that has NULL key map entry, Addr "));)
+ PELOG1( limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ } // if (!pKeyMapEntry->wepOn)
+ else
+ {
+ decryptResult = limDecryptAuthFrame(pMac, pKeyMapEntry->key,
+ pBody,
+ plainBody,
+ key_length,
+ (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH));
+ if (decryptResult == LIM_DECRYPT_ICV_FAIL)
+ {
+ /// ICV failure
+ PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == LIM_DECRYPT_ICV_FAIL ...\n"));)
+ limDeletePreAuthNode(pMac,
+ pHdr->sa);
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame from peer that failed decryption, Addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if ((sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, &rxAuthFrame)!=eSIR_SUCCESS)||(!isAuthValid(pMac, &rxAuthFrame,psessionEntry)))
+ return;
+
+
+ } // end if (pKeyMapEntry->key == NULL)
+ } // if keyMappings has entry
+ else
+ {
+
+ val = SIR_MAC_KEY_LENGTH;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ tpSirKeys pKey;
+ pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0];
+ palCopyMemory( pMac->hHdd, defaultKey, pKey->key, pKey->keyLength);
+ val = pKey->keyLength;
+ }
+ else
+#endif
+ if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId),
+ defaultKey, &val) != eSIR_SUCCESS)
+ {
+ /// Could not get Default key from CFG.
+ //Log error.
+ limLog(pMac, LOGP,
+ FL("could not retrieve Default key\n"));
+
+ /**
+ * Send Authentication frame
+ * with challenge failure status code
+ */
+
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ return;
+ }
+
+ key_length=val;
+
+ decryptResult = limDecryptAuthFrame(pMac, defaultKey,
+ pBody,
+ plainBody,
+ key_length,
+ (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH));
+ if (decryptResult == LIM_DECRYPT_ICV_FAIL)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == LIM_DECRYPT_ICV_FAIL ...\n"));)
+ /// ICV failure
+ limDeletePreAuthNode(pMac,
+ pHdr->sa);
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame from peer that failed decryption, Addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ if ((sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, &rxAuthFrame)!=eSIR_SUCCESS)||(!isAuthValid(pMac, &rxAuthFrame,psessionEntry)))
+ return;
+
+ } // End of check for Key Mapping/Default key presence
+ }
+ else
+ {
+ /**
+ * Privacy option is not implemented.
+ * So reject Authentication frame received with
+ * WEP bit set by sending Authentication frame
+ * with 'challenge failure' status code. This is
+ * another strange thing in the spec. Status code
+ * should have been 'unsupported algorithm' status code.
+ */
+
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame3 from peer that while privacy option is turned OFF, Addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
+ } // if (fc.wep)
+ else
+ {
+
+
+ if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame)!=eSIR_SUCCESS)||(!isAuthValid(pMac, &rxAuthFrame,psessionEntry)))
+ return;
+ }
+
+
+ pRxAuthFrameBody = &rxAuthFrame;
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)\n"),
+ (tANI_U32) pRxAuthFrameBody->authAlgoNumber,
+ (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber,
+ (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);)
+
+ switch (pRxAuthFrameBody->authTransactionSeqNumber)
+ {
+ case SIR_MAC_AUTH_FRAME_1:
+ // AuthFrame 1
+
+ /// Check if there exists pre-auth context for this STA
+ pAuthNode = limSearchPreAuthList(pMac, pHdr->sa);
+ if (pAuthNode)
+ {
+ /// Pre-auth context exists for the STA
+ if (pHdr->fc.retry == 0)
+ {
+ /**
+ * STA is initiating brand-new Authentication
+ * sequence after local Auth Response timeout.
+ * Or STA retrying to transmit First Auth frame due to packet drop OTA
+ * Delete Pre-auth node and fall through.
+ */
+ if(pAuthNode->fTimerStarted)
+ {
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->authNodeIdx);
+ }
+ PELOGE(limLog(pMac, LOGE, FL("STA is initiating brand-new Authentication ...\n"));)
+ limDeletePreAuthNode(pMac,
+ pHdr->sa);
+#ifdef WLAN_SOFTAP_FEATURE
+ /**
+ * SAP Mode:Disassociate the station and
+ * delete its entry if we have its entry
+ * already and received "auth" from the
+ * same station.
+ */
+
+ for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8
+ {
+ pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if (NULL == pStaDs)
+ continue;
+
+ if (pStaDs->valid)
+ {
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) &pStaDs->staAddr,
+ (tANI_U8 *) &(pHdr->sa), (tANI_U8) (sizeof(tSirMacAddr))) )
+ break;
+ }
+ }
+
+ if (NULL != pStaDs)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("lim Delete Station Context (staId: %d, assocId: %d) \n"),pStaDs->staIndex, assocId);)
+ limSendDeauthMgmtFrame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_REASON, (tANI_U8 *) pAuthNode->peerMacAddr,psessionEntry);
+ limTriggerSTAdeletion(pMac, pStaDs, psessionEntry);
+ return;
+ }
+#endif
+ }
+ else
+ {
+ /*
+ * This can happen when first authentication frame is received
+ * but ACK lost at STA side, in this case 2nd auth frame is already
+ * in transmission queue
+ * */
+ PELOGE(limLog(pMac, LOGE, FL("STA is initiating Authentication after ACK lost...\n"));)
+ return;
+ }
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
+ (tANI_U32 *) &maxNumPreAuth) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get MaxNumPreAuth
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve MaxNumPreAuth\n"));
+ }
+#ifdef ANI_AP_SDK_OPT
+ if(maxNumPreAuth > SIR_SDK_OPT_MAX_NUM_PRE_AUTH)
+ maxNumPreAuth = SIR_SDK_OPT_MAX_NUM_PRE_AUTH;
+#endif // ANI_AP_SDK_OPT
+ if (pMac->lim.gLimNumPreAuthContexts == maxNumPreAuth)
+ {
+ /**
+ * Maximum number of pre-auth contexts
+ * reached. Send Authentication frame
+ * with unspecified failure
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ return;
+ }
+ /// No Pre-auth context exists for the STA.
+#ifdef WLAN_SOFTAP_FEATURE
+ if (limIsAuthAlgoSupported(
+ pMac,
+ (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber, psessionEntry))
+#else
+ if (limIsAuthAlgoSupported(
+ pMac,
+ (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber))
+
+#endif
+ {
+ switch (pRxAuthFrameBody->authAlgoNumber)
+ {
+ case eSIR_OPEN_SYSTEM:
+ PELOG1(limLog(pMac, LOG1, FL("=======> eSIR_OPEN_SYSTEM ...\n"));)
+ /// Create entry for this STA in pre-auth list
+ pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
+ if (pAuthNode == NULL)
+ {
+ // Log error
+ limLog(pMac, LOGW,
+ FL("Max pre-auth nodes reached "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer \n"), pAuthNode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pAuthNode->peerMacAddr,
+ pHdr->sa,
+ sizeof(tSirMacAddr));
+
+ pAuthNode->mlmState =
+ eLIM_MLM_AUTHENTICATED_STATE;
+ pAuthNode->authType = (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ pAuthNode->fSeen = 0;
+ pAuthNode->fTimerStarted = 0;
+ limAddPreAuthNode(pMac, pAuthNode);
+
+ /**
+ * Send Authenticaton frame with Success
+ * status code.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ /// Send Auth indication to SME
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) mlmAuthInd.peerMacAddr,
+ (tANI_U8 *) pHdr->sa,
+ sizeof(tSirMacAddr));
+ mlmAuthInd.authType = (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ mlmAuthInd.sessionId = psessionEntry->smeSessionId;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_AUTH_IND,
+ (tANI_U32 *) &mlmAuthInd);
+ break;
+
+ case eSIR_SHARED_KEY:
+ PELOG1(limLog(pMac, LOG1, FL("=======> eSIR_SHARED_KEY ...\n"));)
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ val = psessionEntry->privacy;
+ }
+ else
+#endif
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Privacy option\n"));
+ }
+ cfgPrivacyOptImp = (tANI_U8)val;
+ if (!cfgPrivacyOptImp)
+ {
+ /**
+ * Authenticator does not have WEP
+ * implemented.
+ * Reject by sending Authentication frame
+ * with Auth algorithm not supported status
+ * code.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame for unsupported auth algorithm %d from "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+ else
+ {
+ // Create entry for this STA
+ //in pre-auth list
+ pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
+ if (pAuthNode == NULL)
+ {
+ // Log error
+ limLog(pMac, LOGW,
+ FL("Max pre-auth nodes reached "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pAuthNode->peerMacAddr,
+ pHdr->sa,
+ sizeof(tSirMacAddr));
+
+ pAuthNode->mlmState =
+ eLIM_MLM_WT_AUTH_FRAME3_STATE;
+ pAuthNode->authType =
+ (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ pAuthNode->fSeen = 0;
+ pAuthNode->fTimerStarted = 0;
+ limAddPreAuthNode(pMac, pAuthNode);
+
+ PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x id %d peer \n"),
+ pAuthNode, pAuthNode->authNodeIdx);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ /// Create and activate Auth Response timer
+ if (tx_timer_change_context(&pAuthNode->timer, pAuthNode->authNodeIdx) != TX_SUCCESS)
+ {
+ /// Could not start Auth response timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to chg context auth response timer for peer "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGP);
+
+ /**
+ * Send Authenticaton frame with
+ * unspecified failure status code.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ limDeletePreAuthNode(pMac, pHdr->sa);
+ return;
+ }
+
+ limActivateAuthRspTimer(pMac, pAuthNode);
+
+ pAuthNode->fTimerStarted = 1;
+
+ // get random bytes and use as
+ // challenge text
+ // TODO
+ //if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH ) ) )
+ {
+ limLog(pMac, LOGE,FL("Challenge text preparation failed in limProcessAuthFrame"));
+ }
+
+ pChallenge = pAuthNode->challengeText;
+
+ palCopyMemory( pMac->hHdd,
+ pChallenge,
+ (tANI_U8 *) challengeTextArray,
+ sizeof(challengeTextArray));
+
+ /**
+ * Sending Authenticaton frame with challenge.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_SUCCESS_STATUS;
+ authFrame.type = SIR_MAC_CHALLENGE_TEXT_EID;
+ authFrame.length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ palCopyMemory( pMac->hHdd,
+ authFrame.challengeText,
+ pAuthNode->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+ } // if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
+
+ break;
+
+ default:
+ /**
+ * Responding party does not support the
+ * authentication algorithm requested by
+ * sending party.
+ * Reject by sending Authentication frame
+ * with auth algorithm not supported status code
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1( limLog(pMac, LOG1,
+ FL("received Auth frame for unsupported auth algorithm %d from "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ } // end switch(pRxAuthFrameBody->authAlgoNumber)
+ } // if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber))
+ else
+ {
+ /**
+ * Responding party does not support the
+ * authentication algorithm requested by sending party.
+ * Reject Authentication with StatusCode=13.
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame for unsupported auth algorithm %d from "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ return;
+ } //end if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber))
+ break;
+
+ case SIR_MAC_AUTH_FRAME_2:
+ // AuthFrame 2
+
+ if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE)
+ {
+ /**
+ * Received Authentication frame2 in an unexpected state.
+ * Log error and ignore the frame.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame2 from peer in state %d, addr "),
+ psessionEntry->limMlmState);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if ( !palEqualMemory( pMac->hHdd,(tANI_U8 *) pHdr->sa,
+ (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ {
+ /**
+ * Received Authentication frame from an entity
+ * other than one request was initiated.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame2 from unexpected peer "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode ==
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS)
+ {
+ /**
+ * Interoperability workaround: Linksys WAP4400N is returning
+ * wrong authType in OpenAuth response in case of
+ * SharedKey AP configuration. Pretend we don't see that,
+ * so upper layer can fallback to SharedKey authType,
+ * and successfully connect to the AP.
+ */
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType)
+ {
+ pRxAuthFrameBody->authAlgoNumber =
+ pMac->lim.gpLimMlmAuthReq->authType;
+ }
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType)
+ {
+ /**
+ * Received Authentication frame with an auth
+ * algorithm other than one requested.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame2 for unexpected auth algo number %d from "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1( limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode ==
+ eSIR_MAC_SUCCESS_STATUS)
+ {
+ if (pRxAuthFrameBody->authAlgoNumber ==
+ eSIR_OPEN_SYSTEM)
+ {
+ psessionEntry->limCurrentAuthType = eSIR_OPEN_SYSTEM;
+
+ pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
+
+ if (pAuthNode == NULL)
+ {
+ // Log error
+ limLog(pMac, LOGW,
+ FL("Max pre-auth nodes reached "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer \n"), pAuthNode);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pAuthNode->peerMacAddr,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
+ limAddPreAuthNode(pMac, pAuthNode);
+
+ limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS,
+ pRxAuthFrameBody->authStatusCode,psessionEntry);
+ } // if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM)
+ else
+ {
+ // Shared key authentication
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ val = psessionEntry->privacy;
+ }
+ else
+#endif
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Privacy option\n"));
+ }
+ cfgPrivacyOptImp = (tANI_U8)val;
+ if (!cfgPrivacyOptImp)
+ {
+ /**
+ * Requesting STA does not have WEP implemented.
+ * Reject with unsupported authentication algorithm
+ * Status code and wait until auth failure timeout
+ */
+
+ // Log error
+ PELOG1( limLog(pMac, LOG1,
+ FL("received Auth frame from peer for unsupported auth algo %d, Addr "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+ return;
+ }
+ else
+ {
+
+ if (pRxAuthFrameBody->type !=
+ SIR_MAC_CHALLENGE_TEXT_EID)
+ {
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame with invalid challenge text IE\n"));)
+
+ return;
+ }
+
+ /**
+ * Check if there exists a key mappping key
+ * for the STA that sent Authentication frame
+ */
+ pKeyMapEntry = limLookUpKeyMappings(
+ pHdr->sa);
+
+ if (pKeyMapEntry)
+ {
+ if (pKeyMapEntry->key == NULL)
+ {
+ /**
+ * Key Mapping entry has null key.
+ * Send Auth frame with
+ * challenge failure status code
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame from peer when key mapping key is NULL, addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ limRestoreFromAuthState(pMac, eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+
+ return;
+ } // if (pKeyMapEntry->key == NULL)
+ else
+ {
+ ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber =
+ sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber);
+ ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber =
+ sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
+ ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+ ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID;
+ ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
+ pRxAuthFrameBody->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+
+ limEncryptAuthFrame(pMac, 0,
+ pKeyMapEntry->key,
+ plainBody,
+ encrAuthFrame,key_length);
+
+ psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ limSendAuthMgmtFrame(pMac,
+ (tpSirMacAuthFrameBody) encrAuthFrame,
+ pHdr->sa,
+ LIM_WEP_IN_FC,psessionEntry);
+
+ break;
+ } // end if (pKeyMapEntry->key == NULL)
+ } // if (pKeyMapEntry)
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Default keyId
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Default keyId\n"));
+ }
+ keyId = (tANI_U8)val;
+
+ val = SIR_MAC_KEY_LENGTH;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ tpSirKeys pKey;
+ pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0];
+ palCopyMemory( pMac->hHdd, defaultKey, pKey->key, pKey->keyLength);
+ }
+ else
+#endif
+ if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId),
+ defaultKey,
+ &val)
+ != eSIR_SUCCESS)
+ {
+ /// Could not get Default key from CFG.
+ //Log error.
+ limLog(pMac, LOGP,
+ FL("could not retrieve Default key\n"));
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ limRestoreFromAuthState(pMac, eSIR_SME_INVALID_WEP_DEFAULT_KEY,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+
+ break;
+ }
+ key_length=val;
+ ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber =
+ sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber);
+ ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber =
+ sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1));
+ ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+ ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID;
+ ((tpSirMacAuthFrameBody) plainBody)->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
+ pRxAuthFrameBody->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+
+ limEncryptAuthFrame(pMac, keyId,
+ defaultKey,
+ plainBody,
+ encrAuthFrame,key_length);
+
+ psessionEntry->limMlmState =
+ eLIM_MLM_WT_AUTH_FRAME4_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ limSendAuthMgmtFrame(pMac,
+ (tpSirMacAuthFrameBody) encrAuthFrame,
+ pHdr->sa,
+ LIM_WEP_IN_FC,psessionEntry);
+
+ break;
+ } // end if (pKeyMapEntry)
+ } // end if (!wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED))
+ } // end if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM)
+ } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)
+ else
+ {
+ /**
+ * Authentication failure.
+ * Return Auth confirm with received failure code to SME
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame from peer with failure code %d addr "),
+ pRxAuthFrameBody->authStatusCode);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED,
+ pRxAuthFrameBody->authStatusCode,psessionEntry);
+ } // end if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_3:
+ // AuthFrame 3
+
+ if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY)
+ {
+ /**
+ * Received Authentication frame3 with algorithm other than
+ * Shared Key authentication type. Reject with Auth frame4
+ * with 'out of sequence' status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame3 from peer with auth algo number %d Addr "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE ||
+ psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ {
+ /**
+ * Check if wep bit was set in FC. If not set,
+ * reject with Authentication frame4 with
+ * 'challenge failure' status code.
+ */
+ if (!pHdr->fc.wep)
+ {
+ /// WEP bit is not set in FC of Auth Frame3
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame3 from peer with no WEP bit set, addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ pAuthNode = limSearchPreAuthList(pMac,
+ pHdr->sa);
+ if (pAuthNode == NULL)
+ {
+ /**
+ * No 'pre-auth' context exists for
+ * this STA that sent an Authentication
+ * frame3.
+ * Send Auth frame4 with 'out of sequence'
+ * status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received AuthFrame3 from peer that has no preauth context. Addr "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if (pAuthNode->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)
+ {
+ /**
+ * Received Auth Frame3 after Auth Response timeout.
+ * Reject by sending Auth Frame4 with
+ * Auth respone timeout Status Code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS;
+
+ limSendAuthMgmtFrame(
+ pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ limLog(pMac, LOGW,
+ FL("auth response timer timedout for peer "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+ /// Delete pre-auth context of STA
+ limDeletePreAuthNode(pMac,
+ pHdr->sa);
+
+ return;
+ } // end switch (pAuthNode->mlmState)
+
+ if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS)
+ {
+ /**
+ * Received Authenetication Frame 3 with status code
+ * other than success. Wait until Auth response timeout
+ * to delete STA context.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame3 from peer with status code %d, addr "),
+ pRxAuthFrameBody->authStatusCode);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ /**
+ * Check if received challenge text is same as one sent in
+ * Authentication frame3
+ */
+
+ if (palEqualMemory( pMac->hHdd,pRxAuthFrameBody->challengeText,
+ pAuthNode->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH))
+ {
+ /// Challenge match. STA is autheticated !
+
+ /// Delete Authentication response timer if running
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->authNodeIdx);
+
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+
+ /**
+ * Send Authentication Frame4 with 'success' Status Code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode = eSIR_MAC_SUCCESS_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ /// Send Auth indication to SME
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) mlmAuthInd.peerMacAddr,
+ (tANI_U8 *) pHdr->sa,
+ sizeof(tSirMacAddr));
+ mlmAuthInd.authType = (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ mlmAuthInd.sessionId = psessionEntry->smeSessionId;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_AUTH_IND,
+ (tANI_U32 *) &mlmAuthInd);
+
+ break;
+ }
+ else
+ {
+ /**
+ * Challenge Failure.
+ * Send Authentication frame4 with 'challenge failure'
+ * status code and wait until Auth response timeout to
+ * delete STA context.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ limSendAuthMgmtFrame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ // Log error
+ PELOG1( limLog(pMac, LOG1,
+ FL("Challenge failure for peer "));)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ return;
+ }
+ } // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE || ...
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_4:
+ // AuthFrame 4
+ if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE)
+ {
+ /**
+ * Received Authentication frame4 in an unexpected state.
+ * Log error and ignore the frame.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received unexpected Auth frame4 from peer in state %d, addr "),
+ psessionEntry->limMlmState);)
+ PELOG1( limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY)
+ {
+ /**
+ * Received Authentication frame4 with algorithm other than
+ * Shared Key authentication type.
+ * Wait until Auth failure timeout to report authentication
+ * failure to SME.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame4 from peer with invalid auth algo %d, addr "),
+ pRxAuthFrameBody->authAlgoNumber);)
+ PELOG1(limPrintMacAddr(pMac, pHdr->sa,
+ LOG1);)
+
+ return;
+ }
+
+ if ( !palEqualMemory( pMac->hHdd,(tANI_U8 *) pHdr->sa,
+ (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ {
+ /**
+ * Received Authentication frame from an entity
+ * other than one to which request was initiated.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame4 from unexpected peer "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType)
+ {
+ /**
+ * Received Authentication frame with an auth algorithm
+ * other than one requested.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Authentication frame from peer with invalid auth seq number %d, addr "),
+ pRxAuthFrameBody->authTransactionSeqNumber);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode ==
+ eSIR_MAC_SUCCESS_STATUS)
+ {
+ /**
+ * Authentication Success !
+ * Inform SME of same.
+ */
+ psessionEntry->limCurrentAuthType = eSIR_SHARED_KEY;
+
+ pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable);
+ if (pAuthNode == NULL)
+ {
+ // Log error
+ limLog(pMac, LOGW,
+ FL("Max pre-auth nodes reached "));
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+ PELOG1(limLog(pMac, LOG1, FL("Alloc new data: %x peer \n"), pAuthNode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pAuthNode->peerMacAddr,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType;
+ limAddPreAuthNode(pMac, pAuthNode);
+
+ limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS,
+ pRxAuthFrameBody->authStatusCode,psessionEntry);
+
+ } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS)
+ else
+ {
+ /**
+ * Authentication failure.
+ * Return Auth confirm with received failure code to SME
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1, FL("Authentication failure from peer "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED,
+ pRxAuthFrameBody->authStatusCode,psessionEntry);
+ } // end if (pRxAuthFrameBody->Status == 0)
+
+ break;
+
+ default:
+ /// Invalid Authentication Frame received. Ignore it.
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Auth frame from peer with invalid auth seq number %d, addr "),
+ pRxAuthFrameBody->authTransactionSeqNumber);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ } // end switch (pRxAuthFrameBody->authTransactionSeqNumber)
+} /*** end limProcessAuthFrame() ***/
+
+
+
+
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+
+/*----------------------------------------------------------------------
+ *
+ * Pass the received Auth frame. This is possibly the pre-auth from the
+ * neighbor AP, in the same mobility domain.
+ * This will be used in case of 11r FT.
+ *
+ * !!!! This is going to be renoved for the next checkin. We will be creating
+ * the session before sending out the Auth. Thus when auth response
+ * is received we will have a session in progress. !!!!!
+ *----------------------------------------------------------------------
+ */
+int limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, void *body)
+{
+ tpSirMacMgmtHdr pHdr;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 *pBody;
+ tANI_U16 frameLen;
+ tSirMacAuthFrameBody rxAuthFrame;
+ tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
+ int ret_status = eSIR_FAILURE;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pBd);
+ pBody = WDA_GET_RX_MPDU_DATA(pBd);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
+
+ // Check for the operating channel and see what needs to be done next.
+ psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry;
+ if (psessionEntry == NULL)
+ {
+ limLog(pMac, LOGW, FL("Error: Unable to find session id while in pre-auth phase for FT"));
+ return eSIR_FAILURE;
+ }
+
+ if (pMac->ft.ftPEContext.pFTPreAuthReq == NULL)
+ {
+ // No FT in progress.
+ return eSIR_FAILURE;
+ }
+
+ if (frameLen == 0)
+ {
+ return eSIR_FAILURE;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limPrintMacAddr(pMac, pHdr->bssId, LOGE);
+ limPrintMacAddr(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+#endif
+
+ // Check that its the same bssId we have for preAuth
+ if (!palEqualMemory( pMac->hHdd, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
+ pHdr->bssId, sizeof( tSirMacAddr )))
+ {
+ // In this case SME if indeed has triggered a
+ // pre auth it will time out.
+ return eSIR_FAILURE;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog(pMac, LOGE, FL("Pre-Auth response received from neighbor"));
+ limLog(pMac, LOGE, FL("Pre-Auth done state"));
+#endif
+ // Stopping timer now, that we have our unicast from the AP
+ // of our choice.
+ limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+
+ // Save off the auth resp.
+ if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS))
+ {
+ limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
+ return eSIR_FAILURE;
+ }
+ pRxAuthFrameBody = &rxAuthFrame;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog(pMac, LOGE,
+ FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)\n"),
+ (tANI_U32) pRxAuthFrameBody->authAlgoNumber,
+ (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber,
+ (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);)
+#endif
+
+ switch (pRxAuthFrameBody->authTransactionSeqNumber)
+ {
+ case SIR_MAC_AUTH_FRAME_2:
+ if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS)
+ {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Auth status code received is %d\n",
+ (tANI_U32) pRxAuthFrameBody->authStatusCode);)
+#endif
+ }
+ else
+ {
+ ret_status = eSIR_SUCCESS;
+ }
+ break;
+
+ default:
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Seq. no incorrect expected 2 received %d\n",
+ (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber);)
+#endif
+ break;
+ }
+
+ // Send the Auth response to SME
+ limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry);
+
+ return ret_status;
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
diff --git a/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c
new file mode 100644
index 0000000..0fdd30d
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessBeaconFrame.cc contains the code
+ * for processing Received Beacon Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#include "cfgApi.h"
+#include "schApi.h"
+#include "wniCfgAp.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halCommonApi.h"
+#endif
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSerDesUtils.h"
+
+/**
+ * limProcessBeaconFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon Beacon
+ * frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * 1. Beacons received in 'normal' state in IBSS are handled by
+ * Beacon Processing module.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to RX packet info structure
+ * @return None
+ */
+
+void
+limProcessBeaconFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tSchBeaconStruct beacon;
+
+ pMac->lim.gLimNumBeaconsRcvd++;
+
+ /* here is it required to increment session specific heartBeat beacon counter */
+
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+
+ PELOG2(limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "),
+ WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
+ limPrintMacAddr(pMac, pHdr->sa, LOG2);)
+
+ if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+ return;
+
+ /**
+ * Expect Beacon only when
+ * 1. STA is in Scan mode waiting for Beacon/Probe response or
+ * 2. STA is waiting for Beacon/Probe Respose Frame
+ * to announce join success.
+ * 3. STA/AP is in Learn mode
+ */
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) ||
+ (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE))
+ {
+ // Parse received Beacon
+ if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo,
+ &beacon) != eSIR_SUCCESS)
+ {
+ // Received wrongly formatted/invalid Beacon.
+ // Ignore it and move on.
+ limLog(pMac, LOGW,
+ FL("Received invalid Beacon in state %X\n"),
+ psessionEntry->limMlmState);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+ return;
+ }
+
+
+ MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, beacon.timeStamp[0]);)
+ MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, beacon.timeStamp[1]);)
+
+
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE))
+ {
+#ifdef WLAN_FEATURE_P2P
+ //If we are scanning for P2P, only accept probe rsp
+ if((pMac->lim.gLimHalScanState != eLIM_HAL_SCANNING_STATE) || (NULL == pMac->lim.gpLimMlmScanReq)
+ || !pMac->lim.gpLimMlmScanReq->p2pSearch )
+#endif
+ {
+ limCheckAndAddBssDescription(pMac, &beacon, pRxPacketInfo,
+ ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE),
+ eANI_BOOLEAN_FALSE);
+ }
+ }
+ else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)
+ {
+#if (WNI_POLARIS_FW_PRODUCT == AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // STA/AP is in learn mode
+ /* Not sure whether the below 2 lines are needed for the station. TODO If yes, this should be
+ * uncommented. Also when we tested enabling this, there is a crash as soon as the station
+ * comes up which needs to be fixed*/
+ //if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ // limCheckAndAddBssDescription(pMac, &beacon, pRxPacketInfo, eANI_BOOLEAN_TRUE);
+ limCollectMeasurementData(pMac, pRxPacketInfo, &beacon);
+ PELOG3(limLog(pMac, LOG3, FL("Parsed WDS info in Beacon frames: wdsLength=%d\n"),
+ beacon.propIEinfo.wdsLength);)
+#endif
+ }
+ else
+ {
+ if( psessionEntry->beacon != NULL )
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->beacon);
+ psessionEntry->beacon = NULL;
+ }
+ psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->beacon, psessionEntry->bcnLen)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));)
+ }
+ else
+ {
+ //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->beacon, WDA_GET_RX_MPDU_DATA(pRxPacketInfo), psessionEntry->bcnLen);
+
+ }
+
+ // STA in WT_JOIN_BEACON_STATE (IBSS)
+ limCheckAndAnnounceJoinSuccess(pMac, &beacon, pHdr,psessionEntry);
+ } // if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE)
+ } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ...
+ else
+ {
+ // Ignore Beacon frame in all other states
+ if (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME3_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME4_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_RSP_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_ASSOCIATED_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_REASSOCIATED_STATE ||
+ psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_CNF_STATE ||
+ limIsReassocInProgress(pMac,psessionEntry)) {
+ // nothing unexpected about beacon in these states
+ pMac->lim.gLimNumBeaconsIgnored++;
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Received Beacon in unexpected state %d\n"),
+ psessionEntry->limMlmState);
+ limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState);)
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimUnexpBcnCnt++;
+#endif
+ }
+ }
+
+ return;
+} /*** end limProcessBeaconFrame() ***/
+
+
+/**---------------------------------------------------------------
+\fn limProcessBeaconFrameNoSession
+\brief This function is called by limProcessMessageQueue()
+\ upon Beacon reception.
+\
+\param pMac
+\param *pRxPacketInfo - A pointer to Rx packet info structure
+\return None
+------------------------------------------------------------------*/
+void
+limProcessBeaconFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
+{
+ tpSirMacMgmtHdr pHdr;
+ tSchBeaconStruct beacon;
+
+ pMac->lim.gLimNumBeaconsRcvd++;
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "),
+ WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
+ limPrintMacAddr(pMac, pHdr->sa, LOG2);
+
+ if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+ return;
+
+ /**
+ * No session has been established. Expect Beacon only when
+ * 1. STA is in Scan mode waiting for Beacon/Probe response or
+ * 2. STA/AP is in Learn mode
+ */
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE))
+ {
+ if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, &beacon) != eSIR_SUCCESS)
+ {
+ // Received wrongly formatted/invalid Beacon. Ignore and move on.
+ limLog(pMac, LOGW, FL("Received invalid Beacon in global MLM state %X\n"), pMac->lim.gLimMlmState);
+ limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);
+ return;
+ }
+
+ if ( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) )
+ {
+#ifdef WLAN_FEATURE_P2P
+ //If we are scanning for P2P, only accept probe rsp
+ if((pMac->lim.gLimHalScanState != eLIM_HAL_SCANNING_STATE) || (NULL == pMac->lim.gpLimMlmScanReq)
+ || !pMac->lim.gpLimMlmScanReq->p2pSearch )
+#endif
+ {
+ limCheckAndAddBssDescription(pMac, &beacon, pRxPacketInfo, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE);
+ }
+ }
+ else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)
+ {
+#if (WNI_POLARIS_FW_PRODUCT == AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // STA/AP is in learn mode
+ /* Not sure whether the below 2 lines are needed for the station. TODO If yes, this should be
+ * uncommented. Also when we tested enabling this, there is a crash as soon as the station
+ * comes up which needs to be fixed*/
+ //if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ // limCheckAndAddBssDescription(pMac, &beacon, pRxPacketInfo, eANI_BOOLEAN_TRUE);
+ limCollectMeasurementData(pMac, pRxPacketInfo, &beacon);
+ limLog(pMac, LOG3, FL("Parsed WDS info in Beacon frames: wdsLength=%d\n"),
+ beacon.propIEinfo.wdsLength);
+#endif
+ } // end of eLIM_MLM_LEARN_STATE)
+ } // end of (eLIM_MLM_WT_PROBE_RESP_STATE) || (eLIM_MLM_PASSIVE_SCAN_STATE)
+ else
+ {
+ limLog(pMac, LOG1, FL("Rcvd Beacon in unexpected MLM state %d\n"), pMac->lim.gLimMlmState);
+ limPrintMlmState(pMac, LOG1, pMac->lim.gLimMlmState);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimUnexpBcnCnt++;
+#endif
+ }
+
+ return;
+} /*** end limProcessBeaconFrameNoSession() ***/
+
diff --git a/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c
new file mode 100644
index 0000000..726da44
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c
@@ -0,0 +1,979 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessCfgUpdates.cc contains the utility functions
+ * to handle various CFG parameter update events
+ * Author: Chandra Modumudi
+ * Date: 01/20/03
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "aniGlobal.h"
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "sirMacProtDef.h"
+#include "cfgApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limPropExtsUtils.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halCommonApi.h"
+#endif
+#include "schApi.h"
+#include "pmmApi.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+
+static void limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry);
+
+#if 0
+/**
+ * limGetCfgIdOfDefaultKeyid()
+ *
+ *FUNCTION:
+ * This function is called to get CFG ID of default key id
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param dkid - Value of default key id
+ * @return dkCfgId - CFG ID of key corresponding to default key Id
+ */
+
+static tANI_U32
+limGetCfgIdOfDefaultKeyid(tANI_U32 dkid)
+{
+ if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_0)
+ return WNI_CFG_WEP_DEFAULT_KEY_1;
+ else if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_1)
+ return WNI_CFG_WEP_DEFAULT_KEY_2;
+ else if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_2)
+ return WNI_CFG_WEP_DEFAULT_KEY_3;
+ else // dkid == WNI_CFG_WEP_DEFAULT_KEYID_3
+ return WNI_CFG_WEP_DEFAULT_KEY_4;
+} /*** end limGetCfgIdOfDefaultKeyid() ***/
+#endif
+
+
+/**
+ * limSetDefaultKeyIdAndKeys()
+ *
+ *FUNCTION:
+ * This function is called while applying configuration
+ * during JOIN/REASSOC/START_BSS.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limSetDefaultKeyIdAndKeys(tpAniSirGlobal pMac)
+{
+#ifdef FIXME_GEN6
+ tANI_U32 val;
+ tANI_U32 dkCfgId;
+
+ PELOG1(limLog(pMac, LOG1, FL("Setting default keys at SP\n"));)
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID,
+ &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve defaultKeyId from CFG\n"));
+ }
+ dkCfgId = limGetCfgIdOfDefaultKeyid(val);
+#endif
+
+} /*** end limSetDefaultKeyIdAndKeys() ***/
+
+
+/**
+ * handleCBCFGChange()
+ *
+ *FUNCTION:
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * If this API is invoked with
+ * cfgId == ANI_IGNORE_CFG_ID
+ * Then,
+ * this routine will traverse thru' ALL the
+ * related CFG's that are statically setup
+ * Else,
+ * only update this "1" CFG identified by cfgId
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param cfgId - ID of CFG parameter that got updated
+ * @return None
+ */
+void handleCBCFGChange( tpAniSirGlobal pMac, tANI_U32 cfgId )
+{
+tANI_U32 cfg, val, i = 0;
+tANI_U32 defaultCfgList[] = {
+ WNI_CFG_CHANNEL_BONDING_MODE,
+ ANI_IGNORE_CFG_ID };
+
+ do
+ {
+ //
+ // Determine if we have to use our own default CFG list
+ // OR should we use the argument passed to us
+ //
+ if( ANI_IGNORE_CFG_ID == cfgId )
+ cfg = defaultCfgList[i]; // "n" iterations reqd
+ else
+ cfg = cfgId; // Just "1" iteration reqd
+
+ switch( cfg )
+ {
+ case WNI_CFG_CHANNEL_BONDING_MODE:
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac,
+ WNI_CFG_CHANNEL_BONDING_MODE,
+ &val ))
+ {
+ limLog( pMac, LOGW,
+ FL("Unable to retrieve CHANNEL BONDING Mode from CFG. Defaulting to DISABLE\n"));
+ pMac->lim.gCbMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ }
+ else
+ pMac->lim.gCbMode = (tANI_U8) val;
+
+ // Now, set the CHANNEL BONDING state apropriately
+ switch( pMac->lim.gCbMode )
+ {
+ // Always OFF
+ case WNI_CFG_CHANNEL_BONDING_MODE_DISABLE:
+ SET_CB_STATE_DISABLE( pMac->lim.gCbState );
+ break;
+
+ // Always ON
+ case WNI_CFG_CHANNEL_BONDING_MODE_ENABLE:
+ SET_CB_STATE_ENABLE( pMac->lim.gCbState );
+ break;
+
+ default:
+ SET_CB_STATE_ENABLE( pMac->lim.gCbState );
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // DEBUG LOG the TITAN CFG's
+ limLog( pMac, LOG1,
+ FL("The TITAN related global CFG's are: "
+ "cbMode - %1d cbState - %1d\n"),
+ pMac->lim.gCbMode, pMac->lim.gCbState);
+
+ // If only "1" CFG needs an update, then return
+ if( ANI_IGNORE_CFG_ID == cfgId )
+ i++;
+ else
+ break;
+
+ } while( ANI_IGNORE_CFG_ID != defaultCfgList[i] ); // End-Of-List?
+}
+
+/** -------------------------------------------------------------
+\fn limSetCfgProtection
+\brief sets lim global cfg cache from the config.
+\param tpAniSirGlobal pMac
+\return None
+ -------------------------------------------------------------*/
+#ifdef WLAN_SOFTAP_FEATURE
+void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry)
+#else
+void limSetCfgProtection(tpAniSirGlobal pMac)
+#endif
+{
+ tANI_U32 val = 0;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(( pesessionEntry != NULL ) && (pesessionEntry->limSystemRole == eLIM_AP_ROLE )){
+ if (pesessionEntry->gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE )
+ palZeroMemory( pMac->hHdd, (void *)&pesessionEntry->cfgProtection , sizeof(tCfgProtection));
+ else{
+ limLog(pMac, LOG1, FL(" frm11a = %d, from11b = %d, frm11g = %d, "
+ "ht20 = %d, nongf = %d, lsigTxop = %d, "
+ "rifs = %d, obss = %d\n"),
+ pesessionEntry->cfgProtection.fromlla,
+ pesessionEntry->cfgProtection.fromllb,
+ pesessionEntry->cfgProtection.fromllg,
+ pesessionEntry->cfgProtection.ht20,
+ pesessionEntry->cfgProtection.nonGf,
+ pesessionEntry->cfgProtection.lsigTxop,
+ pesessionEntry->cfgProtection.rifs,
+ pesessionEntry->cfgProtection.obss);
+ }
+ }
+ else{
+#endif
+ if (wlan_cfgGetInt(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("reading WNI_CFG_FORCE_POLICY_PROTECTION cfg failed\n"));
+ return;
+ }
+ else
+ pMac->lim.gLimProtectionControl = (tANI_U8)val;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PROTECTION_ENABLED, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("reading protection cfg failed\n"));
+ return;
+ }
+
+ if(pMac->lim.gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ palZeroMemory( pMac->hHdd, (void *)&pMac->lim.cfgProtection , sizeof(tCfgProtection));
+ else
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ {
+ pMac->lim.cfgProtection.overlapFromlla = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llA) & 1;
+ pMac->lim.cfgProtection.overlapFromllb = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llB) & 1;
+ pMac->lim.cfgProtection.overlapFromllg = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llG) & 1;
+ pMac->lim.cfgProtection.overlapHt20 = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_HT20) & 1;
+ pMac->lim.cfgProtection.overlapNonGf = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_NON_GF) & 1;
+ pMac->lim.cfgProtection.overlapLsigTxop = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_LSIG_TXOP) & 1;
+ pMac->lim.cfgProtection.overlapRifs = (val >> WNI_CFG_PROTECTION_ENABLED_OLBC_RIFS) & 1;
+ pMac->lim.cfgProtection.overlapOBSS = (val>> WNI_CFG_PROTECTION_ENABLED_OLBC_OBSS )&1;
+
+ }
+ #endif
+ pMac->lim.cfgProtection.fromlla = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llA) & 1;
+ pMac->lim.cfgProtection.fromllb = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llB) & 1;
+ pMac->lim.cfgProtection.fromllg = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llG) & 1;
+ pMac->lim.cfgProtection.ht20 = (val >> WNI_CFG_PROTECTION_ENABLED_HT_20) & 1;
+ pMac->lim.cfgProtection.nonGf = (val >> WNI_CFG_PROTECTION_ENABLED_NON_GF) & 1;
+ pMac->lim.cfgProtection.lsigTxop = (val >> WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP) & 1;
+ pMac->lim.cfgProtection.rifs = (val >> WNI_CFG_PROTECTION_ENABLED_RIFS) & 1;
+ pMac->lim.cfgProtection.obss= (val >> WNI_CFG_PROTECTION_ENABLED_OBSS) & 1;
+
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+}
+#endif
+}
+
+
+
+/**
+ * limUpdateTriggerStaBkScanFlag
+ *
+ * FUNCTION:
+ * This function updates the lim global gLimTriggerBackgroundScanDuringQuietBss
+ * based on cfg configuration. Usually triggered after a cfgSetInt call.
+ *
+ * PARAMS:
+ * pMac - Pointer to Global MAC structure
+ *
+ */
+static tSirRetStatus limUpdateTriggerStaBkScanFlag(tpAniSirGlobal pMac)
+{
+ tANI_U32 val;
+ tANI_U8 flag;
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN from cfg\n"));)
+ return eSIR_FAILURE;
+ }
+
+ flag = (val) ? 1 : 0;
+ if(flag != pMac->lim.gLimTriggerBackgroundScanDuringQuietBss)
+ {
+ /* Update global flag */
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = flag;
+ /*Update beacon prop IE also if we're an AP */
+
+ //call a wrapper and if the session role is other than the sta call this function schsetfixedbeacon fields function
+ limUpdateBeacon(pMac);
+
+ }
+
+ return eSIR_FAILURE;
+}
+
+
+/**
+ * limHandleCFGparamUpdate()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessages() to
+ * whenever SIR_CFG_PARAM_UPDATE_IND message is posted
+ * to LIM (due to a set operation on a CFG parameter).
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param cfgId - ID of CFG parameter that got updated
+ * @return None
+ */
+
+void
+limHandleCFGparamUpdate(tpAniSirGlobal pMac, tANI_U32 cfgId)
+{
+ tANI_U32 val1, val2;
+ tANI_U16 val16;
+ tANI_U8 val8;
+ tSirMacHTCapabilityInfo *pHTCapabilityInfo;
+ tSirMacHTParametersInfo *pAmpduParamInfo;
+ tSirMacHTInfoField1 *pHTInfoField1;
+
+ PELOG3(limLog(pMac, LOG3, FL("Handling CFG parameter id %X update\n"), cfgId);)
+ switch (cfgId)
+ {
+ case WNI_CFG_WEP_DEFAULT_KEYID:
+
+ // !!LAC - when the default KeyID is changed, force all of the
+ // keys and the keyID to be reprogrammed. this allows the
+ // keys to change after the initial setting of the keys when the CFG was
+ // applied at association time through CFG changes of the keys.
+ limSetDefaultKeyIdAndKeys( pMac );
+
+ break;
+
+ case WNI_CFG_EXCLUDE_UNENCRYPTED:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_EXCLUDE_UNENCRYPTED,
+ &val1) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve excludeUnencr from CFG\n"));
+ }
+#if 0
+ halSetSpExclUndecrypted(pMac, (tHalBitVal) val);
+#else
+ limLog(pMac, LOGE,
+ FL("Unsupported CFG: WNI_CFG_EXCLUDE_UNENCRYPTED\n"));
+#endif
+
+ break;
+
+ case WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT:
+ if (pMac->lim.gLimMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)
+ {
+ // 'Change' timer for future activations
+ limDeactivateAndChangeTimer(pMac,
+ eLIM_ASSOC_FAIL_TIMER);
+ }
+
+ break;
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA) || defined(ANI_AP_CLIENT_SDK)
+ case WNI_CFG_BACKGROUND_SCAN_PERIOD:
+
+
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, &val1) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve Background scan period value\n"));
+ break;
+ }
+ if (val1 == 0)
+ break;
+
+
+
+ if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) ||
+ ( (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
+ (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE)))
+ {
+ // Reactivate Background scan timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_BACKGROUND_SCAN_TIMER));
+ if (tx_timer_activate(
+ &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ {
+ /// Could not activate background scan timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not activate background scan timer\n"));
+ pMac->lim.gLimBackgroundScanStarted = FALSE;
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+ }
+ else
+ {
+ pMac->lim.gLimBackgroundScanStarted = TRUE;
+ pMac->lim.gLimBackgroundScanTerminate = FALSE;
+ }
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("Updated Background scan period\n"));)
+ }
+
+ break;
+#endif
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ case WNI_CFG_PREAUTH_CLNUP_TIMEOUT:
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ limDeactivateAndChangeTimer(pMac,
+ eLIM_PRE_AUTH_CLEANUP_TIMER);
+
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ * priority - MEDIUM
+ */
+ pMac->lim.limTimers.gLimPreAuthClnupTimer.sessionId = sessionId;
+#endif
+ // Reactivate pre-auth cleanup timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PRE_AUTH_CLEANUP_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimPreAuthClnupTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not activate pre-auth cleanup timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not activate preauth cleanup timer\n"));
+ }
+ PELOG3(limLog(pMac, LOG3,
+ FL("Updated pre-auth cleanup timeout\n"));)
+ }
+
+ break;
+
+#endif
+
+ case WNI_CFG_BG_SCAN_CHANNEL_LIST:
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA) || defined(ANI_AP_CLIENT_SDK)
+ PELOG1(limLog(pMac, LOG1,
+ FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel\n"));)
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+#endif
+
+ break;
+
+ case WNI_CFG_CHANNEL_BONDING_MODE:
+ handleCBCFGChange( pMac, cfgId );
+ //for Secondary channel, change setupCBMode function OR the caller of that function during Join (STA) or Start BSS(AP/IBSS)
+ //Now update the HT Capability CFG based on Channel Bonding CFG
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+
+ //channel bonding mode could be set to anything from 0 to 4(Titan had these modes)
+ //But for Taurus we have only two modes: enable(>0) or disable(=0)
+ pHTCapabilityInfo->supportedChannelWidthSet = val2 ? WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG\n"));)
+ break;
+ }
+ val8 = ( tANI_U8 ) val1;
+ pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8;
+ pHTInfoField1->recommendedTxWidthSet = (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet;
+ pMac->lim.gHTRecommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet;
+ if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field\n"));)
+
+ break;
+
+
+ case WNI_CFG_TRIG_STA_BK_SCAN:
+ if(limUpdateTriggerStaBkScanFlag(pMac) != eSIR_SUCCESS)
+ {
+ PELOG2(limLog(pMac, LOG2,
+ FL("Updating lim trigger sta bk scan global flag failed!\n"));)
+ }
+ break;
+
+ case WNI_CFG_PROTECTION_ENABLED:
+#ifdef WLAN_SOFTAP_FEATURE
+ limSetCfgProtection(pMac, NULL);
+#else
+ limSetCfgProtection(pMac);
+#endif
+ break;
+ case WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG:
+ {
+ tSirMsgQ msg = {0};
+ tANI_U32 status;
+
+ msg.type = SIR_LIM_UPDATE_BEACON;
+
+ status = limPostMsgApi(pMac, &msg);
+
+ if (status != TX_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed limPostMsgApi\n"), status);)
+ break;
+ }
+ case WNI_CFG_GREENFIELD_CAPABILITY:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_GREENFIELD_CAPABILITY, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve GreenField CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->greenField = (tANI_U16)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ break;
+
+ case WNI_CFG_HT_RX_STBC:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_CAP_INFO \n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_RX_STBC, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_RX_STBC\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->rxSTBC = (tANI_U16)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ break;
+
+ case WNI_CFG_MAX_AMSDU_LENGTH:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_AMSDU_LENGTH, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max AMSDU Length CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->maximalAMSDUsize = (tANI_U16)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ break;
+
+ case WNI_CFG_SHORT_GI_20MHZ:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ break;
+ case WNI_CFG_SHORT_GI_40MHZ:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
+ pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
+ break;
+ case WNI_CFG_MPDU_DENSITY:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MPDU_DENSITY, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve MPDU Density CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
+ pAmpduParamInfo->mpduDensity = (tANI_U8)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG\n"));)
+
+ break;
+ case WNI_CFG_MAX_RX_AMPDU_FACTOR:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG\n"));)
+ break;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG\n"));)
+ break;
+ }
+ val16 = ( tANI_U16 ) val1;
+ pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
+ pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2;
+ if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG\n"));)
+ break;
+
+ case WNI_CFG_HEART_BEAT_THRESHOLD:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG\n"));)
+ break;
+ }
+ if(!val1)
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER);
+ pMac->sys.gSysEnableLinkMonitorMode = 0;
+ PELOGE(limLog(pMac, LOGE, "Deactivating heartbeat link monitoring\n");)
+ }
+ else
+ {
+ pMac->sys.gSysEnableLinkMonitorMode = 1;
+ //limReactivateTimer( pMac, eLIM_HEART_BEAT_TIMER );
+ //limReactivateHeartBeatTimer(pMac, psessionEntry);
+ PELOGE(limLog(pMac, LOGE, "Reactivating heartbeat link monitoring\n");)
+ }
+ case WNI_CFG_MAX_PS_POLL:
+ case WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE:
+ case WNI_CFG_MIN_RSSI_THRESHOLD:
+ case WNI_CFG_NTH_BEACON_FILTER:
+ case WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE:
+ {
+ tpSirPowerSaveCfg pPowerSaveConfig;
+
+ /* Allocate and fill in power save configuration. */
+ if (palAllocateMemory(pMac->hHdd, (void **)&pPowerSaveConfig,
+ sizeof(tSirPowerSaveCfg)) != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save configuration\n"));)
+ break;
+ }
+
+ /* This context should be valid if power-save configuration message has been already dispathed
+ * during initialization process. Re-using the present configuration mask
+ */
+ palCopyMemory(pMac->hHdd, pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg, sizeof(tSirPowerSaveCfg));
+
+ if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed \n"));)
+ }
+ }
+ break;
+
+
+ case WNI_CFG_DOT11_MODE:
+ if (wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &val1) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve Dot11 Mode CFG\n"));)
+ break;
+ }
+ /* TODO */
+ //psessionEntry->dot11mode = val1; //// un comment this line ...FORBUILD -TEMPFIX.. HOW TO GET sessionEntry?????
+ break;
+ case WNI_CFG_ADDBA_REQ_DECLINE:
+ if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val1) != eSIR_SUCCESS) {
+ limLog( pMac, LOGE, FL( "Unable to get ADDBA_REQ_DECLINE cfg\n" ));
+ break;
+ }
+ pMac->lim.gAddBA_Declined = (tANI_U8)val1;
+ break;
+
+ case WNI_CFG_SCAN_IN_POWERSAVE:
+ if(wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val1) != eSIR_SUCCESS) {
+ limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_SCAN_IN_POWERSAVE \n" ));
+ break;
+ }
+ pMac->lim.gScanInPowersave = (tANI_U8)val1;
+ break;
+
+
+ case WNI_CFG_ASSOC_STA_LIMIT:
+ if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val1) != eSIR_SUCCESS) {
+ limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_ASSOC_STA_LIMIT" ));
+ break;
+ }
+ pMac->lim.gLimAssocStaLimit = (tANI_U16)val1;
+ break;
+
+ default:
+ break;
+ }
+} /*** end limHandleCFGparamUpdate() ***/
+
+
+
+/**
+ * limApplyConfiguration()
+ *
+ *FUNCTION:
+ * This function is called to apply the configured parameters
+ * before joining or reassociating with a BSS or starting a BSS.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limApplyConfiguration(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ tANI_U32 val=0, phyMode;
+
+ PELOG2(limLog(pMac, LOG2, FL("Applying config\n"));)
+
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ limCleanupMeasResources(pMac);
+#endif
+ limInitWdsInfoParams(pMac);
+
+ psessionEntry->limSentCapsChangeNtf = false;
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ // Set default keyId and keys
+ limSetDefaultKeyIdAndKeys(pMac);
+
+ limUpdateConfig(pMac,psessionEntry);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, &val)
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_SLOT_TIME failed\n"));
+ return;
+ }
+ if (phyMode == WNI_CFG_PHY_MODE_11G)
+ {
+
+ if ((psessionEntry->pePersona == VOS_STA_SAP_MODE) ||
+ (psessionEntry->pePersona == VOS_P2P_GO_MODE))
+ {
+ val = 1;
+ }
+
+ // Program Polaris based on AP capability
+
+ if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)
+ // Joining BSS.
+ val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limCurrentBssCaps);
+ else if (psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE)
+ // Reassociating with AP.
+ val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limReassocBssCaps);
+
+
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not update short slot time at CFG\n"));
+ return;
+ }
+ }
+ else
+ {
+ // Reset short slot time at CFG
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, 0) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not update short slot time at CFG\n"));
+ return;
+ }
+ }
+ //apply protection related config.
+
+#ifdef WLAN_SOFTAP_FEATURE
+ limSetCfgProtection(pMac, psessionEntry);
+#else
+ limSetCfgProtection(pMac);
+#endif
+
+
+ /* Added for BT - AMP Support */
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )
+ {
+ /* This check is required to ensure the beacon generation is not done
+ as a part of join request for a BT-AMP station */
+
+ if(psessionEntry->statypeForBss == STA_ENTRY_SELF)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Initializing BT-AMP beacon generation\n"));)
+ schSetBeaconInterval(pMac,psessionEntry);
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ }
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve WNI_CFG_SCAN_IN_POWERSAVE\n"));
+ return;
+ }
+ pMac->lim.gScanInPowersave = (tANI_U8) val;
+
+} /*** end limApplyConfiguration() ***/
+
+
+/**
+ * limUpdateConfig
+ *
+ * FUNCTION:
+ * Update the local state from CFG database
+ * (This used to be dphUpdateConfig)
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+static void
+limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+ tANI_U32 val;
+
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, pMac->lim.gLimMyMacAddr, &len) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get sta id failed\n"));
+ #endif //To SUPPORT BT-AMP
+ sirCopyMacAddr(pMac->lim.gLimMyMacAddr,psessionEntry->selfMacAddr);
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get short preamble failed\n"));
+ psessionEntry->beaconParams.fShortPreamble = (val) ? 1 : 0;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WME_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get wme enabled failed\n"));
+ psessionEntry->limWmeEnabled = (val) ? 1 : 0;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WSM_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get wsm enabled failed\n"));
+ psessionEntry->limWsmEnabled = (val) ? 1 : 0;
+
+ if ((! psessionEntry->limWmeEnabled) && (psessionEntry->limWsmEnabled))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Can't enable WSM without WME\n"));)
+ psessionEntry->limWsmEnabled = 0;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get qos enabled failed\n"));
+ psessionEntry->limQosEnabled = (val) ? 1 : 0;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HCF_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get hcf enabled failed\n"));
+ psessionEntry->limHcfEnabled = (val) ? 1 : 0;
+
+ // Update the ADD BA Declined configuration
+ if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val) != eSIR_SUCCESS)
+ limLog( pMac, LOGP, FL( "Unable to get ADDBA_REQ_DECLINE cfg\n" ));
+ pMac->lim.gAddBA_Declined = (val) ? 0xff : 0x0;
+
+ // AP: WSM should enable HCF as well, for STA enable WSM only after
+ // association response is received
+ if (psessionEntry->limWsmEnabled && psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ psessionEntry->limHcfEnabled = 1;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_11D_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get 11d enabled failed\n"));
+ psessionEntry->lim11dEnabled = (val) ? 1 : 0;
+
+ if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) {
+ limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" ));
+ }
+ pMac->lim.gLimAssocStaLimit = (tANI_U16)val;
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrmUpdateConfig( pMac, psessionEntry );
+#endif
+ PELOG1(limLog(pMac, LOG1, FL("Updated Lim shadow state based on CFG\n"));)
+
+
+}
+
+
diff --git a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
new file mode 100644
index 0000000..1147e90
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessDeauthFrame.cc contains the code
+ * for processing Deauthentication Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/24/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "palTypes.h"
+#include "aniGlobal.h"
+
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "schApi.h"
+#include "limSendMessages.h"
+
+
+
+/**
+ * limProcessDeauthFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Deauthentication frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+void
+limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
+{
+ tANI_U8 *pBody;
+ tANI_U16 aid, reasonCode;
+ tpSirMacMgmtHdr pHdr;
+ tLimMlmAssocCnf mlmAssocCnf;
+ tLimMlmDeauthInd mlmDeauthInd;
+ tpDphHashNode pStaDs;
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+
+ if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("received Deauth frame in DEAUTH_WT_STATE(already processing previously received DEAUTH frame).. Dropping this..\n "));)
+ return;
+ }
+
+ if (limIsGroupAddr(pHdr->sa))
+ {
+ // Received Deauth frame from a BC/MC address
+ // Log error and ignore it
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame from a BC/MC address\n"));)
+
+ return;
+ }
+
+ if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da))
+ {
+ // Received Deauth frame for a MC address
+ // Log error and ignore it
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame for a MC address\n"));)
+
+ return;
+ }
+ // Get reasonCode from Deauthentication frame body
+ reasonCode = sirReadU16(pBody);
+
+ PELOGE(limLog(pMac, LOGE,
+ FL("received Deauth frame (mlm state = %s) with reason code %d from "),
+ limMlmStateStr(pMac->lim.gLimMlmState), reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);)
+
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE )||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
+ {
+ switch (reasonCode)
+ {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+ // Valid reasonCode in received Deauthentication frame
+ break;
+
+ default:
+ // Invalid reasonCode in received Deauthentication frame
+ // Log error and ignore the frame
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame with invalid reasonCode %d from \n"),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+ }
+ else if (psessionEntry->limSystemRole == eLIM_STA_ROLE ||psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)
+ {
+ switch (reasonCode)
+ {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
+ case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+ case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+ case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+ case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON:
+ // Valid reasonCode in received Deauth frame
+ break;
+
+ default:
+ // Invalid reasonCode in received Deauth frame
+ // Log error and ignore the frame
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame with invalid reasonCode %d from \n"),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ break;
+ }
+ }
+ else
+ {
+ // Received Deauth frame in either IBSS
+ // or un-known role. Log error and ignore it
+ limLog(pMac, LOGE,
+ FL("received Deauth frame with reasonCode %d in role %d from \n"),
+ reasonCode, psessionEntry->limSystemRole);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+
+ /** If we are in the middle of ReAssoc, a few things could happen:
+ * - STA is reassociating to current AP, and receives deauth from:
+ * a) current AP
+ * b) other AP
+ * - STA is reassociating to a new AP, and receives deauth from:
+ * c) current AP
+ * d) reassoc AP
+ * e) other AP
+ *
+ * The logic is:
+ * 1) If rcv deauth from an AP other than the one we're trying to
+ * reassociate with, then drop the deauth frame (case b, c, e)
+ * 2) If rcv deauth from the "new" reassoc AP (case d), then restore
+ * context with previous AP and send SME_REASSOC_RSP failure.
+ * 3) If rcv deauth from the reassoc AP, which is also the same
+ * AP we're currently associated with (case a), then proceed
+ * with normal deauth processing.
+ */
+ if (limIsReassocInProgress(pMac,psessionEntry)) {
+ if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
+ PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different AP while ReAssoc. Ignore \n"));)
+ return;
+ }
+
+ /** Received deauth from the new AP to which we tried to ReAssociate.
+ * Drop ReAssoc and Restore the Previous context( current connected AP).
+ */
+ if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) {
+ PELOGE(limLog(pMac, LOGW, FL("received DeAuth from the New AP to which ReAssoc is sent \n"));)
+ limRestorePreReassocState(pMac,
+ eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
+ return;
+ }
+ }
+
+
+ /* If received DeAuth from AP other than the one we're trying to join with
+ * nor associated with, then ignore deauth and delete Pre-auth entry.
+ */
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole != eLIM_AP_ROLE ){
+#endif
+ if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("received DeAuth from an AP other than we're trying to join. Ignore. \n"));)
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Preauth entry exist. Deleting... \n"));)
+ limDeletePreAuthNode(pMac, pHdr->sa);
+ }
+ return;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ }
+#endif
+
+ // Check for pre-assoc states
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (psessionEntry->limMlmState)
+ {
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ /**
+ * AP sent Deauth frame while waiting
+ * for Auth frame2. Report Auth failure
+ * to SME.
+ */
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame with failure code %d from "),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ limRestoreFromAuthState(pMac, eSIR_SME_DEAUTH_WHILE_JOIN,
+ reasonCode,psessionEntry);
+
+ return;
+
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ /// Issue Deauth Indication to SME.
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &mlmDeauthInd.peerMacAddr,
+ pHdr->sa,
+ sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode = reasonCode;
+
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DEAUTH_IND,
+ (tANI_U32 *) &mlmDeauthInd);
+ return;
+
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ /**
+ * AP may have 'aged-out' our Pre-auth
+ * context. Delete local pre-auth context
+ * if any and issue ASSOC_CNF to SME.
+ */
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN;
+ mlmAssocCnf.protStatusCode = reasonCode;
+
+ /* PE session Id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+
+ psessionEntry->limMlmState =
+ psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, psessionEntry->limMlmState));
+
+ // Deactive Association response timeout
+ limDeactivateAndChangeTimer(
+ pMac,
+ eLIM_ASSOC_FAIL_TIMER);
+
+ limPostSmeMessage(
+ pMac,
+ LIM_MLM_ASSOC_CNF,
+ (tANI_U32 *) &mlmAssocCnf);
+
+ return;
+
+ case eLIM_MLM_IDLE_STATE:
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+ /**
+ * This could be Deauthentication frame from
+ * a BSS with which pre-authentication was
+ * performed. Delete Pre-auth entry if found.
+ */
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ break;
+
+ case eLIM_MLM_WT_REASSOC_RSP_STATE:
+ break;
+
+ case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame in FT state %X with reasonCode=%d from "),
+ psessionEntry->limMlmState, reasonCode);)
+ break;
+
+ default:
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame in state %X with reasonCode=%d from "),
+ psessionEntry->limMlmState, reasonCode);)
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);
+ return;
+ }
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ case eLIM_AP_ROLE:
+ break;
+#endif
+
+ default: // eLIM_AP_ROLE or eLIM_BT_AMP_AP_ROLE
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ /// Check if there exists pre-auth context for this STA
+ if (limSearchPreAuthList(pMac, pHdr->sa) == NULL)
+ {
+ /**
+ * Received Deauthentication from a STA that is neither
+ * Associated nor Pre-authenticated. Log error,
+ * and ignore Deauthentication frame.
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame from peer that does not have context, addr "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ }
+ else
+ {
+ /// Delete STA from pre-auth STA list
+ limDeletePreAuthNode(pMac,
+ pHdr->sa);
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &mlmDeauthInd.peerMacAddr,
+ pHdr->sa,
+ sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode = reasonCode;
+ mlmDeauthInd.aid = 0;
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DEAUTH_IND,
+ (tANI_U32 *) &mlmDeauthInd);
+ }
+#endif
+
+ return;
+ } // end switch (pMac->lim.gLimSystemRole)
+
+
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ if( (pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable)) == NULL)
+ return;
+
+
+ if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE))
+ {
+ /**
+ * Already in the process of deleting context for the peer
+ * and received Deauthentication frame. Log and Ignore.
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Deauth frame from peer that is in state %X, addr "),
+ pStaDs->mlmStaContext.mlmState);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ return;
+ }
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH;
+
+ /// Issue Deauth Indication to SME.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthInd.peerMacAddr,
+ pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmDeauthInd.aid = pStaDs->assocId;
+#endif
+ mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason;
+ mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH;
+
+
+ /* If we're in the middle of ReAssoc and received deauth from
+ * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+ * failure result code. By design, SME will then issue "Disassoc"
+ * and cleanup will happen at that time.
+ */
+ if (limIsReassocInProgress(pMac,psessionEntry)) {
+ /**
+ * AP may have 'aged-out' our Pre-auth
+ * context. Delete local pre-auth context
+ * if any and issue REASSOC_CNF to SME.
+ */
+ if (limSearchPreAuthList(pMac, pHdr->sa))
+ limDeletePreAuthNode(pMac, pHdr->sa);
+
+ if (psessionEntry->limAssocResponseData) {
+ palFreeMemory(pMac->hHdd, psessionEntry->limAssocResponseData);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+
+ PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from ReAssoc AP. Issue REASSOC_CNF. \n"));)
+ limRestorePreReassocState(pMac, eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
+ return;
+ }
+
+ /// Deauthentication from peer MAC entity
+ limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd);
+
+ // send eWNI_SME_DEAUTH_IND to SME
+ limSendSmeDeauthInd(pMac, pStaDs, psessionEntry);
+ return;
+
+} /*** end limProcessDeauthFrame() ***/
+
diff --git a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
new file mode 100644
index 0000000..1e138a9
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessDisassocFrame.cc contains the code
+ * for processing Disassocation Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/24/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "palTypes.h"
+#include "wniApi.h"
+#include "sirApi.h"
+#include "aniGlobal.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#endif
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limSendMessages.h"
+#include "schApi.h"
+
+
+/**
+ * limProcessDisassocFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Disassociation frame reception.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Rx packet info structure
+ * @return None
+ */
+void
+limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
+{
+ tANI_U8 *pBody;
+ tANI_U16 aid, reasonCode;
+ tpSirMacMgmtHdr pHdr;
+ tpDphHashNode pStaDs;
+ tLimMlmDisassocInd mlmDisassocInd;
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+
+ if (limIsGroupAddr(pHdr->sa))
+ {
+ // Received Disassoc frame from a BC/MC address
+ // Log error and ignore it
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame from a BC/MC address\n"));)
+
+ return;
+ }
+
+ if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da))
+ {
+ // Received Disassoc frame for a MC address
+ // Log error and ignore it
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame for a MC address\n"));)
+
+ return;
+ }
+
+ // Get reasonCode from Disassociation frame body
+ reasonCode = sirReadU16(pBody);
+
+ PELOGE(limLog(pMac, LOGE,
+ FL("Received Disassoc frame (mlm state %d sme state %d), with reason code %d from \n"),
+ psessionEntry->limMlmState, psessionEntry->limSmeState, reasonCode);)
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ /**
+ * Disassociating STA is not associated.
+ * Log error.
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame from STA that does not have context reasonCode=%d, addr "),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ /** If we are in the Wait for ReAssoc Rsp state */
+ if (limIsReassocInProgress(pMac,psessionEntry)) {
+ /** If we had received the DisAssoc from,
+ * a. the Current AP during ReAssociate to different AP in same ESS
+ * b. Unknown AP
+ * drop/ignore the DisAssoc received
+ */
+ if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
+ PELOGW(limLog(pMac, LOGW, FL("Ignore the DisAssoc received, while Processing ReAssoc with different/unknown AP\n"));)
+ return;
+ }
+ /** If the Disassoc is received from the new AP to which we tried to ReAssociate
+ * Drop ReAssoc and Restore the Previous context( current connected AP).
+ */
+ if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) {
+ PELOGW(limLog(pMac, LOGW, FL("received Disassoc from the New AP to which ReAssoc is sent \n"));)
+ limRestorePreReassocState(pMac,
+ eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
+ return;
+ }
+ }
+
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
+ {
+ switch (reasonCode)
+ {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+ case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+ case eSIR_MAC_MIC_FAILURE_REASON:
+ case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
+ case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
+ case eSIR_MAC_RSN_IE_MISMATCH_REASON:
+ case eSIR_MAC_1X_AUTH_FAILURE_REASON:
+ // Valid reasonCode in received Disassociation frame
+ break;
+
+ default:
+ // Invalid reasonCode in received Disassociation frame
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame with invalid reasonCode %d from \n"),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ break;
+ }
+ }
+ else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
+ ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) ))
+ {
+ switch (reasonCode)
+ {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON:
+ case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+ case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+ case eSIR_MAC_MIC_FAILURE_REASON:
+ case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
+ case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
+ case eSIR_MAC_RSN_IE_MISMATCH_REASON:
+ case eSIR_MAC_1X_AUTH_FAILURE_REASON:
+ // Valid reasonCode in received Disassociation frame
+ break;
+
+ case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+ // Valid reasonCode in received Disassociation frame
+ // as long as we're not about to channel switch
+ if(pMac->lim.gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE)
+ {
+ limLog(pMac, LOGW,
+ FL("Ignoring disassoc frame due to upcoming "
+ "channel switch, from\n"),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ return;
+ }
+ break;
+
+ default:
+ // Invalid reasonCode in received Disassociation frame
+ // Log error and ignore the frame
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame with invalid reasonCode %d from \n"),
+ reasonCode);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ return;
+ }
+ }
+ else
+ {
+ // Received Disassociation frame in either IBSS
+ // or un-known role. Log error and ignore it
+ limLog(pMac, LOGE,
+ FL("received Disassoc frame with invalid reasonCode %d in role %d in sme state %d from \n"),
+ reasonCode, psessionEntry->limSystemRole, psessionEntry->limSmeState);
+ limPrintMacAddr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+
+ // Disassociation from peer MAC entity
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("Received Disassoc frame from sta with assocId=%d, with reasonCode=%d\n"),
+ pStaDs->assocId, reasonCode);)
+
+ if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE))
+ {
+ /**
+ * Already in the process of deleting context for the peer
+ * and received Disassociation frame. Log and Ignore.
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame in state %d from"),
+ pStaDs->mlmStaContext.mlmState);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+
+ return;
+ }
+
+ if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ /**
+ * Requesting STA is in some 'transient' state?
+ * Log error.
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("received Disassoc frame from peer that is in state %X, addr "),
+ pStaDs->mlmStaContext.mlmState);
+ limPrintMacAddr(pMac, pHdr->sa, LOG1);)
+ } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
+
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
+
+ // Issue Disassoc Indication to SME.
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDisassocInd.peerMacAddr,
+ (tANI_U8 *) pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+ mlmDisassocInd.reasonCode =
+ (tANI_U8) pStaDs->mlmStaContext.disassocReason;
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmDisassocInd.aid = pStaDs->assocId;
+#endif
+ mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
+
+ /* Update PE session Id */
+ mlmDisassocInd.sessionId = psessionEntry->peSessionId;
+
+ if (limIsReassocInProgress(pMac,psessionEntry)) {
+
+ /* If we're in the middle of ReAssoc and received disassoc from
+ * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+ * failure result code. By design, SME will then issue "Disassoc"
+ * and cleanup will happen at that time.
+ */
+ PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting for Reassoc Rsp\n"));)
+
+ if (psessionEntry->limAssocResponseData) {
+ palFreeMemory(pMac->hHdd, psessionEntry->limAssocResponseData);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+
+ limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
+ return;
+ }
+
+ limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND,
+ (tANI_U32 *) &mlmDisassocInd);
+
+
+ // send eWNI_SME_DISASSOC_IND to SME
+ limSendSmeDisassocInd(pMac, pStaDs,psessionEntry);
+
+ return;
+} /*** end limProcessDisassocFrame() ***/
+
diff --git a/CORE/MAC/src/pe/lim/limProcessLmmMessages.c b/CORE/MAC/src/pe/lim/limProcessLmmMessages.c
new file mode 100644
index 0000000..27c95ce
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessLmmMessages.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessLmmMessages.cc contains the code
+ * for processing SME/LMM messages related to ANI feature set.
+ * Author: Chandra Modumudi
+ * Date: 10/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "aniGlobal.h"
+#include "wniApi.h"
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+#include "sirApi.h"
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSerDesUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSession.h"
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+/**
+ * limIsSmeMeasurementReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_MEASUREMENT_REQ.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMeasReq Pointer to Received MEASUREMENT_REQ message
+ * @return true When received SME_MEASUREMENT_REQ is formatted
+ * correctly
+ * false otherwise
+ */
+
+inline static tANI_BOOLEAN
+limIsSmeMeasurementReqValid(tpAniSirGlobal pMac, tpSirSmeMeasurementReq pMeasReq)
+{
+#ifdef ANI_AP_SDK
+ if (!pMeasReq->channelList.numChannels ||
+ ((pMeasReq->measControl.periodicMeasEnabled) &&
+ (!pMeasReq->measIndPeriod)) ||
+ (pMeasReq->measIndPeriod &&
+ ((pMeasReq->measIndPeriod < 1))) ||
+ !pMeasReq->measDuration.shortTermPeriod ||
+ ((pMeasReq->measDuration.shortTermPeriod < 1)) ||
+ !pMeasReq->measDuration.averagingPeriod ||
+ (pMeasReq->measDuration.averagingPeriod <
+ pMeasReq->measDuration.shortTermPeriod) ||
+ !pMeasReq->measDuration.shortChannelScanDuration ||
+ ((pMeasReq->measDuration.shortChannelScanDuration <
+ 1)) ||
+ !pMeasReq->measDuration.longChannelScanDuration ||
+ (pMeasReq->measDuration.longChannelScanDuration <
+ pMeasReq->measDuration.shortChannelScanDuration) ||
+ ((pMeasReq->measDuration.longChannelScanDuration <
+ 1)))
+#else
+ if (!pMeasReq->channelList.numChannels ||
+ ((pMeasReq->measControl.periodicMeasEnabled) &&
+ (!pMeasReq->measIndPeriod)) ||
+ (pMeasReq->measIndPeriod &&
+ ((pMeasReq->measIndPeriod < SYS_TICK_DUR_MS))) ||
+ !pMeasReq->measDuration.shortTermPeriod ||
+ ((pMeasReq->measDuration.shortTermPeriod < SYS_TICK_DUR_MS)) ||
+ !pMeasReq->measDuration.averagingPeriod ||
+ (pMeasReq->measDuration.averagingPeriod <
+ pMeasReq->measDuration.shortTermPeriod) ||
+ !pMeasReq->measDuration.shortChannelScanDuration ||
+ ((pMeasReq->measDuration.shortChannelScanDuration <
+ SYS_TICK_DUR_MS)) ||
+ !pMeasReq->measDuration.longChannelScanDuration ||
+ (pMeasReq->measDuration.longChannelScanDuration <
+ pMeasReq->measDuration.shortChannelScanDuration) ||
+ ((pMeasReq->measDuration.longChannelScanDuration <
+ SYS_TICK_DUR_MS)))
+
+
+#endif
+ {
+ limLog(pMac, LOGW,
+ FL("Received MEASUREMENT_REQ with invalid data\n"));
+
+ return eANI_BOOLEAN_FALSE;
+ }
+ else
+ return eANI_BOOLEAN_TRUE;
+
+} /*** end limIsSmeMeasurementReqValid() ***/
+
+
+/**
+ * limInitMeasResources()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_MEASUREMENT_REQ. This function initializes
+ * resources required for making measurements like creating
+ * timers related to Measurement Request etc.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param None
+ * @return None
+ */
+
+inline static tSirRetStatus
+limInitMeasResources(tpAniSirGlobal pMac)
+{
+ tANI_U32 val;
+ tANI_U32 beaconInterval;
+
+
+ // Create Meas related timers only when
+ // periodic measurements are enabled
+ if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
+ {
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measIndPeriod);
+ if (tx_timer_create(
+ &pMac->lim.gLimMeasParams.measurementIndTimer,
+ "Meas Ind TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_MEASUREMENT_IND_TIMEOUT,
+ val,
+ val,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create MeasInd timer.
+ // Log error
+ limLog(pMac, LOGP, FL("call to create MeasInd timer failed\n"));
+
+ return eSIR_SYS_TX_TIMER_CREATE_FAILED;
+ }
+ pMac->lim.gLimMeasParams.isMeasIndTimerActive = 0;
+ PELOG3(limLog(pMac, LOG3, FL("MeasurementIndication timer initialized, period = %d\n"),
+ pMac->lim.gpLimMeasReq->measIndPeriod);)
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.gLimMeasParams.measurementIndTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+ }
+
+ tANI_U32 learnInterval =
+ pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod /
+ pMac->lim.gpLimMeasReq->channelList.numChannels;
+ if (tx_timer_create(&pMac->lim.gLimMeasParams.learnIntervalTimer,
+ "Learn interval TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_LEARN_INTERVAL_TIMEOUT,
+ SYS_MS_TO_TICKS(learnInterval),
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create learnInterval timer.
+ // Log error
+ limLog(pMac, LOGP, FL("call to create learnInterval timer failed\n"));
+
+ return eSIR_SYS_TX_TIMER_CREATE_FAILED;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration);
+ if (tx_timer_create(
+ &pMac->lim.gLimMeasParams.learnDurationTimer,
+ "Learn duration TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_LEARN_DURATION_TIMEOUT,
+ val,
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create LearnDuration timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to create LearnDuration timer failed\n"));
+
+ return eSIR_SYS_TX_TIMER_CREATE_FAILED;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.gLimMeasParams.learnDurationTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+
+ #if 0
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &beaconInterval) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Can't read beacon interval\n"));
+ return eSIR_FAILURE;
+ }
+ #endif // TO SUPPORT BT-AMP
+
+ /* Copy the beacon interval from the sessio Id */
+ beaconInterval = psessionEntry->beaconParams.beaconInterval;
+
+ if ((learnInterval > ( 2 * beaconInterval)) &&
+ (pMac->lim.gLimSystemRole == eLIM_AP_ROLE))
+ {
+ //learinterval should be > 2 * beaconinterval
+ val = SYS_MS_TO_TICKS(learnInterval - (2 * beaconInterval));
+ // Create Quiet BSS Timer
+ if( TX_SUCCESS !=
+ tx_timer_create( &pMac->lim.limTimers.gLimQuietBssTimer,
+ "QUIET BSS TIMER",
+ limQuietBssTimerHandler,
+ SIR_LIM_QUIET_BSS_TIMEOUT,
+ val, // initial_ticks
+ 0, // reschedule_ticks
+ TX_NO_ACTIVATE ))
+ {
+ limLog( pMac, LOGP,
+ FL( "Failed to create gLimQuietBssTimer!\n" ));
+ return eSIR_SYS_TX_TIMER_CREATE_FAILED;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.limTimers.gLimQuietBssTimer,
+ LIM_TIMER_EXPIRY_LIST );
+#endif
+ pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_TRUE;
+ }
+
+ pMac->lim.gLimMeasParams.shortDurationCount = 0;
+ pMac->lim.gLimMeasParams.nextLearnChannelId = 0;
+
+ pMac->lim.gLimMeasParams.rssiAlpha =
+ (100 * pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod) /
+ pMac->lim.gpLimMeasReq->measDuration.averagingPeriod;
+
+ if (!pMac->lim.gLimMeasParams.rssiAlpha)
+ pMac->lim.gLimMeasParams.rssiAlpha = 1;
+
+ pMac->lim.gLimMeasParams.chanUtilAlpha =
+ (100 * learnInterval) / pMac->lim.gpLimMeasReq->measIndPeriod;
+
+ if (!pMac->lim.gLimMeasParams.chanUtilAlpha)
+ pMac->lim.gLimMeasParams.chanUtilAlpha = 1;
+
+ return eSIR_SUCCESS;
+} /*** end limInitMeasResources() ***/
+
+
+/**-----------------------------------------------
+\fn __limFreeMeasAndSendRsp
+\brief Free the meas related resources and send
+ response to SME.
+\param pMac
+\param resultCode
+\return None
+ ------------------------------------------------*/
+static void
+__limFreeMeasAndSendRsp(tpAniSirGlobal pMac, tSirResultCodes resultCode)
+{
+ if (pMac->lim.gpLimMeasReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasReq);
+ pMac->lim.gpLimMeasReq = NULL;
+ }
+
+ if (pMac->lim.gpLimMeasData != NULL)
+ {
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData);
+ pMac->lim.gpLimMeasData = NULL;
+ }
+
+ /// Send failure response to WSM
+ limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP, resultCode);
+}
+
+/**
+ * limProcessSmeMeasurementReq()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_MEASUREMENT_REQ from WSM.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ *
+ * @return None
+ */
+
+static void
+limProcessSmeMeasurementReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ PELOG1(limLog(pMac, LOG1, FL("SME State = %d\n"), pMac->lim.gLimSmeState);)
+ switch (pMac->lim.gLimSmeState)
+ {
+ case eLIM_SME_OFFLINE_STATE:
+ case eLIM_SME_IDLE_STATE:
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ case eLIM_SME_NORMAL_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ case eLIM_SME_CHANNEL_SCAN_STATE:
+ case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+ break;
+
+ default:
+ limLog(pMac, LOGE,
+ FL("Received unexpected MeasReq message in state %X\n"),
+ pMac->lim.gLimSmeState);
+
+ /// Send failure response to host
+ limSendSmeRsp(
+ pMac,
+ eWNI_SME_MEASUREMENT_RSP,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE);
+ return;
+ } // end switch (pMac->lim.gLimSmeState)
+
+ if (pMac->lim.gpLimMeasReq)
+ {
+ // There was a previous measurement req issued.
+ // Cleanup resources allocated for that request.
+ limDeleteMeasTimers(pMac);
+ limCleanupMeasData(pMac);
+ }
+ else
+ {
+ // There was no previous measurement req issued.
+ // Allocate memory required to hold measurements.
+ if (eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,
+ (void **)&pMac->lim.gpLimMeasData,
+ sizeof(tLimMeasData)))
+ {
+ // Log error
+ limLog(pMac, LOGE,
+ FL("memory allocate failed for MeasData\n"));
+
+ /// Send failure response to host
+ limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP,
+ eSIR_SME_RESOURCES_UNAVAILABLE);
+ return;
+ }
+
+ palZeroMemory(pMac->hHdd, (void *)pMac->lim.gpLimMeasData,
+ sizeof(tLimMeasData));
+ pMac->lim.gpLimMeasData->duration = 120;
+ }
+
+ if (eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,
+ (void **)&pMac->lim.gpLimMeasReq,
+ (sizeof(tSirSmeMeasurementReq) +
+ SIR_MAX_NUM_CHANNELS)))
+ {
+ // Log error
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for MeasReq\n"));)
+
+ __limFreeMeasAndSendRsp(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
+ return;
+ }
+
+ if ((limMeasurementReqSerDes(
+ pMac,
+ pMac->lim.gpLimMeasReq,
+ (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ !limIsSmeMeasurementReqValid(pMac,pMac->lim.gpLimMeasReq))
+ {
+ limLog(pMac, LOGE,
+ FL("Rx'ed MeasReq message with invalid parameters\n"));
+
+ __limFreeMeasAndSendRsp(pMac, eSIR_SME_INVALID_PARAMETERS);
+ return;
+ }
+#ifdef ANI_AP_SDK
+ /* convert from mS to TU and TICKS */
+ limConvertScanDuration(pMac);
+#endif /* ANI_AP_SDK */
+
+ // Initialize Measurement related resources
+ if (limInitMeasResources(pMac) != eSIR_SUCCESS)
+ {
+ __limFreeMeasAndSendRsp(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
+ return;
+ }
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("NumChannels=%d, shortDuration=%d, shortInterval=%d, longInterval=%d\n"),
+ pMac->lim.gpLimMeasReq->channelList.numChannels,
+ pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod,
+ pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration,
+ pMac->lim.gpLimMeasReq->measDuration.longChannelScanDuration);)
+
+ limRadarInit(pMac);
+
+ /**
+ * Start Learn interval timer so that
+ * measurements are made from that
+ * timeout onwards.
+ */
+ limReEnableLearnMode(pMac);
+
+ /// All is well with MeasReq. Send response to WSM
+ limSendSmeRsp(pMac, eWNI_SME_MEASUREMENT_RSP,
+ eSIR_SME_SUCCESS);
+ PELOG2(limLog(pMac, LOG2, FL("Sending succes response to SME\n"));)
+
+ if (pMac->lim.gpLimMeasReq->channelList.numChannels == 1)
+ limLog(pMac, LOGE, FL("Starting Channel Availability Check on Channel %d... Wait\n"),
+ *pMac->lim.gpLimMeasReq->channelList.channelNumber);
+} /*** end limProcessSmeMeasurementReq() ***/
+
+
+/**
+ * limProcessSmeSetWdsInfoReq()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_SET_WDS_INFO_REQ from WSM.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ *
+ * @return None
+ */
+
+static void
+limProcessSmeSetWdsInfoReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 i;
+ tSirSmeSetWdsInfoReq wdsInfoReq;
+
+ pMac->lim.gLimNumWdsInfoSet++;
+
+ switch (pMac->lim.gLimSmeState)
+ {
+ case eLIM_SME_NORMAL_STATE:
+ break;
+
+ default:
+ limLog(pMac, LOGE,
+ FL("Rx'ed unexp SetWdsInfoReq message in state %X\n"),
+ pMac->lim.gLimSmeState);
+
+ /// Send failure response to host
+ limSendSmeRsp(
+ pMac,
+ eWNI_SME_SET_WDS_INFO_RSP,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE);
+ return;
+ } // end switch (pMac->lim.gLimSmeState)
+
+ if ((limWdsReqSerDes( pMac,
+ &wdsInfoReq,
+ (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
+ {
+ limLog(pMac, LOGW,
+ FL("Rx'ed SetWdsInfoReq message with invalid parameters\n"));
+
+ /// Send failure response to WSM
+ limSendSmeRsp(pMac, eWNI_SME_SET_WDS_INFO_RSP,
+ eSIR_SME_INVALID_PARAMETERS);
+
+ return;
+ }
+
+ // check whether the WDS info is the same as current
+ if ((wdsInfoReq.wdsInfo.wdsLength ==
+ psessionEntry->pLimStartBssReq->wdsInfo.wdsLength) &&
+ (palEqualMemory( pMac->hHdd,wdsInfoReq.wdsInfo.wdsBytes,
+ psessionEntry->pLimStartBssReq->wdsInfo.wdsBytes,
+ psessionEntry->pLimStartBssReq->wdsInfo.wdsLength) ) )
+ {
+ /// Send success response to WSM
+ limSendSmeRsp(pMac,
+ eWNI_SME_SET_WDS_INFO_RSP,
+ eSIR_SME_SUCCESS);
+
+ return;
+ }
+
+ // copy WDS info
+ psessionEntry->pLimStartBssReq->wdsInfo.wdsLength =
+ wdsInfoReq.wdsInfo.wdsLength;
+ for (i=0; i<wdsInfoReq.wdsInfo.wdsLength; i++)
+ psessionEntry->pLimStartBssReq->wdsInfo.wdsBytes[i] =
+ wdsInfoReq.wdsInfo.wdsBytes[i];
+
+ schSetFixedBeaconFields(pMac,psessionEntry);
+
+ /// Send success response to WSM
+ limSendSmeRsp(pMac, eWNI_SME_SET_WDS_INFO_RSP,
+ eSIR_SME_SUCCESS);
+
+} /*** end limProcessSmeMeasurementReq() ***/
+
+
+/**
+ * limProcessLearnDurationTimeout()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving LEARN_DURATION_TIMEOUT.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ *
+ * @return None
+ */
+
+static void
+limProcessLearnDurationTimeout(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ if ( pMac->lim.gLimHalScanState == eLIM_HAL_IDLE_SCAN_STATE)
+ {
+ limSendHalInitScanReq(pMac, eLIM_HAL_INIT_LEARN_WAIT_STATE, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN );
+ return;
+ }
+
+ // Current learn duration expired.
+ if (pMac->lim.gLimMeasParams.nextLearnChannelId ==
+ pMac->lim.gpLimMeasReq->channelList.numChannels - 1)
+ {
+ //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);
+ // Send WDA_END_SCAN_REQ to HAL first
+ limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
+ }
+ else
+ {
+ pMac->lim.gLimMeasParams.nextLearnChannelId++;
+
+ if (pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)
+ {
+ // LIM did not take AP/BP role yet.
+ // So continue Learn process on remaining channels
+ // Send WDA_END_SCAN_REQ to HAL first
+ limSendHalEndScanReq(pMac, (tANI_U8)pMac->lim.gLimMeasParams.nextLearnChannelId,
+ eLIM_HAL_END_LEARN_WAIT_STATE);
+ }
+ else
+ {
+ //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);
+ // Send WDA_FINISH_SCAN_REQ to HAL first
+ limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
+ }
+ }
+} /*** end limProcessLearnDurationTimeout() ***/
+
+/**
+ * limProcessLearnIntervalTimeout()
+ *
+ *FUNCTION:
+ * This function is called whenever
+ * SIR_LIM_LEARN_INTERVAL_TIMEOUT message is receive.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ *
+ * @return None
+ */
+
+void
+limProcessLearnIntervalTimeout(tpAniSirGlobal pMac)
+{
+
+#ifdef GEN6_TODO
+ //fetch the sessionEntry based on the sessionId
+ //priority - MEDIUM
+ tpPESession sessionEntry;
+
+ if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.gLimMeasParams.learnIntervalTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+#endif
+
+ PELOG2(limLog(pMac, LOG2, FL("SME state = %d\n"), pMac->lim.gLimSmeState);)
+ if (!pMac->sys.gSysEnableLearnMode)
+ {
+ PELOG3(limLog(pMac, LOG3,
+ FL("Ignoring LEARN_INTERVAL_TIMEOUT because gSysEnableLearnMode is disabled...\n"));)
+ limReEnableLearnMode(pMac);
+ return;
+ }
+
+ if (pMac->lim.gLimSystemInScanLearnMode)
+ {
+ limLog(pMac, LOGE,
+ FL("Sending START_SCAN from LIM while one req is pending\n"));
+ return;
+ }
+
+ pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
+ if ((pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
+ (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ||
+ (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE))
+ pMac->lim.gLimSmeState = eLIM_SME_CHANNEL_SCAN_STATE;
+ else if (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE)
+ pMac->lim.gLimSmeState = eLIM_SME_NORMAL_CHANNEL_SCAN_STATE;
+ else if (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE)
+ pMac->lim.gLimSmeState = eLIM_SME_LINK_EST_WT_SCAN_STATE;
+ else
+ return;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ /* The commented piece of code here is to handle the Measurement Request from WSM as Scan
+ * request in the LIM in Linux Station. Currently, the station uses Measurement request to
+ * get the scan list. If measurement request itself is used for station also while scanning, this
+ * code can be removed. If we need to handle the measurement request as scan request, we need to
+ * implement the below commented code in a more cleaner way(handling the SCAN_CNF, memory freeing, etc)
+ */
+// if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
+ {
+ pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
+ pMac->lim.gLimMlmState = eLIM_MLM_LEARN_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ pMac->lim.gLimSystemInScanLearnMode = eANI_BOOLEAN_TRUE;
+ }
+#if 0
+ /**
+ * start the timer to enter into Learn mode
+ */
+ if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ {
+ tLimMlmScanReq *pMlmScanReq;
+ tANI_U32 len;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmScanReq,
+ (sizeof(tLimMlmScanReq) + WNI_CFG_VALID_CHANNEL_LIST_LEN)))
+ {
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmScanReq\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pMlmScanReq,
+ (tANI_U32)(sizeof(tLimMlmScanReq) + WNI_CFG_VALID_CHANNEL_LIST_LEN ));
+
+ len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+ pMlmScanReq->channelList.channelNumber,
+ &len) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("could not retrieve Valid channel list\n"));
+ }
+ pMlmScanReq->channelList.numChannels = (tANI_U8) len;
+
+ palFillMemory(pMac->hHdd, &pMlmScanReq->bssId, sizeof(tSirMacAddr), 0xff);
+ pMlmScanReq->bssType = eSIR_AUTO_MODE;
+ pMlmScanReq->scanType = eSIR_ACTIVE_SCAN;
+ pMlmScanReq->backgroundScanMode = 0;
+ pMlmScanReq->maxChannelTime = 40;
+ pMlmScanReq->minChannelTime = 20;
+ limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq);
+ }
+ else
+#endif
+ limSetLearnMode(pMac);
+}
+
+
+/**
+ * limProcessLmmMessages()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME messages from WSM and MLM cnf/ind
+ * messages from MLM module.
+ *
+ *LOGIC:
+ * Depending on the message type, corresponding function will be
+ * called.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the SME message type
+ * @param *pMsgBuf A pointer to the SME message buffer
+ *
+ * @return None
+ */
+
+void
+limProcessLmmMessages(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+ switch (msgType)
+ {
+ case eWNI_SME_MEASUREMENT_REQ:
+ PELOG1(limLog(pMac, LOG1, FL("Received MEASUREMENT_REQ message\n"));)
+ limProcessSmeMeasurementReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_SET_WDS_INFO_REQ:
+
+ limProcessSmeSetWdsInfoReq(pMac, pMsgBuf);
+
+ break;
+
+ case SIR_LIM_MEASUREMENT_IND_TIMEOUT:
+ // Time to send Measurement Indication to WSM
+ limSendSmeMeasurementInd(pMac);
+
+ break;
+
+ case SIR_LIM_LEARN_INTERVAL_TIMEOUT:
+ limProcessLearnIntervalTimeout(pMac);
+ break;
+
+ case SIR_LIM_LEARN_DURATION_TIMEOUT:
+ limProcessLearnDurationTimeout(pMac, pMsgBuf);
+
+ break;
+
+ default:
+
+ break;
+ } // switch (msgType)
+
+ return;
+} /*** end limProcessLmmMessages() ***/
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
new file mode 100644
index 0000000..a0d3ca7
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -0,0 +1,2185 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * 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"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#include "halCommonApi.h"
+#elif defined FEATURE_WLAN_INTEGRATED_SOC
+#include "wlan_qct_wdi_ds.h"
+#include "wlan_qct_pal_packet.h"
+#include "wlan_qct_wda.h"
+#endif
+
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#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"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+#if defined FEATURE_WLAN_CCX
+#include "ccxApi.h"
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include "limFT.h"
+#endif
+
+#ifdef WMM_APSD
+#include "wmmApsd.h"
+#endif
+
+#ifdef VOSS_ENABLED
+#include "vos_types.h"
+#include "vos_packet.h"
+#include "vos_memory.h"
+#endif
+
+void limLogSessionStates(tpAniSirGlobal pMac);
+
+/** -------------------------------------------------------------
+\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_SUSPEND_STATE) &&
+ (limMsg->type != SIR_LIM_RESUME_ACTIVITY_NTF))
+ {
+ // Defer processsing this message
+ if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)\n"),
+ 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 != SIR_LIM_RESUME_ACTIVITY_NTF)&&
+ (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) &&
+#ifdef WLAN_FEATURE_P2P
+ (limMsg->type != WDA_P2P_NOA_ATTR_IND) &&
+#endif
+ (limMsg->type != WDA_ADD_TS_RSP))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode\n"),
+ limMsgStr(limMsg->type));)
+
+ // Defer processsing this message
+ if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)\n"),
+ 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);
+
+/**
+ * limProcessMessageQueue
+ *
+ *FUNCTION:
+ * This function is called by LIM thread entry function. This
+ * function fetches messages posted to the message queue
+ * limMsgQ.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limProcessMessageQueue(tpAniSirGlobal pMac)
+{
+ tSirMsgQ limMsg = { 0, 0, 0 };
+
+ if(pMac->gDriverType == eDRIVER_TYPE_MFG)
+ {
+ return;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ ULONG param;
+ while(get_timer_event(LIM_TIMER_EXPIRY_LIST,¶m))
+ {
+ limMsg.type = (tANI_U16) param;
+ limMsg.bodyval = 0;
+ limMsg.bodyptr = NULL;
+ limMessageProcessor(pMac, &limMsg);
+ }
+#endif
+
+ if (tx_queue_receive( &pMac->sys.gSirLimMsgQ, (void *) &limMsg, TX_WAIT_FOREVER)
+ == TX_SUCCESS)
+ {
+ PELOG3(limLog(pMac, LOG3, FL("LIM Received message %s\n"), limMsgStr(limMsg.type));)
+ limPrintMsgInfo(pMac, LOG3, &limMsg);
+ limMessageProcessor(pMac, &limMsg);
+ } // if (tx_queue_receive)
+
+} /*** end limProcessMessageQueue() ***/
+
+
+
+/**
+ * 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;
+#if defined(ANI_OS_TYPE_LINUX) || defined(ANI_OS_TYPE_OSX)
+ PELOG3(limLog(pMac, LOG3, FL("Deferring message %X in Learn mode\n"),
+ pMsg->type);
+ limPrintMsgName(pMac, LOG3, pMsg->type);)
+ retCode = tx_queue_send(&pMac->sys.gSirLimDeferredMsgQ,
+ pMsg,
+ TX_NO_WAIT);
+ if (retCode == TX_SUCCESS)
+ pMac->lim.gLimNumDeferredMsgs++;
+#else
+
+ retCode = limWriteDeferredMsgQ(pMac, pMsg);
+
+#endif
+ if(retCode == TX_SUCCESS)
+ {
+ MTRACE(macTraceMsgRx(pMac, 0, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED));)
+ }
+ else
+ {
+ MTRACE(macTraceMsgRx(pMac, 0, 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;
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ tANI_U32 ignore = 0;
+ tSirMacAddr bssIdRcv;
+#endif
+
+ *deferMsg = false;
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ fc = pHdr->fc;
+ limLog( pMac, LOG2, FL("ProtVersion %d, Type %d, Subtype %d\n"),
+ fc.protVer, fc.type, fc.subType );
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // System is in DFS (Learn) mode
+ pMac->lim.numLearn++;
+
+ // Process all BDs and extract PHY stats
+ limGetBssidFromBD(pMac, (tpHalBufDesc) pRxPacketInfo, bssIdRcv, &ignore);
+
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ palEqualMemory( pMac->hHdd,bssIdRcv, psessionEntry->bssId, sizeof(tSirMacAddr)))
+ {
+ /**
+ * Frame from current BSS. Defer processing of
+ * Disassociation/Deauthentication from
+ * STAs that are currently associated.
+ * Collect stats for other received frames.
+ */
+ if ((fc.subType == SIR_MAC_MGMT_DISASSOC) ||
+ (fc.subType == SIR_MAC_MGMT_DEAUTH))
+ {
+ 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)\n"),
+ limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
+ pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
+ limLogSessionStates(pMac);
+ limPrintMsgName(pMac, LOGE, limMsg->type);
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, NULL, limMsg->bodyptr);
+ }
+ return;
+ }
+ pMac->lim.numLearnIgnore++;
+ }
+ else
+ {
+ // Frame received from other BSS
+ if (fc.type == SIR_MAC_DATA_FRAME && psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ /**
+ * Data Frame from neighbor BSS.
+ * Extract neighbor BSS info as much as possible.
+ */
+ limCollectMeasurementData(pMac, pRxPacketInfo, NULL);
+ }
+ else 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
+ // 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);
+ }
+#if defined WLAN_FEATURE_P2P
+ else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_ACTION))
+ {
+ limProcessActionFrameNoSession( pMac, pRxPacketInfo);
+ }
+#endif
+ else
+ {
+ *deferMsg = true;
+ return;
+ }
+
+#endif
+ 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)
+{
+#ifndef ANI_CHIPSET_VOLANS
+ tpSirMacDataHdr3a pMacHdr;
+
+ /** This prevents from disassoc/deauth being sent in a burst,
+ and gLimDisassocFrameCredit is reset for every 10 seconds.*/
+ if (pMac->lim.gLimDisassocFrameCredit > pMac->lim.gLimDisassocFrameThreshold)
+ return;
+
+ pMac->lim.gLimDisassocFrameCredit++;
+
+ pMacHdr = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo);
+
+ if (limIsGroupAddr(pMacHdr->addr2))
+ {
+ PELOG2(limLog(pMac, LOG2, FL("Ignoring A2 Invalid Packet received for MC/BC:\n"));
+ limPrintMacAddr(pMac, pMacHdr->addr2, LOG2);)
+
+ return;
+ }
+
+ if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )&&
+ (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))
+ {
+ switch (pMacHdr->fc.type)
+ {
+ case SIR_MAC_MGMT_FRAME:
+ switch (pMacHdr->fc.subType)
+ {
+ case SIR_MAC_MGMT_ACTION:
+ // Send Disassociation frame to
+ // sender if role is AP
+ PELOG1(limLog(pMac, LOG1, FL("Send Disassoc Frame due to Invalid Addr2 packet"));
+ limPrintMacAddr(pMac, pMacHdr->addr2, LOG1);)
+ limSendDisassocMgmtFrame(pMac,
+ eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMacHdr->addr2,psessionEntry);
+ break;
+
+ default:
+ break;
+
+ }
+ break;
+
+ case SIR_MAC_CTRL_FRAME:
+ switch (pMacHdr->fc.subType)
+ {
+ case SIR_MAC_CTRL_PS_POLL:
+ case SIR_MAC_CTRL_BAR:
+ // Send Disassociation frame to
+ // sender if role is AP
+ PELOG1(limLog(pMac, LOG1, FL("Send Disassoc Frame due to Invalid Addr2 packet"));
+ limPrintMacAddr(pMac, pMacHdr->addr2, LOG1);)
+ limSendDisassocMgmtFrame(pMac,
+ eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMacHdr->addr2,psessionEntry);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SIR_MAC_DATA_FRAME:
+ switch (pMacHdr->fc.subType)
+ {
+ case SIR_MAC_DATA_NULL:
+ case SIR_MAC_DATA_QOS_NULL:
+ // Send Disassociation frame to
+ // sender if role is AP
+ PELOG1(limLog(pMac, LOG1, FL("Send Disassoc Frame due to Invalid Addr2 packet"));
+ limPrintMacAddr(pMac, pMacHdr->addr2, LOG1);)
+ limSendDisassocMgmtFrame(pMac,
+ eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMacHdr->addr2,psessionEntry);
+ break;
+
+ default:
+ // Send Deauthentication frame to
+ // sender if role is AP
+ PELOG1(limLog(pMac, LOG1, FL("Sending Deauth frame due to Invalid Addr2 packet"));
+ limPrintMacAddr(pMac, pMacHdr->addr2, LOG1);)
+ limSendDeauthMgmtFrame(pMac,
+ eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMacHdr->addr2,psessionEntry);
+ break;
+ }
+ break;
+ }
+ }
+#else
+ /* 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);
+#if defined WLAN_FEATURE_P2P
+ //This could be a public action frame.
+ if( psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE )
+ limProcessActionFrameNoSession(pMac, (tANI_U8 *) pRxPacketInfo);
+#endif
+#endif
+
+ return;
+}
+
+#ifdef WLAN_FEATURE_P2P
+/**
+ * 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\n"));
+ match = VOS_TRUE;
+ break;
+ }
+
+ if (pLimMgmtRegistration->frameType == frameType)
+ {
+ if (pLimMgmtRegistration->matchLen > 0)
+ {
+ if (pLimMgmtRegistration->matchLen <= framelen)
+ {
+ if (palEqualMemory(pMac, 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\n"));
+
+ /* Indicate this to SME */
+ limSendSmeMgmtFrameInd( pMac, pHdr->fc.subType, (tANI_U8*)pHdr,
+ WDA_GET_RX_PAYLOAD_LEN(pBd) + sizeof(tSirMacMgmtHdr),
+ pLimMgmtRegistration->sessionId,
+ WDA_GET_RX_CH(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() ***/
+#endif /* WLAN_FEATURE_P2P */
+
+
+/**
+ * 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;
+
+ *pDeferMsg= false;
+ limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo);
+
+ 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;
+
+ limLog( pMac, LOG1, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d\n"),
+ fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+
+
+#ifdef FEATURE_WLAN_CCX
+ if (fc.type == SIR_MAC_DATA_FRAME && isFrmFt)
+ {
+#if 0 // CCX 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->isCCXconnection)
+ {
+ limLog( pMac, LOGE, FL("LIM received Type %d, Subtype %d in Non CCX connection\n"),
+ 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 CCX\n", __func__);
+#endif
+
+
+ } else
+#endif
+ /* 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, LOGE, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d\n"),
+ fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+ limPrintMacAddr(pMac, pHdr->bssId, LOGE);
+#endif
+ if (limProcessAuthFrameNoSession(pMac, pRxPacketInfo, limMsg->bodyptr) == eSIR_SUCCESS)
+ {
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr);
+ return;
+ }
+ }
+#endif
+ if((fc.subType != SIR_MAC_MGMT_PROBE_RSP )&&
+ (fc.subType != SIR_MAC_MGMT_BEACON)&&
+ (fc.subType != SIR_MAC_MGMT_PROBE_REQ)
+#if defined WLAN_FEATURE_P2P
+ && (fc.subType != SIR_MAC_MGMT_ACTION ) //Public action frame can be received from non-associated stations.
+#endif
+ )
+ {
+
+ if((psessionEntry = peFindSessionByPeerSta(pMac,pHdr->sa,&sessionId))== NULL)
+ {
+ limLog(pMac, LOG1, FL("session does not exist for given bssId\n"));
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr);
+ return;
+ }
+ }
+ }
+
+
+#ifdef WLAN_FEATURE_P2P
+ /* Check if frame is registered by HDD */
+ if(limCheckMgmtRegisteredFrames(pMac, pRxPacketInfo, psessionEntry))
+ {
+ limLog( pMac, LOG1, FL("Received frame is passed to SME\n"));
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, limMsg->bodyptr);
+ return;
+ }
+#endif
+
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) && (LIM_IS_RADAR_DETECTED(pMac)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Droping the received packets as radar is detected\n"));)
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr);
+ return;
+ }
+#endif
+
+ if (fc.protVer != SIR_MAC_PROTOCOL_VERSION)
+ { // Received Frame with non-zero Protocol Version
+ limLog(pMac, LOGE, FL("Unexpected frame with protVersion %d received\n"),
+ fc.protVer);
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr);
+#ifdef WLAN_DEBUG
+ pMac->lim.numProtErr++;
+#endif
+ return;
+ }
+
+
+ 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...\n" ),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...\n"),
+ 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)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ )
+ limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_ASSOC, psessionEntry);
+
+ else
+ {
+ // Unwanted messages - Log error
+ limLog(pMac, LOGE, FL("unexpected message received %X\n"),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)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ ){
+ limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_REASSOC, psessionEntry);
+ }
+ else
+ {
+ // Unwanted messages - Log error
+ limLog(pMac, LOGE, FL("unexpected message received %X\n"),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 defined WLAN_FEATURE_P2P
+ if(psessionEntry == NULL)
+ limProcessActionFrameNoSession(pMac, pRxPacketInfo);
+ else
+ {
+#endif
+ if (WDA_GET_RX_UNKNOWN_UCAST(pRxPacketInfo))
+ limHandleUnknownA2IndexFrames(pMac, pRxPacketInfo,psessionEntry);
+ else
+ limProcessActionFrame(pMac, pRxPacketInfo,psessionEntry);
+#if defined WLAN_FEATURE_P2P
+ }
+#endif
+ break;
+ default:
+ // Received Management frame of 'reserved' subtype
+ break;
+ } // switch (fc.subType)
+
+ }
+ break;
+#ifdef FEATURE_WLAN_CCX
+ case SIR_MAC_DATA_FRAME:
+ {
+ /* We accept data frame (IAPP frame) only if Session is
+ * present and ccx connection is established on that
+ * session
+ */
+ if (psessionEntry && psessionEntry->isCCXconnection) {
+ limProcessIappFrame(pMac, pRxPacketInfo, psessionEntry);
+ }
+ }
+ break;
+#endif
+ default:
+ // Received frame of type 'reserved'
+ break;
+
+ } // switch (fc.type)
+
+ limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr) ;
+ return;
+} /*** end limHandle80211Frames() ***/
+
+
+/**
+ * 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)
+{
+#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
+ */
+ PELOGE(limLog(pMac, LOGE, FL("Processing AbortScan Ind\n"));)
+
+ limAbortBackgroundScan(pMac);
+
+ /* 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\n"), pMac->lim.gLimHalScanState );
+ pMac->lim.abortScan = 1;
+ }
+ else
+ {
+ //Force abort
+ limLog( pMac, LOGW, FL(" Force aborting scan\n") );
+ 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);
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ // process deferred message queue if allowed
+ {
+ if ( (! (pMac->lim.gLimAddtsSent))
+ &&
+ (! (limIsSystemInScanState(pMac)))
+ )
+ {
+ if (true == GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ limProcessDeferredMessageQueue(pMac);
+ }
+ }
+#else
+ {
+ // process deferred message queue if allowed
+ if (! (pMac->lim.gLimSystemInScanLearnMode))
+ {
+#if defined(ANI_AP_CLIENT_SDK)
+ if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE && (pMac->lim.gLimAddtsSent))
+ return;
+#endif
+
+ if (true == GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ limProcessDeferredMessageQueue(pMac);
+ }
+ }
+#endif
+ }
+}
+
+
+
+/**
+ * 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)
+ {
+ return;
+ }
+#ifdef WLAN_DEBUG
+ pMac->lim.numTot++;
+#endif
+
+
+ PELOG3(limLog(pMac, LOG3, FL("rcvd msgType = %s, sme state = %s, mlm state = %s\n"),
+ limMsgStr(limMsg->type), limSmeStateStr(pMac->lim.gLimSmeState),
+ limMlmStateStr(pMac->lim.gLimMlmState));)
+
+ MTRACE(macTraceMsgRx(pMac, 0, LIM_TRACE_MAKE_RXMSG(limMsg->type, LIM_MSG_PROCESSED));)
+
+ switch (limMsg->type)
+ {
+#if defined(ANI_DVT_DEBUG)
+ case SIR_LIM_SUSPEND_ACTIVITY_REQ:
+ // This message is from HAL notifying LIM
+ // to suspend activity. (PTT needs)
+ // Disable TFP & RHP
+ //halSetStaTxEnable(pMac, 1, eHAL_CLEAR);
+ //halStopDataTraffic(pMac);
+ //halSetRxEnable(pMac, eHAL_CLEAR);
+
+ pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
+ pMac->lim.gLimSmeState = eLIM_SME_SUSPEND_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ // Post message back to HAL
+ msgQ.type = WDA_SUSPEND_ACTIVITY_RSP;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ wdaPostCtrlMsg(pMac, &msgQ);
+ break;
+#endif
+
+ case SIR_LIM_UPDATE_BEACON:
+ limUpdateBeacon(pMac);
+ break;
+
+ case SIR_LIM_RESUME_ACTIVITY_NTF:
+ // This message is from HAL notifying LIM
+ // to resume activity.
+ if (pMac->lim.gLimSmeState == eLIM_SME_SUSPEND_STATE)
+ {
+ limLog(pMac, LOGE,
+ FL("Received RESUME_NTF in State %s on Role %d\n"),
+ limSmeStateStr(pMac->lim.gLimSmeState), pMac->lim.gLimSystemRole);
+ pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ handleCBCFGChange( pMac, ANI_IGNORE_CFG_ID );
+ handleHTCapabilityandHTInfo(pMac);
+ //initialize the TSPEC admission control table.
+ limAdmitControlInit(pMac);
+ limRegisterHalIndCallBack(pMac);
+ }
+ else
+ {
+ limLog(pMac, LOGE,
+ FL("Received RESUME_NTF in inval State %X on Role %d\n"),
+ pMac->lim.gLimSmeState, pMac->lim.gLimSystemRole);
+ limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState);
+ }
+
+ 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)
+ {
+ 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)\n"),
+ 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);
+ break;
+
+ case WDA_START_SCAN_RSP:
+ limProcessStartScanRsp(pMac, limMsg->bodyptr);
+ break;
+
+ case WDA_END_SCAN_RSP:
+ limProcessEndScanRsp(pMac, limMsg->bodyptr);
+ break;
+
+ case WDA_FINISH_SCAN_RSP:
+ limProcessFinishScanRsp(pMac, limMsg->bodyptr);
+ break;
+
+ case WDA_SWITCH_CHANNEL_RSP:
+ limProcessSwitchChannelRsp(pMac, limMsg->bodyptr);
+ 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
+
+#ifdef VOSS_ENABLED
+ {
+ 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
+ */
+ palCopyMemory(pMac, (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) )
+ {
+ vos_pkt_return_packet(pVosPkt);
+ break;
+
+ }
+ limHandle80211Frames(pMac, &limMsgNew, &deferMsg);
+
+ if ( deferMsg == true )
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Defer message type=%X \n"), 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)\n"),
+ limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
+ pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
+ limLogSessionStates(pMac);
+ limPrintMsgName(pMac, LOGE, limMsg->type);
+ 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.
+ */
+ vos_pkt_return_packet(pVosPkt);
+ }
+ }
+#else
+ limHandle80211Frames(pMac, limMsg);
+#endif
+ break;
+
+ case eWNI_SME_SCAN_REQ:
+#ifdef WLAN_FEATURE_P2P
+ case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
+#endif
+ case eWNI_SME_DISASSOC_REQ:
+ case eWNI_SME_DEAUTH_REQ:
+ 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_SCANNED_CHANNEL_REQ:
+ case eWNI_SME_GET_STATISTICS_REQ:
+ // These messages are from HDD
+ limProcessNormalHddMsg(pMac, limMsg, true); //need to response to hdd
+ break;
+
+ case eWNI_SME_SCAN_ABORT_IND:
+ vos_mem_free((v_VOID_t *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ limProcessAbortScanInd(pMac);
+ 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:
+#ifdef WLAN_SOFTAP_FEATURE
+ 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:
+#endif
+#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_CCX
+ case eWNI_SME_CCX_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
+ case eWNI_SME_ADD_STA_SELF_REQ:
+ case eWNI_SME_DEL_STA_SELF_REQ:
+#ifdef WLAN_FEATURE_P2P
+ case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+ case eWNI_SME_UPDATE_NOA:
+#endif
+ // 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 :
+ {
+#ifdef SUPPORT_eWNI_PMC_SMPS_STATE_IND
+ tSirMbMsg *pMBMsg;
+ tSirMacHTMIMOPowerSaveState mimoPSstate;
+ /** Is System processing any SMPS Indication*/
+ if (!limIsSystemInSetMimopsState(pMac))
+ {
+ pMBMsg = (tSirMbMsg *)limMsg->bodyptr;
+ palCopyMemory(pMac->hHdd, &mimoPSstate, pMBMsg->data, sizeof(tSirMacHTMIMOPowerSaveState));
+ limSMPowerSaveStateInd(pMac, mimoPSstate);
+ }
+ else
+ {
+ 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)\n"),
+ limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
+ pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
+ limLogSessionStates(pMac);
+ limPrintMsgName(pMac, LOGE, limMsg->type);
+ }
+ }
+#endif
+ if(limMsg->bodyptr){
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ }
+ }
+ break;
+#if defined WLAN_FEATURE_P2P
+ case eWNI_SME_SEND_ACTION_FRAME_IND:
+ limSendP2PActionFrame(pMac, limMsg);
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+ case eWNI_SME_ABORT_REMAIN_ON_CHAN_IND:
+ limAbortRemainOnChan(pMac);
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+ 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\n"), limMsg->type);
+ for(i=0; i < pMac->lim.maxBssId; i++)
+ {
+ if ( (psessionEntry != NULL) && (pMac->lim.gpSession[i].valid) &&
+ (psessionEntry->pePersona == VOS_P2P_GO_MODE))
+ { //Save P2P attributes for P2P Go persona
+
+ palCopyMemory(pMac->hHdd,&psessionEntry->p2pGoPsUpdate, limMsg->bodyptr,sizeof(tSirP2PNoaAttr));
+
+
+ limLog(pMac, LOGE, FL(" &psessionEntry->bssId%02x:%02x:%02x:%02x:%02x:%02x ctWin=%d oppPsFlag=%d\n"),
+ psessionEntry->bssId[0],
+ psessionEntry->bssId[1],
+ psessionEntry->bssId[2],
+ psessionEntry->bssId[3],
+ psessionEntry->bssId[4],
+ psessionEntry->bssId[5],
+ psessionEntry->p2pGoPsUpdate.ctWin,
+ psessionEntry->p2pGoPsUpdate.oppPsFlag);
+
+ limLog(pMac, LOGE, FL(" uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d\n"),
+ psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt,
+ psessionEntry->p2pGoPsUpdate.uNoa1Duration,
+ psessionEntry->p2pGoPsUpdate.uNoa1Interval,
+ psessionEntry->p2pGoPsUpdate.uNoa1StartTime);
+
+
+ break;
+ }
+ }
+
+ }
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+
+ break;
+
+
+#endif
+ /* 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:
+ limProcessChannelSwitchTimeout(pMac);
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)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;
+
+ case WDA_MISSED_BEACON_IND:
+ limHandleMissedBeaconInd(pMac);
+ break;
+ case WDA_MIC_FAILURE_IND:
+ limMicFailureInd(pMac, limMsg);
+ palFreeMemory(pMac->hHdd, (tANI_U8 *)limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ break;
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ case eWNI_SME_MEASUREMENT_REQ:
+ case eWNI_SME_SET_WDS_INFO_REQ:
+ // Message to support ANI feature set
+ // These are handled by LMM sub module
+ if (limIsSystemInScanState(pMac))
+ {
+ // System is in DFS (Learn) mode
+ // Defer processsing this message
+ if (limDeferMsg(pMac, limMsg) != TX_SUCCESS)
+ {
+ pMac->lim.numSme++;
+ 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)\n"),
+ limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
+ pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
+ limLogSessionStates(pMac);
+ limPrintMsgName(pMac, LOGE, limMsg->type);
+ // Release body
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) limMsg->bodyptr);
+ break;
+ }
+
+ if (limMsg->type == eWNI_SME_MEASUREMENT_REQ)
+ {
+ if (GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ {
+ //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_LEARN_WAIT_STATE);
+ }
+ }
+ }
+ else
+ {
+ pMac->lim.numSme++;
+ limProcessLmmMessages(pMac,
+ limMsg->type,
+ (tANI_U32 *) limMsg->bodyptr);
+
+ // Release body
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) limMsg->bodyptr);
+ }
+ break;
+
+ case SIR_LIM_LEARN_INTERVAL_TIMEOUT:
+ if ((pMac->lim.gLimSystemRole == eLIM_STA_ROLE) &&
+ ((pMac->lim.gLimMlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)))
+ {
+ // BP is in the process of cleaning up
+ // its state with previously assocaited AP.
+ // Discard processsing this message.
+ PELOG1(limLog(pMac, LOG1,
+ FL("Discarding LEARN_INTERVAL_TO message\n"));)
+ }
+ else
+ limProcessLmmMessages(pMac,
+ limMsg->type,
+ (tANI_U32 *) limMsg->bodyptr);
+ break;
+
+ case SIR_LIM_MEASUREMENT_IND_TIMEOUT:
+ case SIR_LIM_LEARN_DURATION_TIMEOUT:
+ // These measurement related timeouts are
+ // handled by LMM sub module.
+ limProcessLmmMessages(pMac,
+ limMsg->type,
+ (tANI_U32 *) limMsg->bodyptr);
+
+ break;
+
+ case SIR_LIM_RADAR_DETECT_IND:
+ limDetectRadar(pMac, (tANI_U32*)limMsg->bodyptr);
+ palFreeMemory( pMac->hHdd, (tANI_U32*)limMsg->bodyptr);
+ break;
+
+#endif
+
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ limProcessSmeReqMessages(pMac,limMsg);
+ break;
+#ifdef FEATURE_WLAN_CCX
+ case SIR_LIM_CCX_TSM_TIMEOUT:
+ limProcessTsmTimeoutHandler(pMac,limMsg);
+ break;
+ case WDA_TSM_STATS_RSP:
+ limProcessHalCcxTsmRsp(pMac, limMsg);
+ break;
+#endif
+ case WDA_ADD_TS_RSP:
+ limProcessHalAddTsRsp(pMac, limMsg);
+ break;
+
+ case SIR_LIM_DEL_TS_IND:
+ limProcessDelTsInd(pMac, limMsg);
+ case SIR_LIM_ADD_BA_IND:
+ limProcessAddBaInd(pMac, limMsg);
+ break;
+ case SIR_LIM_DEL_BA_ALL_IND:
+ limDelAllBASessions(pMac); // refer notes and change
+ break;
+ case SIR_LIM_DEL_BA_IND:
+ limProcessMlmHalBADeleteInd( pMac, limMsg );
+ break;
+
+ case SIR_LIM_BEACON_GEN_IND: {
+#ifdef ANI_PRODUCT_TYPE_AP
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ pmmUpdateTIM(pMac, (tpBeaconGenParams)limMsg->bodyptr);
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if( pMac->lim.gLimSystemRole != eLIM_AP_ROLE )
+#endif
+ 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_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
+#ifdef WLAN_FEATURE_P2P
+ case SIR_LIM_REMAIN_CHN_TIMEOUT:
+#endif
+ // 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\n"),
+ 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
+
+ limHandleHeartBeatTimeout(pMac);
+ break;
+
+ case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
+ limHandleHeartBeatFailureTimeout(pMac);
+ break;
+
+ case SIR_LIM_CHANNEL_SCAN_TIMEOUT:
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ /**
+ * 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);
+#endif
+ break;
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ case SIR_LIM_PREAUTH_CLNUP_TIMEOUT:
+ 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)\n"),
+ limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState,
+ pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);)
+ limLogSessionStates(pMac);
+ }
+ }
+ else
+ {
+ // Pre-authentication context cleanup timeout message
+ limPreAuthClnupHandler(pMac);
+ }
+
+ break;
+#endif
+
+ case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+
+ /*
+ ** clear the credit to the send disassociate frame bucket
+ **/
+
+ pMac->lim.gLimDisassocFrameCredit = 0;
+ 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;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+ limHandleUpdateOlbcCache(pMac);
+ break;
+#if 0
+ case SIR_LIM_WPS_OVERLAP_TIMEOUT:
+ limProcessWPSOverlapTimeout(pMac);
+ break;
+#endif
+
+#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;
+
+ 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;
+
+#ifdef ANI_CHIPSET_VOLANS
+ case SIR_LIM_ADDR2_MISS_IND:
+ {
+ limLog(pMac, LOGE,
+ FL("Addr2 mismatch interrupt received %X\n"),
+ 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));
+ break;
+ }
+#endif
+
+#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));
+ 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
+
+ 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\n"),
+ 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\n"),
+ 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 };
+
+#if defined(ANI_OS_TYPE_LINUX) || defined(ANI_OS_TYPE_OSX)
+ while (TX_SUCCESS == tx_queue_receive(&pMac->sys.gSirLimDeferredMsgQ, (void *) &limMsg, TX_NO_WAIT))
+ {
+ PELOG3(limLog(pMac, LOG3, FL("Processing deferred message %X\n"), limMsg.type);)
+ limPrintMsgName(pMac, LOG3, limMsg.type);
+ pMac->lim.gLimNumDeferredMsgs--;
+ limProcessMessages(pMac, &limMsg);
+
+ if(true != GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ break;
+ }
+#else
+ 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)
+ {
+ palCopyMemory( pMac->hHdd, (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))
+ break;
+ }
+ }
+#endif
+} /*** 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)\n"),
+ 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
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pLimMsg->bodyptr);
+ }
+ }
+ 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.
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pLimMsg->bodyptr);
+ }
+ }
+}
+
+void
+handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac)
+{
+ tSirMacHTCapabilityInfo macHTCapabilityInfo;
+ tSirMacHTParametersInfo macHTParametersInfo;
+ tSirMacHTInfoField1 macHTInfoField1;
+ tSirMacHTInfoField2 macHTInfoField2;
+ tSirMacHTInfoField3 macHTInfoField3;
+ tANI_U32 cfgValue;
+ tANI_U8 *ptr;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];//TBD-RAJESH HOW TO GET sessionEntry?????
+
+ pMac->lim.htCapability = IS_DOT11_MODE_HT(psessionEntry->dot11mode);
+
+
+
+ // Get HT Capabilities
+ 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\n"));
+ 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.gHTSupportedChannelWidthSet = (tANI_U8)macHTCapabilityInfo.supportedChannelWidthSet;
+ 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\n"));
+ 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\n"));
+ 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;
+ pMac->lim.gHTRecommendedTxWidthSet = (tANI_U8)macHTInfoField1.recommendedTxWidthSet;
+ pMac->lim.gHTSecondaryChannelOffset = (tSirMacHTSecondaryChannelOffset)macHTInfoField1.secondaryChannelOffset;
+
+ 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\n"));
+ 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\n"));
+ 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;
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = (tANI_U8)macHTInfoField3.lsigTXOPProtectionFullSupport;
+ pMac->lim.gHTSecondaryBeacon = (tANI_U8)macHTInfoField3.secondaryBeacon;
+ pMac->lim.gHTDualCTSProtection = (tANI_U8)macHTInfoField3.dualCTSProtection;
+ pMac->lim.gHTSTBCBasicMCS = (tANI_U8)macHTInfoField3.basicSTBCMCS;
+}
+
+void limLogSessionStates(tpAniSirGlobal pMac)
+{
+#ifdef WLAN_DEBUG
+ int i;
+
+ for(i = 0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Session[%d] sysRole(%d) limSmeState %d (prev sme state %d) mlm state %d (prev mlm state %d)\n"),
+ 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
+}
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
new file mode 100644
index 0000000..ade531d
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c
@@ -0,0 +1,4367 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessMlmMessages.cc contains the code
+ * for processing MLM request messages.
+ * Author: Chandra Modumudi
+ * Date: 02/12/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "palTypes.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#include "sirApi.h"
+#include "sirParams.h"
+#include "cfgApi.h"
+
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSecurityUtils.h"
+#include "limSendMessages.h"
+#include "pmmApi.h"
+#include "limSendMessages.h"
+//#include "limSessionUtils.h"
+#include "limSessionUtils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include <limFT.h>
+#endif
+
+
+
+// MLM REQ processing function templates
+static void limProcessMlmStartReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmScanReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmJoinReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmAuthReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmAssocReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmReassocReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmDisassocReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmDeauthReq(tpAniSirGlobal, tANI_U32 *);
+static void limProcessMlmSetKeysReq(tpAniSirGlobal, tANI_U32 *);
+
+static void limProcessMlmAddBAReq( tpAniSirGlobal, tANI_U32 * );
+static void limProcessMlmAddBARsp( tpAniSirGlobal, tANI_U32 * );
+static void limProcessMlmDelBAReq( tpAniSirGlobal, tANI_U32 * );
+
+// MLM Timeout event handler templates
+static void limProcessMinChannelTimeout(tpAniSirGlobal);
+static void limProcessMaxChannelTimeout(tpAniSirGlobal);
+static void limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac);
+static void limProcessJoinFailureTimeout(tpAniSirGlobal);
+static void limProcessAuthFailureTimeout(tpAniSirGlobal);
+static void limProcessAuthRspTimeout(tpAniSirGlobal, tANI_U32);
+static void limProcessAssocFailureTimeout(tpAniSirGlobal, tANI_U32);
+
+static void limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf);
+void
+limSetChannel(tpAniSirGlobal pMac, tANI_U32 titanHtcap, tANI_U8 channel, tPowerdBm maxTxPower, tANI_U8 peSessionId);
+
+
+/*
+ * determine the secondary channel state for hal
+ */
+static ePhyChanBondState
+mlm_get_ext_chnl(
+ tpAniSirGlobal pMac,
+ tAniCBSecondaryMode chnl)
+{
+ if (chnl == eANI_CB_SECONDARY_UP)
+ return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+ if (chnl == eANI_CB_SECONDARY_DOWN)
+ return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+ return PHY_SINGLE_CHANNEL_CENTERED;
+
+}
+
+
+#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_AGGRESSIVE_BACKGROUND_SCAN)
+
+
+/**
+ * limProcessMlmReqMessages()
+ *
+ *FUNCTION:
+ * This function is called by limPostMlmMessage(). This
+ * function handles MLM primitives invoked by SME.
+ *
+ *LOGIC:
+ * Depending on the message type, corresponding function will be
+ * called.
+ *
+ *ASSUMPTIONS:
+ * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
+ * APIs exposed by Beacon Processing module for setting parameters
+ * at MAC hardware.
+ * 2. If attempt to Reassociate with an AP fails, link with current
+ * AP is restored back.
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM primitive message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+
+void
+limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg)
+{
+ switch (Msg->type)
+ {
+ case LIM_MLM_START_REQ: limProcessMlmStartReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_SCAN_REQ: limProcessMlmScanReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_JOIN_REQ: limProcessMlmJoinReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_AUTH_REQ: limProcessMlmAuthReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_ASSOC_REQ: limProcessMlmAssocReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_REASSOC_REQ: limProcessMlmReassocReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_DISASSOC_REQ: limProcessMlmDisassocReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_DEAUTH_REQ: limProcessMlmDeauthReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_SETKEYS_REQ: limProcessMlmSetKeysReq(pMac, Msg->bodyptr); break;
+ case LIM_MLM_REMOVEKEY_REQ: limProcessMlmRemoveKeyReq(pMac, Msg->bodyptr); break;
+ case SIR_LIM_MIN_CHANNEL_TIMEOUT: limProcessMinChannelTimeout(pMac); break;
+ case SIR_LIM_MAX_CHANNEL_TIMEOUT: limProcessMaxChannelTimeout(pMac); break;
+ case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
+ limProcessPeriodicProbeReqTimer(pMac); break;
+ case SIR_LIM_JOIN_FAIL_TIMEOUT: limProcessJoinFailureTimeout(pMac); break;
+ case SIR_LIM_AUTH_FAIL_TIMEOUT: limProcessAuthFailureTimeout(pMac); break;
+ case SIR_LIM_AUTH_RSP_TIMEOUT: limProcessAuthRspTimeout(pMac, Msg->bodyval); break;
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT: limProcessAssocFailureTimeout(pMac, Msg->bodyval); break;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break;
+#endif
+#ifdef WLAN_FEATURE_P2P
+ case SIR_LIM_REMAIN_CHN_TIMEOUT: limProcessRemainOnChnTimeout(pMac); break;
+#endif
+ case LIM_MLM_ADDBA_REQ: limProcessMlmAddBAReq( pMac, Msg->bodyptr ); break;
+ case LIM_MLM_ADDBA_RSP: limProcessMlmAddBARsp( pMac, Msg->bodyptr ); break;
+ case LIM_MLM_DELBA_REQ: limProcessMlmDelBAReq( pMac, Msg->bodyptr ); break;
+ case LIM_MLM_TSPEC_REQ:
+ default:
+ break;
+ } // switch (msgType)
+} /*** end limProcessMlmReqMessages() ***/
+
+
+/**
+ * limSetScanMode()
+ *
+ *FUNCTION:
+ * This function is called to setup system into Scan mode
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limSetScanMode(tpAniSirGlobal pMac)
+{
+ tSirLinkTrafficCheck checkTraffic;
+
+ /// Set current scan channel id to the first in the channel list
+ pMac->lim.gLimCurrentScanChannelId = 0;
+
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ if ( IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) )
+ checkTraffic = eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
+ else
+ checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
+#else
+ /* Currently checking the traffic before scan for Linux station. This is because MLM
+ * scan request is not filled as scan is received via Measurement req in Linux. This
+ * should be made as common code for Windows/Linux station once the scan requests are
+ * enabled in Linux
+ * TODO */
+ checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN;
+#endif
+
+ PELOG1(limLog(pMac, LOG1, FL("Calling limSendHalInitScanReq\n"));)
+ limSendHalInitScanReq(pMac, eLIM_HAL_INIT_SCAN_WAIT_STATE, checkTraffic);
+
+ return ;
+} /*** end limSetScanMode() ***/
+
+//WLAN_SUSPEND_LINK Related
+
+/* limIsLinkSuspended()
+ *
+ *FUNCTION:
+ * This function returns is link is suspended or not.
+ *
+ *LOGIC:
+ * Since Suspen link uses init scan, it just returns
+ * gLimSystemInScanLearnMode flag.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+tANI_U8
+limIsLinkSuspended(tpAniSirGlobal pMac)
+{
+ return pMac->lim.gLimSystemInScanLearnMode;
+}
+/**
+ * limSuspendLink()
+ *
+ *FUNCTION:
+ * This function is called to suspend traffic. Internally this function uses WDA_INIT_SCAN_REQ.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param trafficCheck - Takes value from enum tSirLinkTrafficCheck.
+ * @param callback - Callback function to be called after suspending the link.
+ * @param data - Pointer to any buffer that will be passed to callback.
+ * @return None
+ */
+void
+limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data)
+{
+ if( NULL == callback )
+ {
+ limLog( pMac, LOGE, "%s:%d: Invalid parameters\n", __FUNCTION__, __LINE__ );
+ return;
+ }
+
+ if( pMac->lim.gpLimSuspendCallback )
+ {
+ limLog( pMac, LOGE, "%s:%d: gLimSuspendLink callback is not NULL...something is wrong\n", __FUNCTION__, __LINE__ );
+ callback( pMac, eHAL_STATUS_FAILURE, data );
+ return;
+ }
+
+ pMac->lim.gLimSystemInScanLearnMode = 1;
+ pMac->lim.gpLimSuspendCallback = callback;
+ pMac->lim.gpLimSuspendData = data;
+ limSendHalInitScanReq(pMac, eLIM_HAL_SUSPEND_LINK_WAIT_STATE, trafficCheck );
+}
+
+/**
+ * limResumeLink()
+ *
+ *FUNCTION:
+ * This function is called to Resume traffic after a suspend. Internally this function uses WDA_FINISH_SCAN_REQ.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param callback - Callback function to be called after Resuming the link.
+ * @param data - Pointer to any buffer that will be passed to callback.
+ * @return None
+ */
+void
+limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data)
+{
+ if( NULL == callback )
+ {
+ limLog( pMac, LOGE, "%s:%d: Invalid parameters\n", __FUNCTION__, __LINE__ );
+ return;
+ }
+
+ if( pMac->lim.gpLimResumeCallback )
+ {
+ limLog( pMac, LOGE, "%s:%d: gLimResumeLink callback is not NULL...something is wrong\n", __FUNCTION__, __LINE__ );
+ callback( pMac, eHAL_STATUS_FAILURE, data );
+ return;
+ }
+
+ pMac->lim.gpLimResumeCallback = callback;
+ pMac->lim.gpLimResumeData = data;
+ limSendHalFinishScanReq(pMac, eLIM_HAL_RESUME_LINK_WAIT_STATE );
+}
+//end WLAN_SUSPEND_LINK Related
+
+
+/**
+ *
+ * limChangeChannelWithCallback()
+ *
+ * FUNCTION:
+ * This function is called to change channel and perform off channel operation
+ * if required. The caller registers a callback to be called at the end of the
+ * channel change.
+ *
+ */
+void
+limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel,
+ CHANGE_CHANNEL_CALLBACK callback,
+ tANI_U32 *cbdata, tpPESession psessionEntry)
+{
+ // Sanity checks for the current and new channel
+#if defined WLAN_VOWIFI_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Switching channel to %d\n", newChannel);)
+#endif
+ psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION;
+
+ pMac->lim.gpchangeChannelCallback = callback;
+ pMac->lim.gpchangeChannelData = cbdata;
+
+ limSendSwitchChnlParams(pMac, newChannel,
+ eHT_SECONDARY_CHANNEL_OFFSET_NONE,
+ psessionEntry->maxTxPower, psessionEntry->peSessionId);
+
+ return;
+}
+
+
+/**
+ * limContinuePostChannelScan()
+ *
+ *FUNCTION:
+ * This function is called to scan the current channel.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+
+void limContinuePostChannelScan(tpAniSirGlobal pMac)
+{
+ tANI_U8 channelNum;
+ tANI_U8 handleError = 0;
+ tANI_U8 i = 0;
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ if( pMac->lim.abortScan || (NULL == pMac->lim.gpLimMlmScanReq ) ||
+ (pMac->lim.gLimCurrentScanChannelId >
+ (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)))
+ {
+ 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;
+ }
+
+ channelNum = limGetCurrentScanChannel(pMac);
+ if ((pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) &&
+ (limActiveScanAllowed(pMac, channelNum)))
+ {
+ TX_TIMER *periodicScanTimer;
+ PELOG2(limLog(pMac, LOG2, FL("ACTIVE Scan chan %d, sending probe\n"), channelNum);)
+
+ do
+ {
+ /* Prepare and send Probe Request frame for all the SSIDs present in the saved MLM
+ */
+
+ PELOGE(limLog(pMac, LOG1, FL("sending ProbeReq number %d, for SSID %s on channel: %d\n"),
+ i, pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);)
+ // include additional IE if there is
+ status = limSendProbeReqMgmtFrame( pMac, &pMac->lim.gpLimMlmScanReq->ssId[i],
+ pMac->lim.gpLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr,
+ pMac->lim.gpLimMlmScanReq->dot11mode,
+ pMac->lim.gpLimMlmScanReq->uIEFieldLen,
+ (tANI_U8 *)(pMac->lim.gpLimMlmScanReq)+pMac->lim.gpLimMlmScanReq->uIEFieldOffset);
+
+ if ( status != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID %s on channel: %d\n"),
+ pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);)
+ limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
+ limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
+ return;
+ }
+ i++;
+ } while (i < pMac->lim.gpLimMlmScanReq->numSsid);
+
+ {
+#if defined WLAN_FEATURE_VOWIFI
+ //If minChannelTime is set to zero, SME is requesting scan to not use min channel timer.
+ //This is used in 11k to request for beacon measurement request with a fixed duration in
+ //max channel time.
+ if( pMac->lim.gpLimMlmScanReq->minChannelTime != 0 )
+ {
+#endif
+ /// TXP has sent Probe Request
+ /// Activate minChannelTimer
+ limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
+
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ * priority - LOW/might not be needed
+ */
+ pMac->lim.limTimers.gLimMinChannelTimer.sessionId = sessionId;
+#endif
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_MIN_CHANNEL_TIMER));
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimMinChannelTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start min channel timer\n"));
+ return;
+ }
+
+ // Initialize max timer too
+ limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
+#if defined WLAN_FEATURE_VOWIFI
+ }
+ else
+ {
+#if defined WLAN_VOWIFI_DEBUG
+ PELOGE(limLog( pMac, LOGE, "Min channel time == 0, Use only max chan timer\n" );)
+#endif
+ //No Need to start Min channel timer. Start Max Channel timer.
+ limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer)
+ == TX_TIMER_ERROR)
+ {
+ /// Could not activate max channel timer.
+ // Log error
+ limLog(pMac,LOGP, FL("could not start max channel timer\n"));
+ return;
+ }
+
+ }
+#endif
+ }
+ /* Start peridic timer which will trigger probe req based on min/max
+ channel timer */
+ periodicScanTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer;
+ if (tx_timer_activate(periodicScanTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start periodic probe req "
+ "timer\n"));
+ return;
+ }
+ periodicScanTimer->sessionId = channelNum;
+ }
+ else
+ {
+ tANI_U32 val;
+ PELOG2(limLog(pMac, LOG2, FL("START PASSIVE Scan chan %d\n"), channelNum);)
+
+ /// Passive Scanning. Activate maxChannelTimer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_MAX_CHANNEL_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate max channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to deactivate max channel timer\n"));
+ return;
+ }
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get max channel value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve passive max channel value\n"));
+ return;
+ }
+ else
+ {
+ tANI_U32 val1 = 0;
+
+ val = SYS_MS_TO_TICKS(val);
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ // If a background was triggered via Quiet BSS,
+ // then we need to adjust the MIN and MAX channel
+ // timer's accordingly to the Quiet duration that
+ // was specified
+ if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState &&
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss )
+ {
+ // gLimQuietDuration is already cached in units of
+ // system ticks. No conversion is reqd...
+ val1 = pMac->lim.gLimSpecMgmt.quietDuration;
+ }
+ else
+ {
+ val1 = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->maxChannelTime);
+ }
+#endif
+ //Pick the longer stay time
+ val = (val > val1) ? val : val1;
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_MAX_CHANNEL_TIMER));
+ if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change max channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change max channel timer\n"));
+ return;
+ }
+ else if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start max channel timer\n"));
+ return;
+ }
+
+ }
+ }
+ // Wait for Beacons to arrive
+ } // if (pMac->lim.gLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN)
+
+ if( handleError )
+ {
+ //
+ // FIXME - With this, LIM/SoftMAC will try and recover
+ // state, but eWNI_SME_SCAN_CNF maybe reporting an
+ // incorrect status back to the SME. Some of the possible
+ // errors are:
+ // eSIR_SME_HAL_SCAN_INIT_FAILED
+ // eSIR_SME_RESOURCES_UNAVAILABLE
+ //
+ //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 );
+ //limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+ }
+ else
+ {
+ limAddScanChannelInfo(pMac, channelNum);
+ }
+
+ return;
+}
+
+
+
+
+/*
+* Creates a Raw frame to be sent before every Scan, if required.
+* If only infra link is active (mlmState = Link Estb), then send Data Null
+* If only BT-AMP-AP link is active(mlmState = BSS_STARTED), then send CTS2Self frame.
+* If only BT-AMP-STA link is active(mlmState = BSS_STARTED or Link Est) then send CTS2Self
+* If Only IBSS link is active, then send CTS2Self
+* for concurrent scenario: Infra+BT or Infra+IBSS, always send CTS2Self, no need to send Data Null
+*
+*/
+static void __limCreateInitScanRawFrame(tpAniSirGlobal pMac,
+ tpInitScanParams pInitScanParam)
+{
+ tANI_U8 i;
+ pInitScanParam->scanEntry.activeBSScnt = 0;
+
+ /* Don't send CTS to self as we have issue with BTQM queues where BTQM can
+ * not handle transmition of CTS2self frames. Sending CTS 2 self at this
+ * juncture also doesn't serve much purpose as probe request frames go out
+ * immediately, No need to notify BSS in IBSS case.
+ * */
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) &&
+ (pInitScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID))
+ {
+ pInitScanParam->scanEntry.bssIdx[pInitScanParam->scanEntry.activeBSScnt]
+ = pMac->lim.gpSession[i].bssIdx;
+ pInitScanParam->scanEntry.activeBSScnt++;
+
+ }
+ }
+#ifdef WLAN_FEATURE_P2P
+ else if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole )
+ && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona )
+ )
+ {
+ pInitScanParam->useNoA = TRUE;
+ }
+#endif
+ }
+ }
+ if (pInitScanParam->scanEntry.activeBSScnt)
+ {
+ pInitScanParam->notifyBss = TRUE;
+ pInitScanParam->frameType = SIR_MAC_DATA_FRAME;
+ pInitScanParam->frameLength = 0;
+ }
+}
+
+/*
+* Creates a Raw frame to be sent during finish scan, if required.
+* Send data null frame, only when there is just one session active and that session is
+* in 'link Estb' state.
+* if more than one session is active, don't send any frame.
+* for concurrent scenario: Infra+BT or Infra+IBSS, no need to send Data Null
+*
+*/
+static void __limCreateFinishScanRawFrame(tpAniSirGlobal pMac,
+ tpFinishScanParams pFinishScanParam)
+{
+ tANI_U8 i;
+ pFinishScanParam->scanEntry.activeBSScnt = 0;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ //BT-STA can either be in LINK-ESTB state or BSS_STARTED State
+ //for BT, need to send CTS2Self
+ if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) &&
+ (pFinishScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID))
+ {
+ pFinishScanParam->scanEntry.bssIdx[pFinishScanParam->scanEntry.activeBSScnt]
+ = pMac->lim.gpSession[i].bssIdx;
+ pFinishScanParam->scanEntry.activeBSScnt++;
+ }
+ }
+ }
+ }
+
+ if (pFinishScanParam->scanEntry.activeBSScnt)
+ {
+ pFinishScanParam->notifyBss = TRUE;
+ pFinishScanParam->frameType = SIR_MAC_DATA_FRAME;
+ pFinishScanParam->frameLength = 0;
+ }
+}
+
+void
+limSendHalInitScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState, tSirLinkTrafficCheck trafficCheck)
+{
+
+
+ tSirMsgQ msg;
+ tpInitScanParams pInitScanParam;
+ tSirRetStatus rc = eSIR_SUCCESS;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pInitScanParam,
+ sizeof(*pInitScanParam)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
+ goto error;
+ }
+
+ /*Initialize the pInitScanParam with 0*/
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pInitScanParam, sizeof(*pInitScanParam));
+
+ msg.type = WDA_INIT_SCAN_REQ;
+ msg.bodyptr = pInitScanParam;
+ msg.bodyval = 0;
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)&pInitScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr));
+ if (nextState == eLIM_HAL_INIT_LEARN_WAIT_STATE)
+ {
+ pInitScanParam->notifyBss = TRUE;
+ pInitScanParam->notifyHost = FALSE;
+ pInitScanParam->scanMode = eHAL_SYS_MODE_LEARN;
+
+#if defined(ANI_AP_CLIENT_SDK)
+ if (GET_LIM_SYSTEM_ROLE(pMac) == eLIM_STA_ROLE)
+ {
+ pInitScanParam->frameType = SIR_MAC_DATA_NULL;
+ // We need to inform the AP only when we are
+ // in the LINK_ESTABLISHED state
+ if( eLIM_SME_LINK_EST_WT_SCAN_STATE != pMac->lim.gLimSmeState )
+ {
+ pInitScanParam->notifyBss = FALSE;
+ // FIXME - Handle this one carefully
+ pInitScanParam->notifyHost = FALSE;
+ }
+ __limCreateInitScanRawFrame(pMac, pInitScanParam);
+ pInitScanParam->checkLinkTraffic = trafficCheck;
+ }
+ else
+#endif
+ {
+ pInitScanParam->frameType = SIR_MAC_CTRL_CTS;
+ __limCreateInitScanRawFrame(pMac, pInitScanParam);
+ pInitScanParam->checkLinkTraffic = trafficCheck;
+ }
+
+#if (defined(ANI_PRODUCT_TYPE_AP) ||defined(ANI_PRODUCT_TYPE_AP_SDK))
+ /* Currently using the AP's scanDuration values for Linux station also. This should
+ * be revisited if this needs to changed depending on AP or Station */
+ {
+ if (pMac->lim.gpLimMeasReq->measControl.longChannelScanPeriodicity &&
+ (pMac->lim.gLimMeasParams.shortDurationCount ==
+ pMac->lim.gpLimMeasReq->measControl.longChannelScanPeriodicity))
+ {
+#ifdef ANI_AP_SDK
+ pInitScanParam->scanDuration = (tANI_U16)pMac->lim.gLimScanDurationConvert.longChannelScanDuration_tick;
+#else
+ pInitScanParam->scanDuration = (tANI_U16)pMac->lim.gpLimMeasReq->measDuration.longChannelScanDuration;
+#endif /* ANI_AP_SDK */
+ }
+ else
+ {
+#ifdef ANI_AP_SDK
+ pInitScanParam->scanDuration = pMac->lim.gLimScanDurationConvert.shortChannelScanDuration_tick;
+#else
+ pInitScanParam->scanDuration = (tANI_U16)pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration;
+#endif /* ANI_AP_SDK */
+ }
+ }
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) ||defined(ANI_PRODUCT_TYPE_AP_SDK))
+ }
+ else
+ {
+ if(nextState == eLIM_HAL_SUSPEND_LINK_WAIT_STATE)
+ {
+ pInitScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK;
+ }
+ else
+ {
+ pInitScanParam->scanMode = eHAL_SYS_MODE_SCAN;
+ }
+ __limCreateInitScanRawFrame(pMac, pInitScanParam);
+#ifdef WLAN_FEATURE_P2P
+ if (pInitScanParam->useNoA)
+ {
+ pInitScanParam->scanDuration = pMac->lim.gTotalScanDuration;
+ }
+#endif
+ /* Inform HAL whether it should check for traffic on the link
+ * prior to performing a background scan
+ */
+ pInitScanParam->checkLinkTraffic = trafficCheck;
+ }
+
+ pMac->lim.gLimHalScanState = nextState;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ rc = wdaPostCtrlMsg(pMac, &msg);
+ if (rc == eSIR_SUCCESS) {
+ PELOG3(limLog(pMac, LOG3, FL("wdaPostCtrlMsg() return eSIR_SUCCESS pMac=%x nextState=%d\n"),
+ pMac, pMac->lim.gLimHalScanState);)
+ return;
+ }
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (void *)pInitScanParam);
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)
+
+error:
+ switch(nextState)
+ {
+ case eLIM_HAL_START_SCAN_WAIT_STATE:
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+ break;
+
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_START_LEARN_WAIT_STATE:
+ // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ limRestorePreLearnState(pMac);
+ limReEnableLearnMode(pMac);
+ }
+ break;
+
+#endif
+
+ //WLAN_SUSPEND_LINK Related
+ case eLIM_HAL_SUSPEND_LINK_WAIT_STATE:
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ if( pMac->lim.gpLimSuspendCallback )
+ {
+ pMac->lim.gpLimSuspendCallback( pMac, rc, pMac->lim.gpLimSuspendData );
+ pMac->lim.gpLimSuspendCallback = NULL;
+ pMac->lim.gpLimSuspendData = NULL;
+ }
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ break;
+ //end WLAN_SUSPEND_LINK Related
+ default:
+ break;
+ }
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+
+ return ;
+}
+
+void
+limSendHalStartScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState)
+{
+ tSirMsgQ msg;
+ tpStartScanParams pStartScanParam;
+ tSirRetStatus rc = eSIR_SUCCESS;
+
+ /**
+ * The Start scan request to be sent only if Start Scan is not already requested
+ */
+ if(pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE)
+ {
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **)&pStartScanParam,
+ sizeof(*pStartScanParam)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
+ goto error;
+ }
+
+ msg.type = WDA_START_SCAN_REQ;
+ msg.bodyptr = pStartScanParam;
+ msg.bodyval = 0;
+ pStartScanParam->status = eHAL_STATUS_SUCCESS;
+ pStartScanParam->scanChannel = (tANI_U8)channelNum;
+
+ pMac->lim.gLimHalScanState = nextState;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+ PELOGW(limLog(pMac, LOGW, FL("Channel %d\n"), channelNum);)
+
+ rc = wdaPostCtrlMsg(pMac, &msg);
+ if (rc == eSIR_SUCCESS) {
+ return;
+ }
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (void *)pStartScanParam);
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)
+
+error:
+ switch(nextState)
+ {
+ case eLIM_HAL_START_SCAN_WAIT_STATE:
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+ break;
+
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_START_LEARN_WAIT_STATE:
+ //if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ limRestorePreLearnState(pMac);
+ limReEnableLearnMode(pMac);
+ }
+ break;
+
+#endif
+
+ default:
+ break;
+ }
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+
+ }
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Invalid state for START_SCAN_REQ message=%d\n"), pMac->lim.gLimHalScanState);)
+ }
+
+ return;
+}
+
+void limSendHalEndScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState)
+{
+ tSirMsgQ msg;
+ tpEndScanParams pEndScanParam;
+ tSirRetStatus rc = eSIR_SUCCESS;
+
+ /**
+ * The End scan request to be sent only if End Scan is not already requested or
+ * Start scan is not already requestd
+ */
+ if((pMac->lim.gLimHalScanState != eLIM_HAL_END_SCAN_WAIT_STATE) &&
+ (pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE))
+ {
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pEndScanParam,
+ sizeof(*pEndScanParam)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
+ goto error;
+ }
+
+ msg.type = WDA_END_SCAN_REQ;
+ msg.bodyptr = pEndScanParam;
+ msg.bodyval = 0;
+ pEndScanParam->status = eHAL_STATUS_SUCCESS;
+ pEndScanParam->scanChannel = (tANI_U8)channelNum;
+
+ pMac->lim.gLimHalScanState = nextState;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ rc = wdaPostCtrlMsg(pMac, &msg);
+ if (rc == eSIR_SUCCESS) {
+ return;
+ }
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (void *)pEndScanParam);
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)
+
+ error:
+ switch(nextState)
+ {
+ case eLIM_HAL_END_SCAN_WAIT_STATE:
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_END_FAILED);
+ break;
+
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_END_LEARN_WAIT_STATE:
+ // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ limRestorePreLearnState(pMac);
+ limReEnableLearnMode(pMac);
+ }
+ break;
+#endif
+
+ default:
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg Rcvd invalid nextState %d\n"), nextState);)
+ break;
+ }
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)
+ }
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Invalid state for END_SCAN_REQ message=%d\n"), pMac->lim.gLimHalScanState);)
+ }
+
+
+ return;
+}
+
+/**
+ * limSendHalFinishScanReq()
+ *
+ *FUNCTION:
+ * This function is called to finish scan/learn request..
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param nextState - this parameters determines whether this call is for scan or learn
+ *
+ * @return None
+ */
+void limSendHalFinishScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState)
+{
+
+ tSirMsgQ msg;
+ tpFinishScanParams pFinishScanParam;
+ tSirRetStatus rc = eSIR_SUCCESS;
+
+ if(pMac->lim.gLimHalScanState == nextState)
+ {
+ /*
+ * PE may receive multiple probe responses, while waiting for HAL to send 'FINISH_SCAN_RSP' message
+ * PE was sending multiple finish scan req messages to HAL
+ * this check will avoid that.
+ * If PE is already waiting for the 'finish_scan_rsp' message from HAL, it will ignore this request.
+ */
+ PELOGW(limLog(pMac, LOGW, FL("Next Scan State is same as the current state: %d \n"), nextState);)
+ return;
+ }
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pFinishScanParam,
+ sizeof(*pFinishScanParam)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));)
+ goto error;
+ }
+
+ msg.type = WDA_FINISH_SCAN_REQ;
+ msg.bodyptr = pFinishScanParam;
+ msg.bodyval = 0;
+ pFinishScanParam->currentOperChannel = peGetResumeChannel(pMac);
+ //TODO: Fix CB State. Get it from session. similar to getChannel.
+ pFinishScanParam->cbState = limGetPhyCBState( pMac );
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)&pFinishScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr));
+
+ if (nextState == eLIM_HAL_FINISH_LEARN_WAIT_STATE)
+ {
+ //AP - No pkt need to be transmitted
+ pFinishScanParam->scanMode = eHAL_SYS_MODE_LEARN;
+ pFinishScanParam->notifyBss = FALSE;
+ pFinishScanParam->notifyHost = FALSE;
+ pFinishScanParam->frameType = 0;
+ pFinishScanParam->frameLength = 0;
+ pMac->lim.gLimHalScanState = nextState;
+ }
+ else
+ {
+ /* If STA is associated with an AP (ie. STA is in
+ * LINK_ESTABLISHED state), then STA need to inform
+ * the AP via either DATA-NULL
+ */
+ if (nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE)
+ {
+ pFinishScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK;
+ }
+ else
+ {
+ pFinishScanParam->scanMode = eHAL_SYS_MODE_SCAN;
+ }
+ pFinishScanParam->notifyHost = FALSE;
+ __limCreateFinishScanRawFrame(pMac, pFinishScanParam);
+ //WLAN_SUSPEND_LINK Related
+ pMac->lim.gLimHalScanState = nextState;
+ //end WLAN_SUSPEND_LINK Related
+ }
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ rc = wdaPostCtrlMsg(pMac, &msg);
+ if (rc == eSIR_SUCCESS) {
+ return;
+ }
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palFreeMemory(pMac->hHdd, (void *)pFinishScanParam);
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d\n"), rc);)
+
+ error:
+ if(nextState == eLIM_HAL_FINISH_SCAN_WAIT_STATE)
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_FINISH_FAILED);
+ //WLAN_SUSPEND_LINK Related
+ else if ( nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE )
+ {
+ if( pMac->lim.gpLimResumeCallback )
+ {
+ pMac->lim.gpLimResumeCallback( pMac, rc, pMac->lim.gpLimResumeData );
+ pMac->lim.gpLimResumeCallback = NULL;
+ pMac->lim.gpLimResumeData = NULL;
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ }
+ }
+ //end WLAN_SUSPEND_LINK Related
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ return;
+}
+
+/**
+ * limContinueChannelScan()
+ *
+ *FUNCTION:
+ * This function is called by limPerformChannelScan().
+ * This function is called to continue channel scanning when
+ * Beacon/Probe Response frame are received.
+ *
+ *LOGIC:
+ * Scan criteria stored in pMac->lim.gLimMlmScanReq is used
+ * to perform channel scan. In this function MLM sub module
+ * makes channel switch, sends PROBE REQUEST frame in case of
+ * ACTIVE SCANNING, starts min/max channel timers, programs
+ * NAV to probeDelay timer and waits for Beacon/Probe Response.
+ * Once all required channels are scanned, LIM_MLM_SCAN_CNF
+ * primitive is used to send Scan results to SME sub module.
+ *
+ *ASSUMPTIONS:
+ * 1. In case of Active scanning, start MAX channel time iff
+ * MIN channel timer expired and activity is observed on
+ * the channel.
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+void
+limContinueChannelScan(tpAniSirGlobal pMac)
+{
+ tANI_U8 channelNum;
+
+ PELOG1(limLog(pMac, LOG1, FL("Continue SCAN : chan %d tot %d\n"),
+ pMac->lim.gLimCurrentScanChannelId,
+ pMac->lim.gpLimMlmScanReq->channelList.numChannels);)
+
+ if (pMac->lim.gLimCurrentScanChannelId >
+ (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)
+ || pMac->lim.abortScan)
+ {
+#ifndef ANI_SNIFFER
+ 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);
+
+ /// Done scanning all required channels
+ limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE);
+#endif
+ return;
+ }
+
+ /// Atleast one more channel is to be scanned
+
+ if ((pMac->lim.gLimReturnAfterFirstMatch & 0x40) ||
+ (pMac->lim.gLimReturnAfterFirstMatch & 0x80))
+ {
+ while (pMac->lim.gLimCurrentScanChannelId <=
+ (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
+ {
+ if (((limGetCurrentScanChannel(pMac) <= 14) &&
+ pMac->lim.gLim24Band11dScanDone) ||
+ ((limGetCurrentScanChannel(pMac) > 14) &&
+ pMac->lim.gLim50Band11dScanDone))
+ {
+ limLog(pMac, LOGW, FL("skipping chan %d\n"),
+ limGetCurrentScanChannel(pMac));
+ pMac->lim.gLimCurrentScanChannelId++;
+ }
+ else
+ break;
+ }
+
+ if (pMac->lim.gLimCurrentScanChannelId >
+ (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
+ {
+ pMac->lim.abortScan = 0;
+ limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
+ limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
+ /// Done scanning all required channels
+ //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;
+ }
+ }
+
+ channelNum = limGetCurrentScanChannel(pMac);
+ PELOG2(limLog(pMac, LOG2, FL("Current Channel to be scanned is %d\n"),
+ channelNum);)
+
+ limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_SCAN_WAIT_STATE);
+ return;
+} /*** end limContinueChannelScan() ***/
+
+
+
+/**
+ * limRestorePreScanState()
+ *
+ *FUNCTION:
+ * This function is called by limContinueChannelScan()
+ * to restore HW state prior to entering 'scan state'
+ *
+ *LOGIC
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+void
+limRestorePreScanState(tpAniSirGlobal pMac)
+{
+ int i;
+
+ /// Deactivate MIN/MAX channel timers if running
+ limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
+ limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
+
+ /* Re-activate Heartbeat timers for connected sessions as scan
+ * is done if the DUT is in active mode*/
+ if((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) ||
+ (ePMM_STATE_READY == pMac->pmm.gPmmState))
+ {
+ for(i=0;i<pMac->lim.maxBssId;i++)
+ {
+ if((pMac->lim.gpSession[i].valid == TRUE) &&
+ (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState))
+ {
+ limReactivateHeartBeatTimer(pMac, peFindSessionBySessionId(pMac,i));
+ }
+ }
+ }
+
+ /**
+ * clean up message queue.
+ * If SME messages, redirect to deferred queue.
+ * The rest will be discarded.
+ */
+ //limCleanupMsgQ(pMac);
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ PELOG1(limLog(pMac, LOG1, FL("Scan ended, took %d tu\n"), (tx_time_get() - pMac->lim.scanStartTime));)
+} /*** limRestorePreScanState() ***/
+
+
+static void
+mlm_add_sta(
+ tpAniSirGlobal pMac,
+ tpAddStaParams pSta,
+ tANI_U8 *pBssid,
+ tANI_U8 htCapable,
+ tpPESession psessionEntry) //psessionEntry may required in future
+{
+ tANI_U32 val;
+ int i;
+
+
+ pSta->staType = STA_ENTRY_SELF; // Identifying self
+
+ palCopyMemory( pMac->hHdd, pSta->bssId, pBssid, sizeof( tSirMacAddr ));
+ palCopyMemory( pMac->hHdd, pSta->staMac, psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+
+ /* Configuration related parameters to be changed to support BT-AMP */
+
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_LISTEN_INTERVAL, &val ))
+ limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL\n"));
+
+ pSta->listenInterval = (tANI_U16) val;
+
+ if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) )
+ limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE\n"));
+ pSta->shortPreambleSupported = (tANI_U8)val;
+
+ pSta->assocId = 0; // Is SMAC OK with this?
+ pSta->wmmEnabled = 0;
+ pSta->uAPSD = 0;
+ pSta->maxSPLen = 0;
+ pSta->us32MaxAmpduDuration = 0;
+ pSta->maxAmpduSize = 0; // 0: 8k, 1: 16k,2: 32k,3: 64k
+
+
+ if(IS_DOT11_MODE_HT(psessionEntry->dot11mode))
+ {
+ pSta->htCapable = htCapable;
+#ifdef WLAN_SOFTAP_FEATURE
+ pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
+ pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry );
+ pSta->mimoPS = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
+ pSta->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
+ pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry );
+ pSta->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry );
+ pSta->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry );
+ pSta->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry );
+ pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry);
+ pSta->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry);
+ pSta->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry);
+#else
+ pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD );
+ pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET );
+ pSta->mimoPS = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE );
+ pSta->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE );
+ pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION );
+ pSta->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA );
+ pSta->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY );
+ pSta->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH );
+ pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ);
+ pSta->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ);
+ pSta->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ);
+
+#endif
+ }
+
+ limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry);
+ limFillSupportedRatesInfo(pMac, NULL, &pSta->supportedRates,psessionEntry);
+
+ limLog( pMac, LOGE, FL( "GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d, SGI20: %d, SGI40%d\n") ,
+ pSta->greenFieldCapable, pSta->txChannelWidthSet, pSta->mimoPS, pSta->lsigTxopProtection,
+ pSta->fDsssCckMode40Mhz,pSta->fShortGI20Mhz, pSta->fShortGI40Mhz);
+
+#ifdef WLAN_FEATURE_P2P
+ if (VOS_P2P_GO_MODE == psessionEntry->pePersona)
+ {
+ pSta->p2pCapableSta = 1;
+ }
+#endif
+
+ //Disable BA. It will be set as part of ADDBA negotiation.
+ for( i = 0; i < STACFG_MAX_TC; i++ )
+ {
+ pSta->staTCParams[i].txUseBA = eBA_DISABLE;
+ pSta->staTCParams[i].rxUseBA = eBA_DISABLE;
+ }
+
+}
+
+//
+// New HAL interface - WDA_ADD_BSS_REQ
+// Package WDA_ADD_BSS_REQ to HAL, in order to start a BSS
+//
+tSirResultCodes
+limMlmAddBss (
+ tpAniSirGlobal pMac,
+ tLimMlmStartReq *pMlmStartReq,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ tANI_U32 retCode;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ tANI_U32 val = 0;
+#endif
+
+ // Package WDA_ADD_BSS_REQ message parameters
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBssParams, sizeof( tAddBssParams )))
+ {
+ limLog( pMac, LOGE, FL( "Unable to PAL allocate memory during ADD_BSS\n" ));
+ // Respond to SME with LIM_MLM_START_CNF
+ return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+
+ palZeroMemory(pMac->hHdd, pAddBssParams, sizeof(tAddBssParams));
+
+ // Fill in tAddBssParams members
+ palCopyMemory( pMac->hHdd, pAddBssParams->bssId, pMlmStartReq->bssId,
+ sizeof( tSirMacAddr ));
+
+ // Fill in tAddBssParams selfMacAddr
+ palCopyMemory ( pMac->hHdd, pAddBssParams->selfMacAddr,
+ psessionEntry->selfMacAddr,
+ sizeof( tSirMacAddr ));
+
+ pAddBssParams->bssType = pMlmStartReq->bssType;
+ if ((pMlmStartReq->bssType == eSIR_IBSS_MODE) ||
+ (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE)||
+ (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE)) {
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ else if (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE){
+#else
+ else{
+#endif
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_AP;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if( wlan_cfgGetInt ( pMac, WNI_CFG_SHORT_SLOT_TIME, &val ) != eSIR_SME_SUCCESS)
+ {
+ limLog ( pMac, LOGP, FL(" Error : unable to fetch the WNI_CFG_SHORT_SLOT_TIME\n"));
+ palFreeMemory(pMac->hHdd,(void *)pAddBssParams);
+ return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ pAddBssParams->shortSlotTimeSupported = (tANI_U8)val;
+#endif
+
+
+ pAddBssParams->beaconInterval = pMlmStartReq->beaconPeriod;
+ pAddBssParams->dtimPeriod = pMlmStartReq->dtimPeriod;
+ pAddBssParams->cfParamSet.cfpCount = pMlmStartReq->cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod = pMlmStartReq->cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration = pMlmStartReq->cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining = pMlmStartReq->cfParamSet.cfpDurRemaining;
+
+ pAddBssParams->rateSet.numRates = pMlmStartReq->rateSet.numRates;
+ palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
+ pMlmStartReq->rateSet.rate, pMlmStartReq->rateSet.numRates );
+
+ pAddBssParams->nwType = pMlmStartReq->nwType;
+
+ pAddBssParams->htCapable = pMlmStartReq->htCapable;
+ pAddBssParams->htOperMode = pMlmStartReq->htOperMode;
+ pAddBssParams->dualCTSProtection = pMlmStartReq->dualCTSProtection;
+ pAddBssParams->txChannelWidthSet = pMlmStartReq->txChannelWidthSet;
+
+ pAddBssParams->currentOperChannel = pMlmStartReq->channelNumber;
+ pAddBssParams->currentExtChannel = mlm_get_ext_chnl(pMac, pMlmStartReq->cbMode);
+
+ /* Update PE sessionId*/
+ pAddBssParams->sessionId = pMlmStartReq->sessionId;
+
+ //Send the SSID to HAL to enable SSID matching for IBSS
+ palCopyMemory( pMac->hHdd, &(pAddBssParams->ssId.ssId),
+ pMlmStartReq->ssId.ssId,
+ pMlmStartReq->ssId.length);
+ pAddBssParams->ssId.length = pMlmStartReq->ssId.length;
+#ifdef WLAN_SOFTAP_FEATURE
+ pAddBssParams->bHiddenSSIDEn = pMlmStartReq->ssidHidden;
+ limLog( pMac, LOGE, FL( "TRYING TO HIDE SSID %d\n" ),pAddBssParams->bHiddenSSIDEn);
+ // CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed.
+ pAddBssParams->bProxyProbeRespEn = 0;
+ pAddBssParams->obssProtEnabled = pMlmStartReq->obssProtEnabled;
+
+#endif
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+#endif
+ mlm_add_sta(pMac, &pAddBssParams->staContext,
+ pAddBssParams->bssId, pAddBssParams->htCapable,psessionEntry);
+
+ pAddBssParams->status = eHAL_STATUS_SUCCESS;
+ pAddBssParams->respReqd = 1;
+
+ // Set a new state for MLME
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ pAddBssParams->halPersona=psessionEntry->pePersona; //pass on the session persona to hal
+
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+#endif
+
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.type = WDA_ADD_BSS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ limLog( pMac, LOGW, FL( "Sending WDA_ADD_BSS_REQ...\n" ));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"), retCode );
+ palFreeMemory(pMac->hHdd,(void *)pAddBssParams);
+ return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+
+ return eSIR_SME_SUCCESS;
+}
+
+
+/**
+ * limProcessMlmStartReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_START_REQ message
+ * from SME
+ *
+ *LOGIC:
+ * 1) MLME receives LIM_MLM_START_REQ from LIM
+ * 2) MLME sends WDA_ADD_BSS_REQ to HAL
+ * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE
+ * MLME now waits for HAL to send WDA_ADD_BSS_RSP
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tLimMlmStartReq *pMlmStartReq;
+ tLimMlmStartCnf mlmStartCnf;
+ tpPESession psessionEntry = NULL;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmStartReq = (tLimMlmStartReq *) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmStartReq->sessionId))==NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ mlmStartCnf.resultCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ if (psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE)
+ {
+ /**
+ * Should not have received Start req in states other than idle.
+ * Return Start confirm with failure code.
+ */
+ PELOGE(limLog(pMac, LOGE, FL("received unexpected MLM_START_REQ in state %X\n"),psessionEntry->limMlmState);)
+ limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
+ mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ goto end;
+ }
+
+ #if 0
+ if (cfgSetInt(pMac, WNI_CFG_CURRENT_CHANNEL, pMlmStartReq->channelNumber)!= eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not set CURRENT_CHANNEL at CFG\n"));
+
+ pMac->lim.gLimCurrentChannelId = pMlmStartReq->channelNumber;
+ #endif //TO SUPPORT BT-AMP
+
+
+ // Update BSSID & SSID at CFG database
+ #if 0 //We are not using the BSSID and SSID from the config file, instead we are reading form the session table
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pMlmStartReq->bssId, sizeof(tSirMacAddr))
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+
+
+
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimCurrentBssId,
+ pMlmStartReq->bssId,
+ sizeof(tSirMacAddr));
+ #endif //TO SUPPORT BT-AMP
+
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *) &pMlmStartReq->ssId.ssId, pMlmStartReq->ssId.length)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update SSID at CFG\n"));
+ #endif //To SUPPORT BT-AMP
+
+
+ // pMac->lim.gLimCurrentSSID.length = pMlmStartReq->ssId.length;
+
+ #if 0
+ if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate,
+ pMac->lim.gpLimStartBssReq->operationalRateSet.numRates)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update Operational Rateset at CFG\n"));
+ #endif //TO SUPPORT BT-AMP
+
+
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (cfgSetInt(pMac, WNI_CFG_CURRENT_TX_POWER_LEVEL, pMac->lim.gpLimStartBssReq->powerLevel)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not set WNI_CFG_CURRENT_TX_POWER_LEVEL at CFG\n"));
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+#if 0 // Periodic timer for remove WPS PBC proble response entry in PE is disbaled now.
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ if(pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated == eANI_BOOLEAN_FALSE)
+ {
+ if (tx_timer_create(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer,
+ "PS OVERLAP Timer",
+ limWPSOverlapTimerHandler,
+ SIR_LIM_WPS_OVERLAP_TIMEOUT, // expiration_input
+ SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS), // initial_ticks
+ SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS), // reschedule_ticks
+ TX_AUTO_ACTIVATE /* TX_NO_ACTIVATE*/) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("failed to create WPS overlap Timer\n"));
+ }
+
+ pMac->lim.limTimers.gLimWPSOverlapTimerObj.sessionId = pMlmStartReq->sessionId;
+ pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated = eANI_BOOLEAN_TRUE;
+ limLog(pMac, LOGE, FL("Create WPS overlap Timer, session=%d\n"), pMlmStartReq->sessionId);
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_activate failed\n"));
+ }
+ }
+ }
+#endif
+#endif
+
+
+
+ mlmStartCnf.resultCode = limMlmAddBss(pMac, pMlmStartReq,psessionEntry);
+
+end:
+ /* Update PE session Id */
+ mlmStartCnf.sessionId = pMlmStartReq->sessionId;
+
+ /// Free up buffer allocated for LimMlmScanReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);
+
+ //
+ // Respond immediately to LIM, only if MLME has not been
+ // successfully able to send WDA_ADD_BSS_REQ to HAL.
+ // Else, LIM_MLM_START_CNF will be sent after receiving
+ // WDA_ADD_BSS_RSP from HAL
+ //
+ if( eSIR_SME_SUCCESS != mlmStartCnf.resultCode )
+ limPostSmeMessage(pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf);
+} /*** limProcessMlmStartReq() ***/
+
+
+/*
+* This function checks if Scan is allowed or not.
+* It checks each session and if any session is not in the normal state,
+* it will return false.
+* Note: BTAMP_STA can be in LINK_EST as well as BSS_STARTED State, so
+* both cases are handled below.
+*/
+
+static tANI_U8 __limMlmScanAllowed(tpAniSirGlobal pMac)
+{
+ int i;
+
+ if(pMac->lim.gLimMlmState != eLIM_SME_IDLE_STATE)
+ {
+ return FALSE;
+ }
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) ||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
+ (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )||
+
+ ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&&
+ (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) )
+#ifdef WLAN_FEATURE_P2P
+ || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE)
+ && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) )
+ || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) )
+ && (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) )
+#endif
+ ))
+ {
+ return FALSE;
+
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+/**
+ * limProcessMlmScanReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_SCAN_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tLimMlmScanCnf mlmScanCnf;
+
+ if (pMac->lim.gLimSystemInScanLearnMode)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("Sending START_SCAN from LIM while one req is pending\n"));)
+ return;
+ }
+
+ if(__limMlmScanAllowed(pMac) &&
+ (((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels != 0))
+
+ {
+ /// Hold onto SCAN REQ criteria
+ pMac->lim.gpLimMlmScanReq = (tLimMlmScanReq *) pMsgBuf;
+
+ PELOG3(limLog(pMac, LOG3, FL("Number of channels to scan are %d \n"),
+ pMac->lim.gpLimMlmScanReq->channelList.numChannels);)
+
+ pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
+
+ if (pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN)
+ pMac->lim.gLimMlmState = eLIM_MLM_WT_PROBE_RESP_STATE;
+ else // eSIR_PASSIVE_SCAN
+ pMac->lim.gLimMlmState = eLIM_MLM_PASSIVE_SCAN_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ pMac->lim.gLimSystemInScanLearnMode = 1;
+
+#ifdef WLAN_FEATURE_P2P
+ pMac->lim.gTotalScanDuration =
+ pMac->lim.gpLimMlmScanReq->maxChannelTime*
+ pMac->lim.gpLimMlmScanReq->channelList.numChannels;
+#endif
+ limSetScanMode(pMac);
+ }
+ else
+ {
+ /**
+ * Should not have received SCAN req in other states
+ * OR should not have received LIM_MLM_SCAN_REQ with
+ * zero number of channels
+ * Log error
+ */
+ limLog(pMac, LOGW,
+ FL("received unexpected MLM_SCAN_REQ in state %X OR zero number of channels: %X\n"),
+ pMac->lim.gLimMlmState, ((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels);
+ limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);
+
+ /// Free up buffer allocated for
+ /// pMac->lim.gLimMlmScanReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf);
+
+ /// Return Scan confirm with INVALID_PARAMETERS
+
+ mlmScanCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ mlmScanCnf.scanResultLength = 0;
+ limPostSmeMessage(pMac,
+ LIM_MLM_SCAN_CNF,
+ (tANI_U32 *) &mlmScanCnf);
+ }
+} /*** limProcessMlmScanReq() ***/
+
+
+
+/**
+ * limProcessMlmPostJoinSuspendLink()
+ *
+ *FUNCTION:
+ * This function is called after the suspend link while joining
+ * off channel.
+ *
+ *LOGIC:
+ * Check for suspend state.
+ * If success, proceed with setting link state to recieve the
+ * probe response/beacon from intended AP.
+ * Switch to the APs channel.
+ * On an error case, send the MLM_JOIN_CNF with error status.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param status status of suspend link.
+ * @param ctx passed while calling suspend link(psessionEntry)
+ * @return None
+ */
+static void
+limProcessMlmPostJoinSuspendLink(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *ctx)
+{
+ tANI_U8 chanNum;
+ tLimMlmJoinCnf mlmJoinCnf;
+ tpPESession psessionEntry = (tpPESession)ctx;
+ tSirLinkState linkState;
+
+ if( eHAL_STATUS_SUCCESS != status )
+ {
+ limLog(pMac, LOGP, FL("Suspend link failed. Not proceeding with join\n"));
+ goto error;
+ }
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
+
+ //assign appropriate sessionId to the timer object
+ pMac->lim.limTimers.gLimJoinFailureTimer.sessionId = psessionEntry->peSessionId;
+
+ linkState = ((psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ? eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE);
+ limLog(pMac, LOG1, FL("[limProcessMlmJoinReq]: linkState:%d\n"),linkState);
+
+ if (limSetLinkState(pMac, linkState,
+ psessionEntry->pLimMlmJoinReq->bssDescription.bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ {
+ limLog(pMac, LOGE, FL("limSetLinkState to eSIR_LINK_PREASSOC_STATE Failed!!\n"));
+ mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ goto error;
+ }
+
+ /** Derive channel from BSS description and store it in the CFG */
+ // chanNum = pMac->lim.gpLimMlmJoinReq->bssDescription.channelId;
+
+ chanNum = psessionEntry->currentOperChannel;
+ //store the channel switch sessionEntry in the lim global var
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN;
+
+ limSetChannel(pMac, psessionEntry->pLimMlmJoinReq->bssDescription.titanHtCaps,
+ chanNum, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+
+ return;
+error:
+ mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmJoinCnf.sessionId = psessionEntry->peSessionId;
+ mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
+
+}
+
+
+
+/**
+ * limProcessMlmJoinReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_JOIN_REQ message
+ * from SME
+ *
+ *LOGIC:
+ * 1) Initialize LIM, HAL, DPH
+ * 2) Configure the BSS for which the JOIN REQ was received
+ * a) Send WDA_ADD_BSS_REQ to HAL -
+ * This will identify the BSS that we are interested in
+ * --AND--
+ * Add a STA entry for the AP (in a STA context)
+ * b) Wait for WDA_ADD_BSS_RSP
+ * c) Send WDA_ADD_STA_REQ to HAL
+ * This will add the "local STA" entry to the STA table
+ * 3) Continue as before, i.e,
+ * a) Send a PROBE REQ
+ * b) Wait for PROBE RSP/BEACON containing the SSID that
+ * we are interested in
+ * c) Then start an AUTH seq
+ * d) Followed by the ASSOC seq
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tLimMlmJoinCnf mlmJoinCnf;
+ tANI_U8 sessionId;
+ tpPESession psessionEntry;
+
+ sessionId = ((tpLimMlmJoinReq)pMsgBuf)->sessionId;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,sessionId))== NULL)
+ {
+ limLog(pMac, LOGP, FL("session does not exist for given sessionId\n"));
+
+ goto error;
+ }
+
+ if (( (psessionEntry->limSystemRole != eLIM_AP_ROLE ) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE )) &&
+ ( (psessionEntry->limMlmState == eLIM_MLM_IDLE_STATE) ||
+ (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE)) &&
+ (SIR_MAC_GET_ESS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo) !=
+ SIR_MAC_GET_IBSS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo)))
+ {
+ #if 0
+ if (pMac->lim.gpLimMlmJoinReq)
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmJoinReq);
+ #endif //TO SUPPORT BT-AMP , review 23sep
+
+ /// Hold onto Join request parameters
+
+ psessionEntry->pLimMlmJoinReq =(tpLimMlmJoinReq) pMsgBuf;
+
+ if( isLimSessionOffChannel(pMac, sessionId) )
+ {
+ //suspend link
+ limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN,
+ limProcessMlmPostJoinSuspendLink, (tANI_U32*)psessionEntry );
+ }
+ else
+ {
+ //No need to suspend link.
+ limProcessMlmPostJoinSuspendLink( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) psessionEntry );
+ }
+
+ return;
+ }
+ else
+ {
+ /**
+ * Should not have received JOIN req in states other than
+ * Idle state or on AP.
+ * Return join confirm with invalid parameters code.
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("Unexpected Join request for role %d state %X\n"),
+ psessionEntry->limSystemRole,
+ psessionEntry->limMlmState);)
+ limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
+
+ limLog(pMac, LOGE, FL("Unexpected Join request for role %d state %X\n"),
+ psessionEntry->limSystemRole, pMac->lim.gLimMlmState);
+ }
+
+error:
+
+
+ mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmJoinCnf.sessionId = sessionId;
+ mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
+
+
+} /*** limProcessMlmJoinReq() ***/
+
+
+
+/**
+ * limProcessMlmAuthReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_AUTH_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U32 numPreAuthContexts;
+ tSirMacAddr currentBssId;
+ tSirMacAuthFrameBody authFrameBody;
+ tLimMlmAuthCnf mlmAuthCnf;
+ struct tLimPreAuthNode *preAuthNode;
+ tpDphHashNode pStaDs;
+ tANI_U8 sessionId;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMac->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) pMsgBuf;
+ sessionId = pMac->lim.gpLimMlmAuthReq->sessionId;
+ if((psessionEntry= peFindSessionBySessionId(pMac,sessionId) )== NULL)
+ {
+ limLog(pMac, LOGP, FL("Session Does not exist for given sessionId\n"));
+ return;
+ }
+
+ /**
+ * Expect Auth request only when:
+ * 1. STA joined/associated with a BSS or
+ * 2. STA is in IBSS mode
+ * and STA is going to authenticate with a unicast
+ * adress and requested authentication algorithm is
+ * supported.
+ */
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //To SuppoRT BT-AMP
+
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ if (((((psessionEntry->limSystemRole== eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
+ ((psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) ||
+ (psessionEntry->limMlmState ==
+ eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
+ ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
+ (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))) &&
+ (limIsGroupAddr(pMac->lim.gpLimMlmAuthReq->peerMacAddr)
+ == false) &&
+#ifdef WLAN_SOFTAP_FEATURE
+ (limIsAuthAlgoSupported(
+ pMac,
+ pMac->lim.gpLimMlmAuthReq->authType,
+ psessionEntry) == true)
+#else
+ (limIsAuthAlgoSupported(
+ pMac,
+ pMac->lim.gpLimMlmAuthReq->authType) == true)
+#endif
+ )
+ {
+ /**
+ * This is a request for pre-authentication.
+ * Check if there exists context already for
+ * the requsted peer OR
+ * if this request is for the AP we're currently
+ * associated with.
+ * If yes, return auth confirm immediately when
+ * requested auth type is same as the one used before.
+ */
+ if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )&&
+ (psessionEntry->limMlmState ==
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) != NULL) &&
+ (pMac->lim.gpLimMlmAuthReq->authType ==
+ pStaDs->mlmStaContext.authType)) &&
+ (palEqualMemory( pMac->hHdd,pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ currentBssId,
+ sizeof(tSirMacAddr)) )) ||
+ (((preAuthNode =
+ limSearchPreAuthList(
+ pMac,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr)) != NULL) &&
+ (preAuthNode->authType ==
+ pMac->lim.gpLimMlmAuthReq->authType)))
+ {
+ PELOG2(limLog(pMac, LOG2,
+ FL("Already have pre-auth context with peer\n"));
+ limPrintMacAddr(pMac, pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ LOG2);)
+
+ mlmAuthCnf.resultCode = (tSirResultCodes)
+ eSIR_MAC_SUCCESS_STATUS;
+
+
+ goto end;
+ }
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
+ (tANI_U32 *) &numPreAuthContexts) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Could not retrieve NumPreAuthLimit from CFG\n"));
+ }
+#ifdef ANI_AP_SDK_OPT
+ if(numPreAuthContexts > SIR_SDK_OPT_MAX_NUM_PRE_AUTH)
+ numPreAuthContexts = SIR_SDK_OPT_MAX_NUM_PRE_AUTH;
+#endif // ANI_AP_SDK_OPT
+
+ if (pMac->lim.gLimNumPreAuthContexts == numPreAuthContexts)
+ {
+ PELOGW(limLog(pMac, LOGW,
+ FL("Number of pre-auth reached max limit\n"));)
+
+ /// Return Auth confirm with reject code
+ mlmAuthCnf.resultCode =
+ eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;
+
+ goto end;
+ }
+ }
+
+ // Delete pre-auth node if exists
+ if (preAuthNode)
+ limDeletePreAuthNode(pMac,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr);
+
+ //assign appropriate sessionId to the timer object
+ pMac->lim.limTimers.gLimAuthFailureTimer.sessionId = sessionId;
+
+ // Activate Auth failure timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_AUTH_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not start Auth failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not start Auth failure timer\n"));
+
+ /// Return Auth confirm with Resources Unavailable
+ mlmAuthCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+
+ goto end;
+ }
+
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /// Prepare & send Authentication frame
+ authFrameBody.authAlgoNumber =
+ (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType;
+ authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrameBody.authStatusCode = 0;
+ limSendAuthMgmtFrame(pMac,
+ &authFrameBody,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ LIM_NO_WEP_IN_FC,psessionEntry);
+
+ return;
+ }
+ else
+ {
+ /**
+ * Unexpected auth request.
+ * Return Auth confirm with Invalid parameters code.
+ */
+ mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+
+ goto end;
+ }
+
+end:
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmAuthCnf.peerMacAddr,
+ (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType;
+ mlmAuthCnf.sessionId = sessionId;
+
+ /// Free up buffer allocated
+ /// for pMac->lim.gLimMlmAuthReq
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+ limPostSmeMessage(pMac, LIM_MLM_AUTH_CNF, (tANI_U32 *) &mlmAuthCnf);
+} /*** limProcessMlmAuthReq() ***/
+
+
+
+/**
+ * limProcessMlmAssocReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_ASSOC_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmAssocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMacAddr currentBssId;
+ tLimMlmAssocReq *pMlmAssocReq;
+ tLimMlmAssocCnf mlmAssocCnf;
+ tpPESession psessionEntry;
+ // tANI_U8 sessionId;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmAssocReq = (tLimMlmAssocReq *) pMsgBuf;
+
+ if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmAssocReq->sessionId) )== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ if ( (psessionEntry->limSystemRole != eLIM_AP_ROLE && psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE) &&
+ (psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) &&
+ (palEqualMemory(pMac->hHdd,pMlmAssocReq->peerMacAddr, currentBssId, sizeof(tSirMacAddr))) )
+ {
+ /// map the session entry pointer to the AssocFailureTimer
+ pMac->lim.limTimers.gLimAssocFailureTimer.sessionId = pMlmAssocReq->sessionId;
+
+
+ /// Start association failure timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_ASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimAssocFailureTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not start Assoc failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not start Association failure timer\n"));
+
+ /// Return Assoc confirm with Resources Unavailable
+
+ mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ goto end;
+ }
+
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /// Prepare and send Association request frame
+ limSendAssocReqMgmtFrame(pMac, pMlmAssocReq,psessionEntry);
+
+ //Set the link state to postAssoc, so HW can start receiving frames from AP.
+ if ((psessionEntry->bssType == eSIR_BTAMP_STA_MODE)||
+ ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))
+ {
+ if(limSetLinkState(pMac, eSIR_LINK_BTAMP_POSTASSOC_STATE, currentBssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+ } else {
+ if(limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, currentBssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+ }
+
+ return;
+ }
+ else
+ {
+ /**
+ * Received Association request either in invalid state
+ * or to a peer MAC entity whose address is different
+ * from one that STA is currently joined with or on AP.
+ * Return Assoc confirm with Invalid parameters code.
+ */
+
+ // Log error
+ PELOGW(limLog(pMac, LOGW,
+ FL("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "),
+ psessionEntry->limMlmState,
+ psessionEntry->limSystemRole);)
+ limPrintMacAddr(pMac, pMlmAssocReq->peerMacAddr, LOGW);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+
+ mlmAssocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ goto end;
+ }
+
+end:
+ /* Update PE session Id*/
+ mlmAssocCnf.sessionId = pMlmAssocReq->sessionId;
+
+ /// Free up buffer allocated for assocReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmAssocReq);
+
+ limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
+} /*** limProcessMlmAssocReq() ***/
+
+
+
+/**
+ * limProcessMlmReassocReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_REASSOC_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U8 chanNum;
+ struct tLimPreAuthNode *pAuthNode;
+ tLimMlmReassocReq *pMlmReassocReq;
+ tLimMlmReassocCnf mlmReassocCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmReassocReq = (tLimMlmReassocReq *) pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmReassocReq->sessionId)) == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Session Does not exist for given sessionId\n"));)
+ return;
+ }
+
+ if (((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) &&
+ (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))
+ {
+ if (psessionEntry->pLimMlmReassocReq)
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmReassocReq);
+
+ /* Hold Re-Assoc request as part of Session, knock-out pMac */
+ /// Hold onto Reassoc request parameters
+ psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
+
+ // See if we have pre-auth context with new AP
+ pAuthNode = limSearchPreAuthList(pMac, psessionEntry->limReAssocbssId);
+
+ if (!pAuthNode &&
+ (!palEqualMemory( pMac->hHdd,pMlmReassocReq->peerMacAddr,
+ psessionEntry->bssId,
+ sizeof(tSirMacAddr)) ))
+ {
+ // Either pre-auth context does not exist AND
+ // we are not reassociating with currently
+ // associated AP.
+ // Return Reassoc confirm with not authenticated
+ mlmReassocCnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ goto end;
+ }
+
+ //assign the sessionId to the timer object
+ pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = pMlmReassocReq->sessionId;
+
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+#if 0
+ // Update BSSID at CFG database
+ if (wlan_cfgSetStr(pMac, WNI_CFG_BSSID,
+ pMac->lim.gLimReassocBssId,
+ sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ /// Could not update BSSID at CFG. Log error.
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+ }
+#endif //TO SUPPORT BT-AMP
+
+ /* Copy Global Reassoc ID*/
+ // sirCopyMacAddr(psessionEntry->reassocbssId,pMac->lim.gLimReAssocBssId);
+
+ /**
+ * Derive channel from BSS description and
+ * store it at CFG.
+ */
+
+ chanNum = psessionEntry->limReassocChannelId;
+
+
+ /* To Support BT-AMP .. read channel number from psessionEntry*/
+ //chanNum = psessionEntry->currentOperChannel;
+
+ // Apply previously set configuration at HW
+ limApplyConfiguration(pMac,psessionEntry);
+
+ //store the channel switch sessionEntry in the lim global var
+ /* We have already saved the ReAssocreq Pointer abobe */
+ //psessionEntry->pLimReAssocReq = (void *)pMlmReassocReq;
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_REASSOC;
+
+ /** Switch channell to the new Operating channel for Reassoc*/
+ limSetChannel(pMac, psessionEntry->limReassocTitanHtCaps, chanNum, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+
+ return;
+ }
+ else
+ {
+ /**
+ * Received Reassoc request in invalid state or
+ * in AP role.Return Reassoc confirm with Invalid
+ * parameters code.
+ */
+
+ // Log error
+ PELOGW(limLog(pMac, LOGW,
+ FL("received unexpected MLM_REASSOC_CNF in state %X for role=%d, MAC addr= "),
+ psessionEntry->limMlmState,
+ psessionEntry->limSystemRole);)
+ limPrintMacAddr(pMac, pMlmReassocReq->peerMacAddr,
+ LOGW);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+
+ mlmReassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ goto end;
+ }
+
+end:
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id*/
+ mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
+ /// Free up buffer allocated for reassocReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
+ psessionEntry->pLimReAssocReq = NULL;
+
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+} /*** limProcessMlmReassocReq() ***/
+
+
+static void
+limProcessMlmDisassocReqPostSuspend(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 aid;
+ tSirMacAddr currentBssId;
+ tpDphHashNode pStaDs;
+ tLimMlmDisassocReq *pMlmDisassocReq;
+ tLimMlmDisassocCnf mlmDisassocCnf;
+ tpPESession psessionEntry;
+ extern tANI_BOOLEAN sendDisassocFrame;
+
+ if(eHAL_STATUS_SUCCESS != suspendStatus)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X\n"), suspendStatus);)
+#if 0
+ //It can ignore the status and proceed with the disassoc processing.
+ mlmDisassocCnf.resultCode = eSIR_SME_REFUSED;
+ goto end;
+#endif
+ }
+
+ pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf;
+
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL)
+ {
+
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given sessionId\n"));)
+ mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //BT-AMP Support
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ if ( !palEqualMemory( pMac->hHdd,pMlmDisassocReq->peerMacAddr,
+ currentBssId,
+ sizeof(tSirMacAddr)) )
+ {
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DISASSOC_REQ with invalid BSS id "));)
+ limPrintMacAddr(pMac, pMlmDisassocReq->peerMacAddr, LOGW);
+
+ /// Prepare and Send LIM_MLM_DISASSOC_CNF
+
+ mlmDisassocCnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+
+ goto end;
+ }
+
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+
+ break;
+
+ default: // eLIM_AP_ROLE
+
+ // Fall through
+ break;
+
+ } // end switch (psessionEntry->limSystemRole)
+
+ /**
+ * Check if there exists a context for the peer entity
+ * to be disassociated with.
+ */
+ pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if ((pStaDs == NULL) ||
+ (pStaDs &&
+ ((pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+ (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_ASSOCIATED_STATE))))
+ {
+ /**
+ * Received LIM_MLM_DISASSOC_REQ for STA that does not
+ * have context or in some transit state.
+ * Log error
+ */
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DISASSOC_REQ for STA that either has no context or in some transit state, Addr= "));)
+ limPrintMacAddr(pMac, pMlmDisassocReq->peerMacAddr, LOGW);
+
+ /// Prepare and Send LIM_MLM_DISASSOC_CNF
+
+ mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+
+ goto end;
+ }
+
+ //pStaDs->mlmStaContext.rxPurgeReq = 1;
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+ pMlmDisassocReq->reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger = pMlmDisassocReq->disassocTrigger;
+
+ /// Send Disassociate frame to peer entity
+ if (sendDisassocFrame)
+ {
+ limSendDisassocMgmtFrame(pMac,
+ pMlmDisassocReq->reasonCode,
+ pMlmDisassocReq->peerMacAddr,psessionEntry);
+ }
+ else
+ {
+ sendDisassocFrame = 1;
+ }
+
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ //SAP mode delay DEL STA for 300ms such that disassoc can be delivered at TIM
+ //100 ms for normal TIM and 300 ms for dynamic TIM
+ vos_sleep(300);
+ }
+
+ /// Receive path cleanup with dummy packet
+ if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs,psessionEntry))
+ {
+ mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE ) &&
+ (
+#ifdef FEATURE_WLAN_CCX
+ (psessionEntry->isCCXconnection ) ||
+#endif
+ (psessionEntry->is11Rconnection )) &&
+ (pMlmDisassocReq->reasonCode != eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("FT Preauth Session Cleanup \n"));)
+ limFTCleanup(pMac);
+ }
+#endif
+
+ /// Free up buffer allocated for mlmDisassocReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDisassocReq);
+
+ return;
+
+end:
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDisassocCnf.peerMacAddr,
+ (tANI_U8 *) pMlmDisassocReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlmDisassocCnf.aid = pMlmDisassocReq->aid;
+ mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger;
+
+ /* Update PE session ID*/
+ mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId;
+
+ /// Free up buffer allocated for mlmDisassocReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDisassocReq);
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DISASSOC_CNF,
+ (tANI_U32 *) &mlmDisassocCnf);
+}
+
+/**
+ * limProcessMlmDisassocReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_DISASSOC_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+// tANI_U16 aid;
+// tSirMacAddr currentBssId;
+// tpDphHashNode pStaDs;
+ tLimMlmDisassocReq *pMlmDisassocReq;
+// tLimMlmDisassocCnf mlmDisassocCnf;
+ tpPESession psessionEntry;
+// extern tANI_BOOLEAN sendDisassocFrame;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL)
+ {
+
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+ if( isLimSessionOffChannel(pMac, pMlmDisassocReq->sessionId) )
+ {
+ //suspend link
+ limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN,
+ limProcessMlmDisassocReqPostSuspend, (tANI_U32*)pMsgBuf );
+ }
+ else
+ {
+ //No need to suspend link.
+ limProcessMlmDisassocReqPostSuspend( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsgBuf );
+ }
+} /*** limProcessMlmDisassocReq() ***/
+
+static void
+limProcessMlmDeauthReqPostSuspend(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 aid;
+ tSirMacAddr currentBssId;
+ tpDphHashNode pStaDs;
+ struct tLimPreAuthNode *pAuthNode;
+ tLimMlmDeauthReq *pMlmDeauthReq;
+ tLimMlmDeauthCnf mlmDeauthCnf;
+ tpPESession psessionEntry;
+
+
+ if(eHAL_STATUS_SUCCESS != suspendStatus)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X\n"), suspendStatus);)
+#if 0
+ //It can ignore the status and proceed with the disassoc processing.
+ mlmDisassocCnf.resultCode = eSIR_SME_REFUSED;
+ goto end;
+#endif
+ }
+
+ pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL)
+ {
+
+ PELOGE(limLog(pMac, LOGE, FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (psessionEntry->limMlmState)
+ {
+ case eLIM_MLM_IDLE_STATE:
+ // Attempting to Deauthenticate
+ // with a pre-authenticated peer.
+ // Deauthetiate with peer if there
+ // exists a pre-auth context below.
+ break;
+
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+ if (!palEqualMemory( pMac->hHdd,pMlmDeauthReq->peerMacAddr,
+ currentBssId,
+ sizeof(tSirMacAddr)) )
+ {
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DEAUTH_REQ with invalid BSS id "));)
+ PELOGE(limLog(pMac, LOGE, FL("Peer MAC Addr : "));)
+ limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr,LOGE);
+
+ PELOGE(limLog(pMac, LOGE, FL("\n CFG BSSID Addr : "));)
+ limPrintMacAddr(pMac, currentBssId,LOGE);
+
+ /// Prepare and Send LIM_MLM_DEAUTH_CNF
+
+ mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+
+ goto end;
+ }
+
+ if ((psessionEntry->limMlmState ==
+ eLIM_MLM_AUTHENTICATED_STATE) ||
+ (psessionEntry->limMlmState ==
+ eLIM_MLM_WT_ASSOC_RSP_STATE))
+ {
+ // Send Deauthentication frame
+ // to peer entity
+ limSendDeauthMgmtFrame(
+ pMac,
+ pMlmDeauthReq->reasonCode,
+ pMlmDeauthReq->peerMacAddr,psessionEntry);
+
+ /// Prepare and Send LIM_MLM_DEAUTH_CNF
+ mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS;
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ goto end;
+ }
+ else
+ {
+ // LINK_ESTABLISED_STATE
+ // Cleanup RX & TX paths
+ // below
+ }
+
+ break;
+
+ default:
+
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DEAUTH_REQ with in state %d for peer "),
+ psessionEntry->limMlmState);)
+ limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+
+ /// Prepare and Send LIM_MLM_DEAUTH_CNF
+ mlmDeauthCnf.resultCode =
+ eSIR_SME_STA_NOT_AUTHENTICATED;
+
+ goto end;
+ }
+
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+
+ return;
+
+ default: // eLIM_AP_ROLE
+ break;
+
+ } // end switch (psessionEntry->limSystemRole)
+
+ /**
+ * Check if there exists a context for the peer entity
+ * to be deauthenticated with.
+ */
+ pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ /// Check if there exists pre-auth context for this STA
+ pAuthNode = limSearchPreAuthList(pMac,
+ pMlmDeauthReq->peerMacAddr);
+
+ if (pAuthNode == NULL)
+ {
+ /**
+ * Received DEAUTH REQ for a STA that is neither
+ * Associated nor Pre-authenticated. Log error,
+ * Prepare and Send LIM_MLM_DEAUTH_CNF
+ */
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DEAUTH_REQ for STA that does not have context, Addr="));)
+ limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);
+
+ mlmDeauthCnf.resultCode =
+ eSIR_SME_STA_NOT_AUTHENTICATED;
+ }
+ else
+ {
+ mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS;
+
+ /// Delete STA from pre-auth STA list
+ limDeletePreAuthNode(pMac, pMlmDeauthReq->peerMacAddr);
+
+ /// Send Deauthentication frame to peer entity
+ limSendDeauthMgmtFrame(pMac,
+ pMlmDeauthReq->reasonCode,
+ pMlmDeauthReq->peerMacAddr,psessionEntry);
+ }
+
+ goto end;
+ }
+ else if ((pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE))
+ {
+ /**
+ * Received LIM_MLM_DEAUTH_REQ for STA that is n
+ * some transit state. Log error.
+ */
+ PELOGW(limLog(pMac, LOGW,
+ FL("received MLM_DEAUTH_REQ for STA that either has no context or in some transit state, Addr="));)
+ limPrintMacAddr(pMac, pMlmDeauthReq->peerMacAddr, LOGW);
+
+ /// Prepare and Send LIM_MLM_DEAUTH_CNF
+
+ mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+
+ goto end;
+ }
+
+ //pStaDs->mlmStaContext.rxPurgeReq = 1;
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+ pMlmDeauthReq->reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger = pMlmDeauthReq->deauthTrigger;
+
+ /// Send Deauthentication frame to peer entity
+ limSendDeauthMgmtFrame(pMac, pMlmDeauthReq->reasonCode,
+ pMlmDeauthReq->peerMacAddr,psessionEntry);
+
+ if( (psessionEntry->limSystemRole == eSYSTEM_AP_ROLE))
+ {
+ // Delay DEL STA for 300ms such that unicast deauth is
+ // delivered at TIM(100 for normal or 300ms for dynamic)
+ // to power save stations after setting PVB
+ vos_sleep(300);
+ }
+
+ /// Receive path cleanup with dummy packet
+ limCleanupRxPath(pMac, pStaDs,psessionEntry);
+
+ /// Free up buffer allocated for mlmDeauthReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);
+
+ return;
+
+end:
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmDeauthCnf.peerMacAddr,
+ (tANI_U8 *) pMlmDeauthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
+ mlmDeauthCnf.aid = pMlmDeauthReq->aid;
+ mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
+
+ // Free up buffer allocated
+ // for mlmDeauthReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmDeauthReq);
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_DEAUTH_CNF,
+ (tANI_U32 *) &mlmDeauthCnf);
+
+}
+
+/**
+ * limProcessMlmDeauthReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_DEAUTH_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+// tANI_U16 aid;
+// tSirMacAddr currentBssId;
+// tpDphHashNode pStaDs;
+// struct tLimPreAuthNode *pAuthNode;
+ tLimMlmDeauthReq *pMlmDeauthReq;
+// tLimMlmDeauthCnf mlmDeauthCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL)
+ {
+
+ PELOGE(limLog(pMac, LOGE, FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+ if( isLimSessionOffChannel(pMac, pMlmDeauthReq->sessionId) )
+ {
+ //suspend link
+ limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN,
+ limProcessMlmDeauthReqPostSuspend, (tANI_U32*)pMsgBuf );
+ }
+ else
+ {
+ //No need to suspend link.
+ limProcessMlmDeauthReqPostSuspend( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsgBuf );
+ }
+} /*** limProcessMlmDeauthReq() ***/
+
+
+
+/**
+ * @function : limProcessMlmSetKeysReq()
+ *
+ * @brief : This function is called to process MLM_SETKEYS_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmSetKeysReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+tANI_U16 aid;
+tANI_U16 staIdx = 0;
+tANI_U32 defaultKeyId = 0;
+tSirMacAddr currentBssId;
+tpDphHashNode pStaDs;
+tLimMlmSetKeysReq *pMlmSetKeysReq;
+tLimMlmSetKeysCnf mlmSetKeysCnf;
+tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+
+ pMlmSetKeysReq = (tLimMlmSetKeysReq *) pMsgBuf;
+ // Hold onto the SetKeys request parameters
+ pMac->lim.gpLimMlmSetKeysReq = (void *) pMlmSetKeysReq;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmSetKeysReq->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Received MLM_SETKEYS_REQ with parameters:\n"
+ "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "),
+ pMlmSetKeysReq->aid,
+ pMlmSetKeysReq->edType,
+ pMlmSetKeysReq->numKeys );
+ limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );
+
+ #if 0
+ if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, currentBssId, &cfg )) {
+ limLog( pMac, LOGP, FL("Could not retrieve BSSID\n"));
+ return;
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ switch( psessionEntry->limSystemRole ) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ if((!limIsAddrBC( pMlmSetKeysReq->peerMacAddr ) ) &&
+ (!palEqualMemory( pMac->hHdd,pMlmSetKeysReq->peerMacAddr,
+ currentBssId, sizeof(tSirMacAddr))) ){
+ limLog( pMac, LOGW, FL("Received MLM_SETKEYS_REQ with invalid BSSID\n"));
+ limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );
+
+ // Prepare and Send LIM_MLM_SETKEYS_CNF with error code
+ mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ // Fall thru' & 'Plumb' keys below
+ break;
+ case eLIM_STA_IN_IBSS_ROLE:
+ default: // others
+ // Fall thru...
+ break;
+ }
+
+ /**
+ * Use the "unicast" parameter to determine if the "Group Keys"
+ * are being set.
+ * pMlmSetKeysReq->key.unicast = 0 -> Multicast/broadcast
+ * pMlmSetKeysReq->key.unicast - 1 -> Unicast keys are being set
+ */
+ if( limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) {
+ limLog( pMac, LOG1, FL("Trying to set Group Keys...%d \n"), pMlmSetKeysReq->sessionId);
+ /** When trying to set Group Keys for any
+ * security mode other than WEP, use the
+ * STA Index corresponding to the AP...
+ */
+ switch( pMlmSetKeysReq->edType ) {
+ case eSIR_ED_CCMP:
+
+#ifdef WLAN_FEATURE_11W
+ case eSIR_ED_AES_128_CMAC:
+#endif
+ staIdx = psessionEntry->staId;
+ break;
+
+ default:
+ break;
+ }
+ }else {
+ limLog( pMac, LOG1, FL("Trying to set Unicast Keys...\n"));
+ /**
+ * Check if there exists a context for the
+ * peer entity for which keys need to be set.
+ */
+
+
+ pStaDs = dphLookupHashEntry( pMac, pMlmSetKeysReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((pStaDs == NULL) ||
+ ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) && (psessionEntry->limSystemRole != eLIM_AP_ROLE))) {
+#else
+ if ((pStaDs == NULL) ||
+ ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) )) {
+#endif
+ /**
+ * Received LIM_MLM_SETKEYS_REQ for STA
+ * that does not have context or in some
+ * transit state. Log error.
+ */
+ limLog( pMac, LOG1,
+ FL("Received MLM_SETKEYS_REQ for STA that either has no context or in some transit state, Addr = "));
+ limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW );
+
+ // Prepare and Send LIM_MLM_SETKEYS_CNF
+ mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ } else
+ staIdx = pStaDs->staIndex;
+ }
+
+ if ((pMlmSetKeysReq->numKeys == 0) && (pMlmSetKeysReq->edType != eSIR_ED_NONE)) {
+ //
+ // Broadcast/Multicast Keys (for WEP!!) are NOT sent
+ // via this interface!!
+ //
+ // This indicates to HAL that the WEP Keys need to be
+ // extracted from the CFG and applied to hardware
+ defaultKeyId = 0xff;
+ }else
+ defaultKeyId = 0;
+
+ limLog( pMac, LOG1,
+ FL( "Trying to set keys for STA Index [%d], using defaultKeyId [%d]\n" ),
+ staIdx,
+ defaultKeyId );
+
+ if(limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) {
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ limLog( pMac, LOG1, FL("Trying to set Group Keys...%d \n"),
+ psessionEntry->peSessionId);
+
+ // Package WDA_SET_BSSKEY_REQ message parameters
+ limSendSetBssKeyReq(pMac, pMlmSetKeysReq,psessionEntry);
+ return;
+ }else {
+ // Package WDA_SET_STAKEY_REQ / WDA_SET_STA_BCASTKEY_REQ message parameters
+ limSendSetStaKeyReq(pMac, pMlmSetKeysReq, staIdx, (tANI_U8) defaultKeyId,psessionEntry);
+ return;
+ }
+
+end:
+ mlmSetKeysCnf.sessionId= pMlmSetKeysReq->sessionId;
+ limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf );
+
+} /*** limProcessMlmSetKeysReq() ***/
+
+/**
+ * limProcessMlmRemoveKeyReq()
+ *
+ *FUNCTION:
+ * This function is called to process MLM_REMOVEKEY_REQ message
+ * from SME
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ * @return None
+ */
+
+static void
+limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+tANI_U16 aid;
+tANI_U16 staIdx = 0;
+tSirMacAddr currentBssId;
+tpDphHashNode pStaDs;
+tLimMlmRemoveKeyReq *pMlmRemoveKeyReq;
+tLimMlmRemoveKeyCnf mlmRemoveKeyCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmRemoveKeyReq = (tLimMlmRemoveKeyReq *) pMsgBuf;
+
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyReq->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+
+ if( pMac->lim.gpLimMlmRemoveKeyReq != NULL )
+ {
+ // Free any previous requests.
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMac->lim.gpLimMlmRemoveKeyReq);
+ pMac->lim.gpLimMlmRemoveKeyReq = NULL;
+ }
+ // Hold onto the RemoveKeys request parameters
+ pMac->lim.gpLimMlmRemoveKeyReq = (void *) pMlmRemoveKeyReq;
+
+ #if 0
+ if( eSIR_SUCCESS != wlan_cfgGetStr( pMac,
+ WNI_CFG_BSSID,
+ currentBssId,
+ &cfg ))
+ limLog( pMac, LOGP, FL("Could not retrieve BSSID\n"));
+ #endif //TO-SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ switch( psessionEntry->limSystemRole )
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ if(( limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr ) != true ) &&
+ (!palEqualMemory( pMac->hHdd,pMlmRemoveKeyReq->peerMacAddr,
+ currentBssId,
+ sizeof(tSirMacAddr))))
+ {
+ limLog( pMac, LOGW,
+ FL("Received MLM_REMOVEKEY_REQ with invalid BSSID\n"));
+ limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW );
+
+ // Prepare and Send LIM_MLM_REMOVEKEY_CNF with error code
+ mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ default: // eLIM_AP_ROLE
+ // Fall thru...
+ break;
+ }
+
+
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ if(limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr )) //Second condition for IBSS or AP role.
+ {
+ psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_BSS_KEY_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ // Package WDA_REMOVE_BSSKEY_REQ message parameters
+ limSendRemoveBssKeyReq( pMac,pMlmRemoveKeyReq,psessionEntry);
+ return;
+ }
+
+ /**
+ * Check if there exists a context for the
+ * peer entity for which keys need to be removed.
+ */
+ pStaDs = dphLookupHashEntry( pMac, pMlmRemoveKeyReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable );
+ if ((pStaDs == NULL) ||
+ (pStaDs &&
+ (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE)))
+ {
+ /**
+ * Received LIM_MLM_REMOVEKEY_REQ for STA
+ * that does not have context or in some
+ * transit state. Log error.
+ */
+ limLog( pMac, LOGW,
+ FL("Received MLM_REMOVEKEYS_REQ for STA that either has no context or in some transit state, Addr = "));
+ limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW );
+
+ // Prepare and Send LIM_MLM_REMOVEKEY_CNF
+ mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ mlmRemoveKeyCnf.sessionId = pMlmRemoveKeyReq->sessionId;
+
+
+ goto end;
+ }
+ else
+ staIdx = pStaDs->staIndex;
+
+
+
+ psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_STA_KEY_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ // Package WDA_REMOVE_STAKEY_REQ message parameters
+ limSendRemoveStaKeyReq( pMac,pMlmRemoveKeyReq,staIdx,psessionEntry);
+ return;
+
+end:
+ limPostSmeRemoveKeyCnf( pMac,
+ pMlmRemoveKeyReq,
+ &mlmRemoveKeyCnf );
+
+} /*** limProcessMlmRemoveKeyReq() ***/
+
+
+/**
+ * limProcessMinChannelTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process Min Channel Timeout
+ * during channel scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessMinChannelTimeout(tpAniSirGlobal pMac)
+{
+ tANI_U8 channelNum;
+
+#ifdef GEN6_TODO
+ //if the min Channel is maintained per session, then use the below seesionEntry
+ //priority - LOW/might not be needed
+
+ //TBD-RAJESH HOW TO GET sessionEntry?????
+ tpPESession psessionEntry;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimMinChannelTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+#endif
+
+
+ if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Scanning : min channel timeout occurred\n"));)
+
+ /// Min channel timer timed out
+ pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff;
+ limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
+ limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER);
+ if (pMac->lim.gLimCurrentScanChannelId <=
+ (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
+ {
+ channelNum = (tANI_U8)limGetCurrentScanChannel(pMac);
+ }
+ else
+ {
+ // This shouldn't be the case, but when this happens, this timeout should be for the last channelId.
+ // Get the channelNum as close to correct as possible.
+ if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber)
+ {
+ channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1];
+ }
+ else
+ {
+ channelNum = 1;
+ }
+ }
+
+ limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
+ }
+ else
+ {
+ /**
+ * MIN channel timer should not have timed out
+ * in states other than wait_probe_response.
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("received unexpected MIN channel timeout in state %X\n"),
+ pMac->lim.gLimMlmState);
+ limPrintMlmState(pMac, LOGE, pMac->lim.gLimMlmState);
+ }
+} /*** limProcessMinChannelTimeout() ***/
+
+
+
+/**
+ * limProcessMaxChannelTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process Max Channel Timeout
+ * during channel scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessMaxChannelTimeout(tpAniSirGlobal pMac)
+{
+ tANI_U8 channelNum;
+
+
+ if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE ||
+ pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Scanning : Max channel timed out\n"));)
+ /**
+ * MAX channel timer timed out
+ * Continue channel scan.
+ */
+ limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
+ limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER);
+ pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff;
+ if (pMac->lim.gLimCurrentScanChannelId <=
+ (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))
+ {
+ channelNum = limGetCurrentScanChannel(pMac);
+ }
+ else
+ {
+ if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber)
+ {
+ channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1];
+ }
+ else
+ {
+ channelNum = 1;
+ }
+ }
+ limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE);
+ }
+ else
+ {
+ /**
+ * MAX channel timer should not have timed out
+ * in states other than wait_scan.
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("received unexpected MAX channel timeout in state %X\n"),
+ pMac->lim.gLimMlmState);
+ limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState);
+ }
+} /*** limProcessMaxChannelTimeout() ***/
+
+/**
+ * limProcessPeriodicProbeReqTimer()
+ *
+ *FUNCTION:
+ * This function is called to process periodic probe request
+ * to send during scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac)
+{
+ tANI_U8 channelNum;
+ tANI_U8 i = 0;
+ tSirRetStatus status = eSIR_SUCCESS;
+ TX_TIMER *pPeriodicProbeReqTimer;
+ pPeriodicProbeReqTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer;
+
+ if(vos_timer_getCurrentState(&pPeriodicProbeReqTimer->vosTimer)
+ != VOS_TIMER_STATE_STOPPED)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Invalid state of timer\n"));)
+ return;
+ }
+
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) &&
+ (pPeriodicProbeReqTimer->sessionId != 0xff))
+ {
+ tLimMlmScanReq *pLimMlmScanReq = pMac->lim.gpLimMlmScanReq;
+ PELOG1(limLog(pMac, LOG1, FL("Scanning : Periodic scanning\n"));)
+ /**
+ * Periodic channel timer timed out
+ * to send probe request.
+ */
+ channelNum = limGetCurrentScanChannel(pMac);
+ do
+ {
+ /* Prepare and send Probe Request frame for all the SSIDs
+ * present in the saved MLM
+ */
+
+ /*
+ * PELOGE(limLog(pMac, LOGW, FL("sending ProbeReq number %d,"
+ * " for SSID %s on channel: %d\n"),
+ * i, pLimMlmScanReq->ssId[i].ssId,
+ * channelNum);)
+ */
+ status = limSendProbeReqMgmtFrame( pMac, &pLimMlmScanReq->ssId[i],
+ pLimMlmScanReq->bssId, channelNum, pMac->lim.gSelfMacAddr,
+ pLimMlmScanReq->dot11mode, pLimMlmScanReq->uIEFieldLen,
+ (tANI_U8 *)(pLimMlmScanReq) + pLimMlmScanReq->uIEFieldOffset);
+
+
+ if ( status != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID "
+ "%s on channel: %d\n"),
+ pLimMlmScanReq->ssId[i].ssId,
+ channelNum);)
+ return;
+ }
+ i++;
+ } while (i < pLimMlmScanReq->numSsid);
+
+ /* Activate timer again */
+ if (tx_timer_activate(pPeriodicProbeReqTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start periodic probe"
+ " req timer\n"));
+ return;
+ }
+ }
+ else
+ {
+ /**
+ * Periodic scan is timeout is happening in
+ * in states other than wait_scan.
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("received unexpected Periodic scan timeout in state %X\n"),
+ pMac->lim.gLimMlmState);
+ }
+} /*** limProcessPeriodicProbeReqTimer() ***/
+
+/**
+ * limProcessJoinFailureTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process JoinFailureTimeout
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessJoinFailureTimeout(tpAniSirGlobal pMac)
+{
+ tLimMlmJoinCnf mlmJoinCnf;
+ tSirMacAddr bssid;
+ tANI_U32 len;
+
+ //fetch the sessionEntry based on the sessionId
+ tpPESession psessionEntry;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimJoinFailureTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)
+ {
+ len = sizeof(tSirMacAddr);
+
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, bssid, &len) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ return;
+ }
+
+ // 'Change' timer for future activations
+ limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER);
+
+ /**
+ * Issue MLM join confirm with timeout reason code
+ */
+ PELOGE(limLog(pMac, LOGE, FL(" Join Failure Timeout occurred.\n"));)
+
+ mlmJoinCnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
+ mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+ /* Update PE session Id */
+ mlmJoinCnf.sessionId = psessionEntry->peSessionId;
+
+
+ // Freeup buffer allocated to join request
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_JOIN_CNF,
+ (tANI_U32 *) &mlmJoinCnf);
+
+ return;
+ }
+ else
+ {
+ /**
+ * Join failure timer should not have timed out
+ * in states other than wait_join_beacon state.
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("received unexpected JOIN failure timeout in state %X\n"),psessionEntry->limMlmState);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+ }
+} /*** limProcessJoinFailureTimeout() ***/
+
+
+
+/**
+ * limProcessAuthFailureTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process Min Channel Timeout
+ * during channel scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessAuthFailureTimeout(tpAniSirGlobal pMac)
+{
+ //fetch the sessionEntry based on the sessionId
+ tpPESession psessionEntry;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAuthFailureTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ switch (psessionEntry->limMlmState)
+ {
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+ /**
+ * Requesting STA did not receive next auth frame
+ * before Auth Failure timeout.
+ * Issue MLM auth confirm with timeout reason code
+ */
+
+
+ limRestoreFromAuthState(pMac,eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+ break;
+
+ default:
+ /**
+ * Auth failure timer should not have timed out
+ * in states other than wt_auth_frame2/4
+ * Log error.
+ */
+ PELOGE(limLog(pMac, LOGE, FL("received unexpected AUTH failure timeout in state %X\n"), psessionEntry->limMlmState);)
+ limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
+
+ break;
+ }
+} /*** limProcessAuthFailureTimeout() ***/
+
+
+
+/**
+ * limProcessAuthRspTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process Min Channel Timeout
+ * during channel scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessAuthRspTimeout(tpAniSirGlobal pMac, tANI_U32 authIndex)
+{
+ struct tLimPreAuthNode *pAuthNode;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+ pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, authIndex);
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pAuthNode->peerMacAddr, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("session does not exist for given BSSID \n"));
+ return;
+ }
+
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE ||
+ psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ {
+ // Check if there exists a context for the STA
+
+ if (pAuthNode == NULL)
+ {
+ /**
+ * Authentication response timer timedout for an STA
+ * that does not have context at AP/STA in IBSS mode.
+ */
+
+ // Log error
+ PELOGE(limLog(pMac, LOGE, FL("received unexpected message\n"));)
+ }
+ else
+ {
+ if (pAuthNode->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE)
+ {
+ /**
+ * Authentication response timer timedout
+ * in unexpected state. Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected AUTH rsp timeout for MAC address "));
+ limPrintMacAddr(pMac, pAuthNode->peerMacAddr, LOGE);)
+ }
+ else
+ {
+ // Authentication response timer
+ // timedout for an STA.
+ pAuthNode->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
+ pAuthNode->fTimerStarted = 0;
+ PELOG1( limLog(pMac, LOG1,
+ FL("AUTH rsp timedout for MAC address "));
+ limPrintMacAddr(pMac, pAuthNode->peerMacAddr, LOG1);)
+
+ // Change timer to reactivate it in future
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->authNodeIdx);
+
+ limDeletePreAuthNode(pMac, pAuthNode->peerMacAddr);
+ }
+ }
+ }
+} /*** limProcessAuthRspTimeout() ***/
+
+
+/**
+ * limProcessAssocFailureTimeout()
+ *
+ *FUNCTION:
+ * This function is called to process Min Channel Timeout
+ * during channel scan.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limProcessAssocFailureTimeout(tpAniSirGlobal pMac, tANI_U32 MsgType)
+{
+
+ tLimMlmAssocCnf mlmAssocCnf;
+ tpPESession psessionEntry;
+
+ //to fetch the lim/mlm state based on the sessionId, use the below sessionEntry
+ tANI_U8 sessionId;
+
+ if(MsgType == LIM_ASSOC)
+ {
+ sessionId = pMac->lim.limTimers.gLimAssocFailureTimer.sessionId;
+ }
+ else
+ {
+ sessionId = pMac->lim.limTimers.gLimReassocFailureTimer.sessionId;
+ }
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ /**
+ * Expected Re/Association Response frame
+ * not received within Re/Association Failure Timeout.
+ */
+
+
+
+
+ /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */
+ /* notify TL that association is failed so that TL can flush the cached frame */
+ WLANTL_AssocFailed (psessionEntry->staId);
+
+ // Log error
+ PELOG1(limLog(pMac, LOG1,
+ FL("Re/Association Response not received before timeout \n"));)
+
+ if (( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )||
+ ( (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
+ (psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&
+ (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE)))
+ {
+ /**
+ * Re/Assoc failure timer should not have timedout on AP
+ * or in a state other than wt_re/assoc_response.
+ */
+
+ // Log error
+ limLog(pMac, LOGW,
+ FL("received unexpected REASSOC failure timeout in state %X for role %d\n"),
+ psessionEntry->limMlmState, psessionEntry->limSystemRole);
+ limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState);
+ }
+ else
+ {
+
+ if ((MsgType == LIM_ASSOC) ||
+ ((MsgType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("(Re)Assoc Failure Timeout occurred.\n"));)
+
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, psessionEntry->limMlmState));
+
+ //Set the RXP mode to IDLE, so it starts filtering the frames.
+ if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+
+ // 'Change' timer for future activations
+ limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER);
+
+ // Free up buffer allocated for JoinReq held by
+ // MLM state machine
+ if (psessionEntry->pLimMlmJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT)
+ //To remove the preauth node in case of fail to associate
+ if (limSearchPreAuthList(pMac, psessionEntry->bssId))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" delete pre auth node for %02X-%02X-%02X-%02X-%02X-%02X\n"),
+ psessionEntry->bssId[0], psessionEntry->bssId[1], psessionEntry->bssId[2],
+ psessionEntry->bssId[3], psessionEntry->bssId[4], psessionEntry->bssId[5]);)
+ limDeletePreAuthNode(pMac, psessionEntry->bssId);
+ }
+#endif
+
+ mlmAssocCnf.resultCode =
+ eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
+ mlmAssocCnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ /* Update PE session Id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+ if (MsgType == LIM_ASSOC)
+ limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
+ else
+ {
+ /* Will come here only in case of 11r, CCx FT when reassoc rsp
+ is not received and we receive a reassoc - timesout */
+ mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf);
+ }
+ }
+ else
+ {
+ /**
+ * Restore pre-reassoc req state.
+ * Set BSSID to currently associated AP address.
+ */
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ limRestorePreReassocState(pMac,
+ eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry);
+ }
+ }
+} /*** limProcessAssocFailureTimeout() ***/
+
+
+
+/**
+ * limCompleteMlmScan()
+ *
+ *FUNCTION:
+ * This function is called to send MLM_SCAN_CNF message
+ * to SME state machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param retCode Result code to be sent
+ * @return None
+ */
+
+void
+limCompleteMlmScan(tpAniSirGlobal pMac, tSirResultCodes retCode)
+{
+ tLimMlmScanCnf mlmScanCnf;
+
+ /// Restore previous MLM state
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ limRestorePreScanState(pMac);
+
+ // Free up pMac->lim.gLimMlmScanReq
+ if( NULL != pMac->lim.gpLimMlmScanReq )
+ {
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmScanReq);
+ pMac->lim.gpLimMlmScanReq = NULL;
+ }
+
+ mlmScanCnf.resultCode = retCode;
+ mlmScanCnf.scanResultLength = pMac->lim.gLimMlmScanResultLength;
+
+ limPostSmeMessage(pMac, LIM_MLM_SCAN_CNF, (tANI_U32 *) &mlmScanCnf);
+
+} /*** limCompleteMlmScan() ***/
+
+/**
+ * \brief Setup an A-MPDU/BA session
+ *
+ * \sa limProcessMlmAddBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pMsgBuf The MLME ADDBA Req message buffer
+ *
+ * \return none
+ */
+void limProcessMlmAddBAReq( tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf )
+{
+tSirRetStatus status = eSIR_SUCCESS;
+tpLimMlmAddBAReq pMlmAddBAReq;
+tpLimMlmAddBACnf pMlmAddBACnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmAddBAReq = (tpLimMlmAddBAReq) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBAReq->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+
+ // Send ADDBA Req over the air
+ status = limSendAddBAReq( pMac, pMlmAddBAReq,psessionEntry);
+
+ //
+ // Respond immediately to LIM, only if MLME has not been
+ // successfully able to send WDA_ADDBA_REQ to HAL.
+ // Else, LIM_MLM_ADDBA_CNF will be sent after receiving
+ // ADDBA Rsp from peer entity
+ //
+ if( eSIR_SUCCESS != status )
+ {
+ // Allocate for LIM_MLM_ADDBA_CNF
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmAddBACnf,
+ sizeof( tLimMlmAddBACnf )))
+ {
+ limLog( pMac, LOGP,
+ FL("palAllocateMemory failed with error code %d\n"));
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
+ return;
+ }
+ else
+ {
+ palZeroMemory( pMac->hHdd, (void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ));
+ palCopyMemory( pMac->hHdd,
+ (void *) pMlmAddBACnf->peerMacAddr,
+ (void *) pMlmAddBAReq->peerMacAddr,
+ sizeof( tSirMacAddr ));
+
+ pMlmAddBACnf->baDialogToken = pMlmAddBAReq->baDialogToken;
+ pMlmAddBACnf->baTID = pMlmAddBAReq->baTID;
+ pMlmAddBACnf->baPolicy = pMlmAddBAReq->baPolicy;
+ pMlmAddBACnf->baBufferSize = pMlmAddBAReq->baBufferSize;
+ pMlmAddBACnf->baTimeout = pMlmAddBAReq->baTimeout;
+ pMlmAddBACnf->sessionId = pMlmAddBAReq->sessionId;
+
+ // Update the result code
+ pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ limPostSmeMessage( pMac,
+ LIM_MLM_ADDBA_CNF,
+ (tANI_U32 *) pMlmAddBACnf );
+ }
+
+ // Restore MLME state
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ }
+
+ // Free the buffer allocated for tLimMlmAddBAReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
+
+}
+
+/**
+ * \brief Send an ADDBA Rsp to peer STA in response
+ * to an ADDBA Req received earlier
+ *
+ * \sa limProcessMlmAddBARsp
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pMsgBuf The MLME ADDBA Rsp message buffer
+ *
+ * \return none
+ */
+void limProcessMlmAddBARsp( tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf )
+{
+tpLimMlmAddBARsp pMlmAddBARsp;
+ tANI_U16 aid;
+ tpDphHashNode pSta;
+ tpPESession psessionEntry;
+
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ pMlmAddBARsp = (tpLimMlmAddBARsp) pMsgBuf;
+
+ if(( psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBARsp->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("session does not exist for given session ID\n"));)
+ return;
+ }
+
+
+ // Send ADDBA Rsp over the air
+ if( eSIR_SUCCESS != limSendAddBARsp( pMac,pMlmAddBARsp,psessionEntry))
+ {
+ limLog( pMac, LOGE,
+ FL("Failed to send ADDBA Rsp to peer \n"));
+ limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGE );
+ /* Clean the BA context maintained by HAL and TL on failure */
+ pSta = dphLookupHashEntry( pMac, pMlmAddBARsp->peerMacAddr, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if( NULL != pSta )
+ {
+ limPostMsgDelBAInd( pMac, pSta, pMlmAddBARsp->baTID, eBA_RECIPIENT,
+ psessionEntry);
+ }
+ }
+
+ // Time to post a WDA_DELBA_IND to HAL in order
+ // to cleanup the HAL and SoftMAC entries
+
+
+ // Free the buffer allocated for tLimMlmAddBARsp
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
+
+}
+
+/**
+ * \brief Setup an A-MPDU/BA session
+ *
+ * \sa limProcessMlmDelBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pMsgBuf The MLME DELBA Req message buffer
+ *
+ * \return none
+ */
+void limProcessMlmDelBAReq( tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf )
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpLimMlmDelBAReq pMlmDelBAReq;
+ tpLimMlmDelBACnf pMlmDelBACnf;
+ tpPESession psessionEntry;
+
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+
+ // TODO - Need to validate MLME state
+ pMlmDelBAReq = (tpLimMlmDelBAReq) pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDelBAReq->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));)
+ return;
+ }
+
+ // Send DELBA Ind over the air
+ if( eSIR_SUCCESS !=
+ (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry)))
+ status = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ else
+ {
+ tANI_U16 aid;
+ tpDphHashNode pSta;
+
+ // Time to post a WDA_DELBA_IND to HAL in order
+ // to cleanup the HAL and SoftMAC entries
+ pSta = dphLookupHashEntry( pMac, pMlmDelBAReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable);
+ if( NULL != pSta )
+ {
+ status = limPostMsgDelBAInd( pMac,
+ pSta,
+ pMlmDelBAReq->baTID,
+ pMlmDelBAReq->baDirection,psessionEntry);
+
+ }
+ }
+
+ //
+ // Respond immediately to SME with DELBA CNF using
+ // LIM_MLM_DELBA_CNF with appropriate status
+ //
+
+ // Allocate for LIM_MLM_DELBA_CNF
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmDelBACnf,
+ sizeof( tLimMlmDelBACnf )))
+ {
+ limLog( pMac, LOGP, FL("palAllocateMemory failed\n"));
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
+ return;
+ }
+ else
+ {
+ palZeroMemory( pMac->hHdd, (void *) pMlmDelBACnf, sizeof( tLimMlmDelBACnf ));
+
+ palCopyMemory( pMac->hHdd,
+ (void *) pMlmDelBACnf,
+ (void *) pMlmDelBAReq,
+ sizeof( tLimMlmDelBAReq ));
+
+ // Update DELBA result code
+ pMlmDelBACnf->delBAReasonCode = pMlmDelBAReq->delBAReasonCode;
+
+ /* Update PE session Id*/
+ pMlmDelBACnf->sessionId = pMlmDelBAReq->sessionId;
+
+ limPostSmeMessage( pMac,
+ LIM_MLM_DELBA_CNF,
+ (tANI_U32 *) pMlmDelBACnf );
+ }
+
+ // Free the buffer allocated for tLimMlmDelBAReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMsgBuf );
+
+}
+
+/**
+ * @function : limSMPowerSaveStateInd( )
+ *
+ * @brief : This function is called upon receiving the PMC Indication to update the STA's MimoPs State.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param limMsg - Lim Message structure object with the MimoPSparam in body
+ * @return None
+ */
+
+tSirRetStatus
+limSMPowerSaveStateInd(tpAniSirGlobal pMac, tSirMacHTMIMOPowerSaveState state)
+{
+#if 0
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+#if 0
+ tANI_U32 cfgVal1;
+ tANI_U16 cfgVal2;
+ tSirMacHTCapabilityInfo *pHTCapabilityInfo;
+ tpDphHashNode pSta = NULL;
+
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ /** Verify the Mode of operation */
+ if (pMac->lim.gLimSystemRole != eSYSTEM_STA_ROLE) {
+ PELOGE(limLog(pMac, LOGE, FL("Got PMC indication when System not in the STA Role\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if ((pMac->lim.gHTMIMOPSState == state) || (state == eSIR_HT_MIMO_PS_NA )) {
+ PELOGE(limLog(pMac, LOGE, FL("Got Indication when already in the same mode or State passed is NA:%d \n"), state);)
+ return eSIR_FAILURE;
+ }
+
+ if (!pMac->lim.htCapability){
+ PELOGW(limLog(pMac, LOGW, FL(" Not in 11n or HT capable mode\n"));)
+ return eSIR_FAILURE;
+ }
+
+ /** Update the CFG about the default MimoPS State */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgVal1) != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("could not retrieve HT Cap CFG \n"));
+ return eSIR_FAILURE;
+ }
+
+ cfgVal2 = (tANI_U16)cfgVal1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &cfgVal2;
+ pHTCapabilityInfo->mimoPowerSave = state;
+
+ if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("could not update HT Cap Info CFG\n"));
+ return eSIR_FAILURE;
+ }
+
+ PELOG2(limLog(pMac, LOG2, FL(" The HT Capability for Mimo Pwr is updated to State: %u \n"),state);)
+ if (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) {
+ PELOG2(limLog(pMac, LOG2,FL(" The STA is not in the Connected/Link Est Sme_State: %d \n"), pMac->lim.gLimSmeState);)
+ /** Update in the LIM the MIMO PS state of the SELF */
+ pMac->lim.gHTMIMOPSState = state;
+ return eSIR_SUCCESS;
+ }
+
+ pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (!pSta->mlmStaContext.htCapability) {
+ limLog( pMac, LOGE,FL( "limSendSMPowerState: Peer is not HT Capable \n" ));
+ return eSIR_FAILURE;
+ }
+
+ if (isEnteringMimoPS(pMac->lim.gHTMIMOPSState, state)) {
+ tSirMacAddr macAddr;
+ /** Obtain the AP's Mac Address */
+ palCopyMemory(pMac ->hHdd, (tANI_U8 *)macAddr, psessionEntry->bssId, sizeof(tSirMacAddr));
+ /** Send Action Frame with the corresponding mode */
+ retStatus = limSendSMPowerStateFrame(pMac, macAddr, state);
+ if (retStatus != eSIR_SUCCESS) {
+ PELOGE(limLog(pMac, LOGE, "Update SM POWER: Sending Action Frame has failed\n");)
+ return retStatus;
+ }
+ }
+
+ /** Update MlmState about the SetMimoPS State */
+ pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState;
+ pMac->lim.gLimMlmState = eLIM_MLM_WT_SET_MIMOPS_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /** Update the HAL and s/w mac about the mode to be set */
+ retStatus = limPostSMStateUpdate( pMac,psessionEntry->staId, state);
+
+ PELOG2(limLog(pMac, LOG2, " Updated the New SMPS State");)
+ /** Update in the LIM the MIMO PS state of the SELF */
+ pMac->lim.gHTMIMOPSState = state;
+#endif
+ return retStatus;
+#endif
+return eSIR_SUCCESS;
+}
+
+void
+limSetChannel(tpAniSirGlobal pMac, tANI_U32 titanHtcap, tANI_U8 channel, tPowerdBm maxTxPower, tANI_U8 peSessionId)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ tANI_U32 localPwrConstraint;
+#endif
+
+ // Setup the CB State appropriately, prior to
+ // issuing a dphChannelChange(). This is done
+ // so that if CB is enabled, the CB Secondary
+ // Channel is setup correctly
+
+ /* if local CB admin state is off or join req CB admin state is off, don't bother with CB channel setup */
+ PELOG1(limLog(pMac, LOG1, FL("Before : gCbState = 0x%x, gCbmode = %x\n"), pMac->lim.gCbState, pMac->lim.gCbMode);)
+ if(GET_CB_ADMIN_STATE(pMac->lim.gCbState) &&
+ SME_GET_CB_ADMIN_STATE(titanHtcap)) {
+ PELOG1(limLog(pMac, LOG1, FL("station doing channel bonding\n"));)
+ setupCBState( pMac, (tAniCBSecondaryMode)SME_GET_CB_OPER_STATE(titanHtcap));
+ }else {
+ PELOG1(limLog(pMac, LOG1, FL("station not doing channel bonding\n"));)
+ setupCBState(pMac, eANI_CB_SECONDARY_NONE);
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("After :gCbState = 0x%x, gCbmode = %x\n"), pMac->lim.gCbState, pMac->lim.gCbMode);)
+
+ #if 0
+ if (wlan_cfgSetInt(pMac, WNI_CFG_CURRENT_CHANNEL, channel) != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("could not set CURRENT_CHANNEL at CFG\n"));
+ return;
+ }
+ #endif // TO SUPPORT BT-AMP
+
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams( pMac, channel, limGetPhyCBState( pMac ), maxTxPower, peSessionId);
+#else
+ if (wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("could not read WNI_CFG_LOCAL_POWER_CONSTRAINT from CFG\n"));
+ return;
+ }
+ // Send WDA_CHNL_SWITCH_IND to HAL
+ limSendSwitchChnlParams( pMac, channel, limGetPhyCBState( pMac ), (tPowerdBm)localPwrConstraint, peSessionId);
+#endif
+
+ }
+
+
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
new file mode 100644
index 0000000..70d3b57
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -0,0 +1,4991 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessMlmRspMessages.cc contains the code
+ * for processing response messages from MLM state machine.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "wniApi.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+#include "sirApi.h"
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limTimerUtils.h"
+#include "limSendMessages.h"
+#include "limAdmitControl.h"
+#include "limSendMessages.h"
+#include "limIbssPeerMgmt.h"
+#include "limSession.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include <limFT.h>
+#endif
+
+static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession);
+void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmJoinCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmAuthCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmStartCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmAuthInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmAssocInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmAssocCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmReassocCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmReassocInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmSetKeysCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmDisassocInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmDisassocCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmDeauthInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmDeauthCnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmPurgeStaInd(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmAddBACnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmDelBACnf(tpAniSirGlobal, tANI_U32 *);
+void limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf);
+static void limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry);
+void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *);
+static void
+limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry);
+/**
+ * limProcessMlmRspMessages()
+ *
+ *FUNCTION:
+ * This function is called to processes various MLM response (CNF/IND
+ * messages from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmRspMessages(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ switch (msgType)
+ {
+ case LIM_MLM_SCAN_CNF:
+ limProcessMlmScanCnf(pMac, pMsgBuf);
+ break;
+
+
+ case LIM_MLM_AUTH_CNF:
+ limProcessMlmAuthCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_AUTH_IND:
+ limProcessMlmAuthInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_ASSOC_CNF:
+ limProcessMlmAssocCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_START_CNF:
+ limProcessMlmStartCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_JOIN_CNF:
+ limProcessMlmJoinCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_ASSOC_IND:
+ limProcessMlmAssocInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_REASSOC_CNF:
+ limProcessMlmReassocCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_REASSOC_IND:
+ limProcessMlmReassocInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DISASSOC_CNF:
+ limProcessMlmDisassocCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DISASSOC_IND:
+ limProcessMlmDisassocInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_PURGE_STA_IND:
+ limProcessMlmPurgeStaInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DEAUTH_CNF:
+ limProcessMlmDeauthCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DEAUTH_IND:
+ limProcessMlmDeauthInd(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_SETKEYS_CNF:
+ limProcessMlmSetKeysCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_REMOVEKEY_CNF:
+ limProcessMlmRemoveKeyCnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_TSPEC_CNF:
+ break;
+ case LIM_MLM_ADDBA_CNF:
+ limProcessMlmAddBACnf( pMac, pMsgBuf );
+ break;
+ case LIM_MLM_DELBA_CNF:
+ limProcessMlmDelBACnf( pMac, pMsgBuf );
+ break;
+ default:
+ break;
+ } // switch (msgType)
+ return;
+} /*** end limProcessMlmRspMessages() ***/
+
+/**
+ * limProcessMlmScanCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_SCAN_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmScanCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ switch(pMac->lim.gLimSmeState)
+ {
+ case eLIM_SME_WT_SCAN_STATE:
+ //case eLIM_SME_LINK_EST_WT_SCAN_STATE: //TO SUPPORT BT-AMP
+ //case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: //TO SUPPORT BT-AMP
+ pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ break;
+ default:
+ /**
+ * Should not have received scan confirm
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_SCAN_CNF in state %X\n"),
+ pMac->lim.gLimSmeState);)
+ return;
+ }
+
+ /// Process received scan confirm
+ /// Increment length of cached scan results
+ pMac->lim.gLimSmeScanResultLength +=
+ ((tLimMlmScanCnf *) pMsgBuf)->scanResultLength;
+ if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults)
+ {
+ tANI_U16 scanRspLen = 0;
+ /// Need to send response to Host
+ pMac->lim.gLimRspReqd = false;
+ if ((((tLimMlmScanCnf *) pMsgBuf)->resultCode ==
+ eSIR_SME_SUCCESS) ||
+ pMac->lim.gLimSmeScanResultLength)
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp) +
+ pMac->lim.gLimSmeScanResultLength -
+ sizeof(tSirBssDescription);
+ }
+ else
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp);
+ }
+ if(pMac->lim.gLimReportBackgroundScanResults)
+ {
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+ }
+ if (pMac->lim.gLimSmeScanResultLength == 0)
+ {
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId);
+ }
+ else
+ {
+ limSendSmeScanRsp(pMac, scanRspLen,
+ eSIR_SME_SUCCESS,pMac->lim.gSmeSessionId, pMac->lim.gTransactionId);
+ }
+ } // if (pMac->lim.gLimRspReqd)
+ //check to see whether we need to run bgScan timer
+ if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
+ {
+ if (tx_timer_activate(
+ &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ {
+ /// Could not activate background scan timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not activate background scan timer\n"));
+ pMac->lim.gLimBackgroundScanStarted = FALSE;
+ }
+ else
+ {
+ pMac->lim.gLimBackgroundScanStarted = TRUE;
+ }
+ }
+} /*** end limProcessMlmScanCnf() ***/
+
+
+/**
+ * limProcessMlmStartCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_START_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmStartCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpPESession psessionEntry = NULL;
+ tLimMlmStartCnf *pLimMlmStartCnf;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pLimMlmStartCnf = (tLimMlmStartCnf*)pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmStartCnf->sessionId))==NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId \n"));)
+ return;
+ }
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+
+ if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE)
+ {
+ /**
+ * Should not have received Start confirm from MLM
+ * in other states.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_START_CNF in state %X\n"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+ if (((tLimMlmStartCnf *) pMsgBuf)->resultCode ==
+ eSIR_SME_SUCCESS)
+ {
+
+ /**
+ * Update global SME state so that Beacon Generation
+ * module starts writing Beacon frames into TFP's
+ * Beacon file register.
+ */
+ psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ if(psessionEntry->bssType == eSIR_BTAMP_STA_MODE)
+ {
+ limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP STA SIDE***\n"));
+ }
+ else if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP AP SIDE***\n"));
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ else if(psessionEntry->bssType == eSIR_INFRA_AP_MODE)
+ {
+ limLog(pMac, LOG1, FL("*** Started BSS in INFRA AP SIDE***\n"));
+ }
+#endif
+ else
+ PELOG1(limLog(pMac, LOG1, FL("*** Started BSS ***\n"));)
+ }
+ else
+ {
+ /// Start BSS is a failure
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+ /// Send response to Host
+ limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP,
+ ((tLimMlmStartCnf *) pMsgBuf)->resultCode,psessionEntry,
+ smesessionId,smetransactionId);
+#ifdef WLAN_SOFTAP_FEATURE
+ if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS)
+ {
+ //Configure beacon and send beacons to HAL
+ limSendBeaconInd(pMac, psessionEntry);
+ }
+#endif
+}
+
+ /*** end limProcessMlmStartCnf() ***/
+
+/**
+ * limProcessMlmJoinCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_JOIN_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmJoinCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirResultCodes resultCode;
+ tLimMlmJoinCnf *pLimMlmJoinCnf;
+ tpPESession psessionEntry;
+ pLimMlmJoinCnf = (tLimMlmJoinCnf*)pMsgBuf;
+ if( (psessionEntry = peFindSessionBySessionId(pMac,pLimMlmJoinCnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Session does not exist for given sessionId\n"));)
+ return;
+ }
+
+ if (psessionEntry->limSmeState!= eLIM_SME_WT_JOIN_STATE)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_JOIN_CNF in state %X\n"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+
+ resultCode = ((tLimMlmJoinCnf *) pMsgBuf)->resultCode ;
+ /// Process Join confirm from MLM
+ if (resultCode == eSIR_SME_SUCCESS)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("*** Joined ESS ***\n"));)
+ //Setup hardware upfront
+ PELOGE(limLog(pMac, LOGE, FL("*** Starting to add BSS***\n"));) //remove me
+ //Done: 7-27-2009. JIM_FIX_ME sessionize the following function
+ if(limStaSendAddBssPreAssoc( pMac, false, psessionEntry) == eSIR_SUCCESS)
+ return;
+ else
+ resultCode = eSIR_SME_REFUSED;
+ }
+ {
+ /// Join failure
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, psessionEntry->limSmeState));
+ /// Send Join response to Host
+ limHandleSmeJoinResult(pMac, resultCode, ((tLimMlmJoinCnf *) pMsgBuf)->protStatusCode, psessionEntry );
+ }
+} /*** end limProcessMlmJoinCnf() ***/
+
+/**
+ * limProcessMlmAuthCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_AUTH_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmAuthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 caps;
+ tANI_U32 val;
+ tAniAuthType cfgAuthType, authMode;
+ tLimMlmAuthReq *pMlmAuthReq;
+ tLimMlmAssocReq *pMlmAssocReq;
+ tLimMlmAuthCnf *pMlmAuthCnf;
+ tpPESession psessionEntry;
+ tANI_U32 teleBcnEn = 0;
+// tANI_U8 sessionId;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmAuthCnf = (tLimMlmAuthCnf*)pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAuthCnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+
+ if (((psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE)) ||
+ (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
+ {
+ /**
+ * Should not have received AUTH confirm
+ * from MLM in other states or on AP.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_AUTH_CNF in state %X\n"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+ /// Process AUTH confirm from MLM
+ if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != eSIR_SME_SUCCESS)
+ {
+ if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE)
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE,
+ (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthType value from CFG.
+ * Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthType value\n"));
+ }
+ }
+ else
+ cfgAuthType = pMac->lim.gLimPreAuthType;
+
+ if ((cfgAuthType == eSIR_AUTO_SWITCH) &&
+ (((tLimMlmAuthCnf *) pMsgBuf)->authType == eSIR_OPEN_SYSTEM)
+ && (eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS == ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode))
+ {
+ /**
+ * When Open authentication fails with reason code "13" and
+ * authType set to 'auto switch', Try with Shared Authentication
+ */
+ authMode = eSIR_SHARED_KEY;
+ // Trigger MAC based Authentication
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmAuthReq, sizeof(tLimMlmAuthReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmAuthReq\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pMlmAuthReq, sizeof(tLimMlmAuthReq));
+ val = sizeof(tSirMacAddr);
+ if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE)
+ {
+ sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId);
+ }
+ else
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmAuthReq->peerMacAddr,
+ (tANI_U8 *) &pMac->lim.gLimPreAuthPeerAddr,
+ sizeof(tSirMacAddr));
+ pMlmAuthReq->authType = authMode;
+ /* Update PE session Id*/
+ pMlmAuthReq->sessionId = pMlmAuthCnf->sessionId;
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmAuthReq->authFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthFailureTimeout value from CFG.
+ * Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value\n"));
+ }
+ limPostMlmMessage(pMac,
+ LIM_MLM_AUTH_REQ,
+ (tANI_U32 *) pMlmAuthReq);
+ return;
+ }
+ else
+ {
+ // MAC based authentication failure
+ if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Auth Failure occurred.\n"));)
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState.\n"));)
+#if defined(ANI_AP_CLIENT_SDK)
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ {
+ tSirMacAddr nullMacAddr = {0, 0, 0, 0, 0, 0};
+ PELOGE(limLog(pMac, LOGE, FL("Setting current BSSID as NULL in cfg\n"));)
+ palCopyMemory(pMac->hHdd, pMac->lim.gLimBssid, nullMacAddr, sizeof(tSirMacAddr));
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, nullMacAddr, sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update BSSID on CFG"));
+ }
+ }
+#endif
+ /**
+ * Need to send Join response with
+ * auth failure to Host.
+ */
+ limHandleSmeJoinResult(pMac,
+ ((tLimMlmAuthCnf *) pMsgBuf)->resultCode, ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode,psessionEntry);
+ }
+ else
+ {
+ /**
+ * Pre-authentication failure.
+ * Send Pre-auth failure response to host
+ */
+ psessionEntry->limSmeState = psessionEntry->limPrevSmeState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limSendSmeAuthRsp(
+ pMac,
+ ((tLimMlmAuthCnf *) pMsgBuf)->resultCode,
+ ((tLimMlmAuthCnf *) pMsgBuf)->peerMacAddr,
+ ((tLimMlmAuthCnf *) pMsgBuf)->authType,
+ ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode,psessionEntry,psessionEntry->smeSessionId,psessionEntry->transactionId);
+ }
+ } // end if (cfgAuthType == eAUTO_SWITCH)
+ } // if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ...
+ else
+ {
+ if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE)
+ {
+ /**
+ * Successful MAC based authentication
+ * Trigger Association with BSS
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Authenticated with BSS ***\n"));)
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmAssocReq, sizeof(tLimMlmAssocReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmAssocReq\n"));
+ return;
+ }
+ val = sizeof(tSirMacAddr);
+ #if 0
+ if (cfgGetStr(pMac, WNI_CFG_BSSID,
+ pMlmAssocReq->peerMacAddr,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //SUPPORT BT-AMP
+ sirCopyMacAddr(pMlmAssocReq->peerMacAddr,psessionEntry->bssId);
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmAssocReq->assocFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AssocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AssocFailureTimeout value\n"));
+ }
+ if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Capabilities value\n"));
+ }
+ /*Clear spectrum management bit if AP doesn't support it*/
+ if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & LIM_SPECTRUM_MANAGEMENT_BIT_MASK))
+ {
+ /*AP doesn't support spectrum management clear spectrum management bit*/
+ caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
+ }
+
+ pMlmAssocReq->capabilityInfo = caps;
+ PELOG3(limLog(pMac, LOG3,
+ FL("Capabilities to be used in AssocReq=0x%X, privacy bit=%x\n"),
+ caps,
+ ((tpSirMacCapabilityInfo) &pMlmAssocReq->capabilityInfo)->privacy);)
+
+ /* If telescopic beaconing is enabled, set listen interval to
+ WNI_CFG_TELE_BCN_MAX_LI */
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
+ eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN\n"));
+
+ val = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ if(teleBcnEn)
+ {
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
+ eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve ListenInterval\n"));
+ }
+ }
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve ListenInterval\n"));
+ }
+ }
+
+ pMlmAssocReq->listenInterval = (tANI_U16)val;
+ /* Update PE session ID*/
+ pMlmAssocReq->sessionId = psessionEntry->peSessionId;
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limPostMlmMessage(pMac,
+ LIM_MLM_ASSOC_REQ,
+ (tANI_U32 *) pMlmAssocReq);
+ }
+ else
+ {
+ /**
+ * Successful Pre-authentication.
+ * Send Pre-auth response to host
+ */
+ psessionEntry->limSmeState = psessionEntry->limPrevSmeState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limSendSmeAuthRsp(
+ pMac,
+ ((tLimMlmAuthCnf *) pMsgBuf)->resultCode,
+ ((tLimMlmAuthCnf *) pMsgBuf)->peerMacAddr,
+ ((tLimMlmAuthCnf *) pMsgBuf)->authType,
+ ((tLimMlmAuthCnf *) pMsgBuf)->protStatusCode,psessionEntry,psessionEntry->smeSessionId,psessionEntry->transactionId);
+ }
+ } // end if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ...
+} /*** end limProcessMlmAuthCnf() ***/
+
+/**
+ * limProcessMlmAssocCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_ASSOC_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmAssocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpPESession psessionEntry;
+ tLimMlmAssocCnf *pLimMlmAssocCnf;
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+ pLimMlmAssocCnf = (tLimMlmAssocCnf*)pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmAssocCnf->sessionId)) == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Session does not exist for given sessionId\n"));)
+ return;
+ }
+ if (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE ||
+ psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry ->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+ {
+ /**
+ * Should not have received Assocication confirm
+ * from MLM in other states OR on AP.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_ASSOC_CNF in state %X\n"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+ if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != eSIR_SME_SUCCESS)
+ {
+ // Association failure
+ PELOG1(limLog(pMac, LOG1, FL("*** Association failure ***\n"));)
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+#if defined(ANI_AP_CLIENT_SDK)
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ {
+ tSirMacAddr nullMacAddr = {0, 0, 0, 0, 0, 0};
+ palCopyMemory(pMac->hHdd, pMac->lim.gLimBssid, nullMacAddr, sizeof(tSirMacAddr));
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, nullMacAddr, sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update BSSID on CFG"));
+ }
+ }
+#endif
+ /**
+ * Need to send Join response with
+ * Association failure to Host.
+ */
+ limHandleSmeJoinResult(pMac,
+ ((tLimMlmAssocCnf *) pMsgBuf)->resultCode,
+ ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry);
+ } // if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != ...
+ else
+ {
+ // Successful Association
+ PELOG1(limLog(pMac, LOG1, FL("*** Associated with BSS ***\n"));)
+ psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ /**
+ * Need to send Join response with
+ * Association success to Host.
+ */
+ limHandleSmeJoinResult(pMac,
+ ((tLimMlmAssocCnf *) pMsgBuf)->resultCode,
+ ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry);
+ } // end if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != ....
+} /*** end limProcessMlmAssocCnf() ***/
+
+/**
+ * limProcessMlmReassocCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_REASSOC_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmReassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpPESession psessionEntry;
+ tLimMlmReassocCnf *pLimMlmReassocCnf;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pLimMlmReassocCnf = (tLimMlmReassocCnf*) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmReassocCnf->sessionId))==NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("session Does not exist for given session Id\n"));)
+ return;
+ }
+ if ((psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) ||
+ (psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
+ {
+ /**
+ * Should not have received Reassocication confirm
+ * from MLM in other states OR on AP.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("Rcv unexpected MLM_REASSOC_CNF in role %d, sme state 0x%X\n"),
+ psessionEntry->limSystemRole, psessionEntry->limSmeState);)
+ return;
+ }
+ if (psessionEntry->pLimReAssocReq) {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimReAssocReq);
+ psessionEntry->pLimReAssocReq = NULL;
+ }
+
+ PELOGE(limLog(pMac, LOGE, FL("Rcv MLM_REASSOC_CNF with result code %d\n"), pLimMlmReassocCnf->resultCode);)
+ if (pLimMlmReassocCnf->resultCode == eSIR_SME_SUCCESS) {
+ // Successful Reassociation
+ PELOG1(limLog(pMac, LOG1, FL("*** Reassociated with new BSS ***\n"));)
+
+ psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ /**
+ * Need to send Reassoc response with
+ * Reassociation success to Host.
+ */
+ limSendSmeJoinReassocRsp(
+ pMac, eWNI_SME_REASSOC_RSP,
+ pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry,
+ psessionEntry->smeSessionId,psessionEntry->transactionId);
+ }else if (pLimMlmReassocCnf->resultCode == eSIR_SME_REASSOC_REFUSED) {
+ /** Reassociation failure With the New AP
+ * but we still have the link with the Older AP
+ */
+ psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ /**
+ * Need to send Reassoc response with
+ * Association failure to Host.
+ */
+ limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP,
+ pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry,
+ psessionEntry->smeSessionId,psessionEntry->transactionId);
+ }else {
+ // Reassociation failure
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ /**
+ * Need to send Reassoc response with
+ * Association failure to Host.
+ */
+ limSendSmeJoinReassocRsp(
+ pMac, eWNI_SME_REASSOC_RSP,
+ pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry,
+ psessionEntry->smeSessionId,psessionEntry->transactionId);
+ }
+} /*** end limProcessMlmReassocCnf() ***/
+
+/**
+ * limProcessMlmReassocInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_REASSOC_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmReassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U32 len;
+ tSirMsgQ msgQ;
+ tSirSmeReassocInd *pSirSmeReassocInd;
+ tpDphHashNode pStaDs=0;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ if((psessionEntry = peFindSessionByBssid(pMac,((tpLimMlmReassocInd)pMsgBuf)->peerMacAddr, &sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));)
+ return;
+ }
+ /// Inform Host of STA reassociation
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ len = sizeof(tSirSmeReassocInd) -
+ sizeof(tSirNeighborBssInfo) +
+ (((tpLimMlmReassocInd) pMsgBuf)->numBss *
+ sizeof(tSirNeighborBssInfo)) -
+ SIR_MAC_MAX_SSID_LENGTH +
+ ((tpLimMlmReassocInd) pMsgBuf)->ssId.length;
+#else
+ len = sizeof(tSirSmeReassocInd);
+#endif
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeReassocInd, len))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_REASSOC_IND\n"));
+ return;
+
+ }
+ sirStoreU16N((tANI_U8 *) &pSirSmeReassocInd->messageType,
+ eWNI_SME_REASSOC_IND);
+ limReassocIndSerDes(pMac, (tpLimMlmReassocInd) pMsgBuf,
+ (tANI_U8 *) &(pSirSmeReassocInd->length), psessionEntry);
+
+ // Required for indicating the frames to upper layer
+ pSirSmeReassocInd->assocReqLength = ((tpLimMlmReassocInd) pMsgBuf)->assocReqLength;
+ pSirSmeReassocInd->assocReqPtr = ((tpLimMlmReassocInd) pMsgBuf)->assocReqPtr;
+ pSirSmeReassocInd->beaconPtr = psessionEntry->beacon;
+ pSirSmeReassocInd->beaconLength = psessionEntry->bcnLen;
+
+ msgQ.type = eWNI_SME_REASSOC_IND;
+ msgQ.bodyptr = pSirSmeReassocInd;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_IND_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ pStaDs = dphGetHashEntry(pMac, ((tpLimMlmReassocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable);
+ if (! pStaDs)
+ {
+ limLog( pMac, LOGP, FL("MLM ReAssocInd: Station context no longer valid (aid %d)\n"),
+ ((tpLimMlmReassocInd) pMsgBuf)->aid);
+ palFreeMemory(pMac->hHdd, pSirSmeReassocInd);
+ return;
+ }
+
+ limSysProcessMmhMsgApi(pMac, &msgQ, ePROT);
+ PELOG1(limLog(pMac, LOG1,
+ FL("Create CNF_WAIT_TIMER after received LIM_MLM_REASSOC_IND\n"));)
+ /*
+ ** turn on a timer to detect the loss of REASSOC CNF
+ **/
+ limActivateCnfTimer(pMac,
+ (tANI_U16) ((tpLimMlmReassocInd) pMsgBuf)->aid, psessionEntry);
+} /*** end limProcessMlmReassocInd() ***/
+
+/**
+ * limProcessMlmAuthInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_AUTH_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmAuthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ msgQ;
+ tSirSmeAuthInd *pSirSmeAuthInd;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeAuthInd, sizeof(tSirSmeAuthInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_AUTH_IND\n"));
+ }
+ limCopyU16((tANI_U8 *) &pSirSmeAuthInd->messageType, eWNI_SME_AUTH_IND);
+ limAuthIndSerDes(pMac, (tpLimMlmAuthInd) pMsgBuf,
+ (tANI_U8 *) &(pSirSmeAuthInd->length));
+ msgQ.type = eWNI_SME_AUTH_IND;
+ msgQ.bodyptr = pSirSmeAuthInd;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_AUTH_IND_EVENT, NULL, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ limSysProcessMmhMsgApi(pMac, &msgQ, ePROT);
+} /*** end limProcessMlmAuthInd() ***/
+
+
+
+
+void
+limFillAssocIndParams(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd,
+ tSirSmeAssocInd *pSirSmeAssocInd,
+ tpPESession psessionEntry)
+{
+ pSirSmeAssocInd->length = sizeof(tSirSmeAssocInd);
+ pSirSmeAssocInd->sessionId = psessionEntry->smeSessionId;
+
+ // Required for indicating the frames to upper layer
+ pSirSmeAssocInd->assocReqLength = pAssocInd->assocReqLength;
+ pSirSmeAssocInd->assocReqPtr = pAssocInd->assocReqPtr;
+
+ pSirSmeAssocInd->beaconPtr = psessionEntry->beacon;
+ pSirSmeAssocInd->beaconLength = psessionEntry->bcnLen;
+
+ // Fill in peerMacAddr
+ palCopyMemory( pMac->hHdd, pSirSmeAssocInd->peerMacAddr, pAssocInd->peerMacAddr, sizeof(tSirMacAddr));
+ // Fill in aid
+ pSirSmeAssocInd->aid = pAssocInd->aid;
+ // Fill in bssId
+ palCopyMemory( pMac->hHdd, pSirSmeAssocInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+ // Fill in staId
+ //pSirSmeAssocInd->staId = psessionEntry->staId;
+ // Fill in authType
+ pSirSmeAssocInd->authType = pAssocInd->authType;
+ // Fill in ssId
+ palCopyMemory( pMac->hHdd, (tANI_U8*)&pSirSmeAssocInd->ssId,
+ (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1);
+ pSirSmeAssocInd->rsnIE.length = pAssocInd->rsnIE.length;
+ palCopyMemory( pMac->hHdd, (tANI_U8*) &pSirSmeAssocInd->rsnIE.rsnIEdata,
+ (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata),
+ pAssocInd->rsnIE.length);
+
+ pSirSmeAssocInd->addIE.length = pAssocInd->addIE.length;
+ palCopyMemory( pMac->hHdd, (tANI_U8*) &pSirSmeAssocInd->addIE.addIEdata,
+ (tANI_U8 *) &(pAssocInd->addIE.addIEdata),
+ pAssocInd->addIE.length);
+
+ // Copy the new TITAN capabilities
+ pSirSmeAssocInd->titanHtCaps = pAssocInd->titanHtCaps;
+ pSirSmeAssocInd->spectrumMgtIndicator = pAssocInd->spectrumMgtIndicator;
+ if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE)
+ {
+ pSirSmeAssocInd->powerCap.minTxPower = pAssocInd->powerCap.minTxPower;
+ pSirSmeAssocInd->powerCap.maxTxPower = pAssocInd->powerCap.maxTxPower;
+ pSirSmeAssocInd->supportedChannels.numChnl = pAssocInd->supportedChannels.numChnl;
+ palCopyMemory( pMac->hHdd, (tANI_U8*) &pSirSmeAssocInd->supportedChannels.channelList,
+ (tANI_U8 *) &(pAssocInd->supportedChannels.channelList),
+ pAssocInd->supportedChannels.numChnl);
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ // Fill in WmmInfo
+ pSirSmeAssocInd->wmmEnabledSta = pAssocInd->WmmStaInfoPresent;
+#endif
+} /*** end limAssocIndSerDes() ***/
+
+
+
+/**
+ * limProcessMlmAssocInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_ASSOC_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmAssocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U32 len;
+ tSirMsgQ msgQ;
+ tSirSmeAssocInd *pSirSmeAssocInd;
+ tpDphHashNode pStaDs=0;
+ tpPESession psessionEntry;
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ if((psessionEntry = peFindSessionBySessionId(pMac,((tpLimMlmAssocInd) pMsgBuf)->sessionId))== NULL)
+ {
+ limLog( pMac, LOGE, FL( "Session Does not exist for given sessionId\n" ));
+ return;
+ }
+ /// Inform Host of STA association
+#if defined (ANI_PRODUCT_TYPE_AP)
+ len = sizeof(tSirSmeAssocInd) -
+ sizeof(tSirNeighborBssInfo) +
+ (((tpLimMlmAssocInd) pMsgBuf)->numBss *
+ sizeof(tSirNeighborBssInfo)) -
+ SIR_MAC_MAX_SSID_LENGTH +
+ ((tpLimMlmAssocInd) pMsgBuf)->ssId.length;
+#else
+ len = sizeof(tSirSmeAssocInd);
+#endif
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeAssocInd, len))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_ASSOC_IND\n"));
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP)
+ sirStoreU16N((tANI_U8 *) &pSirSmeAssocInd->messageType,
+ eWNI_SME_ASSOC_IND);
+ limAssocIndSerDes(pMac, (tpLimMlmAssocInd) pMsgBuf,
+ (tANI_U8 *) &(pSirSmeAssocInd->length), psessionEntry);
+#else
+ pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
+ limFillAssocIndParams(pMac, (tpLimMlmAssocInd) pMsgBuf, pSirSmeAssocInd, psessionEntry);
+#endif
+ msgQ.type = eWNI_SME_ASSOC_IND;
+ msgQ.bodyptr = pSirSmeAssocInd;
+ msgQ.bodyval = 0;
+ pStaDs = dphGetHashEntry(pMac,
+ ((tpLimMlmAssocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable);
+ if (! pStaDs)
+ { // good time to panic...
+ limLog(pMac, LOGE, FL("MLM AssocInd: Station context no longer valid (aid %d)\n"),
+ ((tpLimMlmAssocInd) pMsgBuf)->aid);
+ palFreeMemory(pMac->hHdd, pSirSmeAssocInd);
+
+ return;
+ }
+ pSirSmeAssocInd->staId = pStaDs->staIndex;
+#ifdef WLAN_SOFTAP_FEATURE
+ pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType;
+#endif
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ limSysProcessMmhMsgApi(pMac, &msgQ, ePROT);
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND\n"));)
+ /*
+ ** turn on a timer to detect the loss of ASSOC CNF
+ **/
+ limActivateCnfTimer(pMac, (tANI_U16) ((tpLimMlmAssocInd) pMsgBuf)->aid, psessionEntry);
+
+// Enable this Compile flag to test the BT-AMP -AP assoc sequence
+#ifdef TEST_BTAMP_AP
+//tANI_U32 *pMsgBuf;
+{
+ tpSirSmeAssocCnf pSmeAssoccnf;
+ if(!palAllocateMemory(pMac->hHdd,(void **)&pSmeAssoccnf,sizeof(tSirSmeAssocCnf)))
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed for pSmeAssoccnf \n"));)
+ pSmeAssoccnf->messageType = eWNI_SME_ASSOC_CNF;
+ pSmeAssoccnf->length = sizeof(tSirSmeAssocCnf);
+ palCopyMemory( pMac->hHdd,pSmeAssoccnf->peerMacAddr,((tpLimMlmAssocInd)pMsgBuf)->peerMacAddr,6);
+ pSmeAssoccnf->statusCode = eSIR_SME_SUCCESS;
+ pSmeAssoccnf->aid = ((tpLimMlmAssocInd)pMsgBuf)->aid;
+ palCopyMemory( pMac->hHdd, pSmeAssoccnf->alternateBssId,pSmeAssoccnf->peerMacAddr,sizeof(tSirMacAddr));
+ pSmeAssoccnf->alternateChannelId = 6;
+ palCopyMemory( pMac->hHdd,pSmeAssoccnf->bssId,psessionEntry->selfMacAddr,6);
+ pMsgBuf = (tANI_U32)pSmeAssoccnf;
+ __limProcessSmeAssocCnfNew(pMac, eWNI_SME_ASSOC_CNF, pMsgBuf);
+ palFreeMemory(pMac->hHdd,pSmeAssoccnf);
+}
+#endif
+
+
+} /*** end limProcessMlmAssocInd() ***/
+
+
+
+
+/**
+ * limProcessMlmDisassocInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_DISASSOC_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmDisassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tLimMlmDisassocInd *pMlmDisassocInd;
+ tpPESession psessionEntry;
+ pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf;
+ if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocInd->sessionId) )== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ break;
+ default: // eLIM_AP_ROLE //eLIM_BT_AMP_AP_ROLE
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Peer staId=%d Disassociated ***\n"),
+ pMlmDisassocInd->aid);)
+ // Send SME_DISASOC_IND after Polaris cleanup
+ // (after receiving LIM_MLM_PURGE_STA_IND)
+ break;
+ } // end switch (psessionEntry->limSystemRole)
+} /*** end limProcessMlmDisassocInd() ***/
+
+/**
+ * limProcessMlmDisassocCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_DISASSOC_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirResultCodes resultCode;
+ tLimMlmDisassocCnf *pMlmDisassocCnf;
+ tpPESession psessionEntry;
+ pMlmDisassocCnf = (tLimMlmDisassocCnf *) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocCnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id\n"));)
+ return;
+ }
+ resultCode = (tSirResultCodes)
+ (pMlmDisassocCnf->disassocTrigger ==
+ eLIM_LINK_MONITORING_DISASSOC) ?
+ eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+ pMlmDisassocCnf->resultCode;
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+#if defined(ANI_AP_CLIENT_SDK)
+ tSirMacAddr nullMacAddr = {0, 0, 0, 0, 0, 0};
+#endif
+ // Disassociate Confirm from MLM
+ if ( (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) )
+ {
+ /**
+ * Should not have received
+ * Disassocate confirm
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_DISASSOC_CNF in state %X\n"),psessionEntry->limSmeState);)
+ return;
+ }
+#if defined(ANI_AP_CLIENT_SDK)
+ // Whenever there is a disassoc notification, make sure the bssId is cleared so that
+ // if the station finds the same AP to which it was associated, it can try to associate
+ // with it again. If this is not done, the beacons/probe rsp from this AP will not be given
+ // up to WSM and it never see this is AP unless a cga/reboot is done.
+ palCopyMemory(pMac->hHdd, pMac->lim.gLimBssid, nullMacAddr, sizeof(tSirMacAddr));
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, nullMacAddr, sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update BSSID on CFG"));
+ }
+#endif
+ if (pMac->lim.gLimRspReqd)
+ pMac->lim.gLimRspReqd = false;
+ if (pMlmDisassocCnf->disassocTrigger ==
+ eLIM_PROMISCUOUS_MODE_DISASSOC)
+ {
+ if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS)
+ psessionEntry->limSmeState = psessionEntry->limPrevSmeState;
+ else
+ psessionEntry->limSmeState = eLIM_SME_OFFLINE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ // Send Promiscuous mode response to host
+ limSendSmePromiscuousModeRsp(pMac);
+ }
+ else
+ {
+ if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS)
+ psessionEntry->limSmeState = psessionEntry->limPrevSmeState;
+ else
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr,
+ resultCode,
+ pMlmDisassocCnf->disassocTrigger,
+ pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
+ }
+ }
+ else if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
+ {
+ limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr,
+ resultCode,
+ pMlmDisassocCnf->disassocTrigger,
+ pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
+ }
+} /*** end limProcessMlmDisassocCnf() ***/
+
+/**
+ * limProcessMlmDeauthInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_DEAUTH_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmDeauthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tLimMlmDeauthInd *pMlmDeauthInd;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ pMlmDeauthInd = (tLimMlmDeauthInd *) pMsgBuf;
+ if((psessionEntry = peFindSessionByBssid(pMac,pMlmDeauthInd->peerMacAddr,&sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));)
+ return;
+ }
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, psessionEntry->limSmeState));
+
+ default: // eLIM_AP_ROLE
+ {
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Received Deauthentication from staId=%d ***\n"),
+ pMlmDeauthInd->aid);)
+ }
+ // Send SME_DEAUTH_IND after Polaris cleanup
+ // (after receiving LIM_MLM_PURGE_STA_IND)
+ break;
+ } // end switch (psessionEntry->limSystemRole)
+} /*** end limProcessMlmDeauthInd() ***/
+
+/**
+ * limProcessMlmDeauthCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_DEAUTH_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmDeauthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 aid;
+ tSirResultCodes resultCode;
+ tLimMlmDeauthCnf *pMlmDeauthCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthCnf->sessionId))==NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given session Id \n"));)
+ return;
+ }
+
+ resultCode = (tSirResultCodes)
+ (pMlmDeauthCnf->deauthTrigger ==
+ eLIM_LINK_MONITORING_DEAUTH) ?
+ eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+ pMlmDeauthCnf->resultCode;
+ aid = (psessionEntry->limSystemRole == eLIM_AP_ROLE) ?
+ pMlmDeauthCnf->aid : 1;
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ #if defined(ANI_AP_CLIENT_SDK)
+ tSirMacAddr nullMacAddr = {0, 0, 0, 0, 0, 0};
+ #endif
+ // Deauth Confirm from MLM
+ if (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)
+ {
+ /**
+ * Should not have received Deauth confirm
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_DEAUTH_CNF in state %X\n"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+#if defined(ANI_AP_CLIENT_SDK)
+ // Whenever there is a disassoc notification, make sure the bssId is cleared so that
+ // if the station finds the same AP to which it was associated, it can try to associate
+ // with it again. If this is not done, the beacons/probe rsp from this AP will not be given
+ // up to WSM and it never see this is AP unless a cga/reboot is done.
+ palCopyMemory(pMac->hHdd, pMac->lim.gLimBssid, nullMacAddr, sizeof(tSirMacAddr));
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, nullMacAddr, sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update BSSID on CFG"));
+ }
+#endif
+ if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS)
+ {
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Deauthenticated with BSS ***\n"));)
+ }
+ else
+ psessionEntry->limSmeState = psessionEntry->limPrevSmeState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ if (pMac->lim.gLimRspReqd)
+ pMac->lim.gLimRspReqd = false;
+ }
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // BP deauthenticated by AP or vice versa
+ // Send SME_DISASSOC_RSP to host.
+ limSendSmeDisassocNtf(pMac, pMlmDeauthCnf->peerMacAddr,
+ resultCode,
+ pMlmDeauthCnf->deauthTrigger,
+ aid);
+#else
+ // On STA or on BASIC AP, send SME_DEAUTH_RSP to host
+ limSendSmeDeauthNtf(pMac, pMlmDeauthCnf->peerMacAddr,
+ resultCode,
+ pMlmDeauthCnf->deauthTrigger,
+ aid,psessionEntry->smeSessionId,psessionEntry->transactionId);
+#endif
+} /*** end limProcessMlmDeauthCnf() ***/
+
+/**
+ * limProcessMlmPurgeStaInd()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_PURGE_STA_IND
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmPurgeStaInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirResultCodes resultCode;
+ tpLimMlmPurgeStaInd pMlmPurgeStaInd;
+ tpPESession psessionEntry;
+#if defined(ANI_AP_CLIENT_SDK)
+ tSirMacAddr nullMacAddr = {0, 0, 0, 0, 0, 0};
+#endif
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmPurgeStaInd->sessionId))==NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));)
+ return;
+ }
+ // Purge STA indication from MLM
+ resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode;
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ default: // eLIM_AP_ROLE
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
+ (psessionEntry->limSmeState !=
+ eLIM_SME_WT_DISASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE))
+ {
+ /**
+ * Should not have received
+ * Purge STA indication
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(limLog(pMac, LOGE,
+ FL("received unexpected MLM_PURGE_STA_IND in state %X\n"),
+ psessionEntry->limSmeState);)
+ break;
+ }
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Polaris cleanup completed for staId=%d ***\n"),
+ pMlmPurgeStaInd->aid);)
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+#if defined(ANI_AP_CLIENT_SDK)
+ // Whenever there is a disassoc notification, make sure the bssId is cleared so that
+ // if the station finds the same AP to which it was associated, it can try to associate
+ // with it again. If this is not done, the beacons/probe rsp from this AP will not be given
+ // up to WSM and it never see this is AP unless a cga/reboot is done.
+ palCopyMemory(pMac->hHdd, pMac->lim.gLimBssid, nullMacAddr, sizeof(tSirMacAddr));
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, nullMacAddr, sizeof(tSirMacAddr)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update BSSID on CFG"));
+ }
+#endif
+ }
+ if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH)
+ {
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // BP deauthenticated by AP or vice versa
+ // Send SME_DISASSOC_IND to host.
+ limSendSmeDisassocNtf(pMac,
+ pMlmPurgeStaInd->peerMacAddr,
+ resultCode,
+ pMlmPurgeStaInd->purgeTrigger,
+ pMlmPurgeStaInd->aid,psessionEntry);
+#else
+ limSendSmeDeauthNtf(pMac,
+ pMlmPurgeStaInd->peerMacAddr,
+ resultCode,
+ pMlmPurgeStaInd->purgeTrigger,
+ pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId);
+#endif
+ }
+ else
+ limSendSmeDisassocNtf(pMac,
+ pMlmPurgeStaInd->peerMacAddr,
+ resultCode,
+ pMlmPurgeStaInd->purgeTrigger,
+ pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
+ } // end switch (psessionEntry->limSystemRole)
+} /*** end limProcessMlmPurgeStaInd() ***/
+
+/**
+ * limProcessMlmSetKeysCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_SETKEYS_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmSetKeysCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ // Prepare and send SME_SETCONTEXT_RSP message
+ tLimMlmSetKeysCnf *pMlmSetKeysCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf;
+ if ((psessionEntry = peFindSessionBySessionId(pMac, pMlmSetKeysCnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId \n"));)
+ return;
+ }
+ limLog( pMac, LOG1,
+ FL("Received MLM_SETKEYS_CNF with resultCode = %d\n"),
+ pMlmSetKeysCnf->resultCode );
+ limSendSmeSetContextRsp(pMac,
+ pMlmSetKeysCnf->peerMacAddr,
+#ifdef ANI_PRODUCT_TYPE_AP
+ pMlmSetKeysCnf->aid,
+#else
+ 1,
+#endif
+ (tSirResultCodes) pMlmSetKeysCnf->resultCode,psessionEntry,psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+} /*** end limProcessMlmSetKeysCnf() ***/
+/**
+ * limProcessMlmRemoveKeyCnf()
+ *
+ *FUNCTION:
+ * This function is called to processes MLM_REMOVEKEY_CNF
+ * message from MLM State machine.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ // Prepare and send SME_REMOVECONTEXT_RSP message
+ tLimMlmRemoveKeyCnf *pMlmRemoveKeyCnf;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmRemoveKeyCnf = (tLimMlmRemoveKeyCnf *) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyCnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id\n"));)
+ return;
+ }
+ limLog( pMac, LOG1,
+ FL("Received MLM_REMOVEKEYS_CNF with resultCode = %d\n"),
+ pMlmRemoveKeyCnf->resultCode );
+ limSendSmeRemoveKeyRsp(pMac,
+ pMlmRemoveKeyCnf->peerMacAddr,
+ (tSirResultCodes) pMlmRemoveKeyCnf->resultCode,psessionEntry,
+ psessionEntry->smeSessionId,psessionEntry->transactionId);
+} /*** end limProcessMlmRemoveKeyCnf() ***/
+
+
+/**
+ * limHandleSmeJoinResult()
+ *
+ *FUNCTION:
+ * This function is called to process join/auth/assoc failures
+ * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or
+ * MLM_ASSOC_CNF with a success code in case of STA role and
+ * MLM_JOIN_CNF with success in case of STA in IBSS role.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param resultCode Failure code to be sent
+ *
+ *
+ * @return None
+ */
+static void
+limHandleSmeJoinResult(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode, tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs = NULL;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ /* Newly Added on oct 11 th*/
+ if(psessionEntry == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("psessionEntry is NULL \n"));)
+ return;
+ }
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+ /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */
+ if(resultCode != eSIR_SME_SUCCESS)
+ {
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON;
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_JOIN_FAILURE;
+ pStaDs->mlmStaContext.resultCode = resultCode;
+ pStaDs->mlmStaContext.protStatusCode = protStatusCode;
+ //Done: 7-27-2009. JIM_FIX_ME: at the end of limCleanupRxPath, make sure PE is sending eWNI_SME_JOIN_RSP to SME
+ limCleanupRxPath(pMac, pStaDs, psessionEntry);
+ return;
+ }
+ }
+
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimJoinReq);
+ psessionEntry->pLimJoinReq = NULL;
+ //Delete teh session if JOIN failure occurred.
+ if(resultCode != eSIR_SME_SUCCESS)
+ {
+ if(NULL != psessionEntry)
+ {
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+ }
+ limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, resultCode, protStatusCode,psessionEntry,
+ smesessionId, smetransactionId);
+} /*** end limHandleSmeJoinResult() ***/
+
+/**
+ * limProcessMlmAddStaRsp()
+ *
+ *FUNCTION:
+ * This function is called to process a WDA_ADD_STA_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry )
+{
+ //we need to process the deferred message since the initiating req. there might be nested request.
+ //in the case of nested request the new request initiated from the response will take care of resetting
+ //the deffered flag.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+#ifdef ANI_PRODUCT_TYPE_AP
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ limProcessApMlmAddStaRsp(pMac, limMsgQ);
+ return;
+ }
+#endif
+ if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ )
+ {
+ limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
+ return;
+ }
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
+#endif
+}
+void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
+{
+ tLimMlmAssocCnf mlmAssocCnf;
+ tpDphHashNode pStaDs;
+ tANI_U32 mesgType = LIM_MLM_ASSOC_CNF;
+ tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+
+ if(NULL == pAddStaParams )
+ {
+ limLog( pMac, LOGE, FL( "Encountered NULL Pointer\n" ));
+ return;
+ }
+ if( eHAL_STATUS_SUCCESS == pAddStaParams->status )
+ {
+ if( eLIM_MLM_WT_ADD_STA_RSP_STATE != psessionEntry->limMlmState)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_ADD_STA_RSP in state %X\n" ),
+ psessionEntry->limMlmState);
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+ mesgType = LIM_MLM_REASSOC_CNF;
+ //
+ // Update the DPH Hash Entry for this STA
+ // with proper state info
+ //
+ pStaDs = dphGetHashEntry( pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if( NULL != pStaDs)
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ else
+ limLog( pMac, LOGW,
+ FL( "Unable to get the DPH Hash Entry for AID - %d\n" ),
+ DPH_STA_HASH_INDEX_PEER);
+ psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ /*
+ * Storing the self StaIndex(Generated by HAL) in session context,
+ * instead of storing it in DPH Hash entry for Self STA.
+ * DPH entry for the self STA stores the sta index for the BSS entry
+ * to which the STA is associated.
+ */
+ psessionEntry->staId = pAddStaParams->staIdx;
+ //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_KEEPALIVE_TIMER));
+
+ //assign the sessionId to the timer Object
+ pMac->lim.limTimers.gLimKeepaliveTimer.sessionId = psessionEntry->peSessionId;
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimKeepaliveTimer) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("Cannot activate keepalive timer.\n"));
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumLinkEsts++;
+#endif
+ // Return Assoc confirm to SME with success
+ // FIXME_GEN4 - Need the correct ASSOC RSP code to
+ // be passed in here....
+ //mlmAssocCnf.resultCode = (tSirResultCodes) assoc.statusCode;
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS;
+ }
+ else
+ {
+ limLog( pMac, LOGW, FL( "ADD_STA failed!\n"));
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ }
+ /* Updating PE session Id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+ limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf );
+ return;
+}
+void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ //we need to process the deferred message since the initiating req. there might be nested request.
+ //in the case of nested request the new request initiated from the response will take care of resetting
+ //the deffered flag.
+ // tpPESession psessionEntry;
+ // tpDeleteBssParams pDeleteBssParams =( tpDeleteBssParams)limMsgQ->bodyptr;
+ // if((psessionEntry = peFindSessionBySessionId(pMac,pDeleteBssParams->sessionId)) == NULL)
+ // {
+ // limLog( pMac, LOGE, FL( "Session deos not exist with given sessionId\n" ));
+ // return;
+ // }
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ #ifdef ANI_PRODUCT_TYPE_AP
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ limProcessApMlmDelBssRsp(pMac, limMsgQ);
+ return;
+ }
+#endif
+
+ if (((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ ) &&
+ (psessionEntry->statypeForBss == STA_ENTRY_SELF))
+ {
+ limProcessBtAmpApMlmDelBssRsp(pMac, limMsgQ,psessionEntry);
+ return;
+ }
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ limProcessStaMlmDelBssRsp(pMac, limMsgQ,psessionEntry);
+#endif
+}
+
+void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ if( eHAL_STATUS_SUCCESS == pDelBssParams->status )
+ {
+ PELOGW(limLog( pMac, LOGW,
+ FL( "STA received the DEL_BSS_RSP for BSSID: %X.\n"),pDelBssParams->bssIdx);)
+ if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "Failure in setting link state to IDLE\n"));)
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if(pStaDs == NULL)
+ {
+ limLog( pMac, LOGE, FL( "DPH Entry for STA 1 missing.\n"));
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != pStaDs->mlmStaContext.mlmState)
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "Received unexpected WDA_DEL_BSS_RSP in state %X\n" ),
+ pStaDs->mlmStaContext.mlmState);)
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ PELOG1(limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId );
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ }
+ else
+ {
+ limLog( pMac, LOGP, FL( "DEL BSS failed!\n" ) );
+ return;
+ }
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelBssParams );
+ }
+ if(pStaDs == NULL)
+ return;
+ if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE &&
+ psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) &&
+ pStaDs->mlmStaContext.cleanupTrigger != eLIM_JOIN_FAILURE)
+ {
+ /** The Case where the DelBss is invoked from
+ * context of other than normal DisAssoc / Deauth OR
+ * as part of Join Failure.
+ */
+ limHandleDelBssInReAssocContext(pMac, pStaDs,psessionEntry);
+ return;
+ }
+ limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry);
+ return;
+}
+
+
+#ifdef ANI_PRODUCT_TYPE_AP
+void limProcessApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
+{
+ tSirResultCodes rc = eSIR_SME_SUCCESS;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr;
+ if (pDelBss == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!\n"));)
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != pMac->lim.gLimMlmState)
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_DEL_BSS_RSP in state %X\n" ), pMac->lim.gLimMlmState);
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (pDelBss->status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ rc = eSIR_SME_STOP_BSS_FAILURE;
+ goto end;
+ }
+ //Not used for station or softap.
+ rc = limSetLinkState(pMac, eSIR_LINK_IDLE_STATE);
+ if( rc != eSIR_SUCCESS )
+ goto end;
+ /** Softmac may send all the buffered packets right after resuming the transmission hence
+ * to occupy the medium during non channel occupancy period. So resume the transmission after
+ * HAL gives back the response.
+ */
+ if (LIM_IS_RADAR_DETECTED(pMac))
+ {
+ limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_RESUME_TX);
+ LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
+ }
+ dphHashTableClassInit(pMac);
+ limDeletePreAuthList(pMac);
+ //Is it ok to put LIM into IDLE state.
+ pMac->lim.gLimMlmState->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ end:
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc);
+ if(pDelBss != NULL)
+ palFreeMemory( pMac->hHdd, (void *) pDelBss );
+}
+#endif
+/* This code is same as limProcessApMlmDelBssRsp used for BT-AMP */
+void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tSirResultCodes rc = eSIR_SME_SUCCESS;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr;
+ tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ if(psessionEntry == NULL)
+ {
+ limLog(pMac, LOGE,FL("Session entry passed is NULL\n"));
+ return;
+ }
+
+ if (pDelBss == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!\n"));)
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState)
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_DEL_BSS_RSP in state %X\n" ),psessionEntry->limMlmState);
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (pDelBss->status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ rc = eSIR_SME_STOP_BSS_FAILURE;
+ goto end;
+ }
+ rc = limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ psessionEntry->selfMacAddr, NULL, NULL);
+ if( rc != eSIR_SUCCESS )
+ goto end;
+ /** Softmac may send all the buffered packets right after resuming the transmission hence
+ * to occupy the medium during non channel occupancy period. So resume the transmission after
+ * HAL gives back the response.
+ */
+ if (LIM_IS_RADAR_DETECTED(pMac))
+ {
+ limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_RESUME_TX);
+ LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
+ }
+ dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);//TBD-RAJESH is it needed ?
+ limDeletePreAuthList(pMac);
+#ifdef WLAN_SOFTAP_FEATURE
+ //Initialize number of associated stations during cleanup
+ pMac->lim.gLimNumOfCurrentSTAs = 0;
+#endif
+ end:
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc, psessionEntry->smeSessionId, psessionEntry->transactionId);
+ peDeleteSession(pMac, psessionEntry);
+
+ if(pDelBss != NULL)
+ palFreeMemory( pMac->hHdd, (void *) pDelBss );
+}
+
+void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ //we need to process the deferred message since the initiating req. there might be nested request.
+ //in the case of nested request the new request initiated from the response will take care of resetting
+ //the deffered flag.
+
+ tpPESession psessionEntry;
+ tpDeleteStaParams pDeleteStaParams;
+ pDeleteStaParams = (tpDeleteStaParams)limMsgQ->bodyptr;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if((psessionEntry = peFindSessionBySessionId(pMac,pDeleteStaParams->sessionId))==NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ limProcessApMlmDelStaRsp(pMac, limMsgQ);
+ return;
+ }
+#endif
+ if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+#endif
+ )
+ {
+ limProcessBtAmpApMlmDelStaRsp(pMac,limMsgQ,psessionEntry);
+ return;
+ }
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ limProcessStaMlmDelStaRsp(pMac, limMsgQ,psessionEntry);
+#endif
+}
+
+#ifdef ANI_PRODUCT_TYPE_AP
+void limProcessApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId);
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ if( eHAL_STATUS_SUCCESS == pDelStaParams->status )
+ {
+ limLog( pMac, LOGW,
+ FL( "AP received the DEL_STA_RSP for assocID: %X.\n"), pDelStaParams->assocId);
+ if(pStaDs == NULL)
+ {
+ limLog( pMac, LOGE,
+ FL( "DPH Entry for STA %X missing.\n"), pDelStaParams->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if(( eLIM_MLM_WT_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) &&
+ ( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState))
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_DEL_STA_RSP in state %s for staId %d assocId %d \n" ),
+ limMlmStateStr(pStaDs->mlmStaContext.mlmState), pStaDs->staIndex, pStaDs->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ PELOG1(limLog( pMac, LOG1,
+ FL("Deleted STA AssocID %d staId %d MAC "),
+ pStaDs->assocId, pStaDs->staIndex);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == pStaDs->mlmStaContext.mlmState)
+ {
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ }
+ if (limAddSta(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("could not Add STA with assocId=%d\n"),
+ pStaDs->assocId);)
+ // delete the TS if it has already been added.
+ // send the response with error status.
+ if(pStaDs->qos.addtsPresent)
+ {
+ tpLimTspecInfo pTspecInfo;
+ if(eSIR_SUCCESS == limTspecFindByAssocId(pMac, pStaDs->assocId,
+ &pStaDs->qos.addts.tspec, &pMac->lim.tspecInfo[0], &pTspecInfo))
+ {
+ limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo,
+ NULL, &pTspecInfo->idx);
+ }
+ }
+ limRejectAssociation(pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS);
+ }
+ return;
+ }
+ }
+ else
+ {
+ limLog( pMac, LOGW,
+ FL( "DEL STA failed!\n" ));
+ statusCode = eSIR_SME_REFUSED;
+ }
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ }
+ if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)
+ {
+ limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry);
+ }
+ return;
+}
+#endif
+/* This is the copy of limProcessApMlmDelStaRsp used for BT-AMP Support */
+void limProcessBtAmpApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs;
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ if(limMsgQ->bodyptr == NULL)
+ {
+ return;
+ }
+
+ pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId, &psessionEntry->dph.dphHashTable);
+ if(pStaDs == NULL)
+ {
+ limLog( pMac, LOGE,
+ FL( "DPH Entry for STA %X missing.\n"), pDelStaParams->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+
+ return;
+ }
+ if( eHAL_STATUS_SUCCESS == pDelStaParams->status )
+ {
+ limLog( pMac, LOGW,
+ FL( "AP received the DEL_STA_RSP for assocID: %X.\n"), pDelStaParams->assocId);
+
+ if(( eLIM_MLM_WT_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) &&
+ ( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState))
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_DEL_STA_RSP in state %s for staId %d assocId %d \n" ),
+ limMlmStateStr(pStaDs->mlmStaContext.mlmState), pStaDs->staIndex, pStaDs->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ limLog( pMac, LOG1,
+ FL("Deleted STA AssocID %d staId %d MAC "),
+ pStaDs->assocId, pStaDs->staIndex);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);
+ if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == pStaDs->mlmStaContext.mlmState)
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ if (limAddSta(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("could not Add STA with assocId=%d\n"),
+ pStaDs->assocId);)
+ // delete the TS if it has already been added.
+ // send the response with error status.
+ if(pStaDs->qos.addtsPresent)
+ {
+ tpLimTspecInfo pTspecInfo;
+ if(eSIR_SUCCESS == limTspecFindByAssocId(pMac, pStaDs->assocId,
+ &pStaDs->qos.addts.tspec, &pMac->lim.tspecInfo[0], &pTspecInfo))
+ {
+ limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo,
+ NULL, &pTspecInfo->idx);
+ }
+ }
+ limRejectAssociation(pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ }
+ return;
+ }
+ }
+ else
+ {
+ limLog( pMac, LOGW,
+ FL( "DEL STA failed!\n" ));
+ statusCode = eSIR_SME_REFUSED;
+ }
+ end:
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)
+ {
+ limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry);
+ }
+ return;
+}
+
+void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = NULL;
+ if(NULL == pDelStaParams )
+ {
+ limLog( pMac, LOGE, FL( "Encountered NULL Pointer\n" ));
+ goto end;
+ }
+ if( eHAL_STATUS_SUCCESS == pDelStaParams->status )
+ {
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing.\n"),
+ pDelStaParams->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if( eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE, FL( "Received unexpected WDA_DELETE_STA_RSP in state %s\n" ),
+ limMlmStateStr(psessionEntry->limMlmState));
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ PELOG1(limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId );
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ limLog( pMac, LOGW, FL( "DEL_STA_RSP received for assocID: %X\n"), pDelStaParams->assocId);
+ //we must complete all cleanup related to delSta before calling limDelBSS.
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ }
+ statusCode = (tSirResultCodes) limDelBss(pMac, pStaDs, 0,psessionEntry);
+ return;
+ }
+ else
+ {
+ limLog( pMac, LOGW, FL( "DEL_STA failed!\n" ));
+ statusCode = eSIR_SME_REFUSED;
+ }
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pDelStaParams );
+ }
+ return;
+}
+
+#ifdef ANI_PRODUCT_TYPE_AP
+void limProcessApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = dphGetHashEntry(pMac, pAddStaParams->assocId);
+ if(pStaDs == NULL)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing.\n"), pAddStaParams->assocId);
+ goto end;
+ }
+ //
+ // TODO & FIXME_GEN4
+ // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
+ //
+ //TODO: any check for pMac->lim.gLimMlmState ?
+ if( eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_ADD_STA_RSP in state %X\n" ),
+ pStaDs->mlmStaContext.mlmState);
+ goto end;
+ }
+ if(eHAL_STATUS_SUCCESS != pAddStaParams->status)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Error! rcvd delSta rsp from HAL with status %d\n"),pAddStaParams->status);)
+ limRejectAssociation(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS);
+ goto end;
+ }
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
+ pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
+ if(pStaDs->qos.addtsPresent)
+ {
+ //need to send halMsg_AddTs to HAL.
+ tpLimTspecInfo pTspecInfo;
+ if(eSIR_SUCCESS ==
+ limTspecFindByAssocId(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec,
+ &pMac->lim.tspecInfo[0], &pTspecInfo))
+ {
+ if(eSIR_SUCCESS != limSendHalMsgAddTs(pMac, pStaDs->staIndex, pTspecInfo->idx, pStaDs->qos.addts.tspec))
+ {
+ // delete the TS that has already been added.
+ // send the response with error status.
+ limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo, NULL, &pTspecInfo->idx);
+ PELOGE(limLog(pMac, LOGE,
+ FL("limSendHalMsgAddTs failed for STA with assocId=%d\n"),
+ pStaDs->assocId);)
+ limRejectAssociation(pMac,
+ pStaDs->staAddr, pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, false,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS);
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ }
+ limDelSta(pMac, pStaDs, true,psessionEntry);
+ return;
+ }
+ }
+ }
+ //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state
+ pStaDs->valid = 1;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ PELOG1(limLog( pMac, LOG1,
+ FL("STA AssocID %d staId %d MAC "),
+ pStaDs->assocId,
+ pStaDs->staIndex);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);)
+ // Send Re/Association Response with
+ // status code to requesting STA.
+ limSendAssocRspMgmtFrame(pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType, pStaDs,psessionEntry);
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ }
+ return;
+}
+#endif
+/* This is the copy of limProcessApMlmAddStaRsp function .... used for BT-AMP AP Support */
+void limProcessBtAmpApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = dphGetHashEntry(pMac, pAddStaParams->assocId, &psessionEntry->dph.dphHashTable);
+ if(pStaDs == NULL)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing.\n"), pAddStaParams->assocId);
+ goto end;
+ }
+ //
+ // TODO & FIXME_GEN4
+ // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
+ //
+ //TODO: any check for pMac->lim.gLimMlmState ?
+ if( eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)
+ {
+ //TODO: any response to be sent out here ?
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_ADD_STA_RSP in state %X\n" ),
+ pStaDs->mlmStaContext.mlmState);
+ goto end;
+ }
+ if(eHAL_STATUS_SUCCESS != pAddStaParams->status)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Error! rcvd delSta rsp from HAL with status %d\n"),pAddStaParams->status);)
+ limRejectAssociation(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ goto end;
+ }
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state
+ pStaDs->valid = 1;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
+ limLog( pMac, LOG1,
+ FL("STA AssocID %d staId %d MAC "),
+ pStaDs->assocId,
+ pStaDs->staIndex);
+ limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);
+
+ /* For BTAMP-AP, the flow sequence shall be:
+ * 1) PE sends eWNI_SME_ASSOC_IND to SME
+ * 2) PE receives eWNI_SME_ASSOC_CNF from SME
+ * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA
+ */
+ limSendMlmAssocInd(pMac, pStaDs, psessionEntry);
+ // fall though to reclaim the original Add STA Response message
+end:
+ if( 0 != limMsgQ->bodyptr )
+ {
+ palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+ }
+ return;
+}
+
+/**
+ * limProcessApMlmAddBssRsp()
+ *
+ *FUNCTION:
+ * This function is called to process a WDA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WDA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ *LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WDA_ADD_BSS_REQ to HAL
+ * HAL responds with WDA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ *ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+static void
+limProcessApMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tANI_U32 val;
+ tpPESession psessionEntry;
+// tANI_U8 sessionId;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ if(NULL == pAddBssParams )
+ {
+ limLog( pMac, LOGE, FL( "Encountered NULL Pointer\n" ));
+ goto end;
+ }
+ //TBD: free the memory before returning, do it for all places where lookup fails.
+ if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+ /* Update PE session Id*/
+ mlmStartCnf.sessionId = pAddBssParams->sessionId;
+ if( eHAL_STATUS_SUCCESS == pAddBssParams->status )
+ {
+ PELOG2(limLog(pMac, LOG2, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS\n"));)
+ if (limSetLinkState(pMac, eSIR_LINK_AP_STATE,psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ goto end;
+ // Set MLME state
+ psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ if( eSIR_IBSS_MODE == pAddBssParams->bssType )
+ {
+ /** IBSS is 'active' when we receive
+ * Beacon frames from other STAs that are part of same IBSS.
+ * Mark internal state as inactive until then.
+ */
+ psessionEntry->limIbssActive = false;
+ psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know session created for self/peer
+ limResetHBPktCount( psessionEntry );
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if (limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("could not activate Heartbeat timer\n"));
+ }
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ psessionEntry->limSystemRole = eLIM_AP_ROLE;
+#else
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if ( eSIR_INFRA_AP_MODE == pAddBssParams->bssType )
+ psessionEntry->limSystemRole = eLIM_AP_ROLE;
+ else
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+#endif
+ schEdcaProfileUpdate(pMac, psessionEntry);
+ limInitPreAuthList(pMac);
+ limInitAIDpool(pMac,psessionEntry);
+ // Create timers used by LIM
+ if (!pMac->lim.gLimTimersCreated)
+ limCreateTimers(pMac);
+ /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val ))
+ limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!\n"));
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0;
+ // Apply previously set configuration at HW
+ limApplyConfiguration(pMac,psessionEntry);
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d\n" ),pAddBssParams->status );
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf );
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd, (void *) pAddBssParams );
+}
+
+
+/**
+ * limProcessIbssMlmAddBssRsp()
+ *
+ *FUNCTION:
+ * This function is called to process a WDA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WDA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ *LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WDA_ADD_BSS_REQ to HAL
+ * HAL responds with WDA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ *ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+static void
+limProcessIbssMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ tANI_U32 val;
+ if( eHAL_STATUS_SUCCESS == pAddBssParams->status )
+ {
+ PELOG1(limLog(pMac, LOG1, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS\n"));)
+ if (limSetLinkState(pMac, eSIR_LINK_IBSS_STATE,psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ goto end;
+ // Set MLME state
+ psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ /** IBSS is 'active' when we receive
+ * Beacon frames from other STAs that are part of same IBSS.
+ * Mark internal state as inactive until then.
+ */
+ psessionEntry->limIbssActive = false;
+ limResetHBPktCount( psessionEntry );
+ /* Timer related functions are not modified for BT-AMP : To be Done */
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if (limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("could not activate Heartbeat timer\n"));
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+ psessionEntry->statypeForBss = STA_ENTRY_SELF;
+ schEdcaProfileUpdate(pMac, psessionEntry);
+ //TBD-RAJESH limInitPreauthList should re removed for IBSS also ?????
+ //limInitPreAuthList(pMac);
+ limInitAIDpool(pMac,psessionEntry);
+ // Create timers used by LIM
+#ifdef FIXME_GEN6 //following code may not be required, as limCreateTimers is now invoked from limInitialize (peStart)
+ if (!pMac->lim.gLimTimersCreated)
+ limCreateTimers(pMac);
+#endif
+ /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val ))
+ limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!\n"));
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0;
+ // Apply previously set configuration at HW
+ limApplyConfiguration(pMac,psessionEntry);
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ //If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM
+ if(true == pMac->lim.gLimIbssCoalescingHappened)
+ {
+ limIbssAddBssRspWhenCoalescing(pMac, limMsgQ->bodyptr, psessionEntry);
+ goto end;
+ }
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d\n" ),
+ pAddBssParams->status );
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ //Send this message to SME, when ADD_BSS is initiated by SME
+ //If ADD_BSS is done as part of coalescing, this won't happen.
+ /* Update PE session Id*/
+ mlmStartCnf.sessionId =psessionEntry->peSessionId;
+ limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf );
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd, (void *) pAddBssParams );
+}
+
+static void
+limProcessStaMlmAddBssRspPreAssoc( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry )
+{
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ tAniAuthType cfgAuthType, authMode;
+ tLimMlmAuthReq *pMlmAuthReq;
+ tpDphHashNode pStaDs = NULL;
+ if( eHAL_STATUS_SUCCESS == pAddBssParams->status )
+ {
+ if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->staContext.staMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL)
+ {
+ // Could not add hash table entry
+ PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for \n"));)
+ limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE);
+ goto joinFailure;
+ }
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+ //Success, handle below
+ pStaDs->bssId = pAddBssParams->bssIdx;
+ //STA Index(genr by HAL) for the BSS entry is stored here
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+ // Trigger Authentication with AP
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE,
+ (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthType from CFG.
+ * Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthType\n"));
+ }
+ if (cfgAuthType == eSIR_AUTO_SWITCH)
+ authMode = eSIR_OPEN_SYSTEM; // Try Open Authentication first
+ else
+ authMode = cfgAuthType;
+
+ // Trigger MAC based Authentication
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmAuthReq, sizeof(tLimMlmAuthReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmAuthReq\n"));
+ return;
+ }
+ #if 0
+ val = sizeof(tSirMacAddr);
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID,
+ pMlmAuthReq->peerMacAddr,
+ &val) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId);
+
+ pMlmAuthReq->authType = authMode;
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmAuthReq->authFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthFailureTimeout
+ * value from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value\n"));
+ }
+ // SUNIT_FIX_ME: Set BOTH? Assume not. Please verify here and below.
+ //pMac->lim.gLimMlmState = eLIM_MLM_JOINED_STATE;
+ psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_JOINED_STATE));
+ pMlmAuthReq->sessionId = psessionEntry->peSessionId;
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_AUTH_STATE;
+ // remember staId in case of assoc timeout/failure handling
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, psessionEntry->limSmeState));
+ limPostMlmMessage(pMac,
+ LIM_MLM_AUTH_REQ,
+ (tANI_U32 *) pMlmAuthReq);
+ return;
+ }
+
+joinFailure:
+ {
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, psessionEntry->limSmeState));
+
+ /// Send Join response to Host
+ limHandleSmeJoinResult(pMac, eSIR_SME_REFUSED, eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+
+ }
+
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/*------------------------------------------------------------------------------------------
+ *
+ * Function to handle WDA_ADD_BSS_RSP, in FT reassoc state.
+ *
+ *
+ *------------------------------------------------------------------------------------------
+ */
+static inline void
+limProcessStaMlmAddBssRspFT(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs = NULL;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ tpAddStaParams pAddStaParams = NULL;
+ tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ tLimMlmReassocReq *pMlmReassocReq;
+ tLimMlmReassocCnf mlmReassocCnf; // keep sme
+
+ pMlmReassocReq = (tLimMlmReassocReq *)(psessionEntry->pLimMlmReassocReq);
+
+ if ( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE != psessionEntry->limMlmState )
+ {
+ goto end;
+ }
+
+ if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->bssId, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable)) == NULL)
+ {
+ // Could not add hash table entry
+ PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for \n"));)
+ limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE);
+ goto end;
+ }
+
+ // Set the filter state to post assoc
+ if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE,
+ pAddBssParams->bssId, psessionEntry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));)
+ goto end;
+ }
+
+ // Prepare and send Reassociation request frame
+ // start reassoc timer.
+ pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId;
+ /// Start reassociation failure timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_REASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not start reassoc failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not start Reassociation failure timer\n"));
+ // Return Reassoc confirm with
+ // Resources Unavailable
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto end;
+ }
+ limSendReassocReqWithFTIEsMgmtFrame(pMac, psessionEntry->pLimMlmReassocReq, psessionEntry);
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
+ PELOGE(limLog(pMac, LOGE, FL("Set the mlm state to %d session=%d\n"),
+ psessionEntry->limMlmState, psessionEntry->peSessionId);)
+
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+
+ //Success, handle below
+ pStaDs->bssId = pAddBssParams->bssIdx;
+ //STA Index(genr by HAL) for the BSS entry is stored here
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+ pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig;
+ pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig;
+
+ // Downgrade the EDCA parameters if needed
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ // Send the active EDCA parameters to HAL
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
+ {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ }
+ else
+ {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry );
+#endif
+
+ if( eHAL_STATUS_SUCCESS !=
+ palAllocateMemory( pMac->hHdd, (void **) &pAddStaParams, sizeof( tAddStaParams )))
+ {
+ limLog( pMac, LOGP, FL( "Unable to PAL allocate memory during ADD_STA\n" ));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams, sizeof(tAddStaParams));
+
+ /// Add STA context at MAC HW (BMU, RHP & TFP)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->staMac,
+ (tANI_U8 *) psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pAddStaParams->bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ // Update this when we get reassoc rsp , with success.
+ // pAddStaParams->assocId = psessionEntry->limAID;
+
+ pAddStaParams->staType = STA_ENTRY_SELF;
+ pAddStaParams->status = eHAL_STATUS_SUCCESS;
+ pAddStaParams->respReqd = 1;
+
+ /* Update PE session ID */
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
+
+ // This will indicate HAL to "allocate" a new STA index
+ pAddStaParams->staIdx = HAL_STA_INVALID_IDX;
+ pAddStaParams->updateSta = FALSE;
+
+ pAddStaParams->shortPreambleSupported = (tANI_U8)psessionEntry->beaconParams.fShortPreamble;
+ limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry);
+
+ if( psessionEntry->htCapabality)
+ {
+ pAddStaParams->htCapable = psessionEntry->htCapabality;
+#ifdef DISABLE_GF_FOR_INTEROP
+ /*
+ * To resolve the interop problem with Broadcom AP,
+ * where TQ STA could not pass traffic with GF enabled,
+ * TQ STA will do Greenfield only with TQ AP, for
+ * everybody else it will be turned off.
+ */
+ if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator))
+ {
+ limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry"));
+ pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ }
+ else
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
+ pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
+ pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
+ pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
+ pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry );
+ pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry );
+ pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry );
+ pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry);
+ pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry );
+ pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry);
+ pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry);
+ pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry);
+#else
+ pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD );
+ pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET );
+ pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE );
+ pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE );
+ pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION );
+ pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA );
+ pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY );
+ pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR);
+ pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH );
+ pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ);
+ pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ);
+ pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ);
+#endif
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL\n"));
+ pAddStaParams->listenInterval = (tANI_U16)listenInterval;
+
+ limFillSupportedRatesInfo(pMac, NULL, &pAddStaParams->supportedRates,psessionEntry);
+
+ // Lets save this for when we receive the Reassoc Rsp
+ pMac->ft.ftPEContext.pAddStaReq = pAddStaParams;
+ return;
+
+end:
+ // Free up buffer allocated for reassocReq
+ if (pMlmReassocReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
+ }
+ mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id*/
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+
+/**
+ * limProcessStaMlmAddBssRsp()
+ *
+ *FUNCTION:
+ * This function is called to process a WDA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WDA_ADD_BSS_REQ
+ * > Now, send an ADD_STA to HAL and ADD the "local" STA itself
+ *
+ *LOGIC:
+ * MLME had sent WDA_ADD_BSS_REQ to HAL
+ * HAL responded with WDA_ADD_BSS_RSP to MLME
+ * MLME now sends WDA_ADD_STA_REQ to HAL
+ *
+ *ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during limProcessMlmJoinReq
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+static void
+limProcessStaMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry)
+{
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ tLimMlmAssocCnf mlmAssocCnf;
+ tANI_U32 mesgType = LIM_MLM_ASSOC_CNF;
+ tANI_U32 subType = LIM_ASSOC;
+ tpDphHashNode pStaDs = NULL;
+ tANI_U16 staIdx = HAL_STA_INVALID_IDX;
+ tANI_U8 updateSta = false;
+ mlmAssocCnf.resultCode = eSIR_SME_SUCCESS;
+
+ if(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE == psessionEntry->limMlmState)
+ {
+ //Done: 7-28-2009. JIM_FIX_ME: sessionize the following function
+ limProcessStaMlmAddBssRspPreAssoc(pMac, limMsgQ, psessionEntry);
+ goto end;
+ }
+ if( eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == psessionEntry->limMlmState )
+ {
+ mesgType = LIM_MLM_REASSOC_CNF;
+ subType = LIM_REASSOC;
+ //If Reassoc is happening for the same BSS, then use the existing StaId and indicate to HAL
+ //to update the existing STA entry.
+ //If Reassoc is happening for the new BSS, then old BSS and STA entry would have been already deleted
+ //before PE tries to add BSS for the new BSS, so set the updateSta to false and pass INVALID STA Index.
+ if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId))
+ {
+ staIdx = psessionEntry->staId;
+ updateSta = true;
+ }
+ }
+ if( eHAL_STATUS_SUCCESS == pAddBssParams->status )
+ {
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_CCX)
+ if( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState )
+ {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog(pMac, LOGE, FL("Mlm=%d %d\n"),
+ psessionEntry->limMlmState,
+ eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);)
+#endif
+ limProcessStaMlmAddBssRspFT( pMac, limMsgQ, psessionEntry);
+ goto end;
+ }
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+ // Set MLME state
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know the session started for self or for peer oct6th
+ // Now, send WDA_ADD_STA_REQ
+ limLog( pMac, LOGW, FL( "On STA: ADD_BSS was successful\n" ));
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not Add Self Entry for the station\n"));)
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+ else
+ {
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+ //Success, handle below
+ pStaDs->bssId = pAddBssParams->bssIdx;
+ //STA Index(genr by HAL) for the BSS entry is stored here
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+ pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig;
+ pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig;
+ // Downgrade the EDCA parameters if needed
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+ // Send the active EDCA parameters to HAL
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ } else {
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry );
+#endif
+
+ if (subType == LIM_REASSOC)
+ limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER);
+ if (limAddStaSelf(pMac,staIdx, updateSta, psessionEntry) != eSIR_SUCCESS)
+ {
+ // Add STA context at HW
+ PELOGE(limLog(pMac, LOGE, FL("could not Add Self Entry for the station\n"));)
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+ }
+ }
+ else
+ {
+ limLog( pMac, LOGP, FL( "ADD_BSS failed!\n" ));
+ // Return Assoc confirm to SME with failure
+ mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+
+ if(mlmAssocCnf.resultCode != eSIR_SME_SUCCESS)
+ {
+ /* Update PE session Id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+ limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf );
+ }
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd,(void *) pAddBssParams );
+}
+
+
+
+/**
+ * limProcessMlmAddBssRsp()
+ *
+ *FUNCTION:
+ * This function is called to process a WDA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ *
+ *LOGIC:
+ * WDA_ADD_BSS_RSP can be received by MLME while the LIM is
+ * in the following two states:
+ * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE
+ * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE
+ * Based on these two states, this API will determine where to
+ * route the message to
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tpPESession psessionEntry;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) (limMsgQ->bodyptr);
+
+ if(NULL == pAddBssParams )
+ {
+ limLog( pMac, LOGE, FL( "Encountered NULL Pointer\n" ));
+ return;
+ }
+
+ //
+ // TODO & FIXME_GEN4
+ // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
+ //
+ //we need to process the deferred message since the initiating req. there might be nested request.
+ //in the case of nested request the new request initiated from the response will take care of resetting
+ //the deffered flag.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ // Validate SME/LIM state
+ // Validate MLME state
+ if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL)
+ {
+ limLog( pMac, LOGE, FL( "Session Does not exist for given sessionId\n" ));
+ return;
+ }
+ /* update PE session Id*/
+ mlmStartCnf.sessionId = psessionEntry->peSessionId;
+ if( eSIR_IBSS_MODE == psessionEntry->bssType )
+ limProcessIbssMlmAddBssRsp( pMac, limMsgQ, psessionEntry );
+ else
+ {
+ if( eLIM_SME_WT_START_BSS_STATE == psessionEntry->limSmeState )
+ {
+ if( eLIM_MLM_WT_ADD_BSS_RSP_STATE != psessionEntry->limMlmState )
+ {
+ // Mesg received from HAL in Invalid state!
+ limLog( pMac, LOGE,
+ FL( "Received unexpected WDA_ADD_BSS_RSP in state %X\n" ),
+ psessionEntry->limMlmState );
+ mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd, (void *) pAddBssParams );
+ limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf );
+ }
+ else if ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE)||(psessionEntry->bssType == eSIR_BTAMP_STA_MODE))
+ {
+ limProcessBtampAddBssRsp(pMac,limMsgQ,psessionEntry);
+ }
+ else
+ limProcessApMlmAddBssRsp( pMac,limMsgQ);
+ }
+ else
+ /* Called while processing assoc response */
+ limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry);
+ }
+}
+/**
+ * limProcessMlmSetKeyRsp()
+ *
+ *FUNCTION:
+ * This function is called to process the following two
+ * messages from HAL:
+ * 1) WDA_SET_BSSKEY_RSP
+ * 2) WDA_SET_STAKEY_RSP
+ * 3) WDA_SET_STA_BCASTKEY_RSP
+ * Upon receipt of this message from HAL,
+ * MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ *
+ *LOGIC:
+ * WDA_SET_BSSKEY_RSP/WDA_SET_STAKEY_RSP can be
+ * received by MLME while in the following state:
+ * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE
+ * Based on this state, this API will determine where to
+ * route the message to
+ *
+ *ASSUMPTIONS:
+ * ONLY the MLME state is being taken into account for now.
+ * This is because, it appears that the handling of the
+ * SETKEYS REQ is handled symmetrically on both the AP & STA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ tANI_U8 respReqd = 1;
+ tLimMlmSetKeysCnf mlmSetKeysCnf;
+ tANI_U8 sessionId = 0;
+ tpPESession psessionEntry;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palZeroMemory( pMac->hHdd, (void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ));
+ //BTAMP
+ if(NULL == limMsgQ->bodyptr)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is NULL\n"));)
+ return;
+ }
+ sessionId = ((tpSetStaKeyParams) limMsgQ->bodyptr)->sessionId;
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+ if( eLIM_MLM_WT_SET_STA_KEY_STATE != psessionEntry->limMlmState )
+ {
+ // Mesg received from HAL in Invalid state!
+ limLog( pMac, LOGW, FL( "Received unexpected [Mesg Id - %d] in state %X\n" ), limMsgQ->type, pMac->lim.gLimMlmState );
+ // There's not much that MLME can do at this stage...
+ respReqd = 0;
+ }
+ else
+ mlmSetKeysCnf.resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status);
+
+ palFreeMemory( pMac->hHdd, (void *) limMsgQ->bodyptr );
+ // Restore MLME state
+ //pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ if( respReqd )
+ {
+ tpLimMlmSetKeysReq lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq;
+ // Prepare and Send LIM_MLM_SETKEYS_CNF
+ if( NULL != lpLimMlmSetKeysReq )
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, sizeof(tSirMacAddr) );
+#ifdef ANI_PRODUCT_TYPE_AP
+ mlmSetKeysCnf.aid = lpLimMlmSetKeysReq->aid;
+#endif
+ // Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMac->lim.gpLimMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ }
+ mlmSetKeysCnf.sessionId = sessionId;
+ limPostSmeMessage( pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf );
+ }
+}
+void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+ tANI_U8 respReqd = 1;
+ tLimMlmSetKeysCnf mlmSetKeysCnf;
+ tANI_U16 resultCode;
+ tANI_U8 sessionId =0;
+ tpPESession psessionEntry;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palZeroMemory( pMac->hHdd, (void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ));
+ //BTAMP
+ if(NULL == limMsgQ->bodyptr)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is null\n"));)
+ return;
+ }
+ sessionId = ((tpSetBssKeyParams) limMsgQ->bodyptr)->sessionId;
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId\n"));)
+ return;
+ }
+ if( eLIM_MLM_WT_SET_BSS_KEY_STATE == psessionEntry->limMlmState )
+ resultCode = (tANI_U16) (((tpSetBssKeyParams) limMsgQ->bodyptr)->status);
+ else
+ resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status); //BCAST key also uses tpSetStaKeyParams. Done this way for readabilty.
+
+ //
+ // TODO & FIXME_GEN4
+ // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
+ //
+ // Validate SME/LIM state - Read the above "ASSUMPTIONS"
+ //if( eLIM_SME_LINK_EST_STATE == pMac->lim.gLimSmeState )
+ //{
+ // Validate MLME state
+ if( eLIM_MLM_WT_SET_BSS_KEY_STATE != psessionEntry->limMlmState &&
+ eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != psessionEntry->limMlmState )
+ {
+ // Mesg received from HAL in Invalid state!
+ limLog( pMac, LOGW, FL( "Received unexpected [Mesg Id - %d] in state %X\n" ), limMsgQ->type, pMac->lim.gLimMlmState );
+ // There's not much that MLME can do at this stage...
+ respReqd = 0;
+ }
+ else
+ mlmSetKeysCnf.resultCode = resultCode;
+
+ palFreeMemory( pMac->hHdd, (void *) limMsgQ->bodyptr );
+ // Restore MLME state
+ //pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ if( respReqd )
+ {
+ tpLimMlmSetKeysReq lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq;
+ mlmSetKeysCnf.sessionId = sessionId;
+
+ // Prepare and Send LIM_MLM_SETKEYS_CNF
+ if( NULL != lpLimMlmSetKeysReq )
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, sizeof(tSirMacAddr) );
+#ifdef ANI_PRODUCT_TYPE_AP
+ mlmSetKeysCnf.aid = lpLimMlmSetKeysReq->aid;
+#endif
+ // Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMac->lim.gpLimMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ }
+ limPostSmeMessage( pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf );
+ }
+}
+/**
+ * limProcessMlmRemoveKeyRsp()
+ *
+ *FUNCTION:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
+{
+tLimMlmRemoveKeyCnf mlmRemoveCnf;
+tANI_U16 resultCode;
+tpLimMlmRemoveKeyReq lpLimMlmRemoveKeyReq = (tpLimMlmRemoveKeyReq) pMac->lim.gpLimMlmRemoveKeyReq;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ palZeroMemory( pMac->hHdd,
+ (void *) &mlmRemoveCnf,
+ sizeof( tLimMlmRemoveKeyCnf ));
+ // Validate MLME state
+ if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE != pMac->lim.gLimMlmState &&
+ eLIM_MLM_WT_REMOVE_STA_KEY_STATE != pMac->lim.gLimMlmState )
+ {
+ // Mesg received from HAL in Invalid state!
+ limLog( pMac, LOGW,
+ FL( "Received unexpected [Mesg Id - %d] in state %X\n" ),
+ limMsgQ->type,
+ pMac->lim.gLimMlmState );
+ return; //ignore the response.
+ }
+
+ if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE == pMac->lim.gLimMlmState )
+ resultCode = (tANI_U16) (((tpRemoveBssKeyParams) limMsgQ->bodyptr)->status);
+ else
+ resultCode = (tANI_U16) (((tpRemoveStaKeyParams) limMsgQ->bodyptr)->status);
+ //
+ // TODO & FIXME_GEN4
+ // Need to inspect tSirMsgQ.reserved for a valid Dialog token!
+ //
+
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd, (void *) limMsgQ->bodyptr );
+ // Restore MLME state
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ // Prepare and Send LIM_MLM_REMOVEKEY_CNF
+ if( NULL != lpLimMlmRemoveKeyReq )
+ {
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &mlmRemoveCnf.peerMacAddr,
+ (tANI_U8 *) lpLimMlmRemoveKeyReq->peerMacAddr,
+ sizeof( tSirMacAddr ));
+ mlmRemoveCnf.resultCode = resultCode;
+ // Free the buffer cached for the global pMac->lim.gpLimMlmRemoveKeyReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMac->lim.gpLimMlmRemoveKeyReq);
+ pMac->lim.gpLimMlmRemoveKeyReq = NULL;
+ }
+ limPostSmeMessage( pMac,
+ LIM_MLM_REMOVEKEY_CNF,
+ (tANI_U32 *) &mlmRemoveCnf );
+}
+
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+/**----------------------------------------------------
+\fn __limProcessFinishLearnRsp
+\brief Handle finish learn rsp state, only for AP.
+\param pMac
+\return NONE
+-----------------------------------------------------*/
+static void __limProcessFinishLearnRsp(tpAniSirGlobal pMac)
+{
+ PELOG2(limLog(pMac, LOG2, FL("System Role: %d\n"), pMac->lim.gLimSystemRole);)
+ if (pMac->lim.gpLimMeasReq == NULL)
+ {
+ limRestorePreLearnState(pMac);
+ return;
+ }
+ /**
+ * Initial measurement -> periodic measurement should keep enabled, so that
+ * if system Role is UNKNOWN LIM can send indication to WSM. Overloading
+ * periodic measurement to distinguish initial measurement and radar
+ * detect park basically to avoid sending measurement indication after
+ * radar detect park.
+ * Radar detect park -> periodic measurement should be disabled, so that
+ * LIM wont send indication even when role is UNKNOWN.
+ * Final measurement -> periodic measurement should be enabled, so that
+ * LIM could start measurement indication timer.
+ */
+ if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled &&
+ !pMac->lim.gLimMeasParams.isMeasIndTimerActive)
+ {
+#if 0 /* Will we be ever in UNKNOWN ROLE: Veerendra */
+ if (pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)
+ {
+ limSendSmeMeasurementInd(pMac);
+ limCleanupMeasResources(pMac);
+ limRestorePreLearnState(pMac);
+ return;
+ }
+ else
+#endif
+ {
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ * priority - MEDIUM
+ */
+ pMac->lim.gLimMeasParams.measurementIndTimer.sessionId = sessionId;
+#endif
+ // Activate periodic measurement indication timer
+ if (tx_timer_activate(
+ &pMac->lim.gLimMeasParams.measurementIndTimer)
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not start Meas IND timer\n"));
+ return;
+ }
+ pMac->lim.gLimMeasParams.isMeasIndTimerActive = 1;
+ }
+ }
+ if (pMac->lim.gLimMeasParams.nextLearnChannelId >=
+ pMac->lim.gpLimMeasReq->channelList.numChannels - 1)
+ {
+ // All channels in the channel set are learned.
+ pMac->lim.gLimMeasParams.nextLearnChannelId = 0;
+ }
+ // Go back to previous state.
+ limRestorePreLearnState(pMac);
+ // Restart the learn interval timer.
+ if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
+ limReEnableLearnMode(pMac);
+ return;
+}
+#endif
+
+/** ---------------------------------------------------------------------
+\fn limProcessInitScanRsp
+\brief This function is called when LIM receives WDA_INIT_SCAN_RSP
+\ message from HAL. If status code is failure, then
+\ update the gLimNumOfConsecutiveBkgndScanFailure count.
+\param tpAniSirGlobal pMac
+\param tANI_U32 body
+\return none
+\ ----------------------------------------------------------------------- */
+void limProcessInitScanRsp(tpAniSirGlobal pMac, void *body)
+{
+ tpInitScanParams pInitScanParam;
+ eHalStatus status;
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U8 channelNum;
+#endif
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pInitScanParam = (tpInitScanParams) body;
+ status = pInitScanParam->status;
+ palFreeMemory( pMac->hHdd, (char *)body);
+
+ //Only abort scan if the we are scanning.
+ if( pMac->lim.abortScan &&
+ (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) )
+ {
+ limLog( pMac, LOGW, FL(" finish scan\n") );
+ 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);
+ }
+ switch(pMac->lim.gLimHalScanState)
+ {
+ case eLIM_HAL_INIT_SCAN_WAIT_STATE:
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("InitScanRsp with failed status= %d\n"), status);)
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ pMac->lim.gLimNumOfConsecutiveBkgndScanFailure += 1;
+ /*
+ * On Windows eSIR_SME_HAL_SCAN_INIT_FAILED message to CSR may trigger
+ * another Scan request in the same context (happens when 11d is enabled
+ * and first scan request with 11d channels fails for whatever reason, then CSR issues next init
+ * scan in the same context but with bigger channel list), so the state needs to be
+ * changed before this response message is sent.
+ */
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ /* For handling the measurement request from WSM as scan request in LIM*/
+#if 0
+ if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE && pMac->lim.gpLimMeasReq != NULL)
+ {
+ limRestorePreLearnState(pMac);
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ limReEnableLearnMode(pMac);
+ }
+#endif
+#endif
+ return;
+ }
+ else if (status == eHAL_STATUS_SUCCESS)
+ {
+ /* since we have successfully triggered a background scan,
+ * reset the "consecutive bkgnd scan failure" count to 0
+ */
+ pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0;
+ pMac->lim.gLimNumOfBackgroundScanSuccess += 1;
+ }
+ limContinueChannelScan(pMac);
+ break;
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_INIT_LEARN_WAIT_STATE:
+// if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ limRestorePreLearnState(pMac);
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ limReEnableLearnMode(pMac);
+ return;
+ }
+ channelNum = limGetCurrentLearnChannel(pMac);
+ limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_LEARN_WAIT_STATE);
+ }
+ break;
+#endif
+//WLAN_SUSPEND_LINK Related
+ case eLIM_HAL_SUSPEND_LINK_WAIT_STATE:
+ if( pMac->lim.gpLimSuspendCallback )
+ {
+ if( status == eHAL_STATUS_SUCCESS )
+ pMac->lim.gLimHalScanState = eLIM_HAL_SUSPEND_LINK_STATE;
+ else
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+
+ pMac->lim.gpLimSuspendCallback( pMac, status, pMac->lim.gpLimSuspendData );
+ pMac->lim.gpLimSuspendCallback = NULL;
+ pMac->lim.gpLimSuspendData = NULL;
+ }
+ else
+ {
+ limLog( pMac, LOGP, "No suspend link callback set but station is in suspend state\n");
+ return;
+ }
+ break;
+//end WLAN_SUSPEND_LINK Related
+ default:
+ limLog(pMac, LOGW, FL("limProcessInitScanRsp: Rcvd InitScanRsp not in WAIT State, state %d\n"),
+ pMac->lim.gLimHalScanState);
+ break;
+ }
+ return;
+}
+/**
+ * limProcessSwitchChannelReAssocReq()
+ *
+ *FUNCTION:
+ * This function is called to send the reassoc req mgmt frame after the
+ * switchChannelRsp message is received from HAL.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure.
+ * @param psessionEntry - session related information.
+ * @param status - channel switch success/failure.
+ *
+ * @return None
+ */
+static void limProcessSwitchChannelReAssocReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ tLimMlmReassocReq *pMlmReassocReq;
+ pMlmReassocReq = (tLimMlmReassocReq *)(psessionEntry->pLimMlmReassocReq);
+ if(pMlmReassocReq == NULL)
+ {
+ limLog(pMac, LOGP, FL("pLimMlmReassocReq does not exist for given switchChanSession\n"));
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ if(status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!\n"));)
+ mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL;
+ goto end;
+ }
+ /// Start reassociation failure timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_REASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+ != TX_SUCCESS)
+ {
+ /// Could not start reassoc failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not start Reassociation failure timer\n"));
+ // Return Reassoc confirm with
+ // Resources Unavailable
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ /// Prepare and send Reassociation request frame
+ limSendReassocReqMgmtFrame(pMac, pMlmReassocReq, psessionEntry);
+ return;
+end:
+ // Free up buffer allocated for reassocReq
+ if(pMlmReassocReq != NULL)
+ {
+ /* Update PE session Id*/
+ mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmReassocReq);
+ }
+ else
+ {
+ mlmReassocCnf.sessionId = 0;
+ }
+
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id*/
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+}
+/**
+ * limProcessSwitchChannelJoinReq()
+ *
+ *FUNCTION:
+ * This function is called to send the probe req mgmt frame after the
+ * switchChannelRsp message is received from HAL.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure.
+ * @param psessionEntry - session related information.
+ * @param status - channel switch success/failure.
+ *
+ * @return None
+ */
+static void limProcessSwitchChannelJoinReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status)
+{
+ tANI_U32 val;
+ tSirMacSSid ssId;
+ tLimMlmJoinCnf mlmJoinCnf;
+ if(status != eHAL_STATUS_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!\n"));)
+ goto error;
+ }
+
+ if ( (NULL == psessionEntry ) || (NULL == psessionEntry->pLimMlmJoinReq) )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("invalid pointer!!\n"));)
+ goto error;
+ }
+
+ // Activate Join failure timer
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_JOIN_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimJoinFailureTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not activate Join failure timer\n"));
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ //memory is freed up below.
+ psessionEntry->pLimMlmJoinReq = NULL;
+ goto error;
+ }
+ /* eSIR_BTAMP_AP_MODE stroed as bss type in session Table when join req is received, is to be veified */
+ if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ if (limSetLinkState(pMac, eSIR_LINK_BTAMP_PREASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ goto error;
+ }
+ else
+ {
+ if(limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ goto error;
+ }
+ // Update BSSID at CFG database
+#if 0
+ if (cfgSetStr(pMac, WNI_CFG_BSSID, pMac->lim.gpLimMlmJoinReq->bssDescription.bssId,
+ sizeof(tSirMacAddr))
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
+#endif //TO SUPPORT BT-AMP
+ //sirCopyMacAddr(psessionEntry->pLimMlmJoinReq->bssDescription.bssId,psessionEntry->bssId);
+
+ /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("failed to get WNI_CFG_TRIG_STA_BK_SCAN cfg value!\n"));
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0;
+ // Apply previously set configuration at HW
+ limApplyConfiguration(pMac, psessionEntry);
+ /// Wait for Beacon to announce join success
+#if 0
+ if (cfgGetStr(pMac, WNI_CFG_SSID, ssId.ssId, &cfgLen) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrive SSID\n"));
+#endif //To SUPPORT BT-AMP
+ palCopyMemory( pMac->hHdd, ssId.ssId,
+ psessionEntry->ssId.ssId,
+ psessionEntry->ssId.length);
+ ssId.length = psessionEntry->ssId.length;
+ // include additional IE if there is
+ limSendProbeReqMgmtFrame( pMac, &ssId,
+ psessionEntry->pLimMlmJoinReq->bssDescription.bssId, psessionEntry->currentOperChannel/*chanNum*/,
+ psessionEntry->selfMacAddr, psessionEntry->dot11mode,
+ psessionEntry->pLimJoinReq->addIEScan.length, psessionEntry->pLimJoinReq->addIEScan.addIEdata);
+ return;
+error:
+ if(NULL != psessionEntry)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) (psessionEntry->pLimMlmJoinReq));
+ psessionEntry->pLimMlmJoinReq = NULL;
+ mlmJoinCnf.sessionId = psessionEntry->peSessionId;
+ }
+ else
+ {
+ mlmJoinCnf.sessionId = 0;
+ }
+ mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf);
+}
+
+/**
+ * limProcessSwitchChannelRsp()
+ *
+ *FUNCTION:
+ * This function is called to process switchChannelRsp message from HAL.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param body - message body.
+ *
+ * @return None
+ */
+void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body)
+{
+ tpSwitchChannelParams pChnlParams = NULL;
+ eHalStatus status;
+ tANI_U16 channelChangeReasonCode;
+ tANI_U8 peSessionId;
+ tpPESession psessionEntry;
+ //we need to process the deferred message since the initiating req. there might be nested request.
+ //in the case of nested request the new request initiated from the response will take care of resetting
+ //the deffered flag.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pChnlParams = (tpSwitchChannelParams) body;
+ status = pChnlParams->status;
+ peSessionId = pChnlParams->peSessionId;
+ if((psessionEntry = peFindSessionBySessionId(pMac, peSessionId))== NULL)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *)body);
+ limLog(pMac, LOGP, FL("session does not exist for given sessionId\n"));
+ return;
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ //HAL fills in the tx power used for mgmt frames in this field.
+ //Store this value to use in TPC report IE.
+ rrmCacheMgmtTxPower( pMac, pChnlParams->txMgmtPower, psessionEntry );
+#endif
+ palFreeMemory( pMac->hHdd, (tANI_U8 *)body);
+ channelChangeReasonCode = psessionEntry->channelChangeReasonCode;
+ // initialize it back to invalid id
+ psessionEntry->channelChangeReasonCode = 0xBAD;
+ switch(channelChangeReasonCode)
+ {
+ case LIM_SWITCH_CHANNEL_REASSOC:
+ limProcessSwitchChannelReAssocReq(pMac, psessionEntry, status);
+ break;
+ case LIM_SWITCH_CHANNEL_JOIN:
+ limProcessSwitchChannelJoinReq(pMac, psessionEntry, status);
+ break;
+
+ case LIM_SWITCH_CHANNEL_OPERATION:
+ /*
+ * The above code should also use the callback.
+ * mechanism below, there is scope for cleanup here.
+ * THat way all this response handler does is call the call back
+ * We can get rid of the reason code here.
+ */
+ if (pMac->lim.gpchangeChannelCallback)
+ {
+ PELOG1(limLog( pMac, LOG1, "Channel changed hence invoke registered call back\n");)
+ pMac->lim.gpchangeChannelCallback(pMac, status, pMac->lim.gpchangeChannelData, psessionEntry);
+ }
+ break;
+ default:
+ break;
+ }
+}
+/**
+ * limProcessStartScanRsp()
+ *
+ *FUNCTION:
+ * This function is called to process startScanRsp message from HAL. If scan/learn was successful
+ * then it will start scan/learn on the next channel.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param body - message body.
+ *
+ * @return None
+ */
+
+void limProcessStartScanRsp(tpAniSirGlobal pMac, void *body)
+{
+ tpStartScanParams pStartScanParam;
+ eHalStatus status;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pStartScanParam = (tpStartScanParams) body;
+ status = pStartScanParam->status;
+#if defined WLAN_FEATURE_VOWIFI
+ //HAL fills in the tx power used for mgmt frames in this field.
+ //Store this value to use in TPC report IE.
+ rrmCacheMgmtTxPower( pMac, pStartScanParam->txMgmtPower, NULL );
+ //Store start TSF of scan start. This will be stored in BSS params.
+ rrmUpdateStartTSF( pMac, pStartScanParam->startTSF );
+#endif
+ palFreeMemory( pMac->hHdd, (tANI_U8 *)body);
+ if( pMac->lim.abortScan )
+ {
+ limLog( pMac, LOGW, FL(" finish scan\n") );
+ 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);
+ }
+ switch(pMac->lim.gLimHalScanState)
+ {
+ case eLIM_HAL_START_SCAN_WAIT_STATE:
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("StartScanRsp with failed status= %d\n"), status);)
+ //
+ // FIXME - With this, LIM will try and recover state, but
+ // eWNI_SME_SCAN_CNF maybe reporting an incorrect
+ // status back to the SME
+ //
+ //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 );
+ //limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+ }
+ else
+ {
+ pMac->lim.gLimHalScanState = eLIM_HAL_SCANNING_STATE;
+ limContinuePostChannelScan(pMac);
+ }
+ break;
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_START_LEARN_WAIT_STATE:
+ // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ //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_LEARN_WAIT_STATE);
+ }
+ else
+ {
+ limContinueChannelLearn(pMac);
+ }
+ }
+ break;
+#endif
+ default:
+ limLog(pMac, LOGW, FL("Rcvd StartScanRsp not in WAIT State, state %d\n"),
+ pMac->lim.gLimHalScanState);
+ break;
+ }
+ return;
+}
+void limProcessEndScanRsp(tpAniSirGlobal pMac, void *body)
+{
+ tpEndScanParams pEndScanParam;
+ eHalStatus status;
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U8 channelNum;
+#endif
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pEndScanParam = (tpEndScanParams) body;
+ status = pEndScanParam->status;
+ palFreeMemory( pMac->hHdd, (char *)body);
+ switch(pMac->lim.gLimHalScanState)
+ {
+ case eLIM_HAL_END_SCAN_WAIT_STATE:
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d\n"), status);)
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED);
+ }
+ else
+ {
+ pMac->lim.gLimCurrentScanChannelId++;
+ limContinueChannelScan(pMac);
+ }
+ break;
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case eLIM_HAL_END_LEARN_WAIT_STATE:
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ //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_LEARN_WAIT_STATE);
+ }
+#if 0 /* Will we be in UNKNOWN ROLE ever in this context: Veerendra */
+ else if (pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)
+ {
+ /** Before starting BSS, we do complete set of measurement before putting
+ * softmac back into normal mode.
+ */
+ channelNum = limGetCurrentLearnChannel(pMac);
+ limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_LEARN_WAIT_STATE);
+ }
+ else
+#endif
+ {
+ limLog(pMac, LOGW, FL("ERROR! This state is set only when AP in UNKNOWN_ROLE\n"),
+ pMac->lim.gLimHalScanState);
+ limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE);
+ }
+ break;
+#endif
+ default:
+ limLog(pMac, LOGW, FL("Rcvd endScanRsp not in WAIT State, state %d\n"),
+ pMac->lim.gLimHalScanState);
+ break;
+ }
+ return;
+}
+void limProcessFinishScanRsp(tpAniSirGlobal pMac, void *body)
+{
+ tpFinishScanParams pFinishScanParam;
+ tANI_U8 dummySessionId = 0;
+ eHalStatus status;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pFinishScanParam = (tpFinishScanParams) body;
+ status = pFinishScanParam->status;
+ palFreeMemory( pMac->hHdd, (char *)body);
+ switch(pMac->lim.gLimHalScanState)
+ {
+ case eLIM_HAL_FINISH_SCAN_WAIT_STATE:
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ limCompleteMlmScan(pMac, eSIR_SME_SUCCESS);
+ if (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
+ {
+ /** Right time to stop tx and start the timer for channel switch */
+ /* Sending Session ID 0, may not be correct, since SCAN is global there should not
+ * be any associated session id
+ */
+ limStopTxAndSwitchChannel(pMac, dummySessionId);
+ }
+ else if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN)
+ {
+ /** Start the quieting */
+ /* Sending Session ID 0, may not be correct, since SCAN is global there should not
+ * be any associated session id
+ */
+ limStartQuietTimer(pMac, dummySessionId);
+ }
+#ifdef ANI_PRODUCT_TYPE_AP
+ /* For handling the measurement request from WSM as scan request in LIM*/
+#if 0
+ if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE && pMac->lim.gpLimMeasReq != NULL)
+ {
+ limSendSmeMeasurementInd(pMac);
+ limCleanupMeasResources(pMac);
+ limRestorePreLearnState(pMac);
+ }
+#endif
+#endif
+ if (status != (tANI_U32) eHAL_STATUS_SUCCESS)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d\n"), status);)
+ }
+ break;
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ case eLIM_HAL_FINISH_LEARN_WAIT_STATE:
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ __limProcessFinishLearnRsp(pMac);
+ break;
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+//WLAN_SUSPEND_LINK Related
+ case eLIM_HAL_RESUME_LINK_WAIT_STATE:
+ if( pMac->lim.gpLimResumeCallback )
+ {
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ pMac->lim.gpLimResumeCallback( pMac, status, pMac->lim.gpLimResumeData );
+ pMac->lim.gpLimResumeCallback = NULL;
+ pMac->lim.gpLimResumeData = NULL;
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ }
+ else
+ {
+ limLog( pMac, LOGP, "No Resume link callback set but station is in suspend state\n");
+ return;
+ }
+ break;
+//end WLAN_SUSPEND_LINK Related
+
+ default:
+ limLog(pMac, LOGW, FL("Rcvd FinishScanRsp not in WAIT State, state %d\n"),
+ pMac->lim.gLimHalScanState);
+ break;
+ }
+ return;
+}
+/**
+ * @function : limProcessMlmHalAddBARsp
+ *
+ * @brief: Process WDA_ADDBA_RSP coming from HAL
+ *
+ *
+ * @param pMac The global tpAniSirGlobal object
+ *
+ * @param tSirMsgQ The MsgQ header containing the response buffer
+ *
+ * @return none
+ */
+void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ )
+{
+ // Send LIM_MLM_ADDBA_CNF to LIM
+ tpLimMlmAddBACnf pMlmAddBACnf;
+ tpPESession psessionEntry;
+ tpAddBAParams pAddBAParams = (tpAddBAParams) limMsgQ->bodyptr;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ //now LIM can process any defer message.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (pAddBAParams == NULL) {
+ PELOGE(limLog(pMac, LOGE,FL("NULL ADD BA Response from HAL\n"));)
+ return;
+ }
+ if((psessionEntry = peFindSessionBySessionId(pMac, pAddBAParams->sessionId))==NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionID: %d\n"),pAddBAParams->sessionId );)
+ palFreeMemory(pMac->hHdd, (void*)limMsgQ->bodyptr);
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ // Allocate for LIM_MLM_ADDBA_CNF
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmAddBACnf, sizeof( tLimMlmAddBACnf ))) {
+ limLog( pMac, LOGP, FL(" palAllocateMemory failed with error code %d\n"));
+ palFreeMemory(pMac->hHdd, (void*)limMsgQ->bodyptr);
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ));
+ // Copy the peer MAC
+ palCopyMemory( pMac->hHdd, pMlmAddBACnf->peerMacAddr, pAddBAParams->peerMacAddr,
+ sizeof( tSirMacAddr ));
+ // Copy other ADDBA Rsp parameters
+ pMlmAddBACnf->baDialogToken = pAddBAParams->baDialogToken;
+ pMlmAddBACnf->baTID = pAddBAParams->baTID;
+ pMlmAddBACnf->baPolicy = pAddBAParams->baPolicy;
+ pMlmAddBACnf->baBufferSize = pAddBAParams->baBufferSize;
+ pMlmAddBACnf->baTimeout = pAddBAParams->baTimeout;
+ pMlmAddBACnf->baDirection = pAddBAParams->baDirection;
+ pMlmAddBACnf->sessionId = psessionEntry->peSessionId;
+ if(eHAL_STATUS_SUCCESS == pAddBAParams->status)
+ pMlmAddBACnf->addBAResultCode = eSIR_MAC_SUCCESS_STATUS;
+ else
+ pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ palFreeMemory(pMac->hHdd, (void*)limMsgQ->bodyptr);
+ // Send ADDBA CNF to LIM
+ limPostSmeMessage( pMac, LIM_MLM_ADDBA_CNF, (tANI_U32 *) pMlmAddBACnf );
+}
+/**
+ * \brief Process LIM_MLM_ADDBA_CNF
+ *
+ * \sa limProcessMlmAddBACnf
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param tSirMsgQ The MsgQ header containing the response buffer
+ *
+ * \return none
+ */
+void limProcessMlmAddBACnf( tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf )
+{
+tpLimMlmAddBACnf pMlmAddBACnf;
+tpDphHashNode pSta;
+tANI_U16 aid;
+tLimBAState curBaState;
+tpPESession psessionEntry = NULL;
+if(pMsgBuf == NULL)
+{
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+}
+pMlmAddBACnf = (tpLimMlmAddBACnf) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBACnf->sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));)
+ return;
+ }
+ // First, extract the DPH entry
+ pSta = dphLookupHashEntry( pMac, pMlmAddBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if( NULL == pSta )
+ {
+ PELOGE(limLog( pMac, LOGE,
+ FL( "STA context not found - ignoring ADDBA CNF from HAL\n" ));)
+ palFreeMemory( pMac->hHdd, (void *) pMsgBuf );
+ return;
+ }
+ LIM_GET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, &curBaState);
+ // Need to validate SME state
+ if( eLIM_BA_STATE_WT_ADD_RSP != curBaState)
+ {
+ PELOGE(limLog( pMac, LOGE,
+ FL( "Received unexpected ADDBA CNF when STA BA state is %d\n" ),
+ curBaState );)
+ palFreeMemory( pMac->hHdd, (void *) pMsgBuf );
+ return;
+ }
+ // Restore STA BA state
+ LIM_SET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, eLIM_BA_STATE_IDLE);
+ if( eSIR_SUCCESS == pMlmAddBACnf->addBAResultCode )
+ {
+ // Update LIM internal cache...
+ if( eBA_RECIPIENT == pMlmAddBACnf->baDirection )
+ {
+ pSta->tcCfg[pMlmAddBACnf->baTID].fUseBARx = 1;
+ pSta->tcCfg[pMlmAddBACnf->baTID].fRxCompBA = 1;
+ pSta->tcCfg[pMlmAddBACnf->baTID].fRxBApolicy = pMlmAddBACnf->baPolicy;
+ pSta->tcCfg[pMlmAddBACnf->baTID].rxBufSize = pMlmAddBACnf->baBufferSize;
+ pSta->tcCfg[pMlmAddBACnf->baTID].tuRxBAWaitTimeout = pMlmAddBACnf->baTimeout;
+ }
+ else
+ {
+ pSta->tcCfg[pMlmAddBACnf->baTID].fUseBATx = 1;
+ pSta->tcCfg[pMlmAddBACnf->baTID].fTxCompBA = 1;
+ pSta->tcCfg[pMlmAddBACnf->baTID].fTxBApolicy = pMlmAddBACnf->baPolicy;
+ pSta->tcCfg[pMlmAddBACnf->baTID].txBufSize = pMlmAddBACnf->baBufferSize;
+ pSta->tcCfg[pMlmAddBACnf->baTID].tuTxBAWaitTimeout = pMlmAddBACnf->baTimeout;
+ }
+ }
+ if( eBA_RECIPIENT == pMlmAddBACnf->baDirection )
+ {
+ //
+ // Package LIM_MLM_ADDBA_RSP to MLME, with proper
+ // status code. MLME will then send an ADDBA RSP
+ // over the air to the peer MAC entity
+ //
+ if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac,
+ pMlmAddBACnf->peerMacAddr,
+ pMlmAddBACnf->addBAResultCode,
+ pMlmAddBACnf->baDialogToken,
+ (tANI_U8) pMlmAddBACnf->baTID,
+ (tANI_U8) pMlmAddBACnf->baPolicy,
+ pMlmAddBACnf->baBufferSize,
+ pMlmAddBACnf->baTimeout,psessionEntry))
+ {
+ PELOGW(limLog( pMac, LOGW,
+ FL( "Failed to post LIM_MLM_ADDBA_RSP to " ));
+ limPrintMacAddr( pMac, pMlmAddBACnf->peerMacAddr, LOGW );)
+ }
+ }
+ // Free the memory allocated for LIM_MLM_ADDBA_CNF
+ palFreeMemory( pMac->hHdd, (void *) pMsgBuf );
+}
+/**
+ * \brief Process LIM_MLM_DELBA_CNF
+ *
+ * \sa limProcessMlmDelBACnf
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param tSirMsgQ The MsgQ header containing the response buffer
+ *
+ * \return none
+ */
+void limProcessMlmDelBACnf( tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf )
+{
+ tpLimMlmDelBACnf pMlmDelBACnf;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+// tANI_U8 sessionId;
+ tLimBAState curBaState;
+ tpPESession psessionEntry;
+
+ if(pMsgBuf == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));)
+ return;
+ }
+ pMlmDelBACnf = (tpLimMlmDelBACnf) pMsgBuf;
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDelBACnf->sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ // First, extract the DPH entry
+ pSta = dphLookupHashEntry( pMac, pMlmDelBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable );
+ if( NULL == pSta )
+ {
+ limLog( pMac, LOGE,
+ FL( "STA context not found - ignoring DELBA CNF from HAL\n" ));
+ return;
+ }
+ if(NULL == pMlmDelBACnf)
+ {
+ limLog( pMac, LOGE,
+ FL( "pMlmDelBACnf is NULL - ignoring DELBA CNF from HAL\n" ));
+ return;
+ }
+ // Need to validate baState
+ LIM_GET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, &curBaState);
+ if( eLIM_BA_STATE_WT_DEL_RSP != curBaState )
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected DELBA CNF when STA BA state is %d\n" ),
+ curBaState );
+ return;
+ }
+ // Restore STA BA state
+ LIM_SET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, eLIM_BA_STATE_IDLE);
+ // Free the memory allocated for LIM_MLM_DELBA_CNF
+ palFreeMemory( pMac->hHdd, (void *) pMsgBuf );
+}
+/**
+ * \brief Process SIR_LIM_DEL_BA_IND
+ *
+ * \sa limProcessMlmHalBADeleteInd
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param tSirMsgQ The MsgQ header containing the indication buffer
+ *
+ * \return none
+ */
+void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ )
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpBADeleteParams pBADeleteParams;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+ tLimBAState curBaState;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+ pBADeleteParams = (tpBADeleteParams) limMsgQ->bodyptr;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pBADeleteParams->bssId,&sessionId))== NULL)
+ {
+ PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));)
+ return;
+ }
+ // First, extract the DPH entry
+ pSta = dphLookupHashEntry( pMac, pBADeleteParams->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable );
+ if( NULL == pSta )
+ {
+ limLog( pMac, LOGE,
+ FL( "STA context not found - ignoring BA Delete IND from HAL\n" ));
+ goto returnAfterCleanup;
+ }
+
+ // Need to validate BA state
+ LIM_GET_STA_BA_STATE(pSta, pBADeleteParams->baTID, &curBaState);
+ if( eLIM_BA_STATE_IDLE != curBaState )
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected BA Delete IND when STA BA state is %d\n" ),
+ curBaState );
+ goto returnAfterCleanup;
+ }
+
+ // Validate if a BA is active for the requested TID
+ // AND in that desired direction
+ if( eBA_INITIATOR == pBADeleteParams->baDirection )
+ {
+ if( 0 == pSta->tcCfg[pBADeleteParams->baTID].fUseBATx )
+ status = eSIR_FAILURE;
+ }
+ else
+ {
+ if( 0 == pSta->tcCfg[pBADeleteParams->baTID].fUseBARx )
+ status = eSIR_FAILURE;
+ }
+ if( eSIR_FAILURE == status )
+ {
+ limLog( pMac, LOGW,
+ FL("Received an INVALID DELBA Delete Ind for TID %d...\n"),
+ pBADeleteParams->baTID );
+ }
+ else
+ {
+ // Post DELBA REQ to MLME...
+ if( eSIR_SUCCESS !=
+ (status = limPostMlmDelBAReq( pMac,
+ pSta,
+ pBADeleteParams->baDirection,
+ pBADeleteParams->baTID,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry )))
+ {
+ limLog( pMac, LOGE,
+ FL( "Attempt to post LIM_MLM_DELBA_REQ failed with status %d\n" ), status);
+ }
+ else
+ {
+ limLog( pMac, LOGE,
+ FL( "BA Delete - Reason 0x%08x. Attempting to delete BA session for TID %d with peer STA " ),
+ pBADeleteParams->reasonCode, pBADeleteParams->baTID );
+ limPrintMacAddr( pMac, pSta->staAddr, LOGE );
+ }
+ }
+returnAfterCleanup:
+ // Free the memory allocated for SIR_LIM_DEL_BA_IND
+ palFreeMemory( pMac->hHdd, (void *) limMsgQ->bodyptr );
+}
+/**
+ * @function : limProcessSetMimoRsp()
+ *
+ * @brief : This function is called upon receiving the WDA_SET_MIMOPS_RSP from the HAL
+ * after Processing the Req from the SME (PMC)
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param limMsg - Lim Message structure object with the MimoPSparam in body
+ * @return None
+ */
+
+void
+limProcessSetMimoRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+#if 0
+ tSirRetStatus retStatus;
+ tpSetMIMOPS pMIMO_PSParams;
+
+
+ do {
+
+ pMIMO_PSParams = (tpSetMIMOPS)limMsg->bodyptr;
+ if( NULL == pMIMO_PSParams ) {
+ PELOGE(limLog(pMac, LOGE, "Received the WDA_SET_MIMOPS_RSP with NULL as the PS param");)
+ return;
+ }
+
+ /** If Updation of the HAL Fail's*/
+ if (pMIMO_PSParams->status != eSIR_SUCCESS) {
+ limLog(pMac, LOGP, FL("Update HAL / SW Mac for MIMO State has Failed\n"));
+ break;
+ }
+
+ if ((pMac->lim.gLimSystemRole != eSYSTEM_STA_ROLE) ||
+ (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) )
+ break;
+
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /** In the Case of Exiting out of the Powersave (changing from Dynamic/Static mode to SM Enabled)
+ * send the action Frame to Peer to update the PS State of the STA , for the case of Entering PowerSave
+ * the Action Frame is being sent at first before setting the internal structures
+ */
+ if (!isEnteringMimoPS(pMac->lim.gHTMIMOPSState, pMIMO_PSParams->htMIMOPSState)) {
+ tSirMacAddr macAddr;
+
+ /** Obtain the AP's Mac Address */
+ palCopyMemory(pMac -> hHdd, (tANI_U8 *)macAddr, pMac->lim.gLimBssid, sizeof(tSirMacAddr));
+
+ /** Send Action Frame with the corresponding mode */
+ retStatus = limSendSMPowerStateFrame(pMac, macAddr, pMIMO_PSParams->htMIMOPSState);
+ if (retStatus != eSIR_SUCCESS) {
+ PELOGE(limLog(pMac, LOGE, FL("Sending Action Frame has failed\n"));)
+ break;
+ }
+ }
+ PELOG1(limLog(pMac, LOG1, FL("The Setting up of LimGlobals is successful for MIMOPS"));)
+ }while(0);
+
+ palFreeMemory( pMac->hHdd, (void *) pMIMO_PSParams );
+#endif
+}
+/**
+ * @function : limHandleDelBssInReAssocContext
+ * @brief : While Processing the ReAssociation Response Frame in STA,
+ * a. immediately after receiving the Reassoc Response the RxCleanUp is
+ * being issued and the end of DelBSS the new BSS is being added.
+ *
+ * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context
+ * change, We need to update CSR with ReAssocCNF Response with the
+ * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS
+ * context only
+ *
+ * @param : pMac - tpAniSirGlobal
+ * pStaDs - Station Descriptor
+ *
+ * @return : none
+ */
+static void
+limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/
+ /** Set the MlmState to IDLE*/
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ /* Update PE session Id*/
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ switch (psessionEntry->limMlmState) {
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ case eLIM_SME_WT_REASSOC_STATE :
+ {
+ tpSirAssocRsp assocRsp;
+ tpDphHashNode pStaDs;
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ tSchBeaconStruct beaconStruct;
+#endif
+ /** Delete the older STA Table entry */
+ limDeleteDphHashEntry(pMac, psessionEntry->bssId, DPH_STA_HASH_INDEX_PEER, psessionEntry);
+ /**
+ * Add an entry for AP to hash table
+ * maintained by DPH module
+ */
+ if ((pStaDs = dphAddHashEntry(pMac, psessionEntry->limReAssocbssId, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL)
+ {
+ // Could not add hash table entry
+ PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for \n"));)
+ limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOGE);
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+ goto Error;
+ }
+ /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame
+ * is being stored to be used here for sending ADDBSS
+ */
+ assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData;
+ limUpdateAssocStaDatas(pMac, pStaDs, assocRsp,psessionEntry);
+ limUpdateReAssocGlobals(pMac, assocRsp,psessionEntry);
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
+ limGetIElenFromBssDescription( &psessionEntry->pLimReAssocReq->bssDescription ),
+ &beaconStruct );
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideStaProtectionOnAssoc(pMac, &beaconStruct, psessionEntry);
+ if(beaconStruct.erpPresent) {
+ if (beaconStruct.erpIEInfo.barkerPreambleMode)
+ psessionEntry->beaconParams.fShortPreamble = 0;
+ else
+ psessionEntry->beaconParams.fShortPreamble = 1;
+ }
+ //updateBss flag is false, as in this case, PE is first deleting the existing BSS and then adding a new one.
+ if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, &beaconStruct,
+ &psessionEntry->pLimReAssocReq->bssDescription, false, psessionEntry)) {
+ limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed \n"));
+ retStatus = eSIR_FAILURE;
+ }
+#elif defined(ANI_AP_CLIENT_SDK)
+ if (eSIR_SUCCESS != limStaSendAddBss( pMac, (*assocRsp), &psessionEntry->pLimReAssocReq->neighborBssList.bssList[0],
+ false, psessionEntry)) {
+ limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed \n"));
+ retStatus = eSIR_FAILURE;
+ }
+#endif
+ if (retStatus != eSIR_SUCCESS)
+ {
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ palFreeMemory(pMac->hHdd, assocRsp);
+ pMac->lim.gLimAssocResponseData = NULL;
+ goto Error;
+ }
+ palFreeMemory(pMac->hHdd, assocRsp);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+ break;
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE:
+ {
+ /** Case wherein the DisAssoc / Deauth
+ * being sent as response to ReAssoc Req*/
+ /** Send the Reason code as the same received in Disassoc / Deauth Frame*/
+ mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason;
+ mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger;
+ /** Set the SME State back to WT_Reassoc State*/
+ psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry);
+ if((psessionEntry->limSystemRole == eLIM_STA_ROLE)||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ }
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+ }
+ break;
+#endif
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State\n"));)
+ mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+ mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto Error;
+ }
+return;
+Error:
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+}
+
+/* Added For BT -AMP Support */
+static void
+limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tANI_U32 val;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+
+ if( eHAL_STATUS_SUCCESS == pAddBssParams->status )
+ {
+ limLog(pMac, LOG2, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS\n"));
+ if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ if (limSetLinkState(pMac, eSIR_LINK_BTAMP_AP_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ goto end;
+ } else if (psessionEntry->bssType == eSIR_BTAMP_STA_MODE) {
+ if (limSetLinkState(pMac, eSIR_LINK_SCAN_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS )
+ goto end;
+ }
+
+ // Set MLME state
+ psessionEntry->limMlmState= eLIM_MLM_BSS_STARTED_STATE;
+ psessionEntry->statypeForBss = STA_ENTRY_SELF; // to know session started for peer or for self
+ psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx;
+ schEdcaProfileUpdate(pMac, psessionEntry);
+ limInitAIDpool(pMac,psessionEntry);
+ // Create timers used by LIM
+ if (!pMac->lim.gLimTimersCreated)
+ limCreateTimers(pMac);
+ /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val ))
+ limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!\n"));
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0;
+ // Apply previously set configuration at HW
+ limApplyConfiguration(pMac,psessionEntry);
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d\n" ),pAddBssParams->status );
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ mlmStartCnf.sessionId = psessionEntry->peSessionId;
+ limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf );
+ end:
+ if( 0 != limMsgQ->bodyptr )
+ palFreeMemory( pMac->hHdd, (void *) pAddBssParams );
+}
+
+/**
+ * @function : limHandleAddBssInReAssocContext
+ * @brief : While Processing the ReAssociation Response Frame in STA,
+ * a. immediately after receiving the Reassoc Response the RxCleanUp is
+ * being issued and the end of DelBSS the new BSS is being added.
+ *
+ * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context
+ * change, We need to update CSR with ReAssocCNF Response with the
+ * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS
+ * context only
+ *
+ * @param : pMac - tpAniSirGlobal
+ * pStaDs - Station Descriptor
+ *
+ * @return : none
+ */
+void
+limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/
+ /** Set the MlmState to IDLE*/
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ switch (psessionEntry->limSmeState) {
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ case eLIM_SME_WT_REASSOC_STATE : {
+ tpSirAssocRsp assocRsp;
+ tpDphHashNode pStaDs;
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ tSchBeaconStruct beaconStruct;
+#endif
+ // Get the AP entry from DPH hash table
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Fail to get STA PEER entry from hash\n"));)
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+ goto Error;
+ }
+ /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame
+ * is being stored to be used here for sending ADDBSS
+ */
+ assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData;
+ limUpdateAssocStaDatas(pMac, pStaDs, assocRsp, psessionEntry);
+ limUpdateReAssocGlobals(pMac, assocRsp, psessionEntry);
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+ limExtractApCapabilities( pMac,
+ (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
+ limGetIElenFromBssDescription( &psessionEntry->pLimReAssocReq->bssDescription ),
+ &beaconStruct );
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideStaProtectionOnAssoc(pMac, &beaconStruct, psessionEntry);
+ if(beaconStruct.erpPresent) {
+ if (beaconStruct.erpIEInfo.barkerPreambleMode)
+ psessionEntry->beaconParams.fShortPreamble = 0;
+ else
+ psessionEntry->beaconParams.fShortPreamble = 1;
+ }
+
+ if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, &beaconStruct,
+ &psessionEntry->pLimReAssocReq->bssDescription, true, psessionEntry)) {
+ limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed \n"));
+ retStatus = eSIR_FAILURE;
+ }
+#elif defined(ANI_AP_CLIENT_SDK)
+ if (eSIR_SUCCESS != limStaSendAddBss( pMac, (*assocRsp), &pMac->lim.gpLimReassocReq->neighborBssList.bssList[0], true)) {
+ limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed \n"));
+ retStatus = eSIR_FAILURE;
+ }
+#endif
+ if (retStatus != eSIR_SUCCESS)
+ {
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ palFreeMemory(pMac->hHdd, assocRsp);
+ pMac->lim.gLimAssocResponseData = NULL;
+ goto Error;
+ }
+ palFreeMemory(pMac->hHdd, assocRsp);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+ break;
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: { /** Case wherein the DisAssoc / Deauth
+ * being sent as response to ReAssoc Req*/
+ /** Send the Reason code as the same received in Disassoc / Deauth Frame*/
+ mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason;
+ mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger;
+ /** Set the SME State back to WT_Reassoc State*/
+ psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry);
+ if(psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+ }
+ break;
+#endif
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State\n"));)
+ mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+ mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto Error;
+ }
+return;
+Error:
+ limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf);
+}
+
+#if 0
+ static void
+limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+ tSirSmeAssocCnf assocCnf;
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE, FL("pMsgBuf is NULL \n"));
+ goto end;
+ }
+ if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ !__limIsSmeAssocCnfValid(&assocCnf))
+ {
+ limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message \n"));
+ goto end;
+ }
+ if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, FL("session does not exist for given bssId\n"));
+ goto end;
+ }
+ if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) ||
+ ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE)))
+ {
+ limLog(pMac, LOGE, FL("Received unexpected message %X in state %X, in role %X\n"),
+ msgType, psessionEntry->limSmeState , psessionEntry->limSystemRole);
+ goto end;
+ }
+ pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ limLog(pMac, LOG1,
+ FL("Received invalid message %X due to no STA context, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);
+ /*
+ ** send a DISASSOC_IND message to WSM to make sure
+ ** the state in WSM and LIM is the same
+ **/
+ limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED,
+ eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
+ goto end;
+ }
+ if ((pStaDs &&
+ (( !palEqualMemory( pMac->hHdd,(tANI_U8 *) pStaDs->staAddr,
+ (tANI_U8 *) assocCnf.peerMacAddr,
+ sizeof(tSirMacAddr)) ) ||
+ (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
+ ((pStaDs->mlmStaContext.subType == LIM_ASSOC) &&
+ (msgType != eWNI_SME_ASSOC_CNF)) ||
+ ((pStaDs->mlmStaContext.subType == LIM_REASSOC) &&
+ (msgType != eWNI_SME_REASSOC_CNF)))))
+ {
+ limLog(pMac, LOG1,
+ FL("Received invalid message %X due to peerMacAddr mismatched or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);
+ goto end;
+ }
+ /*
+ ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF
+ ** has been received
+ **/
+ limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer\n"));
+ limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId);
+ if (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ {
+ /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence
+ * when it had received Assoc Request frame. Now, PE just needs to send
+ * Association Response frame to the requesting BTAMP-STA.
+ */
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) \n"), pStaDs->assocId);
+ limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType, pStaDs, psessionEntry);
+ goto end;
+ } // (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ else
+ {
+ // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated
+ limRejectAssociation(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ assocCnf.statusCode, psessionEntry);
+ return;
+ }
+end:
+ if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL )
+ {
+ if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame)
+ {
+ palFreeMemory(pMac->hHdd,((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame);
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL;
+ }
+
+ palFreeMemory(pMac->hHdd, psessionEntry->parsedAssocReq[pStaDs->assocId]);
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
+ }
+} /*** end __limProcessSmeAssocCnfNew() ***/
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+void
+limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry){
+ tBeaconGenParams *pBeaconGenParams = NULL;
+ tSirMsgQ limMsg;
+ /** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/
+ if(psessionEntry == NULL ){
+ PELOGE( limLog( pMac, LOGE,
+ FL( "Error:Unable to get the PESessionEntry\n" ));)
+ return;
+ }
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pBeaconGenParams, (sizeof(*pBeaconGenParams))))
+ {
+ PELOGE( limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during sending beaconPreMessage\n" ));)
+ return;
+ }
+ palZeroMemory( pMac->hHdd, pBeaconGenParams, sizeof(*pBeaconGenParams));
+ palCopyMemory( pMac->hHdd, (void *) pBeaconGenParams->bssId,
+ (void *)psessionEntry->bssId,
+ SIR_MAC_ADDR_LENGTH );
+ limMsg.bodyptr = pBeaconGenParams;
+ schProcessPreBeaconInd(pMac, &limMsg);
+ return;
+}
+#endif
diff --git a/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c b/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c
new file mode 100644
index 0000000..ecb7719
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c
@@ -0,0 +1,918 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessProbeReqFrame.cc contains the code
+ * for processing Probe Request Frame.
+ * Author: Chandra Modumudi
+ * Date: 02/28/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#include "cfgApi.h"
+
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSerDesUtils.h"
+#include "parserApi.h"
+#include "limSession.h"
+
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+void limSendP2PProbeResponse(tpAniSirGlobal pMac, tANI_U8 *pBd,
+ tpPESession psessionEntry);
+#endif
+#ifdef WLAN_SOFTAP_FEATURE
+void
+
+limSendSmeProbeReqInd(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tANI_U8 *pProbeReqIE,
+ tANI_U32 ProbeReqIELen,
+ tpPESession psessionEntry);
+
+/**
+ * limGetWPSPBCSessions
+ *
+ *FUNCTION:
+ * This function is called to query the WPS PBC overlap
+ *
+ *LOGIC:
+ * This function check WPS PBC probe request link list for PBC overlap
+ *
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param addr A pointer to probe request source MAC addresss
+ * @param uuid_e A pointer to UUIDE element of WPS IE in WPS PBC probe request
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr,
+ tANI_U8 *uuid_e, eWPSPBCOverlap *overlap,
+ tpPESession psessionEntry)
+{
+ int count = 0;
+ tSirWPSPBCSession *pbc;
+ tANI_TIMESTAMP curTime;
+
+ curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND);
+
+ palFillMemory( pMac->hHdd, (tANI_U8 *)addr, sizeof(tSirMacAddr), 0);
+ palFillMemory( pMac->hHdd, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN, 0);
+
+ for (pbc = psessionEntry->pAPWPSPBCSession; pbc; pbc = pbc->next) {
+
+ if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME)
+ break;
+
+ count++;
+ if(count > 1)
+ break;
+
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)addr, (tANI_U8 *)pbc->addr, sizeof(tSirMacAddr));
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)uuid_e, (tANI_U8 *)pbc->uuid_e, SIR_WPS_UUID_LEN);
+ }
+
+ if (count > 1)
+ {
+ *overlap = eSAP_WPSPBC_OVERLAP_IN120S; // Overlap
+ }
+ else if(count == 0)
+ {
+ *overlap = eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S; // no WPS probe request in 120 second
+ } else
+ {
+ *overlap = eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S; // One WPS probe request in 120 second
+ }
+
+ PELOGE(limLog(pMac, LOGE, FL("overlap = %d\n"), *overlap);)
+ PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, addr, sizeof(tSirMacAddr));)
+ PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, uuid_e, SIR_WPS_UUID_LEN);)
+
+ return;
+}
+
+/**
+ * limRemoveTimeoutPBCsessions
+ *
+ *FUNCTION:
+ * This function is called to remove the WPS PBC probe request entires from specific entry to end.
+ *
+ *LOGIC:
+ *
+ *
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pbc The beginning entry in WPS PBC probe request link list
+ *
+ * @return None
+ */
+static void limRemoveTimeoutPBCsessions(tpAniSirGlobal pMac, tSirWPSPBCSession *pbc)
+{
+ tSirWPSPBCSession *prev;
+
+ while (pbc) {
+ prev = pbc;
+ pbc = pbc->next;
+
+ PELOG4(limLog(pMac, LOG4, FL("WPS PBC sessions remove\n"));)
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->addr, sizeof(tSirMacAddr));)
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->uuid_e, SIR_WPS_UUID_LEN);)
+
+ palFreeMemory(pMac->hHdd, prev);
+ }
+}
+
+void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry)
+{
+ tSirWPSPBCSession *pbc, *prev = NULL;
+ prev = pbc = psessionEntry->pAPWPSPBCSession;
+
+ while (pbc) {
+ if (palEqualMemory(pMac->hHdd, (tANI_U8 *)pbc->addr,
+ (tANI_U8 *)pRemoveMac, sizeof(tSirMacAddr))) {
+ prev->next = pbc->next;
+ if (pbc == psessionEntry->pAPWPSPBCSession)
+ psessionEntry->pAPWPSPBCSession = pbc->next;
+ palFreeMemory(pMac->hHdd, pbc);
+ return;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+
+}
+
+/**
+ * limUpdatePBCSessionEntry
+ *
+ *FUNCTION:
+ * This function is called when probe request with WPS PBC IE is received
+ *
+ *LOGIC:
+ * This function add the WPS PBC probe request in the WPS PBC probe request link list
+ * The link list is in decreased time order of probe request that is received.
+ * The entry that is more than 120 second is removed.
+ *
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param addr A pointer to probe request source MAC addresss
+ * @param uuid_e A pointer to UUIDE element of WPS IE
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+static void limUpdatePBCSessionEntry(tpAniSirGlobal pMac,
+ tANI_U8 *addr, tANI_U8 *uuid_e,
+ tpPESession psessionEntry)
+{
+ tSirWPSPBCSession *pbc, *prev = NULL;
+
+ tANI_TIMESTAMP curTime;
+
+ curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND);
+
+ PELOG4(limLog(pMac, LOG4, FL("Receive WPS probe reques curTime=%d\n"), curTime);)
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, addr, sizeof(tSirMacAddr));)
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, uuid_e, SIR_WPS_UUID_LEN);)
+
+ pbc = psessionEntry->pAPWPSPBCSession;
+
+ while (pbc) {
+ if (palEqualMemory(pMac->hHdd, (tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr)) &&
+ palEqualMemory(pMac->hHdd, (tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN)) {
+ if (prev)
+ prev->next = pbc->next;
+ else
+ psessionEntry->pAPWPSPBCSession = pbc->next;
+ break;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+
+ if (!pbc) {
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pbc, sizeof(tSirWPSPBCSession)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
+ return;
+ }
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr));
+
+ if (uuid_e)
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN);
+ }
+
+ pbc->next = psessionEntry->pAPWPSPBCSession;
+ psessionEntry->pAPWPSPBCSession = pbc;
+ pbc->timestamp = curTime;
+
+ /* remove entries that have timed out */
+ prev = pbc;
+ pbc = pbc->next;
+
+ while (pbc) {
+ if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) {
+ prev->next = NULL;
+ limRemoveTimeoutPBCsessions(pMac, pbc);
+ break;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+}
+#if 0
+/**
+ * limWPSPBCTimeout
+ *
+ *FUNCTION:
+ * This function is called when WPS PBC enrtries clean up timer is expired
+ *
+ *LOGIC:
+ * This function remove all the entryies that more than 120 second old
+ *
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tANI_TIMESTAMP curTime;
+ tSirWPSPBCSession *pbc, *prev = NULL;
+
+ curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND);
+
+ PELOG3(limLog(pMac, LOG3, FL("WPS PBC cleanup timeout curTime=%d\n"), curTime);)
+
+ prev = psessionEntry->pAPWPSPBCSession;
+ if(prev)
+ pbc = prev->next;
+ else
+ return;
+
+ while (pbc) {
+ if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) {
+ prev->next = NULL;
+ limRemoveTimeoutPBCsessions(pMac, pbc);
+ break;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+
+ if(prev)
+ {
+ if (curTime > prev->timestamp + SIR_WPS_PBC_WALK_TIME) {
+ psessionEntry->pAPWPSPBCSession = NULL;
+ limRemoveTimeoutPBCsessions(pMac, prev);
+ }
+ }
+
+}
+#endif
+/**
+ * limWPSPBCClose
+ *
+ *FUNCTION:
+ * This function is called when BSS is closed
+ *
+ *LOGIC:
+ * This function remove all the WPS PBC entries
+ *
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ limRemoveTimeoutPBCsessions(pMac, psessionEntry->pAPWPSPBCSession);
+
+}
+#endif
+
+/**
+ * limCheck11bRates
+ *
+ *FUNCTION:
+ * This function is called by limProcessProbeReqFrame() upon
+ * Probe Request frame reception.
+ *
+ *LOGIC:
+ * This function check 11b rates in supportedRates and extendedRates rates
+ *
+ *NOTE:
+ *
+ * @param rate
+ *
+ * @return BOOLEAN
+ */
+
+tANI_BOOLEAN limCheck11bRates(tANI_U8 rate)
+{
+ if ( ( 0x02 == (rate))
+ || ( 0x04 == (rate))
+ || ( 0x0b == (rate))
+ || ( 0x16 == (rate))
+ )
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * limProcessProbeReqFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception.
+ *
+ *LOGIC:
+ * This function processes received Probe Request frame and responds
+ * with Probe Response.
+ * Only AP or STA in IBSS mode that sent last Beacon will respond to
+ * Probe Request.
+ *
+ *ASSUMPTIONS:
+ * 1. AP or STA in IBSS mode that sent last Beacon will always respond
+ * to Probe Request received with broadcast SSID.
+ *
+ *NOTE:
+ * 1. Dunno what to do with Rates received in Probe Request frame
+ * 2. Frames with out-of-order fields/IEs are dropped.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs
+ *
+ * @return None
+ */
+
+void
+limProcessProbeReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tANI_U8 *pBody;
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+ tSirProbeReq probeReq;
+ tAniSSID ssId;
+ tSirMsgQ msgQ;
+ tSirSmeProbeReq *pSirSmeProbeReq;
+ tANI_U32 wpsApEnable=0, tmp;
+
+ do{
+ // Don't send probe responses if disabled
+ if (pMac->lim.gLimProbeRespDisableFlag)
+ break;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)||
+ ( (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
+ (WDA_GET_RX_BEACON_SENT(pRxPacketInfo)) ) )
+ {
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ PELOG3(limLog(pMac, LOG3, FL("Received Probe Request %d bytes from "), frameLen);
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+
+ // Get pointer to Probe Request frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ // Parse Probe Request frame
+ if (sirConvertProbeReqFrame2Struct(pMac, pBody, frameLen, &probeReq)==eSIR_FAILURE)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Parse error ProbeRequest, length=%d, SA is:"), frameLen);)
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ pMac->sys.probeError++;
+ break;
+ }
+ else
+ {
+#ifdef WLAN_FEATURE_P2P
+ if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
+ {
+ tANI_U8 i = 0, rate_11b = 0, other_rates = 0;
+ // Check 11b rates in supported rates
+ for ( i = 0 ; i < probeReq.supportedRates.numRates;
+ i++ )
+ {
+ if (limCheck11bRates(probeReq.supportedRates.rate[i] & 0x7f))
+ {
+ rate_11b++;
+ }
+ else
+ {
+ other_rates++;
+ }
+ }
+
+ // Check 11b rates in extended rates
+ for ( i = 0 ; i < probeReq.extendedRates.numRates; i++ )
+ {
+ if (limCheck11bRates(probeReq.extendedRates.rate[i] & 0x7f))
+ {
+ rate_11b++;
+ }
+ else
+ {
+ other_rates++;
+ }
+ }
+
+ if ( (rate_11b > 0) && (other_rates == 0) )
+ {
+ PELOG3(limLog(pMac, LOG3,
+ FL("Received a probe request frame with only 11b rates, SA is: "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+ return;
+ }
+ }
+#endif
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+
+ if ( (psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent &
+ SIR_WPS_PROBRSP_VER_PRESENT) &&
+ (probeReq.wscIePresent == 1) &&
+ (probeReq.probeReqWscIeInfo.DevicePasswordID.id ==
+ WSC_PASSWD_ID_PUSH_BUTTON) &&
+ (probeReq.probeReqWscIeInfo.UUID_E.present == 1))
+ {
+ if(psessionEntry->fwdWPSPBCProbeReq)
+ {
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4,
+ pHdr->sa, sizeof(tSirMacAddr));)
+ PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBody, frameLen);)
+ limSendSmeProbeReqInd(pMac, pHdr->sa, pBody, frameLen, psessionEntry);
+ }
+ else
+ {
+ limUpdatePBCSessionEntry(pMac,
+ pHdr->sa, probeReq.probeReqWscIeInfo.UUID_E.uuid, psessionEntry);
+ }
+ }
+ }
+ else
+ {
+#endif
+ if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
+ limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_ENABLE );
+
+ wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP;
+ if ((wpsApEnable) &&
+ (probeReq.wscIePresent == 1) &&
+ (probeReq.probeReqWscIeInfo.DevicePasswordID.id == WSC_PASSWD_ID_PUSH_BUTTON))
+ {
+ // send the probe req to WSM when it is from a PBC station
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **)&pSirSmeProbeReq, sizeof(tSirSmeProbeReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_PROBE_REQ\n"));
+ return;
+ }
+ msgQ.type = eWNI_SME_PROBE_REQ;
+ msgQ.bodyval = 0;
+ msgQ.bodyptr = pSirSmeProbeReq;
+#if defined(ANI_PRODUCT_TYPE_AP) && defined(ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeProbeReq->messageType, eWNI_SME_PROBE_REQ);
+ sirStoreU16N((tANI_U8*)&pSirSmeProbeReq->length, sizeof(tSirSmeProbeReq));
+#else
+
+ pSirSmeProbeReq->messageType = eWNI_SME_PROBE_REQ;
+ pSirSmeProbeReq->length = sizeof(tSirSmeProbeReq);
+#endif
+ pSirSmeProbeReq->sessionId = psessionEntry->smeSessionId;
+ palCopyMemory( pMac->hHdd, pSirSmeProbeReq->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
+ pSirSmeProbeReq->devicePasswdId = probeReq.probeReqWscIeInfo.DevicePasswordID.id;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){
+ PELOG3(limLog(pMac, LOG3, FL("couldnt send the probe req to wsm "));)
+ }
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ }
+#endif
+ }
+
+ ssId.length = psessionEntry->ssId.length;
+ /* Copy the SSID from sessio entry to local variable */
+ palCopyMemory( pMac->hHdd, ssId.ssId,
+ psessionEntry->ssId.ssId,
+ psessionEntry->ssId.length);
+
+ // Compare received SSID with current SSID. If they
+ // match, reply with Probe Response.
+ if (probeReq.ssId.length)
+ {
+ if (!ssId.length)
+ goto multipleSSIDcheck;
+
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) &ssId,
+ (tANI_U8 *) &(probeReq.ssId), (tANI_U8) (ssId.length + 1)) )
+ {
+ limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME, psessionEntry,
+ probeReq.p2pIePresent);
+ break;
+ }
+#ifdef WLAN_FEATURE_P2P
+ else if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
+ {
+ tANI_U8 direct_ssid[7] = "DIRECT-";
+ tANI_U8 direct_ssid_len = 7;
+ if (palEqualMemory( pMac->hHdd, (tANI_U8 *) &direct_ssid,
+ (tANI_U8 *) &(probeReq.ssId.ssId), (tANI_U8) (direct_ssid_len)) )
+ {
+ limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME, psessionEntry,
+ probeReq.p2pIePresent);
+ break;
+ }
+ }
+#endif
+ else
+ {
+ PELOG3(limLog(pMac, LOG3,
+ FL("Ignoring ProbeReq frame with unmatched SSID received from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+ pMac->sys.probeBadSsid++;
+ }
+ }
+ else
+ {
+#if (WNI_POLARIS_FW_PRODUCT == AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U32 cfg;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SEND_SINGLE_SSID_ALWAYS, &cfg)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve SEND_SSID_IN_PR\n"));
+
+ if (!ssId.length &&
+ (psessionEntry->pLimStartBssReq->numSSID == 1) &&
+ cfg)
+ {
+ PELOG2(limLog(pMac, LOG2, FL("Sending ProbeRsp with suppressed SSID to"));
+ limPrintMacAddr(pMac, pHdr->sa, LOG2);)
+
+ limSendProbeRspMgmtFrame( pMac, pHdr->sa,
+ (tAniSSID *) psessionEntry->pLimStartBssReq->ssIdList,
+ DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME, psessionEntry,
+ probeReq.p2pIePresent);
+ }
+ else
+#endif
+ {
+ // Broadcast SSID in the Probe Request.
+ // Reply with SSID we're configured with.
+#ifdef WLAN_SOFTAP_FEATURE
+ //Turn off the SSID length to 0 if hidden SSID feature is present
+ if(psessionEntry->ssidHidden)
+ /*We are returning from here as probe request contains the broadcast SSID.
+ So no need to send the probe resp*/
+ //ssId.length = 0;
+ return;
+#endif
+ limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME, psessionEntry,
+ probeReq.p2pIePresent);
+ }
+ break;
+ }
+multipleSSIDcheck:
+#if (WNI_POLARIS_FW_PRODUCT == AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (!psessionEntry->pLimStartBssReq->ssId.length)
+ {
+ tANI_U8 i;
+
+ // Multiple SSIDs/Suppressed SSID is enabled.
+ for (i = 0; i < psessionEntry->pLimStartBssReq->numSSID; i++)
+ {
+ if (palEqualMemory( pMac->hHdd,
+ (tANI_U8 *) &psessionEntry->pLimStartBssReq->ssIdList[i],
+ (tANI_U8 *) &probeReq.ssId,
+ (tANI_U8) psessionEntry->pLimStartBssReq->ssIdList[i].length + 1))
+ {
+ limSendProbeRspMgmtFrame( pMac, pHdr->sa,
+ (tAniSSID *) &psessionEntry->pLimStartBssReq->ssIdList[i],
+ DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME, psessionEntry,
+ probeReq.p2pIePresent);
+ break;
+ }
+ }
+
+ if (i == psessionEntry->pLimStartBssReq->numSSID)
+ {
+ // Local SSID does not match with received one
+ // Ignore received Probe Request frame
+ PELOG3(limLog(pMac, LOG3,
+ FL("Ignoring ProbeReq frame with unmatched SSID received from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+ pMac->sys.probeBadSsid++;
+ }
+ }
+ else
+#endif
+ {
+ PELOG3(limLog(pMac, LOG3,
+ FL("Ignoring ProbeReq frame with unmatched SSID received from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+ pMac->sys.probeBadSsid++;
+ }
+ }
+ else
+ {
+ // Ignore received Probe Request frame
+ PELOG3(limLog(pMac, LOG3, FL("Ignoring Probe Request frame received from "));
+ limPrintMacAddr(pMac, pHdr->sa, LOG3);)
+ pMac->sys.probeIgnore++;
+ break;
+ }
+ }while(0);
+
+ return;
+} /*** end limProcessProbeReqFrame() ***/
+
+/**
+ * limIndicateProbeReqToHDD
+ *
+ *FUNCTION:
+ * This function is called by limProcessProbeReqFrame_multiple_BSS() upon
+ * Probe Request frame reception.
+ *
+ *LOGIC:
+ * This function processes received Probe Request frame and Pass
+ * Probe Request Frame to HDD.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pBd A pointer to Buffer descriptor + associated PDUs
+ * @param psessionEntry A pointer to PE session
+ *
+ * @return None
+ */
+
+#if defined WLAN_FEATURE_P2P
+static void
+limIndicateProbeReqToHDD(tpAniSirGlobal pMac, tANI_U8 *pBd,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+
+ limLog( pMac, LOG1, "Received a probe request frame");
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pBd);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
+
+ //send the probe req to SME.
+ limSendSmeMgmtFrameInd( pMac, pHdr->fc.subType,
+ (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)),
+ psessionEntry->smeSessionId, WDA_GET_RX_CH(pBd) );
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+ limSendP2PProbeResponse(pMac, pBd, psessionEntry);
+#endif
+} /*** end limIndicateProbeReqToHDD() ***/
+#endif
+
+/**
+ * limProcessProbeReqFrame_multiple_BSS
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception.
+ *
+ *LOGIC:
+ * This function call limIndicateProbeReqToHDD function to indicate
+ * Probe Request frame to HDD. It also call limProcessProbeReqFrame
+ * function which process received Probe Request frame and responds
+ * with Probe Response.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pBd A pointer to Buffer descriptor + associated PDUs
+ * @param psessionEntry A pointer to PE session
+ *
+ * @return None
+ */
+
+void
+limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal pMac, tANI_U8 *pBd, tpPESession psessionEntry)
+{
+ tANI_U8 i;
+
+ if (psessionEntry != NULL)
+ {
+#ifdef WLAN_FEATURE_P2P
+ if ((eLIM_AP_ROLE == psessionEntry->limSystemRole)
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+ || (psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE)
+#endif
+ )
+ {
+ limIndicateProbeReqToHDD(pMac, pBd, psessionEntry);
+ }
+#endif
+ limProcessProbeReqFrame(pMac,pBd,psessionEntry);
+ return;
+ }
+
+ for(i =0; i < pMac->lim.maxBssId;i++)
+ {
+ psessionEntry = peFindSessionBySessionId(pMac,i);
+ if ( (psessionEntry != NULL) )
+ {
+#ifdef WLAN_FEATURE_P2P
+ if ((eLIM_AP_ROLE == psessionEntry->limSystemRole)
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+ || (psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE)
+#endif
+ )
+ {
+ limIndicateProbeReqToHDD(pMac, pBd, psessionEntry);
+ }
+#endif
+ if ( (eLIM_AP_ROLE == psessionEntry->limSystemRole) ||
+ (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) ||
+ (eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) ||
+ (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole)
+ )
+ {
+ limProcessProbeReqFrame(pMac,pBd,psessionEntry);
+ }
+ }
+ }
+
+} /*** end limProcessProbeReqFrame_multiple_BSS() ***/
+
+#ifdef WLAN_SOFTAP_FEATURE
+/**
+ * limSendSmeProbeReqInd()
+ *
+ *FUNCTION:
+ * This function is to send
+ * eWNI_SME_WPS_PBC_PROBE_REQ_IND message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * This function is used for sending eWNI_SME_WPS_PBC_PROBE_REQ_IND
+ * to host.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr that the probe request
+ * is generated.
+ * @param pProbeReqIE pointer to RAW probe request IE
+ * @param ProbeReqIELen The length of probe request IE.
+ * @param psessionEntry A pointer to PE session
+ *
+ * @return None
+ */
+void
+limSendSmeProbeReqInd(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tANI_U8 *pProbeReqIE,
+ tANI_U32 ProbeReqIELen,
+ tpPESession psessionEntry)
+{
+ tSirSmeProbeReqInd *pSirSmeProbeReqInd;
+ tSirMsgQ msgQ;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeProbeReqInd, sizeof(tSirSmeProbeReqInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_PROBE_REQ\n"));
+ return;
+ }
+
+ msgQ.type = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+ msgQ.bodyval = 0;
+ msgQ.bodyptr = pSirSmeProbeReqInd;
+
+ pSirSmeProbeReqInd->messageType = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+ pSirSmeProbeReqInd->length = sizeof(tSirSmeProbeReq);
+ pSirSmeProbeReqInd->sessionId = psessionEntry->smeSessionId;
+
+ palCopyMemory( pMac->hHdd, pSirSmeProbeReqInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+ palCopyMemory( pMac->hHdd, pSirSmeProbeReqInd->WPSPBCProbeReq.peerMacAddr, peerMacAddr, sizeof(tSirMacAddr));
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIELen = (tANI_U16)ProbeReqIELen;
+ palCopyMemory( pMac->hHdd, pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIE, pProbeReqIE, ProbeReqIELen);
+
+ if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){
+ PELOGE(limLog(pMac, LOGE, FL("couldnt send the probe req to hdd"));)
+ }
+
+} /*** end limSendSmeProbeReqInd() ***/
+#endif
+#ifdef WLAN_FEATURE_P2P_INTERNAL
+void limSendP2PProbeResponse(tpAniSirGlobal pMac, tANI_U8 *pBd,
+ tpPESession psessionEntry)
+{
+ tAniSSID ssId = { P2P_WILDCARD_SSID_LEN, P2P_WILDCARD_SSID };
+ tANI_U8 *pBody;
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+ tSirProbeReq probeReq;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pBd);
+ // Get pointer to Probe Request frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pBd);
+
+ if( (pBody[0] == 0) && (pBody[1] == ssId.length) &&
+ (palEqualMemory( pMac->hHdd, ssId.ssId, pBody + 2,
+ ssId.length)))
+ {
+ // Parse Probe Request frame
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
+ if (eSIR_FAILURE == sirConvertProbeReqFrame2Struct(pMac, pBody, frameLen, &probeReq))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Parse error ProbeRequest, length=%d, SA is:"), frameLen);)
+ limPrintMacAddr(pMac, pHdr->sa, LOGW);
+ pMac->sys.probeError++;
+ return;
+ }
+
+ if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
+ {
+ ssId.length = psessionEntry->ssId.length;
+ palCopyMemory(pMac->hHdd, ssId.ssId, psessionEntry->ssId.ssId,psessionEntry->ssId.length);
+ limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME,
+ psessionEntry, probeReq.p2pIePresent );
+ }
+ else
+ {
+ limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME,
+ psessionEntry, probeReq.p2pIePresent );
+ }
+ }
+}
+#endif //#ifdef WLAN_FEATURE_P2P_INTERNAL
diff --git a/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
new file mode 100644
index 0000000..f7949ea
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessProbeRspFrame.cc contains the code
+ * for processing Probe Response Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wniApi.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "aniGlobal.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halCommonApi.h"
+#endif
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSerDesUtils.h"
+#include "limSendMessages.h"
+
+#include "parserApi.h"
+
+/**
+ * limProcessProbeRspFrame
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Response frame reception.
+ *
+ *LOGIC:
+ * This function processes received Probe Response frame.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * 1. Frames with out-of-order IEs are dropped.
+ * 2. In case of IBSS, join 'success' makes MLM state machine
+ * transition into 'BSS started' state. This may have to change
+ * depending on supporting what kinda Authentication in IBSS.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+
+void
+limProcessProbeRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
+{
+ tANI_U8 *pBody;
+ tANI_U32 frameLen = 0;
+ tSirMacAddr currentBssId;
+ tpSirMacMgmtHdr pHdr;
+ tSirProbeRespBeacon probeRsp;
+ tANI_U8 qosEnabled = false;
+ tANI_U8 wmeEnabled = false;
+
+ probeRsp.ssId.length = 0;
+ probeRsp.wpa.length = 0;
+ probeRsp.propIEinfo.apName.length = 0;
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ probeRsp.propIEinfo.aniIndicator = 0;
+ probeRsp.propIEinfo.wdsLength = 0;
+#endif
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("Received Probe Response frame with length=%d from "),
+ WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
+ limPrintMacAddr(pMac, pHdr->sa, LOG2);)
+
+ if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+ return;
+
+
+ /**
+ * Expect Probe Response only when
+ * 1. STA is in scan mode waiting for Beacon/Probe response or
+ * 2. STA is waiting for Beacon/Probe Response to announce
+ * join success or
+ * 3. STA is in IBSS mode in BSS started state or
+ * 4. STA/AP is in learn mode
+ * 5. STA in link established state. In this state, the probe response is
+ * expected for two scenarios:
+ * -- As part of heart beat mechanism, probe req is sent out
+ * -- If QoS Info IE in beacon has a different count for EDCA Params,
+ * and EDCA IE is not present in beacon,
+ * then probe req is sent out to get the EDCA params.
+ *
+ * Ignore Probe Response frame in all other states
+ */
+ // TO SUPPORT BT-AMP
+ if (((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct
+ (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) || //mlm state check should be global - 18th oct
+ (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) ||
+ (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )||
+ ((GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) &&
+ (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)))
+ {
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ // Get pointer to Probe Response frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, &probeRsp)
+ ==eSIR_FAILURE)
+ {
+ PELOG1(limLog(pMac, LOG1,
+ FL("PArse error ProbeResponse, length=%d\n"),
+ frameLen);)
+ return;
+ }
+ //To Support BT-AMP
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE))
+ limCheckAndAddBssDescription(pMac, &probeRsp, pRxPacketInfo,
+ ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE), eANI_BOOLEAN_TRUE);
+ else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) //mlm state check should be global - 18th oct
+ {
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // STA/AP is in learn mode
+ /* Not sure whether the below 2 lines are needed for the station. TODO If yes, this should be
+ * uncommented. Also when we tested enabling this, there is a crash as soon as the station
+ * comes up which needs to be fixed*/
+ //if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ // limCheckAndAddBssDescription(pMac, &probeRsp, pRxPacketInfo, eANI_BOOLEAN_TRUE);
+ limCollectMeasurementData(pMac, pRxPacketInfo, &probeRsp);
+ PELOG3(limLog(pMac, LOG3,
+ FL("Parsed WDS info in ProbeRsp frames: wdsLength=%d\n"),
+ probeRsp.propIEinfo.wdsLength);)
+#endif
+ }
+ else if (psessionEntry->limMlmState ==
+ eLIM_MLM_WT_JOIN_BEACON_STATE)
+ {
+ if( psessionEntry->beacon != NULL ) //Either Beacon/probe response is required. Hence store it in same buffer.
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->beacon);
+ psessionEntry->beacon = NULL;
+ }
+ psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->beacon, psessionEntry->bcnLen)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));)
+ }
+ else
+ {
+ //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->beacon, WDA_GET_RX_MPDU_DATA(pRxPacketInfo), psessionEntry->bcnLen);
+ }
+
+
+ // STA in WT_JOIN_BEACON_STATE
+ limCheckAndAnnounceJoinSuccess(pMac, &probeRsp, pHdr,psessionEntry);
+ }
+ else if(psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ tpDphHashNode pStaDs = NULL;
+ /**
+ * Check if this Probe Response is for
+ * our Probe Request sent upon reaching
+ * heart beat threshold
+ */
+ #if 0
+ if (wlan_cfgGetStr(pMac,
+ WNI_CFG_BSSID,
+ currentBssId,
+ &cfg) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,psessionEntry->bssId);
+
+ if ( !palEqualMemory( pMac->hHdd,currentBssId, pHdr->bssId, sizeof(tSirMacAddr)) )
+ return;
+
+ if (!LIM_IS_CONNECTION_ACTIVE(psessionEntry))
+ {
+ limLog(pMac, LOGW,
+ FL("Received Probe Resp from AP. So it is alive!!\n"));
+
+ if (probeRsp.HTInfo.present)
+ limReceivedHBHandler(pMac, (tANI_U8)probeRsp.HTInfo.primaryChannel, psessionEntry);
+ else
+ limReceivedHBHandler(pMac, (tANI_U8)probeRsp.channelNumber, psessionEntry);
+ }
+
+#if defined ANI_PRODUCT_TYPE_CLIENT || defined (ANI_AP_CLIENT_SDK)
+
+ if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ {
+ if (probeRsp.quietIEPresent)
+ {
+ limUpdateQuietIEFromBeacon(pMac, &(probeRsp.quietIE), psessionEntry);
+ }
+ else if ((pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) ||
+ (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Received a probe rsp without Quiet IE\n"));)
+ limCancelDot11hQuiet(pMac, psessionEntry);
+ }
+
+ if (probeRsp.channelSwitchPresent ||
+ probeRsp.propIEinfo.propChannelSwitchPresent)
+ {
+ limUpdateChannelSwitch(pMac, &probeRsp, psessionEntry);
+ }
+ else if (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
+ {
+ limCancelDot11hChannelSwitch(pMac, psessionEntry);
+ }
+ }
+
+#endif
+
+ /**
+ * Now Process EDCA Parameters, if EDCAParamSet count is different.
+ * -- While processing beacons in link established state if it is determined that
+ * QoS Info IE has a different count for EDCA Params,
+ * and EDCA IE is not present in beacon,
+ * then probe req is sent out to get the EDCA params.
+ */
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+
+ limGetQosMode(psessionEntry, &qosEnabled);
+ limGetWmeMode(psessionEntry, &wmeEnabled);
+ PELOG2(limLog(pMac, LOG2,
+ FL("wmeEdcaPresent: %d wmeEnabled: %d, edcaPresent: %d, qosEnabled: %d, edcaParams.qosInfo.count: %d schObject.gLimEdcaParamSetCount: %d\n"),
+ probeRsp.wmeEdcaPresent, wmeEnabled, probeRsp.edcaPresent, qosEnabled,
+ probeRsp.edcaParams.qosInfo.count, psessionEntry->gLimEdcaParamSetCount);)
+ if (((probeRsp.wmeEdcaPresent && wmeEnabled) ||
+ (probeRsp.edcaPresent && qosEnabled)) &&
+ (probeRsp.edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount))
+ {
+ if (schBeaconEdcaProcess(pMac, &probeRsp.edcaParams, psessionEntry) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("EDCA parameter processing error\n"));)
+ else if (pStaDs != NULL)
+ {
+ // If needed, downgrade the EDCA parameters
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ else
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ }
+ else
+ PELOGE(limLog(pMac, LOGE, FL("Self Entry missing in Hash Table\n"));)
+
+ }
+ }
+ else if ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
+ (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))
+ limHandleIBSScoalescing(pMac, &probeRsp, pRxPacketInfo,psessionEntry);
+ } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ...
+
+ // Ignore Probe Response frame in all other states
+ return;
+} /*** end limProcessProbeRspFrame() ***/
+
+
+void
+limProcessProbeRspFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
+{
+ tANI_U8 *pBody;
+ tANI_U32 frameLen = 0;
+ tpSirMacMgmtHdr pHdr;
+ tSirProbeRespBeacon probeRsp;
+
+ probeRsp.ssId.length = 0;
+ probeRsp.wpa.length = 0;
+ probeRsp.propIEinfo.apName.length = 0;
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ probeRsp.propIEinfo.aniIndicator = 0;
+ probeRsp.propIEinfo.wdsLength = 0;
+#endif
+
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+
+ limLog(pMac, LOG2,
+ FL("Received Probe Response frame with length=%d from "),
+ WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
+ limPrintMacAddr(pMac, pHdr->sa, LOG2);
+
+ if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+ return;
+
+ /* Since there is no psessionEntry, PE cannot be in the following states:
+ * - eLIM_MLM_WT_JOIN_BEACON_STATE
+ * - eLIM_MLM_LINK_ESTABLISHED_STATE
+ * - eLIM_MLM_BSS_STARTED_STATE
+ * Hence, expect Probe Response only when
+ * 1. STA is in scan mode waiting for Beacon/Probe response
+ *
+ * Ignore Probe Response frame in all other states
+ */
+ if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct
+ (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) )
+ {
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ // Get pointer to Probe Response frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, &probeRsp) == eSIR_FAILURE)
+ {
+ limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d\n"), frameLen);
+ return;
+ }
+
+ if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) )
+ limCheckAndAddBssDescription(pMac, &probeRsp, pRxPacketInfo, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
+ else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)
+ {
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // STA/AP is in learn mode
+ /* Not sure whether the below 2 lines are needed for the station. TODO If yes, this should be
+ * uncommented. Also when we tested enabling this, there is a crash as soon as the station
+ * comes up which needs to be fixed*/
+ //if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE)
+ // limCheckAndAddBssDescription(pMac, &probeRsp, pRxPacketInfo, eANI_BOOLEAN_TRUE);
+ limCollectMeasurementData(pMac, pRxPacketInfo, &probeRsp);
+ limLog(pMac, LOG3,
+ FL("Parsed WDS info in ProbeRsp frames: wdsLength=%d\n"),
+ probeRsp.propIEinfo.wdsLength);
+#endif
+ }
+ }
+ return;
+} /*** end limProcessProbeRspFrameNew() ***/
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
new file mode 100644
index 0000000..4523e68
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -0,0 +1,5263 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limProcessSmeReqMessages.cc contains the code
+ * for processing SME request messages.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "palTypes.h"
+#include "wniApi.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+#include "sirApi.h"
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limSmeReqUtils.h"
+#include "limIbssPeerMgmt.h"
+#include "limAdmitControl.h"
+#include "dphHashTable.h"
+#include "limSendMessages.h"
+#include "limApi.h"
+#include "wmmApsd.h"
+
+#ifdef WLAN_SOFTAP_FEATURE
+#include "sapApi.h"
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+#if defined FEATURE_WLAN_CCX
+#include "ccxApi.h"
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include <limFT.h>
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+/* These are the min/max tx power (non virtual rates) range
+ supported by prima hardware */
+#define MIN_TX_PWR_CAP 12
+#define MAX_TX_PWR_CAP 19
+
+#endif
+
+
+// SME REQ processing function templates
+static void __limProcessSmeStartReq(tpAniSirGlobal, tANI_U32 *);
+static tANI_BOOLEAN __limProcessSmeSysReadyInd(tpAniSirGlobal, tANI_U32 *);
+static tANI_BOOLEAN __limProcessSmeStartBssReq(tpAniSirGlobal, tpSirMsgQ pMsg);
+static void __limProcessSmeScanReq(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeJoinReq(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeReassocReq(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeDisassocReq(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *);
+static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *);
+static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg);
+
+#if 0
+ static void __limProcessSmeAuthReq(tpAniSirGlobal, tANI_U32 *);
+ static void __limProcessSmePromiscuousReq(tpAniSirGlobal, tANI_U32 *);
+#endif
+
+#ifdef ANI_PRODUCT_TYPE_AP
+static void __limProcessSmeAssocCnf(tpAniSirGlobal, tANI_U32, tANI_U32 *);
+#endif
+void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *);
+
+#ifdef VOSS_ENABLED
+extern void peRegisterTLHandle(tpAniSirGlobal pMac);
+#endif
+
+#ifdef WLAN_FEATURE_P2P
+extern int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg);
+#endif
+
+#ifdef ANI_PRODUCT_TYPE_CLIENT
+#ifdef BACKGROUND_SCAN_ENABLED
+
+// start the background scan timers if it hasn't already started
+static void
+__limBackgroundScanInitiate(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gLimBackgroundScanStarted)
+ return;
+
+ //make sure timer is created first
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_BACKGROUND_SCAN_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("could not activate background scan timer\n"));
+ pMac->lim.gLimBackgroundScanStarted = true;
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+ }
+}
+
+#endif // BACKGROUND_SCAN_ENABLED
+#endif
+
+// determine if a fresh scan request must be issued or not
+/*
+* PE will do fresh scan, if all of the active sessions are in good state (Link Est or BSS Started)
+* If one of the sessions is not in one of the above states, then PE does not do fresh scan
+* If no session exists (scanning very first time), then PE will always do fresh scan if SME
+* asks it to do that.
+*/
+static tANI_U8
+__limFreshScanReqd(tpAniSirGlobal pMac, tANI_U8 returnFreshResults)
+{
+
+ tANI_U8 validState = TRUE;
+ int i;
+
+ if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE)
+ {
+ return FALSE;
+ }
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) ||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
+ (pMac->lim.gpSession[i].limSmeState == eLIM_SME_LINK_EST_STATE) )||
+
+ ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&&
+ (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) )
+#ifdef WLAN_FEATURE_P2P
+ || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE)
+ && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) )
+ || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) )
+ && (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) )
+#endif
+ ))
+ {
+ validState = FALSE;
+ break;
+ }
+
+ }
+ }
+ PELOG1(limLog(pMac, LOG1, FL("FreshScanReqd: %d \n"), validState);)
+
+ if( (validState) && (returnFreshResults & SIR_BG_SCAN_RETURN_FRESH_RESULTS))
+ return TRUE;
+
+ return FALSE;
+}
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+static tANI_BOOLEAN __limProcessSmeSwitchChlReq(tpAniSirGlobal, tpSirMsgQ pMsg);
+#endif
+
+
+/**
+ * __limIsSmeAssocCnfValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_ASSOC_CNF.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMeasReq Pointer to Received ASSOC_CNF message
+ * @return true When received SME_ASSOC_CNF is formatted
+ * correctly
+ * false otherwise
+ */
+
+inline static tANI_U8
+__limIsSmeAssocCnfValid(tpSirSmeAssocCnf pAssocCnf)
+{
+ if (limIsGroupAddr(pAssocCnf->peerMacAddr))
+ return false;
+ else
+ return true;
+} /*** end __limIsSmeAssocCnfValid() ***/
+
+
+/**
+ * __limGetSmeJoinReqSizeForAlloc()
+ *
+ *FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pBssDescr
+ * @return Total IE length
+ */
+
+static tANI_U16
+__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf)
+{
+ tANI_U16 len = 0;
+
+ if (!pBuf)
+ return len;
+
+ pBuf += sizeof(tANI_U16);
+ len = limGetU16( pBuf );
+ return (len + sizeof( tANI_U16 ));
+} /*** end __limGetSmeJoinReqSizeForAlloc() ***/
+
+
+/**----------------------------------------------------------------
+\fn __limIsDeferedMsgForLearn
+
+\brief Has role only if 11h is enabled. Not used on STA side.
+ Defers the message if SME is in learn state and brings
+ the LIM back to normal mode.
+
+\param pMac
+\param pMsg - Pointer to message posted from SME to LIM.
+\return TRUE - If defered
+ FALSE - Otherwise
+------------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limIsDeferedMsgForLearn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (limIsSystemInScanState(pMac))
+ {
+ if (limDeferMsg(pMac, pMsg) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d\n"), pMsg->type);)
+ return eANI_BOOLEAN_FALSE;
+ }
+ PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d\n"),
+ pMsg->type);)
+
+ /** Send finish scan req to HAL only if LIM is not waiting for any response
+ * from HAL like init scan rsp, start scan rsp etc.
+ */
+ if (GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ {
+ //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_LEARN_WAIT_STATE);
+ }
+
+ return eANI_BOOLEAN_TRUE;
+ }
+ return eANI_BOOLEAN_FALSE;
+}
+
+/**----------------------------------------------------------------
+\fn __limIsDeferedMsgForRadar
+
+\brief Has role only if 11h is enabled. Not used on STA side.
+ Defers the message if radar is detected.
+
+\param pMac
+\param pMsg - Pointer to message posted from SME to LIM.
+\return TRUE - If defered
+ FALSE - Otherwise
+------------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limIsDeferedMsgForRadar(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ /** fRadarDetCurOperChan will be set only if we detect radar in current
+ * operating channel and System Role == AP ROLE */
+ if (LIM_IS_RADAR_DETECTED(pMac))
+ {
+ if (limDeferMsg(pMac, pMsg) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d\n"), pMsg->type);)
+ return eANI_BOOLEAN_FALSE;
+ }
+ PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d\n"),
+ pMsg->type);)
+ return eANI_BOOLEAN_TRUE;
+ }
+ return eANI_BOOLEAN_FALSE;
+}
+
+
+/**
+ * __limProcessSmeStartReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_START_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+
+ PELOG1(limLog(pMac, LOG1, FL("Received START_REQ\n"));)
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
+ {
+ pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ /// By default do not return after first scan match
+ pMac->lim.gLimReturnAfterFirstMatch = 0;
+
+ /// Initialize MLM state machine
+ limInitMlm(pMac);
+
+ /// By default return unique scan results
+ pMac->lim.gLimReturnUniqueResults = true;
+ pMac->lim.gLimSmeScanResultLength = 0;
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ if (((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd)
+ {
+ /*
+ * Need to indicate new BSSs found during background scanning to
+ * host. Update this parameter at CFG
+ */
+ if (cfgSetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, ((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd)
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not set NEIGHBOR_BSS_IND at CFG\n"));
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ }
+ }
+#endif
+ }
+ else
+ {
+ /**
+ * Should not have received eWNI_SME_START_REQ in states
+ * other than OFFLINE. Return response to host and
+ * log error
+ */
+ limLog(pMac, LOGE, FL("Invalid SME_START_REQ received in SME state %X\n"),pMac->lim.gLimSmeState );
+ limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState);
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ }
+ limSendSmeRsp(pMac, eWNI_SME_START_RSP, retCode,smesessionId,smetransactionId);
+} /*** end __limProcessSmeStartReq() ***/
+
+
+/** -------------------------------------------------------------
+\fn __limProcessSmeSysReadyInd
+\brief handles the notification from HDD. PE just forwards this message to HAL.
+\param tpAniSirGlobal pMac
+\param tANI_U32* pMsgBuf
+\return TRUE-Posting to HAL failed, so PE will consume the buffer.
+\ FALSE-Posting to HAL successful, so HAL will consume the buffer.
+ -------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limProcessSmeSysReadyInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ msg;
+
+ msg.type = WDA_SYS_READY_IND;
+ msg.reserved = 0;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+
+#ifdef VOSS_ENABLED
+ if(pMac->gDriverType != eDRIVER_TYPE_MFG)
+ {
+ peRegisterTLHandle(pMac);
+ }
+#endif
+ PELOGW(limLog(pMac, LOGW, FL("sending WDA_SYS_READY_IND msg to HAL\n"));)
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed\n"));
+ return eANI_BOOLEAN_TRUE;
+ }
+ return eANI_BOOLEAN_FALSE;
+}
+
+
+/**
+ * __limHandleSmeStartBssRequest()
+ *
+ *FUNCTION:
+ * This function is called to process SME_START_BSS_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 size;
+ tANI_U32 val = 0;
+ tSirRetStatus retStatus;
+ tSirMacChanNum channelNumber;
+ tLimMlmStartReq *pMlmStartReq;
+ tpSirSmeStartBssReq pSmeStartBssReq; //Local variable for Start BSS Req.. Added For BT-AMP Support
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tANI_U32 autoGenBssId = FALSE; //Flag Used in case of IBSS to Auto generate BSSID.
+ tSirMacHTChannelWidth txWidthSet;
+ tANI_U8 sessionId;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ //Since the session is not created yet, sending NULL. The response should have the correct state.
+ limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_REQ_EVENT, NULL, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ PELOG1(limLog(pMac, LOG1, FL("Received START_BSS_REQ\n"));)
+
+ /* Global Sme state and mlm states are not defined yet , for BT-AMP Suppoprt . TO BE DONE */
+ if ( (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
+ (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE))
+ {
+ size = sizeof(tSirSmeStartBssReq) + SIR_MAC_MAX_IE_LENGTH;
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ size + = ANI_WDS_INFO_MAX_LENGTH;
+#endif
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSmeStartBssReq, size))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed for pMac->lim.gpLimStartBssReq\n"));)
+ /// Send failure response to host
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ (void) palZeroMemory(pMac->hHdd, (void *)pSmeStartBssReq, size);
+
+ if ((limStartBssReqSerDes(pMac, pSmeStartBssReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ (!limIsSmeStartBssReqValid(pMac, pSmeStartBssReq)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ\n"));)
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto free;
+ }
+#if 0
+ PELOG3(limLog(pMac, LOG3,
+ FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d\n"),
+ pMac->lim.gpLimStartBssReq->bssType, pMac->lim.gpLimStartBssReq->channelId);)
+#endif
+
+ /* This is the place where PE is going to create a session.
+ * If session is not existed , then create a new session */
+ if((psessionEntry = peFindSessionByBssid(pMac,pSmeStartBssReq->bssId,&sessionId)) != NULL)
+ {
+ limLog(pMac, LOGW, FL("Session Already exists for given BSSID\n"));
+ retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ psessionEntry = NULL;
+ goto free;
+ }
+ else
+ {
+ if((psessionEntry = peCreateSession(pMac,pSmeStartBssReq->bssId,&sessionId, pMac->lim.maxStation)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("Session Can not be created \n"));
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+
+ }
+
+ /* Store the session related parameters in newly created session */
+ psessionEntry->pLimStartBssReq = pSmeStartBssReq;
+
+ /* Store PE sessionId in session Table */
+ psessionEntry->peSessionId = sessionId;
+
+ /* Store SME session Id in sessionTable */
+ psessionEntry->smeSessionId = pSmeStartBssReq->sessionId;
+
+ psessionEntry->transactionId = pSmeStartBssReq->transactionId;
+
+ sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeStartBssReq->selfMacAddr);
+
+ /* Copy SSID to session table */
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)&psessionEntry->ssId,
+ (tANI_U8 *)&pSmeStartBssReq->ssId,
+ (pSmeStartBssReq->ssId.length + 1));
+
+
+
+ psessionEntry->bssType = pSmeStartBssReq->bssType;
+
+ psessionEntry->nwType = pSmeStartBssReq->nwType;
+
+ psessionEntry->beaconParams.beaconInterval = pSmeStartBssReq->beaconInterval;
+
+ /* Store the channel number in session Table */
+ psessionEntry->currentOperChannel = pSmeStartBssReq->channelId;
+
+ /*Store Persona */
+ psessionEntry->pePersona = pSmeStartBssReq->bssPersona;
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,FL("PE PERSONA=%d\n"),
+ psessionEntry->pePersona);
+
+ /*Update the phymode*/
+ psessionEntry->gLimPhyMode = pSmeStartBssReq->nwType;
+
+ psessionEntry->maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac,
+ psessionEntry->currentOperChannel );
+ /* Store the dot 11 mode in to the session Table*/
+
+ psessionEntry->dot11mode = pSmeStartBssReq->dot11mode;
+ psessionEntry->htCapabality = IS_DOT11_MODE_HT(psessionEntry->dot11mode);
+
+ palCopyMemory(pMac->hHdd, (void*)&psessionEntry->rateSet,
+ (void*)&pSmeStartBssReq->operationalRateSet,
+ sizeof(tSirMacRateSet));
+ palCopyMemory(pMac->hHdd, (void*)&psessionEntry->extRateSet,
+ (void*)&pSmeStartBssReq->extendedRateSet,
+ sizeof(tSirMacRateSet));
+
+ switch(pSmeStartBssReq->bssType)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ case eSIR_INFRA_AP_MODE:
+ psessionEntry->limSystemRole = eLIM_AP_ROLE;
+ psessionEntry->privacy = pSmeStartBssReq->privacy;
+ psessionEntry->fwdWPSPBCProbeReq = pSmeStartBssReq->fwdWPSPBCProbeReq;
+ psessionEntry->authType = pSmeStartBssReq->authType;
+ /* Store the DTIM period */
+ psessionEntry->dtimPeriod = (tANI_U8)pSmeStartBssReq->dtimPeriod;
+ /*Enable/disable UAPSD*/
+ psessionEntry->apUapsdEnable = pSmeStartBssReq->apUapsdEnable;
+ if (psessionEntry->pePersona == VOS_P2P_GO_MODE)
+ {
+ psessionEntry->proxyProbeRspEn = 0;
+ }
+ else
+ {
+ /* To detect PBC overlap in SAP WPS mode, Host handles
+ * Probe Requests.
+ */
+ if(SAP_WPS_DISABLED == pSmeStartBssReq->wps_state)
+ {
+ psessionEntry->proxyProbeRspEn = 1;
+ }
+ else
+ {
+ psessionEntry->proxyProbeRspEn = 0;
+ }
+ }
+ psessionEntry->ssidHidden = pSmeStartBssReq->ssidHidden;
+ psessionEntry->wps_state = pSmeStartBssReq->wps_state;
+ break;
+#endif
+ case eSIR_IBSS_MODE:
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+ break;
+
+ case eSIR_BTAMP_AP_MODE:
+ psessionEntry->limSystemRole = eLIM_BT_AMP_AP_ROLE;
+ break;
+
+ case eSIR_BTAMP_STA_MODE:
+ psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ break;
+
+ /* There is one more mode called auto mode. which is used no where */
+
+ //FORBUILD -TEMPFIX.. HOW TO use AUTO MODE?????
+
+
+ default:
+ //not used anywhere...used in scan function
+ break;
+ }
+
+ // BT-AMP: Allocate memory for the array of parsed (Re)Assoc request structure
+ if ( (pSmeStartBssReq->bssType == eSIR_BTAMP_AP_MODE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (pSmeStartBssReq->bssType == eSIR_INFRA_AP_MODE)
+#endif
+ )
+ {
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&psessionEntry->parsedAssocReq,
+ (psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)) ))
+ {
+ limLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+ palZeroMemory(pMac->hHdd, psessionEntry->parsedAssocReq, (psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)) );
+ }
+
+ /* Channel Bonding is not addressd yet for BT-AMP Support.. sunit will address channel bonding */
+ if (pSmeStartBssReq->channelId)
+ {
+ channelNumber = pSmeStartBssReq->channelId;
+ /*Update cbMode received from sme with LIM's updated cbMode*/
+ pSmeStartBssReq->cbMode = (tAniCBSecondaryMode)pMac->lim.gCbMode;
+
+ setupCBState( pMac, pSmeStartBssReq->cbMode );
+ pMac->lim.gHTSecondaryChannelOffset = limGetHTCBState(pSmeStartBssReq->cbMode);
+#ifdef WLAN_SOFTAP_FEATURE
+ txWidthSet = (tSirMacHTChannelWidth)limGetHTCapability(pMac, eHT_RECOMMENDED_TX_WIDTH_SET, psessionEntry);
+#else
+ txWidthSet = (tSirMacHTChannelWidth)limGetHTCapability(pMac, eHT_RECOMMENDED_TX_WIDTH_SET);
+#endif
+
+ /*
+ * If there is a mismatch in secondaryChannelOffset being passed in the START_BSS request and
+ * ChannelBonding CFG, then MAC will override the 'ChannelBonding' CFG with what is being passed
+ * in StartBss Request.
+ * HAL RA and PHY will go out of sync, if both these values are not consistent and will result in TXP Errors
+ * when HAL RA tries to use 40Mhz rates when CB is turned off in PHY.
+ */
+ if(((pMac->lim.gHTSecondaryChannelOffset == eHT_SECONDARY_CHANNEL_OFFSET_NONE) &&
+ (txWidthSet == eHT_CHANNEL_WIDTH_40MHZ)) ||
+ ((pMac->lim.gHTSecondaryChannelOffset != eHT_SECONDARY_CHANNEL_OFFSET_NONE) &&
+ (txWidthSet == eHT_CHANNEL_WIDTH_20MHZ)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("secondaryChannelOffset and txWidthSet don't match, resetting txWidthSet CFG\n"));)
+ txWidthSet = (txWidthSet == eHT_CHANNEL_WIDTH_20MHZ) ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
+ if (cfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, txWidthSet)
+ != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not set WNI_CFG_CHANNEL_BONDING_MODE at CFG\n"));
+ retCode = eSIR_LOGP_EXCEPTION;
+ goto free;
+ }
+ }
+ }
+
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ\n"));)
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto free;
+ }
+
+ // Delete pre-auth list if any
+ limDeletePreAuthList(pMac);
+
+ // Delete IBSS peer BSSdescription list if any
+ //limIbssDelete(pMac); sep 26 review
+
+
+
+#ifdef FIXME_GEN6 //following code may not be required. limInitMlm is now being invoked during peStart
+ /// Initialize MLM state machine
+#ifdef ANI_PRODUCT_TYPE_AP
+ /* The Role is not set yet. Currently assuming the AddBss in Linux will be called by AP only.
+ * This should be handled when IBSS functionality is implemented in the Linux
+ * TODO */
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+#else
+ limInitMlm(pMac);
+#endif
+#endif
+
+ psessionEntry->htCapabality = IS_DOT11_MODE_HT(pSmeStartBssReq->dot11mode);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ /* keep the RSN/WPA IE information in PE Session Entry
+ * later will be using this to check when received (Re)Assoc req
+ * */
+ limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac,&pSmeStartBssReq->rsnIE,psessionEntry);
+
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ //Taken care for only softAP case rest need to be done
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ psessionEntry->gLimProtectionControl = pSmeStartBssReq->protEnabled;
+ /*each byte will have the following info
+ *bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ *reserved reserved RIFS Lsig n-GF ht20 11g 11b*/
+ palCopyMemory( pMac->hHdd, (void *) &psessionEntry->cfgProtection,
+ (void *) &pSmeStartBssReq->ht_capab,
+ sizeof( tCfgProtection ));
+ psessionEntry->pAPWPSPBCSession = NULL; // Initialize WPS PBC session link list
+ }
+#endif
+
+ // Prepare and Issue LIM_MLM_START_REQ to MLM
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmStartReq, sizeof(tLimMlmStartReq)))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for mlmStartReq\n"));
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+
+ (void)palZeroMemory(pMac->hHdd, (void *) pMlmStartReq, sizeof(tLimMlmStartReq));
+
+ /* Copy SSID to the MLM start structure */
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmStartReq->ssId,
+ (tANI_U8 *) &pSmeStartBssReq->ssId,
+ pSmeStartBssReq->ssId.length + 1);
+#ifdef WLAN_SOFTAP_FEATURE
+ pMlmStartReq->ssidHidden = pSmeStartBssReq->ssidHidden;
+ pMlmStartReq->obssProtEnabled = pSmeStartBssReq->obssProtEnabled;
+#endif
+
+
+ pMlmStartReq->bssType = psessionEntry->bssType;
+
+ /* Fill PE session Id from the session Table */
+ pMlmStartReq->sessionId = psessionEntry->peSessionId;
+
+ if( (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE) || (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE )
+#ifdef WLAN_SOFTAP_FEATURE
+ || (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE)
+#endif
+ )
+ {
+ //len = sizeof(tSirMacAddr);
+ //retStatus = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8 *) pMlmStartReq->bssId, &len);
+ //if (retStatus != eSIR_SUCCESS)
+ //limLog(pMac, LOGP, FL("could not retrive BSSID, retStatus=%d\n"), retStatus);
+
+ /* Copy the BSSId from sessionTable to mlmStartReq struct */
+ sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId);
+ }
+
+ else // ibss mode
+ {
+ pMac->lim.gLimIbssCoalescingHappened = false;
+
+ if((retStatus = wlan_cfgGetInt(pMac, WNI_CFG_IBSS_AUTO_BSSID, &autoGenBssId)) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not retrieve Auto Gen BSSID, retStatus=%d\n"), retStatus);
+ retCode = eSIR_LOGP_EXCEPTION;
+ goto free;
+ }
+
+ if(!autoGenBssId)
+ {
+ // We're not auto generating BSSID. Instead, get it from session entry
+ sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId);
+
+ if(pMlmStartReq->bssId[0] & 0x01)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Request to start IBSS with group BSSID\n Autogenerating the BSSID\n"));)
+ autoGenBssId = TRUE;
+ }
+ }
+
+ if( autoGenBssId )
+ { //if BSSID is not any uc id. then use locally generated BSSID.
+ //Autogenerate the BSSID
+ limGetRandomBssid( pMac, pMlmStartReq->bssId);
+ pMlmStartReq->bssId[0]= 0x02;
+
+ /* Copy randomly generated BSSID to the session Table */
+ sirCopyMacAddr(psessionEntry->bssId,pMlmStartReq->bssId);
+ }
+ }
+ /* store the channel num in mlmstart req structure */
+ pMlmStartReq->channelNumber = psessionEntry->currentOperChannel;
+ pMlmStartReq->cbMode = pSmeStartBssReq->cbMode;
+ pMlmStartReq->beaconPeriod = psessionEntry->beaconParams.beaconInterval;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){
+ pMlmStartReq->dtimPeriod = psessionEntry->dtimPeriod;
+ pMlmStartReq->wps_state = psessionEntry->wps_state;
+
+ }else
+#endif
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve DTIM Period\n"));
+ pMlmStartReq->dtimPeriod = (tANI_U8)val;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve Beacon interval\n"));
+ pMlmStartReq->cfParamSet.cfpPeriod = (tANI_U8)val;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve CFPMaxDuration\n"));
+ pMlmStartReq->cfParamSet.cfpMaxDuration = (tANI_U16) val;
+
+ //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context.
+ palCopyMemory(pMac->hHdd, (void*)&pMlmStartReq->rateSet, (void*)&psessionEntry->rateSet,
+ sizeof(tSirMacRateSet));
+
+
+ // Now populate the 11n related parameters
+ pMlmStartReq->nwType = psessionEntry->nwType;
+ pMlmStartReq->htCapable = psessionEntry->htCapabality;
+ //
+ // FIXME_GEN4 - Determine the appropriate defaults...
+ //
+ pMlmStartReq->htOperMode = pMac->lim.gHTOperMode;
+ pMlmStartReq->dualCTSProtection = pMac->lim.gHTDualCTSProtection; // Unused
+ pMlmStartReq->txChannelWidthSet = pMac->lim.gHTRecommendedTxWidthSet;
+
+ //Update the global LIM parameter, which is used to populate HT Info IEs in beacons/probe responses.
+ pMac->lim.gHTSecondaryChannelOffset = limGetHTCBState(pMlmStartReq->cbMode);
+
+ /* sep26 review */
+ psessionEntry->limRFBand = limGetRFBand(channelNumber);
+
+ // Initialize 11h Enable Flag
+ psessionEntry->lim11hEnable = 0;
+ if((pMlmStartReq->bssType != eSIR_IBSS_MODE) &&
+ (SIR_BAND_5_GHZ == psessionEntry->limRFBand) )
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED \n"));
+ psessionEntry->lim11hEnable = val;
+ }
+
+ if (!psessionEntry->lim11hEnable)
+ {
+ if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED \n"));
+ }
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ PELOGE(limLog(pMac, LOGE, FL("Dot 11h is %s\n"), pMac->lim.gLim11hEnable?"Enabled":"Disabled");)
+ if (pMac->lim.gLim11hEnable)
+ {
+ PELOG2(limLog(pMac, LOG2, FL("Cb state = %d, SecChanOffset = %d\n"),
+ pMac->lim.gCbState, pMac->lim.gHTSecondaryChannelOffset);)
+ limRadarInit(pMac);
+ }
+#endif
+ psessionEntry ->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry ->limSmeState = eLIM_SME_WT_START_BSS_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ limPostMlmMessage(pMac, LIM_MLM_START_REQ, (tANI_U32 *) pMlmStartReq);
+ return;
+ }
+ else
+ {
+
+ limLog(pMac, LOGE, FL("Received unexpected START_BSS_REQ, in state %X\n"),pMac->lim.gLimSmeState);
+ retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ goto end;
+ } // if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
+
+free:
+ palFreeMemory( pMac->hHdd, pSmeStartBssReq);
+ pSmeStartBssReq = NULL;
+
+end:
+
+ /* This routine should return the sme sessionId and SME transaction Id */
+ limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if(NULL != psessionEntry)
+ {
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+ limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, retCode,psessionEntry,smesessionId,smetransactionId);
+} /*** end __limHandleSmeStartBssRequest() ***/
+
+
+/**--------------------------------------------------------------
+\fn __limProcessSmeStartBssReq
+
+\brief Wrapper for the function __limHandleSmeStartBssRequest
+ This message will be defered until softmac come out of
+ scan mode or if we have detected radar on the current
+ operating channel.
+\param pMac
+\param pMsg
+
+\return TRUE - If we consumed the buffer
+ FALSE - If have defered the message.
+ ---------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limProcessSmeStartBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (__limIsDeferedMsgForLearn(pMac, pMsg) ||
+ __limIsDeferedMsgForRadar(pMac, pMsg))
+ {
+ /**
+ * If message defered, buffer is not consumed yet.
+ * So return false
+ */
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ __limHandleSmeStartBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr);
+ return eANI_BOOLEAN_TRUE;
+}
+
+
+/**
+ * limGetRandomBssid()
+ *
+ * FUNCTION:This function is called to process generate the random number for bssid
+ * This function is called to process SME_SCAN_REQ message
+ * from HDD or upper layer application.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ * 1. geneartes the unique random number for bssid in ibss
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *data Pointer to bssid buffer
+ * @return None
+ */
+void limGetRandomBssid(tpAniSirGlobal pMac, tANI_U8 *data)
+{
+ tANI_U32 random[2] ;
+ random[0] = tx_time_get();
+ random[0] |= (random[0] << 15) ;
+ random[1] = random[0] >> 1;
+ palCopyMemory(pMac->hHdd, data, (tANI_U8*)random, sizeof(tSirMacAddr));
+}
+
+
+/**
+ * __limProcessSmeScanReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_SCAN_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * 1. Periodic scanning should be requesting to return unique
+ * scan results.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U32 len;
+ tLimMlmScanReq *pMlmScanReq;
+ tpSirSmeScanReq pScanReq;
+ tANI_U8 i = 0;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ pScanReq = (tpSirSmeScanReq) pMsgBuf;
+ PELOG1(limLog(pMac, LOG1, FL("SME SCAN REQ numChan %d min %d max %d IELen %d first %d fresh %d unique %d type %d rsp %d\n"),
+ pScanReq->channelList.numChannels,
+ pScanReq->minChannelTime,
+ pScanReq->maxChannelTime,
+ pScanReq->uIEFieldLen,
+ pScanReq->returnAfterFirstMatch,
+ pScanReq->returnFreshResults,
+ pScanReq->returnUniqueResults,
+ pScanReq->scanType, pMac->lim.gLimRspReqd ? 1 : 0);)
+
+ /*copy the Self MAC address from SmeReq to the globalplace , used for sending probe req.discussed on code review sep18*/
+ sirCopyMacAddr(pMac->lim.gSelfMacAddr, pScanReq->selfMacAddr);
+
+ /* This routine should return the sme sessionId and SME transaction Id */
+
+ if (!limIsSmeScanReqValid(pMac, pScanReq))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Received SME_SCAN_REQ with invalid parameters\n"));)
+
+ if (pMac->lim.gLimRspReqd)
+ {
+ pMac->lim.gLimRspReqd = false;
+
+ limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId);
+
+ } // if (pMac->lim.gLimRspReqd)
+
+ return;
+ }
+
+ //if scan is disabled then return as invalid scan request.
+ //if scan in power save is disabled, and system is in power save mode, then ignore scan request.
+ if( (pMac->lim.fScanDisabled) || (!pMac->lim.gScanInPowersave && !limIsSystemInActiveState(pMac)) )
+ {
+ limSendSmeScanRsp(pMac, 8, eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId);
+ return;
+ }
+
+
+ /**
+ * If scan request is received in idle, joinFailed
+ * states or in link established state (in STA role)
+ * or in normal state (in STA-in-IBSS/AP role) with
+ * 'return fresh scan results' request from HDD or
+ * it is periodic background scanning request,
+ * trigger fresh scan request to MLM
+ */
+ if (__limFreshScanReqd(pMac, pScanReq->returnFreshResults))
+ {
+ #if 0
+ // Update global SME state
+ pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
+ if ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ||
+ (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE))
+ pMac->lim.gLimSmeState = eLIM_SME_WT_SCAN_STATE;
+ else if (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE)
+ pMac->lim.gLimSmeState = eLIM_SME_NORMAL_CHANNEL_SCAN_STATE;
+ else
+
+ #endif //TO SUPPORT BT-AMP
+
+ /*Change Global SME state */
+
+ /* Store the previous SME state */
+
+ pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
+
+ pMac->lim.gLimSmeState = eLIM_SME_WT_SCAN_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS)
+ {
+ // Discard previously cached scan results
+ limReInitScanResults(pMac);
+ }
+
+ pMac->lim.gLim24Band11dScanDone = 0;
+ pMac->lim.gLim50Band11dScanDone = 0;
+ pMac->lim.gLimReturnAfterFirstMatch =
+ pScanReq->returnAfterFirstMatch;
+
+ pMac->lim.gLimReturnUniqueResults =
+ ((pScanReq->returnUniqueResults) > 0 ? true : false);
+ /* De-activate Heartbeat timers for connected sessions while
+ * scan is in progress if the system is in Active mode */
+ if((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) ||
+ (ePMM_STATE_READY == pMac->pmm.gPmmState))
+ {
+ for(i=0;i<pMac->lim.maxBssId;i++)
+ {
+ if((pMac->lim.gpSession[i].valid == TRUE) &&
+ (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState))
+ {
+ limHeartBeatDeactivateAndChangeTimer(pMac, peFindSessionBySessionId(pMac,i));
+ }
+ }
+ }
+
+ if (pScanReq->channelList.numChannels == 0)
+ {
+ tANI_U32 cfg_len;
+ // Scan all channels
+ len = sizeof(tLimMlmScanReq) +
+ (sizeof( pScanReq->channelList.channelNumber ) * (WNI_CFG_VALID_CHANNEL_LIST_LEN - 1)) +
+ pScanReq->uIEFieldLen;
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmScanReq, len) )
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmScanReq (%d)\n"), len);
+
+ return;
+ }
+
+ // Initialize this buffer
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pMlmScanReq, len );
+
+ cfg_len = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+ pMlmScanReq->channelList.channelNumber,
+ &cfg_len) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Valid channel list from CFG.
+ * Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Valid channel list\n"));
+ }
+ pMlmScanReq->channelList.numChannels = (tANI_U8) cfg_len;
+ }
+ else
+ {
+ len = sizeof( tLimMlmScanReq ) - sizeof( pScanReq->channelList.channelNumber ) +
+ (sizeof( pScanReq->channelList.channelNumber ) * pScanReq->channelList.numChannels ) +
+ pScanReq->uIEFieldLen;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmScanReq, len) )
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmScanReq(%d)\n"), len);
+
+ return;
+ }
+
+ // Initialize this buffer
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pMlmScanReq, len);
+ pMlmScanReq->channelList.numChannels =
+ pScanReq->channelList.numChannels;
+
+ palCopyMemory( pMac->hHdd, pMlmScanReq->channelList.channelNumber,
+ pScanReq->channelList.channelNumber,
+ pScanReq->channelList.numChannels);
+ }
+
+ pMlmScanReq->uIEFieldLen = pScanReq->uIEFieldLen;
+ pMlmScanReq->uIEFieldOffset = len - pScanReq->uIEFieldLen;
+
+ if(pScanReq->uIEFieldLen)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)pMlmScanReq+ pMlmScanReq->uIEFieldOffset,
+ (tANI_U8 *)pScanReq+(pScanReq->uIEFieldOffset),
+ pScanReq->uIEFieldLen);
+ }
+
+ pMlmScanReq->bssType = pScanReq->bssType;
+ palCopyMemory( pMac->hHdd, pMlmScanReq->bssId,
+ pScanReq->bssId,
+ sizeof(tSirMacAddr));
+ pMlmScanReq->numSsid = pScanReq->numSsid;
+
+ i = 0;
+ while (i < pMlmScanReq->numSsid)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmScanReq->ssId[i],
+ (tANI_U8 *) &pScanReq->ssId[i],
+ pScanReq->ssId[i].length + 1);
+
+ i++;
+ }
+
+
+ pMlmScanReq->scanType = pScanReq->scanType;
+ pMlmScanReq->backgroundScanMode = pScanReq->backgroundScanMode;
+ pMlmScanReq->minChannelTime = pScanReq->minChannelTime;
+ pMlmScanReq->maxChannelTime = pScanReq->maxChannelTime;
+ pMlmScanReq->dot11mode = pScanReq->dot11mode;
+#ifdef WLAN_FEATURE_P2P
+ pMlmScanReq->p2pSearch = pScanReq->p2pSearch;
+#endif
+
+ //Store the smeSessionID and transaction ID for later use.
+ pMac->lim.gSmeSessionId = pScanReq->sessionId;
+ pMac->lim.gTransactionId = pScanReq->transactionId;
+
+ // Issue LIM_MLM_SCAN_REQ to MLM
+ limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq);
+
+ } // if ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ...
+
+ else
+ {
+ /// In all other cases return 'cached' scan results
+ if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults)
+ {
+ tANI_U16 scanRspLen = sizeof(tSirSmeScanRsp);
+
+ pMac->lim.gLimRspReqd = false;
+
+ if (pMac->lim.gLimSmeScanResultLength == 0)
+ {
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pScanReq->sessionId, pScanReq->transactionId);
+ }
+ else
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp) +
+ pMac->lim.gLimSmeScanResultLength -
+ sizeof(tSirBssDescription);
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pScanReq->sessionId, pScanReq->transactionId);
+ }
+
+ if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS)
+ {
+ // Discard previously cached scan results
+ limReInitScanResults(pMac);
+ }
+
+ } // if (pMac->lim.gLimRspReqd)
+ } // else ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ...
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+#ifdef BACKGROUND_SCAN_ENABLED
+ // start background scans if needed
+ // There is a bug opened against softmac. Need to enable when the bug is fixed.
+ __limBackgroundScanInitiate(pMac);
+#endif
+#endif
+
+} /*** end __limProcessSmeScanReq() ***/
+
+
+
+
+/**
+ * __limProcessSmeJoinReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_JOIN_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ // tANI_U8 *pBuf;
+ //tANI_U32 len;
+// tSirMacAddr currentBssId;
+ tpSirSmeJoinReq pSmeJoinReq = NULL;
+ tLimMlmJoinReq *pMlmJoinReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tANI_U32 val = 0;
+ tANI_U16 nSize;
+ tANI_U8 sessionId;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+ tPowerdBm localPowerConstraint = 0, regMax = 0;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ //Not sending any session, since it is not created yet. The response whould have correct state.
+ limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ PELOG1(limLog(pMac, LOG1, FL("Received SME_JOIN_REQ\n"));)
+
+#ifdef WLAN_FEATURE_VOWIFI
+ /* Need to read the CFG here itself as this is used in limExtractAPCapability() below.
+ * This CFG is actually read in rrmUpdateConfig() which is called later. Because this is not
+ * read, RRM related path before calling rrmUpdateConfig() is not getting executed causing issues
+ * like not honoring power constraint on 1st association after driver loading. */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfg get rrm enabled failed\n"));
+ pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0;
+ val = 0;
+#endif /* WLAN_FEATURE_VOWIFI */
+
+ /**
+ * Expect Join request in idle state.
+ * Reassociate request is expected in link established state.
+ */
+
+ /* Global SME and LIM states are not defined yet for BT-AMP Support */
+ if(pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE)
+ {
+ nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8*) pMsgBuf);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSmeJoinReq, nSize))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for pSmeJoinReq\n"));
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ (void) palZeroMemory(pMac->hHdd, (void *) pSmeJoinReq, nSize);
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ handleHTCapabilityandHTInfo(pMac);
+#endif
+ if ((limJoinReqSerDes(pMac, pSmeJoinReq, (tANI_U8 *)pMsgBuf) == eSIR_FAILURE) ||
+ (!limIsSmeJoinReqValid(pMac, pSmeJoinReq)))
+ {
+ /// Received invalid eWNI_SME_JOIN_REQ
+ // Log the event
+ limLog(pMac, LOGW, FL("received SME_JOIN_REQ with invalid data\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ //pMac->lim.gpLimJoinReq = pSmeJoinReq; TO SUPPORT BT-AMP ,review os sep 23
+
+ /* check for the existence of start BSS session */
+#ifdef FIXME_GEN6
+ if(pSmeJoinReq->bsstype == eSIR_BTAMP_AP_MODE)
+ {
+ if(peValidateBtJoinRequest(pMac)!= TRUE)
+ {
+ limLog(pMac, LOGW, FL("Start Bss session not present::SME_JOIN_REQ in unexpected state\n"));
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ psessionEntry = NULL;
+ goto end;
+ }
+ }
+
+#endif
+
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId)) != NULL)
+ {
+ limLog(pMac, LOGE, FL("Session Already exists for given BSSID\n"));
+
+ if(psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)
+ {
+ // Received eWNI_SME_JOIN_REQ for same
+ // BSS as currently associated.
+ // Log the event and send success
+ PELOGW(limLog(pMac, LOGW, FL("Received SME_JOIN_REQ for currently joined BSS\n"));)
+ /// Send Join success response to host
+ retCode = eSIR_SME_SUCCESS;
+ goto end;
+ }
+ else
+ {
+ retCode = eSIR_SME_REFUSED;
+ psessionEntry = NULL;
+ goto end;
+ }
+ }
+ else /* Session Entry does not exist for given BSSId */
+ {
+ /* Try to Create a new session */
+ if((psessionEntry = peCreateSession(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId, pMac->lim.maxStation)) == NULL)
+ {
+ limLog(pMac, LOGE, FL("Session Can not be created \n"));
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ }
+
+ /* Store Session related parameters */
+ /* Store PE session Id in session Table */
+ psessionEntry->peSessionId = sessionId;
+
+ /* store the smejoin req handle in session table */
+ psessionEntry->pLimJoinReq = pSmeJoinReq;
+
+ /* Store SME session Id in sessionTable */
+ psessionEntry->smeSessionId = pSmeJoinReq->sessionId;
+
+ /* Store SME transaction Id in session Table */
+ psessionEntry->transactionId = pSmeJoinReq->transactionId;
+
+ /* Store beaconInterval */
+ psessionEntry->beaconParams.beaconInterval = pSmeJoinReq->bssDescription.beaconInterval;
+
+ /* Copying of bssId is already done, while creating session */
+ //sirCopyMacAddr(psessionEntry->bssId,pSmeJoinReq->bssId);
+ sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeJoinReq->selfMacAddr);
+ psessionEntry->bssType = pSmeJoinReq->bsstype;
+
+ psessionEntry->statypeForBss = STA_ENTRY_PEER;
+
+ /* Copy the dot 11 mode in to the session table */
+
+ psessionEntry->dot11mode = pSmeJoinReq->dot11mode;
+ psessionEntry->nwType = pSmeJoinReq->bssDescription.nwType;
+
+ /*Phy mode*/
+ psessionEntry->gLimPhyMode = pSmeJoinReq->bssDescription.nwType;
+
+ /* Copy The channel Id to the session Table */
+ psessionEntry->currentOperChannel = pSmeJoinReq->bssDescription.channelId;
+
+
+ /*Store Persona */
+ psessionEntry->pePersona = pSmeJoinReq->staPersona;
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+ FL("PE PERSONA=%d"), psessionEntry->pePersona);
+
+ /* Copy the SSID from smejoinreq to session entry */
+ psessionEntry->ssId.length = pSmeJoinReq->ssId.length;
+ palCopyMemory( pMac->hHdd,psessionEntry->ssId.ssId,pSmeJoinReq->ssId.ssId,psessionEntry->ssId.length);
+
+ /* Copy the SSID from smejoinreq to session entry */
+ psessionEntry->ssId.length = pSmeJoinReq->ssId.length;
+ palCopyMemory( pMac->hHdd,psessionEntry->ssId.ssId,pSmeJoinReq->ssId.ssId,psessionEntry->ssId.length);
+
+ // Determin 11r or CCX connection based on input from SME
+ // which inturn is dependent on the profile the user wants to connect
+ // to, So input is coming from supplicant
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ psessionEntry->is11Rconnection = pSmeJoinReq->is11Rconnection;
+#endif
+#ifdef FEATURE_WLAN_CCX
+ psessionEntry->isCCXconnection = pSmeJoinReq->isCCXconnection;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX
+ psessionEntry->isFastTransitionEnabled = pSmeJoinReq->isFastTransitionEnabled;
+#endif
+
+ if(psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
+ {
+ psessionEntry->limSystemRole = eLIM_STA_ROLE;
+ }
+ else if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE)
+ {
+ psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ }
+ else
+ {
+ /* Throw an error and return and make sure to delete the session.*/
+ limLog(pMac, LOGW, FL("received SME_JOIN_REQ with invalid bss type\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ if(pSmeJoinReq->addIEScan.length)
+ {
+ palCopyMemory(pMac->hHdd, &psessionEntry->pLimJoinReq->addIEScan,
+ &pSmeJoinReq->addIEScan, sizeof(tSirAddie));
+ }
+
+ if(pSmeJoinReq->addIEAssoc.length)
+ {
+ palCopyMemory(pMac->hHdd, &psessionEntry->pLimJoinReq->addIEAssoc,
+ &pSmeJoinReq->addIEAssoc, sizeof(tSirAddie));
+ }
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+
+ val = sizeof(tLimMlmJoinReq) + sizeof(tSirMacSSidIE) +
+ sizeof(tSirMacRateSetIE) + sizeof(tSirMacDsParamSetIE);
+#else
+ val = sizeof(tLimMlmJoinReq) + psessionEntry->pLimJoinReq->bssDescription.length + 2;
+#endif
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmJoinReq, val))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for mlmJoinReq\n"));
+ return;
+ }
+ (void) palZeroMemory(pMac->hHdd, (void *) pMlmJoinReq, val);
+
+ /* PE SessionId is stored as a part of JoinReq*/
+ pMlmJoinReq->sessionId = psessionEntry->peSessionId;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, (tANI_U32 *) &pMlmJoinReq->joinFailureTimeout)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve JoinFailureTimer value\n"));
+
+ /* copy operational rate from psessionEntry*/
+ palCopyMemory(pMac->hHdd, (void*)&psessionEntry->rateSet, (void*)&pSmeJoinReq->operationalRateSet,
+ sizeof(tSirMacRateSet));
+ palCopyMemory(pMac->hHdd, (void*)&psessionEntry->extRateSet, (void*)&pSmeJoinReq->extendedRateSet,
+ sizeof(tSirMacRateSet));
+ //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context.
+ palCopyMemory(pMac->hHdd, (void*)&pMlmJoinReq->operationalRateSet, (void*)&psessionEntry->rateSet,
+ sizeof(tSirMacRateSet));
+
+ psessionEntry->encryptType = pSmeJoinReq->UCEncryptionType;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ palCopyMemory( pMac->hHdd, pMlmJoinReq->bssDescription.bssId,
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].bssId,
+ sizeof(tSirMacAddr));
+
+ pMlmJoinReq->bssDescription.capabilityInfo = 1;
+
+ pMlmJoinReq->bssDescription.aniIndicator =
+ (tANI_U8) pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].wniIndicator;
+
+ pMlmJoinReq->bssDescription.nwType =
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].nwType;
+
+ pMlmJoinReq->bssDescription.channelId =
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].channelId;
+
+ limCopyNeighborInfoToCfg(pMac,
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0], psessionEntry);
+
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimCurrentBssId,
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].bssId,
+ sizeof(tSirMacAddr));
+
+ pMac->lim.gLimCurrentChannelId =
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].channelId;
+
+ pMac->lim.gLimCurrentBssCaps =
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].capabilityInfo;
+
+ pMac->lim.gLimCurrentTitanHtCaps =
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].titanHtCaps;
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pMac->lim.gLimCurrentSSID,
+ (tANI_U8 *) &pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].ssId,
+ pMac->lim.gpLimJoinReq->neighborBssList.bssList[0].ssId.length+1);
+#else
+ pMlmJoinReq->bssDescription.length = psessionEntry->pLimJoinReq->bssDescription.length;
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pMlmJoinReq->bssDescription.bssId,
+ (tANI_U8 *) &psessionEntry->pLimJoinReq->bssDescription.bssId,
+ psessionEntry->pLimJoinReq->bssDescription.length + 2);
+
+#if 0
+
+ pMac->lim.gLimCurrentChannelId =
+ psessionEntry->pLimJoinReq->bssDescription.channelId;
+#endif //oct 9th review remove globals
+
+
+ psessionEntry->limCurrentBssCaps =
+ psessionEntry->pLimJoinReq->bssDescription.capabilityInfo;
+
+
+ psessionEntry->limCurrentTitanHtCaps=
+ psessionEntry->pLimJoinReq->bssDescription.titanHtCaps;
+
+ regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );
+ localPowerConstraint = regMax;
+ limExtractApCapability( pMac,
+ (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields,
+ limGetIElenFromBssDescription(&psessionEntry->pLimJoinReq->bssDescription),
+ &psessionEntry->limCurrentBssQosCaps,
+ &psessionEntry->limCurrentBssPropCap,
+ &pMac->lim.gLimCurrentBssUapsd //TBD-RAJESH make gLimCurrentBssUapsd this session specific
+ , &localPowerConstraint
+ );
+#ifdef FEATURE_WLAN_CCX
+ psessionEntry->maxTxPower = limGetMaxTxPower(regMax, localPowerConstraint);
+#else
+ psessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) );
+#endif
+#if defined WLAN_VOWIFI_DEBUG
+ limLog( pMac, LOGE, "Regulatory max = %d, local power constraint = %d, max tx = %d", regMax, localPowerConstraint, psessionEntry->maxTxPower );
+#endif
+
+ if (pMac->lim.gLimCurrentBssUapsd)
+ {
+ pMac->lim.gUapsdPerAcBitmask = psessionEntry->pLimJoinReq->uapsdPerAcBitmask;
+ limLog( pMac, LOG1, FL("UAPSD flag for all AC - 0x%2x\n"), pMac->lim.gUapsdPerAcBitmask);
+
+ // resetting the dynamic uapsd mask
+ pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;
+ pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
+ }
+#endif
+
+ psessionEntry->limRFBand = limGetRFBand(psessionEntry->currentOperChannel);
+
+ // Initialize 11h Enable Flag
+ if(SIR_BAND_5_GHZ == psessionEntry->limRFBand)
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED \n"));
+ psessionEntry->lim11hEnable = val;
+ }
+ else
+ psessionEntry->lim11hEnable = 0;
+
+ //To care of the scenario when STA transitions from IBSS to Infrastructure mode.
+ pMac->lim.gLimIbssCoalescingHappened = false;
+
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_JOIN_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ PELOG1(limLog(pMac, LOG1, FL("SME JoinReq: SSID %d.%c%c%c%c%c%c\n"),
+ psessionEntry->ssId.length,
+ psessionEntry->ssId.ssId[0],
+ psessionEntry->ssId.ssId[1],
+ psessionEntry->ssId.ssId[2],
+ psessionEntry->ssId.ssId[3],
+ psessionEntry->ssId.ssId[4],
+ psessionEntry->ssId.ssId[5]);
+ limLog(pMac, LOG1, FL("Channel %d, BSSID %x:%x:%x:%x:%x:%x\n"),
+ psessionEntry->currentOperChannel,
+ psessionEntry->bssId[0],
+ psessionEntry->bssId[1],
+ psessionEntry->bssId[2],
+ psessionEntry->bssId[3],
+ psessionEntry->bssId[4],
+ psessionEntry->bssId[5]);)
+
+ /* Indicate whether spectrum management is enabled*/
+ psessionEntry->spectrumMgtEnabled =
+ pSmeJoinReq->spectrumMgtIndicator;
+ /* Issue LIM_MLM_JOIN_REQ to MLM */
+ limPostMlmMessage(pMac, LIM_MLM_JOIN_REQ, (tANI_U32 *) pMlmJoinReq);
+ return;
+
+ }
+ else
+ {
+ /* Received eWNI_SME_JOIN_REQ un expected state */
+ limLog(pMac, LOGE, FL("received unexpected SME_JOIN_REQ in state %X\n"), pMac->lim.gLimSmeState);
+ limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState);
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ psessionEntry = NULL;
+ goto end;
+
+ }
+
+end:
+ limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if(pSmeJoinReq)
+ {
+ palFreeMemory( pMac->hHdd, pSmeJoinReq);
+ pSmeJoinReq = NULL;
+ if (NULL != psessionEntry)
+ {
+ psessionEntry->pLimJoinReq = NULL;
+ }
+ }
+
+ if(retCode != eSIR_SME_SUCCESS)
+ {
+ if(NULL != psessionEntry)
+ {
+ peDeleteSession(pMac,psessionEntry);
+ psessionEntry = NULL;
+ }
+ }
+
+ limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry,smesessionId,smetransactionId);
+} /*** end __limProcessSmeJoinReq() ***/
+
+
+#ifdef FEATURE_WLAN_CCX
+tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower)
+{
+ tANI_U8 maxTxPower = 0;
+ tANI_U8 txPower = VOS_MIN( regMax , (apTxPower) );
+ if((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP))
+ maxTxPower = txPower;
+ else if (txPower < MIN_TX_PWR_CAP)
+ maxTxPower = MIN_TX_PWR_CAP;
+ else
+ maxTxPower = MAX_TX_PWR_CAP;
+
+ return (maxTxPower);
+}
+#endif
+
+
+#if 0
+/**
+ * __limProcessSmeAuthReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_AUTH_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+
+ tAniAuthType authMode;
+ tLimMlmAuthReq *pMlmAuthReq;
+ tpSirSmeAuthReq pSirSmeAuthReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ pSirSmeAuthReq = (tpSirSmeAuthReq) pMsgBuf;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pSirSmeAuthReq->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("Session Does not exist for given BssId\n"));
+ return;
+ }
+
+ if (!limIsSmeAuthReqValid(pSirSmeAuthReq))
+ {
+ limLog(pMac, LOGW,
+ FL("received invalid SME_AUTH_REQ message\n"));
+
+ /// Send AUTH failure response to host
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("RECEIVED AUTH_REQ\n"));)
+
+ /**
+ * Expect Auth request for STA in link established state
+ * or STA in IBSS mode in normal state.
+ */
+
+ if ((psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) ||
+ ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) &&
+ (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)))
+ {
+ if (pSirSmeAuthReq->authType == eSIR_AUTO_SWITCH)
+ authMode = eSIR_SHARED_KEY; // Try Shared Key first
+ else
+ authMode = pSirSmeAuthReq->authType;
+
+ // Trigger MAC based Authentication
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmAuthReq, sizeof(tLimMlmAuthReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmAuthReq\n"));
+ return;
+ }
+
+ pMac->lim.gLimPreAuthType = pSirSmeAuthReq->authType;
+
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_PRE_AUTH_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ // Store channel specified in auth request.
+ // This will be programmed later by MLM.
+ pMac->lim.gLimPreAuthChannelNumber =
+ (tSirMacChanNum)
+ pSirSmeAuthReq->channelNumber;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMac->lim.gLimPreAuthPeerAddr,
+ (tANI_U8 *) &pSirSmeAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmAuthReq->peerMacAddr,
+ (tANI_U8 *) &pSirSmeAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ pMlmAuthReq->authType = authMode;
+
+ /* Update PE session Id */
+ pMlmAuthReq->sessionId = sessionId;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmAuthReq->authFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthFailureTimeout value from CFG.
+ * Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value\n"));
+ }
+
+ limPostMlmMessage(pMac, LIM_MLM_AUTH_REQ, (tANI_U32 *) pMlmAuthReq);
+ return;
+ }
+ else
+ {
+ /// Should not have received eWNI_SME_AUTH_REQ
+ // Log the event
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_AUTH_REQ in state %X\n"),psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ /// Send AUTH failure response to host
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto end;
+ }
+
+end:
+ limSendSmeAuthRsp(pMac, retCode,
+ pSirSmeAuthReq->peerMacAddr,
+ pSirSmeAuthReq->authType,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS );
+
+} /*** end __limProcessSmeAuthReq() ***/
+#endif
+
+
+/**
+ * __limProcessSmeReassocReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_REASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 caps;
+ tANI_U32 val;
+ tpSirSmeReassocReq pReassocReq = NULL;
+ tLimMlmReassocReq *pMlmReassocReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 sessionId;
+ tANI_U8 smeSessionId;
+ tANI_U16 transactionId;
+ tPowerdBm localPowerConstraint = 0, regMax = 0;
+ tANI_U32 teleBcnEn = 0;
+
+
+ PELOG3(limLog(pMac, LOG3, FL("Received REASSOC_REQ\n"));)
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pReassocReq, __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) pMsgBuf)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for pReassocReq\n"));
+
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+
+ if ((limJoinReqSerDes(pMac, (tpSirSmeJoinReq) pReassocReq,
+ (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ (!limIsSmeJoinReqValid(pMac,
+ (tpSirSmeJoinReq) pReassocReq)))
+ {
+ /// Received invalid eWNI_SME_REASSOC_REQ
+ // Log the event
+ limLog(pMac, LOGW,
+ FL("received SME_REASSOC_REQ with invalid data\n"));
+
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pReassocReq->bssDescription.bssId,&sessionId))==NULL)
+ {
+ limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE);
+ limLog(pMac, LOGP, FL("Session does not exist for given bssId\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ //pMac->lim.gpLimReassocReq = pReassocReq;//TO SUPPORT BT-AMP
+
+ /* Store the reassoc handle in the session Table.. 23rd sep review */
+ psessionEntry->pLimReAssocReq = pReassocReq;
+
+ /**
+ * Reassociate request is expected
+ * in link established state only.
+ */
+
+ if (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)
+ {
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_CCX)
+ if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+ {
+ // May be from 11r FT pre-auth. So lets check it before we bail out
+ limLog(pMac, LOGE, FL("Session in reassoc state is %d\n"),
+ psessionEntry->peSessionId);
+
+ // Make sure its our preauth bssid
+ if (!palEqualMemory( pMac->hHdd, pReassocReq->bssDescription.bssId,
+ pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, 6))
+ {
+ limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE);
+ limPrintMacAddr(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE);
+ limLog(pMac, LOGP, FL("Unknown bssId in reassoc state\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ limProcessMlmFTReassocReq(pMac, pMsgBuf, psessionEntry);
+ return;
+ }
+#endif
+ /// Should not have received eWNI_SME_REASSOC_REQ
+ // Log the event
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_REASSOC_REQ in state %X\n"),
+ psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto end;
+ }
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ limCopyNeighborInfoToCfg(pMac,
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0],
+ psessionEntry);
+
+ palCopyMemory( pMac->hHdd,
+ pMac->lim.gLimReassocBssId,
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].bssId,
+ sizeof(tSirMacAddr));
+
+ pMac->lim.gLimReassocChannelId =
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].channelId;
+
+ pMac->lim.gLimReassocBssCaps =
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].capabilityInfo;
+
+ pMac->lim.gLimReassocTitanHtCaps =
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].titanHtCaps;
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pMac->lim.gLimReassocSSID,
+ (tANI_U8 *) &psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].ssId,
+ psessionEntry->pLimReAssocReq->neighborBssList.bssList[0].ssId.length+1);
+#else
+ palCopyMemory( pMac->hHdd,
+ psessionEntry->limReAssocbssId,
+ psessionEntry->pLimReAssocReq->bssDescription.bssId,
+ sizeof(tSirMacAddr));
+
+ psessionEntry->limReassocChannelId =
+ psessionEntry->pLimReAssocReq->bssDescription.channelId;
+
+ psessionEntry->limReassocBssCaps =
+ psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo;
+
+ psessionEntry->limReassocTitanHtCaps =
+ psessionEntry->pLimReAssocReq->bssDescription.titanHtCaps;
+
+ regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel );
+ localPowerConstraint = regMax;
+ limExtractApCapability( pMac,
+ (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
+ limGetIElenFromBssDescription(
+ &psessionEntry->pLimReAssocReq->bssDescription),
+ &psessionEntry->limReassocBssQosCaps,
+ &psessionEntry->limReassocBssPropCap,
+ &pMac->lim.gLimCurrentBssUapsd //TBD-RAJESH make gLimReassocBssUapsd session specific
+ , &localPowerConstraint
+ );
+
+ psessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) );
+#if defined WLAN_VOWIFI_DEBUG
+ limLog( pMac, LOGE, "Regulatory max = %d, local power constraint = %d, max tx = %d", regMax, localPowerConstraint, psessionEntry->maxTxPower );
+#endif
+ {
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SSID, pMac->lim.gLimReassocSSID.ssId,
+ &cfgLen) != eSIR_SUCCESS)
+ {
+ /// Could not get SSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrive SSID\n"));
+ }
+ #endif//TO SUPPORT BT-AMP
+
+ /* Copy the SSID from sessio entry to local variable */
+ #if 0
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimReassocSSID.ssId,
+ psessionEntry->ssId.ssId,
+ psessionEntry->ssId.length);
+ #endif
+ psessionEntry->limReassocSSID.length = pReassocReq->ssId.length;
+ palCopyMemory( pMac->hHdd, psessionEntry->limReassocSSID.ssId,
+ pReassocReq->ssId.ssId, psessionEntry->limReassocSSID.length);
+
+ }
+
+ if (pMac->lim.gLimCurrentBssUapsd)
+ {
+ pMac->lim.gUapsdPerAcBitmask = psessionEntry->pLimReAssocReq->uapsdPerAcBitmask;
+ limLog( pMac, LOG1, FL("UAPSD flag for all AC - 0x%2x\n"), pMac->lim.gUapsdPerAcBitmask);
+ }
+
+#endif
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmReassocReq, sizeof(tLimMlmReassocReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmReassocReq\n"));
+
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ palCopyMemory( pMac->hHdd, pMlmReassocReq->peerMacAddr,
+ psessionEntry->limReAssocbssId,
+ sizeof(tSirMacAddr));
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout)
+ != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve ReassocFailureTimeout value\n"));
+ }
+
+ if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Capabilities value\n"));
+ }
+ pMlmReassocReq->capabilityInfo = caps;
+
+ /* Update PE sessionId*/
+ pMlmReassocReq->sessionId = sessionId;
+
+ /* If telescopic beaconing is enabled, set listen interval to
+ WNI_CFG_TELE_BCN_MAX_LI */
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
+ eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN\n"));
+
+ val = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ if(teleBcnEn)
+ {
+ if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
+ eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve ListenInterval\n"));
+ }
+ }
+ else
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve ListenInterval\n"));
+ }
+ }
+
+ /* Delete all BA sessions before Re-Assoc.
+ * BA frames are class 3 frames and the session
+ * is lost upon disassociation and reassociation.
+ */
+
+ limDelAllBASessions(pMac);
+
+ pMlmReassocReq->listenInterval = (tANI_U16) val;
+
+ /* Indicate whether spectrum management is enabled*/
+ psessionEntry->spectrumMgtEnabled = pReassocReq->spectrumMgtIndicator;
+
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ limPostMlmMessage(pMac,
+ LIM_MLM_REASSOC_REQ,
+ (tANI_U32 *) pMlmReassocReq);
+ return;
+
+end:
+ if (pReassocReq)
+ palFreeMemory( pMac->hHdd, pReassocReq);
+
+ if (psessionEntry)
+ {
+ // error occurred after we determined the session so extract
+ // session and transaction info from there
+ smeSessionId = psessionEntry->smeSessionId;
+ transactionId = psessionEntry->transactionId;
+ }
+ else
+ {
+ // error occurred before or during the time we determined the session
+ // so extract the session and transaction info from the message
+ limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
+ }
+
+ /// Send Reassoc failure response to host
+ /// (note psessionEntry may be NULL, but that's OK)
+ limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP,
+ retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry, smeSessionId, transactionId);
+
+} /*** end __limProcessSmeReassocReq() ***/
+
+
+tANI_BOOLEAN sendDisassocFrame = 1;
+/**
+ * __limProcessSmeDisassocReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_DISASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 disassocTrigger, reasonCode;
+ tLimMlmDisassocReq *pMlmDisassocReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tSirSmeDisassocReq smeDisassocReq;
+ tpPESession psessionEntry = NULL;
+ tANI_U8 sessionId;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ PELOG1(limLog(pMac, LOG1,FL("received DISASSOC_REQ message\n"));)
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ retCode = limDisassocReqSerDes(pMac, &smeDisassocReq, (tANI_U8 *) pMsgBuf);
+
+ if ( (retCode == eSIR_FAILURE) ||(!limIsSmeDisassocReqValid(pMac, &smeDisassocReq, psessionEntry)) )
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("received invalid SME_DISASSOC_REQ message\n"));)
+
+ if (pMac->lim.gLimRspReqd)
+ {
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+
+ return;
+ }
+
+
+ PELOGE(limLog(pMac, LOGE, FL("received DISASSOC_REQ message. Reason: %d SmeState: %d\n"),
+ smeDisassocReq.reasonCode, pMac->lim.gLimSmeState);)
+
+
+ if((psessionEntry = peFindSessionByBssid(pMac,smeDisassocReq.bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry, 0, smeDisassocReq.reasonCode);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ /* Update SME session Id and SME transaction ID*/
+
+ psessionEntry->smeSessionId = smesessionId;
+ psessionEntry->transactionId = smetransactionId;
+
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (psessionEntry->limSmeState)
+ {
+ case eLIM_SME_ASSOCIATED_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ break;
+
+ case eLIM_SME_WT_DEAUTH_STATE:
+ /* PE shall still process the DISASSOC_REQ and proceed with
+ * link tear down even if it had already sent a DEAUTH_IND to
+ * to SME. pMac->lim.gLimPrevSmeState shall remain the same as
+ * its been set when PE entered WT_DEAUTH_STATE.
+ */
+ psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DEAUTH_STATE. \n"));
+ break;
+
+ case eLIM_SME_WT_DISASSOC_STATE:
+ /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it
+ * received DISASSOC_REQ. Which means host is also trying to disconnect.
+ * PE can continue processing DISASSOC_REQ and send the response instead
+ * of failing the request. SME will anyway ignore DEAUTH_IND that was sent
+ * for disassoc frame.
+ *
+ * It will send a disassoc, which is ok. However, we can use the global flag
+ * sendDisassoc to not send disassoc frame.
+ */
+ limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DISASSOC_STATE. \n"));
+ break;
+
+ case eLIM_SME_JOIN_FAILURE_STATE: {
+ /** Return Success as we are already in Disconnected State*/
+ if (pMac->lim.gLimRspReqd) {
+ retCode = eSIR_SME_SUCCESS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+ }break;
+ default:
+ /**
+ * STA is not currently associated.
+ * Log error and send response to host
+ */
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_REQ in state %X\n"),
+ psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ if (pMac->lim.gLimRspReqd)
+ {
+ if (psessionEntry->limSmeState !=
+ eLIM_SME_WT_ASSOC_STATE)
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+
+ return;
+ }
+
+ break;
+
+ case eLIM_AP_ROLE:
+ case eLIM_BT_AMP_AP_ROLE:
+ // Fall through
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ default: // eLIM_UNKNOWN_ROLE
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_REQ for role %d\n"),
+ psessionEntry->limSystemRole);
+
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ } // end switch (pMac->lim.gLimSystemRole)
+
+ if (smeDisassocReq.reasonCode == eLIM_LINK_MONITORING_DISASSOC)
+ {
+ /// Disassociation is triggered by Link Monitoring
+ disassocTrigger = eLIM_LINK_MONITORING_DISASSOC;
+ reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+ }
+ else
+ {
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ reasonCode = smeDisassocReq.reasonCode;
+ }
+
+ if (smeDisassocReq.doNotSendOverTheAir)
+ {
+ sendDisassocFrame = 0;
+ }
+ // Trigger Disassociation frame to peer MAC entity
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmDisassocReq, sizeof(tLimMlmDisassocReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmDisassocReq\n"));
+
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmDisassocReq->peerMacAddr,
+ (tANI_U8 *) &smeDisassocReq.peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ pMlmDisassocReq->reasonCode = reasonCode;
+ pMlmDisassocReq->disassocTrigger = disassocTrigger;
+
+ /* Update PE session ID*/
+ pMlmDisassocReq->sessionId = sessionId;
+#ifdef ANI_PRODUCT_TYPE_AP
+ pMlmDisassocReq->aid = smeDisassocReq.aid;
+#endif
+
+ limPostMlmMessage(pMac,
+ LIM_MLM_DISASSOC_REQ,
+ (tANI_U32 *) pMlmDisassocReq);
+ return;
+
+sendDisassoc:
+ if (psessionEntry)
+ limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr,
+ retCode,
+ disassocTrigger,
+#ifdef ANI_PRODUCT_TYPE_AP
+ smeDisassocReq.aid);
+#else
+ 1,smesessionId,smetransactionId,psessionEntry);
+#endif
+ else
+ limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr,
+ retCode,
+ disassocTrigger,
+#ifdef ANI_PRODUCT_TYPE_AP
+ smeDisassocReq.aid);
+#else
+ 1, 0, 0, NULL);
+#endif
+
+
+} /*** end __limProcessSmeDisassocReq() ***/
+
+
+/** -----------------------------------------------------------------
+ \brief __limProcessSmeDisassocCnf() - Process SME_DISASSOC_CNF
+
+ This function is called to process SME_DISASSOC_CNF message
+ from HDD or upper layer application.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+static void
+__limProcessSmeDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirSmeDisassocCnf smeDisassocCnf;
+ tANI_U16 aid;
+ tpDphHashNode pStaDs;
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+
+ PELOG1(limLog(pMac, LOG1, FL("received DISASSOC_CNF message\n"));)
+
+ status = limDisassocCnfSerDes(pMac, &smeDisassocCnf,(tANI_U8 *) pMsgBuf);
+
+ if (status == eSIR_FAILURE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("invalid SME_DISASSOC_CNF message\n"));)
+ return;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac, smeDisassocCnf.bssId, &sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));
+ return;
+ }
+
+ if (!limIsSmeDisassocCnfValid(pMac, &smeDisassocCnf, psessionEntry))
+ {
+ limLog(pMac, LOGW, FL("received invalid SME_DISASSOC_CNF message\n"));
+ return;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF)
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0);
+ else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF)
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE: //To test reconn
+ if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE))
+ {
+ limLog(pMac, LOGE,
+ FL("received unexp SME_DISASSOC_CNF in state %X\n"),
+ psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+ return;
+ }
+ break;
+
+ case eLIM_AP_ROLE:
+ // Fall through
+#ifdef WLAN_SOFTAP_FEATURE
+ break;
+#else
+ return;
+#endif
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ default: // eLIM_UNKNOWN_ROLE
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_CNF role %d\n"),
+ psessionEntry->limSystemRole);
+
+ return;
+ }
+
+
+ if ( (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE)
+#ifdef WLAN_SOFTAP_FEATURE
+ || (psessionEntry->limSystemRole == eLIM_AP_ROLE )
+#endif
+ )
+ {
+ pStaDs = dphLookupHashEntry(pMac, smeDisassocCnf.peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("received DISASSOC_CNF for a STA that does not have context, addr= "));
+ limPrintMacAddr(pMac, smeDisassocCnf.peerMacAddr, LOGW);)
+ return;
+ }
+ limCleanupRxPath(pMac, pStaDs, psessionEntry);
+ }
+
+ return;
+}
+
+
+/**
+ * __limProcessSmeDeauthReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_DEAUTH_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 deauthTrigger, reasonCode;
+ tLimMlmDeauthReq *pMlmDeauthReq;
+ tSirSmeDeauthReq smeDeauthReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionId
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ PELOG1(limLog(pMac, LOG1,FL("received DEAUTH_REQ message\n"));)
+
+ status = limDeauthReqSerDes(pMac, &smeDeauthReq,(tANI_U8 *) pMsgBuf);
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ //We need to get a session first but we don't even know if the message is correct.
+ if((psessionEntry = peFindSessionByBssid(pMac, smeDeauthReq.bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ deauthTrigger = eLIM_HOST_DEAUTH;
+ goto sendDeauth;
+
+ }
+
+ if ((status == eSIR_FAILURE) || (!limIsSmeDeauthReqValid(pMac, &smeDeauthReq, psessionEntry)))
+ {
+ PELOGE(limLog(pMac, LOGW,FL("received invalid SME_DEAUTH_REQ message\n"));)
+ if (pMac->lim.gLimRspReqd)
+ {
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ deauthTrigger = eLIM_HOST_DEAUTH;
+ goto sendDeauth;
+ }
+
+ return;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_REQ_EVENT, psessionEntry, 0, smeDeauthReq.reasonCode);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ /* Update SME session ID and Transaction ID */
+ psessionEntry->smeSessionId = smesessionId;
+ psessionEntry->transactionId = smetransactionId;
+
+
+ switch (psessionEntry->limSystemRole)
+ {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+
+ switch (psessionEntry->limSmeState)
+ {
+ case eLIM_SME_ASSOCIATED_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ case eLIM_SME_WT_ASSOC_STATE:
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ case eLIM_SME_IDLE_STATE:
+ psessionEntry->limPrevSmeState = psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ // Send Deauthentication request to MLM below
+
+ break;
+
+ default:
+ /**
+ * STA is not in a state to deauthenticate with
+ * peer. Log error and send response to host.
+ */
+ limLog(pMac, LOGE,
+ FL("received unexp SME_DEAUTH_REQ in state %X\n"),psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ if (pMac->lim.gLimRspReqd)
+ {
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_STA_NOT_AUTHENTICATED;
+ deauthTrigger = eLIM_HOST_DEAUTH;
+ goto sendDeauth;
+ }
+
+ return;
+ }
+
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+
+ return;
+
+ case eLIM_AP_ROLE:
+ // Fall through
+
+ break;
+
+ default:
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_DEAUTH_REQ for role %X\n"),psessionEntry->limSystemRole);
+
+ return;
+ } // end switch (pMac->lim.gLimSystemRole)
+
+ if (smeDeauthReq.reasonCode == eLIM_LINK_MONITORING_DEAUTH)
+ {
+ /// Deauthentication is triggered by Link Monitoring
+ PELOG1(limLog(pMac, LOG1, FL("**** Lost link with AP ****\n"));)
+ deauthTrigger = eLIM_LINK_MONITORING_DEAUTH;
+ reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+ }
+ else
+ {
+ deauthTrigger = eLIM_HOST_DEAUTH;
+ reasonCode = smeDeauthReq.reasonCode;
+ }
+
+ // Trigger Deauthentication frame to peer MAC entity
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmDeauthReq, sizeof(tLimMlmDeauthReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmDeauthReq\n"));
+
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmDeauthReq->peerMacAddr,
+ (tANI_U8 *) &smeDeauthReq.peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ pMlmDeauthReq->reasonCode = reasonCode;
+ pMlmDeauthReq->deauthTrigger = deauthTrigger;
+#ifdef ANI_PRODUCT_TYPE_AP
+ pMlmDeauthReq->aid = smeDeauthReq.aid;
+#endif
+
+ /* Update PE session Id*/
+ pMlmDeauthReq->sessionId = sessionId;
+
+ limPostMlmMessage(pMac,
+ LIM_MLM_DEAUTH_REQ,
+ (tANI_U32 *) pMlmDeauthReq);
+ return;
+
+sendDeauth:
+ limSendSmeDeauthNtf(pMac, smeDeauthReq.peerMacAddr,
+ retCode,
+ deauthTrigger,
+#ifdef ANI_PRODUCT_TYPE_AP
+ smeDeauthReq.aid,
+#else
+ 1,
+#endif
+ smesessionId, smetransactionId);
+} /*** end __limProcessSmeDeauthReq() ***/
+
+
+
+/**
+ * __limProcessSmeSetContextReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_SETCONTEXT_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeSetContextReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirSmeSetContextReq pSetContextReq;
+ tLimMlmSetKeysReq *pMlmSetKeysReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received SETCONTEXT_REQ message\n")););
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSetContextReq,
+ (sizeof(tSirKeys) * SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for pSetContextReq\n"));
+ return;
+ }
+
+ if ((limSetContextReqSerDes(pMac, pSetContextReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ (!limIsSmeSetContextReqValid(pMac, pSetContextReq)))
+ {
+ limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message\n"));
+ goto end;
+ }
+
+ if(pSetContextReq->keyMaterial.numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS\n"), pSetContextReq->keyMaterial.numKeys);)
+ limSendSmeSetContextRsp(pMac,
+ pSetContextReq->peerMacAddr,
+#ifdef ANI_PRODUCT_TYPE_AP
+ pSetContextReq->aid,
+#else
+ 1,
+#endif
+ eSIR_SME_INVALID_PARAMETERS,NULL,
+ smesessionId,smetransactionId);
+
+ goto end;
+ }
+
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pSetContextReq->bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("Session does not exist for given BSSID\n"));
+ limSendSmeSetContextRsp(pMac,
+ pSetContextReq->peerMacAddr,
+#ifdef ANI_PRODUCT_TYPE_AP
+ pSetContextReq->aid,
+#else
+ 1,
+#endif
+ eSIR_SME_INVALID_PARAMETERS,NULL,
+ smesessionId,smetransactionId);
+
+ goto end;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+
+ if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
+ (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
+ (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) &&
+ (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)))
+ {
+ // Trigger MLM_SETKEYS_REQ
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for mlmSetKeysReq\n"));
+ goto end;
+ }
+
+ pMlmSetKeysReq->edType = pSetContextReq->keyMaterial.edType;
+ pMlmSetKeysReq->numKeys = pSetContextReq->keyMaterial.numKeys;
+ if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
+ {
+ limLog(pMac, LOGP, FL("Num of keys exceeded max num of default keys limit\n"));
+ goto end;
+ }
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmSetKeysReq->peerMacAddr,
+ (tANI_U8 *) &pSetContextReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ pMlmSetKeysReq->aid = pSetContextReq->aid;
+#endif
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmSetKeysReq->key,
+ (tANI_U8 *) &pSetContextReq->keyMaterial.key,
+ sizeof(tSirKeys) * (pMlmSetKeysReq->numKeys ? pMlmSetKeysReq->numKeys : 1));
+
+ pMlmSetKeysReq->sessionId = sessionId;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(limLog(pMac, LOG1,
+ FL("received SETCONTEXT_REQ message sessionId=%d\n"), pMlmSetKeysReq->sessionId););
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) || (pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104))
+ && (psessionEntry->limSystemRole == eLIM_AP_ROLE))
+ {
+ if(pSetContextReq->keyMaterial.key[0].keyLength)
+ {
+ tANI_U8 keyId;
+ keyId = pSetContextReq->keyMaterial.key[0].keyId;
+ palCopyMemory(pMac, (tANI_U8 *)&psessionEntry->WEPKeyMaterial[keyId],
+ (tANI_U8 *) &pSetContextReq->keyMaterial, sizeof(tSirKeyMaterial));
+ }
+ else {
+ tANI_U32 i;
+ for( i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmSetKeysReq->key[i],
+ (tANI_U8 *)psessionEntry->WEPKeyMaterial[i].key, sizeof(tSirKeys));
+ }
+ }
+ }
+#endif
+
+ limPostMlmMessage(pMac, LIM_MLM_SETKEYS_REQ, (tANI_U32 *) pMlmSetKeysReq);
+
+#ifdef ANI_AP_SDK
+ /* For SDK acting as STA under Linux, need to consider the AP as *
+ * as authenticatated. */
+ if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
+ (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE))
+ {
+ tpDphHashNode pSta;
+ pSta = dphGetHashEntry(pMac, 0, &psessionEntry->dph.dphHashTable);
+ if (pSta)
+ pSta->staAuthenticated = 1;
+ }
+#endif
+ }
+ else
+ {
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_SETCONTEXT_REQ for role %d, state=%X\n"),
+ psessionEntry->limSystemRole,
+ psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ limSendSmeSetContextRsp(pMac, pSetContextReq->peerMacAddr,
+#ifdef ANI_PRODUCT_TYPE_AP
+ pSetContextReq->aid,
+#else
+ 1,
+#endif
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry,
+ smesessionId,
+ smetransactionId);
+ }
+
+end:
+ palFreeMemory( pMac->hHdd, pSetContextReq);
+ return;
+} /*** end __limProcessSmeSetContextReq() ***/
+
+/**
+ * __limProcessSmeRemoveKeyReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_REMOVEKEY_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirSmeRemoveKeyReq pRemoveKeyReq;
+ tLimMlmRemoveKeyReq *pMlmRemoveKeyReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received REMOVEKEY_REQ message\n"));)
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pRemoveKeyReq,
+ (sizeof(*pRemoveKeyReq))))
+ {
+ //Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for pRemoveKeyReq\n"));
+
+ return;
+ }
+
+ if ((limRemoveKeyReqSerDes(pMac,
+ pRemoveKeyReq,
+ (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
+ {
+ limLog(pMac, LOGW,
+ FL("received invalid SME_REMOVECONTEXT_REQ message\n"));
+
+ /* extra look up is needed since, session entry to be passed il limsendremovekey response */
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));
+ //goto end;
+ }
+
+ limSendSmeRemoveKeyRsp(pMac,
+ pRemoveKeyReq->peerMacAddr,
+ eSIR_SME_INVALID_PARAMETERS,psessionEntry,
+ smesessionId,smetransactionId);
+
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId, &sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,
+ FL("session does not exist for given bssId\n"));
+ limSendSmeRemoveKeyRsp(pMac,
+ pRemoveKeyReq->peerMacAddr,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, NULL,
+ smesessionId, smetransactionId);
+ goto end;
+ }
+
+
+ if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&&
+ (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
+ (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) ||
+ (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) &&
+ (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)))
+ {
+ // Trigger MLM_REMOVEKEYS_REQ
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmRemoveKeyReq, sizeof(tLimMlmRemoveKeyReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmRemoveKeysReq\n"));
+
+ goto end;
+ }
+
+ pMlmRemoveKeyReq->edType = (tAniEdType)pRemoveKeyReq->edType;
+ pMlmRemoveKeyReq->keyId = pRemoveKeyReq->keyId;
+ pMlmRemoveKeyReq->wepType = pRemoveKeyReq->wepType;
+ pMlmRemoveKeyReq->unicast = pRemoveKeyReq->unicast;
+
+ /* Update PE session Id */
+ pMlmRemoveKeyReq->sessionId = sessionId;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmRemoveKeyReq->peerMacAddr,
+ (tANI_U8 *) &pRemoveKeyReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+
+ limPostMlmMessage(pMac,
+ LIM_MLM_REMOVEKEY_REQ,
+ (tANI_U32 *) pMlmRemoveKeyReq);
+ }
+ else
+ {
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_REMOVEKEY_REQ for role %d, state=%X\n"),
+ psessionEntry->limSystemRole,
+ psessionEntry->limSmeState);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+
+ limSendSmeRemoveKeyRsp(pMac,
+ pRemoveKeyReq->peerMacAddr,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry,
+ smesessionId,smetransactionId);
+ }
+
+end:
+ palFreeMemory( pMac->hHdd, pRemoveKeyReq);
+} /*** end __limProcessSmeRemoveKeyReq() ***/
+
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * __limHandleSmeSwitchChlRequest()
+ *
+ *FUNCTION:
+ * This function is called to process the following SME messages
+ * received from HDD or WSM:
+ * - eWNI_SME_SWITCH_CHL_REQ
+ * - eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ
+ * - eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ
+ *
+ *ASSUMPTIONS:
+ *
+ * eWNI_SME_SWITCH_CHL_REQ is issued only when 11h is enabled,
+ * and WSM wishes to switch its primary channel. AP shall
+ * populate the 802.11h channel switch IE in its Beacons/Probe Rsp.
+ *
+ * eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ is issued only when 11h is enabled,
+ * and WSM wishes to switch both its primary channel and secondary channel.
+ * (In the case of if 11h is disabled, and WSM wants to change both
+ * primary & secondary channel, then WSM should issue a restart-BSS). AP
+ * shall populate the 802.11h channel switch IE in its Beacons/Probe Rsp.
+ *
+ * eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ is issued when WSM wishes to
+ * switch/disable only its secondary channel. This can occur when 11h
+ * is enabled or disabled. AP shall populate the airgo proprietary
+ * channel switch IE in its Beacons/Probe Rsp.
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limHandleSmeSwitchChlRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirSmeSwitchChannelReq pSmeMsg;
+ eHalStatus status;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, NULL, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE ||
+ pMac->lim.gLimSystemRole != eLIM_AP_ROLE ||
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
+ {
+ PELOGE(limLog(pMac, LOGE, "Rcvd Switch Chl Req in wrong state\n");)
+ limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_CHANNEL_SWITCH_FAIL);
+ return;
+ }
+
+ status = palAllocateMemory( pMac->hHdd, (void **)&pSmeMsg, sizeof(tSirSmeSwitchChannelReq));
+ if( eHAL_STATUS_SUCCESS != status)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed, status = %d\n"), status);)
+ return;
+ }
+
+ if (!limIsSmeSwitchChannelReqValid(pMac, (tANI_U8 *)pMsgBuf, pSmeMsg))
+ {
+ limLog(pMac, LOGE,
+ FL("invalid sme message received\n"));
+ palFreeMemory( pMac->hHdd, pSmeMsg);
+ limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_INVALID_PARAMETERS);
+ return;
+ }
+
+
+ /* If we're already doing channel switching and we're in the
+ * middle of counting down, then reject this channel switch msg.
+ */
+ if (pMac->lim.gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE)
+ {
+ limLog(pMac, LOGE,
+ FL("channel switching is already in progress.\n"));
+ palFreeMemory( pMac->hHdd, pSmeMsg);
+ limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_CHANNEL_SWITCH_DISABLED);
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("rcvd eWNI_SME_SWITCH_CHL_REQ, message type = %d\n"), pSmeMsg->messageType);)
+ switch(pSmeMsg->messageType)
+ {
+ case eWNI_SME_SWITCH_CHL_REQ:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ break;
+
+ case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ:
+
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ break;
+
+ case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_SECONDARY_ONLY;
+ break;
+
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("unknown message\n"));)
+ palFreeMemory( pMac->hHdd, pSmeMsg);
+ limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_INVALID_PARAMETERS);
+ return;
+ }
+
+ pMac->lim.gLimChannelSwitch.primaryChannel = pSmeMsg->channelId;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = pSmeMsg->cbMode;
+ pMac->lim.gLimChannelSwitch.switchCount = computeChannelSwitchCount(pMac, pSmeMsg->dtimFactor);
+ if (LIM_IS_RADAR_DETECTED(pMac))
+ {
+ /** Measurement timers not running */
+ pMac->lim.gLimChannelSwitch.switchMode = eSIR_CHANSW_MODE_SILENT;
+ }
+ else
+ {
+ /** Stop measurement timers till channel switch */
+ limStopMeasTimers(pMac);
+ pMac->lim.gLimChannelSwitch.switchMode = eSIR_CHANSW_MODE_NORMAL;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("state %d, primary %d, subband %d, count %d \n"),
+ pMac->lim.gLimChannelSwitch.state,
+ pMac->lim.gLimChannelSwitch.primaryChannel,
+ pMac->lim.gLimChannelSwitch.secondarySubBand,
+ pMac->lim.gLimChannelSwitch.switchCount);)
+ palFreeMemory( pMac->hHdd, pSmeMsg);
+
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING;
+
+ return;
+} /*** end __limHandleSmeSwitchChlRequest() ***/
+
+
+/**--------------------------------------------------------------
+\fn __limProcessSmeSwitchChlReq
+
+\brief Wrapper for the function __limHandleSmeSwitchChlRequest
+ This message will be defered until softmac come out of
+ scan mode.
+\param pMac
+\param pMsg
+
+\return TRUE - If we consumed the buffer
+ FALSE - If have defered the message.
+ ---------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limProcessSmeSwitchChlReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (__limIsDeferedMsgForLearn(pMac, pMsg))
+ {
+ /**
+ * If message defered, buffer is not consumed yet.
+ * So return false
+ */
+ return eANI_BOOLEAN_FALSE;
+ }
+ __limHandleSmeSwitchChlRequest(pMac, (tANI_U32 *) pMsg->bodyptr);
+ return eANI_BOOLEAN_TRUE;
+}
+#endif
+
+
+void limProcessSmeGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ mmhMsg;
+ tpSmeGetScanChnRsp pSirSmeRsp;
+ tANI_U16 len = 0;
+
+ if(pMac->lim.scanChnInfo.numChnInfo > SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ limLog(pMac, LOGW, FL("numChn is out of bounds %d\n"),
+ pMac->lim.scanChnInfo.numChnInfo);
+ pMac->lim.scanChnInfo.numChnInfo = SIR_MAX_SUPPORTED_CHANNEL_LIST;
+ }
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("Sending message %s with number of channels %d\n"),
+ limMsgStr(eWNI_SME_GET_SCANNED_CHANNEL_RSP), pMac->lim.scanChnInfo.numChnInfo);)
+
+ len = sizeof(tSmeGetScanChnRsp) + (pMac->lim.scanChnInfo.numChnInfo - 1) * sizeof(tLimScanChn);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeRsp, len ))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for JOIN/REASSOC_RSP\n"));
+
+ return;
+ }
+ palZeroMemory(pMac->hHdd, pSirSmeRsp, len);
+
+#if defined(ANI_PRODUCT_TYPE_AP) && defined(ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->mesgType, eWNI_SME_GET_SCANNED_CHANNEL_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->mesgLen, len);
+#else
+ pSirSmeRsp->mesgType = eWNI_SME_GET_SCANNED_CHANNEL_RSP;
+ pSirSmeRsp->mesgLen = len;
+#endif
+ pSirSmeRsp->sessionId = 0;
+
+ if(pMac->lim.scanChnInfo.numChnInfo)
+ {
+ pSirSmeRsp->numChn = pMac->lim.scanChnInfo.numChnInfo;
+ palCopyMemory(pMac->hHdd, pSirSmeRsp->scanChn, pMac->lim.scanChnInfo.scanChn, sizeof(tLimScanChn) * pSirSmeRsp->numChn);
+ }
+ //Clear the list
+ limRessetScanChannelInfo(pMac);
+
+ mmhMsg.type = eWNI_SME_GET_SCANNED_CHANNEL_RSP;
+ mmhMsg.bodyptr = pSirSmeRsp;
+ mmhMsg.bodyval = 0;
+
+ pMac->lim.gLimRspReqd = false;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+void limProcessSmeGetAssocSTAsInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirSmeGetAssocSTAsReq getAssocSTAsReq;
+ tpDphHashNode pStaDs = NULL;
+ tpPESession psessionEntry = NULL;
+ tSap_Event sapEvent;
+ tpWLAN_SAPEventCB pSapEventCallback = NULL;
+ tpSap_AssocMacAddr pAssocStasTemp = NULL;// #include "sapApi.h"
+ tANI_U8 sessionId = CSR_SESSION_ID_INVALID;
+ tANI_U8 assocId = 0;
+ tANI_U8 staCount = 0;
+
+ if (!limIsSmeGetAssocSTAsReqValid(pMac, &getAssocSTAsReq, (tANI_U8 *) pMsgBuf))
+ {
+ limLog(pMac, LOGE,
+ FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message\n"));
+ goto limAssocStaEnd;
+ }
+
+ switch (getAssocSTAsReq.modId)
+ {
+/**
+ case VOS_MODULE_ID_HAL:
+ wdaPostCtrlMsg( pMac, &msgQ );
+ return;
+
+ case VOS_MODULE_ID_TL:
+ Post msg TL
+ return;
+*/
+ case VOS_MODULE_ID_PE:
+ default:
+ break;
+ }
+
+ // Get Assoctiated stations from PE
+ // Find PE session Entry
+ if ((psessionEntry = peFindSessionByBssid(pMac, getAssocSTAsReq.bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGE,
+ FL("session does not exist for given bssId\n"));
+ goto limAssocStaEnd;
+ }
+
+ if (psessionEntry->limSystemRole != eLIM_AP_ROLE)
+ {
+ limLog(pMac, LOGE,
+ FL("Received unexpected message in state %X, in role %X\n"),
+ psessionEntry->limSmeState , psessionEntry->limSystemRole);
+ goto limAssocStaEnd;
+ }
+
+ // Retrieve values obtained in the request message
+ pSapEventCallback = (tpWLAN_SAPEventCB)getAssocSTAsReq.pSapEventCallback;
+ pAssocStasTemp = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray;
+
+ for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8
+ {
+ pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if (NULL == pStaDs)
+ continue;
+
+ if (pStaDs->valid)
+ {
+ palCopyMemory(pMac->hHdd, (tANI_U8 *)&pAssocStasTemp->staMac,
+ (tANI_U8 *)&pStaDs->staAddr,
+ sizeof(v_MACADDR_t)); // Mac address
+ pAssocStasTemp->assocId = (v_U8_t)pStaDs->assocId; // Association Id
+ pAssocStasTemp->staId = (v_U8_t)pStaDs->staIndex; // Station Id
+
+ limLog(pMac, LOG1, FL("dph Station Number = %d"), staCount+1);
+ limLog(pMac, LOG1, FL("MAC = %02x:%02x:%02x:%02x:%02x:%02x"),
+ pStaDs->staAddr[0],
+ pStaDs->staAddr[1],
+ pStaDs->staAddr[2],
+ pStaDs->staAddr[3],
+ pStaDs->staAddr[4],
+ pStaDs->staAddr[5]);
+ limLog(pMac, LOG1, FL("Association Id = %d"),pStaDs->assocId);
+ limLog(pMac, LOG1, FL("Station Index = %d"),pStaDs->staIndex);
+
+ pAssocStasTemp++;
+ staCount++;
+ }
+ }
+
+limAssocStaEnd:
+ // Call hdd callback with sap event to send the list of associated stations from PE
+ if (pSapEventCallback != NULL)
+ {
+ sapEvent.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT;
+ sapEvent.sapevt.sapAssocStaListEvent.module = VOS_MODULE_ID_PE;
+ sapEvent.sapevt.sapAssocStaListEvent.noOfAssocSta = staCount;
+ sapEvent.sapevt.sapAssocStaListEvent.pAssocStas = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray;
+ pSapEventCallback(&sapEvent, getAssocSTAsReq.pUsrContext);
+ }
+}
+
+
+/**
+ * limProcessSmeGetWPSPBCSessions
+ *
+ *FUNCTION:
+ * This function is called when query the WPS PBC overlap message is received
+ *
+ *LOGIC:
+ * This function parses get WPS PBC overlap information message and call callback to pass
+ * WPS PBC overlap information back to hdd.
+ *ASSUMPTIONS:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to WPS PBC overlap query message
+*
+ * @return None
+ */
+void limProcessSmeGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirSmeGetWPSPBCSessionsReq GetWPSPBCSessionsReq;
+ tpPESession psessionEntry = NULL;
+ tSap_Event sapEvent;
+ tpWLAN_SAPEventCB pSapEventCallback = NULL;
+ tANI_U8 sessionId = CSR_SESSION_ID_INVALID;
+ tSirMacAddr zeroMac = {0,0,0,0,0,0};
+
+ sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_E_FAULT;
+
+ if (limIsSmeGetWPSPBCSessionsReqValid(pMac, &GetWPSPBCSessionsReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message\n"));
+ goto limGetWPSPBCSessionsEnd;
+ }
+
+ // Get Assoctiated stations from PE
+ // Find PE session Entry
+ if ((psessionEntry = peFindSessionByBssid(pMac, GetWPSPBCSessionsReq.bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGE,
+ FL("session does not exist for given bssId\n"));
+ goto limGetWPSPBCSessionsEnd;
+ }
+
+ if (psessionEntry->limSystemRole != eLIM_AP_ROLE)
+ {
+ limLog(pMac, LOGE,
+ FL("Received unexpected message in role %X\n"),
+ psessionEntry->limSystemRole);
+ goto limGetWPSPBCSessionsEnd;
+ }
+
+ // Call hdd callback with sap event to send the WPS PBC overlap infromation
+ sapEvent.sapHddEventCode = eSAP_GET_WPSPBC_SESSION_EVENT;
+ sapEvent.sapevt.sapGetWPSPBCSessionEvent.module = VOS_MODULE_ID_PE;
+
+ if (palEqualMemory(pMac->hHdd, zeroMac, GetWPSPBCSessionsReq.pRemoveMac, sizeof(tSirMacAddr)))
+ { //This is GetWpsSession call
+
+ limGetWPSPBCSessions(pMac,
+ sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, sapEvent.sapevt.sapGetWPSPBCSessionEvent.UUID_E,
+ &sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap, psessionEntry);
+ }
+ else
+ {
+ limRemovePBCSessions(pMac, GetWPSPBCSessionsReq.pRemoveMac,psessionEntry);
+ /* don't have to inform the HDD/Host */
+ return;
+ }
+
+ PELOG4(limLog(pMac, LOGE, FL("wpsPBCOverlap %d\n"), sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap);)
+ PELOG4(limPrintMacAddr(pMac, sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, LOG4);)
+
+ sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_SUCCESS;
+
+limGetWPSPBCSessionsEnd:
+ pSapEventCallback = (tpWLAN_SAPEventCB)GetWPSPBCSessionsReq.pSapEventCallback;
+ pSapEventCallback(&sapEvent, GetWPSPBCSessionsReq.pUsrContext);
+}
+
+#endif
+
+
+/**
+ * __limCounterMeasures()
+ *
+ * FUNCTION:
+ * This function is called to "implement" MIC counter measure
+ * and is *temporary* only
+ *
+ * LOGIC: on AP, disassoc all STA associated thru TKIP,
+ * we don't do the proper STA disassoc sequence since the
+ * BSS will be stoped anyway
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+__limCounterMeasures(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMacAddr mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)
+ || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )
+
+ limSendDisassocMgmtFrame(pMac, eSIR_MAC_MIC_FAILURE_REASON, mac, psessionEntry);
+
+ tx_thread_sleep(10);
+};
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+void
+limProcessTkipCounterMeasures(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirSmeTkipCntrMeasReq tkipCntrMeasReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionId
+
+ if ( limTkipCntrMeasReqSerDes( pMac, &tkipCntrMeasReq, (tANI_U8 *) pMsgBuf ) != eSIR_SUCCESS )
+ {
+ limLog(pMac, LOGE,
+ FL("received invalid eWNI_SME_TKIP_CNTR_MEAS_REQ message\n"));
+ return;
+ }
+
+ if ( NULL == (psessionEntry = peFindSessionByBssid( pMac, tkipCntrMeasReq.bssId, &sessionId )) )
+ {
+ limLog(pMac, LOGE, FL("session does not exist for given BSSID \n"));
+ return;
+ }
+
+ if ( tkipCntrMeasReq.bEnable )
+ {
+ __limCounterMeasures( pMac, psessionEntry );
+ }
+
+ psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable;
+}
+#endif
+
+
+static void
+__limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirSmeStopBssReq stopBssReq;
+ tSirRetStatus status;
+ tLimSmeStates prevState;
+ tANI_U8 sessionId; //PE sessionId
+ tpPESession psessionEntry;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+
+
+ if ((limStopBssReqSerDes(pMac, &stopBssReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) ||
+ !limIsSmeStopBssReqValid(pMsgBuf))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("received invalid SME_STOP_BSS_REQ message\n"));)
+ /// Send Stop BSS response to host
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId);
+ return;
+ }
+
+
+ if((psessionEntry = peFindSessionByBssid(pMac,stopBssReq.bssId,&sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("session does not exist for given BSSID \n"));
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId);
+ return;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+
+ if ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) || /* Added For BT -AMP Support */
+ (psessionEntry->limSystemRole == eLIM_STA_ROLE ))
+ {
+ /**
+ * Should not have received STOP_BSS_REQ in states
+ * other than 'normal' state or on STA in Infrastructure
+ * mode. Log error and return response to host.
+ */
+ limLog(pMac, LOGE,
+ FL("received unexpected SME_STOP_BSS_REQ in state %X, for role %d\n"),
+ psessionEntry->limSmeState, psessionEntry->limSystemRole);
+ limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState);
+ /// Send Stop BSS response to host
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,smesessionId,smetransactionId);
+ return;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE )
+ {
+ limWPSPBCClose(pMac, psessionEntry);
+ }
+#endif
+ PELOGW(limLog(pMac, LOGW, FL("RECEIVED STOP_BSS_REQ with reason code=%d\n"), stopBssReq.reasonCode);)
+
+ prevState = psessionEntry->limSmeState;
+
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ /* Update SME session Id and Transaction Id */
+ psessionEntry->smeSessionId = smesessionId;
+ psessionEntry->transactionId = smetransactionId;
+
+ /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */
+ if ( (eLIM_STA_IN_IBSS_ROLE != psessionEntry->limSystemRole) && (eLIM_BT_AMP_STA_ROLE != psessionEntry->limSystemRole) )
+ {
+ tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ if ((stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES))
+ // Send disassoc all stations associated thru TKIP
+ __limCounterMeasures(pMac,psessionEntry);
+ else
+ limSendDisassocMgmtFrame(pMac, eSIR_MAC_DISASSOC_LEAVING_BSS_REASON, bcAddr,psessionEntry);
+ }
+
+ //limDelBss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg.
+ pMac->lim.gLimIbssCoalescingHappened = false;
+
+ /* send a delBss to HAL and wait for a response */
+ status = limDelBss(pMac, NULL,psessionEntry->bssIdx,psessionEntry);
+
+ if (status != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d\n"), psessionEntry->bssIdx);)
+ psessionEntry->limSmeState= prevState;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_STOP_BSS_FAILURE,smesessionId,smetransactionId);
+ }
+}
+
+
+/**--------------------------------------------------------------
+\fn __limProcessSmeStopBssReq
+
+\brief Wrapper for the function __limHandleSmeStopBssRequest
+ This message will be defered until softmac come out of
+ scan mode. Message should be handled even if we have
+ detected radar in the current operating channel.
+\param pMac
+\param pMsg
+
+\return TRUE - If we consumed the buffer
+ FALSE - If have defered the message.
+ ---------------------------------------------------------------*/
+static tANI_BOOLEAN
+__limProcessSmeStopBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (__limIsDeferedMsgForLearn(pMac, pMsg))
+ {
+ /**
+ * If message defered, buffer is not consumed yet.
+ * So return false
+ */
+ return eANI_BOOLEAN_FALSE;
+ }
+ __limHandleSmeStopBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr);
+ return eANI_BOOLEAN_TRUE;
+} /*** end __limProcessSmeStopBssReq() ***/
+
+
+void limProcessSmeDelBssRsp(
+ tpAniSirGlobal pMac,
+ tANI_U32 body,tpPESession psessionEntry)
+{
+
+ (void) body;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ //TBD: get the sessionEntry
+ dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);
+ limDeletePreAuthList(pMac);
+ limIbssDelete(pMac,psessionEntry);
+ limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,psessionEntry->smeSessionId,psessionEntry->transactionId);
+ return;
+}
+
+
+#if 0
+/**
+ * __limProcessSmePromiscuousReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_PROMISCUOUS_REQ message
+ * from HDD or upper layer application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmePromiscuousReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+
+ tANI_U32 cfg = sizeof(tSirMacAddr);
+ tSirMacAddr currentBssId;
+ tLimMlmDisassocReq *pMlmDisassocReq;
+ tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received PROMISCUOUS_REQ message\n"));)
+
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+
+ if ((((pMac->lim.gLimSystemRole == eLIM_STA_ROLE) ||
+ (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)) &&
+ ((pMac->lim.gLimSmeState == eLIM_SME_ASSOCIATED_STATE) ||
+ (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE))) ||
+ ((pMac->lim.gLimSystemRole == eLIM_AP_ROLE) &&
+ (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE)))
+ {
+ // Trigger Disassociation frame to peer MAC entity
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmDisassocReq, sizeof(tLimMlmDisassocReq)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for mlmDisassocReq\n"));
+
+ return;
+ }
+
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMlmDisassocReq->peerMacAddr,
+ (tANI_U8 *) &bcAddr,
+ sizeof(tSirMacAddr));
+ else
+ palCopyMemory( pMac->hHdd, pMlmDisassocReq->peerMacAddr,
+ currentBssId,
+ sizeof(tSirMacAddr));
+
+ pMlmDisassocReq->reasonCode =
+ eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
+ pMlmDisassocReq->disassocTrigger =
+ eLIM_PROMISCUOUS_MODE_DISASSOC;
+
+ pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState;
+ pMac->lim.gLimSmeState = eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+
+ limPostMlmMessage(pMac,
+ LIM_MLM_DISASSOC_REQ,
+ (tANI_U32 *) pMlmDisassocReq);
+ }
+ else
+ {
+ // Send Promiscuous mode response to host
+ limSendSmePromiscuousModeRsp(pMac);
+
+ pMac->lim.gLimSmeState = eLIM_SME_OFFLINE_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ }
+
+} /*** end __limProcessSmePromiscuousReq() ***/
+#endif
+
+
+/**---------------------------------------------------------------
+\fn __limProcessSmeAssocCnfNew
+\brief This function handles SME_ASSOC_CNF/SME_REASSOC_CNF
+\ in BTAMP AP.
+\
+\param pMac
+\param msgType - message type
+\param pMsgBuf - a pointer to the SME message buffer
+\return None
+------------------------------------------------------------------*/
+
+ void
+__limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+ tSirSmeAssocCnf assocCnf;
+ tpDphHashNode pStaDs = NULL;
+ tpPESession psessionEntry= NULL;
+ tANI_U8 sessionId;
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE, FL("pMsgBuf is NULL \n"));
+ goto end;
+ }
+
+ if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) ||
+ !__limIsSmeAssocCnfValid(&assocCnf))
+ {
+ limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message \n"));
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, FL("session does not exist for given bssId\n"));
+ goto end;
+ }
+
+ if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) ||
+ ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE)))
+ {
+ limLog(pMac, LOGE, FL("Received unexpected message %X in state %X, in role %X\n"),
+ msgType, psessionEntry->limSmeState , psessionEntry->limSystemRole);
+ goto end;
+ }
+
+ pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL)
+ {
+ limLog(pMac, LOG1,
+ FL("Received invalid message %X due to no STA context, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);
+
+ /*
+ ** send a DISASSOC_IND message to WSM to make sure
+ ** the state in WSM and LIM is the same
+ **/
+ limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED,
+ eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry);
+ goto end;
+ }
+ if ((pStaDs &&
+ (( !palEqualMemory( pMac->hHdd,(tANI_U8 *) pStaDs->staAddr,
+ (tANI_U8 *) assocCnf.peerMacAddr,
+ sizeof(tSirMacAddr)) ) ||
+ (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
+ ((pStaDs->mlmStaContext.subType == LIM_ASSOC) &&
+ (msgType != eWNI_SME_ASSOC_CNF)) ||
+ ((pStaDs->mlmStaContext.subType == LIM_REASSOC) &&
+#ifdef WLAN_SOFTAP_FEATURE
+ (msgType != eWNI_SME_ASSOC_CNF))))) // since softap is passing this as ASSOC_CNF and subtype differs
+#else
+ (msgType != eWNI_SME_REASSOC_CNF)))))
+#endif
+ {
+ limLog(pMac, LOG1,
+ FL("Received invalid message %X due to peerMacAddr mismatched or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);
+ goto end;
+ }
+
+ /*
+ ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF
+ ** has been received
+ **/
+ limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer\n"));
+ limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId);
+
+ if (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ {
+ /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence
+ * when it had received Assoc Request frame. Now, PE just needs to send
+ * Association Response frame to the requesting BTAMP-STA.
+ */
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) \n"), pStaDs->assocId);
+ limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType, pStaDs, psessionEntry);
+ goto end;
+ } // (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ else
+ {
+ // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated
+ /*Since the HAL sta entry is created for denied STA we need to remove this HAL entry.So to do that set updateContext to 1*/
+ if(!pStaDs->mlmStaContext.updateContext)
+ pStaDs->mlmStaContext.updateContext = 1;
+ limRejectAssociation(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry);
+ return;
+ }
+
+end:
+ if((psessionEntry != NULL) && (pStaDs != NULL))
+ {
+ if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL )
+ {
+ if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame)
+ {
+ palFreeMemory(pMac->hHdd,((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame);
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL;
+ }
+
+ palFreeMemory(pMac->hHdd, psessionEntry->parsedAssocReq[pStaDs->assocId]);
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
+ }
+ }
+
+} /*** end __limProcessSmeAssocCnfNew() ***/
+
+
+#ifdef ANI_PRODUCT_TYPE_AP
+/**
+ * __limProcessSmeAssocCnf()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon
+ * receiving SME_ASSOC_CNF/SME_REASSOC_CNF from WSM.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ *
+ * @return None
+ */
+
+static void
+__limProcessSmeAssocCnf(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+ tSirSmeAssocCnf assocCnf;
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tHalBitVal cbBitVal;
+ tANI_U8 tspecIdx = 0; //index in the lim tspec table.
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) ==
+ eSIR_FAILURE) ||
+ !__limIsSmeAssocCnfValid(&assocCnf))
+ {
+ limLog(pMac, LOGW,
+ FL("Received re/assocCnf message with invalid parameters\n"));
+
+ return;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac,assocCnf->bssId,&sessionId))== NULL)
+ {
+
+ limLog(pMac, LOGE,
+ FL("session does not exist for given bssId\n"));
+ return;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_CNF_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) ||
+ ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE)))
+ {
+ limLog(pMac, LOGE,
+ FL("Received unexpected message %X in state %X, in role %X\n"),
+ msgType, psessionEntry->limSmeState , psessionEntry->limSystemRole);
+
+ return;
+ }
+
+ pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable);
+
+
+ if (pStaDs == NULL)
+ {
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Received invalid message %X due to no STA context, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);)
+
+ /*
+ ** send a DISASSOC_IND message to WSM to make sure
+ ** the state in WSM and LIM is the same
+ **/
+
+ limSendSmeDisassocNtf(pMac,
+ assocCnf.peerMacAddr,
+ eSIR_SME_STA_NOT_ASSOCIATED,
+ eLIM_PEER_ENTITY_DISASSOC,
+ assocCnf.aid,psessionEntry);
+
+ return;
+ }
+ if ((pStaDs &&
+ (( !palEqualMemory( pMac->hHdd,(tANI_U8 *) pStaDs->staAddr,
+ (tANI_U8 *) assocCnf.peerMacAddr,
+ sizeof(tSirMacAddr)) ) ||
+ (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE) ||
+ ((pStaDs->mlmStaContext.subType == LIM_ASSOC) &&
+ (msgType != eWNI_SME_ASSOC_CNF)) ||
+ ((pStaDs->mlmStaContext.subType == LIM_REASSOC) &&
+ (msgType != eWNI_SME_REASSOC_CNF)))))
+ {
+ PELOG1(limLog(pMac, LOG1,
+ FL("Received invalid message %X due to peerMacAddr mismatched or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "),
+ msgType, assocCnf.aid);
+ limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1);)
+
+ return;
+ }
+
+ /*
+ ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF
+ ** has been received
+ **/
+
+ PELOG1(limLog(pMac, LOG1, FL("Received Cnf. Delete Timer\n"));)
+ limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER,
+ pStaDs->assocId);
+
+ if (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ {
+ tSirMacScheduleIE schedule;
+
+ // If STA is a TITAN-compatible device, then setup
+ // the TITAN proprietary capabilities appropriately
+ // in the per STA DS, as per the local TITAN Prop
+ // capabilities of this AP
+
+ // STA is allowed to be associated
+ if (pStaDs->mlmStaContext.updateContext)
+ {
+
+ tLimMlmStates mlmPrevState = pStaDs->mlmStaContext.mlmState;
+ //we need to set the mlmState here in order differentiate in limDelSta.
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
+ if(limDelSta(pMac, pStaDs, true,psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("could not DEL STA with assocId=%d staId %d\n"),
+ pStaDs->assocId, pStaDs->staIndex);
+
+ limRejectAssociation(pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ //Restoring the state back.
+ pStaDs->mlmStaContext.mlmState = mlmPrevState;
+ return;
+ }
+ return;
+ }
+ else
+ {
+ // Add STA context at HW
+ if (limAddSta(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("could not Add STA with assocId=%d\n"),
+ pStaDs->assocId);
+
+ // delete the TS if it has already been added.
+ // send the response with error status.
+ if(pStaDs->qos.addtsPresent)
+ {
+ limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo, NULL, &tspecIdx);
+ }
+
+ limRejectAssociation(pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ }
+ return;
+ }
+
+ } // if (assocCnf.statusCode == eSIR_SME_SUCCESS)
+ else
+ {
+ // STA is not allowed to be associated
+ limRejectAssociation(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ assocCnf.statusCode, psessionEntry);
+ }
+} /*** end __limProcessSmeAssocCnf() ***/
+#endif
+
+
+static void
+__limProcessSmeAddtsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpDphHashNode pStaDs;
+ tSirMacAddr peerMac;
+ tpSirAddtsReq pSirAddts;
+ tANI_U32 timeout;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionId
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ pSirAddts = (tpSirAddtsReq) pMsgBuf;
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pSirAddts->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, "Session Does not exist for given bssId\n");
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+
+
+ /* if sta
+ * - verify assoc state
+ * - send addts request to ap
+ * - wait for addts response from ap
+ * if ap, just ignore with error log
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("Received SME_ADDTS_REQ (TSid %d, UP %d)\n"),
+ pSirAddts->req.tspec.tsinfo.traffic.tsid,
+ pSirAddts->req.tspec.tsinfo.traffic.userPrio);)
+
+ if ((psessionEntry->limSystemRole != eLIM_STA_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE))
+ {
+ PELOGE(limLog(pMac, LOGE, "AddTs received on AP - ignoring\n");)
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ //Ignore the request if STA is in 11B mode.
+ if(psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B)
+ {
+ PELOGE(limLog(pMac, LOGE, "AddTS received while Dot11Mode is 11B - ignoring\n");)
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+
+ if(pStaDs == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, "Cannot find AP context for addts req\n");)
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ if ((! pStaDs->valid) ||
+ (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE))
+ {
+ PELOGE(limLog(pMac, LOGE, "AddTs received in invalid MLM state\n");)
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ pSirAddts->req.wsmTspecPresent = 0;
+ pSirAddts->req.wmeTspecPresent = 0;
+ pSirAddts->req.lleTspecPresent = 0;
+
+ if ((pStaDs->wsmEnabled) &&
+ (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA))
+ pSirAddts->req.wsmTspecPresent = 1;
+ else if (pStaDs->wmeEnabled)
+ pSirAddts->req.wmeTspecPresent = 1;
+ else if (pStaDs->lleEnabled)
+ pSirAddts->req.lleTspecPresent = 1;
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled\n"));)
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
+ {
+ limLog(pMac, LOGE, "AddTs received in invalid LIMsme state (%d)\n",
+ psessionEntry->limSmeState);
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ if (pMac->lim.gLimAddtsSent)
+ {
+ limLog(pMac, LOGE, "Addts (token %d, tsid %d, up %d) is still pending\n",
+ pMac->lim.gLimAddtsReq.req.dialogToken,
+ pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
+ pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.userPrio);
+ limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec,
+ smesessionId,smetransactionId);
+ return;
+ }
+
+ #if 0
+ val = sizeof(tSirMacAddr);
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMac, &val) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ return;
+ }
+ #endif
+ sirCopyMacAddr(peerMac,psessionEntry->bssId);
+
+ // save the addts request
+ pMac->lim.gLimAddtsSent = true;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMac->lim.gLimAddtsReq, (tANI_U8 *) pSirAddts, sizeof(tSirAddtsReq));
+
+ // ship out the message now
+ limSendAddtsReqActionFrame(pMac, peerMac, &pSirAddts->req,
+ psessionEntry);
+ PELOG1(limLog(pMac, LOG1, "Sent ADDTS request\n");)
+
+ // start a timer to wait for the response
+ if (pSirAddts->timeout)
+ timeout = pSirAddts->timeout;
+ else if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get Cfg param %d (Addts Rsp Timeout)\n"),
+ WNI_CFG_ADDTS_RSP_TIMEOUT);
+ return;
+ }
+
+ timeout = SYS_MS_TO_TICKS(timeout);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("AddtsRsp timer change failed!\n"));
+ return;
+ }
+ pMac->lim.gLimAddtsRspTimerCount++;
+ if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
+ pMac->lim.gLimAddtsRspTimerCount) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("AddtsRsp timer change failed!\n"));
+ return;
+ }
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_ADDTS_RSP_TIMER));
+
+ //add the sessionId to the timer object
+ pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId;
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("AddtsRsp timer activation failed!\n"));
+ return;
+ }
+ return;
+}
+
+
+static void
+__limProcessSmeDeltsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U8 ac;
+ tSirMacTSInfo *pTsinfo;
+ tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf;
+ tpDphHashNode pStaDs = NULL;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tANI_U32 status = eSIR_SUCCESS;
+ tANI_U8 smesessionId;
+ tANI_U16 smetransactionId;
+
+ limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId);
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pDeltsReq->bssId, &sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, "Session Does not exist for given bssId\n");
+ status = eSIR_FAILURE;
+ goto end;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+
+ if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDeltsReq, peerMacAddr,psessionEntry))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed\n"));)
+ status = eSIR_FAILURE;
+ limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_FAILURE,psessionEntry,smesessionId,smetransactionId);
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("Sent DELTS request to station with assocId = %d MacAddr = %x:%x:%x:%x:%x:%x\n"),
+ pDeltsReq->aid, peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
+ peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);)
+
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, pDeltsReq->req.wmeTspecPresent, &pDeltsReq->req.tsinfo, &pDeltsReq->req.tspec,
+ psessionEntry);
+
+ pTsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo : &pDeltsReq->req.tsinfo;
+
+ /* We've successfully send DELTS frame to AP. Update the
+ * dynamic UAPSD mask. The AC for this TSPEC to be deleted
+ * is no longer trigger enabled or delivery enabled
+ */
+ limSetTspecUapsdMask(pMac, pTsinfo, CLEAR_UAPSD_MASK);
+
+ /* We're deleting the TSPEC, so this particular AC is no longer
+ * admitted. PE needs to downgrade the EDCA
+ * parameters(for the AC for which TS is being deleted) to the
+ * next best AC for which ACM is not enabled, and send the
+ * updated values to HAL.
+ */
+ ac = upToAc(pTsinfo->traffic.userPrio);
+
+ if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
+ }
+ else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
+ }
+ else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
+ }
+
+ limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
+
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ {
+ if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
+ else
+ limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
+ status = eSIR_SUCCESS;
+ }
+ else
+ {
+ limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
+ status = eSIR_FAILURE;
+ }
+#ifdef FEATURE_WLAN_CCX
+ limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
+#endif
+
+ // send an sme response back
+ end:
+ limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_SUCCESS,psessionEntry,smesessionId,smetransactionId);
+}
+
+
+void
+limProcessSmeAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param)
+{
+ //fetch the sessionEntry based on the sessionId
+ tpPESession psessionEntry;
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAddtsRspTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ if ( (psessionEntry->limSystemRole != eLIM_STA_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE) )
+ {
+ limLog(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)\n", psessionEntry->limSystemRole);
+ pMac->lim.gLimAddtsSent = false;
+ return;
+ }
+
+ if (! pMac->lim.gLimAddtsSent)
+ {
+ PELOGW(limLog(pMac, LOGW, "AddtsRspTimeout but no AddtsSent\n");)
+ return;
+ }
+
+ if (param != pMac->lim.gLimAddtsRspTimerCount)
+ {
+ limLog(pMac, LOGE, FL("Invalid AddtsRsp Timer count %d (exp %d)\n"),
+ param, pMac->lim.gLimAddtsRspTimerCount);
+ return;
+ }
+
+ // this a real response timeout
+ pMac->lim.gLimAddtsSent = false;
+ pMac->lim.gLimAddtsRspTimerCount++;
+
+ limSendSmeAddtsRsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT, psessionEntry, pMac->lim.gLimAddtsReq.req.tspec,
+ psessionEntry->smeSessionId, psessionEntry->transactionId);
+}
+
+
+/**
+ * __limProcessSmeStatsRequest()
+ *
+ *FUNCTION:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__limProcessSmeStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpAniGetStatsReq pStatsReq;
+ tSirMsgQ msgQ;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ pStatsReq = (tpAniGetStatsReq) pMsgBuf;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pStatsReq->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, FL("session does not exist for given bssId\n"));
+ return;
+ }
+
+
+
+ switch(pStatsReq->msgType)
+ {
+ //Add Lim stats here. and send reqsponse.
+
+ //HAL maintained Stats.
+ case eWNI_SME_STA_STAT_REQ:
+ msgQ.type = WDA_STA_STAT_REQ;
+ break;
+ case eWNI_SME_AGGR_STAT_REQ:
+ msgQ.type = WDA_AGGR_STAT_REQ;
+ break;
+ case eWNI_SME_GLOBAL_STAT_REQ:
+ msgQ.type = WDA_GLOBAL_STAT_REQ;
+ break;
+ case eWNI_SME_STAT_SUMM_REQ:
+ msgQ.type = WDA_STAT_SUMM_REQ;
+ break;
+ default: //Unknown request.
+ PELOGE(limLog(pMac, LOGE, "Unknown Statistics request\n");)
+ palFreeMemory( pMac, pMsgBuf );
+ return;
+ }
+
+ if ( !pMac->lim.gLimRspReqd )
+ {
+ palFreeMemory( pMac, pMsgBuf );
+ return;
+ }
+ else
+ {
+ pMac->lim.gLimRspReqd = FALSE;
+ }
+
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMsgBuf;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){
+ limLog(pMac, LOGP, "Unable to forward request\n");
+ return;
+ }
+
+ return;
+}
+
+
+/**
+ * __limProcessSmeGetStatisticsRequest()
+ *
+ *FUNCTION:
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__limProcessSmeGetStatisticsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpAniGetPEStatsReq pPEStatsReq;
+ tSirMsgQ msgQ;
+
+ pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf;
+
+ //pPEStatsReq->msgType should be eWNI_SME_GET_STATISTICS_REQ
+
+ msgQ.type = WDA_GET_STATISTICS_REQ;
+
+ if ( !pMac->lim.gLimRspReqd )
+ {
+ palFreeMemory( pMac, pMsgBuf );
+ return;
+ }
+ else
+ {
+ pMac->lim.gLimRspReqd = FALSE;
+ }
+
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMsgBuf;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){
+ palFreeMemory( pMac, pMsgBuf );
+ limLog(pMac, LOGP, "Unable to forward request\n");
+ return;
+ }
+
+ return;
+}
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+static void
+__limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received UPDATE_APWPSIEs_REQ message\n")););
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ if( palAllocateMemory( pMac->hHdd, (void **)&pUpdateAPWPSIEsReq, sizeof(tSirUpdateAPWPSIEsReq)))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for pUpdateAPWPSIEsReq\n"));
+ return;
+ }
+
+ if ((limUpdateAPWPSIEsReqSerDes(pMac, pUpdateAPWPSIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
+ {
+ limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message\n"));
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPSIEsReq->bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("Session does not exist for given BSSID\n"));
+ goto end;
+ }
+
+ palCopyMemory(pMac->hHdd, &psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs, sizeof(tSirAPWPSIEs));
+
+ schSetFixedBeaconFields(pMac, psessionEntry);
+ limSendBeaconInd(pMac, psessionEntry);
+
+end:
+ palFreeMemory( pMac->hHdd, pUpdateAPWPSIEsReq);
+ return;
+} /*** end __limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/
+
+static void
+__limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirUpdateParams pUpdateParams;
+ tpPESession psessionEntry;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("received HIDE_SSID message\n")););
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ pUpdateParams = (tpSirUpdateParams)pMsgBuf;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pUpdateParams->sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, "Session does not exist for given sessionId %d\n",
+ pUpdateParams->sessionId);
+ return;
+ }
+
+ /* Update the session entry */
+ psessionEntry->ssidHidden = pUpdateParams->ssidHidden;
+
+ /* Update beacon */
+ schSetFixedBeaconFields(pMac, psessionEntry);
+ limSendBeaconInd(pMac, psessionEntry);
+
+ return;
+} /*** end __limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/
+
+static void
+__limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId; //PE sessionID
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ if( palAllocateMemory( pMac->hHdd, (void **)&pUpdateAPWPARSNIEsReq, sizeof(tSirUpdateAPWPSIEsReq)))
+ {
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for pUpdateAPWPARSNIEsReq\n"));
+ return;
+ }
+
+ if ((limUpdateAPWPARSNIEsReqSerDes(pMac, pUpdateAPWPARSNIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE))
+ {
+ limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message\n"));
+ goto end;
+ }
+
+ if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPARSNIEsReq->bssId, &sessionId)) == NULL)
+ {
+ limLog(pMac, LOGW, FL("Session does not exist for given BSSID\n"));
+ goto end;
+ }
+
+ palCopyMemory(pMac->hHdd, &psessionEntry->pLimStartBssReq->rsnIE, &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie));
+
+ limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac, &psessionEntry->pLimStartBssReq->rsnIE, psessionEntry);
+
+ psessionEntry->pLimStartBssReq->privacy = 1;
+ psessionEntry->privacy = 1;
+
+ schSetFixedBeaconFields(pMac, psessionEntry);
+ limSendBeaconInd(pMac, psessionEntry);
+
+end:
+ palFreeMemory( pMac->hHdd, pUpdateAPWPARSNIEsReq);
+ return;
+} /*** end __limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/
+
+#endif
+
+
+/** -------------------------------------------------------------
+\fn limProcessSmeDelBaPeerInd
+\brief handles indication message from HDD to send delete BA request
+\param tpAniSirGlobal pMac
+\param tANI_U32 pMsgBuf
+\return None
+-------------------------------------------------------------*/
+void
+limProcessSmeDelBaPeerInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tANI_U16 assocId =0;
+ tpSmeDelBAPeerInd pSmeDelBAPeerInd = (tpSmeDelBAPeerInd)pMsgBuf;
+ tpDphHashNode pSta;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+
+
+ if(NULL == pSmeDelBAPeerInd)
+ return;
+
+ if ((psessionEntry = peFindSessionByBssid(pMac,pSmeDelBAPeerInd->bssId,&sessionId))==NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given bssId\n"));
+ return;
+ }
+ limLog(pMac, LOGW, FL("called with staId = %d, tid = %d, baDirection = %d\n"),
+ pSmeDelBAPeerInd->staIdx, pSmeDelBAPeerInd->baTID, pSmeDelBAPeerInd->baDirection);
+
+ pSta = dphLookupAssocId(pMac, pSmeDelBAPeerInd->staIdx, &assocId, &psessionEntry->dph.dphHashTable);
+ if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac,
+ pSta,
+ pSmeDelBAPeerInd->baDirection,
+ pSmeDelBAPeerInd->baTID,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to post LIM_MLM_DELBA_REQ to " ));
+ if (pSta)
+ limPrintMacAddr(pMac, pSta->staAddr, LOGW);
+ }
+}
+
+// --------------------------------------------------------------------
+/**
+ * __limProcessReportMessage
+ *
+ * FUNCTION: Processes the next received Radio Resource Management message
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+#ifdef WLAN_FEATURE_VOWIFI
+ switch (pMsg->type)
+ {
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ rrmProcessNeighborReportReq( pMac, pMsg->bodyptr );
+ break;
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+ {
+#if defined FEATURE_WLAN_CCX
+ tpSirBeaconReportXmitInd pBcnReport=NULL;
+ tpPESession psessionEntry=NULL;
+ tANI_U8 sessionId;
+
+ if(pMsg->bodyptr == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+ pBcnReport = (tpSirBeaconReportXmitInd )pMsg->bodyptr;
+ if((psessionEntry = peFindSessionByBssid(pMac, pBcnReport->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE, "Session Does not exist for given bssId\n");
+ return;
+ }
+ if (psessionEntry->isCCXconnection)
+ ccxProcessBeaconReportXmit( pMac, pMsg->bodyptr);
+ else
+#endif
+ rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr );
+ }
+ break;
+ }
+#endif
+}
+
+#if defined(FEATURE_WLAN_CCX) || defined(WLAN_FEATURE_VOWIFI)
+// --------------------------------------------------------------------
+/**
+ * limSendSetMaxTxPowerReq
+ *
+ * FUNCTION: Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry )
+{
+ tpMaxTxPowerParams pMaxTxParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if( pSessionEntry == NULL )
+ {
+ PELOGE(limLog(pMac, LOGE, "%s:%d: Inavalid parameters\n", __func__, __LINE__ );)
+ return eSIR_FAILURE;
+ }
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMaxTxParams, sizeof(tMaxTxPowerParams) ) )
+ {
+ limLog( pMac, LOGP, "%s:%d:Unable to allocate memory for pMaxTxParams \n", __func__, __LINE__);
+ return eSIR_MEM_ALLOC_FAILED;
+
+ }
+#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_CCX)
+ PELOG1(limLog( pMac, LOG1, "%s:%d: Allocated memory for pMaxTxParams...will be freed in other module\n", __func__, __LINE__ );)
+#endif
+ pMaxTxParams->power = txPower;
+ palCopyMemory( pMac->hHdd, pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
+ palCopyMemory( pMac->hHdd, pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );
+
+ msgQ.type = WDA_SET_MAX_TX_POWER_REQ;
+ msgQ.bodyptr = pMaxTxParams;
+ msgQ.bodyval = 0;
+ PELOGW(limLog(pMac, LOG1, FL("Posting WDA_SET_MAX_TX_POWER_REQ to WDA\n"));)
+ if(eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ)))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
+ if (NULL != pMaxTxParams)
+ {
+ palFreeMemory(pMac->hHdd, (tANI_U8*)pMaxTxParams);
+ }
+ return retCode;
+ }
+ return retCode;
+}
+#endif
+
+/**
+ * __limProcessSmeAddStaSelfReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_ADD_STA_SELF_REQ message
+ * from SME. It sends a SIR_HAL_ADD_STA_SELF_REQ message to HAL.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeAddStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ msg;
+ tpAddStaSelfParams pAddStaSelfParams;
+ tpSirSmeAddStaSelfReq pSmeReq = (tpSirSmeAddStaSelfReq) pMsgBuf;
+
+ if ( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void**) &pAddStaSelfParams,
+ sizeof( tAddStaSelfParams) ) )
+ {
+ limLog( pMac, LOGP, FL("Unable to allocate memory for tAddSelfStaParams") );
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, pAddStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) );
+
+ msg.type = SIR_HAL_ADD_STA_SELF_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = pAddStaSelfParams;
+ msg.bodyval = 0;
+
+ PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL\n"));)
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed\n"));
+ }
+ return;
+} /*** end __limProcessAddStaSelfReq() ***/
+
+
+/**
+ * __limProcessSmeDelStaSelfReq()
+ *
+ *FUNCTION:
+ * This function is called to process SME_DEL_STA_SELF_REQ message
+ * from SME. It sends a SIR_HAL_DEL_STA_SELF_REQ message to HAL.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void
+__limProcessSmeDelStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ msg;
+ tpDelStaSelfParams pDelStaSelfParams;
+ tpSirSmeDelStaSelfReq pSmeReq = (tpSirSmeDelStaSelfReq) pMsgBuf;
+
+ if ( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void**) &pDelStaSelfParams,
+ sizeof( tDelStaSelfParams) ) )
+ {
+ limLog( pMac, LOGP, FL("Unable to allocate memory for tDelStaSelfParams") );
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, pDelStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) );
+
+ msg.type = SIR_HAL_DEL_STA_SELF_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = pDelStaSelfParams;
+ msg.bodyval = 0;
+
+ PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL\n"));)
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed\n"));
+ }
+ return;
+} /*** end __limProcessSmeDelStaSelfReq() ***/
+
+
+#ifdef WLAN_FEATURE_P2P
+/**
+ * __limProcessSmeRegisterMgmtFrameReq()
+ *
+ *FUNCTION:
+ * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message
+ * from SME. It Register this information within PE.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__limProcessSmeRegisterMgmtFrameReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
+{
+ VOS_STATUS vosStatus;
+ tpSirRegisterMgmtFrame pSmeReq = (tpSirRegisterMgmtFrame)pMsgBuf;
+ tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("%s: registerFrame %d, frameType %d, matchLen %d\n",
+ __func__, pSmeReq->registerFrame, pSmeReq->frameType,
+ pSmeReq->matchLen)));
+
+ if(pSmeReq->registerFrame)
+ {
+ palAllocateMemory(pMac, (void**)&pLimMgmtRegistration,
+ sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen);
+ if(pLimMgmtRegistration != NULL)
+ {
+ palZeroMemory(pMac, (void*)pLimMgmtRegistration,
+ sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen );
+ pLimMgmtRegistration->frameType = pSmeReq->frameType;
+ pLimMgmtRegistration->matchLen = pSmeReq->matchLen;
+ pLimMgmtRegistration->sessionId = pSmeReq->sessionId;
+ if(pSmeReq->matchLen)
+ {
+ palCopyMemory(pMac,pLimMgmtRegistration->matchData,
+ pSmeReq->matchData, pSmeReq->matchLen);
+ }
+
+ vos_list_insert_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
+ &pLimMgmtRegistration->node);
+ }
+ }
+ else
+ {
+ tANI_BOOLEAN match = VOS_FALSE;
+
+ vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
+ (vos_list_node_t**)&pLimMgmtRegistration);
+
+ while(pLimMgmtRegistration != NULL)
+ {
+ if (pLimMgmtRegistration->frameType == pSmeReq->frameType)
+ {
+ if(pSmeReq->matchLen)
+ {
+ if (pLimMgmtRegistration->matchLen == pSmeReq->matchLen)
+ {
+ if (palEqualMemory(pMac, pLimMgmtRegistration->matchData,
+ pSmeReq->matchData, 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)
+ {
+ vos_list_remove_node(&pMac->lim.gLimMgmtFrameRegistratinQueue,
+ (vos_list_node_t*)pLimMgmtRegistration);
+ palFreeMemory(pMac,pLimMgmtRegistration);
+ }
+ }
+
+ return;
+} /*** end __limProcessSmeRegisterMgmtFrameReq() ***/
+#endif
+
+
+/**
+ * limProcessSmeReqMessages()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the SME message type
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed.
+ * FALSE - if pMsgBuf is not to be freed.
+ */
+
+tANI_BOOLEAN
+limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ tANI_BOOLEAN bufConsumed = TRUE; //Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed.
+ tANI_U32 *pMsgBuf = pMsg->bodyptr;
+
+ PELOG1(limLog(pMac, LOG1, FL("LIM Received SME Message %s(%d) LimSmeState:%s(%d) LimMlmState: %s(%d)\n"),
+ limMsgStr(pMsg->type), pMsg->type,
+ limSmeStateStr(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState,
+ limMlmStateStr(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState );)
+
+ switch (pMsg->type)
+ {
+ case eWNI_SME_START_REQ:
+ __limProcessSmeStartReq(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_SYS_READY_IND:
+ bufConsumed = __limProcessSmeSysReadyInd(pMac, pMsgBuf);
+ break;
+
+
+ case eWNI_SME_START_BSS_REQ:
+ bufConsumed = __limProcessSmeStartBssReq(pMac, pMsg);
+ break;
+
+ case eWNI_SME_SCAN_REQ:
+ __limProcessSmeScanReq(pMac, pMsgBuf);
+
+ break;
+
+#ifdef WLAN_FEATURE_P2P
+ case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
+ bufConsumed = limProcessRemainOnChnlReq(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_UPDATE_NOA:
+ __limProcessSmeNoAUpdate(pMac, pMsgBuf);
+ break;
+#endif
+ case eWNI_SME_JOIN_REQ:
+ __limProcessSmeJoinReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_AUTH_REQ:
+ // __limProcessSmeAuthReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_REASSOC_REQ:
+ __limProcessSmeReassocReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_PROMISCUOUS_MODE_REQ:
+ //__limProcessSmePromiscuousReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_DISASSOC_REQ:
+ __limProcessSmeDisassocReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_DISASSOC_CNF:
+ case eWNI_SME_DEAUTH_CNF:
+ __limProcessSmeDisassocCnf(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_DEAUTH_REQ:
+ __limProcessSmeDeauthReq(pMac, pMsgBuf);
+
+ break;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ case eWNI_SME_SWITCH_CHL_REQ:
+ case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ:
+ case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ:
+ bufConsumed = __limProcessSmeSwitchChlReq(pMac, pMsg);
+ break;
+#endif
+
+
+ case eWNI_SME_SETCONTEXT_REQ:
+ __limProcessSmeSetContextReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_REMOVEKEY_REQ:
+ __limProcessSmeRemoveKeyReq(pMac, pMsgBuf);
+
+ break;
+
+ case eWNI_SME_STOP_BSS_REQ:
+ bufConsumed = __limProcessSmeStopBssReq(pMac, pMsg);
+ break;
+
+ case eWNI_SME_ASSOC_CNF:
+ case eWNI_SME_REASSOC_CNF:
+ if (pMsg->type == eWNI_SME_ASSOC_CNF)
+ PELOG1(limLog(pMac, LOG1, FL("Received ASSOC_CNF message\n"));)
+ else
+ PELOG1(limLog(pMac, LOG1, FL("Received REASSOC_CNF message\n"));)
+#ifdef ANI_PRODUCT_TYPE_AP
+ __limProcessSmeAssocCnf(pMac, pMsg->type, pMsgBuf);
+#endif
+ __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf);
+ break;
+
+ case eWNI_SME_ADDTS_REQ:
+ PELOG1(limLog(pMac, LOG1, FL("Received ADDTS_REQ message\n"));)
+ __limProcessSmeAddtsReq(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DELTS_REQ:
+ PELOG1(limLog(pMac, LOG1, FL("Received DELTS_REQ message\n"));)
+ __limProcessSmeDeltsReq(pMac, pMsgBuf);
+ break;
+
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ PELOG1(limLog(pMac, LOG1, FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message \n"));)
+ limProcessSmeAddtsRspTimeout(pMac, pMsg->bodyval);
+ break;
+
+ case eWNI_SME_STA_STAT_REQ:
+ case eWNI_SME_AGGR_STAT_REQ:
+ case eWNI_SME_GLOBAL_STAT_REQ:
+ case eWNI_SME_STAT_SUMM_REQ:
+ __limProcessSmeStatsRequest( pMac, pMsgBuf);
+ //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false.
+ bufConsumed = FALSE;
+ break;
+ case eWNI_SME_GET_STATISTICS_REQ:
+ __limProcessSmeGetStatisticsRequest( pMac, pMsgBuf);
+ //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false.
+ bufConsumed = FALSE;
+ break;
+ case eWNI_SME_DEL_BA_PEER_IND:
+ limProcessSmeDelBaPeerInd(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_GET_SCANNED_CHANNEL_REQ:
+ limProcessSmeGetScanChannelInfo(pMac, pMsgBuf);
+ break;
+#ifdef WLAN_SOFTAP_FEATURE
+ case eWNI_SME_GET_ASSOC_STAS_REQ:
+ limProcessSmeGetAssocSTAsInfo(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_TKIP_CNTR_MEAS_REQ:
+ limProcessTkipCounterMeasures(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_HIDE_SSID_REQ:
+ __limProcessSmeHideSSID(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_UPDATE_APWPSIE_REQ:
+ __limProcessSmeUpdateAPWPSIEs(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_GET_WPSPBC_SESSION_REQ:
+ limProcessSmeGetWPSPBCSessions(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_SET_APWPARSNIEs_REQ:
+ __limProcessSmeSetWPARSNIEs(pMac, pMsgBuf);
+ break;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+ __limProcessReportMessage(pMac, pMsg);
+ break;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ case eWNI_SME_FT_PRE_AUTH_REQ:
+ bufConsumed = (tANI_BOOLEAN)limProcessFTPreAuthReq(pMac, pMsg);
+ break;
+ case eWNI_SME_FT_UPDATE_KEY:
+ limProcessFTUpdateKey(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_FT_AGGR_QOS_REQ:
+ limProcessFTAggrQosReq(pMac, pMsgBuf);
+ break;
+#endif
+
+#if defined FEATURE_WLAN_CCX
+ case eWNI_SME_CCX_ADJACENT_AP_REPORT:
+ limProcessAdjacentAPRepMsg ( pMac, pMsgBuf );
+ break;
+#endif
+ case eWNI_SME_ADD_STA_SELF_REQ:
+ __limProcessSmeAddStaSelfReq( pMac, pMsgBuf );
+ break;
+ case eWNI_SME_DEL_STA_SELF_REQ:
+ __limProcessSmeDelStaSelfReq( pMac, pMsgBuf );
+ break;
+
+#ifdef WLAN_FEATURE_P2P
+ case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+ __limProcessSmeRegisterMgmtFrameReq( pMac, pMsgBuf );
+ break;
+#endif
+
+
+ default:
+ vos_mem_free((v_VOID_t*)pMsg->bodyptr);
+ pMsg->bodyptr = NULL;
+ break;
+ } // switch (msgType)
+
+ return bufConsumed;
+} /*** end limProcessSmeReqMessages() ***/
diff --git a/CORE/MAC/src/pe/lim/limPropExtsUtils.c b/CORE/MAC/src/pe/lim/limPropExtsUtils.c
new file mode 100644
index 0000000..cfd824f
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limPropExtsUtils.c
@@ -0,0 +1,1475 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limPropExtsUtils.cc contains the utility functions
+ * to populate, parse proprietary extensions required to
+ * support ANI feature set.
+ *
+ * Author: Chandra Modumudi
+ * Date: 11/27/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "aniGlobal.h"
+#ifdef ANI_PRODUCT_TYPE_AP
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "sirCommon.h"
+#include "sirDebug.h"
+#include "utilsApi.h"
+#include "cfgApi.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halCommonApi.h"
+#endif
+#include "limApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSerDesUtils.h"
+#include "limTrace.h"
+#include "limSession.h"
+
+#define LIM_GET_NOISE_MAX_TRY 5
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+/**
+ * limGetCurrentLearnChannel()
+ *
+ *FUNCTION:
+ * This function is called in various places to get current channel
+ * number being 'learned'.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return Channel number
+ */
+tANI_U8
+limGetCurrentLearnChannel(tpAniSirGlobal pMac)
+{
+ tANI_U8 *pChanNum = pMac->lim.gpLimMeasReq->channelList.channelNumber;
+
+ return (*(pChanNum + pMac->lim.gLimMeasParams.nextLearnChannelId));
+} /*** end limGetCurrentLearnChannel() ***/
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+
+/**
+ * limExtractApCapability()
+ *
+ *FUNCTION:
+ * This function is called to extract AP's HCF/WME/WSM capability
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pIE Pointer to starting IE in Beacon/Probe Response
+ * @param ieLen Length of all IEs combined
+ * @param qosCap Bits are set according to capabilities
+ * @return 0 - If AP does not assert HCF capability & 1 - otherwise
+ */
+
+void
+limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen,
+ tANI_U8 *qosCap, tANI_U16 *propCap, tANI_U8 *uapsd,
+ tPowerdBm *localConstraint
+ )
+{
+ tSirProbeRespBeacon beaconStruct;
+#if !defined WLAN_FEATURE_VOWIFI
+ tANI_U32 localPowerConstraints = 0;
+#endif
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) &beaconStruct, sizeof(beaconStruct));
+
+ *qosCap = 0;
+ *propCap = 0;
+ *uapsd = 0;
+
+ PELOG3(limLog( pMac, LOG3,
+ FL("In limExtractApCapability: The IE's being received are:\n"));
+ sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );)
+ if (sirParseBeaconIE(pMac, &beaconStruct, pIE, (tANI_U32)ieLen) == eSIR_SUCCESS)
+ {
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (beaconStruct.propIEinfo.hcfEnabled)
+ LIM_BSS_CAPS_SET(HCF, *qosCap);
+#endif
+ if (beaconStruct.wmeInfoPresent || beaconStruct.wmeEdcaPresent)
+ LIM_BSS_CAPS_SET(WME, *qosCap);
+ if (LIM_BSS_CAPS_GET(WME, *qosCap) && beaconStruct.wsmCapablePresent)
+ LIM_BSS_CAPS_SET(WSM, *qosCap);
+ if (beaconStruct.propIEinfo.aniIndicator &&
+ beaconStruct.propIEinfo.capabilityPresent)
+ *propCap = beaconStruct.propIEinfo.capability;
+ if (beaconStruct.HTCaps.present)
+ pMac->lim.htCapabilityPresentInBeacon = 1;
+ else
+ pMac->lim.htCapabilityPresentInBeacon = 0;
+
+ // Extract the UAPSD flag from WMM Parameter element
+ if (beaconStruct.wmeEdcaPresent)
+ *uapsd = beaconStruct.edcaParams.qosInfo.uapsd;
+
+#if defined FEATURE_WLAN_CCX
+ /* If there is Power Constraint Element specifically,
+ * adapt to it. Hence there is else condition check
+ * for this if statement.
+ */
+ if ( beaconStruct.ccxTxPwr.present)
+ {
+ *localConstraint = beaconStruct.ccxTxPwr.power_limit;
+ }
+#endif
+
+ if (beaconStruct.powerConstraintPresent && ( pMac->lim.gLim11hEnable
+#if defined WLAN_FEATURE_VOWIFI
+ || pMac->rrm.rrmPEContext.rrmEnable
+#endif
+ ))
+ {
+#if defined WLAN_FEATURE_VOWIFI
+ *localConstraint -= beaconStruct.localPowerConstraint.localPowerConstraints;
+#else
+ localPowerConstraints = (tANI_U32)beaconStruct.localPowerConstraint.localPowerConstraints;
+#endif
+ }
+
+#if !defined WLAN_FEATURE_VOWIFI
+ if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.\n"));
+ }
+#endif
+ }
+
+ return;
+} /****** end limExtractApCapability() ******/
+
+
+
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+/**
+ * limQuietBss()
+ *
+ *FUNCTION:
+ * This function is called to quiet the BSS
+ * while entering into Learn mode
+ *
+ *LOGIC:
+ * Data frame to self with duration value passed is
+ * transmitted
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * If all associated STAs are 11h compliant, Quiet IE
+ * need to be sent in Beacon/Probe Response frames.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param duration Specifies quiet duration in millisec
+ * @return None
+ */
+
+void
+limQuietBss(tpAniSirGlobal pMac, tANI_U32 duration)
+{
+
+ // Temporarily not quieting BSS
+ (void) pMac; (void) duration;
+ return;
+} /****** end limQuietBss() ******/
+
+
+
+/**
+ * limIsMatrixNodePresent()
+ *
+ *FUNCTION:
+ * This function is called to determine if measurements are
+ * already made on the current learn channel
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return pNode - Pointer to Matrix node if found. Else NULL
+ */
+
+static tpLimMeasMatrixNode
+limIsMatrixNodePresent(tpAniSirGlobal pMac)
+{
+ tANI_U8 i, chanNum = limGetCurrentLearnChannel(pMac);
+ tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
+
+ if (!pNode)
+ return NULL;
+
+ for (i = 0; i < pMac->lim.gpLimMeasReq->channelList.numChannels; i++)
+ {
+ if (pNode->matrix.channelNumber == chanNum)
+ {
+ return pNode;
+ }
+ else
+ {
+ if (pNode->next)
+ pNode = pNode->next;
+ else
+ break;
+ }
+ }
+
+ return NULL;
+} /****** end limIsMatrixNodePresent() ******/
+
+
+
+/**
+ * limGetMatrixNode()
+ *
+ *FUNCTION:
+ * This function is called to get a metrics node associated
+ * with the current measurement channel. If no node is found
+ * for this channel, one is added at the beginning of the list.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static tpLimMeasMatrixNode
+limGetMatrixNode(tpAniSirGlobal pMac)
+{
+ tpLimMeasMatrixNode pNewMatrix;
+ eHalStatus status;
+
+ pNewMatrix = limIsMatrixNodePresent(pMac);
+ if (!pNewMatrix)
+ {
+ // Making first time measurements on this channel.
+ // Add matrix node for this at the front.
+ status = palAllocateMemory( pMac->hHdd, (void **)&pNewMatrix, sizeof(*pNewMatrix));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ /// Could not allocate buffer for new measMatrix Node
+ // Log error
+ limLog(pMac, LOGP,
+ FL("palAllocateMemory failed for new measMatrix Node\n"));
+ return NULL;
+ }
+
+ status = palZeroMemory( pMac->hHdd, (void *)pNewMatrix, sizeof(*pNewMatrix));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ /// Could not allocate buffer for new measMatrix Node
+ // Log error
+ limLog(pMac, LOGP,
+ FL("palZeroMemory failed for new measMatrix Node\n"));
+ return NULL;
+ }
+
+ pNewMatrix->matrix.channelNumber =
+ limGetCurrentLearnChannel(pMac);
+ pNewMatrix->avgRssi = 0;
+
+ PELOG3(limLog(pMac, LOG3, FL("Adding new Matrix info:channel#=%d\n"),
+ pNewMatrix->matrix.channelNumber);)
+
+ pNewMatrix->next = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
+ pMac->lim.gpLimMeasData->pMeasMatrixInfo = pNewMatrix;
+ pMac->lim.gpLimMeasData->numMatrixNodes++;
+ }
+
+ return pNewMatrix;
+} /****** end limGetMatrixNode() ******/
+
+
+
+/**
+ * limComputeAvg()
+ *
+ *FUNCTION:
+ * This function is called to compute exponential average
+ * of RSSI, channel utilization etc.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param oldVal Previous averaged value
+ * @param newVal New averaged value
+ * @return None
+ */
+
+tANI_U32
+limComputeAvg(tpAniSirGlobal pMac, tANI_U32 oldVal, tANI_U32 newVal)
+{
+ return (halExpAvg(newVal,
+ oldVal,
+ pMac->lim.gLimMeasParams.rssiAlpha));
+} /****** end limComputeAvg() ******/
+
+
+
+/**
+ * limCollectRSSI()
+ *
+ *FUNCTION:
+ * This function is called to collect RSSI measurements on
+ * the current learn channel
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCollectRSSI(tpAniSirGlobal pMac)
+{
+ tpLimMeasMatrixNode pNewMatrix = limGetMatrixNode(pMac);
+ tANI_U32 i, noise;
+
+ for (i = 0; i < LIM_GET_NOISE_MAX_TRY; i++)
+ if ((noise = halGetNoise(pMac)) != HAL_NOISE_INVALID)
+ {
+ pNewMatrix->avgRssi = limComputeAvg(pMac,
+ pNewMatrix->avgRssi,
+ noise);
+ break;
+ }
+} /****** end limCollectRSSI() ******/
+
+
+/**----------------------------------------------------------------------------
+\fn limGetNeighbourBssNode
+
+\brief returns neighbour bss node if it is already present in the list.
+\param pMac
+\param bssid - Bssid of new beacon or data packet.
+\param pSsId - Pointer to SSID of new packet.
+\param nwType - 11b/g/a
+\param chanId - Channel in which we received the packet.
+
+\return tpLimNeighborBssWdsNode or NULL
+-------------------------------------------------------------------------------*/
+static tpLimNeighborBssWdsNode
+limGetNeighbourBssNode(tpAniSirGlobal pMac, tANI_U8 *bssId, tANI_U8 chanId,
+ tSirNwType nwType, tpAniSSID pSsId, tANI_U8 type)
+{
+ tpLimNeighborBssWdsNode pNode = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
+
+ while (pNode)
+ {
+ //Do we need to check for ssId also ?
+ if (palEqualMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId,
+ bssId, sizeof(tSirMacAddr)) &&
+ (pNode->info.neighborBssInfo.channelId == chanId))
+ {
+#if 0
+/** Commented out assuming that comparing bssId and ChanId would be enough to
+uniquely identify a particular BSS, Uncomment if strict checking is needed,
+eventhough not possible if packet type is DATA. */
+ if (type == eSIR_MAC_MGMT_FRAME)
+ {
+ /** Beacon Frame */
+ if (palEqualMemory(pMac->hHdd, &pNode->info.neighborBssInfo.ssId,
+ pSsId, pSsId->length+1) &&
+ (pNode->info.neighborBssInfo.nwType == nwType))
+ {
+ return pNode;
+ }
+ }
+ else
+#endif
+ return pNode;
+ }
+
+ if (!pNode->next)
+ break;
+ else
+ pNode = pNode->next;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * limCollectMeasurementData()
+ *
+ *FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * or Data frames to collect measurement related data.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pRxPacketInfo - Pointer to received BD+payload
+ * @param pBeacon - Pointer to parsed BSS info
+ * @return None
+ */
+
+void
+limCollectMeasurementData(tpAniSirGlobal pMac,
+ tANI_U32 *pRxPacketInfo, tpSchBeaconStruct pBeacon)
+{
+ tANI_U16 allocLen=0, len=0, realLen=0, ieLen=0;
+ tANI_U32 i;
+ tANI_U8 found = eANI_BOOLEAN_TRUE;
+ tSirMacFrameCtl fc ;
+ tSirMacAddr bssIdRcv;
+ tSirNwType nwType;
+ tAniSSID ssId;
+ tANI_U8 chanId = 0;
+ tpLimNeighborBssWdsNode pNode = NULL;
+ tpLimMeasMatrixNode pNewMatrix;
+ eHalStatus status;
+ tpSirMacMgmtHdr pHdr;
+
+ PELOG3(limLog(pMac, LOG3, FL("Collecting measurement data for RadioId %d\n"),
+ pMac->sys.gSirRadioId);)
+
+ tANI_U32 ignore = 0;
+ limGetBssidFromBD(pMac, (tpHalBufDesc) pRxPacketInfo, bssIdRcv, &ignore);
+ if (palEqualMemory( pMac->hHdd, bssIdRcv, pMac->lim.gLimBssid, sizeof(tSirMacAddr)))
+ {
+ // Packet received from our own BSS, dont take measurement.
+ return;
+ }
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ fc = pHdr->fc;
+
+ if (fc.type == SIR_MAC_DATA_FRAME)
+ {
+ PELOG2(limLog(pMac, LOG2, FL("Received DATA packet\n"));)
+ ssId.length = 0;
+ ieLen = 0;
+ }
+ else
+ {
+ /** Probe response or beaccon packet */
+ palCopyMemory(pMac->hHdd, (void *)&ssId, (void *) &pBeacon->ssId,
+ sizeof(ssId));
+ chanId = limGetChannelFromBeacon(pMac, pBeacon);
+ ieLen = pBeacon->wpa.length + pBeacon->propIEinfo.wdsLength;
+ }
+
+ if (chanId == 0)
+ {
+ /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
+ /* Unmapped the channel.This We have to do since we have done mapping in the hal to
+ overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/
+ chanId = WDA_GET_RX_CH(pRxPacketInfo);
+ if(!( chanId = limUnmapChannel(chanId)))
+ {
+ chanId = pMac->lim.gLimCurrentScanChannelId;
+ }
+ }
+
+ /*
+ * Now always returns nwType as 11G for data packets - FIXIT
+ */
+ nwType = limGetNwType(pMac, chanId, fc.type, pBeacon);
+
+ pNewMatrix = limGetMatrixNode(pMac);
+ /** LOGP would result in freeing all dynamicall allocated memories. So
+ * return from here if limGetMatrixNode returns NULL
+ */
+ if (!pNewMatrix)
+ return;
+
+ pNewMatrix->matrix.aggrRssi += WDA_GET_RX_RSSI_DB(pRxPacketInfo);
+ pNewMatrix->matrix.totalPackets++;
+
+ // Find if this neighbor is already 'learned'
+ // If found, update its information.
+ pNode = limGetNeighbourBssNode(pMac, bssIdRcv, chanId, nwType, &ssId, fc.type);
+
+ if (!pNode)
+ {
+ realLen = sizeof(tSirNeighborBssWdsInfo);
+
+ /** Newly discovered neighbor. Inform WSM of this
+ * and add this BSS info at the beginning
+ * Need to limit the number newly discovered BSS added
+ * to the list.
+ */
+ len = LIM_MAX_BUF_SIZE - (sizeof(tSirSmeMeasurementInd) +
+ (pMac->lim.gpLimMeasReq->channelList.numChannels *
+ sizeof(tSirMeasMatrixInfo)));
+ PELOG2(limLog(pMac, LOG2, FL("Current BSS length %d, Real length %d\n"),
+ pMac->lim.gpLimMeasData->totalBssSize, realLen);)
+
+ /** Check if we have enough room for adding a new node.
+ */
+ if (pMac->lim.gpLimMeasData->totalBssSize + realLen < len)
+ {
+ pMac->lim.gpLimMeasData->numBssWds++;
+ pMac->lim.gpLimMeasData->totalBssSize += realLen;
+
+ PELOG2(limPrintMacAddr(pMac, bssIdRcv, LOG2);)
+ }
+ else
+ {
+ PELOG2(limLog(pMac, LOG2, FL("Dropping the measurement packets: No memory!\n"));)
+ return;
+ }
+
+ /** Allocate max memory required even if the packet is of type DATA,
+ * So that next time we receive a beacon, won't run out of memory to
+ * update the information.
+ */
+ allocLen = sizeof(tLimNeighborBssWdsNode) + 4 + ieLen;
+ status = palAllocateMemory( pMac->hHdd, (void **)&pNode, allocLen);
+
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
+ return;
+ }
+
+ status = palZeroMemory(pMac->hHdd, pNode, allocLen);
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for new NeighborBssWds Node\n"));
+ return;
+ }
+ pNode->next = pMac->lim.gpLimMeasData->pNeighborWdsInfo;
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo = pNode;
+ found = eANI_BOOLEAN_FALSE;
+ }
+
+ pNode->info.neighborBssInfo.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo);
+ pNode->info.neighborBssInfo.aggrRssi += pNode->info.neighborBssInfo.rssi;
+ if (fc.type == SIR_MAC_DATA_FRAME)
+ pNode->info.neighborBssInfo.dataCount++;
+ pNode->info.neighborBssInfo.totalPackets++;
+
+ /** If node not found or previous learn was not from a beacon/probe rsp
+ * then learn again.
+ */
+ if (!found || ((pNode->info.neighborBssInfo.ssId.length == 0) &&
+ (fc.type == SIR_MAC_MGMT_FRAME)))
+ {
+ palCopyMemory(pMac->hHdd, pNode->info.neighborBssInfo.bssId, bssIdRcv,
+ sizeof(tSirMacAddr));
+ pNode->info.neighborBssInfo.channelId = chanId;
+ if (fc.type == SIR_MAC_DATA_FRAME)
+ {
+ // Data frame received from other BSS.
+ // Collect as much information as possible
+ pNode->info.neighborBssInfo.wniIndicator = (tAniBool) 0;
+
+ if (fc.toDS || fc.fromDS)
+ pNode->info.neighborBssInfo.bssType = eSIR_INFRASTRUCTURE_MODE;
+ else
+ pNode->info.neighborBssInfo.bssType = eSIR_IBSS_MODE;
+
+ pNode->info.neighborBssInfo.load.numStas = 0;
+ pNode->info.neighborBssInfo.load.channelUtilization = 0;
+ pNode->info.neighborBssInfo.ssId.length = 0;
+ pNode->info.neighborBssInfo.apName.length = 0;
+ pNode->info.neighborBssInfo.rsnIE.length = 0;
+ pNode->info.wdsInfo.wdsLength = 0;
+ }
+ else
+ {
+ //FIXME_CBMODE: need to seperate out TITAN and HT cb modes.
+ if(pBeacon->HTCaps.present)
+ {
+ limGetHtCbAdminState(pMac, pBeacon->HTCaps,
+ &pNode->info.neighborBssInfo.titanHtCaps);
+
+ if( pBeacon->HTInfo.present)
+ {
+ limGetHtCbOpState(pMac, pBeacon->HTInfo,
+ &pNode->info.neighborBssInfo.titanHtCaps);
+ }
+ }
+
+ // This must be either Beacon frame or
+ // Probe Response. Copy all relevant information.
+ pNode->info.neighborBssInfo.wniIndicator = (tAniBool) pBeacon->propIEinfo.aniIndicator;
+ pNode->info.neighborBssInfo.bssType = (tSirBssType) pBeacon->capabilityInfo.ibss;
+ pNode->info.neighborBssInfo.load.numStas = pBeacon->propIEinfo.load.numStas;
+ pNode->info.neighborBssInfo.load.channelUtilization = pBeacon->propIEinfo.load.channelUtilization;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.ssId,
+ &pBeacon->ssId, pBeacon->ssId.length+1);
+ pNode->info.neighborBssInfo.apName.length = pBeacon->propIEinfo.apName.length;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.neighborBssInfo.apName.name,
+ pBeacon->propIEinfo.apName.name, pBeacon->propIEinfo.apName.length);
+
+ pNode->info.neighborBssInfo.rsnIE.length = 0;
+ // Add WPA2 information. Before that make sure that memory is available
+ if (pBeacon->rsnPresent && (pBeacon->rsn.length < SIR_MAC_MAX_IE_LENGTH))
+ {
+ pNode->info.neighborBssInfo.rsnIE.length = 2 + pBeacon->rsn.length;
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1] = pBeacon->rsn.length;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[2],
+ pBeacon->rsn.info, pBeacon->rsn.length);
+
+ PELOG2(limLog(pMac, LOG2, FL("NeighborBss RSN IE, type=%x, length=%x\n"),
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[0],
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[1]);)
+ }
+
+ // Add WPA information. Before that make sure that memory is available
+ if (pBeacon->wpaPresent && ((pBeacon->rsn.length + pBeacon->wpa.length) < (SIR_MAC_MAX_IE_LENGTH-2)))
+ {
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length] =
+ SIR_MAC_WPA_EID;
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1] =
+ pBeacon->wpa.length;
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 2],
+ pBeacon->wpa.info, pBeacon->wpa.length);
+
+ PELOG2(limLog(pMac, LOG2, FL("NeighborBss WPA IE, type=%x, length=%x\n"),
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length],
+ pNode->info.neighborBssInfo.rsnIE.rsnIEdata[pNode->info.neighborBssInfo.rsnIE.length + 1]);)
+ pNode->info.neighborBssInfo.rsnIE.length += 2 + pBeacon->wpa.length;
+ }
+ pNode->info.wdsInfo.wdsLength = (tANI_U16) pBeacon->propIEinfo.wdsLength;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pNode->info.wdsInfo.wdsBytes,
+ pBeacon->propIEinfo.wdsData,
+ pBeacon->propIEinfo.wdsLength);
+
+ pNode->info.neighborBssInfo.capabilityInfo = *((tANI_U16*)&pBeacon->capabilityInfo);
+
+#if 0
+ if (pBeacon->HTCaps.present)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTCaps,
+ (tANI_U8 *)&pBeacon->HTCaps, HT_CAPABILITY_IE_SIZE);
+ else
+ pNode->info.neighborBssInfo.HTCaps.present = 0;
+
+ if (pBeacon->HTInfo.present)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)&pNode->info.neighborBssInfo.HTInfo,
+ (tANI_U8 *)&pBeacon->HTInfo, HT_INFO_IE_SIZE);
+ else
+ pNode->info.neighborBssInfo.HTInfo.present = 0;
+#endif
+
+ if (pBeacon->suppRatesPresent && (pBeacon->supportedRates.numRates <=
+ SIR_MAC_RATESET_EID_MAX))
+ {
+ pNode->info.neighborBssInfo.operationalRateSet.numRates = pBeacon->supportedRates.numRates;
+
+ PELOG4(limLog(pMac, LOG4, FL("Supported Rates (%d) : "),
+ pNode->info.neighborBssInfo.operationalRateSet.numRates);)
+ for (i=0; i<pBeacon->supportedRates.numRates; i++)
+ {
+ pNode->info.neighborBssInfo.operationalRateSet.rate[i] = pBeacon->supportedRates.rate[i];
+ PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->supportedRates.rate[i]);)
+ }
+ PELOG4(limLog(pMac, LOG4, FL("\n"));)
+ }
+
+ if (pBeacon->extendedRatesPresent && (pBeacon->extendedRates.numRates <=
+ SIR_MAC_RATESET_EID_MAX))
+ {
+ pNode->info.neighborBssInfo.extendedRateSet.numRates = pBeacon->extendedRates.numRates;
+
+ PELOG4(limLog(pMac, LOG4, FL("Extended Rates (%d) : "),
+ pNode->info.neighborBssInfo.extendedRateSet.numRates);)
+ for (i=0; i<pBeacon->extendedRates.numRates; i++)
+ {
+ pNode->info.neighborBssInfo.extendedRateSet.rate[i] = pBeacon->extendedRates.rate[i];
+ PELOG4(limLog(pMac, LOG4, FL("%d "), pBeacon->extendedRates.rate[i]);)
+ }
+ }
+ else
+ {
+ pNode->info.neighborBssInfo.extendedRateSet.numRates = 0;
+ }
+ pNode->info.neighborBssInfo.nwType = nwType;
+ pNode->info.neighborBssInfo.hcfEnabled = pBeacon->propIEinfo.hcfEnabled;
+ pNode->info.neighborBssInfo.beaconInterval = pBeacon->beaconInterval;
+ pNode->info.neighborBssInfo.wmeInfoPresent = pBeacon->wmeInfoPresent;
+ pNode->info.neighborBssInfo.wmeEdcaPresent = pBeacon->wmeEdcaPresent;
+ pNode->info.neighborBssInfo.wsmCapablePresent = pBeacon->wsmCapablePresent;
+ pNode->info.neighborBssInfo.propIECapability = pBeacon->propIEinfo.capability;
+ pNode->info.neighborBssInfo.localPowerConstraints = pBeacon->localPowerConstraint.localPowerConstraints;
+ pNode->info.neighborBssInfo.dtimPeriod = pBeacon->tim.dtimPeriod;
+ pNode->info.neighborBssInfo.HTCapsPresent = pBeacon->HTCaps.present;
+ pNode->info.neighborBssInfo.HTInfoPresent = pBeacon->HTInfo.present;
+ }
+ }
+} /****** end limCollectMeasurementData() ******/
+
+/**
+ * limCleanupMatrixNodes()
+ *
+ *FUNCTION:
+ * This function is called from various places within LIM code
+ * to cleanup channel info matrix collected by learn mode measurements.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limCleanupMatrixNodes(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
+ {
+ tpLimMeasMatrixNode pNode = pMac->lim.gpLimMeasData->pMeasMatrixInfo;
+ tpLimMeasMatrixNode pNext;
+
+ while (pNode)
+ {
+ pNext = pNode->next;
+ palFreeMemory( pMac->hHdd, pNode);
+
+ if (pNext)
+ pNode = pNext;
+ else
+ break;
+ }
+ }
+
+ pMac->lim.gpLimMeasData->numMatrixNodes = 0;
+ PELOG2(limLog(pMac, LOG2,
+ FL("Cleaned up channel matrix nodes\n"));)
+
+ pMac->lim.gpLimMeasData->pMeasMatrixInfo = NULL;
+} /****** end limCleanupMatrixNodes() ******/
+
+/**
+ * limCleanupNeighborBssNodes()
+ *
+ *FUNCTION:
+ * This function is called from various places within LIM code
+ * to cleanup neighbor info collected by learn mode measurements.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void
+limCleanupNeighborBssNodes(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
+ {
+ tpLimNeighborBssWdsNode pNode =
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo;
+ tpLimNeighborBssWdsNode pNext;
+ while (pNode)
+ {
+ pNext = pNode->next;
+ pMac->lim.gpLimMeasData->numBssWds--;
+ palFreeMemory( pMac->hHdd, pNode);
+
+ if (pNext)
+ pNode = pNext;
+ else
+ break;
+ }
+ }
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("Cleaned up neighbor nodes\n"));)
+
+ pMac->lim.gpLimMeasData->numBssWds = 0;
+ pMac->lim.gpLimMeasData->totalBssSize = 0;
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
+} /****** end limCleanupNeighborBssNodes() ******/
+
+
+/**
+ * limSendSmeMeasurementInd()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() to
+ * send SME_MEASUREMENT_IND message to WSM.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limSendSmeMeasurementInd(tpAniSirGlobal pMac)
+{
+ tANI_U8 *pMeasInd;
+ tANI_U16 len = 0;
+ tSirMsgQ mmhMsg;
+
+#ifdef GEN6_TODO
+ //fetch the sessionEntry based on the sessionId
+ //priority - MEDIUM
+ tpPESession sessionEntry;
+
+ if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.gLimMeasParams.measurementIndTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+#endif
+
+ if (!pMac->sys.gSysEnableLearnMode ||
+ (pMac->lim.gpLimMeasReq == NULL))
+ {
+ return;
+ }
+
+ len = sizeof(tSirSmeMeasurementInd) +
+ (pMac->lim.gpLimMeasReq->channelList.numChannels *
+ sizeof(tSirMeasMatrixInfo)) +
+ pMac->lim.gpLimMeasData->totalBssSize;
+ if (len > LIM_MAX_BUF_SIZE)
+ {
+ limLog(pMac, LOGP,
+ FL("len %d numChannels %d numBssWds %d totalBssSize %d\n"),
+ len,
+ pMac->lim.gpLimMeasReq->channelList.numChannels,
+ pMac->lim.gpLimMeasData->numBssWds,
+ pMac->lim.gpLimMeasData->totalBssSize);
+ }
+
+ PELOG2(limLog(pMac, LOG2, FL("***** Measurement IND size %d\n"), len);)
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMeasInd, len))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_MEAS_IND\n"));
+
+ return;
+ }
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("Sending eWNI_SME_MEAS_IND on Radio %d, requested len=%d\n"),
+ pMac->sys.gSirRadioId, len);)
+
+ limMeasurementIndSerDes(pMac, pMeasInd);
+
+ mmhMsg.type = eWNI_SME_MEASUREMENT_IND;
+ mmhMsg.bodyptr = pMeasInd;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ // Cleanup neighbor information
+ limCleanupNeighborBssNodes(pMac);
+ limCleanupMatrixNodes(pMac);
+} /*** end limSendSmeMeasurementInd() ***/
+
+
+
+/**
+ * limCleanupMeasData()
+ *
+ *FUNCTION:
+ * This function is called from various places within LIM code
+ * to cleanup measurement related data.
+ *
+ *LOGIC:
+ * Buffers and associated timer resources will be deleted when
+ * this function is called
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCleanupMeasData(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gpLimMeasReq)
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasReq);
+
+ pMac->lim.gpLimMeasReq = NULL;
+
+ if (!pMac->lim.gpLimMeasData)
+ return;
+
+ if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
+ {
+ // Retain current channel's data and flush remaining
+ tpLimMeasMatrixNode pMatrix =
+ (pMac->lim.gpLimMeasData->pMeasMatrixInfo)->next;
+ tpLimMeasMatrixNode pNext;
+
+ while (pMatrix)
+ {
+ pNext = pMatrix->next;
+ palFreeMemory( pMac->hHdd, pMatrix);
+
+ if (pNext)
+ pMatrix = pNext;
+ else
+ break;
+ }
+
+ pMac->lim.gpLimMeasData->pMeasMatrixInfo->next = NULL;
+ }
+
+ pMac->lim.gpLimMeasData->numMatrixNodes = 0;
+ PELOG2(limLog(pMac, LOG2,
+ FL("Cleaned up measurement metrics nodes\n"));)
+
+ // Cleanup neighbor information
+ limCleanupNeighborBssNodes(pMac);
+} /****** end limCleanupMeasData() ******/
+
+/**---------------------------------------------------------
+\fn limStopMeasTimers
+\brief Stops all measurement related timers.
+
+\param pMac
+\return None
+ ----------------------------------------------------------*/
+void
+limStopMeasTimers(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gpLimMeasReq == NULL)
+ return;
+
+ if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
+ {
+ if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.measurementIndTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Cannot stop measurement Ind timer\n"));)
+ }
+ }
+ pMac->lim.gLimMeasParams.isMeasIndTimerActive = 0;
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_LEARN_INTERVAL_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnIntervalTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn interval timer\n"));)
+ }
+
+ if (pMac->lim.gLimSpecMgmt.fQuietEnabled)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_LEARN_DURATION_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
+ }
+ }
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_LEARN_DURATION_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Cannot stop learn duration timer\n"));)
+ }
+}
+
+/**
+ * limDeleteMeasTimers()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() upon
+ * receiving SME_MEASUREMENT_REQ. This function deletes
+ * timers associated with Measurements.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limDeleteMeasTimers(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gpLimMeasReq->measControl.periodicMeasEnabled)
+ tx_timer_delete(&pMac->lim.gLimMeasParams.measurementIndTimer);
+ tx_timer_delete(&pMac->lim.gLimMeasParams.learnIntervalTimer);
+ tx_timer_delete(&pMac->lim.gLimMeasParams.learnDurationTimer);
+} /*** end limDeleteMeasTimers() ***/
+
+
+
+/**
+ * limCleanupMeasResources()
+ *
+ *FUNCTION:
+ * This function is called from various places within LIM code
+ * to cleanup measurement related data and resources.
+ *
+ *LOGIC:
+ * Buffers and associated timer resources will be deleted when
+ * this function is called
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCleanupMeasResources(tpAniSirGlobal pMac)
+{
+ PELOG1( limLog(pMac, LOG1,
+ FL("Cleaning up Learn mode Measurement resources\n"));)
+
+ if (pMac->lim.gpLimMeasReq == NULL)
+ return;
+
+ limDeleteMeasTimers(pMac);
+
+ if (pMac->lim.gpLimMeasData)
+ {
+ limCleanupMeasData(pMac);
+ if (pMac->lim.gpLimMeasData->pMeasMatrixInfo)
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData->pMeasMatrixInfo);
+
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMeasData);
+ pMac->lim.gpLimMeasData = NULL;
+ }
+} /****** end limCleanupMeasResources() ******/
+
+
+/**
+ * limDeleteCurrentBssWdsNode()
+ *
+ *FUNCTION:
+ * This function is called when Loss of link
+ * is detected with AP and its BssWds info node
+ * to be deleted
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param None
+ * @return None
+ */
+void limDeleteCurrentBssWdsNode(tpAniSirGlobal pMac)
+{
+ tANI_U32 cfg = sizeof(tSirMacAddr);
+ tSirMacAddr currentBssId;
+
+#if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) !=
+ eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+#endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,sessionEntry->bssId);
+
+ if (!pMac->lim.gpLimMeasData)
+ return;
+
+ if (pMac->lim.gpLimMeasData->pNeighborWdsInfo)
+ {
+ tpLimNeighborBssWdsNode pNode =
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo;
+ tpLimNeighborBssWdsNode pPrev = pNode;
+ while (pNode)
+ {
+ if (palEqualMemory( pMac->hHdd,pNode->info.neighborBssInfo.bssId,
+ currentBssId,
+ sizeof(tSirMacAddr)))
+ {
+ pMac->lim.gpLimMeasData->numBssWds--;
+ pPrev->next = pNode->next;
+ palFreeMemory( pMac->hHdd, pNode);
+ break;
+ }
+ pPrev = pNode;
+
+ if (pNode->next)
+ pNode = pNode->next;
+ else
+ break;
+ }
+
+ if (!pMac->lim.gpLimMeasData->numBssWds)
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo = NULL;
+ }
+} /****** end limDeleteCurrentBssWdsNode() ******/
+
+
+
+/**
+ * limRestorePreLearnState()
+ *
+ *FUNCTION:
+ * This function is called when Learn duration timer expires
+ * to restore pre-Learn mode state
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limRestorePreLearnState(tpAniSirGlobal pMac)
+{
+ PELOG4(limLog(pMac, LOG4,
+ FL("Restoring from Learn mode on RadioId %d\n"),
+ pMac->sys.gSirRadioId);)
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+
+ // Go back to previous state.
+ pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState;
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ PELOG4(limLog(pMac, LOG4,
+ FL("Restored from Learn mode on RadioId %d\n"),
+ pMac->sys.gSirRadioId);)
+} /****** end limRestorePreLearnState() ******/
+
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || (ANI_PRODUCT_TYPE_AP_SDK))
+
+/**
+ * limGetPhyCBState
+ *
+ *FUNCTION:
+ * Based on the current state of LIM, this routine determines
+ * the correct PHY enumeration "ePhyChanBondState" to use
+ *
+ *LOGIC:
+ * Is it possible to have a common enumeration?
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return The corresponding PHY enumeration ePhyChanBondState
+ */
+ePhyChanBondState limGetPhyCBState( tpAniSirGlobal pMac )
+{
+ ePhyChanBondState cbState = PHY_SINGLE_CHANNEL_CENTERED;
+
+ if( GET_CB_OPER_STATE( pMac->lim.gCbState ))
+ {
+ if( GET_CB_SEC_CHANNEL( pMac->lim.gCbState ))
+ cbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+ else
+ cbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+ }
+ return cbState;
+}
+
+
+/**
+ * limGetHTCBState
+ *
+ *FUNCTION:
+ * This routing provides the translation of Airgo Enum to HT enum for determining
+ * secondary channel offset.
+ * Airgo Enum is required for backward compatibility purposes.
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return The corresponding HT enumeration
+ */
+
+tSirMacHTSecondaryChannelOffset limGetHTCBState(tAniCBSecondaryMode aniCBMode)
+{
+ if(aniCBMode == eANI_CB_SECONDARY_DOWN)
+ return eHT_SECONDARY_CHANNEL_OFFSET_DOWN;
+ else if(aniCBMode == eANI_CB_SECONDARY_UP)
+ return eHT_SECONDARY_CHANNEL_OFFSET_UP;
+ else
+ return eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+}
+
+
+/**
+ * limGetAniCBState
+ *
+ *FUNCTION:
+ * This routing provides the translation of HT Enum to Airgo enum for determining
+ * secondary channel offset.
+ * Airgo Enum is required for backward compatibility purposes.
+ *
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return The corresponding ANI enumeration
+ */
+
+tAniCBSecondaryMode limGetAniCBState( tSirMacHTSecondaryChannelOffset htCBMode)
+{
+ if(eHT_SECONDARY_CHANNEL_OFFSET_DOWN == htCBMode)
+ return eANI_CB_SECONDARY_DOWN;
+ else if(eHT_SECONDARY_CHANNEL_OFFSET_UP == htCBMode)
+ return eANI_CB_SECONDARY_UP;
+ else
+ return eANI_CB_SECONDARY_NONE;
+}
+
+
+/**
+ * limGetStaPeerType
+ *
+ *FUNCTION:
+ * Based on a combination of the following -
+ * 1) tDphHashNode.aniPeer
+ * 2) tDphHashNode.propCapability
+ * this API determines if a given STA is an ANI peer or not
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the tpDphHashNode of the STA
+ * under consideration
+ * @return tStaRateMode
+ */
+tStaRateMode limGetStaPeerType( tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+tStaRateMode staPeerType = eSTA_11b;
+
+ // Determine the peer-STA type
+ if( pStaDs->aniPeer )
+ {
+ if(PROP_CAPABILITY_GET( TAURUS, pStaDs->propCapability ))
+ staPeerType = eSTA_TAURUS;
+ else if( PROP_CAPABILITY_GET( TITAN, pStaDs->propCapability ))
+ staPeerType = eSTA_TITAN;
+ else
+ staPeerType = eSTA_POLARIS;
+ }
+ else if(pStaDs->mlmStaContext.htCapability)
+ staPeerType = eSTA_11n;
+ else if(pStaDs->erpEnabled)
+ staPeerType = eSTA_11bg;
+ else if(psessionEntry->limRFBand == SIR_BAND_5_GHZ)
+ staPeerType = eSTA_11a;
+
+ return staPeerType;
+}
+
+/**
+ * setupCBState()
+ *
+ *FUNCTION:
+ * This function is called during eWNI_SME_START_BSS_REQ.
+ * Based on the configured Channel Bonding mode, the
+ * appropriate Channel Bonding state is setup in the global
+ * LIM object - gCbState. This will then be subsequently used
+ * in the proprietary IE field
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param cbMode The CB mode as set by SME (WSM)
+ * @return None
+ */
+void setupCBState( tpAniSirGlobal pMac,
+ tAniCBSecondaryMode cbMode )
+{
+
+ switch( cbMode )
+ {
+ case eANI_CB_SECONDARY_DOWN:
+ SET_CB_OPER_STATE( pMac->lim.gCbState, eHAL_SET );
+ SET_CB_SEC_CHANNEL( pMac->lim.gCbState, eHAL_CLEAR );
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_LOWER) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+ // AU state is set via CFG
+ break;
+
+ case eANI_CB_SECONDARY_UP:
+ SET_CB_OPER_STATE( pMac->lim.gCbState, eHAL_SET );
+ SET_CB_SEC_CHANNEL( pMac->lim.gCbState, eHAL_SET );
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_HIGHER) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+ // AU state is set via CFG
+ break;
+
+ case eANI_CB_SECONDARY_NONE:
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_NONE) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+
+ default:
+ SET_CB_OPER_STATE( pMac->lim.gCbState, eHAL_CLEAR );
+ break;
+ }
+
+
+
+ limLog( pMac, LOG2,
+ FL("New CB State: 0x%1x for Mode %d\n"),
+ pMac->lim.gCbState,
+ cbMode );
+}
+
+/**
+ * limGetCurrentCBSecChannel()
+ *
+ *FUNCTION:
+ * This function is called to determine the current
+ * "secondary" channel when Channel Bonding is enabled
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return Channel number
+ */
+tANI_U8 limGetCurrentCBSecChannel( tpAniSirGlobal pMac,tpPESession psessionEntry)
+{
+tANI_U8 chanNum;
+
+ //
+ // FIXME - This is a HACK!!
+ // Need to have a clean way of determining the current
+ // CB secondary channel!!
+ //
+ chanNum = psessionEntry->currentOperChannel;
+ if( GET_CB_OPER_STATE( pMac->lim.gCbState ))
+ {
+ if( GET_CB_SEC_CHANNEL( pMac->lim.gCbState ))
+ chanNum += 4;
+ else
+ chanNum -= 4;
+ }
+
+ limLog( pMac, LOG4,
+ FL("Returning CB Sec Channel %1d\n"),
+ chanNum );
+
+ return chanNum;
+}
+
+
diff --git a/CORE/MAC/src/pe/lim/limPropExtsUtils.h b/CORE/MAC/src/pe/lim/limPropExtsUtils.h
new file mode 100644
index 0000000..17f2da2
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limPropExtsUtils.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limPropExtsUtils.h contains the definitions
+ * used by all LIM modules to support proprietary features.
+ * Author: Chandra Modumudi
+ * Date: 12/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_PROP_EXTS_UTILS_H
+#define __LIM_PROP_EXTS_UTILS_H
+
+
+// Function templates
+void limQuietBss(tpAniSirGlobal, tANI_U32);
+void limCleanupMeasData(tpAniSirGlobal);
+void limDeleteMeasTimers(tpAniSirGlobal);
+void limStopMeasTimers(tpAniSirGlobal pMac);
+void limCleanupMeasResources(tpAniSirGlobal);
+void limRestorePreLearnState(tpAniSirGlobal);
+void limCollectMeasurementData(tpAniSirGlobal,
+ tANI_U32 *, tpSchBeaconStruct);
+void limCollectRSSI(tpAniSirGlobal);
+void limDeleteCurrentBssWdsNode(tpAniSirGlobal);
+tANI_U32 limComputeAvg(tpAniSirGlobal, tANI_U32, tANI_U32);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+// Timer Handlers
+void limMeasurementTimerHandler(VOID*, tANI_U32);
+#endif
+
+/// Function to extract AP's HCF capability from IE fields
+void limExtractApCapability(tpAniSirGlobal, tANI_U8 *, tANI_U16, tANI_U8 *, tANI_U16 *, tANI_U8 *, tPowerdBm*);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/// Function to extract current Learn channel
+tANI_U8 limGetCurrentLearnChannel(tpAniSirGlobal);
+// Determine if a newly discovered BSS is TITAN-compatible
+void handleNonTitanBss( tpAniSirGlobal, tSirNeighborBssWdsInfo );
+#endif
+ePhyChanBondState limGetPhyCBState( tpAniSirGlobal );
+tStaRateMode limGetStaPeerType( tpAniSirGlobal, tpDphHashNode ,tpPESession);
+void setupCBState( tpAniSirGlobal, tAniCBSecondaryMode );
+
+tANI_U8 limGetCurrentCBSecChannel( tpAniSirGlobal,tpPESession );
+
+#endif /* __LIM_PROP_EXTS_UTILS_H */
+
diff --git a/CORE/MAC/src/pe/lim/limRoamingAlgo.c b/CORE/MAC/src/pe/lim/limRoamingAlgo.c
new file mode 100644
index 0000000..a77140a
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limRoamingAlgo.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limRoamingAlgo.cc contains the code for LIM
+ * algorithms.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+#include "limTypes.h"
+#include "limTimerUtils.h"
+
+
+
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA) || defined(ANI_AP_CLIENT_SDK)
+/** ----------------------------------------------------------------------
+\fn limSelectsBackgroundScanMode()
+\brief This function is called by limIsBackgroundScanAllowed().
+\ Here LIM decides whether we shall enforce this background
+\ scan or let HAL decide whether to proceed with the background
+\ scan as HAL sees fits. LIM shall enforce background scan if:
+\ 1) station is not in link established state
+\ 2) station is in link established state, but there has been
+\ max number of consecutive background scan failure.
+\
+\param tpAniSirGlobal pMac
+\return none
+\ ------------------------------------------------------------------------- */
+tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal pMac)
+{
+ tANI_U32 cfgVal;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, &cfgVal) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE value\n"));
+ return eSIR_NORMAL_BACKGROUND_SCAN;
+ }
+
+ if (cfgVal == 0)
+ return eSIR_NORMAL_BACKGROUND_SCAN;
+
+ /* If the "number of consecutive background scan failure"
+ * exceeds the maximum allowed, then LIM shall trigger an
+ * aggressive background scan.
+ */
+ if (pMac->lim.gLimNumOfConsecutiveBkgndScanFailure >= cfgVal)
+ {
+ pMac->lim.gLimNumOfForcedBkgndScan += 1;
+ limLog(pMac, LOGE,
+ FL("Had %d consec scan fail(when expect < %d). Trigger AGGRESSIVE bkgnd scan.\n"),
+ pMac->lim.gLimNumOfConsecutiveBkgndScanFailure, cfgVal);
+ return eSIR_AGGRESSIVE_BACKGROUND_SCAN;
+ }
+
+ return eSIR_NORMAL_BACKGROUND_SCAN;
+}
+
+
+/** -----------------------------------------------------------
+\fn limIsBackgroundScanAllowed
+\brief This function determines if background scan should be
+\ allowed. It is called by limTriggerBackgroundScan().
+\param tpAniSirGlobal pMac
+\return none
+\ ------------------------------------------------------------- */
+static tANI_U8 limIsBackgroundScanAllowed(tpAniSirGlobal pMac)
+{
+ // if we are in the middle of a scan already, skip the background scan
+ if (limIsSystemInScanState(pMac) ||
+ (pMac->lim.gLimBackgroundScanDisable) ||
+ (pMac->lim.gLimForceBackgroundScanDisable) ||
+ (pMac->lim.gLimBackgroundScanTerminate))
+ return false;
+
+ //need to do background scan in IBSS mode.
+ if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ {
+ if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE)
+ return false;
+ return true;
+ }
+
+ // If station is not in link established state, then skip background scan
+ if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) && (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) )
+ return false;
+
+ /* now that we have checked for scan state, check for other transitional
+ * states which should not be interrupted by scans
+ */
+ if ((! (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ) &&
+ (! (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE) ) &&
+ (! (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE) ) )
+ return false;
+
+ return true;
+}
+
+
+/** ---------------------------------------------------------------
+\fn limTriggerBackgroundScan()
+\brief This function is called upon background scan interval
+\ when there is an exisiting link with an AP.
+\ SME_SCAN_REQ is issued to SME state machine with Active
+\ scanning is performed on one channel at a time.
+\
+\ Assumptions:
+\ Valid channel list at CFG is either populated by Roaming
+\ algorithm upon determining/selecting a regulatory domain
+\ or by default has all 36 possible channels.
+\
+\param tpAniSirGlobal pMac
+\return none
+\ ----------------------------------------------------------------- */
+void limTriggerBackgroundScan(tpAniSirGlobal pMac)
+{
+ tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN;
+ tANI_U32 ssidLen = SIR_MAC_MAX_SSID_LENGTH;
+ tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN];
+ tSirSmeScanReq smeScanReq;
+ tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ tSirBackgroundScanMode backgroundScan;
+
+ PELOG1(limLog(pMac, LOG1, FL("Background Scan: %d success, %d consec fail \n"),
+ pMac->lim.gLimNumOfBackgroundScanSuccess, pMac->lim.gLimNumOfConsecutiveBkgndScanFailure);)
+
+ if (! limIsBackgroundScanAllowed(pMac))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Skipping Background Scan \n"));)
+ return;
+ }
+
+ // Get background scan channel list from CFG
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST,
+ (tANI_U8 *) bgScanChannelList,
+ (tANI_U32 *) &len) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Valid channel list from CFG.
+ * Log error.
+ */
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list\n"));)
+
+ return;
+ }
+
+ // Time to perform background scan. Prepare and issue
+ // SME_SCAN_REQ to SME State machine
+ smeScanReq.messageType = eWNI_SME_SCAN_REQ;
+ smeScanReq.length = sizeof(tSirSmeScanReq);
+ smeScanReq.bssType = eSIR_INFRASTRUCTURE_MODE;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) smeScanReq.bssId,
+ (tANI_U8 *) &bcAddr, sizeof(tSirMacAddr));
+
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SSID,
+ (tANI_U8 *) (smeScanReq.ssId[0].ssId),
+ (tANI_U32 *) &ssidLen) != eSIR_SUCCESS)
+ {
+ /// Could not get SSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve SSID\n"));
+ }
+ smeScanReq.ssId[0].length = (tANI_U8) ssidLen;
+ smeScanReq.numSsid = 1;
+
+ smeScanReq.scanType = eSIR_ACTIVE_SCAN;
+ smeScanReq.sessionId = 0;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
+ &smeScanReq.minChannelTime) != eSIR_SUCCESS)
+ {
+ /// Could not get minChlTime value from CFG. Log error.
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve minChlTime value\n"));)
+
+ return;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+ &smeScanReq.maxChannelTime) != eSIR_SUCCESS)
+ {
+ /// Could not get maxChlTime value from CFG. Log error.
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve maxChlTime value\n"));)
+
+ return;
+ }
+
+ smeScanReq.returnAfterFirstMatch = 0;
+ smeScanReq.returnUniqueResults = 1;
+
+ //At the first channel scan, clear the cached results
+ if(pMac->lim.gLimBackgroundScanChannelId == 0)
+ {
+ smeScanReq.returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS;
+ }
+ else
+ {
+ smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS;
+ }
+
+
+ smeScanReq.channelList.numChannels = 1;
+ if (pMac->lim.gLimBackgroundScanChannelId >= len)
+ {
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+
+ PELOGE(limLog(pMac, LOGE, FL("Skipping Background Scan since the channel list is exhausted.\n"));)
+ PELOGE(limLog(pMac, LOGE, FL("SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication to start the background scan again.\n"));)
+
+ /* Stop the BG scan timer here. SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD
+ * indication to start the background scan again.
+ */
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate BackgroundScanTimer timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate BackgroundScanTimer timer\n"));
+ }
+ }
+
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+
+ PELOGE(limLog(pMac, LOGE, FL("Send dummy scan with returnFreshResults as 0 to report BG scan results to SME.\n"));)
+ return;
+ }
+ smeScanReq.channelList.channelNumber[0] =
+ bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId++];
+
+ smeScanReq.uIEFieldLen = 0;
+ smeScanReq.uIEFieldOffset = sizeof(tSirSmeScanReq);
+
+ backgroundScan = limSelectsBackgroundScanMode(pMac);
+ PELOG1(limLog(pMac, LOG1, FL("Performing (mode %d) Background Scan \n"), backgroundScan);)
+ smeScanReq.backgroundScanMode = backgroundScan;
+
+ //determine whether to send the results or not, If so, notify the BG scan results to SME
+ if (pMac->lim.gLimBackgroundScanChannelId >= len)
+ {
+ pMac->lim.gLimReportBackgroundScanResults = TRUE;
+ }
+
+ limPostSmeMessage(pMac,
+ eWNI_SME_SCAN_REQ,
+ (tANI_U32 *) &smeScanReq);
+} /*** limTriggerBackgroundScan() ***/
+
+
+/** ----------------------------------------------------------------------
+\fn limAbortBackgroundScan
+\brief This function aborts background scan and send scan
+\ response to SME.
+\param tpAniSirGlobal pMac
+\return none
+\ ------------------------------------------------------------------------- */
+void limAbortBackgroundScan(tpAniSirGlobal pMac)
+{
+ tANI_U16 scanRspLen = 8;
+
+ if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
+ {
+ limLog(pMac, LOGE, FL("Abort Background Scan \n"));
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+ }
+
+ pMac->lim.gLimBackgroundScanTerminate = TRUE;
+ pMac->lim.gLimBackgroundScanStarted = FALSE;
+
+ if (pMac->lim.gLimSmeScanResultLength == 0)
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
+ else
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp) +
+ pMac->lim.gLimSmeScanResultLength -
+ sizeof(tSirBssDescription);
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0);
+ }
+ }
+
+ // reset background scan variables
+ pMac->lim.gLimBackgroundScanChannelId = 0;
+ return;
+}
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c
new file mode 100644
index 0000000..a866152
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c
@@ -0,0 +1,922 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limScanResultUtils.cc contains the utility functions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limSerDesUtils.h"
+#include "limApi.h"
+#include "limSession.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+
+
+
+/**
+ * limDeactiveMinChannelTimerDuringScan()
+ *
+ *FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to deactivate MIN channel
+ * timer if running.
+ *
+ * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return eSIR_SUCCESS in case of success
+ */
+
+tANI_U32
+limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac)
+{
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE))
+ {
+ /**
+ * Beacon/Probe Response is received during active scanning.
+ * Deactivate MIN channel timer if running.
+ */
+
+ limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_MAX_CHANNEL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer)
+ == TX_TIMER_ERROR)
+ {
+ /// Could not activate max channel timer.
+ // Log error
+ limLog(pMac,LOGP, FL("could not activate max channel timer\n"));
+
+ limCompleteMlmScan(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
+ return TX_TIMER_ERROR;
+ }
+ }
+ return eSIR_SUCCESS;
+} /*** end limDeactivateMinChannelTimerDuringScan() ***/
+
+
+
+/**
+ * limCollectBssDescription()
+ *
+ *FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * frame matches scan criteria, collect BSS description
+ * and add it to cached scan results.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBPR - Pointer to parsed Beacon/Probe Response structure
+ * @param pRxPacketInfo - Pointer to Received frame's BD
+ * ---------if defined WLAN_FEATURE_VOWIFI------
+ * @param fScanning - flag to indicate if it is during scan.
+ * ---------------------------------------------
+ *
+ * @return None
+ */
+#if defined WLAN_FEATURE_VOWIFI
+void
+limCollectBssDescription(tpAniSirGlobal pMac,
+ tSirBssDescription *pBssDescr,
+ tpSirProbeRespBeacon pBPR,
+ tANI_U8 *pRxPacketInfo,
+ tANI_U8 fScanning)
+#else
+void
+limCollectBssDescription(tpAniSirGlobal pMac,
+ tSirBssDescription *pBssDescr,
+ tpSirProbeRespBeacon pBPR,
+ tANI_U8 *pRxPacketInfo)
+#endif
+{
+ tANI_U8 *pBody;
+ tANI_U32 ieLen = 0;
+ tpSirMacMgmtHdr pHdr;
+ tANI_U8 channelNum;
+ tANI_U8 rxChannel;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
+ rxChannel = WDA_GET_RX_CH(pRxPacketInfo);
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+
+ /**
+ * Length of BSS desription is without length of
+ * length itself and length of pointer
+ * that holds the next BSS description
+ */
+ pBssDescr->length = (tANI_U16)(
+ sizeof(tSirBssDescription) - sizeof(tANI_U16) -
+ sizeof(tANI_U32) + ieLen);
+
+ // Copy BSS Id
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pBssDescr->bssId,
+ (tANI_U8 *) pHdr->bssId,
+ sizeof(tSirMacAddr));
+
+ // Copy Timestamp, Beacon Interval and Capability Info
+ pBssDescr->scanSysTimeMsec = vos_timer_get_system_time();
+
+ pBssDescr->timeStamp[0] = pBPR->timeStamp[0];
+ pBssDescr->timeStamp[1] = pBPR->timeStamp[1];
+ pBssDescr->beaconInterval = pBPR->beaconInterval;
+ pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo);
+
+
+ /*
+ * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut
+ * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz
+ * band, so not relying on the 'last Scanned Channel' stored in LIM.
+ * Instead use the value returned by RXP in BD. This the the same value which HAL programs into
+ * RXP before every channel switch.
+ * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from
+ * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen.
+ * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it
+ * is not present in the beacon, we go for the channel info present in RXP.
+ * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel.
+ * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices.
+ */
+ pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR);
+
+ if (pBssDescr->channelId == 0)
+ {
+ /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
+ /* Unmapped the channel.This We have to do since we have done mapping in the hal to
+ overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/
+ if (!( rxChannel = limUnmapChannel(rxChannel)))
+ {
+ rxChannel = pMac->lim.gLimCurrentScanChannelId;
+ }
+ pBssDescr->channelId = rxChannel;
+ }
+
+ pBssDescr->channelIdSelf = rxChannel;
+ pBssDescr->titanHtCaps = 0;
+
+ //FIXME_CBMODE : need to seperate out TITAN and HT CB mode.
+ //HT neighbor with channel bonding
+ if( pBPR->HTCaps.present )
+ {
+ tAniTitanHtCapabilityInfo titanHtCaps = 0;
+ limGetHtCbAdminState(pMac, pBPR->HTCaps, &titanHtCaps);
+ if( pBPR->HTInfo.present &&
+ pBPR->HTInfo.secondaryChannelOffset )
+ {
+
+ limGetHtCbOpState( pMac,
+ pBPR->HTInfo,
+ &titanHtCaps );
+ }
+ pBssDescr->titanHtCaps = (tANI_U32) titanHtCaps;
+ }
+
+ // Is this is a TITAN neighbor?
+ else if( pBPR->propIEinfo.aniIndicator &&
+ pBPR->propIEinfo.titanPresent )
+ {
+ tAniTitanHtCapabilityInfo titanHtCaps = 0;
+ pBssDescr->titanHtCaps = (tANI_U32) titanHtCaps;
+ }
+
+ //set the network type in bss description
+ channelNum = pBssDescr->channelId;
+ pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR);
+
+ pBssDescr->aniIndicator = pBPR->propIEinfo.aniIndicator;
+
+ // Copy RSSI & SINR from BD
+
+ PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** ");
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 );
+ sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );)
+
+ pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo);
+
+ //SINR no longer reported by HW
+ pBssDescr->sinr = 0;
+
+ pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( fScanning )
+ {
+ rrmGetStartTSF( pMac, pBssDescr->startTSF );
+ pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo);
+ }
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // MobilityDomain
+ pBssDescr->mdie[0] = 0;
+ pBssDescr->mdie[1] = 0;
+ pBssDescr->mdie[2] = 0;
+ pBssDescr->mdiePresent = FALSE;
+ // If mdie is present in the probe resp we
+ // fill it in the bss description
+ if( pBPR->mdiePresent)
+ {
+ pBssDescr->mdiePresent = TRUE;
+ pBssDescr->mdie[0] = pBPR->mdie[0];
+ pBssDescr->mdie[1] = pBPR->mdie[1];
+ pBssDescr->mdie[2] = pBPR->mdie[2];
+ }
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ pBssDescr->QBSSLoad_present = FALSE;
+ pBssDescr->QBSSLoad_avail = 0;
+ if( pBPR->QBSSLoad.present)
+ {
+ pBssDescr->QBSSLoad_present = TRUE;
+ pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail;
+ }
+#endif
+ // Copy IE fields
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pBssDescr->ieFields,
+ pBody + SIR_MAC_B_PR_SSID_OFFSET,
+ ieLen);
+
+ //sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGW, (tANI_U8 *) pBssDescr, pBssDescr->length + 2 );
+ limLog( pMac, LOG3,
+ FL("Collected BSS Description for Channel(%1d), length(%u), aniIndicator(%d), IE Fields(%u)\n"),
+ pBssDescr->channelId,
+ pBssDescr->length,
+ pBssDescr->aniIndicator,
+ ieLen );
+
+ return;
+} /*** end limCollectBssDescription() ***/
+
+/**
+ * limIsScanRequestedSSID()
+ *
+ *FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * SSID is present in the list of requested SSIDs in scan
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param ssId - SSID Received in beacons/Probe responses that is compared against the
+ requeusted SSID in scan list
+ * ---------------------------------------------
+ *
+ * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise
+ */
+
+tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId)
+{
+ tANI_U8 i = 0;
+
+ for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++)
+ {
+ if ( eANI_BOOLEAN_TRUE == palEqualMemory( pMac->hHdd,(tANI_U8 *) ssId,
+ (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i],
+ (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1)))
+ {
+ return eANI_BOOLEAN_TRUE;
+ }
+ }
+ return eANI_BOOLEAN_FALSE;
+}
+
+/**
+ * limCheckAndAddBssDescription()
+ *
+ *FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * frame matches scan criteria, collect BSS description
+ * and add it to cached scan results.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBPR - Pointer to parsed Beacon/Probe Response structure
+ * @param pRxPacketInfo - Pointer to Received frame's BD
+ * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon
+ *
+ * @return None
+ */
+
+void
+limCheckAndAddBssDescription(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBPR,
+ tANI_U8 *pRxPacketInfo,
+ tANI_BOOLEAN fScanning,
+ tANI_U8 fProbeRsp)
+{
+ tLimScanResultNode *pBssDescr;
+ tANI_U32 frameLen, ieLen = 0;
+ tANI_U8 rxChannelInBeacon = 0;
+ eHalStatus status;
+
+#ifdef WLAN_FEATURE_P2P
+ tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ tANI_BOOLEAN fFound = FALSE;
+ tpSirMacDataHdr3a pHdr;
+
+ pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo);
+
+ //Checking if scanning for a particular BSSID
+ if ((fScanning) && (pMac->lim.gpLimMlmScanReq))
+ {
+ fFound = palEqualMemory(pMac->hHdd, pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6);
+ if (!fFound)
+ {
+ if ((pMac->lim.gpLimMlmScanReq->p2pSearch) &&
+ (palEqualMemory(pMac->hHdd, pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress,
+ &pMac->lim.gpLimMlmScanReq->bssId, 6)))
+ {
+ fFound = eANI_BOOLEAN_TRUE;
+ }
+ }
+ }
+#endif
+
+ /**
+ * Compare SSID with the one sent in
+ * Probe Request frame, if any.
+ * If they don't match, ignore the
+ * Beacon frame.
+ * pMac->lim.gLimMlmScanReq->ssId.length == 0
+ * indicates Broadcast SSID.
+ * When gLimReturnAfterFirstMatch is set, it means the scan has to match
+ * a SSID (if it is also set). Ignore the other BSS in that case.
+ */
+
+ if (((fScanning) && ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 )
+ && (pMac->lim.gpLimMlmScanReq->numSsid) &&
+ !limIsScanRequestedSSID(pMac, &pBPR->ssId))
+ || (!fFound && (pMac->lim.gpLimMlmScanReq && pMac->lim.gpLimMlmScanReq->bssId) &&
+ !palEqualMemory(pMac->hHdd, bssid, &pMac->lim.gpLimMlmScanReq->bssId, 6))
+ )
+ {
+ /**
+ * Received SSID does not match with
+ * the one we're scanning for.
+ * Ignore received Beacon frame
+ */
+
+ return;
+ }
+
+ /* There is no point in caching & reporting the scan results for APs
+ * which are in the process of switching the channel. So, we are not
+ * caching the scan results for APs which are adverzing the channel-switch
+ * element in their beacons and probe responses.
+ */
+ if(pBPR->channelSwitchPresent)
+ {
+ return;
+ }
+
+ /* If beacon/probe resp DS param channel does not match with
+ * RX BD channel then don't save the results. It might be a beacon
+ * from another channel heard as noise on the current scanning channel
+ */
+
+ if (pBPR->dsParamsPresent)
+ {
+ /* This means that we are in 2.4GHz mode or 5GHz 11n mode */
+ rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR);
+ if (rxChannelInBeacon < 15)
+ {
+ /* This means that we are in 2.4GHz mode */
+ if(WDA_GET_RX_CH(pRxPacketInfo) != rxChannelInBeacon)
+ {
+ limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. "
+ "Channel in beacon" " %d\n"),
+ WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR));
+ return;
+ }
+ }
+ }
+
+ /**
+ * Allocate buffer to hold BSS description from
+ * received Beacon frame.
+ * Include size of fixed fields and IEs length
+ */
+
+ ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
+ frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); // Sizeof(tANI_U32) is for ieFields[1]
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pBssDescr, frameLen))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call for palAllocateMemory failed for storing BSS description\n"));
+
+ return;
+ }
+
+ // In scan state, store scan result.
+#if defined WLAN_FEATURE_VOWIFI
+ limCollectBssDescription(pMac, &pBssDescr->bssDescription,
+ pBPR, pRxPacketInfo, fScanning);
+#else
+ limCollectBssDescription(pMac, &pBssDescr->bssDescription,
+ pBPR, pRxPacketInfo);
+#endif
+
+ pBssDescr->bssDescription.fProbeRsp = fProbeRsp;
+
+ pBssDescr->next = NULL;
+
+ /**
+ * Depending on whether to store unique or all
+ * scan results, pass hash update/add parameter
+ */
+
+ //If it is not scanning, only save unique results
+ if (pMac->lim.gLimReturnUniqueResults || (!fScanning))
+ {
+ status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE);
+ }
+ else
+ {
+ status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD);
+ }
+
+ if(fScanning)
+ {
+ if ((pBssDescr->bssDescription.channelId <= 14) &&
+ (pMac->lim.gLimReturnAfterFirstMatch & 0x40) &&
+ pBPR->countryInfoPresent)
+ pMac->lim.gLim24Band11dScanDone = 1;
+
+ if ((pBssDescr->bssDescription.channelId > 14) &&
+ (pMac->lim.gLimReturnAfterFirstMatch & 0x80) &&
+ pBPR->countryInfoPresent)
+ pMac->lim.gLim50Band11dScanDone = 1;
+
+ if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) ||
+ ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) ||
+ ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) )
+#ifdef WLAN_FEATURE_P2P
+ || fFound
+#endif
+ )
+/*
+ if ((pMac->lim.gLimReturnAfterFirstMatch & 0x01) ||
+ (pMac->lim.gLim24Band11dScanDone &&
+ !(pMac->lim.gLimReturnAfterFirstMatch & 0xC0)) ||
+ (pMac->lim.gLim50Band11dScanDone &&
+ !(pMac->lim.gLimReturnAfterFirstMatch & 0xC0)) ||
+ (pMac->lim.gLim24Band11dScanDone &&
+ pMac->lim.gLim50Band11dScanDone &&
+ pMac->lim.gLimReturnAfterFirstMatch & 0xC0))
+*/
+ {
+ /**
+ * Stop scanning and return the BSS description(s)
+ * collected so far.
+ */
+ limLog(pMac,
+ LOGW,
+ FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id\n"),
+ pMac->lim.gLim24Band11dScanDone,
+ pMac->lim.gLim50Band11dScanDone);
+
+ //Need to disable the timers. If they fire, they will send END_SCAN
+ //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState
+ 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 );
+ //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE );
+ }
+ }//(eANI_BOOLEAN_TRUE == fScanning)
+
+ if( eHAL_STATUS_SUCCESS != status )
+ {
+ palFreeMemory( pMac->hHdd, pBssDescr );
+ }
+} /****** end limCheckAndAddBssDescription() ******/
+
+
+
+/**
+ * limScanHashFunction()
+ *
+ *FUNCTION:
+ * This function is called during scan hash entry operations
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param bssId - Received BSSid
+ *
+ * @return Hash index
+ */
+
+tANI_U8
+limScanHashFunction(tSirMacAddr bssId)
+{
+ tANI_U16 i, hash = 0;
+
+ for (i = 0; i < sizeof(tSirMacAddr); i++)
+ hash += bssId[i];
+
+ return hash % LIM_MAX_NUM_OF_SCAN_RESULTS;
+} /****** end limScanHashFunction() ******/
+
+
+
+/**
+ * limInitHashTable()
+ *
+ *FUNCTION:
+ * This function is called upon receiving SME_START_REQ
+ * to initialize global cached scan hash table
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limInitHashTable(tpAniSirGlobal pMac)
+{
+ tANI_U16 i;
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ pMac->lim.gLimCachedScanHashTable[i] = NULL;
+} /****** end limInitHashTable() ******/
+
+
+
+/**
+ * limLookupNaddHashEntry()
+ *
+ *FUNCTION:
+ * This function is called upon receiving a Beacon or
+ * Probe Response frame during scan phase to store
+ * received BSS description into scan result hash table.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBssDescr - Pointer to BSS description to be
+ * added to the scan result hash table.
+ * @param action - Indicates action to be performed
+ * when same BSS description is found. This is
+ * dependent on whether unique scan result to
+ * be stored or not.
+ *
+ * @return None
+ */
+
+eHalStatus
+limLookupNaddHashEntry(tpAniSirGlobal pMac,
+ tLimScanResultNode *pBssDescr, tANI_U8 action)
+{
+ tANI_U8 index, ssidLen = 0;
+ tANI_U8 found = false;
+ tLimScanResultNode *ptemp, *pprev;
+ tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
+ int idx, len;
+ tANI_U8 *pbIe;
+
+ index = limScanHashFunction(pBssDescr->bssDescription.bssId);
+ ptemp = pMac->lim.gLimCachedScanHashTable[index];
+
+ //ieFields start with TLV of SSID IE
+ ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+ pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
+
+ for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
+ {
+ //For infrastructure, only check BSSID. For IBSS, check more
+ pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo;
+ if((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first
+ (palEqualMemory( pMac->hHdd,(tANI_U8 *) pBssDescr->bssDescription.bssId,
+ (tANI_U8 *) ptemp->bssDescription.bssId,
+ sizeof(tSirMacAddr))) && //matching BSSID
+ ((pSirCapTemp->ess) || //we are done for infrastructure
+ //For IBSS, matching SSID, nwType and channelId
+ ((palEqualMemory( pMac->hHdd,((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
+ ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
+ (tANI_U8) (ssidLen + 1)) &&
+ (pBssDescr->bssDescription.nwType ==
+ ptemp->bssDescription.nwType) &&
+ (pBssDescr->bssDescription.channelId ==
+ ptemp->bssDescription.channelId))))
+ )
+ {
+ // Found the same BSS description
+ if (action == LIM_HASH_UPDATE)
+ {
+ if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp)
+ {
+ //We get a different, save the old frame WSC IE if it is there
+ idx = 0;
+ len = ptemp->bssDescription.length - sizeof(tSirBssDescription) +
+ sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
+ pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields;
+ //Save WPS IE if it exists
+ pBssDescr->bssDescription.WscIeLen = 0;
+ while(idx < len)
+ {
+ if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
+ (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
+ {
+ //Found it
+ if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
+ {
+ palCopyMemory(pMac->hHdd, pBssDescr->bssDescription.WscIeProbeRsp,
+ pbIe, pbIe[1] + 2);
+ pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2;
+ }
+ break;
+ }
+ idx += pbIe[1] + 2;
+ pbIe += pbIe[1] + 2;
+ }
+ }
+
+
+ if(NULL != pMac->lim.gpLimMlmScanReq)
+ {
+ if((pMac->lim.gpLimMlmScanReq->numSsid)&&
+ ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *)
+ &pBssDescr->bssDescription.ieFields + 1))))
+ return eHAL_STATUS_FAILURE;
+ }
+
+ // Delete this entry
+ if (ptemp == pMac->lim.gLimCachedScanHashTable[index])
+ pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next;
+ else
+ pprev->next = ptemp->next;
+
+ pMac->lim.gLimMlmScanResultLength -=
+ ptemp->bssDescription.length + sizeof(tANI_U16);
+
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) ptemp);
+ }
+ found = true;
+ break;
+ }
+ }
+
+ // Add this BSS description at same index
+ if (pprev == pMac->lim.gLimCachedScanHashTable[index])
+ {
+ pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index];
+ pMac->lim.gLimCachedScanHashTable[index] = pBssDescr;
+ }
+ else
+ {
+ pBssDescr->next = pprev->next;
+ pprev->next = pBssDescr;
+ }
+ pMac->lim.gLimMlmScanResultLength +=
+ pBssDescr->bssDescription.length + sizeof(tANI_U16);
+
+ PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"),
+ pBssDescr->bssDescription.length,
+ pMac->lim.gLimMlmScanResultLength);
+ limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);)
+
+ // Send new BSS found indication to HDD if CFG option is set
+ if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr);
+
+ //
+ // TODO: IF applicable, do we need to send:
+ // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF
+ // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP
+ //
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+
+/**
+ * limDeleteHashEntry()
+ *
+ *FUNCTION:
+ * This function is called upon to delete
+ * a BSS description from scan result hash table.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * Yet to find the utility of the function
+ *
+ * @param pBssDescr - Pointer to BSS description to be
+ * deleted from the scan result hash table.
+ *
+ * @return None
+ */
+
+void limDeleteHashEntry(tLimScanResultNode *pBssDescr)
+{
+} /****** end limDeleteHashEntry() ******/
+
+
+
+/**
+ * limCopyScanResult()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() while
+ * sending SME_SCAN_RSP with scan result to HDD.
+ *
+ *LOGIC:
+ * This function traverses the scan list stored in scan hash table
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pDest - Destination pointer
+ *
+ * @return None
+ */
+
+void
+limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest)
+{
+ tLimScanResultNode *ptemp;
+ tANI_U16 i;
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ {
+ if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL)
+ {
+ while(ptemp)
+ {
+ /// Copy entire BSS description including length
+ palCopyMemory( pMac->hHdd, pDest,
+ (tANI_U8 *) &ptemp->bssDescription,
+ ptemp->bssDescription.length + 2);
+ pDest += ptemp->bssDescription.length + 2;
+ ptemp = ptemp->next;
+ }
+ }
+ }
+} /****** end limCopyScanResult() ******/
+
+
+
+/**
+ * limDeleteCachedScanResults()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_SCAN_REQ with fresh scan result flag set.
+ *
+ *LOGIC:
+ * This function traverses the scan list stored in scan hash table
+ * and deletes the entries if any
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limDeleteCachedScanResults(tpAniSirGlobal pMac)
+{
+ tLimScanResultNode *pNode, *pNextNode;
+ tANI_U16 i;
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ {
+ if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL)
+ {
+ while (pNode)
+ {
+ pNextNode = pNode->next;
+
+ // Delete the current node
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pNode);
+
+ pNode = pNextNode;
+ }
+ }
+ }
+
+ pMac->lim.gLimSmeScanResultLength = 0;
+} /****** end limDeleteCachedScanResults() ******/
+
+
+
+/**
+ * limReInitScanResults()
+ *
+ *FUNCTION:
+ * This function is called delete exisiting scan results
+ * and initialize the scan hash table
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limReInitScanResults(tpAniSirGlobal pMac)
+{
+ limDeleteCachedScanResults(pMac);
+ limInitHashTable(pMac);
+
+ // !!LAC - need to clear out the global scan result length
+ // since the list was just purged from the hash table.
+ pMac->lim.gLimMlmScanResultLength = 0;
+
+} /****** end limReInitScanResults() ******/
diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.h b/CORE/MAC/src/pe/lim/limScanResultUtils.h
new file mode 100644
index 0000000..0913ea6
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limScanResultUtils.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limScanResultUtils.h contains the utility definitions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SCAN_UTILS_H
+#define __LIM_SCAN_UTILS_H
+
+#include "parserApi.h"
+#include "limTypes.h"
+
+// Scan result hash related functions
+tANI_U8 limScanHashFunction(tSirMacAddr);
+void limInitHashTable(tpAniSirGlobal);
+eHalStatus
+ limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8);
+void limDeleteHashEntry(tLimScanResultNode *);
+void limDeleteCachedScanResults(tpAniSirGlobal);
+void limRestorePreScanState(tpAniSirGlobal);
+void limCopyScanResult(tpAniSirGlobal, tANI_U8 *);
+void limReInitScanResults(tpAniSirGlobal);
+tANI_U32 limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal);
+void limCheckAndAddBssDescription(tpAniSirGlobal, tpSirProbeRespBeacon, tANI_U8 *, tANI_BOOLEAN, tANI_U8);
+#if defined WLAN_FEATURE_VOWIFI
+void limCollectBssDescription(tpAniSirGlobal,
+ tSirBssDescription *,
+ tpSirProbeRespBeacon,
+ tANI_U8 *,
+ tANI_U8);
+#else
+void limCollectBssDescription(tpAniSirGlobal,
+ tSirBssDescription *,
+ tpSirProbeRespBeacon,
+ tANI_U8 *);
+#endif
+
+#endif /* __LIM_SCAN_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limSecurityUtils.c b/CORE/MAC/src/pe/lim/limSecurityUtils.c
new file mode 100644
index 0000000..d1c774f
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSecurityUtils.c
@@ -0,0 +1,1469 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limUtils.cc contains the utility functions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "aniGlobal.h"
+#include "wniApi.h"
+
+#include "sirCommon.h"
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#include "halCommonApi.h"
+#endif
+
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limSecurityUtils.h"
+#include "limSession.h"
+
+
+#define LIM_SEED_LENGTH 16
+
+/**
+ * limIsAuthAlgoSupported()
+ *
+ *FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed authentication algorithm is enabled
+ * or not
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param authType Indicates MAC based authentication type
+ * (eSIR_OPEN_SYSTEM or eSIR_SHARED_KEY)
+ * If Shared Key authentication to be used,
+ * 'Privacy Option Implemented' flag is also
+ * checked.
+ *
+ * @return true if passed authType is enabled else false
+ */
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_U8
+limIsAuthAlgoSupported(tpAniSirGlobal pMac, tAniAuthType authType, tpPESession psessionEntry)
+#else
+tANI_U8
+limIsAuthAlgoSupported(tpAniSirGlobal pMac, tAniAuthType authType)
+#endif
+{
+ tANI_U32 algoEnable, privacyOptImp;
+
+ if (authType == eSIR_OPEN_SYSTEM)
+ {
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ if((psessionEntry->authType == eSIR_OPEN_SYSTEM) || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+ return true;
+ else
+ return false;
+ }
+#endif
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE,
+ &algoEnable) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthAlgo1 Enable value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE,
+ FL("could not retrieve AuthAlgo1 Enable value\n"));
+
+ return false;
+ }
+ else
+ return ( (algoEnable > 0 ? true : false) );
+ }
+ else
+ {
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ if((psessionEntry->authType == eSIR_SHARED_KEY) || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+ algoEnable = true;
+ else
+ algoEnable = false;
+
+ }
+ else
+#endif
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHARED_KEY_AUTH_ENABLE,
+ &algoEnable) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthAlgo2 Enable value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE,
+ FL("could not retrieve AuthAlgo2 Enable value\n"));
+
+ return false;
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ privacyOptImp = psessionEntry->privacy;
+ }
+ else
+#endif
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &privacyOptImp) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get PrivacyOptionImplemented value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE,
+ FL("could not retrieve PrivacyOptImplemented value\n"));
+
+ return false;
+ }
+ return (algoEnable && privacyOptImp);
+ }
+} /****** end limIsAuthAlgoSupported() ******/
+
+
+
+/**
+ * limInitPreAuthList
+ *
+ *FUNCTION:
+ * This function is called while starting a BSS at AP
+ * to initialize MAC authenticated STA list. This may also be called
+ * while joining/starting an IBSS if MAC authentication is allowed
+ * in IBSS mode.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limInitPreAuthList(tpAniSirGlobal pMac)
+{
+ pMac->lim.pLimPreAuthList = NULL;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE )
+ {
+ tANI_U32 authClnupTimeout;
+ //tANI_U32 cfgValue;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PREAUTH_CLNUP_TIMEOUT,
+ &authClnupTimeout) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get PreAuthClnupTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGE,
+ FL("could not retrieve PreAuthClnupTimeout value\n"));
+
+ return;
+ }
+ authClnupTimeout = SYS_MS_TO_TICKS(authClnupTimeout);
+
+ /// Create and start periodic pre-auth context cleanup timeout
+ if (tx_timer_create(&pMac->lim.limTimers.gLimPreAuthClnupTimer,
+ "preAuthCleanup",
+ limTimerHandler,
+ SIR_LIM_PREAUTH_CLNUP_TIMEOUT,
+ authClnupTimeout, authClnupTimeout,
+ TX_AUTO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create PreAuthCleanup timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create PreAuthCleanup timer\n"));
+
+ return;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(&pMac->lim.limTimers.gLimPreAuthClnupTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+ PELOG1(limLog(pMac, LOG1,
+ FL("Created pre-auth cleanup timer\n"));)
+
+ }
+#endif
+} /*** end limInitPreAuthList() ***/
+
+
+
+/**
+ * limDeletePreAuthList
+ *
+ *FUNCTION:
+ * This function is called cleanup Pre-auth list either on
+ * AP or on STA when moving from one persona to other.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limDeletePreAuthList(tpAniSirGlobal pMac)
+{
+ struct tLimPreAuthNode *pCurrNode, *pTempNode;
+
+ pCurrNode = pTempNode = pMac->lim.pLimPreAuthList;
+ while (pCurrNode != NULL)
+ {
+ pTempNode = pCurrNode->next;
+
+ PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthList \n"));)
+ limReleasePreAuthNode(pMac, pCurrNode);
+
+ pCurrNode = pTempNode;
+ }
+ pMac->lim.pLimPreAuthList = NULL;
+} /*** end limDeletePreAuthList() ***/
+
+
+
+/**
+ * limSearchPreAuthList
+ *
+ *FUNCTION:
+ * This function is called when Authentication frame is received
+ * by AP (or at a STA in IBSS supporting MAC based authentication)
+ * to search if a STA is in the middle of MAC Authentication
+ * transaction sequence.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param macAddr - MAC address of the STA that sent
+ * Authentication frame.
+ *
+ * @return Pointer to pre-auth node if found, else NULL
+ */
+
+struct tLimPreAuthNode *
+limSearchPreAuthList(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+ struct tLimPreAuthNode *pTempNode = pMac->lim.pLimPreAuthList;
+
+ while (pTempNode != NULL)
+ {
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
+ (tANI_U8 *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ break;
+
+ pTempNode = pTempNode->next;
+ }
+
+ return pTempNode;
+} /*** end limSearchPreAuthList() ***/
+
+
+
+/**
+ * limAddPreAuthNode
+ *
+ *FUNCTION:
+ * This function is called at AP while sending Authentication
+ * frame2.
+ * This may also be called on a STA in IBSS if MAC authentication is
+ * allowed in IBSS mode.
+ *
+ *LOGIC:
+ * Node is always added to the front of the list
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAuthNode - Pointer to pre-auth node to be added to the list.
+ *
+ * @return None
+ */
+
+void
+limAddPreAuthNode(tpAniSirGlobal pMac, struct tLimPreAuthNode *pAuthNode)
+{
+ pMac->lim.gLimNumPreAuthContexts++;
+
+ pAuthNode->next = pMac->lim.pLimPreAuthList;
+
+ pMac->lim.pLimPreAuthList = pAuthNode;
+} /*** end limAddPreAuthNode() ***/
+
+
+/**
+ * limReleasePreAuthNode
+ *
+ *FUNCTION:
+ * This function is called to realease the accquired
+ * pre auth node from list.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAuthNode - Pointer to Pre Auth node to be released
+ * @return None
+ */
+
+void
+limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode)
+{
+ pAuthNode->fFree = 1;
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_PRE_AUTH_CLEANUP_TIMER));
+ tx_timer_deactivate(&pAuthNode->timer);
+ pMac->lim.gLimNumPreAuthContexts--;
+} /*** end limReleasePreAuthNode() ***/
+
+
+/**
+ * limDeletePreAuthNode
+ *
+ *FUNCTION:
+ * This function is called at AP when a pre-authenticated STA is
+ * Associated/Reassociated or when AuthFrame4 is received after
+ * Auth Response timeout.
+ * This may also be called on a STA in IBSS if MAC authentication and
+ * Association/Reassociation is allowed in IBSS mode.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param peerMacAddr - MAC address of the STA that need to be deleted
+ * from pre-auth node list.
+ *
+ * @return None
+ */
+
+void
+limDeletePreAuthNode(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+ struct tLimPreAuthNode *pPrevNode, *pTempNode;
+
+ pTempNode = pPrevNode = pMac->lim.pLimPreAuthList;
+
+ if (pTempNode == NULL)
+ return;
+
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
+ (tANI_U8 *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ {
+ // First node to be deleted
+
+ pMac->lim.pLimPreAuthList = pTempNode->next;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ // Delete the auth response timer if running
+ if (pTempNode->fTimerStarted)
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pTempNode->authNodeIdx);
+
+#endif
+
+ PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthNode : first node to delete\n"));)
+ PELOG1(limLog(pMac, LOG1, FL("Release data entry: %x id %d peer \n"),
+ pTempNode, pTempNode->authNodeIdx);
+ limPrintMacAddr(pMac, macAddr, LOG1);)
+ limReleasePreAuthNode(pMac, pTempNode);
+
+ return;
+ }
+
+ pTempNode = pTempNode->next;
+
+ while (pTempNode != NULL)
+ {
+ if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
+ (tANI_U8 *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)) )
+ {
+ // Found node to be deleted
+
+ pPrevNode->next = pTempNode->next;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ // Delete the auth response timer if running
+ if (pTempNode->fTimerStarted)
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pTempNode->authNodeIdx);
+#endif
+ PELOG1(limLog(pMac, LOG1, FL("=====> limDeletePreAuthNode : subsequent node to delete\n"));
+ limLog(pMac, LOG1, FL("Release data entry: %x id %d peer \n"),
+ pTempNode, pTempNode->authNodeIdx);
+ limPrintMacAddr(pMac, macAddr, LOG1);)
+ limReleasePreAuthNode(pMac, pTempNode);
+
+ return;
+ }
+
+ pPrevNode = pTempNode;
+ pTempNode = pTempNode->next;
+ }
+
+ // Should not be here
+ // Log error
+ limLog(pMac, LOGP, FL("peer not found in pre-auth list, addr= "));
+ limPrintMacAddr(pMac, macAddr, LOGP);
+
+} /*** end limDeletePreAuthNode() ***/
+
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+/**
+ * limPreAuthClnupHandler
+ *
+ *FUNCTION:
+ * This function is called on AP upon peridic Pre-authentication
+ * context cleanup.
+ *
+ *LOGIC:
+ * A Pre-auth node is marked as seen first time it comes across
+ * the list traversal. It'll be deleted if already 'seen' (during
+ * next Pre-auth cleanup).
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limPreAuthClnupHandler(tpAniSirGlobal pMac)
+{
+ tANI_U16 aid;
+ tANI_U8 firstNode=false;
+ tpDphHashNode pStaDs;
+ struct tLimPreAuthNode *pPrevNode, *pCurrNode;
+
+#ifdef GEN6_TODO
+ //fetch the sessionEntry based on the sessionId
+ //priority - MEDIUM
+ tpPESession sessionEntry;
+
+ if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimPreAuthClnupTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+#endif
+
+ pCurrNode = pPrevNode = pMac->lim.pLimPreAuthList;
+
+ while (pCurrNode != NULL)
+ {
+ if (pCurrNode->fSeen)
+ {
+ // Found node to be deleted
+
+ if (pCurrNode == pMac->lim.pLimPreAuthList)
+ {
+ // First node being deleted
+ pMac->lim.pLimPreAuthList = pPrevNode = pCurrNode->next;
+ firstNode = true;
+ }
+ else
+ {
+ pPrevNode->next = pCurrNode->next;
+ }
+
+ // Delete the auth response timer if running
+ if (pCurrNode->fTimerStarted)
+ limDeactivateAndChangePerStaIdTimer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pCurrNode->authNodeIdx);
+
+ pStaDs = dphLookupHashEntry(pMac,
+ pCurrNode->peerMacAddr,
+ &aid);
+
+ if (!pStaDs)
+ {
+ /**
+ * STA does not have associated context.
+ * Send advisory Deauthentication frame
+ * to STA being deleted
+ */
+ limSendDeauthMgmtFrame(
+ pMac,
+ eSIR_MAC_PREV_AUTH_NOT_VALID_REASON, //=2
+ pCurrNode->peerMacAddr,sessionEntry);
+ }
+
+ limLog(pMac,
+ LOG3,
+ FL("Release preAuth node during periodic cleanup\n"));
+ limReleasePreAuthNode(pMac, pCurrNode);
+
+ if (firstNode)
+ {
+ // First node was deleted
+ if (pMac->lim.pLimPreAuthList == NULL)
+ break;
+
+ pCurrNode = pMac->lim.pLimPreAuthList;
+ firstNode = false;
+ }
+ else
+ {
+ pCurrNode = pPrevNode->next;
+ }
+ }
+ else
+ {
+ // Mark this node as 'seen'. To be deleted next time.
+ pCurrNode->fSeen = 1;
+
+ pPrevNode = pCurrNode;
+ pCurrNode = pCurrNode->next;
+ }
+ }
+} /*** end limPreAuthClnupHandler() ***/
+#endif
+
+
+
+/**
+ * limRestoreFromPreAuthState
+ *
+ *FUNCTION:
+ * This function is called on STA whenever an Authentication
+ * sequence is complete and state prior to auth need to be
+ * restored.
+ *
+ *LOGIC:
+ * MLM_AUTH_CNF is prepared and sent to SME state machine.
+ * In case of restoring from pre-auth:
+ * - Channel Id is programmed at LO/RF synthesizer
+ * - BSSID is programmed at RHP
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param resultCode - result of authentication attempt
+ * @return None
+ */
+
+void
+limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode,tpPESession sessionEntry)
+{
+ tSirMacAddr currentBssId;
+ tLimMlmAuthCnf mlmAuthCnf;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmAuthCnf.peerMacAddr,
+ (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType;
+ mlmAuthCnf.resultCode = resultCode;
+ mlmAuthCnf.protStatusCode = protStatusCode;
+
+ /* Update PE session ID*/
+ mlmAuthCnf.sessionId = sessionEntry->peSessionId;
+
+ /// Free up buffer allocated
+ /// for pMac->lim.gLimMlmAuthReq
+ palFreeMemory( pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+
+ sessionEntry->limMlmState = sessionEntry->limPrevMlmState;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+
+ // 'Change' timer for future activations
+ limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER);
+
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(currentBssId,sessionEntry->bssId);
+
+ if (sessionEntry->limSmeState == eLIM_SME_WT_PRE_AUTH_STATE)
+ {
+ pMac->lim.gLimPreAuthChannelNumber = 0;
+ }
+
+ limPostSmeMessage(pMac,
+ LIM_MLM_AUTH_CNF,
+ (tANI_U32 *) &mlmAuthCnf);
+} /*** end limRestoreFromAuthState() ***/
+
+
+
+/**
+ * limLookUpKeyMappings()
+ *
+ *FUNCTION:
+ * This function is called in limProcessAuthFrame() function
+ * to determine if there exists a Key Mapping key for a given
+ * MAC address.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param macAddr MAC address of the peer STA for which existence
+ * of Key Mapping key is to be determined
+ *
+ * @return pKeyMapEntry - Pointer to the keyMapEntry returned by CFG
+ */
+
+tCfgWepKeyEntry *
+limLookUpKeyMappings(tSirMacAddr macAddr)
+{
+ return NULL;
+} /****** end limLookUpKeyMappings() ******/
+
+
+
+/**
+ * limEncryptAuthFrame()
+ *
+ *FUNCTION:
+ * This function is called in limProcessAuthFrame() function
+ * to encrypt Authentication frame3 body.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param keyId key id to used
+ * @param pKey Pointer to the key to be used for encryption
+ * @param pPlainText Pointer to the body to be encrypted
+ * @param pEncrBody Pointer to the encrypted auth frame body
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ * @return None
+ */
+
+void
+limEncryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 keyId, tANI_U8 *pKey, tANI_U8 *pPlainText,
+ tANI_U8 *pEncrBody, tANI_U32 keyLength)
+{
+ tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+
+ keyLength += 3;
+
+ // Bytes 0-2 of seed is IV
+ // Read TSF timestamp into seed to get random IV - 1st 3 bytes
+ halGetTxTSFtimer(pMac, (tSirMacTimeStamp *) &seed);
+
+ // Bytes 3-7 of seed is key
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &seed[3], pKey, keyLength - 3);
+
+ // Compute CRC-32 and place them in last 4 bytes of plain text
+ limComputeCrc32(icv, pPlainText, sizeof(tSirMacAuthFrameBody));
+
+ palCopyMemory( pMac->hHdd, pPlainText + sizeof(tSirMacAuthFrameBody),
+ icv, SIR_MAC_WEP_ICV_LENGTH);
+
+ // Run RC4 on plain text with the seed
+ limRC4(pEncrBody + SIR_MAC_WEP_IV_LENGTH,
+ (tANI_U8 *) pPlainText, seed, keyLength,
+ LIM_ENCR_AUTH_BODY_LEN - SIR_MAC_WEP_IV_LENGTH);
+
+ // Prepare IV
+ pEncrBody[0] = seed[0];
+ pEncrBody[1] = seed[1];
+ pEncrBody[2] = seed[2];
+ pEncrBody[3] = keyId << 6;
+} /****** end limEncryptAuthFrame() ******/
+
+
+
+/**
+ * limComputeCrc32()
+ *
+ *FUNCTION:
+ * This function is called to compute CRC-32 on a given source.
+ * Used while encrypting/decrypting Authentication frame 3.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pDest Destination location for computed CRC
+ * @param pSrc Source location to be CRC computed
+ * @param len Length over which CRC to be computed
+ * @return None
+ */
+
+void
+limComputeCrc32(tANI_U8 *pDest, tANI_U8 * pSrc, tANI_U8 len)
+{
+ tANI_U32 crc;
+ int i;
+
+ crc = 0;
+ crc = ~crc;
+
+ while(len-- > 0)
+ crc = limCrcUpdate(crc, *pSrc++);
+
+ crc = ~crc;
+
+ for (i=0; i < SIR_MAC_WEP_IV_LENGTH; i++)
+ {
+ pDest[i] = (tANI_U8)crc;
+ crc >>= 8;
+ }
+} /****** end limComputeCrc32() ******/
+
+
+
+/**
+ * limRC4()
+ *
+ *FUNCTION:
+ * This function is called to run RC4 algorithm. Called while
+ * encrypting/decrypting Authentication frame 3.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pDest Destination location for encrypted text
+ * @param pSrc Source location to be encrypted
+ * @param seed Contains seed (IV + key) for PRNG
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ * @param frameLen Length of the frame
+ *
+ * @return None
+ */
+
+void
+limRC4(tANI_U8 *pDest, tANI_U8 *pSrc, tANI_U8 *seed, tANI_U32 keyLength, tANI_U16 frameLen)
+{
+ typedef struct
+ {
+ tANI_U8 i, j;
+ tANI_U8 sbox[256];
+ } tRC4Context;
+
+ tRC4Context ctx;
+
+ {
+ tANI_U16 i, j, k;
+
+ //
+ // Initialize sbox using seed
+ //
+
+ ctx.i = ctx.j = 0;
+ for (i=0; i<256; i++)
+ ctx.sbox[i] = (tANI_U8)i;
+
+ j = 0;
+ k = 0;
+ for (i=0; i<256; i++)
+ {
+ tANI_U8 temp;
+
+ j = (tANI_U8)(j + ctx.sbox[i] + seed[k]);
+ temp = ctx.sbox[i];
+ ctx.sbox[i] = ctx.sbox[j];
+ ctx.sbox[j] = temp;
+
+ if (++k >= keyLength)
+ k = 0;
+ }
+ }
+
+ {
+ tANI_U8 i = ctx.i;
+ tANI_U8 j = ctx.j;
+ tANI_U8 len = (tANI_U8) frameLen;
+
+ while (len-- > 0)
+ {
+ tANI_U8 temp1, temp2;
+
+ i = (tANI_U8)(i+1);
+ temp1 = ctx.sbox[i];
+ j = (tANI_U8)(j + temp1);
+
+ ctx.sbox[i] = temp2 = ctx.sbox[j];
+ ctx.sbox[j] = temp1;
+
+ temp1 = (tANI_U8)(temp1 + temp2);
+ temp1 = ctx.sbox[temp1];
+ temp2 = (tANI_U8)(pSrc ? *pSrc++ : 0);
+
+ *pDest++ = (tANI_U8)(temp1 ^ temp2);
+ }
+
+ ctx.i = i;
+ ctx.j = j;
+ }
+} /****** end limRC4() ******/
+
+
+
+/**
+ * limDecryptAuthFrame()
+ *
+ *FUNCTION:
+ * This function is called in limProcessAuthFrame() function
+ * to decrypt received Authentication frame3 body.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pKey Pointer to the key to be used for decryption
+ * @param pEncrBody Pointer to the body to be decrypted
+ * @param pPlainBody Pointer to the decrypted body
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ *
+ * @return Decrypt result - eSIR_SUCCESS for success and
+ * LIM_DECRYPT_ICV_FAIL for ICV mismatch.
+ * If decryption is a success, pBody will
+ * have decrypted auth frame body.
+ */
+
+tANI_U8
+limDecryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pKey, tANI_U8 *pEncrBody,
+ tANI_U8 *pPlainBody, tANI_U32 keyLength, tANI_U16 frameLen)
+{
+ tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+ int i;
+ keyLength += 3;
+
+
+ // Bytes 0-2 of seed is received IV
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) seed, pEncrBody, SIR_MAC_WEP_IV_LENGTH - 1);
+
+ // Bytes 3-7 of seed is key
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &seed[3], pKey, keyLength - 3);
+
+ // Run RC4 on encrypted text with the seed
+ limRC4(pPlainBody,
+ pEncrBody + SIR_MAC_WEP_IV_LENGTH,
+ seed,
+ keyLength,
+ frameLen);
+
+ PELOG4(limLog(pMac, LOG4, FL("plainbody is \n"));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pPlainBody, frameLen);)
+
+ // Compute CRC-32 and place them in last 4 bytes of encrypted body
+ limComputeCrc32(icv,
+ (tANI_U8 *) pPlainBody,
+ (tANI_U8) (frameLen - SIR_MAC_WEP_ICV_LENGTH));
+
+ // Compare RX_ICV with computed ICV
+ for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++)
+ {
+ PELOG4(limLog(pMac, LOG4, FL(" computed ICV%d[%x], rxed ICV%d[%x]\n"),
+ i, icv[i], i, pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]);)
+ if (icv[i] != pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i])
+ return LIM_DECRYPT_ICV_FAIL;
+ }
+
+ return eSIR_SUCCESS;
+} /****** end limDecryptAuthFrame() ******/
+
+/**
+ * limPostSmeSetKeysCnf
+ *
+ * A utility API to send MLM_SETKEYS_CNF to SME
+ */
+void limPostSmeSetKeysCnf( tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ tLimMlmSetKeysCnf *mlmSetKeysCnf)
+{
+ // Prepare and Send LIM_MLM_SETKEYS_CNF
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr,
+ (tANI_U8 *) pMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr,
+ (tANI_U8 *) pMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ mlmSetKeysCnf->aid = pMlmSetKeysReq->aid;
+#endif
+
+ /// Free up buffer allocated for mlmSetKeysReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmSetKeysReq );
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+
+ limPostSmeMessage( pMac,
+ LIM_MLM_SETKEYS_CNF,
+ (tANI_U32 *) mlmSetKeysCnf );
+}
+
+/**
+ * limPostSmeRemoveKeysCnf
+ *
+ * A utility API to send MLM_REMOVEKEY_CNF to SME
+ */
+void limPostSmeRemoveKeyCnf( tpAniSirGlobal pMac,
+ tLimMlmRemoveKeyReq *pMlmRemoveKeyReq,
+ tLimMlmRemoveKeyCnf *mlmRemoveKeyCnf)
+{
+ // Prepare and Send LIM_MLM_REMOVEKEYS_CNF
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmRemoveKeyCnf->peerMacAddr,
+ (tANI_U8 *) pMlmRemoveKeyReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ /// Free up buffer allocated for mlmRemoveKeysReq
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pMlmRemoveKeyReq );
+ pMac->lim.gpLimMlmRemoveKeyReq = NULL;
+
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; //Restore the state.
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ limPostSmeMessage( pMac,
+ LIM_MLM_REMOVEKEY_CNF,
+ (tANI_U32 *) mlmRemoveKeyCnf );
+}
+
+/**
+ * limSendSetBssKeyReq()
+ *
+ *FUNCTION:
+ * This function is called from limProcessMlmSetKeysReq(),
+ * when PE is trying to setup the Group Keys related
+ * to a specified encryption type
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @return none
+ */
+void limSendSetBssKeyReq( tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ tpPESession psessionEntry)
+{
+tSirMsgQ msgQ;
+tpSetBssKeyParams pSetBssKeyParams = NULL;
+tLimMlmSetKeysCnf mlmSetKeysCnf;
+tSirRetStatus retCode;
+tANI_U32 val = 0;
+
+ if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
+ {
+ limLog( pMac, LOG1,
+ FL( "numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS\n" ), pMlmSetKeysReq->numKeys);
+
+ // Respond to SME with error code
+ mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ // Package WDA_SET_BSSKEY_REQ message parameters
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pSetBssKeyParams,
+ sizeof( tSetBssKeyParams )))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to PAL allocate memory during SET_BSSKEY\n" ));
+
+ // Respond to SME with error code
+ mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ else
+ palZeroMemory( pMac->hHdd,
+ (void *) pSetBssKeyParams,
+ sizeof( tSetBssKeyParams ));
+
+ // Update the WDA_SET_BSSKEY_REQ parameters
+ pSetBssKeyParams->bssIdx = psessionEntry->bssIdx;
+ pSetBssKeyParams->encType = pMlmSetKeysReq->edType;
+ pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys;
+
+ if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val))
+ {
+ limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC\n" ));
+ }
+
+ pSetBssKeyParams->singleTidRc = (tANI_U8)val;
+
+ /* Update PE session Id*/
+ pSetBssKeyParams->sessionId = psessionEntry ->peSessionId;
+
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pSetBssKeyParams->key,
+ (tANI_U8 *) &pMlmSetKeysReq->key,
+ sizeof( tSirKeys ) * pMlmSetKeysReq->numKeys );
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ msgQ.type = WDA_SET_BSSKEY_REQ;
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pSetBssKeyParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Sending WDA_SET_BSSKEY_REQ...\n" ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE,
+ FL("Posting SET_BSSKEY to HAL failed, reason=%X\n"),
+ retCode );
+
+ // Respond to SME with LIM_MLM_SETKEYS_CNF
+ mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ else
+ return; // Continue after WDA_SET_BSSKEY_RSP...
+
+end:
+ limPostSmeSetKeysCnf( pMac,
+ pMlmSetKeysReq,
+ &mlmSetKeysCnf );
+
+}
+
+/**
+ * @function : limSendSetStaKeyReq()
+ *
+ * @brief : This function is called from limProcessMlmSetKeysReq(),
+ * when PE is trying to setup the Unicast Keys related
+ * to a specified STA with specified encryption type
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @param staIdx STA index for which the keys are being set
+ * @param defWEPIdx The default WEP key index [0..3]
+ * @return none
+ */
+void limSendSetStaKeyReq( tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ tANI_U16 staIdx,
+ tANI_U8 defWEPIdx,
+ tpPESession sessionEntry)
+{
+tSirMsgQ msgQ;
+tpSetStaKeyParams pSetStaKeyParams = NULL;
+tLimMlmSetKeysCnf mlmSetKeysCnf;
+tSirRetStatus retCode;
+tANI_U32 val = 0;
+
+ // Package WDA_SET_STAKEY_REQ message parameters
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **) &pSetStaKeyParams,
+ sizeof( tSetStaKeyParams ))) {
+ limLog( pMac, LOGP, FL( "Unable to PAL allocate memory during SET_BSSKEY\n" ));
+ return;
+ }else
+ palZeroMemory( pMac->hHdd, (void *) pSetStaKeyParams, sizeof( tSetStaKeyParams ));
+
+ // Update the WDA_SET_STAKEY_REQ parameters
+ pSetStaKeyParams->staIdx = staIdx;
+ pSetStaKeyParams->encType = pMlmSetKeysReq->edType;
+
+
+ if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val))
+ {
+ limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC\n" ));
+ }
+
+ pSetStaKeyParams->singleTidRc = (tANI_U8)val;
+
+ /* Update PE session ID*/
+ pSetStaKeyParams->sessionId = sessionEntry->peSessionId;
+
+ /**
+ * For WEP - defWEPIdx indicates the default WEP
+ * Key to be used for TX
+ * For all others, there's just one key that can
+ * be used and hence it is assumed that
+ * defWEPIdx = 0 (from the caller)
+ */
+
+ pSetStaKeyParams->defWEPIdx = defWEPIdx;
+
+ /** Store the Previous MlmState*/
+ sessionEntry->limPrevMlmState = sessionEntry->limMlmState;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ if(sessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && !pMlmSetKeysReq->key[0].unicast) {
+ sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE;
+ msgQ.type = WDA_SET_STA_BCASTKEY_REQ;
+ }else {
+ sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE;
+ msgQ.type = WDA_SET_STAKEY_REQ;
+ }
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /**
+ * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP
+ * the Key[0] contains the KEY, so just copy that alone,
+ * for the case of WEP_STATIC the hal gets the key from cfg
+ */
+ switch( pMlmSetKeysReq->edType ) {
+ case eSIR_ED_WEP40:
+ case eSIR_ED_WEP104:
+ // FIXME! Is this OK?
+ if( 0 == pMlmSetKeysReq->numKeys ) {
+#ifdef WLAN_SOFTAP_FEATURE
+ tANI_U32 i;
+
+ for(i=0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS ;i++)
+ {
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pSetStaKeyParams->key[i],
+ (tANI_U8 *) &pMlmSetKeysReq->key[i], sizeof( tSirKeys ));
+ }
+#endif
+ pSetStaKeyParams->wepType = eSIR_WEP_STATIC;
+ sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ }else {
+ pSetStaKeyParams->wepType = eSIR_WEP_DYNAMIC;
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) &pSetStaKeyParams->key,
+ (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof( tSirKeys ));
+ }
+ break;
+ case eSIR_ED_TKIP:
+ case eSIR_ED_CCMP:
+#ifdef FEATURE_WLAN_WAPI
+ case eSIR_ED_WPI:
+#endif
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pSetStaKeyParams->key,
+ (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof( tSirKeys ));
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pSetStaKeyParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG1, FL( "Sending WDA_SET_STAKEY_REQ...\n" ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) {
+ limLog( pMac, LOGE, FL("Posting SET_STAKEY to HAL failed, reason=%X\n"), retCode );
+ // Respond to SME with LIM_MLM_SETKEYS_CNF
+ mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }else
+ return; // Continue after WDA_SET_STAKEY_RSP...
+
+ limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf );
+}
+
+/**
+ * limSendRemoveBssKeyReq()
+ *
+ *FUNCTION:
+ * This function is called from limProcessMlmRemoveReq(),
+ * when PE is trying to Remove a Group Key related
+ * to a specified encryption type
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmRemoveKeyReq Pointer to MLM_REMOVEKEY_REQ buffer
+ * @return none
+ */
+void limSendRemoveBssKeyReq( tpAniSirGlobal pMac,
+ tLimMlmRemoveKeyReq *pMlmRemoveKeyReq,
+ tpPESession psessionEntry)
+{
+tSirMsgQ msgQ;
+tpRemoveBssKeyParams pRemoveBssKeyParams = NULL;
+tLimMlmRemoveKeyCnf mlmRemoveKeysCnf;
+tSirRetStatus retCode;
+
+ // Package WDA_REMOVE_BSSKEY_REQ message parameters
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pRemoveBssKeyParams,
+ sizeof( tRemoveBssKeyParams )))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to PAL allocate memory during REMOVE_BSSKEY\n" ));
+
+ // Respond to SME with error code
+ mlmRemoveKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ else
+ palZeroMemory( pMac->hHdd,
+ (void *) pRemoveBssKeyParams,
+ sizeof( tRemoveBssKeyParams ));
+
+ // Update the WDA_REMOVE_BSSKEY_REQ parameters
+ pRemoveBssKeyParams->bssIdx = psessionEntry->bssIdx;
+ pRemoveBssKeyParams->encType = pMlmRemoveKeyReq->edType;
+ pRemoveBssKeyParams->keyId = pMlmRemoveKeyReq->keyId;
+ pRemoveBssKeyParams->wepType = pMlmRemoveKeyReq->wepType;
+
+ /* Update PE session Id*/
+
+ pRemoveBssKeyParams->sessionId = psessionEntry->peSessionId;
+
+ msgQ.type = WDA_REMOVE_BSSKEY_REQ;
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pRemoveBssKeyParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Sending WDA_REMOVE_BSSKEY_REQ...\n" ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE,
+ FL("Posting REMOVE_BSSKEY to HAL failed, reason=%X\n"),
+ retCode );
+
+ // Respond to SME with LIM_MLM_REMOVEKEYS_CNF
+ mlmRemoveKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ else
+ return;
+
+end:
+ limPostSmeRemoveKeyCnf( pMac,
+ pMlmRemoveKeyReq,
+ &mlmRemoveKeysCnf );
+
+}
+
+/**
+ * limSendRemoveStaKeyReq()
+ *
+ *FUNCTION:
+ * This function is called from limProcessMlmRemoveKeysReq(),
+ * when PE is trying to setup the Unicast Keys related
+ * to a specified STA with specified encryption type
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmRemoveKeysReq Pointer to MLM_REMOVEKEYS_REQ buffer
+ * @param staIdx STA index for which the keys are being set
+ * @return none
+ */
+void limSendRemoveStaKeyReq( tpAniSirGlobal pMac,
+ tLimMlmRemoveKeyReq *pMlmRemoveKeyReq,
+ tANI_U16 staIdx ,
+ tpPESession sessionEntry)
+{
+tSirMsgQ msgQ;
+tpRemoveStaKeyParams pRemoveStaKeyParams = NULL;
+tLimMlmRemoveKeyCnf mlmRemoveKeyCnf;
+tSirRetStatus retCode;
+
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pRemoveStaKeyParams,
+ sizeof( tRemoveStaKeyParams )))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to PAL allocate memory during REMOVE_STAKEY\n" ));
+
+ // Respond to SME with error code
+ mlmRemoveKeyCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ else
+ palZeroMemory( pMac->hHdd,
+ (void *) pRemoveStaKeyParams,
+ sizeof( tRemoveStaKeyParams ));
+
+ if( (pMlmRemoveKeyReq->edType == eSIR_ED_WEP104 || pMlmRemoveKeyReq->edType == eSIR_ED_WEP40) &&
+ pMlmRemoveKeyReq->wepType == eSIR_WEP_STATIC )
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Request to remove static WEP keys through station interface\n Should use BSS interface\n"));)
+ mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ // Update the WDA_REMOVEKEY_REQ parameters
+ pRemoveStaKeyParams->staIdx = staIdx;
+ pRemoveStaKeyParams->encType = pMlmRemoveKeyReq->edType;
+ pRemoveStaKeyParams->keyId = pMlmRemoveKeyReq->keyId;
+ pRemoveStaKeyParams->unicast = pMlmRemoveKeyReq->unicast;
+
+ /* Update PE session ID*/
+ pRemoveStaKeyParams->sessionId = sessionEntry->peSessionId;
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WDA_REMOVE_STAKEY_REQ;
+ //
+ // FIXME_GEN4
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pRemoveStaKeyParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Sending WDA_REMOVE_STAKEY_REQ...\n" ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGE,
+ FL("Posting REMOVE_STAKEY to HAL failed, reason=%X\n"),
+ retCode );
+
+ // Respond to SME with LIM_MLM_REMOVEKEY_CNF
+ mlmRemoveKeyCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ else
+ return;
+
+end:
+ limPostSmeRemoveKeyCnf( pMac,
+ pMlmRemoveKeyReq,
+ &mlmRemoveKeyCnf );
+
+}
+
+
diff --git a/CORE/MAC/src/pe/lim/limSecurityUtils.h b/CORE/MAC/src/pe/lim/limSecurityUtils.h
new file mode 100644
index 0000000..2479f14
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSecurityUtils.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSecurityUtils.h contains the utility definitions
+ * related to WEP encryption/decryption etc.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SECURITY_UTILS_H
+#define __LIM_SECURITY_UTILS_H
+#include "sirMacProtDef.h" //for tSirMacAuthFrameBody
+
+#define LIM_ENCR_AUTH_BODY_LEN sizeof(tSirMacAuthFrameBody) + \
+ SIR_MAC_WEP_IV_LENGTH + \
+ SIR_MAC_WEP_ICV_LENGTH
+struct tLimPreAuthNode;
+
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession);
+#else
+tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType);
+#endif
+
+// MAC based authentication related functions
+void limInitPreAuthList(tpAniSirGlobal);
+void limDeletePreAuthList(tpAniSirGlobal);
+struct tLimPreAuthNode *limSearchPreAuthList(tpAniSirGlobal, tSirMacAddr);
+void limAddPreAuthNode(tpAniSirGlobal, struct tLimPreAuthNode *);
+void limDeletePreAuthNode(tpAniSirGlobal, tSirMacAddr);
+void limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode);
+void limRestoreFromAuthState(tpAniSirGlobal,
+ tSirResultCodes, tANI_U16,tpPESession);
+
+// Encryption/Decryption related functions
+tCfgWepKeyEntry *limLookUpKeyMappings(tSirMacAddr);
+void limComputeCrc32(tANI_U8 *, tANI_U8 *, tANI_U8);
+void limRC4(tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16);
+void limEncryptAuthFrame(tpAniSirGlobal, tANI_U8, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32);
+tANI_U8 limDecryptAuthFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16);
+
+void limSendSetBssKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *,tpPESession );
+void limSendSetStaKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *, tANI_U16, tANI_U8,tpPESession);
+void limPostSmeSetKeysCnf( tpAniSirGlobal, tLimMlmSetKeysReq *, tLimMlmSetKeysCnf * );
+
+void limSendRemoveBssKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq,tpPESession);
+void limSendRemoveStaKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tANI_U16 staIdx,tpPESession);
+void limPostSmeRemoveKeyCnf(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tLimMlmRemoveKeyCnf * mlmRemoveKeyCnf);
+
+#define PTAPS 0xedb88320
+
+static inline tANI_U32
+limCrcUpdate(tANI_U32 crc, tANI_U8 x)
+{
+
+ // Update CRC computation for 8 bits contained in x
+ //
+ tANI_U32 z;
+ tANI_U32 fb;
+ int i;
+
+ z = crc^x;
+ for (i=0; i<8; i++) {
+ fb = z & 1;
+ z >>= 1;
+ if (fb) z ^= PTAPS;
+ }
+ return z;
+}
+
+#endif /* __LIM_SECURITY_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
new file mode 100644
index 0000000..3ecffb2
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -0,0 +1,5489 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/**
+ * \file limSendManagementFrames.c
+ *
+ * \brief Code for preparing and sending 802.11 Management frames
+ *
+ * Copyright (C) 2005-2007 Airgo Networks, Incorporated
+ *
+ */
+
+#include "sirApi.h"
+#include "aniGlobal.h"
+#include "sirMacProtDef.h"
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#endif
+#include "cfgApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limSecurityUtils.h"
+#include "dot11f.h"
+#include "limStaHashApi.h"
+#include "schApi.h"
+#include "limSendMessages.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrmApi.h"
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+#include <limCcxparserApi.h>
+#endif
+#include "wlan_qct_wda.h"
+#ifdef WLAN_FEATURE_11W
+#include "dot11fdefs.h"
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+
+/// Get an integral configuration item & check return status; if it
+/// fails, return.
+#define CFG_LIM_GET_INT_NO_STATUS(nStatus, pMac, nItem, cfg ) \
+ (nStatus) = wlan_cfgGetInt( (pMac), (nItem), & (cfg) ); \
+ if ( eSIR_SUCCESS != (nStatus) ) \
+ { \
+ limLog( (pMac), LOGP, FL("Failed to retrieve " \
+ #nItem " from CFG (%d).\n"), \
+ (nStatus) ); \
+ return; \
+ }
+
+/// Get an text configuration item & check return status; if it fails,
+/// return.
+#define CFG_LIM_GET_STR_NO_STATUS(nStatus, pMac, nItem, cfg, nCfg, \
+ nMaxCfg) \
+ (nCfg) = (nMaxCfg); \
+ (nStatus) = wlan_cfgGetStr( (pMac), (nItem), (cfg), & (nCfg) ); \
+ if ( eSIR_SUCCESS != (nStatus) ) \
+ { \
+ limLog( (pMac), LOGP, FL("Failed to retrieve " \
+ #nItem " from CFG (%d).\n"), \
+ (nStatus) ); \
+ return; \
+ }
+
+/**
+ *
+ * \brief This function is called by various LIM modules to prepare the
+ * 802.11 frame MAC header
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pBD Pointer to the frame buffer that needs to be populate
+ *
+ * \param type Type of the frame
+ *
+ * \param subType Subtype of the frame
+ *
+ * \return eHalStatus
+ *
+ *
+ * The pFrameBuf argument points to the beginning of the frame buffer to
+ * which - a) The 802.11 MAC header is set b) Following this MAC header
+ * will be the MGMT frame payload The payload itself is populated by the
+ * caller API
+ *
+ *
+ */
+
+tSirRetStatus limPopulateMacHeader( tpAniSirGlobal pMac,
+ tANI_U8* pBD,
+ tANI_U8 type,
+ tANI_U8 subType,
+ tSirMacAddr peerAddr ,tSirMacAddr selfMacAddr)
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tpSirMacMgmtHdr pMacHdr;
+
+ /// Prepare MAC management header
+ pMacHdr = (tpSirMacMgmtHdr) (pBD);
+
+ // Prepare FC
+ pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ pMacHdr->fc.type = type;
+ pMacHdr->fc.subType = subType;
+
+ // Prepare Address 1
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pMacHdr->da,
+ (tANI_U8 *) peerAddr,
+ sizeof( tSirMacAddr ));
+
+ // Prepare Address 2
+ #if 0
+ if ((statusCode = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8 *) pMacHdr->sa,
+ &cfgLen)) != eSIR_SUCCESS)
+ {
+ // Could not get STA_ID from CFG. Log error.
+ limLog( pMac, LOGP,
+ FL("Failed to retrive STA_ID\n"));
+ return statusCode;
+ }
+ #endif// TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->sa,selfMacAddr);
+
+ // Prepare Address 3
+ palCopyMemory( pMac->hHdd,
+ (tANI_U8 *) pMacHdr->bssId,
+ (tANI_U8 *) peerAddr,
+ sizeof( tSirMacAddr ));
+ return statusCode;
+} /*** end limPopulateMacHeader() ***/
+
+/**
+ * \brief limSendProbeReqMgmtFrame
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pSsid SSID to be sent in Probe Request frame
+ *
+ * \param bssid BSSID to be sent in Probe Request frame
+ *
+ * \param nProbeDelay probe delay to be used before sending Probe Request
+ * frame
+ *
+ * \param nChannelNum Channel # on which the Probe Request is going out
+ *
+ * \param nAdditionalIELen if non-zero, include pAdditionalIE in the Probe Request frame
+ *
+ * \param pAdditionalIE if nAdditionalIELen is non zero, include this field in the Probe Request frame
+ *
+ * This function is called by various LIM modules to send Probe Request frame
+ * during active scan/learn phase.
+ * Probe request is sent out in the following scenarios:
+ * --heartbeat failure: session needed
+ * --join req: session needed
+ * --foreground scan: no session
+ * --background scan: no session
+ * --schBeaconProcessing: to get EDCA parameters: session needed
+ *
+ *
+ */
+tSirRetStatus
+limSendProbeReqMgmtFrame(tpAniSirGlobal pMac,
+ tSirMacSSid *pSsid,
+ tSirMacAddr bssid,
+ tANI_U8 nChannelNum,
+ tSirMacAddr SelfMacAddr,
+ tANI_U32 dot11mode,
+ tANI_U32 nAdditionalIELen,
+ tANI_U8 *pAdditionalIE)
+{
+ tDot11fProbeRequest pr;
+ tANI_U32 nStatus, nBytes, nPayload;
+ tSirRetStatus nSirStatus;
+ tANI_U8 *pFrame;
+ void *pPacket;
+ eHalStatus halstatus;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+#ifdef WLAN_FEATURE_P2P
+ tANI_U8 *p2pIe = NULL;
+#endif
+ tANI_U8 txFlag = 0;
+
+#ifndef GEN4_SCAN
+ return eSIR_FAILURE;
+#endif
+
+#if defined ( ANI_DVT_DEBUG )
+ return eSIR_FAILURE;
+#endif
+
+ /*
+ * session context may or may not be present, when probe request needs to be sent out.
+ * following cases exist:
+ * --heartbeat failure: session needed
+ * --join req: session needed
+ * --foreground scan: no session
+ * --background scan: no session
+ * --schBeaconProcessing: to get EDCA parameters: session needed
+ * If session context does not exist, some IEs will be populated from CFGs,
+ * e.g. Supported and Extended rate set IEs
+ */
+ psessionEntry = peFindSessionByBssid(pMac,bssid,&sessionId);
+
+ // The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ // and then hand it off to 'dot11fPackProbeRequest' (for
+ // serialization). We start by zero-initializing the structure:
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&pr, sizeof( pr ) );
+
+ // & delegating to assorted helpers:
+ PopulateDot11fSSID( pMac, pSsid, &pr.SSID );
+
+#ifdef WLAN_FEATURE_P2P
+ if( nAdditionalIELen && pAdditionalIE )
+ {
+ p2pIe = limGetP2pIEPtr(pMac, pAdditionalIE, nAdditionalIELen);
+ }
+ if( p2pIe != NULL)
+ {
+ /* In the below API pass channel number > 14, do that it fills only
+ * 11a rates in supported rates */
+ PopulateDot11fSuppRates( pMac, 15, &pr.SuppRates,psessionEntry);
+ }
+ else
+ {
+#endif
+ PopulateDot11fSuppRates( pMac, nChannelNum,
+ &pr.SuppRates,psessionEntry);
+
+ if ( WNI_CFG_DOT11_MODE_11B != dot11mode )
+ {
+ PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates );
+ }
+#ifdef WLAN_FEATURE_P2P
+ }
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+ //Table 7-14 in IEEE Std. 802.11k-2008 says
+ //DS params "can" be present in RRM is disabled and "is" present if
+ //RRM is enabled. It should be ok even if we add it into probe req when
+ //RRM is not enabled.
+ PopulateDot11fDSParams( pMac, &pr.DSParams, nChannelNum, psessionEntry );
+ //Call RRM module to get the tx power for management used.
+ {
+ tANI_U8 txPower = (tANI_U8) rrmGetMgmtTxPower( pMac, psessionEntry );
+ PopulateDot11fWFATPC( pMac, &pr.WFATPC, txPower, 0 );
+ }
+#endif
+ pMac->lim.htCapability = IS_DOT11_MODE_HT(dot11mode);
+
+ if (psessionEntry != NULL ) {
+ psessionEntry->htCapabality = IS_DOT11_MODE_HT(dot11mode);
+ //Include HT Capability IE
+ if (psessionEntry->htCapabality)
+ {
+ PopulateDot11fHTCaps( pMac, &pr.HTCaps );
+ }
+ } else {
+ if (pMac->lim.htCapability)
+ {
+ PopulateDot11fHTCaps( pMac, &pr.HTCaps );
+ }
+ }
+
+ // That's it-- now we pack it. First, how much space are we going to
+ // need?
+ nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Probe Request (0x%08x).\n"), nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fProbeRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Probe Request ("
+ "0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAdditionalIELen;
+
+ // Ok-- try to allocate some memory:
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro"
+ "be Request.\n"), nBytes );
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_PROBE_REQ, bssid ,SelfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a Probe Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return nSirStatus; // allocated!
+ }
+
+ // That done, pack the Probe Request:
+ nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame +
+ sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Probe Request (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a P"
+ "robe Request (0x%08x).\n") );
+ }
+
+ // Append any AddIE if present.
+ if( nAdditionalIELen )
+ {
+ palCopyMemory( pMac->hHdd, pFrame+sizeof(tSirMacMgmtHdr)+nPayload,
+ pAdditionalIE, nAdditionalIELen );
+ nPayload += nAdditionalIELen;
+ }
+
+ /* If this probe request is sent during P2P Search State, then we need
+ * to send it at OFDM rate.
+ */
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(nChannelNum))
+#ifdef WLAN_FEATURE_P2P
+ || (( pMac->lim.gpLimMlmScanReq != NULL) &&
+ pMac->lim.gpLimMlmScanReq->p2pSearch )
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) sizeof(tSirMacMgmtHdr) + nPayload,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("could not send Probe Request frame!\n" ));
+ //Pkt will be freed up by the callback
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} // End limSendProbeReqMgmtFrame.
+
+#ifdef WLAN_FEATURE_P2P
+tSirRetStatus limGetAddnIeForProbeResp(tpAniSirGlobal pMac,
+ tANI_U8* addIE, tANI_U16 *addnIELen,
+ tANI_U8 probeReqP2pIe)
+{
+ /* If Probe request doesn't have P2P IE, then take out P2P IE
+ from additional IE */
+ if(!probeReqP2pIe)
+ {
+ tANI_U8* tempbuf = NULL;
+ tANI_U16 tempLen = 0;
+ int left = *addnIELen;
+ v_U8_t *ptr = addIE;
+ v_U8_t elem_id, elem_len;
+
+ if(NULL == addIE)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL(" NULL addIE pointer"));)
+ return eSIR_FAILURE;
+ }
+
+ if( (palAllocateMemory(pMac->hHdd, (void**)&tempbuf,
+ left)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("Unable to allocate memory to store addn IE"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ while(left >= 2)
+ {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if(elem_len > left)
+ {
+ limLog( pMac, LOGE,
+ FL("****Invalid IEs eid = %d elem_len=%d left=%d*****\n"),
+ elem_id,elem_len,left);
+ palFreeMemory(pMac->hHdd, tempbuf);
+ return eSIR_FAILURE;
+ }
+ if ( !( (SIR_MAC_EID_VENDOR == elem_id) &&
+ (memcmp(&ptr[2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)==0) ) )
+ {
+ palCopyMemory ( pMac->hHdd, tempbuf + tempLen, &ptr[0], elem_len + 2);
+ tempLen += (elem_len + 2);
+ }
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ palCopyMemory ( pMac->hHdd, addIE, tempbuf, tempLen);
+ *addnIELen = tempLen;
+ palFreeMemory(pMac->hHdd, tempbuf);
+ }
+ return eSIR_SUCCESS;
+}
+#endif
+
+void
+limSendProbeRspMgmtFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tpAniSSID pSsid,
+ short nStaId,
+ tANI_U8 nKeepAlive,
+ tpPESession psessionEntry,
+ tANI_U8 probeReqP2pIe)
+{
+ tDot11fProbeResponse frm;
+ tSirRetStatus nSirStatus;
+ tANI_U32 cfg, nPayload, nBytes, nStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U8 *pFrame;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U32 addnIEPresent;
+ tANI_U32 addnIE1Len=0;
+ tANI_U32 addnIE2Len=0;
+ tANI_U32 addnIE3Len=0;
+ tANI_U16 totalAddnIeLen = 0;
+ tANI_U32 wpsApEnable=0, tmp;
+ tANI_U8 txFlag = 0;
+ tANI_U8 *addIE = NULL;
+#ifdef WLAN_FEATURE_P2P
+ tANI_U8 *pP2pIe = NULL;
+ tANI_U8 noaLen = 0;
+ tANI_U8 total_noaLen = 0;
+ tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN
+ + SIR_P2P_IE_HEADER_LEN];
+ tANI_U8 noaIe[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+#endif
+
+ if(pMac->gDriverType == eDRIVER_TYPE_MFG) // We don't answer requests
+ {
+ return; // in this case.
+ }
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ // Fill out 'frm', after which we'll just hand the struct off to
+ // 'dot11fPackProbeResponse'.
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ // Timestamp to be updated by TFP, below.
+
+ // Beacon Interval:
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ frm.BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval;
+ }
+ else
+ {
+#endif
+ CFG_LIM_GET_INT_NO_STATUS( nSirStatus, pMac,
+ WNI_CFG_BEACON_INTERVAL, cfg );
+ frm.BeaconInterval.interval = ( tANI_U16 ) cfg;
+#ifdef WLAN_SOFTAP_FEATURE
+ }
+#endif
+
+
+ PopulateDot11fCapabilities( pMac, &frm.Capabilities, psessionEntry );
+ PopulateDot11fSSID( pMac, ( tSirMacSSid* )pSsid, &frm.SSID );
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates,psessionEntry);
+
+ PopulateDot11fDSParams( pMac, &frm.DSParams, psessionEntry->currentOperChannel, psessionEntry);
+ PopulateDot11fIBSSParams( pMac, &frm.IBSSParams, psessionEntry );
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ PopulateDot11fCFParams( pMac, &frm.Capabilities, &frm.CFParams );
+#endif // AP Image
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ if(psessionEntry->wps_state != SAP_WPS_DISABLED)
+ {
+ PopulateDot11fProbeResWPSIEs(pMac, &frm.WscProbeRes, psessionEntry);
+ }
+ }
+ else
+ {
+#endif
+ if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
+ limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_ENABLE );
+
+ wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP;
+
+ if (wpsApEnable)
+ {
+ PopulateDot11fWscInProbeRes(pMac, &frm.WscProbeRes);
+ }
+
+ if (pMac->lim.wscIeInfo.probeRespWscEnrollmentState == eLIM_WSC_ENROLL_BEGIN)
+ {
+ PopulateDot11fWscRegistrarInfoInProbeRes(pMac, &frm.WscProbeRes);
+ pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS;
+ }
+
+ if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END)
+ {
+ DePopulateDot11fWscRegistrarInfoInProbeRes(pMac, &frm.WscProbeRes);
+ pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_NOOP;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ }
+#endif
+
+ PopulateDot11fCountry( pMac, &frm.Country, psessionEntry);
+ PopulateDot11fEDCAParamSet( pMac, &frm.EDCAParamSet, psessionEntry);
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ if( pMac->lim.gLim11hEnable )
+ {
+ PopulateDot11fPowerConstraints( pMac, &frm.PowerConstraints );
+ PopulateDot11fTPCReport( pMac, &frm.TPCReport, psessionEntry);
+
+ // If .11h isenabled & channel switching is not already started and
+ // we're in either PRIMARY_ONLY or PRIMARY_AND_SECONDARY state, then
+ // populate 802.11h channel switch IE
+ if (( pMac->lim.gLimChannelSwitch.switchCount != 0 ) &&
+ ( pMac->lim.gLimChannelSwitch.state ==
+ eLIM_CHANNEL_SWITCH_PRIMARY_ONLY ||
+ pMac->lim.gLimChannelSwitch.state ==
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY ) )
+ {
+ PopulateDot11fChanSwitchAnn( pMac, &frm.ChanSwitchAnn );
+ PopulateDot11fExtChanSwitchAnn(pMac, &frm.ExtChanSwitchAnn);
+ }
+ }
+#endif
+
+ if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B)
+ PopulateDot11fERPInfo( pMac, &frm.ERPInfo, psessionEntry);
+
+
+ // N.B. In earlier implementations, the RSN IE would be placed in
+ // the frame here, before the WPA IE, if 'RSN_BEFORE_WPA' was defined.
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry );
+
+ //Populate HT IEs, when operating in 11n or Taurus modes.
+ if ( psessionEntry->htCapabality )
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+#ifdef WLAN_SOFTAP_FEATURE
+ PopulateDot11fHTInfo( pMac, &frm.HTInfo, psessionEntry );
+#else
+ PopulateDot11fHTInfo( pMac, &frm.HTInfo );
+#endif
+ }
+
+ if ( psessionEntry->pLimStartBssReq )
+ {
+ PopulateDot11fWPA( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ),
+ &frm.WPA );
+ PopulateDot11fRSN( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ),
+ &frm.RSN );
+ }
+
+ PopulateDot11fWMM( pMac, &frm.WMMInfoAp, &frm.WMMParams, &frm.WMMCaps, psessionEntry );
+
+#if defined(FEATURE_WLAN_WAPI)
+ if( psessionEntry->pLimStartBssReq )
+ {
+ PopulateDot11fWAPI( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ),
+ &frm.WAPI );
+ }
+
+#endif // defined(FEATURE_WLAN_WAPI)
+
+
+ nStatus = dot11fGetPackedProbeResponseSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Probe Response (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fProbeResponse );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Probe Response "
+ "(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ addnIEPresent = false;
+
+#ifdef WLAN_FEATURE_P2P
+ if( pMac->lim.gpLimRemainOnChanReq )
+ {
+ nBytes += (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq ) );
+ }
+ //Only use CFG for non-listen mode. This CFG is not working for concurrency
+ //In listening mode, probe rsp IEs is passed in the message from SME to PE
+ else
+#endif
+ {
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
+ &addnIEPresent) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
+ return;
+ }
+ }
+
+ if (addnIEPresent)
+ {
+ if( (palAllocateMemory(pMac->hHdd, (void**)&addIE,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN*3 )) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("Unable to allocate memory to store addn IE"));)
+ return;
+ }
+
+ //Probe rsp IE available
+ if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addnIE1Len) )
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ if (addnIE1Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIE1Len &&
+ (nBytes + addnIE1Len) <= SIR_MAX_PACKET_SIZE)
+ {
+ if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addIE[0],
+ &addnIE1Len) )
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 String"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ }
+
+ //Probe rsp IE available
+ if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA2, &addnIE2Len) )
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 length"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ if (addnIE2Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN && addnIE2Len &&
+ (nBytes + addnIE2Len) <= SIR_MAX_PACKET_SIZE)
+ {
+ if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA2, &addIE[addnIE1Len],
+ &addnIE2Len) )
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 String"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ }
+
+ //Probe rsp IE available
+ if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA3, &addnIE3Len) )
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 length"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ if (addnIE3Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN && addnIE3Len &&
+ (nBytes + addnIE3Len) <= SIR_MAX_PACKET_SIZE)
+ {
+ if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
+ &addIE[addnIE1Len + addnIE2Len],
+ &addnIE3Len) )
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 String"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ }
+ totalAddnIeLen = addnIE1Len + addnIE2Len + addnIE3Len;
+
+#ifdef WLAN_FEATURE_P2P
+ if(eSIR_SUCCESS != limGetAddnIeForProbeResp(pMac, addIE, &totalAddnIeLen, probeReqP2pIe))
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to get final Additional IE for Probe Req"));
+ palFreeMemory(pMac->hHdd, addIE);
+ return;
+ }
+ nBytes = nBytes + totalAddnIeLen;
+
+ if (probeReqP2pIe)
+ {
+ pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], totalAddnIeLen);
+ if (pP2pIe != NULL)
+ {
+ //get NoA attribute stream P2P IE
+ noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry);
+ if (noaLen != 0)
+ {
+ total_noaLen = limBuildP2pIe(pMac, &noaIe[0],
+ &noaStream[0], noaLen);
+ nBytes = nBytes + total_noaLen;
+ }
+ }
+ }
+#endif
+ }
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro"
+ "be Response.\n"), nBytes );
+ if ( addIE != NULL )
+ {
+ palFreeMemory(pMac->hHdd, addIE);
+ }
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_PROBE_RSP, peerMacAddr,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a Probe Response (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ if ( addIE != NULL )
+ {
+ palFreeMemory(pMac->hHdd, addIE);
+ }
+ return;
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // That done, pack the Probe Response:
+ nStatus = dot11fPackProbeResponse( pMac, &frm, pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ if ( addIE != NULL )
+ {
+ palFreeMemory(pMac->hHdd, addIE);
+ }
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a P"
+ "robe Response (0x%08x).\n") );
+ }
+
+ PELOG3(limLog( pMac, LOG3, FL("Sending Probe Response frame to ") );
+ limPrintMacAddr( pMac, peerMacAddr, LOG3 );)
+
+ pMac->sys.probeRespond++;
+
+#ifdef WLAN_FEATURE_P2P
+ if( pMac->lim.gpLimRemainOnChanReq )
+ {
+ palCopyMemory ( pMac->hHdd, pFrame+sizeof(tSirMacMgmtHdr)+nPayload,
+ pMac->lim.gpLimRemainOnChanReq->probeRspIe, (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq )) );
+ }
+#endif
+
+ if ( addnIEPresent )
+ {
+ if (palCopyMemory ( pMac->hHdd, pFrame+sizeof(tSirMacMgmtHdr)+nPayload,
+ &addIE[0], totalAddnIeLen) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Additional Probe Rp IE request failed while Appending: %x"),halstatus);
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ if ( addIE != NULL )
+ {
+ palFreeMemory(pMac->hHdd, addIE);
+ }
+ return;
+ }
+ }
+#ifdef WLAN_FEATURE_P2P
+ if (noaLen != 0)
+ {
+ if (palCopyMemory ( pMac->hHdd, &pFrame[nBytes - (total_noaLen)],
+ &noaIe[0], total_noaLen) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("Not able to insert NoA because of length constraint"));
+ }
+ }
+#endif
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ // Queue Probe Response frame in high priority WQ
+ halstatus = halTxFrame( ( tHalHandle ) pMac, pPacket,
+ ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_LOW,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Could not send Probe Response.\n") );
+ //Pkt will be freed up by the callback
+ }
+
+ if ( addIE != NULL )
+ {
+ palFreeMemory(pMac->hHdd, addIE);
+ }
+
+} // End limSendProbeRspMgmtFrame.
+
+void
+limSendAddtsReqActionFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirAddtsReqInfo *pAddTS,
+ tpPESession psessionEntry)
+{
+ tANI_U16 i;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tDot11fAddTSRequest AddTSReq;
+ tDot11fWMMAddTSRequest WMMAddTSReq;
+ tANI_U32 nPayload, nBytes, nStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ void *pPacket;
+#ifdef FEATURE_WLAN_CCX
+ tANI_U32 phyMode;
+#endif
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ if ( ! pAddTS->wmeTspecPresent )
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&AddTSReq, sizeof( AddTSReq ) );
+
+ AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+ AddTSReq.DialogToken.token = pAddTS->dialogToken;
+ AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+ if ( pAddTS->lleTspecPresent )
+ {
+ PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSReq.TSPEC );
+ }
+ else
+ {
+ PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSReq.WMMTSPEC );
+ }
+
+ if ( pAddTS->lleTspecPresent )
+ {
+ AddTSReq.num_WMMTCLAS = 0;
+ AddTSReq.num_TCLAS = pAddTS->numTclas;
+ for ( i = 0; i < pAddTS->numTclas; ++i)
+ {
+ PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i],
+ &AddTSReq.TCLAS[i] );
+ }
+ }
+ else
+ {
+ AddTSReq.num_TCLAS = 0;
+ AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
+ for ( i = 0; i < pAddTS->numTclas; ++i)
+ {
+ PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i],
+ &AddTSReq.WMMTCLAS[i] );
+ }
+ }
+
+ if ( pAddTS->tclasProcPresent )
+ {
+ if ( pAddTS->lleTspecPresent )
+ {
+ AddTSReq.TCLASSPROC.processing = pAddTS->tclasProc;
+ AddTSReq.TCLASSPROC.present = 1;
+ }
+ else
+ {
+ AddTSReq.WMMTCLASPROC.version = 1;
+ AddTSReq.WMMTCLASPROC.processing = pAddTS->tclasProc;
+ AddTSReq.WMMTCLASPROC.present = 1;
+ }
+ }
+
+ nStatus = dot11fGetPackedAddTSRequestSize( pMac, &AddTSReq, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or an Add TS Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAddTSRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for an Add TS Request"
+ " (0x%08x).\n"), nStatus );
+ }
+ }
+ else
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&WMMAddTSReq, sizeof( WMMAddTSReq ) );
+
+ WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+ WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
+ WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
+
+ // WMM spec 2.2.10 - status code is only filled in for ADDTS response
+ WMMAddTSReq.StatusCode.statusCode = 0;
+
+ PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSReq.WMMTSPEC );
+#ifdef FEATURE_WLAN_CCX
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A)
+ {
+ pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
+ }
+ else
+ {
+ pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
+ }
+ PopulateDot11TSRSIE(pMac,&pAddTS->tsrsIE, &WMMAddTSReq.CCXTrafStrmRateSet,sizeof(tANI_U8));
+#endif
+ // fillWmeTspecIE
+
+ nStatus = dot11fGetPackedWMMAddTSRequestSize( pMac, &WMMAddTSReq, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a WMM Add TS Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAddTSRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a WMM Add TS Requ"
+ "est (0x%08x).\n"), nStatus );
+ }
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
+ "d TS Request.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peerMacAddr,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Add TS Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ #if 0
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID,
+ ( tANI_U8* )pMacHdr->bssId, &cfgLen ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil"
+ "e sending an Add TS Request.\n") );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ #endif //TO SUPPORT BT-AMP
+
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // That done, pack the struct:
+ if ( ! pAddTS->wmeTspecPresent )
+ {
+ nStatus = dot11fPackAddTSRequest( pMac, &AddTSReq,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack an Add TS Request "
+ "(0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "an Add TS Request (0x%08x).\n") );
+ }
+ }
+ else
+ {
+ nStatus = dot11fPackWMMAddTSRequest( pMac, &WMMAddTSReq,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Reque"
+ "st (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "a WMM Add TS Request (0x%08x).\n") );
+ }
+ }
+
+ PELOG3(limLog( pMac, LOG3, FL("Sending an Add TS Request frame to ") );
+ limPrintMacAddr( pMac, peerMacAddr, LOG3 );)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ // Queue Addts Response frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL( "*** Could not send an Add TS Request"
+ " (%X) ***\n" ), halstatus );
+ //Pkt will be freed up by the callback
+ }
+
+} // End limSendAddtsReqActionFrame.
+
+/* Added ANI_PRODUCT_TYPE_CLIENT for BT-AMP Support */
+#ifdef ANI_PRODUCT_TYPE_AP
+
+void
+limSendAssocRspMgmtFrame(tpAniSirGlobal pMac,
+ tANI_U16 statusCode,
+ tANI_U16 aid,
+ tSirMacAddr peerMacAddr,
+ tANI_U8 subType,
+ tpDphHashNode pSta,
+ tpPESession psessionEntry)
+{
+ tDot11fAssocResponse frm;
+ tANI_U8 *pFrame, *macAddr;
+ tpSirMacMgmtHdr pMacHdr;
+ tSirRetStatus nSirStatus;
+ tANI_U8 lleMode = 0, fAddTS, edcaInclude = 0;
+ tHalBitVal qosMode, wmeMode;
+ tANI_U32 nPayload, nBytes, nStatus, cfgLen;
+ void *pPacket;
+ eHalStatus halstatus;
+ tUpdateBeaconParams beaconParams;
+ tANI_U32 wpsApEnable=0, tmp;
+ tANI_U8 txFlag = 0;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ limGetQosMode(pMac, &qosMode);
+ limGetWmeMode(pMac, &wmeMode);
+
+ // An Add TS IE is added only if the AP supports it and the requesting
+ // STA sent a traffic spec.
+ fAddTS = ( qosMode && pSta && pSta->qos.addtsPresent ) ? 1 : 0;
+
+ PopulateDot11fCapabilities( pMac, &frm.Capabilities, psessionEntry);
+
+ frm.Status.status = statusCode;
+
+ frm.AID.associd = aid | LIM_AID_MASK;
+
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.SuppRates );
+
+ if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
+ limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_ENABLE );
+
+ wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP;
+
+ if (wpsApEnable)
+ {
+ PopulateDot11fWscInAssocRes(pMac, &frm.WscAssocRes);
+ }
+
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry );
+
+ if ( NULL != pSta )
+ {
+ if ( eHAL_SET == qosMode )
+ {
+ if ( pSta->lleEnabled )
+ {
+ lleMode = 1;
+ if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) )
+ {
+ PopulateDot11fEDCAParamSet( pMac, &frm.EDCAParamSet, psessionEntry);
+
+// FramesToDo:...
+// if ( fAddTS )
+// {
+// tANI_U8 *pAf = pBody;
+// *pAf++ = SIR_MAC_QOS_ACTION_EID;
+// tANI_U32 tlen;
+// status = sirAddtsRspFill(pMac, pAf, statusCode, &pSta->qos.addts, NULL,
+// &tlen, bufLen - frameLen);
+// } // End if on Add TS.
+ }
+ } // End if on .11e enabled in 'pSta'.
+ } // End if on QOS Mode on.
+
+ if ( ( ! lleMode ) && ( eHAL_SET == wmeMode ) && pSta->wmeEnabled )
+ {
+ if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) )
+ {
+ PopulateDot11fWMMParams( pMac, &frm.WMMParams );
+
+ if ( pSta->wsmEnabled )
+ {
+ PopulateDot11fWMMCaps(&frm.WMMCaps );
+ }
+ }
+ }
+
+ if ( pSta->aniPeer )
+ {
+ if ( ( lleMode && PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) ||
+ ( pSta->wmeEnabled && PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) )
+ {
+ edcaInclude = 1;
+ }
+
+ } // End if on Airgo peer.
+
+ if ( pSta->mlmStaContext.htCapability &&
+ pMac->lim.htCapability )
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+ PopulateDot11fHTInfo( pMac, &frm.HTInfo );
+ }
+ } // End if on non-NULL 'pSta'.
+
+
+ if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideApProtection(pMac, peerMacAddr, &beaconParams);
+ limUpdateShortPreamble(pMac, peerMacAddr, &beaconParams);
+ limUpdateShortSlotTime(pMac, peerMacAddr, &beaconParams);
+
+ //Send message to HAL about beacon parameter change.
+ if(beaconParams.paramChangeBitmap)
+ {
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry );
+ }
+
+ // Allocate a buffer for this frame:
+ nStatus = dot11fGetPackedAssocResponseSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to calculate the packed size f"
+ "or an Association Response (0x%08x).\n"),
+ nStatus );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for an Association Re"
+ "sponse (0x%08x).\n"), nStatus );
+ }
+
+ nBytes = sizeof( tSirMacMgmtHdr ) + nPayload;
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog(pMac, LOGP, FL("Call to bufAlloc failed for RE/ASSOC RSP.\n"));
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac,
+ pFrame,
+ SIR_MAC_MGMT_FRAME,
+ ( LIM_ASSOC == subType ) ?
+ SIR_MAC_MGMT_ASSOC_RSP :
+ SIR_MAC_MGMT_REASSOC_RSP,
+ peerMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Association Response (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID,
+ ( tANI_U8* )pMacHdr->bssId, &cfgLen ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil"
+ "e sending an Association Response.\n") );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+
+ nStatus = dot11fPackAssocResponse( pMac, &frm,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack an Association Response (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing an "
+ "Association Response (0x%08x).\n") );
+ }
+
+ macAddr = pMacHdr->da;
+
+ if (subType == LIM_ASSOC)
+ limLog(pMac, LOG1,
+ FL("*** Sending Assoc Resp status %d aid %d to "),
+ statusCode, aid);
+ else
+ limLog(pMac, LOG1,
+ FL("*** Sending ReAssoc Resp status %d aid %d to "),
+ statusCode, aid);
+ limPrintMacAddr(pMac, pMacHdr->da, LOG1);
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ /// Queue Association Response frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog(pMac, LOGE,
+ FL("*** Could not Send Re/AssocRsp, retCode=%X ***\n"),
+ nSirStatus);
+
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ (void *) pFrame, (void *) pPacket );
+ }
+
+ // update the ANI peer station count
+ //FIXME_PROTECTION : take care of different type of station
+ // counter inside this function.
+ limUtilCountStaAdd(pMac, pSta, psessionEntry);
+
+} // End limSendAssocRspMgmtFrame.
+
+
+#endif // ANI_PRODUCT_TYPE_AP
+
+
+void
+limSendAssocRspMgmtFrame(tpAniSirGlobal pMac,
+ tANI_U16 statusCode,
+ tANI_U16 aid,
+ tSirMacAddr peerMacAddr,
+ tANI_U8 subType,
+ tpDphHashNode pSta,tpPESession psessionEntry)
+{
+ static tDot11fAssocResponse frm;
+ tANI_U8 *pFrame, *macAddr;
+ tpSirMacMgmtHdr pMacHdr;
+ tSirRetStatus nSirStatus;
+ tANI_U8 lleMode = 0, fAddTS, edcaInclude = 0;
+ tHalBitVal qosMode, wmeMode;
+ tANI_U32 nPayload, nBytes, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tUpdateBeaconParams beaconParams;
+ tANI_U8 txFlag = 0;
+ tANI_U32 addnIEPresent = false;
+ tANI_U32 addnIELen=0;
+ tANI_U8 addIE[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
+ tpSirAssocReq pAssocReq = NULL;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ limGetQosMode(psessionEntry, &qosMode);
+ limGetWmeMode(psessionEntry, &wmeMode);
+
+ // An Add TS IE is added only if the AP supports it and the requesting
+ // STA sent a traffic spec.
+ fAddTS = ( qosMode && pSta && pSta->qos.addtsPresent ) ? 1 : 0;
+
+ PopulateDot11fCapabilities( pMac, &frm.Capabilities, psessionEntry );
+
+ frm.Status.status = statusCode;
+
+ frm.AID.associd = aid | LIM_AID_MASK;
+
+ if ( NULL == pSta )
+ {
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.SuppRates,psessionEntry);
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates, psessionEntry );
+ }
+ else
+ {
+ PopulateDot11fAssocRspRates( pMac, &frm.SuppRates, &frm.ExtSuppRates,
+ pSta->supportedRates.llbRates, pSta->supportedRates.llaRates );
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ {
+ if( pSta != NULL && eSIR_SUCCESS == statusCode )
+ {
+ pAssocReq =
+ (tpSirAssocReq) psessionEntry->parsedAssocReq[pSta->assocId];
+#ifdef WLAN_FEATURE_P2P
+ /* populate P2P IE in AssocRsp when assocReq from the peer includes P2P IE */
+ if( pAssocReq != NULL && pAssocReq->addIEPresent ) {
+ PopulateDot11AssocResP2PIE(pMac, &frm.P2PAssocRes, pAssocReq);
+ }
+#endif
+ }
+ }
+#endif
+
+ if ( NULL != pSta )
+ {
+ if ( eHAL_SET == qosMode )
+ {
+ if ( pSta->lleEnabled )
+ {
+ lleMode = 1;
+ if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) )
+ {
+ PopulateDot11fEDCAParamSet( pMac, &frm.EDCAParamSet, psessionEntry);
+
+// FramesToDo:...
+// if ( fAddTS )
+// {
+// tANI_U8 *pAf = pBody;
+// *pAf++ = SIR_MAC_QOS_ACTION_EID;
+// tANI_U32 tlen;
+// status = sirAddtsRspFill(pMac, pAf, statusCode, &pSta->qos.addts, NULL,
+// &tlen, bufLen - frameLen);
+// } // End if on Add TS.
+ }
+ } // End if on .11e enabled in 'pSta'.
+ } // End if on QOS Mode on.
+
+ if ( ( ! lleMode ) && ( eHAL_SET == wmeMode ) && pSta->wmeEnabled )
+ {
+ if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) )
+ {
+
+#ifdef WLAN_SOFTAP_FEATURE
+ PopulateDot11fWMMParams( pMac, &frm.WMMParams, psessionEntry);
+#else
+ PopulateDot11fWMMParams( pMac, &frm.WMMParams );
+#endif
+
+ if ( pSta->wsmEnabled )
+ {
+ PopulateDot11fWMMCaps(&frm.WMMCaps );
+ }
+ }
+ }
+
+ if ( pSta->aniPeer )
+ {
+ if ( ( lleMode && PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) ||
+ ( pSta->wmeEnabled && PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) )
+ {
+ edcaInclude = 1;
+ }
+
+ } // End if on Airgo peer.
+
+ if ( pSta->mlmStaContext.htCapability &&
+ psessionEntry->htCapabality )
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+#ifdef WLAN_SOFTAP_FEATURE
+ PopulateDot11fHTInfo( pMac, &frm.HTInfo, psessionEntry );
+#else
+ PopulateDot11fHTInfo( pMac, &frm.HTInfo );
+#endif
+ }
+ } // End if on non-NULL 'pSta'.
+
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&beaconParams, sizeof( tUpdateBeaconParams) );
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if( psessionEntry->limSystemRole == eLIM_AP_ROLE ){
+ if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ limDecideApProtection(pMac, peerMacAddr, &beaconParams,psessionEntry);
+ }
+#endif
+
+ limUpdateShortPreamble(pMac, peerMacAddr, &beaconParams, psessionEntry);
+ limUpdateShortSlotTime(pMac, peerMacAddr, &beaconParams, psessionEntry);
+
+ beaconParams.bssIdx = psessionEntry->bssIdx;
+
+ //Send message to HAL about beacon parameter change.
+ if(beaconParams.paramChangeBitmap)
+ {
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry );
+ }
+
+ // Allocate a buffer for this frame:
+ nStatus = dot11fGetPackedAssocResponseSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to calculate the packed size f"
+ "or an Association Response (0x%08x).\n"),
+ nStatus );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for an Association Re"
+ "sponse (0x%08x).\n"), nStatus );
+ }
+
+ nBytes = sizeof( tSirMacMgmtHdr ) + nPayload;
+
+ if ( pAssocReq != NULL )
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_FLAG,
+ &addnIEPresent) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_ASSOC_RSP_ADDNIE_FLAG"));
+ return;
+ }
+
+ if (addnIEPresent)
+ {
+ //Assoc rsp IE available
+ if (wlan_cfgGetStrLen(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA,
+ &addnIELen) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Unable to get WNI_CFG_ASSOC_RSP_ADDNIE_DATA length"));
+ return;
+ }
+
+ if (addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN && addnIELen &&
+ (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE)
+ {
+ if (wlan_cfgGetStr(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA,
+ &addIE[0], &addnIELen) == eSIR_SUCCESS)
+ {
+ nBytes = nBytes + addnIELen;
+ }
+ }
+ }
+ }
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog(pMac, LOGP, FL("Call to bufAlloc failed for RE/ASSOC RSP.\n"));
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac,
+ pFrame,
+ SIR_MAC_MGMT_FRAME,
+ ( LIM_ASSOC == subType ) ?
+ SIR_MAC_MGMT_ASSOC_RSP :
+ SIR_MAC_MGMT_REASSOC_RSP,
+ peerMacAddr,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Association Response (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ #if 0
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if ( eSIR_SUCCESS != cfgGetStr( pMac, WNI_CFG_BSSID,
+ ( tANI_U8* )pMacHdr->bssId, &cfgLen ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil"
+ "e sending an Association Response.\n") );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ nStatus = dot11fPackAssocResponse( pMac, &frm,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack an Association Response (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing an "
+ "Association Response (0x%08x).\n") );
+ }
+
+ macAddr = pMacHdr->da;
+
+ if (subType == LIM_ASSOC)
+ {
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Sending Assoc Resp status %d aid %d to "),
+ statusCode, aid);)
+ }
+ else{
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Sending ReAssoc Resp status %d aid %d to "),
+ statusCode, aid);)
+ }
+ PELOG1(limPrintMacAddr(pMac, pMacHdr->da, LOG1);)
+
+ if ( addnIEPresent )
+ {
+ if (palCopyMemory ( pMac->hHdd, pFrame+sizeof(tSirMacMgmtHdr)+nPayload,
+ &addIE[0], addnIELen ) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Additional Assoc IEs request failed while Appending: %x\n"),halstatus);
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ }
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ /// Queue Association Response frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog(pMac, LOGE,
+ FL("*** Could not Send Re/AssocRsp, retCode=%X ***\n"),
+ nSirStatus);
+
+ //Pkt will be freed up by the callback
+ }
+
+ // update the ANI peer station count
+ //FIXME_PROTECTION : take care of different type of station
+ // counter inside this function.
+ limUtilCountStaAdd(pMac, pSta, psessionEntry);
+
+} // End limSendAssocRspMgmtFrame.
+
+
+
+void
+limSendAddtsRspActionFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ tANI_U16 nStatusCode,
+ tSirAddtsReqInfo *pAddTS,
+ tSirMacScheduleIE *pSchedule,
+ tpPESession psessionEntry)
+{
+ tANI_U8 *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tDot11fAddTSResponse AddTSRsp;
+ tDot11fWMMAddTSResponse WMMAddTSRsp;
+ tSirRetStatus nSirStatus;
+ tANI_U32 i, nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ if ( ! pAddTS->wmeTspecPresent )
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&AddTSRsp, sizeof( AddTSRsp ) );
+
+ AddTSRsp.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+ AddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP;
+ AddTSRsp.DialogToken.token = pAddTS->dialogToken;
+ AddTSRsp.Status.status = nStatusCode;
+
+ // The TsDelay information element is only filled in for a specific
+ // status code:
+ if ( eSIR_MAC_TS_NOT_CREATED_STATUS == nStatusCode )
+ {
+ if ( pAddTS->wsmTspecPresent )
+ {
+ AddTSRsp.WMMTSDelay.version = 1;
+ AddTSRsp.WMMTSDelay.delay = 10;
+ AddTSRsp.WMMTSDelay.present = 1;
+ }
+ else
+ {
+ AddTSRsp.TSDelay.delay = 10;
+ AddTSRsp.TSDelay.present = 1;
+ }
+ }
+
+ if ( pAddTS->wsmTspecPresent )
+ {
+ PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSRsp.WMMTSPEC );
+ }
+ else
+ {
+ PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSRsp.TSPEC );
+ }
+
+ if ( pAddTS->wsmTspecPresent )
+ {
+ AddTSRsp.num_WMMTCLAS = 0;
+ AddTSRsp.num_TCLAS = pAddTS->numTclas;
+ for ( i = 0; i < AddTSRsp.num_TCLAS; ++i)
+ {
+ PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i],
+ &AddTSRsp.TCLAS[i] );
+ }
+ }
+ else
+ {
+ AddTSRsp.num_TCLAS = 0;
+ AddTSRsp.num_WMMTCLAS = pAddTS->numTclas;
+ for ( i = 0; i < AddTSRsp.num_WMMTCLAS; ++i)
+ {
+ PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i],
+ &AddTSRsp.WMMTCLAS[i] );
+ }
+ }
+
+ if ( pAddTS->tclasProcPresent )
+ {
+ if ( pAddTS->wsmTspecPresent )
+ {
+ AddTSRsp.WMMTCLASPROC.version = 1;
+ AddTSRsp.WMMTCLASPROC.processing = pAddTS->tclasProc;
+ AddTSRsp.WMMTCLASPROC.present = 1;
+ }
+ else
+ {
+ AddTSRsp.TCLASSPROC.processing = pAddTS->tclasProc;
+ AddTSRsp.TCLASSPROC.present = 1;
+ }
+ }
+
+ // schedule element is included only if requested in the tspec and we are
+ // using hcca (or both edca and hcca)
+ // 11e-D8.0 is inconsistent on whether the schedule element is included
+ // based on tspec schedule bit or not. Sec 7.4.2.2. says one thing but
+ // pg 46, line 17-18 says something else. So just include it and let the
+ // sta figure it out
+ if ((pSchedule != NULL) &&
+ ((pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
+ (pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)))
+ {
+ if ( pAddTS->wsmTspecPresent )
+ {
+ PopulateDot11fWMMSchedule( pSchedule, &AddTSRsp.WMMSchedule );
+ }
+ else
+ {
+ PopulateDot11fSchedule( pSchedule, &AddTSRsp.Schedule );
+ }
+ }
+
+ nStatus = dot11fGetPackedAddTSResponseSize( pMac, &AddTSRsp, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed si"
+ "ze for an Add TS Response (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAddTSResponse );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calcula"
+ "tingthe packed size for an Add TS"
+ " Response (0x%08x).\n"), nStatus );
+ }
+ }
+ else
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&WMMAddTSRsp, sizeof( WMMAddTSRsp ) );
+
+ WMMAddTSRsp.Category.category = SIR_MAC_ACTION_WME;
+ WMMAddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP;
+ WMMAddTSRsp.DialogToken.token = pAddTS->dialogToken;
+ WMMAddTSRsp.StatusCode.statusCode = (tANI_U8)nStatusCode;
+
+ PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSRsp.WMMTSPEC );
+
+ nStatus = dot11fGetPackedWMMAddTSResponseSize( pMac, &WMMAddTSRsp, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed si"
+ "ze for a WMM Add TS Response (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fWMMAddTSResponse );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calcula"
+ "tingthe packed size for a WMM Add"
+ "TS Response (0x%08x).\n"), nStatus );
+ }
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
+ "d TS Response.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Add TS Response (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+
+ #if 0
+ if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID,
+ ( tANI_U8* )pMacHdr->bssId, &cfgLen ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil"
+ "e sending an Add TS Response.\n") );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // That done, pack the struct:
+ if ( ! pAddTS->wmeTspecPresent )
+ {
+ nStatus = dot11fPackAddTSResponse( pMac, &AddTSRsp,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack an Add TS Response "
+ "(0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "an Add TS Response (0x%08x).\n") );
+ }
+ }
+ else
+ {
+ nStatus = dot11fPackWMMAddTSResponse( pMac, &WMMAddTSRsp,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Response "
+ "(0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "a WMM Add TS Response (0x%08x).\n") );
+ }
+ }
+
+ PELOG1(limLog( pMac, LOG1, FL("Sending an Add TS Response (status %d) to "),
+ nStatusCode );
+ limPrintMacAddr( pMac, pMacHdr->da, LOG1 );)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ // Queue the frame in high priority WQ:
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Add TS Response (%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ }
+
+} // End limSendAddtsRspActionFrame.
+
+void
+limSendDeltsReqActionFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ tANI_U8 wmmTspecPresent,
+ tSirMacTSInfo *pTsinfo,
+ tSirMacTspecIE *pTspecIe,
+ tpPESession psessionEntry)
+{
+ tANI_U8 *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tDot11fDelTS DelTS;
+ tDot11fWMMDelTS WMMDelTS;
+ tSirRetStatus nSirStatus;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ if ( ! wmmTspecPresent )
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&DelTS, sizeof( DelTS ) );
+
+ DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+ DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+ PopulateDot11fTSInfo( pTsinfo, &DelTS.TSInfo );
+
+ nStatus = dot11fGetPackedDelTSSize( pMac, &DelTS, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed si"
+ "ze for a Del TS (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fDelTS );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calcula"
+ "ting the packed size for a Del TS"
+ " (0x%08x).\n"), nStatus );
+ }
+ }
+ else
+ {
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&WMMDelTS, sizeof( WMMDelTS ) );
+
+ WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
+ WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+ WMMDelTS.DialogToken.token = 0;
+ WMMDelTS.StatusCode.statusCode = 0;
+ PopulateDot11fWMMTSPEC( pTspecIe, &WMMDelTS.WMMTSPEC );
+ nStatus = dot11fGetPackedWMMDelTSSize( pMac, &WMMDelTS, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed si"
+ "ze for a WMM Del TS (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fDelTS );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calcula"
+ "ting the packed size for a WMM De"
+ "l TS (0x%08x).\n"), nStatus );
+ }
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
+ "d TS Response.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer,
+ psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Add TS Response (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ #if 0
+
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID,
+ ( tANI_U8* )pMacHdr->bssId, &cfgLen ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil"
+ "e sending an Add TS Response.\n") );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId, psessionEntry->bssId);
+
+ // That done, pack the struct:
+ if ( !wmmTspecPresent )
+ {
+ nStatus = dot11fPackDelTS( pMac, &DelTS,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Del TS frame (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "a Del TS frame (0x%08x).\n") );
+ }
+ }
+ else
+ {
+ nStatus = dot11fPackWMMDelTS( pMac, &WMMDelTS,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a WMM Del TS frame (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing"
+ "a WMM Del TS frame (0x%08x).\n") );
+ }
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
+ limPrintMacAddr(pMac, pMacHdr->da, LOG1);)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Del TS (%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ }
+
+} // End limSendDeltsReqActionFrame.
+
+void
+limSendAssocReqMgmtFrame(tpAniSirGlobal pMac,
+ tLimMlmAssocReq *pMlmAssocReq,
+ tpPESession psessionEntry)
+{
+ tDot11fAssocRequest frm;
+ tANI_U16 caps;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tLimMlmAssocCnf mlmAssocCnf;
+ tANI_U32 nBytes, nPayload, nStatus;
+ tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U16 nAddIELen;
+ tANI_U8 *pAddIE;
+ tANI_U8 *wpsIe = NULL;
+#if defined WLAN_FEATURE_VOWIFI
+ tANI_U8 PowerCapsPopulated = FALSE;
+#endif
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ if(NULL == psessionEntry->pLimJoinReq)
+ {
+ return;
+ }
+
+ /* check this early to avoid unncessary operation */
+ if(NULL == psessionEntry->pLimJoinReq)
+ {
+ return;
+ }
+ nAddIELen = psessionEntry->pLimJoinReq->addIEAssoc.length;
+ pAddIE = psessionEntry->pLimJoinReq->addIEAssoc.addIEdata;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ caps = pMlmAssocReq->capabilityInfo;
+ if ( PROP_CAPABILITY_GET( 11EQOS, psessionEntry->limCurrentBssPropCap ) )
+ ((tSirMacCapabilityInfo *) &caps)->qos = 0;
+#if defined(FEATURE_WLAN_WAPI)
+ /* CR: 262463 :
+ According to WAPI standard:
+ 7.3.1.4 Capability Information field
+ In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
+ Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
+ Reassociation management frames. */
+ if ( psessionEntry->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swapBitField16(caps, ( tANI_U16* )&frm.Capabilities );
+
+ frm.ListenInterval.interval = pMlmAssocReq->listenInterval;
+ PopulateDot11fSSID2( pMac, &frm.SSID );
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates,psessionEntry);
+
+ fQosEnabled = ( psessionEntry->limQosEnabled) &&
+ SIR_MAC_GET_QOS( psessionEntry->limCurrentBssCaps );
+
+ fWmeEnabled = ( psessionEntry->limWmeEnabled ) &&
+ LIM_BSS_CAPS_GET( WME, psessionEntry->limCurrentBssQosCaps );
+
+ // We prefer .11e asociations:
+ if ( fQosEnabled ) fWmeEnabled = false;
+
+ fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled &&
+ LIM_BSS_CAPS_GET( WSM, psessionEntry->limCurrentBssQosCaps );
+
+ if ( psessionEntry->lim11hEnable &&
+ psessionEntry->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE )
+ {
+#if defined WLAN_FEATURE_VOWIFI
+ PowerCapsPopulated = TRUE;
+
+ PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_ASSOC,psessionEntry);
+#endif
+ PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_ASSOC,psessionEntry);
+
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) )
+ {
+ if (PowerCapsPopulated == FALSE)
+ {
+ PowerCapsPopulated = TRUE;
+ PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_ASSOC, psessionEntry);
+ }
+ }
+#endif
+
+ if ( fQosEnabled &&
+ ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limCurrentBssPropCap)))
+ PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation );
+
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry );
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) )
+ {
+ PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry );
+ }
+#endif
+ // The join request *should* contain zero or one of the WPA and RSN
+ // IEs. The payload send along with the request is a
+ // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+
+ // typedef struct sSirRSNie
+ // {
+ // tANI_U16 length;
+ // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+ // } tSirRSNie, *tpSirRSNie;
+
+ // So, we should be able to make the following two calls harmlessly,
+ // since they do nothing if they don't find the given IE in the
+ // bytestream with which they're provided.
+
+ // The net effect of this will be to faithfully transmit whatever
+ // security IE is in the join request.
+
+ // *However*, if we're associating for the purpose of WPS
+ // enrollment, and we've been configured to indicate that by
+ // eliding the WPA or RSN IE, we just skip this:
+ if( nAddIELen && pAddIE )
+ {
+ wpsIe = limGetWscIEPtr (pMac, pAddIE, nAddIELen);
+ }
+ if ( NULL == wpsIe )
+ {
+ PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ),
+ &frm.RSNOpaque );
+ PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ),
+ &frm.WPAOpaque );
+#if defined(FEATURE_WLAN_WAPI)
+ PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ),
+ &frm.WAPIOpaque );
+#endif // defined(FEATURE_WLAN_WAPI)
+ }
+
+ // include WME EDCA IE as well
+ if ( fWmeEnabled )
+ {
+ if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limCurrentBssPropCap ) )
+ {
+ PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation );
+ }
+
+ if ( fWsmEnabled &&
+ ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limCurrentBssPropCap )))
+ {
+ PopulateDot11fWMMCaps( &frm.WMMCaps );
+ }
+ }
+
+ //Populate HT IEs, when operating in 11n or Taurus modes AND
+ //when AP is also operating in 11n mode.
+ if ( psessionEntry->htCapabality &&
+ pMac->lim.htCapabilityPresentInBeacon)
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+#ifdef DISABLE_GF_FOR_INTEROP
+
+ /*
+ * To resolve the interop problem with Broadcom AP,
+ * where TQ STA could not pass traffic with GF enabled,
+ * TQ STA will do Greenfield only with TQ AP, for
+ * everybody else it will be turned off.
+ */
+
+ if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator))
+ {
+ limLog( pMac, LOG1, FL("Sending Assoc Req to Non-TQ AP, Turning off Greenfield"));
+ frm.HTCaps.greenField = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ }
+#endif
+
+ }
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (psessionEntry->pLimJoinReq->is11Rconnection)
+ {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL("mdie = %02x %02x %02x\n"),
+ (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[0],
+ (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[1],
+ (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[2]);
+#endif
+ PopulateMDIE( pMac, &frm.MobilityDomain, psessionEntry->pLimJoinReq->bssDescription.mdie);
+ }
+ else
+ {
+ // No 11r IEs dont send any MDIE
+ limLog( pMac, LOGE, FL("mdie not present\n"));
+ }
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ // For CCX Associations fill the CCX IEs
+ if (psessionEntry->isCCXconnection)
+ {
+ PopulateDot11fCCXRadMgmtCap(&frm.CCXRadMgmtCap);
+ PopulateDot11fCCXVersion(&frm.CCXVersion);
+ }
+#endif
+
+ nStatus = dot11fGetPackedAssocRequestSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or an Association Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAssocRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for an Association Re "
+ "quest(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen;
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an As"
+ "sociation Request.\n"), nBytes );
+
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+
+ /* Update PE session id*/
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+
+ mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+
+ limPostSmeMessage( pMac, LIM_MLM_ASSOC_CNF,
+ ( tANI_U32* ) &mlmAssocCnf);
+
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ASSOC_REQ, psessionEntry->bssId,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Association Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+
+
+ // That done, pack the Probe Request:
+ nStatus = dot11fPackAssocRequest( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%0"
+ "8x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a P"
+ "robe Response (0x%08x).\n") );
+ }
+
+ PELOG1(limLog( pMac, LOG1, FL("*** Sending Association Request length %d"
+ "to \n"),
+ nBytes );)
+ // limPrintMacAddr( pMac, bssid, LOG1 );
+
+ if( psessionEntry->assocReq != NULL )
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+ }
+
+ if( nAddIELen )
+ {
+ palCopyMemory( pMac->hHdd, pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+ pAddIE,
+ nAddIELen );
+ nPayload += nAddIELen;
+ }
+
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->assocReq, nPayload)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));)
+ }
+ else
+ {
+ //Store the Assoc request. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload);
+ psessionEntry->assocReqLen = nPayload;
+ }
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload),
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Association Request (%X)!\n"),
+ halstatus );
+ //Pkt will be freed up by the callback
+ return;
+ }
+
+ // Free up buffer allocated for mlmAssocReq
+ palFreeMemory( pMac->hHdd, ( tANI_U8* ) pMlmAssocReq );
+
+} // End limSendAssocReqMgmtFrame
+
+
+
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX
+/*------------------------------------------------------------------------------------
+ *
+ * Send Reassoc Req with FTIEs.
+ *
+ *-----------------------------------------------------------------------------------
+ */
+void
+limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry)
+{
+ static tDot11fReAssocRequest frm;
+ tANI_U16 caps;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tANI_U32 nBytes, nPayload, nStatus;
+ tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled;
+ void *pPacket;
+ eHalStatus halstatus;
+#if defined WLAN_FEATURE_VOWIFI
+ tANI_U8 PowerCapsPopulated = FALSE;
+#endif
+ tANI_U16 ft_ies_length = 0;
+ tANI_U8 *pBody;
+ tANI_U16 nAddIELen;
+ tANI_U8 *pAddIE;
+#ifdef FEATURE_WLAN_CCX
+ tANI_U8 *wpsIe = NULL;
+#endif
+ tANI_U8 txFlag = 0;
+
+ if (NULL == psessionEntry)
+ {
+ return;
+ }
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (psessionEntry->is11Rconnection)
+ {
+ if (pMac->ft.ftSmeContext.reassoc_ft_ies_length == 0)
+ {
+ return;
+ }
+ }
+#endif
+
+ /* check this early to avoid unncessary operation */
+ if(NULL == psessionEntry->pLimReAssocReq)
+ {
+ return;
+ }
+ nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
+ pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
+ limLog( pMac, LOGE, FL("limSendReassocReqWithFTIEsMgmtFrame received in "
+ "state (%d).\n"), psessionEntry->limMlmState);
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ caps = pMlmReassocReq->capabilityInfo;
+ if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap))
+ ((tSirMacCapabilityInfo *) &caps)->qos = 0;
+#if defined(FEATURE_WLAN_WAPI)
+ /* CR: 262463 :
+ According to WAPI standard:
+ 7.3.1.4 Capability Information field
+ In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
+ Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
+ Reassociation management frames. */
+ if ( psessionEntry->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swapBitField16(caps, ( tANI_U16* )&frm.Capabilities );
+
+ frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
+
+ // Get the old bssid of the older AP.
+ palCopyMemory( pMac->hHdd, ( tANI_U8* )frm.CurrentAPAddress.mac,
+ pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, 6);
+
+ PopulateDot11fSSID2( pMac, &frm.SSID );
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates,psessionEntry);
+
+ fQosEnabled = ( psessionEntry->limQosEnabled) &&
+ SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps );
+
+ fWmeEnabled = ( psessionEntry->limWmeEnabled ) &&
+ LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps );
+
+ fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled &&
+ LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps );
+
+ if ( psessionEntry->lim11hEnable &&
+ psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE )
+ {
+#if defined WLAN_FEATURE_VOWIFI
+ PowerCapsPopulated = TRUE;
+
+ PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_REASSOC,psessionEntry);
+ PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_REASSOC,psessionEntry);
+#endif
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) )
+ {
+ if (PowerCapsPopulated == FALSE)
+ {
+ PowerCapsPopulated = TRUE;
+ PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry);
+ }
+ }
+#endif
+
+ if ( fQosEnabled &&
+ ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) ))
+ {
+ PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation );
+ }
+
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry );
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) )
+ {
+ PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry );
+ }
+#endif
+
+ // Ideally this should be enabled for 11r also. But 11r does
+ // not follow the usual norm of using the Opaque object
+ // for rsnie and fties. Instead we just add
+ // the rsnie and fties at the end of the pack routine for 11r.
+ // This should ideally! be fixed.
+#ifdef FEATURE_WLAN_CCX
+ //
+ // The join request *should* contain zero or one of the WPA and RSN
+ // IEs. The payload send along with the request is a
+ // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+
+ // typedef struct sSirRSNie
+ // {
+ // tANI_U16 length;
+ // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+ // } tSirRSNie, *tpSirRSNie;
+
+ // So, we should be able to make the following two calls harmlessly,
+ // since they do nothing if they don't find the given IE in the
+ // bytestream with which they're provided.
+
+ // The net effect of this will be to faithfully transmit whatever
+ // security IE is in the join request.
+
+ // *However*, if we're associating for the purpose of WPS
+ // enrollment, and we've been configured to indicate that by
+ // eliding the WPA or RSN IE, we just skip this:
+ if (!psessionEntry->is11Rconnection)
+ {
+ if( nAddIELen && pAddIE )
+ {
+ wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
+ }
+ if ( NULL == wpsIe )
+ {
+ PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ),
+ &frm.RSNOpaque );
+ PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ),
+ &frm.WPAOpaque );
+ }
+
+ if(psessionEntry->pLimReAssocReq->cckmIE.length)
+ {
+ PopulateDot11fCCXCckmOpaque( pMac, &( psessionEntry->pLimReAssocReq->cckmIE ),
+ &frm.CCXCckmOpaque );
+ }
+ }
+
+ // For CCX Associations fill the CCX IEs
+ if (psessionEntry->isCCXconnection)
+ {
+ PopulateDot11fCCXRadMgmtCap(&frm.CCXRadMgmtCap);
+ PopulateDot11fCCXVersion(&frm.CCXVersion);
+ }
+#endif
+
+ // include WME EDCA IE as well
+ if ( fWmeEnabled )
+ {
+ if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) )
+ {
+ PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation );
+ }
+
+ if ( fWsmEnabled &&
+ ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap )))
+ {
+ PopulateDot11fWMMCaps( &frm.WMMCaps );
+ }
+#ifdef FEATURE_WLAN_CCX
+ if (psessionEntry->isCCXconnection)
+ {
+ PopulateDot11fReAssocTspec(pMac, &frm, psessionEntry);
+
+ // Populate the TSRS IE if TSPEC is included in the reassoc request
+ if (psessionEntry->pLimReAssocReq->ccxTspecInfo.numTspecs)
+ {
+ tANI_U32 phyMode;
+ tSirMacCCXTSRSIE tsrsIE;
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ tsrsIE.tsid = 0;
+ if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A)
+ {
+ tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
+ }
+ else
+ {
+ tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
+ }
+ PopulateDot11TSRSIE(pMac,&tsrsIE, &frm.CCXTrafStrmRateSet, sizeof(tANI_U8));
+ }
+ }
+#endif
+ }
+
+ if ( psessionEntry->htCapabality &&
+ pMac->lim.htCapabilityPresentInBeacon)
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+ }
+
+ nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Re-Association Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fReAssocRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Re-Association Re "
+ "quest(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; ;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ limLog( pMac, LOGE, FL("FT IE Reassoc Req (%d).\n"),
+ pMac->ft.ftSmeContext.reassoc_ft_ies_length);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (psessionEntry->is11Rconnection)
+ {
+ ft_ies_length = pMac->ft.ftSmeContext.reassoc_ft_ies_length;
+ }
+#endif
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes+ft_ies_length, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As"
+ "sociation Request.\n"), nBytes );
+ goto end;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes + ft_ies_length);
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX
+ limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOGE);
+#endif
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_REASSOC_REQ,
+ psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Association Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ goto end;
+ }
+
+
+ // That done, pack the ReAssoc Request:
+ nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque"
+ "st (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ goto end;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a R"
+ "e-Association Request (0x%08x).\n") );
+ }
+
+ PELOG3(limLog( pMac, LOG3,
+ FL("*** Sending Re-Association Request length %d %d to \n"),
+ nBytes, nPayload );)
+ if( psessionEntry->assocReq != NULL )
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+ }
+
+ if( nAddIELen )
+ {
+ palCopyMemory( pMac->hHdd, pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+ pAddIE,
+ nAddIELen );
+ nPayload += nAddIELen;
+ }
+
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->assocReq, nPayload)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));)
+ }
+ else
+ {
+ //Store the Assoc request. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload);
+ psessionEntry->assocReqLen = nPayload;
+ }
+
+ if (psessionEntry->is11Rconnection)
+ {
+ {
+ int i = 0;
+
+ pBody = pFrame + nBytes;
+ for (i=0; i<ft_ies_length; i++)
+ {
+ *pBody = pMac->ft.ftSmeContext.reassoc_ft_ies[i];
+ pBody++;
+ }
+ }
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog(pMac, LOGE, FL("Re-assoc Req Frame is: "));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE,
+ (tANI_U8 *)pFrame,
+ (nBytes + ft_ies_length));)
+#endif
+
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (nBytes + ft_ies_length),
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Re-Association Request"
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ goto end;
+ }
+
+end:
+ // Free up buffer allocated for mlmAssocReq
+ palFreeMemory( pMac->hHdd, ( tANI_U8* ) pMlmReassocReq );
+ psessionEntry->pLimMlmReassocReq = NULL;
+
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+
+void
+limSendReassocReqMgmtFrame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry)
+{
+ static tDot11fReAssocRequest frm;
+ tANI_U16 caps;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tANI_U32 nBytes, nPayload, nStatus;
+ tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U16 nAddIELen;
+ tANI_U8 *pAddIE;
+ tANI_U8 *wpsIe = NULL;
+ tANI_U8 txFlag = 0;
+#if defined WLAN_FEATURE_VOWIFI
+ tANI_U8 PowerCapsPopulated = FALSE;
+#endif
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ /* check this early to avoid unncessary operation */
+ if(NULL == psessionEntry->pLimReAssocReq)
+ {
+ return;
+ }
+ nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
+ pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ caps = pMlmReassocReq->capabilityInfo;
+ if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap))
+ ((tSirMacCapabilityInfo *) &caps)->qos = 0;
+#if defined(FEATURE_WLAN_WAPI)
+ /* CR: 262463 :
+ According to WAPI standard:
+ 7.3.1.4 Capability Information field
+ In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
+ Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
+ Reassociation management frames. */
+ if ( psessionEntry->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swapBitField16(caps, ( tANI_U16* )&frm.Capabilities );
+
+ frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
+
+ palCopyMemory( pMac->hHdd, ( tANI_U8* )frm.CurrentAPAddress.mac,
+ ( tANI_U8* )psessionEntry->bssId, 6 );
+
+ PopulateDot11fSSID2( pMac, &frm.SSID );
+ PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates,psessionEntry);
+
+ fQosEnabled = ( psessionEntry->limQosEnabled ) &&
+ SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps );
+
+ fWmeEnabled = ( psessionEntry->limWmeEnabled ) &&
+ LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps );
+
+ fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled &&
+ LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps );
+
+
+ if ( psessionEntry->lim11hEnable &&
+ psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE )
+ {
+#if defined WLAN_FEATURE_VOWIFI
+ PowerCapsPopulated = TRUE;
+ PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_REASSOC,psessionEntry);
+ PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_REASSOC,psessionEntry);
+#endif
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) )
+ {
+ if (PowerCapsPopulated == FALSE)
+ {
+ PowerCapsPopulated = TRUE;
+ PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry);
+ }
+ }
+#endif
+
+ if ( fQosEnabled &&
+ ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) ))
+ {
+ PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation );
+ }
+
+ PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry );
+
+#if defined WLAN_FEATURE_VOWIFI
+ if( pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) )
+ {
+ PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry );
+ }
+#endif
+ // The join request *should* contain zero or one of the WPA and RSN
+ // IEs. The payload send along with the request is a
+ // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+
+ // typedef struct sSirRSNie
+ // {
+ // tANI_U16 length;
+ // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+ // } tSirRSNie, *tpSirRSNie;
+
+ // So, we should be able to make the following two calls harmlessly,
+ // since they do nothing if they don't find the given IE in the
+ // bytestream with which they're provided.
+
+ // The net effect of this will be to faithfully transmit whatever
+ // security IE is in the join request.
+
+ // *However*, if we're associating for the purpose of WPS
+ // enrollment, and we've been configured to indicate that by
+ // eliding the WPA or RSN IE, we just skip this:
+ if( nAddIELen && pAddIE )
+ {
+ wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
+ }
+ if ( NULL == wpsIe )
+ {
+ PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ),
+ &frm.RSNOpaque );
+ PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ),
+ &frm.WPAOpaque );
+#if defined(FEATURE_WLAN_WAPI)
+ PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ),
+ &frm.WAPIOpaque );
+#endif // defined(FEATURE_WLAN_WAPI)
+ }
+
+ // include WME EDCA IE as well
+ if ( fWmeEnabled )
+ {
+ if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) )
+ {
+ PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation );
+ }
+
+ if ( fWsmEnabled &&
+ ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap )))
+ {
+ PopulateDot11fWMMCaps( &frm.WMMCaps );
+ }
+ }
+
+ if ( psessionEntry->htCapabality &&
+ pMac->lim.htCapabilityPresentInBeacon)
+ {
+ PopulateDot11fHTCaps( pMac, &frm.HTCaps );
+ }
+
+ nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Re-Association Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fReAssocRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Re-Association Re "
+ "quest(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen;
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As"
+ "sociation Request.\n"), nBytes );
+ goto end;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_REASSOC_REQ,
+ psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for an Association Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ goto end;
+ }
+
+
+ // That done, pack the Probe Request:
+ nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque"
+ "st (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ goto end;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a R"
+ "e-Association Request (0x%08x).\n") );
+ }
+
+ PELOG1(limLog( pMac, LOG1, FL("*** Sending Re-Association Request length %d"
+ "to \n"),
+ nBytes );)
+
+ if( psessionEntry->assocReq != NULL )
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+ }
+
+ if( nAddIELen )
+ {
+ palCopyMemory( pMac->hHdd, pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+ pAddIE,
+ nAddIELen );
+ nPayload += nAddIELen;
+ }
+
+ if( (palAllocateMemory(pMac->hHdd, (void**)&psessionEntry->assocReq, nPayload)) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));)
+ }
+ else
+ {
+ //Store the Assoc request. This is sent to csr/hdd in join cnf response.
+ palCopyMemory(pMac->hHdd, psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload);
+ psessionEntry->assocReqLen = nPayload;
+ }
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload),
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Re-Association Request"
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ goto end;
+ }
+
+end:
+ // Free up buffer allocated for mlmAssocReq
+ palFreeMemory( pMac->hHdd, ( tANI_U8* ) pMlmReassocReq );
+ psessionEntry->pLimMlmReassocReq = NULL;
+
+} // limSendReassocReqMgmtFrame
+
+/**
+ * \brief Send an Authentication frame
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pAuthFrameBody Pointer to Authentication frame structure that need
+ * to be sent
+ *
+ * \param peerMacAddr MAC address of the peer entity to which Authentication
+ * frame is destined
+ *
+ * \param wepBit Indicates whether wep bit to be set in FC while sending
+ * Authentication frame3
+ *
+ *
+ * This function is called by limProcessMlmMessages(). Authentication frame
+ * is formatted and sent when this function is called.
+ *
+ *
+ */
+
+void
+limSendAuthMgmtFrame(tpAniSirGlobal pMac,
+ tpSirMacAuthFrameBody pAuthFrameBody,
+ tSirMacAddr peerMacAddr,
+ tANI_U8 wepBit,
+ tpPESession psessionEntry
+ )
+{
+ tANI_U8 *pFrame, *pBody;
+ tANI_U32 frameLen = 0, bodyLen = 0;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U16 i;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ if (wepBit == LIM_WEP_IN_FC)
+ {
+ /// Auth frame3 to be sent with encrypted framebody
+ /**
+ * Allocate buffer for Authenticaton frame of size equal
+ * to management frame header length plus 2 bytes each for
+ * auth algorithm number, transaction number, status code,
+ * 128 bytes for challenge text and 4 bytes each for
+ * IV & ICV.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) + LIM_ENCR_AUTH_BODY_LEN;
+
+ bodyLen = LIM_ENCR_AUTH_BODY_LEN;
+ } // if (wepBit == LIM_WEP_IN_FC)
+ else
+ {
+ switch (pAuthFrameBody->authTransactionSeqNumber)
+ {
+ case SIR_MAC_AUTH_FRAME_1:
+ /**
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus 2 bytes
+ * each for auth algorithm number, transaction number
+ * and status code.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH)
+ {
+ if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies)
+ {
+ frameLen += pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length;
+ limLog(pMac, LOG3, FL("Auth frame, FTIES length added=%d\n"),
+ pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length);
+ }
+ else
+ limLog(pMac, LOG3, FL("Auth frame, Does not contain FTIES!!!\n"));
+ }
+#endif
+ break;
+
+ case SIR_MAC_AUTH_FRAME_2:
+ if ((pAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
+ ((pAuthFrameBody->authAlgoNumber == eSIR_SHARED_KEY) &&
+ (pAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS)))
+ {
+ /**
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus
+ * 2 bytes each for auth algorithm number,
+ * transaction number and status code.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ }
+ else
+ {
+ // Shared Key algorithm with challenge text
+ // to be sent
+ /**
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus
+ * 2 bytes each for auth algorithm number,
+ * transaction number, status code and 128 bytes
+ * for challenge text.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) +
+ sizeof(tSirMacAuthFrame);
+ bodyLen = sizeof(tSirMacAuthFrameBody);
+ }
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_3:
+ /// Auth frame3 to be sent without encrypted framebody
+ /**
+ * Allocate buffer for Authenticaton frame of size equal
+ * to management frame header length plus 2 bytes each
+ * for auth algorithm number, transaction number and
+ * status code.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_4:
+ /**
+ * Allocate buffer for Authenticaton frame of size equal
+ * to management frame header length plus 2 bytes each
+ * for auth algorithm number, transaction number and
+ * status code.
+ */
+
+ frameLen = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+
+ break;
+ } // switch (pAuthFrameBody->authTransactionSeqNumber)
+ } // end if (wepBit == LIM_WEP_IN_FC)
+
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )frameLen, ( void** ) &pFrame, ( void** ) &pPacket );
+
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("call to bufAlloc failed for AUTH frame\n"));
+
+ return;
+ }
+
+ for (i = 0; i < frameLen; i++)
+ pFrame[i] = 0;
+
+ // Prepare BD
+ if (limPopulateMacHeader(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_AUTH, peerMacAddr,psessionEntry->selfMacAddr) != eSIR_SUCCESS)
+ {
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+ pMacHdr->fc.wep = wepBit;
+
+ // Prepare BSSId
+ if( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
+ {
+ palCopyMemory( pMac->hHdd,(tANI_U8 *) pMacHdr->bssId,
+ (tANI_U8 *) psessionEntry->bssId,
+ sizeof( tSirMacAddr ));
+ }
+
+ /// Prepare Authentication frame body
+ pBody = pFrame + sizeof(tSirMacMgmtHdr);
+
+ if (wepBit == LIM_WEP_IN_FC)
+ {
+ palCopyMemory( pMac->hHdd, pBody, (tANI_U8 *) pAuthFrameBody, bodyLen);
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Sending Auth seq# 3 status %d (%d) to\n"),
+ pAuthFrameBody->authStatusCode,
+ (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS));
+
+ limPrintMacAddr(pMac, pMacHdr->da, LOG1);)
+ }
+ else
+ {
+ *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authAlgoNumber);
+ pBody += sizeof(tANI_U16);
+ bodyLen -= sizeof(tANI_U16);
+
+ *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authTransactionSeqNumber);
+ pBody += sizeof(tANI_U16);
+ bodyLen -= sizeof(tANI_U16);
+
+ *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authStatusCode);
+ pBody += sizeof(tANI_U16);
+ bodyLen -= sizeof(tANI_U16);
+
+ palCopyMemory( pMac->hHdd, pBody, (tANI_U8 *) &pAuthFrameBody->type, bodyLen);
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if ((pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH) &&
+ (pAuthFrameBody->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1))
+ {
+
+ {
+ int i = 0;
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Auth1 Frame FTIE is: "));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE,
+ (tANI_U8 *)pBody,
+ (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length));)
+ }
+#endif
+ for (i=0; i<pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length; i++)
+ {
+ *pBody = pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[i];
+ pBody++;
+ }
+ }
+ }
+#endif
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Sending Auth seq# %d status %d (%d) to "),
+ pAuthFrameBody->authTransactionSeqNumber,
+ pAuthFrameBody->authStatusCode,
+ (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS));
+
+ limPrintMacAddr(pMac, pMacHdr->da, LOG1);)
+ }
+ PELOG2(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, pFrame, frameLen);)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ /// Queue Authentication frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) frameLen,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog(pMac, LOGE,
+ FL("*** Could not send Auth frame, retCode=%X ***\n"),
+ halstatus);
+
+ //Pkt will be freed up by the callback
+ }
+
+ return;
+} /*** end limSendAuthMgmtFrame() ***/
+
+/**
+ * \brief This function is called to send Disassociate frame.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in
+ * Disassociation frame
+ *
+ * \param peerMacAddr MAC address of the STA to which Disassociation frame is
+ * sent
+ *
+ *
+ */
+
+void
+limSendDisassocMgmtFrame(tpAniSirGlobal pMac,
+ tANI_U16 nReason,
+ tSirMacAddr peer,tpPESession psessionEntry)
+{
+ tDot11fDisassociation frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Reason.code = nReason;
+
+ nStatus = dot11fGetPackedDisassociationSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Disassociation (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fDisassociation );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Disassociation "
+ "(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
+ "association.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_DISASSOC, peer,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a Disassociation (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ // Prepare the BSSID
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ nStatus = dot11fPackDisassociation( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Disassociation (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a D"
+ "isassociation (0x%08x).\n") );
+ }
+
+ PELOG1(limLog( pMac, LOG1, FL("*** Sending Disassociation frame with rea"
+ "son %d to\n"), nReason );
+ limPrintMacAddr( pMac, pMacHdr->da, LOG1 );)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ // Queue Disassociation frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send Disassociation "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return;
+ }
+
+} // End limSendDisassocMgmtFrame.
+
+/**
+ * \brief This function is called to send a Deauthenticate frame
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in the
+ * Deauthenticate frame
+ *
+ * \param peeer address of the STA to which the frame is to be sent
+ *
+ *
+ */
+
+void
+limSendDeauthMgmtFrame(tpAniSirGlobal pMac,
+ tANI_U16 nReason,
+ tSirMacAddr peer,tpPESession psessionEntry)
+{
+ tDot11fDeAuth frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return;
+ }
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* ) &frm, sizeof( frm ) );
+
+ frm.Reason.code = nReason;
+
+ nStatus = dot11fGetPackedDeAuthSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a De-Authentication (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fDeAuth );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a De-Authentication "
+ "(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( tANI_U16 )nBytes, ( void** ) &pFrame,
+ ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
+ "Authentication.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_DEAUTH, peer,psessionEntry->selfMacAddr);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a De-Authentication (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ // Prepare the BSSID
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ nStatus = dot11fPackDeAuth( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a DeAuthentication (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+ ( void* ) pFrame, ( void* ) pPacket );
+ return;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a D"
+ "e-Authentication (0x%08x).\n") );
+ }
+
+ PELOG1(limLog( pMac, LOG1, FL("*** Sending De-Authentication frame with rea"
+ "son %d to\n"), nReason );
+ limPrintMacAddr( pMac, pMacHdr->da, LOG1 );)
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ // Queue Disassociation frame in high priority WQ
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, txFlag );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send De-Authentication "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return;
+ }
+
+} // End limSendDeauthMgmtFrame.
+
+
+#ifdef ANI_SUPPORT_11H
+/**
+ * \brief Send a Measurement Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendMeasReportFrame(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peer)
+{
+ tDot11fMeasurementReport frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus, nCfg;
+ void *pPacket;
+ eHalStatus halstatus;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
+ frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
+
+ switch ( pMeasReqFrame->measReqIE.measType )
+ {
+ case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+ nSirStatus =
+ PopulateDot11fMeasurementReport0( pMac, pMeasReqFrame,
+ &frm.MeasurementReport );
+ break;
+ case SIR_MAC_CCA_MEASUREMENT_TYPE:
+ nSirStatus =
+ PopulateDot11fMeasurementReport1( pMac, pMeasReqFrame,
+ &frm.MeasurementReport );
+ break;
+ case SIR_MAC_RPI_MEASUREMENT_TYPE:
+ nSirStatus =
+ PopulateDot11fMeasurementReport2( pMac, pMeasReqFrame,
+ &frm.MeasurementReport );
+ break;
+ default:
+ limLog( pMac, LOGE, FL("Unknown measurement type %d in limSen"
+ "dMeasReportFrame.\n"),
+ pMeasReqFrame->measReqIE.measType );
+ return eSIR_FAILURE;
+ }
+
+ if ( eSIR_SUCCESS != nSirStatus ) return eSIR_FAILURE;
+
+ nStatus = dot11fGetPackedMeasurementReportSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Measurement Report (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fMeasurementReport );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Measurement Rep"
+ "ort (0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
+ "Authentication.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a Measurement Report (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ nCfg = 6;
+ nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg );
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from"
+ " CFG (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ nStatus = dot11fPackMeasurementReport( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Measurement Report (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a M"
+ "easurement Report (0x%08x).\n") );
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, 0 );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send a Measurement Report "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ return eSIR_SUCCESS;
+
+} // End limSendMeasReportFrame.
+
+
+/**
+ * \brief Send a TPC Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which the frame should be sent
+ *
+ *
+ */
+
+void
+limSendTpcRequestFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peer)
+{
+ tDot11fTPCRequest frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus, nCfg;
+ void *pPacket;
+ eHalStatus halstatus;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
+ frm.DialogToken.token = 1;
+ frm.TPCRequest.present = 1;
+
+ nStatus = dot11fGetPackedTPCRequestSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a TPC Request (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fTPCRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a TPC Request (0x"
+ "%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Request.\n"), nBytes );
+ return;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a TPC Request (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ nCfg = 6;
+ nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg );
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from"
+ " CFG (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // just allocated...
+ }
+
+ nStatus = dot11fPackTPCRequest( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a T"
+ "PC Request (0x%08x).\n") );
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, 0 );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send a TPC Request "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return;
+ }
+
+} // End limSendTpcRequestFrame.
+
+
+/**
+ * \brief Send a TPC Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param pTpcReqFrame Pointer to the received TPC Request
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendTpcReportFrame(tpAniSirGlobal pMac,
+ tpSirMacTpcReqActionFrame pTpcReqFrame,
+ tSirMacAddr peer)
+{
+ tDot11fTPCReport frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus, nCfg;
+ void *pPacket;
+ eHalStatus halstatus;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
+ frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
+
+ // FramesToDo: On the Gen4_TVM branch, there was a comment:
+ // "misplaced this function, need to replace:
+ // txPower = halGetRateToPwrValue(pMac, staid,
+ // pMac->lim.gLimCurrentChannelId, 0);
+ frm.TPCReport.tx_power = 0;
+ frm.TPCReport.link_margin = 0;
+ frm.TPCReport.present = 1;
+
+ nStatus = dot11fGetPackedTPCReportSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a TPC Report (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fTPCReport );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a TPC Report (0x"
+ "%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Report.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a TPC Report (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ nCfg = 6;
+ nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg );
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from"
+ " CFG (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ nStatus = dot11fPackTPCReport( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a T"
+ "PC Report (0x%08x).\n") );
+ }
+
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, 0 );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send a TPC Report "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ return eSIR_SUCCESS;
+
+} // End limSendTpcReportFrame.
+#endif //ANI_SUPPORT_11H
+
+
+#ifdef ANI_PRODUCT_TYPE_AP
+/**
+ * \brief Send a Channel Switch Announcement
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which this frame will be sent
+ *
+ * \param nMode
+ *
+ * \param nNewChannel
+ *
+ * \param nCount
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendChannelSwitchMgmtFrame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ tANI_U8 nMode,
+ tANI_U8 nNewChannel,
+ tANI_U8 nCount)
+{
+ tDot11fChannelSwitch frm;
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus, nCfg;
+ void *pPacket;
+ eHalStatus halstatus;
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
+ frm.ChanSwitchAnn.switchMode = nMode;
+ frm.ChanSwitchAnn.newChannel = nNewChannel;
+ frm.ChanSwitchAnn.switchCount = nCount;
+ frm.ChanSwitchAnn.present = 1;
+
+ nStatus = dot11fGetPackedChannelSwitchSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Channel Switch (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fChannelSwitch );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Channel Switch (0x"
+ "%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Report.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a Channel Switch (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ nCfg = 6;
+ nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg );
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from"
+ " CFG (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to pack a Channel Switch (0x%08x).\n"),
+ nStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // allocated!
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while packing a C"
+ "hannel Switch (0x%08x).\n") );
+ }
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame, 0 );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send a Channel Switch "
+ "(%X)!\n"),
+ nSirStatus );
+ //Pkt will be freed up by the callback
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+} // End limSendChannelSwitchMgmtFrame.
+
+#endif // (ANI_PRODUCT_TYPE_AP)
+
+
+/**
+ * \brief Send an ADDBA Req Action Frame to peer
+ *
+ * \sa limSendAddBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pMlmAddBAReq A pointer to tLimMlmAddBAReq. This contains
+ * the necessary parameters reqd by PE send the ADDBA Req Action
+ * Frame to the peer
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac,
+ tpLimMlmAddBAReq pMlmAddBAReq ,tpPESession psessionEntry)
+{
+ tDot11fAddBAReq frmAddBAReq;
+ tANI_U8 *pAddBAReqBuffer = NULL;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 frameLen = 0, nStatus, nPayload;
+ tSirRetStatus statusCode;
+ eHalStatus halStatus;
+ void *pPacket;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) &frmAddBAReq, sizeof( frmAddBAReq ));
+
+ // Category - 3 (BA)
+ frmAddBAReq.Category.category = SIR_MAC_ACTION_BLKACK;
+
+ // Action - 0 (ADDBA Req)
+ frmAddBAReq.Action.action = SIR_MAC_BLKACK_ADD_REQ;
+
+ // FIXME - Dialog Token, generalize this...
+ frmAddBAReq.DialogToken.token = pMlmAddBAReq->baDialogToken;
+
+ // Fill the ADDBA Parameter Set
+ frmAddBAReq.AddBAParameterSet.tid = pMlmAddBAReq->baTID;
+ frmAddBAReq.AddBAParameterSet.policy = pMlmAddBAReq->baPolicy;
+ frmAddBAReq.AddBAParameterSet.bufferSize = pMlmAddBAReq->baBufferSize;
+
+ // BA timeout
+ // 0 - indicates no BA timeout
+ frmAddBAReq.BATimeout.timeout = pMlmAddBAReq->baTimeout;
+
+ // BA Starting Sequence Number
+ // Fragment number will always be zero
+ if (pMlmAddBAReq->baSSN < LIM_TX_FRAMES_THRESHOLD_ON_CHIP) {
+ pMlmAddBAReq->baSSN = LIM_TX_FRAMES_THRESHOLD_ON_CHIP;
+ }
+
+ frmAddBAReq.BAStartingSequenceControl.ssn =
+ pMlmAddBAReq->baSSN - LIM_TX_FRAMES_THRESHOLD_ON_CHIP;
+
+ nStatus = dot11fGetPackedAddBAReqSize( pMac, &frmAddBAReq, &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to calculate the packed size for "
+ "an ADDBA Request (0x%08x).\n"),
+ nStatus );
+
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAddBAReq );
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while calculating"
+ "the packed size for an ADDBA Req (0x%08x).\n"),
+ nStatus );
+ }
+
+ // Add the MGMT header to frame length
+ frameLen = nPayload + sizeof( tSirMacMgmtHdr );
+
+ // Need to allocate a buffer for ADDBA AF
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = palPktAlloc( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (tANI_U16) frameLen,
+ (void **) &pAddBAReqBuffer,
+ (void **) &pPacket )))
+ {
+ // Log error
+ limLog( pMac, LOGP,
+ FL("palPktAlloc FAILED! Length [%d], Status [%d]\n"),
+ frameLen,
+ halStatus );
+
+ statusCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnAfterError;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pAddBAReqBuffer, frameLen );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pAddBAReqBuffer,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ pMlmAddBAReq->peerMacAddr,psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+ pMacHdr = ( tpSirMacMgmtHdr ) pAddBAReqBuffer;
+
+ #if 0
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if( eSIR_SUCCESS != cfgGetStr( pMac,
+ WNI_CFG_BSSID,
+ (tANI_U8 *) pMacHdr->bssId,
+ &cfgLen ))
+ {
+ limLog( pMac, LOGP,
+ FL( "Failed to retrieve WNI_CFG_BSSID while"
+ "sending an ACTION Frame\n" ));
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ #endif//TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackAddBAReq( pMac,
+ &frmAddBAReq,
+ pAddBAReqBuffer + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an ADDBA Req (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing an ADDBA Req (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending an ADDBA REQ to \n" ));
+ limPrintMacAddr( pMac, pMlmAddBAReq->peerMacAddr, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) frameLen,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pAddBAReqBuffer, txFlag )))
+ {
+ limLog( pMac, LOGE,
+ FL( "halTxFrame FAILED! Status [%d]\n"),
+ halStatus );
+
+ // FIXME - Need to convert eHalStatus to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+
+ // Release buffer, if allocated
+ if( NULL != pAddBAReqBuffer )
+ palPktFree( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (void *) pAddBAReqBuffer,
+ (void *) pPacket );
+
+ return statusCode;
+}
+
+/**
+ * \brief Send an ADDBA Rsp Action Frame to peer
+ *
+ * \sa limSendAddBARsp
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pMlmAddBARsp A pointer to tLimMlmAddBARsp. This contains
+ * the necessary parameters reqd by PE send the ADDBA Rsp Action
+ * Frame to the peer
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac,
+ tpLimMlmAddBARsp pMlmAddBARsp,
+ tpPESession psessionEntry)
+{
+ tDot11fAddBARsp frmAddBARsp;
+ tANI_U8 *pAddBARspBuffer = NULL;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 frameLen = 0, nStatus, nPayload;
+ tSirRetStatus statusCode;
+ eHalStatus halStatus;
+ void *pPacket;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!\n"));)
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) &frmAddBARsp, sizeof( frmAddBARsp ));
+
+ // Category - 3 (BA)
+ frmAddBARsp.Category.category = SIR_MAC_ACTION_BLKACK;
+ // Action - 1 (ADDBA Rsp)
+ frmAddBARsp.Action.action = SIR_MAC_BLKACK_ADD_RSP;
+
+ // Should be same as the one we received in the ADDBA Req
+ frmAddBARsp.DialogToken.token = pMlmAddBARsp->baDialogToken;
+
+ // ADDBA Req status
+ frmAddBARsp.Status.status = pMlmAddBARsp->addBAResultCode;
+
+ // Fill the ADDBA Parameter Set as provided by caller
+ frmAddBARsp.AddBAParameterSet.tid = pMlmAddBARsp->baTID;
+ frmAddBARsp.AddBAParameterSet.policy = pMlmAddBARsp->baPolicy;
+ frmAddBARsp.AddBAParameterSet.bufferSize = pMlmAddBARsp->baBufferSize;
+
+ // BA timeout
+ // 0 - indicates no BA timeout
+ frmAddBARsp.BATimeout.timeout = pMlmAddBARsp->baTimeout;
+
+ nStatus = dot11fGetPackedAddBARspSize( pMac, &frmAddBARsp, &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to calculate the packed size for "
+ "an ADDBA Response (0x%08x).\n"),
+ nStatus );
+
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fAddBARsp );
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while calculating"
+ "the packed size for an ADDBA Rsp (0x%08x).\n"),
+ nStatus );
+ }
+
+ // Need to allocate a buffer for ADDBA AF
+ frameLen = nPayload + sizeof( tSirMacMgmtHdr );
+
+ // Allocate shared memory
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = palPktAlloc( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (tANI_U16) frameLen,
+ (void **) &pAddBARspBuffer,
+ (void **) &pPacket )))
+ {
+ // Log error
+ limLog( pMac, LOGP,
+ FL("palPktAlloc FAILED! Length [%d], Status [%d]\n"),
+ frameLen,
+ halStatus );
+
+ statusCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnAfterError;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pAddBARspBuffer, frameLen );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pAddBARspBuffer,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ pMlmAddBARsp->peerMacAddr,psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pAddBARspBuffer;
+
+ #if 0
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if( eSIR_SUCCESS != wlan_cfgGetStr( pMac,
+ WNI_CFG_BSSID,
+ (tANI_U8 *) pMacHdr->bssId,
+ &cfgLen ))
+ {
+ limLog( pMac, LOGP,
+ FL( "Failed to retrieve WNI_CFG_BSSID while"
+ "sending an ACTION Frame\n" ));
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ #endif // TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackAddBARsp( pMac,
+ &frmAddBARsp,
+ pAddBARspBuffer + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an ADDBA Rsp (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing an ADDBA Rsp (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending an ADDBA RSP to \n" ));
+ limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) frameLen,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pAddBARspBuffer, txFlag )))
+ {
+ limLog( pMac, LOGE,
+ FL( "halTxFrame FAILED! Status [%d]\n" ),
+ halStatus );
+
+ // FIXME - HAL error codes are different from PE error
+ // codes!! And, this routine is returning tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+ returnAfterError:
+
+ // Release buffer, if allocated
+ if( NULL != pAddBARspBuffer )
+ palPktFree( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (void *) pAddBARspBuffer,
+ (void *) pPacket );
+
+ return statusCode;
+}
+
+/**
+ * \brief Send a DELBA Indication Action Frame to peer
+ *
+ * \sa limSendDelBAInd
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param peerMacAddr MAC Address of peer
+ *
+ * \param reasonCode Reason for the DELBA notification
+ *
+ * \param pBAParameterSet The DELBA Parameter Set.
+ * This identifies the TID for which the BA session is
+ * being deleted.
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac,
+ tpLimMlmDelBAReq pMlmDelBAReq,tpPESession psessionEntry)
+{
+ tDot11fDelBAInd frmDelBAInd;
+ tANI_U8 *pDelBAIndBuffer = NULL;
+ //tANI_U32 val;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 frameLen = 0, nStatus, nPayload;
+ tSirRetStatus statusCode;
+ eHalStatus halStatus;
+ void *pPacket;
+ tANI_U8 txFlag = 0;
+
+ if(NULL == psessionEntry)
+ {
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) &frmDelBAInd, sizeof( frmDelBAInd ));
+
+ // Category - 3 (BA)
+ frmDelBAInd.Category.category = SIR_MAC_ACTION_BLKACK;
+ // Action - 2 (DELBA)
+ frmDelBAInd.Action.action = SIR_MAC_BLKACK_DEL;
+
+ // Fill the DELBA Parameter Set as provided by caller
+ frmDelBAInd.DelBAParameterSet.tid = pMlmDelBAReq->baTID;
+ frmDelBAInd.DelBAParameterSet.initiator = pMlmDelBAReq->baDirection;
+
+ // BA Starting Sequence Number
+ // Fragment number will always be zero
+ frmDelBAInd.Reason.code = pMlmDelBAReq->delBAReasonCode;
+
+ nStatus = dot11fGetPackedDelBAIndSize( pMac, &frmDelBAInd, &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "Failed to calculate the packed size for "
+ "an DELBA Indication (0x%08x).\n"),
+ nStatus );
+
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fDelBAInd );
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while calculating"
+ "the packed size for an DELBA Ind (0x%08x).\n"),
+ nStatus );
+ }
+
+ // Add the MGMT header to frame length
+ frameLen = nPayload + sizeof( tSirMacMgmtHdr );
+
+ // Allocate shared memory
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = palPktAlloc( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (tANI_U16) frameLen,
+ (void **) &pDelBAIndBuffer,
+ (void **) &pPacket )))
+ {
+ // Log error
+ limLog( pMac, LOGP,
+ FL("palPktAlloc FAILED! Length [%d], Status [%d]\n"),
+ frameLen,
+ halStatus );
+
+ statusCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnAfterError;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pDelBAIndBuffer, frameLen );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pDelBAIndBuffer,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ pMlmDelBAReq->peerMacAddr,psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+ pMacHdr = ( tpSirMacMgmtHdr ) pDelBAIndBuffer;
+
+ #if 0
+ cfgLen = SIR_MAC_ADDR_LENGTH;
+ if( eSIR_SUCCESS != cfgGetStr( pMac,
+ WNI_CFG_BSSID,
+ (tANI_U8 *) pMacHdr->bssId,
+ &cfgLen ))
+ {
+ limLog( pMac, LOGP,
+ FL( "Failed to retrieve WNI_CFG_BSSID while"
+ "sending an ACTION Frame\n" ));
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ #endif //TO SUPPORT BT-AMP
+ sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackDelBAInd( pMac,
+ &frmDelBAInd,
+ pDelBAIndBuffer + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an DELBA Ind (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing an DELBA Ind (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending a DELBA IND to \n" ));
+ limPrintMacAddr( pMac, pMlmDelBAReq->peerMacAddr, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halStatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) frameLen,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pDelBAIndBuffer, txFlag )))
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]\n" ), halStatus );)
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+ returnAfterError:
+
+ // Release buffer, if allocated
+ if( NULL != pDelBAIndBuffer )
+ palPktFree( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (void *) pDelBAIndBuffer,
+ (void *) pPacket );
+
+ return statusCode;
+}
+
+#if defined WLAN_FEATURE_VOWIFI
+
+/**
+ * \brief Send a Neighbor Report Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pNeighborReq Address of a tSirMacNeighborReportReq
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendNeighborReportRequestFrame(tpAniSirGlobal pMac,
+ tpSirMacNeighborReportReq pNeighborReq,
+ tSirMacAddr peer,
+ tpPESession psessionEntry
+ )
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tDot11fNeighborReportRequest frm;
+ tANI_U8 *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+ if ( psessionEntry == NULL )
+ {
+ limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Neighbor Report request action frame\n") );
+ return eSIR_FAILURE;
+ }
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_RRM;
+ frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
+ frm.DialogToken.token = pNeighborReq->dialogToken;
+
+
+ if( pNeighborReq->ssid_present )
+ {
+ PopulateDot11fSSID( pMac, &pNeighborReq->ssid, &frm.SSID );
+ }
+
+ nStatus = dot11fGetPackedNeighborReportRequestSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Neighbor Report Request(0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fNeighborReportRequest );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Neighbor Rep"
+ "ort Request(0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Neighbor "
+ "Report Request.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pFrame,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ peer, psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackNeighborReportRequest( pMac,
+ &frm,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an Neighbor Report Request (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing Neighbor Report Request (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending a Neighbor Report Request to \n" ));
+ limPrintMacAddr( pMac, peer, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halstatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pFrame, txFlag )))
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]\n" ), halstatus );)
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+
+ return statusCode;
+} // End limSendNeighborReportRequestFrame.
+
+/**
+ * \brief Send a Link Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pLinkReport Address of a tSirMacLinkReport
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendLinkReportActionFrame(tpAniSirGlobal pMac,
+ tpSirMacLinkReport pLinkReport,
+ tSirMacAddr peer,
+ tpPESession psessionEntry
+ )
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tDot11fLinkMeasurementReport frm;
+ tANI_U8 *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 txFlag = 0;
+
+
+ if ( psessionEntry == NULL )
+ {
+ limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Link Report action frame\n") );
+ return eSIR_FAILURE;
+ }
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_RRM;
+ frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
+ frm.DialogToken.token = pLinkReport->dialogToken;
+
+
+ //IEEE Std. 802.11 7.3.2.18. for the report element.
+ //Even though TPC report an IE, it is represented using fixed fields since it is positioned
+ //in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4
+ //and frame parser always expects IEs to come after all fixed fields. It is easier to handle
+ //such case this way than changing the frame parser.
+ frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
+ frm.TPCEleLen.TPCLen = 2;
+ frm.TxPower.txPower = pLinkReport->txPower;
+ frm.LinkMargin.linkMargin = 0;
+
+ frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
+ frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
+ frm.RCPI.rcpi = pLinkReport->rcpi;
+ frm.RSNI.rsni = pLinkReport->rsni;
+
+ nStatus = dot11fGetPackedLinkMeasurementReportSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Link Report (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fLinkMeasurementReport );
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Link Rep"
+ "ort (0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
+ "Report.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pFrame,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ peer, psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackLinkMeasurementReport( pMac,
+ &frm,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an Link Report (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing Link Report (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending a Link Report to \n" ));
+ limPrintMacAddr( pMac, peer, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halstatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pFrame, txFlag )))
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]\n" ), halstatus );)
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+
+ return statusCode;
+} // End limSendLinkReportActionFrame.
+
+/**
+ * \brief Send a Beacon Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param dialog_token dialog token to be used in the action frame.
+ *
+ * \param num_report number of reports in pRRMReport.
+ *
+ * \param pRRMReport Address of a tSirMacRadioMeasureReport.
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+limSendRadioMeasureReportActionFrame(tpAniSirGlobal pMac,
+ tANI_U8 dialog_token,
+ tANI_U8 num_report,
+ tpSirMacRadioMeasureReport pRRMReport,
+ tSirMacAddr peer,
+ tpPESession psessionEntry
+ )
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tDot11fRadioMeasurementReport frm;
+ tANI_U8 *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload, nStatus;
+ void *pPacket;
+ eHalStatus halstatus;
+ tANI_U8 i;
+ tANI_U8 txFlag = 0;
+
+ if ( psessionEntry == NULL )
+ {
+ limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Beacon Report action frame\n") );
+ return eSIR_FAILURE;
+ }
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+
+ frm.Category.category = SIR_MAC_ACTION_RRM;
+ frm.Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
+ frm.DialogToken.token = dialog_token;
+
+ frm.num_MeasurementReport = (num_report > RADIO_REPORTS_MAX_IN_A_FRAME ) ? RADIO_REPORTS_MAX_IN_A_FRAME : num_report;
+
+ for( i = 0 ; i < frm.num_MeasurementReport ; i++ )
+ {
+ frm.MeasurementReport[i].type = pRRMReport[i].type;
+ frm.MeasurementReport[i].token = pRRMReport[i].token;
+ frm.MeasurementReport[i].late = 0; //IEEE 802.11k section 7.3.22. (always zero in rrm)
+ switch( pRRMReport[i].type )
+ {
+ case SIR_MAC_RRM_BEACON_TYPE:
+ PopulateDot11fBeaconReport( pMac, &frm.MeasurementReport[i], &pRRMReport[i].report.beaconReport );
+ frm.MeasurementReport[i].incapable = pRRMReport[i].incapable;
+ frm.MeasurementReport[i].refused = pRRMReport[i].refused;
+ frm.MeasurementReport[i].present = 1;
+ break;
+ default:
+ frm.MeasurementReport[i].present = 1;
+ break;
+ }
+ }
+
+ nStatus = dot11fGetPackedRadioMeasurementReportSize( pMac, &frm, &nPayload );
+ if ( DOT11F_FAILED( nStatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Radio Measure Report (0x%08x).\n"),
+ nStatus );
+ // We'll fall back on the worst case scenario:
+ nPayload = sizeof( tDot11fLinkMeasurementReport );
+ return eSIR_FAILURE;
+ }
+ else if ( DOT11F_WARNED( nStatus ) )
+ {
+ limLog( pMac, LOGW, FL("There were warnings while calculating"
+ "the packed size for a Radio Measure Rep"
+ "ort (0x%08x).\n"), nStatus );
+ }
+
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Radio Measure "
+ "Report.\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Copy necessary info to BD
+ if( eSIR_SUCCESS !=
+ (statusCode = limPopulateMacHeader( pMac,
+ pFrame,
+ SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION,
+ peer, psessionEntry->selfMacAddr)))
+ goto returnAfterError;
+
+ // Update A3 with the BSSID
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId );
+
+ // Now, we're ready to "pack" the frames
+ nStatus = dot11fPackRadioMeasurementReport( pMac,
+ &frm,
+ pFrame + sizeof( tSirMacMgmtHdr ),
+ nPayload,
+ &nPayload );
+
+ if( DOT11F_FAILED( nStatus ))
+ {
+ limLog( pMac, LOGE,
+ FL( "Failed to pack an Radio Measure Report (0x%08x).\n" ),
+ nStatus );
+
+ // FIXME - Need to convert to tSirRetStatus
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ }
+ else if( DOT11F_WARNED( nStatus ))
+ {
+ limLog( pMac, LOGW,
+ FL( "There were warnings while packing Radio Measure Report (0x%08x).\n" ));
+ }
+
+ limLog( pMac, LOGW,
+ FL( "Sending a Radio Measure Report to \n" ));
+ limPrintMacAddr( pMac, peer, LOGW );
+
+ if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) ||
+ ( psessionEntry->pePersona == VOS_P2P_GO_MODE)
+#endif
+ )
+ {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if( eHAL_STATUS_SUCCESS !=
+ (halstatus = halTxFrame( pMac,
+ pPacket,
+ (tANI_U16) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete,
+ pFrame, txFlag )))
+ {
+ PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]\n" ), halstatus );)
+ statusCode = eSIR_FAILURE;
+ //Pkt will be freed up by the callback
+ return statusCode;
+ }
+ else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+
+ return statusCode;
+} // End limSendBeaconReportActionFrame.
+
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * \brief Send SA query response action frame to peer
+ *
+ * \sa limSendSaQueryResponseFrame
+ *
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param peer The Mac address of the AP to which this action frame is
+addressed
+ *
+ * \param transId Transaction identifier received in SA query request action
+frame
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+
+tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, tANI_U16 transId,
+tSirMacAddr peer,tpPESession psessionEntry)
+{
+
+ tDot11wSaQueryRsp frm; // SA query reponse action frame
+ tANI_U8 *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ tANI_U32 nBytes, nPayload;
+ void *pPacket;
+ eHalStatus halstatus;
+ // Local variables used to dump prepared SA query response frame
+ tANI_U8 *pDump;
+ tANI_U16 dumpCount;
+ tANI_U8 txFlag = 0;
+ //tANI_U16 nBytes
+
+ palZeroMemory( pMac->hHdd, ( tANI_U8* )&frm, sizeof( frm ) );
+ frm.category = SIR_MAC_ACTION_SA_QUERY;
+ /*11w action fiedl is :
+ action: 0 --> SA query request action frame
+ action: 1 --> SA query response action frame */
+ frm.action = 1;
+ /*11w Draft9.0 SA query response transId is same as
+ SA query request transId*/
+ frm.transId = transId;
+
+ nPayload = sizeof(tDot11wSaQueryRsp);
+ nBytes = nPayload + sizeof( tSirMacMgmtHdr );
+ halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, nBytes, ( void** ) &pFrame, ( void** ) &pPacket );
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a SA query response"
+ " action frame\n"), nBytes );
+ return eSIR_FAILURE;
+ }
+
+ // Paranoia:
+ palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+ // Next, we fill out the buffer descriptor:
+ nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer,psessionEntry->selfMacAddr );
+ if ( eSIR_SUCCESS != nSirStatus )
+ {
+ limLog( pMac, LOGE, FL("Failed to populate the buffer descrip"
+ "tor for a TPC Report (%d).\n"),
+ nSirStatus );
+ palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket );
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
+
+ // Pack 11w SA query response frame
+ DOT11F_MEMCPY(pMac, (tANI_U8 *)(pFrame + sizeof(tSirMacMgmtHdr)),(tANI_U8 *)&frm, nPayload);
+ pDump = (tANI_U8 *) pFrame;
+
+ halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+ HAL_TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+ limTxComplete, pFrame,txFlag);
+ if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+ {
+ limLog( pMac, LOGE, FL("Failed to send a SA Query resp frame "
+ "(%X)!\n"),halstatus );
+ //Pkt will be freed up by the callback
+ return eSIR_FAILURE; // just allocated...
+ }
+
+ return eSIR_SUCCESS;
+}
+#endif
diff --git a/CORE/MAC/src/pe/lim/limSendMessages.c b/CORE/MAC/src/pe/lim/limSendMessages.c
new file mode 100644
index 0000000..3b95f1d
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSendMessages.c
@@ -0,0 +1,747 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * limSendMessages.c: Provides functions to send messages or Indications to HAL.
+ * Author: Sunit Bhatia
+ * Date: 09/21/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#include "limSendMessages.h"
+#include "cfgApi.h"
+#include "limTrace.h"
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+#include "vos_diag_core_log.h"
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+/* When beacon filtering is enabled, firmware will
+ * analyze the selected beacons received during BMPS,
+ * and monitor any changes in the IEs as listed below.
+ * The format of the table is:
+ * - EID
+ * - Check for IE presence
+ * - Byte offset
+ * - Byte value
+ * - Bit Mask
+ * - Byte refrence
+ */
+static tBeaconFilterIe beaconFilterTable[] = {
+ {SIR_MAC_DS_PARAM_SET_EID, 0, {0, 0, DS_PARAM_CHANNEL_MASK, 0}},
+ {SIR_MAC_ERP_INFO_EID, 0, {0, 0, ERP_FILTER_MASK, 0}},
+ {SIR_MAC_EDCA_PARAM_SET_EID, 0, {0, 0, EDCA_FILTER_MASK, 0}},
+ {SIR_MAC_QOS_CAPABILITY_EID, 0, {0, 0, QOS_FILTER_MASK, 0}},
+ {SIR_MAC_CHNL_SWITCH_ANN_EID, 1, {0, 0, 0, 0}},
+ {SIR_MAC_QUIET_EID, 1, {0, 0, 0, 0}},
+ {SIR_MAC_HT_INFO_EID, 0, {0, 0, HT_BYTE0_FILTER_MASK, 0}},
+ {SIR_MAC_HT_INFO_EID, 0, {2, 0, HT_BYTE2_FILTER_MASK, 0}},
+ {SIR_MAC_HT_INFO_EID, 0, {5, 0, HT_BYTE5_FILTER_MASK, 0}}
+#if defined WLAN_FEATURE_VOWIFI
+ ,{SIR_MAC_PWR_CONSTRAINT_EID, 0, {0, 0, 0, 0}}
+#endif
+};
+
+
+/**
+ * limSendCFParams()
+ *
+ *FUNCTION:
+ * This function is called to send CFP Parameters to WDA, when they are changed.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param bssIdx Bss Index of the BSS to which STA is associated.
+ * @param cfpCount CFP Count, if that is changed.
+ * @param cfpPeriod CFP Period if that is changed.
+ *
+ * @return success if message send is ok, else false.
+ */
+
+tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod)
+{
+ tpUpdateCFParams pCFParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pCFParams,
+ sizeof( tUpdateCFParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during Update CF Params\n" ));
+
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pCFParams, sizeof(tUpdateCFParams));
+
+ pCFParams->cfpCount = cfpCount;
+ pCFParams->cfpPeriod = cfpPeriod;
+ pCFParams->bssIdx = bssIdx;
+
+
+ msgQ.type = WDA_UPDATE_CF_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pCFParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG3,
+ FL( "Sending WDA_UPDATE_CF_IND..." ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ palFreeMemory(pMac->hHdd, pCFParams);
+ limLog( pMac, LOGP,
+ FL("Posting WDA_UPDATE_CF_IND to WDA failed, reason=%X\n"),
+ retCode );
+ }
+
+returnFailure:
+ return retCode;
+}
+
+
+
+/**
+ * limSendBeaconParams()
+ *
+ *FUNCTION:
+ * This function is called to send beacnon interval, short preamble or other
+ * parameters to WDA, which are changed and indication is received in beacon.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param tpUpdateBeaconParams pointer to the structure,
+ which contains the beacon parameters which are changed.
+ *
+ * @return success if message send is ok, else false.
+ */
+
+tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pUpdatedBcnParams,
+ tpPESession psessionEntry )
+{
+ tpUpdateBeaconParams pBcnParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pBcnParams, sizeof(*pBcnParams)))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during Update Beacon Params\n" ));
+
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBcnParams, pUpdatedBcnParams, sizeof(*pBcnParams));
+
+ msgQ.type = WDA_UPDATE_BEACON_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pBcnParams;
+ msgQ.bodyval = 0;
+
+ PELOG3(limLog( pMac, LOG3,
+ FL( "Sending WDA_UPDATE_BEACON_IND, paramChangeBitmap in hex = %x" ),
+ pUpdatedBcnParams->paramChangeBitmap);)
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ palFreeMemory(pMac->hHdd, pBcnParams);
+ limLog( pMac, LOGP,
+ FL("Posting WDA_UPDATE_BEACON_IND to WDA failed, reason=%X\n"),
+ retCode );
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ limSendBeaconInd(pMac, psessionEntry);
+#endif
+
+ return retCode;
+}
+
+
+/**
+ * limSendSwitchChnlParams()
+ *
+ *FUNCTION:
+ * This function is called to send Channel Switch Indication to WDA
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param chnlNumber New Channel Number to be switched to.
+ * @param secondaryChnlOffset an enum for secondary channel offset.
+ * @param localPowerConstraint 11h local power constraint value
+ *
+ * @return success if message send is ok, else false.
+ */
+
+#if !defined WLAN_FEATURE_VOWIFI
+tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
+ tANI_U8 chnlNumber,
+ tSirMacHTSecondaryChannelOffset secondaryChnlOffset,
+ tANI_U8 localPwrConstraint, tANI_U8 peSessionId)
+#else
+tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac,
+ tANI_U8 chnlNumber,
+ tSirMacHTSecondaryChannelOffset secondaryChnlOffset,
+ tPowerdBm maxTxPower, tANI_U8 peSessionId)
+
+#endif
+{
+ tpSwitchChannelParams pChnlParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ tpPESession pSessionEntry;
+
+ if((pSessionEntry = peFindSessionBySessionId(pMac , peSessionId)) == NULL)
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to get Session for session Id %d\n" ), peSessionId);
+ return eSIR_FAILURE;
+
+ }
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pChnlParams,
+ sizeof( tSwitchChannelParams )))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during Switch Channel Params\n" ));
+
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pChnlParams, sizeof(tSwitchChannelParams));
+
+ pChnlParams->secondaryChannelOffset = secondaryChnlOffset;
+ pChnlParams->channelNumber= chnlNumber;
+#if defined WLAN_FEATURE_VOWIFI
+ pChnlParams->maxTxPower = maxTxPower;
+ palCopyMemory( pMac->hHdd, pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) );
+#else
+ pChnlParams->localPowerConstraint = localPwrConstraint;
+#endif
+
+ palCopyMemory( pMac->hHdd, pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) );
+ pChnlParams->peSessionId = peSessionId;
+
+ //we need to defer the message until we get the response back from WDA.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WDA_CHNL_SWITCH_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pChnlParams;
+ msgQ.bodyval = 0;
+
+#if !defined WLAN_FEATURE_VOWIFI
+ PELOG3(limLog( pMac, LOG3,
+ FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, maxTxPower - %d"),
+ pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->maxTxPower);)
+#else
+ PELOG3(limLog( pMac, LOG3,
+ FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, ChannelNumber - %d, LocalPowerConstraint - %d"),
+ pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, pChnlParams->localPowerConstraint);)
+#endif
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ palFreeMemory(pMac->hHdd, pChnlParams);
+ limLog( pMac, LOGP,
+ FL("Posting WDA_CHNL_SWITCH_REQ to WDA failed, reason=%X\n"),
+ retCode );
+ }
+
+returnFailure:
+ return retCode;
+}
+
+
+/**
+ * limSendEdcaParams()
+ *
+ *FUNCTION:
+ * This function is called to send dynamically changing EDCA Parameters to WDA.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param tpUpdatedEdcaParams pointer to the structure which contains
+ * dynamically changing EDCA parameters.
+ * @param highPerformance If the peer is Airgo (taurus) then switch to highPerformance is true.
+ *
+ * @return success if message send is ok, else false.
+ */
+
+tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance)
+{
+ tEdcaParams *pEdcaParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pEdcaParams,
+ sizeof(tEdcaParams)))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory during Update EDCA Params\n" ));
+
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+
+ pEdcaParams->bssIdx = bssIdx;
+ pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE];
+ pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK];
+ pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI];
+ pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO];
+ pEdcaParams->highPerformance = highPerformance;
+
+ msgQ.type = WDA_UPDATE_EDCA_PROFILE_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pEdcaParams;
+ msgQ.bodyval = 0;
+
+ {
+ tANI_U8 i;
+ PELOG1(limLog( pMac, LOG1,FL("Sending WDA_UPDATE_EDCA_PROFILE_IND with EDCA Parameters:" ));)
+ for(i=0; i<MAX_NUM_AC; i++)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("AC[%d]: AIFSN %d, ACM %d, CWmin %d, CWmax %d, TxOp %d \n"),
+ i, pUpdatedEdcaParams[i].aci.aifsn, pUpdatedEdcaParams[i].aci.acm,
+ pUpdatedEdcaParams[i].cw.min, pUpdatedEdcaParams[i].cw.max, pUpdatedEdcaParams[i].txoplimit);)
+ }
+ }
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ palFreeMemory(pMac->hHdd, pEdcaParams);
+ limLog( pMac, LOGP,
+ FL("Posting WDA_UPDATE_EDCA_PROFILE_IND to WDA failed, reason=%X\n"),
+ retCode );
+ }
+
+ return retCode;
+}
+
+
+/**
+ * limSetActiveEdcaParams()
+ *
+ * FUNCTION:
+ * This function is called to set the most up-to-date EDCA parameters
+ * given the default local EDCA parameters. The rules are as following:
+ * - If ACM bit is set for all ACs, then downgrade everything to Best Effort.
+ * - If ACM is not set for any AC, then PE will use the default EDCA
+ * parameters as advertised by AP.
+ * - If ACM is set in any of the ACs, PE will use the EDCA parameters
+ * from the next best AC for which ACM is not enabled.
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param plocalEdcaParams pointer to the local EDCA parameters
+ * @ param psessionEntry point to the session entry
+ * @return none
+ */
+ void limSetActiveEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *plocalEdcaParams, tpPESession psessionEntry)
+{
+ tANI_U8 ac, newAc, i;
+ tANI_U8 acAdmitted;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ vos_log_qos_edca_pkt_type *log_ptr = NULL;
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ // Initialize gLimEdcaParamsActive[] to be same as localEdcaParams
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE] = plocalEdcaParams[EDCA_AC_BE];
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK] = plocalEdcaParams[EDCA_AC_BK];
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI] = plocalEdcaParams[EDCA_AC_VI];
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO] = plocalEdcaParams[EDCA_AC_VO];
+
+ /* An AC requires downgrade if the ACM bit is set, and the AC has not
+ * yet been admitted in uplink or bi-directions.
+ * If an AC requires downgrade, it will downgrade to the next beset AC
+ * for which ACM is not enabled.
+ *
+ * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence
+ * start the for loop with AC_BK.
+ * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then
+ * traverse thru the AC list. If we do find the next best AC which is
+ * better than AC_BE, then use that one. For example, if ACM bits are set
+ * such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0
+ * then all AC will be downgraded to AC_BE.
+ */
+ limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x \n"), pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] );
+ limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x \n"), pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] );
+ for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++)
+ {
+ acAdmitted = ( (pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & (1 << ac)) >> ac );
+ limLog(pMac, LOG1, FL("For AC[%d]: acm=%d, acAdmit=%d \n"), ac, plocalEdcaParams[ac].aci.acm, acAdmitted);
+
+ if ( (plocalEdcaParams[ac].aci.acm == 1) && (acAdmitted == 0) )
+ {
+ limLog(pMac, LOG1, FL("We need to downgrade AC %d!! "), ac);
+ newAc = EDCA_AC_BE;
+ for (i=ac-1; i>0; i--)
+ {
+ if (plocalEdcaParams[i].aci.acm == 0)
+ {
+ newAc = i;
+ break;
+ }
+ }
+ limLog(pMac, LOGW, FL("Downgrading AC %d ---> AC %d "), ac, newAc);
+ psessionEntry->gLimEdcaParamsActive[ac] = plocalEdcaParams[newAc];
+ }
+ }
+//log: LOG_WLAN_QOS_EDCA_C
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C);
+ if(log_ptr)
+ {
+ log_ptr->aci_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].aci.aci;
+ log_ptr->cw_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.max << 4 |
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.min;
+ log_ptr->txoplimit_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].txoplimit;
+ log_ptr->aci_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].aci.aci;
+ log_ptr->cw_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.max << 4 |
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.min;
+ log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].txoplimit;
+ log_ptr->aci_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].aci.aci;
+ log_ptr->cw_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.max << 4 |
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.min;
+ log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].txoplimit;
+ log_ptr->aci_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].aci.aci;
+ log_ptr->cw_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.max << 4 |
+ psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.min;
+ log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].txoplimit;
+ }
+ WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ return;
+ }
+
+
+/** ---------------------------------------------------------
+\fn limSetLinkState
+\brief LIM sends a message to WDA to set the link state
+\param tpAniSirGlobal pMac
+\param tSirLinkState state
+\return None
+ -----------------------------------------------------------*/
+ //Original code with out anu's change
+#if 0
+tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId)
+{
+ tSirMsgQ msg;
+ tSirRetStatus retCode;
+
+ msg.type = WDA_SET_LINK_STATE;
+ msg.bodyval = (tANI_U32) state;
+ msg.bodyptr = NULL;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+ retCode = wdaPostCtrlMsg(pMac, &msg);
+ if (retCode != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x \n"), retCode);
+
+ return retCode;
+}
+#endif //0
+
+tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId,
+ tSirMacAddr selfMacAddr, tpSetLinkStateCallback callback,
+ void *callbackArg)
+{
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ tpLinkStateParams pLinkStateParams = NULL;
+
+ // Allocate memory.
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pLinkStateParams,
+ sizeof(tLinkStateParams)))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory while sending Set Link State\n" ));
+
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ return retCode;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams));
+
+ pLinkStateParams->state = state;
+ pLinkStateParams->callback = callback;
+ pLinkStateParams->callbackArg = callbackArg;
+
+
+ /* Copy Mac address */
+ sirCopyMacAddr(pLinkStateParams->bssid,bssId);
+ sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr);
+
+
+ msgQ.type = WDA_SET_LINK_STATE;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pLinkStateParams;
+ msgQ.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ);
+ if (retCode != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac, (void*)pLinkStateParams);
+ limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x \n"), retCode);
+ }
+
+ return retCode;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState
+state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ tpLinkStateParams pLinkStateParams = NULL;
+
+ // Allocate memory.
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pLinkStateParams,
+ sizeof(tLinkStateParams)))
+ {
+ limLog( pMac, LOGP,
+ FL( "Unable to PAL allocate memory while sending Set Link State\n" ));
+
+ retCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ return retCode;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams));
+
+ pLinkStateParams->state = state;
+
+ /* Copy Mac address */
+ sirCopyMacAddr(pLinkStateParams->bssid,bssId);
+ sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr);
+ pLinkStateParams->ft = 1;
+ pLinkStateParams->session = psessionEntry;
+
+
+ msgQ.type = WDA_SET_LINK_STATE;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pLinkStateParams;
+ msgQ.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+
+ retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ);
+ if (retCode != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac, (void*)pLinkStateParams);
+ limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x \n"), retCode);
+ }
+
+ return retCode;
+}
+#endif
+
+
+
+/** ---------------------------------------------------------
+\fn limSendSetTxPowerReq
+\brief LIM sends a WDA_SET_TX_POWER_REQ message to WDA
+\param tpAniSirGlobal pMac
+\param tpSirSetTxPowerReq request message
+\return None
+ -----------------------------------------------------------*/
+tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tpSirSetTxPowerReq pTxPowerReq)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if (NULL == pTxPowerReq)
+ return retCode;
+
+ msgQ.type = WDA_SET_TX_POWER_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pTxPowerReq;
+ msgQ.bodyval = 0;
+
+ PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_SET_TX_POWER_REQ to WDA"));)
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGP, FL("Posting WDA_SET_TX_POWER_REQ to WDA failed, reason=%X"), retCode );
+ if (NULL != pTxPowerReq)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pTxPowerReq);
+ }
+ return retCode;
+ }
+ return retCode;
+}
+
+/** ---------------------------------------------------------
+\fn limSendGetTxPowerReq
+\brief LIM sends a WDA_GET_TX_POWER_REQ message to WDA
+\param tpAniSirGlobal pMac
+\param tpSirGetTxPowerReq request message
+\return None
+ -----------------------------------------------------------*/
+tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if (NULL == pTxPowerReq)
+ return retCode;
+
+ msgQ.type = WDA_GET_TX_POWER_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pTxPowerReq;
+ msgQ.bodyval = 0;
+
+ PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_GET_TX_POWER_REQ to WDA"));)
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ limLog( pMac, LOGP, FL("Posting WDA_GET_TX_POWER_REQ to WDA failed, reason=%X"), retCode );
+ if (NULL != pTxPowerReq)
+ {
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pTxPowerReq);
+ }
+ return retCode;
+ }
+ return retCode;
+}
+
+/** ---------------------------------------------------------
+\fn limSendBeaconFilterInfo
+\brief LIM sends beacon filtering info to WDA
+\param tpAniSirGlobal pMac
+\return None
+ -----------------------------------------------------------*/
+tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac)
+{
+ tpBeaconFilterMsg pBeaconFilterMsg = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ tANI_U8 *ptr;
+ tANI_U32 i;
+ tANI_U32 msgSize;
+ tpBeaconFilterIe pIe;
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH get the sessionEntry from the caller
+
+
+ msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pBeaconFilterMsg, msgSize) )
+ {
+ limLog( pMac, LOGP, FL("Fail to allocate memory for beaconFiilterMsg \n"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) pBeaconFilterMsg, msgSize);
+
+ // Fill in capability Info and mask
+ //TBD-RAJESH get the BSS capability from session.
+ //Don't send this message if no active Infra session is found.
+ pBeaconFilterMsg->capabilityInfo = psessionEntry->limCurrentBssCaps;
+ pBeaconFilterMsg->capabilityMask = CAPABILITY_FILTER_MASK;
+
+ pBeaconFilterMsg->beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval;
+
+ // Fill in number of IEs in beaconFilterTable
+ pBeaconFilterMsg->ieNum = (tANI_U16) (sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe));
+
+ //Fill message with info contained in the beaconFilterTable
+ ptr = (tANI_U8 *)pBeaconFilterMsg + sizeof(tBeaconFilterMsg);
+ for(i=0; i < (pBeaconFilterMsg->ieNum); i++)
+ {
+ pIe = (tpBeaconFilterIe) ptr;
+ pIe->elementId = beaconFilterTable[i].elementId;
+ pIe->checkIePresence = beaconFilterTable[i].checkIePresence;
+ pIe->byte.offset = beaconFilterTable[i].byte.offset;
+ pIe->byte.value = beaconFilterTable[i].byte.value;
+ pIe->byte.bitMask = beaconFilterTable[i].byte.bitMask;
+ pIe->byte.ref = beaconFilterTable[i].byte.ref;
+ ptr += sizeof(tBeaconFilterIe);
+ }
+
+ msgQ.type = WDA_BEACON_FILTER_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pBeaconFilterMsg;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG3, FL( "Sending WDA_BEACON_FILTER_IND..." ));
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ {
+ palFreeMemory(pMac->hHdd, pBeaconFilterMsg);
+ limLog( pMac, LOGP,
+ FL("Posting WDA_BEACON_FILTER_IND to WDA failed, reason=%X\n"),
+ retCode );
+ return retCode;
+ }
+
+ return retCode;
+}
+
diff --git a/CORE/MAC/src/pe/lim/limSendMessages.h b/CORE/MAC/src/pe/lim/limSendMessages.h
new file mode 100644
index 0000000..3871659
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSendMessages.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * limSendMessages.h: Provides functions to send messages or Indications to HAL.
+ * Author: Sunit Bhatia
+ * Date: 09/21/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_MESSAGES_H
+#define __LIM_SEND_MESSAGES_H
+
+
+
+#include "aniGlobal.h"
+#include "limTypes.h"
+#include "halMsgApi.h"
+#include "sirParams.h"
+
+tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod);
+tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pUpdatedBcnParams,
+ tpPESession psessionEntry );
+
+//tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, tpUpdateBeaconParams pUpdatedBcnParams);
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber,
+ tSirMacHTSecondaryChannelOffset secondaryChnlOffset,
+ tPowerdBm maxTxPower,tANI_U8 peSessionId);
+#else
+tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber,
+ tSirMacHTSecondaryChannelOffset secondaryChnlOffset,
+ tANI_U8 localPwrConstraint,tANI_U8 peSessionId);
+#endif
+tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance);
+tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state, tSirMacAddr bssId,
+ tSirMacAddr selfMac, tpSetLinkStateCallback callback,
+ void *callbackArg);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState
+state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry);
+#endif
+tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tpSirSetTxPowerReq pTxPowerReq);
+tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq);
+
+void limSetActiveEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *plocalEdcaParams, tpPESession psessionEntry);
+
+#define CAPABILITY_FILTER_MASK 0x73CF
+#define ERP_FILTER_MASK 0xF8
+#define EDCA_FILTER_MASK 0xF0
+#define QOS_FILTER_MASK 0xF0
+#define HT_BYTE0_FILTER_MASK 0x0
+#define HT_BYTE2_FILTER_MASK 0xEB
+#define HT_BYTE5_FILTER_MASK 0xFD
+#define DS_PARAM_CHANNEL_MASK 0x0
+
+
+tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac);
+
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
new file mode 100644
index 0000000..a77d8ff
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -0,0 +1,2443 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSendSmeRspMessages.cc contains the functions
+ * for sending SME response/notification messages to applications
+ * above MAC software.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "vos_types.h"
+#include "wniApi.h"
+#include "sirCommon.h"
+#include "aniGlobal.h"
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "sysDef.h"
+#include "cfgApi.h"
+
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halDataStruct.h"
+#include "halCommonApi.h"
+#endif
+
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+#include "limSendSmeRspMessages.h"
+#include "limIbssPeerMgmt.h"
+#include "limSessionUtils.h"
+
+
+/**
+ * limSendSmeRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() to send
+ * eWNI_SME_START_RSP, eWNI_SME_MEASUREMENT_RSP, eWNI_SME_STOP_BSS_RSP
+ * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
+ * Software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates message type
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+limSendSmeRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
+ tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeRsp *pSirSmeRsp;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Sending message %s with reasonCode %s\n"),
+ limMsgStr(msgType), limResultCodeStr(resultCode));)
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeRsp, sizeof(tSirSmeRsp)))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_*_RSP\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->messageType, msgType);
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->length, sizeof(tSirSmeRsp));
+#else
+ pSirSmeRsp->messageType = msgType;
+ pSirSmeRsp->length = sizeof(tSirSmeRsp);
+#endif
+ pSirSmeRsp->statusCode = resultCode;
+
+ /* Update SME session Id and Transaction Id */
+ pSirSmeRsp->sessionId = smesessionId;
+ pSirSmeRsp->transactionId = smetransactionId;
+
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pSirSmeRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ {
+ tpPESession psessionEntry = peGetValidPowerSaveSession(pMac);
+ switch(msgType)
+ {
+ case eWNI_PMC_ENTER_BMPS_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_EXIT_BMPS_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_ENTER_IMPS_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_EXIT_IMPS_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_ENTER_UAPSD_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_EXIT_UAPSD_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_SME_SWITCH_CHL_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT, NULL, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_SME_STOP_BSS_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, NULL, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_ENTER_WOWL_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ case eWNI_PMC_EXIT_WOWL_RSP:
+ limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ break;
+ }
+ }
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+} /*** end limSendSmeRsp() ***/
+
+
+/**
+ * limSendSmeJoinReassocRspAfterResume()
+ *
+ *FUNCTION:
+ * This function is called to send Join/Reassoc rsp
+ * message to SME after the resume link.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param status Resume link status
+ * @param ctx context passed while calling resmune link.
+ * (join response to be sent)
+ *
+ * @return None
+ */
+static void limSendSmeJoinReassocRspAfterResume( tpAniSirGlobal pMac,
+ eHalStatus status, tANI_U32 *ctx)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeJoinRsp pSirSmeJoinRsp = (tpSirSmeJoinRsp) ctx;
+
+ mmhMsg.type = pSirSmeJoinRsp->messageType;
+ mmhMsg.bodyptr = pSirSmeJoinRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+
+/**
+ * limSendSmeJoinReassocRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() to send
+ * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications
+ * above MAC Software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates message type
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+limSendSmeJoinReassocRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
+ tSirResultCodes resultCode, tANI_U16 protStatusCode,
+ tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId)
+{
+ tpSirSmeJoinRsp pSirSmeJoinRsp;
+ tANI_U32 rspLen;
+ tpDphHashNode pStaDs = NULL;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ if (msgType == eWNI_SME_REASSOC_RSP)
+ limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+ else
+ limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Sending message %s with reasonCode %s\n"),
+ limMsgStr(msgType), limResultCodeStr(resultCode));)
+
+ if(psessionEntry == NULL)
+ {
+
+ rspLen = sizeof(tSirSmeJoinRsp);
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeJoinRsp, rspLen))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for JOIN/REASSOC_RSP\n"));
+ return;
+ }
+
+ palZeroMemory(pMac, (tANI_U8*)pSirSmeJoinRsp, rspLen);
+
+
+ pSirSmeJoinRsp->beaconLength = 0;
+ pSirSmeJoinRsp->assocReqLength = 0;
+ pSirSmeJoinRsp->assocRspLength = 0;
+ }
+
+ else
+ {
+ rspLen = psessionEntry->assocReqLen + psessionEntry->assocRspLen +
+ psessionEntry->bcnLen +
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ psessionEntry->RICDataLen +
+#endif
+#ifdef FEATURE_WLAN_CCX
+ psessionEntry->tspecLen +
+#endif
+ sizeof(tSirSmeJoinRsp) - sizeof(tANI_U8) ;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeJoinRsp, rspLen))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for JOIN/REASSOC_RSP\n"));
+
+ return;
+ }
+
+ palZeroMemory(pMac, (tANI_U8*)pSirSmeJoinRsp, rspLen);
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeJoinRsp->messageType, msgType);
+ sirStoreU16N((tANI_U8*)&pSirSmeJoinRsp->length, rspLen);
+#endif
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA)
+ if (resultCode == eSIR_SME_SUCCESS)
+ {
+ pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not Get Self Entry for the station\n"));)
+ }
+ else
+ {
+ //Pass the peer's staId
+ pSirSmeJoinRsp->staId = pStaDs->staIndex;
+ pSirSmeJoinRsp->ucastSig = pStaDs->ucUcastSig;
+ pSirSmeJoinRsp->bcastSig = pStaDs->ucBcastSig;
+ }
+ }
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (resultCode == eSIR_SME_TRANSFER_STA)
+ {
+ palCopyMemory( pMac->hHdd, pSirSmeJoinRsp->alternateBssId,
+ pMac->lim.gLimAlternateRadio.bssId,
+ sizeof(tSirMacAddr));
+ pSirSmeJoinRsp->alternateChannelId =
+ pMac->lim.gLimAlternateRadio.channelId;
+ }
+#endif
+
+ pSirSmeJoinRsp->beaconLength = 0;
+ pSirSmeJoinRsp->assocReqLength = 0;
+ pSirSmeJoinRsp->assocRspLength = 0;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ pSirSmeJoinRsp->parsedRicRspLen = 0;
+#endif
+#ifdef FEATURE_WLAN_CCX
+ pSirSmeJoinRsp->tspecIeLen = 0;
+#endif
+
+ if(resultCode == eSIR_SME_SUCCESS)
+ {
+
+ if(psessionEntry->beacon != NULL)
+ {
+ pSirSmeJoinRsp->beaconLength = psessionEntry->bcnLen;
+ palCopyMemory(pMac->hHdd, pSirSmeJoinRsp->frames, psessionEntry->beacon, pSirSmeJoinRsp->beaconLength);
+ palFreeMemory(pMac->hHdd, psessionEntry->beacon);
+ psessionEntry->beacon = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(limLog(pMac, LOG1, FL("Beacon=%d\n"), psessionEntry->bcnLen);)
+#endif
+ }
+
+ if(psessionEntry->assocReq != NULL)
+ {
+ pSirSmeJoinRsp->assocReqLength = psessionEntry->assocReqLen;
+ palCopyMemory(pMac->hHdd, pSirSmeJoinRsp->frames + psessionEntry->bcnLen, psessionEntry->assocReq, pSirSmeJoinRsp->assocReqLength);
+ palFreeMemory(pMac->hHdd, psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(limLog(pMac, LOG1, FL("AssocReq=%d\n"), psessionEntry->assocReqLen);)
+#endif
+ }
+ if(psessionEntry->assocRsp != NULL)
+ {
+ pSirSmeJoinRsp->assocRspLength = psessionEntry->assocRspLen;
+ palCopyMemory(pMac->hHdd, pSirSmeJoinRsp->frames + psessionEntry->bcnLen + psessionEntry->assocReqLen, psessionEntry->assocRsp, pSirSmeJoinRsp->assocRspLength);
+ palFreeMemory(pMac->hHdd, psessionEntry->assocRsp);
+ psessionEntry->assocRsp = NULL;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if(psessionEntry->ricData != NULL)
+ {
+ pSirSmeJoinRsp->parsedRicRspLen = psessionEntry->RICDataLen;
+ palCopyMemory(pMac->hHdd, pSirSmeJoinRsp->frames + psessionEntry->bcnLen + psessionEntry->assocReqLen + psessionEntry->assocRspLen, psessionEntry->ricData, pSirSmeJoinRsp->parsedRicRspLen);
+ palFreeMemory(pMac->hHdd, psessionEntry->ricData);
+ psessionEntry->ricData = NULL;
+ PELOG1(limLog(pMac, LOG1, FL("RicLength=%d\n"), psessionEntry->parsedRicRspLen);)
+ }
+#endif
+#ifdef FEATURE_WLAN_CCX
+ if(psessionEntry->tspecIes != NULL)
+ {
+ pSirSmeJoinRsp->tspecIeLen = psessionEntry->tspecLen;
+ palCopyMemory(pMac->hHdd, pSirSmeJoinRsp->frames + psessionEntry->bcnLen + psessionEntry->assocReqLen + psessionEntry->assocRspLen + psessionEntry->RICDataLen, psessionEntry->tspecIes, pSirSmeJoinRsp->tspecIeLen);
+ palFreeMemory(pMac->hHdd, psessionEntry->tspecIes);
+ psessionEntry->tspecIes = NULL;
+ PELOG1(limLog(pMac, LOG1, FL("CCX-TspecLen=%d\n"), psessionEntry->tspecLen);)
+ }
+#endif
+ pSirSmeJoinRsp->aid = psessionEntry->limAID;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(limLog(pMac, LOG1, FL("AssocRsp=%d\n"), psessionEntry->assocRspLen);)
+#endif
+ }
+ }
+
+
+ pSirSmeJoinRsp->messageType = msgType;
+ pSirSmeJoinRsp->length = (tANI_U16) rspLen;
+ pSirSmeJoinRsp->statusCode = resultCode;
+ pSirSmeJoinRsp->protStatusCode = protStatusCode;
+
+ /* Update SME session ID and transaction Id */
+ pSirSmeJoinRsp->sessionId = smesessionId;
+ pSirSmeJoinRsp->transactionId = smetransactionId;
+
+ if(IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) )
+ {
+ if( psessionEntry && psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE )
+ {
+ peSetResumeChannel( pMac, psessionEntry->currentOperChannel, 0);
+ }
+ else
+ {
+ peSetResumeChannel( pMac, 0, 0);
+ }
+ limResumeLink( pMac, limSendSmeJoinReassocRspAfterResume,
+ (tANI_U32*) pSirSmeJoinRsp );
+ }
+ else
+ {
+ limSendSmeJoinReassocRspAfterResume( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pSirSmeJoinRsp );
+ }
+} /*** end limSendSmeJoinReassocRsp() ***/
+
+
+
+/**
+ * limSendSmeStartBssRsp()
+ *
+ *FUNCTION:
+ * This function is called to send eWNI_SME_START_BSS_RSP
+ * message to applications above MAC Software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates message type
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+limSendSmeStartBssRsp(tpAniSirGlobal pMac,
+ tANI_U16 msgType, tSirResultCodes resultCode,tpPESession psessionEntry,
+ tANI_U8 smesessionId,tANI_U16 smetransactionId)
+{
+
+
+ tANI_U16 size = 0;
+ tSirMsgQ mmhMsg;
+ tSirSmeStartBssRsp *pSirSmeRsp;
+ tANI_U16 ieLen;
+ tANI_U16 ieOffset, curLen;
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending message %s with reasonCode %s\n"),
+ limMsgStr(msgType), limResultCodeStr(resultCode));)
+
+ size = sizeof(tSirSmeStartBssRsp);
+
+ if(psessionEntry == NULL)
+ {
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeRsp, size))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,FL("call to palAllocateMemory failed for eWNI_SME_START_BSS_RSP\n"));
+ return;
+ }
+ palZeroMemory(pMac, (tANI_U8*)pSirSmeRsp, size);
+
+ }
+ else
+ {
+ //subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID
+ ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET;
+ ieLen = pMac->sch.schObject.gSchBeaconOffsetBegin + pMac->sch.schObject.gSchBeaconOffsetEnd - ieOffset;
+ //calculate the memory size to allocate
+ size += ieLen;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeRsp, size))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_START_BSS_RSP\n"));
+
+ return;
+ }
+ palZeroMemory(pMac, (tANI_U8*)pSirSmeRsp, size);
+ size = sizeof(tSirSmeStartBssRsp);
+ if (resultCode == eSIR_SME_SUCCESS)
+ {
+
+ sirCopyMacAddr(pSirSmeRsp->bssDescription.bssId, psessionEntry->bssId);
+
+ /* Read beacon interval from session */
+ pSirSmeRsp->bssDescription.beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval;
+ pSirSmeRsp->bssType = psessionEntry->bssType;
+
+ if (cfgGetCapabilityInfo( pMac, &pSirSmeRsp->bssDescription.capabilityInfo,psessionEntry)
+ != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve Capabilities value\n"));
+
+ limGetPhyMode(pMac, (tANI_U32 *)&pSirSmeRsp->bssDescription.nwType, psessionEntry);
+
+#if 0
+ if (wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_CHANNEL, &len) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("could not retrieve CURRENT_CHANNEL from CFG\n"));
+
+#endif// TO SUPPORT BT-AMP
+
+ pSirSmeRsp->bssDescription.channelId = psessionEntry->currentOperChannel;
+
+ pSirSmeRsp->bssDescription.aniIndicator = 1;
+
+ curLen = pMac->sch.schObject.gSchBeaconOffsetBegin - ieOffset;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields,
+ pMac->sch.schObject.gSchBeaconFrameBegin + ieOffset,
+ (tANI_U32)curLen);
+
+ palCopyMemory( pMac->hHdd, ((tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields) + curLen,
+ pMac->sch.schObject.gSchBeaconFrameEnd,
+ (tANI_U32)pMac->sch.schObject.gSchBeaconOffsetEnd);
+
+
+ //subtracting size of length indicator itself and size of pointer to ieFields
+ pSirSmeRsp->bssDescription.length = sizeof(tSirBssDescription) -
+ sizeof(tANI_U16) - sizeof(tANI_U32) +
+ ieLen;
+ //This is the size of the message, subtracting the size of the pointer to ieFields
+ size += ieLen - sizeof(tANI_U32);
+ }
+
+
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->messageType, msgType);
+ sirStoreU16N((tANI_U8*)&pSirSmeRsp->length, size);
+
+#endif
+
+ }
+
+ pSirSmeRsp->messageType = msgType;
+ pSirSmeRsp->length = size;
+
+ /* Update SME session Id and transaction Id */
+ pSirSmeRsp->sessionId = smesessionId;
+ pSirSmeRsp->transactionId = smetransactionId;
+ pSirSmeRsp->statusCode = resultCode;
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry != NULL )
+ pSirSmeRsp->staId = psessionEntry->staId; //else it will be always zero smeRsp StaID = 0
+
+#endif
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pSirSmeRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+} /*** end limSendSmeStartBssRsp() ***/
+
+
+
+
+
+#define LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED 20
+#define LIM_SIZE_OF_EACH_BSS 400 // this is a rough estimate
+
+
+/**
+ * limSendSmeScanRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() to send
+ * eWNI_SME_SCAN_RSP message to applications above MAC
+ * Software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param length Indicates length of message
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_SCAN_REQ message
+ *
+ * @return None
+ */
+
+void
+limSendSmeScanRsp(tpAniSirGlobal pMac, tANI_U16 length,
+ tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeScanRsp pSirSmeScanRsp=NULL;
+ tLimScanResultNode *ptemp = NULL;
+ tANI_U16 msgLen, allocLength, curMsgLen = 0;
+ tANI_U16 i, bssCount;
+ tANI_U8 *pbBuf;
+ tSirBssDescription *pDesc;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Sending message SME_SCAN_RSP with length=%d reasonCode %s\n"),
+ length, limResultCodeStr(resultCode));)
+
+ if (resultCode != eSIR_SME_SUCCESS)
+ {
+ limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId);
+ return;
+ }
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ i = 0;
+ bssCount = 0;
+ msgLen = 0;
+ allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS;
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeScanRsp, allocLength))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_SCAN_RSP\n"));
+
+ return;
+ }
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ {
+ //when ptemp is not NULL it is a left over
+ ptemp = pMac->lim.gLimCachedScanHashTable[i];
+ while(ptemp)
+ {
+ pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen;
+ if(0 == bssCount)
+ {
+ msgLen = sizeof(tSirSmeScanRsp) -
+ sizeof(tSirBssDescription) +
+ ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = pSirSmeScanRsp->bssDescription;
+ }
+ else
+ {
+ msgLen += ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = (tSirBssDescription *)pbBuf;
+ }
+ if( (allocLength < msgLen) ||
+ (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) )
+ {
+ pSirSmeScanRsp->statusCode =
+ eSIR_SME_MORE_SCAN_RESULTS_FOLLOW;
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->messageType,
+ eWNI_SME_SCAN_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->length, curMsgLen);
+#else
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->length = curMsgLen;
+#endif
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeScanRsp, allocLength))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_SCAN_RSP\n"));
+ return;
+ }
+ msgLen = sizeof(tSirSmeScanRsp) -
+ sizeof(tSirBssDescription) +
+ ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = pSirSmeScanRsp->bssDescription;
+ bssCount = 1;
+ }
+ curMsgLen = msgLen;
+
+ PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d\n"),
+ msgLen, ptemp->bssDescription.length);)
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pDesc->length,
+ ptemp->bssDescription.length);
+#else
+ pDesc->length
+ = ptemp->bssDescription.length;
+#endif
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pDesc->bssId,
+ (tANI_U8 *) &ptemp->bssDescription.bssId,
+ ptemp->bssDescription.length);
+
+ PELOG2(limLog(pMac, LOG2, FL("BssId "));
+ limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);)
+
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetranscationId;
+
+ ptemp = ptemp->next;
+ } //while(ptemp)
+ } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+
+ if(0 == bssCount)
+ {
+ limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId);
+ }
+ else
+ {
+ // send last message
+ pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS;
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->messageType,
+ eWNI_SME_SCAN_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->length, curMsgLen);
+#else
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->length = curMsgLen;
+#endif
+
+ /* Update SME session Id and SME transcation Id */
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetranscationId;
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ PELOG2(limLog(pMac, LOG2, FL("statusCode : eSIR_SME_SUCCESS\n"));)
+ }
+
+ return;
+
+} /*** end limSendSmeScanRsp() ***/
+
+
+/**
+ * limPostSmeScanRspMessage()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeScanRsp() to send
+ * eWNI_SME_SCAN_RSP message with failed result code
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param length Indicates length of message
+ * @param resultCode failed result code
+ *
+ * @return None
+ */
+
+void
+limPostSmeScanRspMessage(tpAniSirGlobal pMac,
+ tANI_U16 length,
+ tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId)
+{
+ tpSirSmeScanRsp pSirSmeScanRsp;
+ tSirMsgQ mmhMsg;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("limPostSmeScanRspMessage: send SME_SCAN_RSP (len %d, reasonCode %s). \n"),
+ length, limResultCodeStr(resultCode));)
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeScanRsp, length))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_SCAN_RSP\n"));
+ return;
+ }
+ palZeroMemory(pMac->hHdd, (void*)pSirSmeScanRsp, length);
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->messageType, eWNI_SME_SCAN_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeScanRsp->length, length);
+#else
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->length = length;
+#endif
+
+ if(sizeof(tSirSmeScanRsp) <= length)
+ {
+ pSirSmeScanRsp->bssDescription->length = sizeof(tSirBssDescription);
+ }
+
+ pSirSmeScanRsp->statusCode = resultCode;
+
+ /*Update SME session Id and transaction Id */
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL, (tANI_U16)resultCode, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+
+} /*** limPostSmeScanRspMessage ***/
+
+
+
+/**
+ * limSendSmeAuthRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_AUTH_RSP message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param statusCode Indicates the result of previously issued
+ * eWNI_SME_AUTH_REQ message
+ *
+ * @return None
+ */
+void
+limSendSmeAuthRsp(tpAniSirGlobal pMac,
+ tSirResultCodes statusCode,
+ tSirMacAddr peerMacAddr,
+ tAniAuthType authType,
+ tANI_U16 protStatusCode,
+ tpPESession psessionEntry,tANI_U8 smesessionId,
+ tANI_U16 smetransactionId)
+{
+#if 0
+ tSirMsgQ mmhMsg;
+ tSirSmeAuthRsp *pSirSmeAuthRsp;
+
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeAuthRsp, sizeof(tSirSmeAuthRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_AUTH_RSP\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeAuthRsp->messageType, eWNI_SME_AUTH_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeAuthRsp->length, sizeof(tSirSmeAuthRsp));
+
+#endif
+
+
+ if(psessionEntry != NULL)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pSirSmeAuthRsp->peerMacAddr,
+ (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr));
+ pSirSmeAuthRsp->authType = authType;
+
+ }
+
+ pSirSmeAuthRsp->messageType = eWNI_SME_AUTH_RSP;
+ pSirSmeAuthRsp->length = sizeof(tSirSmeAuthRsp);
+ pSirSmeAuthRsp->statusCode = statusCode;
+ pSirSmeAuthRsp->protStatusCode = protStatusCode;
+
+ /* Update SME session and transaction Id*/
+ pSirSmeAuthRsp->sessionId = smesessionId;
+ pSirSmeAuthRsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_AUTH_RSP;
+ mmhMsg.bodyptr = pSirSmeAuthRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+#endif
+} /*** end limSendSmeAuthRsp() ***/
+
+
+void limSendSmeDisassocDeauthNtfPostResume( tpAniSirGlobal pMac,
+ eHalStatus status, tANI_U32 *pCtx )
+{
+ tSirMsgQ mmhMsg;
+ tSirMsgQ *pMsg = (tSirMsgQ*) pCtx;
+
+ mmhMsg.type = pMsg->type;
+ mmhMsg.bodyptr = pMsg;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+/**
+ * limSendSmeDisassocNtf()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * This function is used for sending eWNI_SME_DISASSOC_CNF,
+ * or eWNI_SME_DISASSOC_IND to host depending on
+ * disassociation trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * disassociate was initiated
+ * @param reasonCode Indicates the reason for Disassociation
+ * @param disassocTrigger Indicates the trigger for Disassociation
+ * @param aid Indicates the STAID. This parameter is
+ * present only on AP.
+ *
+ * @return None
+ */
+void
+limSendSmeDisassocNtf(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirResultCodes reasonCode,
+ tANI_U16 disassocTrigger,
+ tANI_U16 aid,
+ tANI_U8 smesessionId,
+ tANI_U16 smetransactionId,
+ tpPESession psessionEntry)
+{
+
+ tANI_U8 *pBuf;
+ tSirSmeDisassocRsp *pSirSmeDisassocRsp;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+ tANI_U32 *pMsg;
+
+ switch (disassocTrigger)
+ {
+ case eLIM_PEER_ENTITY_DISASSOC:
+ return;
+
+ case eLIM_HOST_DISASSOC:
+ /**
+ * Disassociation response due to
+ * host triggered disassociation
+ */
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDisassocRsp, sizeof(tSirSmeDisassocRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_DISASSOC_RSP\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocRsp->messageType,
+ eWNI_SME_DISASSOC_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocRsp->length,
+ sizeof(tSirSmeDisassocRsp));
+#else
+ pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
+ pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
+#endif
+ //sessionId
+ pBuf = (tANI_U8 *) &pSirSmeDisassocRsp->sessionId;
+ *pBuf = smesessionId;
+ pBuf++;
+
+ //transactionId
+ limCopyU16(pBuf, smetransactionId);
+ pBuf += sizeof(tANI_U16);
+
+ //statusCode
+ limCopyU32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ limCopyU16(pBuf, aid);
+ pBuf += sizeof(tANI_U16);
+
+ // perStaStats
+ limStatSerDes(pMac, &pMac->hal.halMac.macStats.pPerStaStats[aid].staStat, pBuf);
+#else
+ // Clear Station Stats
+ //for sta, it is always 1, IBSS is handled at halInitSta
+
+#endif//#if (WNI_POLARIS_FW_PRODUCT == AP)
+
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ psessionEntry, (tANI_U16)reasonCode, 0);
+#endif
+ pMsg = (tANI_U32*) pSirSmeDisassocRsp;
+ break;
+
+ default:
+ /**
+ * Disassociation indication due to Disassociation
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDisassocInd, sizeof(tSirSmeDisassocInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_DISASSOC_IND\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocInd->messageType,
+ eWNI_SME_DISASSOC_IND);
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocInd->length,
+ sizeof(tSirSmeDisassocInd));
+#else
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+ /* Update SME session Id and Transaction Id */
+ pSirSmeDisassocInd->sessionId = smesessionId;
+ pSirSmeDisassocInd->transactionId = smetransactionId;
+#endif
+ pBuf = (tANI_U8 *) &pSirSmeDisassocInd->statusCode;
+
+ limCopyU32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ palCopyMemory( pMac->hHdd, pBuf, peerMacAddr, sizeof(tSirMacAddr));
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf += sizeof(tSirMacAddr);
+ limCopyU16(pBuf, aid);
+ pBuf += sizeof(tANI_U16);
+
+ limStatSerDes(pMac, &pMac->hal.halMac.macStats.pPerStaStats[aid].staStat, pBuf);
+
+#endif//#if (WNI_POLARIS_FW_PRODUCT == AP)
+
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ psessionEntry, (tANI_U16)reasonCode, 0);
+#endif
+ pMsg = (tANI_U32*) pSirSmeDisassocInd;
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ PELOG1(limLog(pMac, LOG1,
+ FL("*** Sending DisAssocInd staId=%d, reasonCode=%d ***\n"),
+ aid, reasonCode);)
+#endif
+
+ break;
+ }
+
+ /* Delete the PE session Created */
+ if((psessionEntry != NULL) && ((psessionEntry ->limSystemRole == eLIM_STA_ROLE) ||
+ (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE)) )
+ {
+ peDeleteSession(pMac,psessionEntry);
+ }
+
+ if( IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) )
+ {
+ //Resume on the first active session channel.
+ peSetResumeChannel( pMac, peGetActiveSessionChannel( pMac ), 0);
+
+ limResumeLink( pMac, limSendSmeDisassocDeauthNtfPostResume,
+ (tANI_U32*) pMsg );
+ }
+ else
+ {
+ limSendSmeDisassocDeauthNtfPostResume( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsg );
+ }
+} /*** end limSendSmeDisassocNtf() ***/
+
+
+/** -----------------------------------------------------------------
+ \brief limSendSmeDisassocInd() - sends SME_DISASSOC_IND
+
+ After receiving disassociation frame from peer entity, this
+ function sends a eWNI_SME_DISASSOC_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmeDisassocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDisassocInd, sizeof(tSirSmeDisassocInd)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_DISASSOC_IND\n"));
+ return;
+ }
+
+ //psessionEntry = peFindSessionByBssid(pMac,pStaDs->staAddr,&sessionId);
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocInd->messageType, eWNI_SME_DISASSOC_IND);
+ sirStoreU16N((tANI_U8*)&pSirSmeDisassocInd->length, sizeof(tSirSmeDisassocInd));
+#else
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+#endif
+
+#if 0 //Commenting out all the serialization
+ //statusCode
+ pBuf = (tANI_U8 *) &pSirSmeDisassocInd->statusCode;
+ limCopyU32(pBuf, pStaDs->mlmStaContext.disassocReason);
+ pBuf += sizeof(tSirResultCodes);
+
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pStaDs->staAddr, sizeof(tSirMacAddr));
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ pBuf += sizeof(tSirMacAddr);
+ //aid
+ limCopyU16(pBuf, pStaDs->assocId);
+ pBuf += sizeof(tANI_U16);
+
+ //perStaStats
+ limStatSerDes(pMac, &pMac->hal.halMac.macStats.pPerStaStats[pStaDs->assocId].staStat, pBuf);
+#endif
+#endif
+ pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDisassocInd->transactionId = psessionEntry->transactionId;
+ pSirSmeDisassocInd->statusCode = pStaDs->mlmStaContext.disassocReason;
+
+ palCopyMemory( pMac->hHdd, pSirSmeDisassocInd->bssId , psessionEntry->bssId , sizeof(tSirMacAddr));
+
+ palCopyMemory( pMac->hHdd, pSirSmeDisassocInd->peerMacAddr , pStaDs->staAddr, sizeof(tSirMacAddr));
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ pSirSmeDisassocInd->aid = pStaDs->assocId;
+ limStatSerDes(pMac, &pMac->hal.halMac.macStats.pPerStaStats[pStaDs->assocId].staStat,(tANI_U8*)&pSirSmeDisassocInd-> perStaStats );
+#endif
+#ifdef WLAN_SOFTAP_FEATURE
+ pSirSmeDisassocInd->staId = pStaDs->staIndex;
+#endif
+
+ mmhMsg.type = eWNI_SME_DISASSOC_IND;
+ mmhMsg.bodyptr = pSirSmeDisassocInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry, 0, (tANI_U16)pStaDs->mlmStaContext.disassocReason);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+} /*** end limSendSmeDisassocInd() ***/
+
+
+/** -----------------------------------------------------------------
+ \brief limSendSmeDeauthInd() - sends SME_DEAUTH_IND
+
+ After receiving deauthentication frame from peer entity, this
+ function sends a eWNI_SME_DEAUTH_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmeDeauthInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+#ifndef WLAN_SOFTAP_FEATURE
+ tANI_U8 *pBuf;
+#endif
+ tSirMsgQ mmhMsg;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDeauthInd, sizeof(tSirSmeDeauthInd)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_DEAUTH_IND \n"));
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeDeauthInd->messageType, eWNI_SME_DEAUTH_IND);
+ sirStoreU16N((tANI_U8*)&pSirSmeDeauthInd->length, sizeof(tSirSmeDeauthInd));
+#else
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDeauthInd->transactionId = psessionEntry->transactionId;
+ if(eSIR_INFRA_AP_MODE == psessionEntry->bssType)
+ {
+ pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.cleanupTrigger;
+ }
+ else
+ {
+ //Need to indicatet he reascon code over the air
+ pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.disassocReason;
+ }
+ //BSSID
+ palCopyMemory( pMac->hHdd, pSirSmeDeauthInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr));
+#else
+
+ //sessionId
+ pBuf = (tANI_U8 *) &pSirSmeDeauthInd->sessionId;
+ *pBuf++ = psessionEntry->smeSessionId;
+
+ //transactionId
+ limCopyU16(pBuf, 0);
+ pBuf += sizeof(tANI_U16);
+
+ // status code
+ limCopyU32(pBuf, pStaDs->mlmStaContext.cleanupTrigger);
+ pBuf += sizeof(tSirResultCodes);
+
+ //bssid
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pStaDs->staAddr, sizeof(tSirMacAddr));
+#endif
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf += sizeof(tSirMacAddr);
+ limCopyU16(pBuf, pStaDs->staAddr);
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ pSirSmeDeauthInd->staId = pStaDs->staIndex;
+#endif
+
+ mmhMsg.type = eWNI_SME_DEAUTH_IND;
+ mmhMsg.bodyptr = pSirSmeDeauthInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry, 0, pStaDs->mlmStaContext.cleanupTrigger);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end limSendSmeDeauthInd() ***/
+
+
+/**
+ * limSendSmeDeauthNtf()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * This function is used for sending eWNI_SME_DEAUTH_CNF or
+ * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * deauthentication was initiated
+ * @param reasonCode Indicates the reason for Deauthetication
+ * @param deauthTrigger Indicates the trigger for Deauthetication
+ * @param aid Indicates the STAID. This parameter is present
+ * only on AP.
+ *
+ * @return None
+ */
+void
+limSendSmeDeauthNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes reasonCode,
+ tANI_U16 deauthTrigger, tANI_U16 aid,tANI_U8 smesessionId, tANI_U16 smetransactionId)
+{
+ tANI_U8 *pBuf;
+ tSirSmeDeauthRsp *pSirSmeDeauthRsp;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tANI_U32 *pMsg;
+
+ psessionEntry = peFindSessionByBssid(pMac,peerMacAddr,&sessionId);
+ switch (deauthTrigger)
+ {
+ case eLIM_PEER_ENTITY_DEAUTH:
+ return;
+
+ case eLIM_HOST_DEAUTH:
+ /**
+ * Deauthentication response to host triggered
+ * deauthentication.
+ */
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDeauthRsp, sizeof(tSirSmeDeauthRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_DEAUTH_RSP\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*) &(pSirSmeDeauthRsp->messageType),
+ eWNI_SME_DEAUTH_RSP);
+ sirStoreU16N((tANI_U8*) &(pSirSmeDeauthRsp->length),
+ sizeof(tSirSmeDeauthRsp));
+#else
+ pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
+ pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
+#endif
+ pSirSmeDeauthRsp->statusCode = reasonCode;
+ pSirSmeDeauthRsp->sessionId = smesessionId;
+ pSirSmeDeauthRsp->transactionId = smetransactionId;
+
+ pBuf = (tANI_U8 *) pSirSmeDeauthRsp->peerMacAddr;
+ palCopyMemory( pMac->hHdd, pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf += sizeof(tSirMacAddr);
+ limCopyU16(pBuf, aid);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ psessionEntry, 0, (tANI_U16)reasonCode);
+#endif
+ pMsg = (tANI_U32*)pSirSmeDeauthRsp;
+
+ break;
+
+ default:
+ /**
+ * Deauthentication indication due to Deauthentication
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeDeauthInd, sizeof(tSirSmeDeauthInd)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_DEAUTH_Ind\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeDeauthInd->messageType,
+ eWNI_SME_DEAUTH_IND);
+ sirStoreU16N((tANI_U8*)&pSirSmeDeauthInd->length,
+ sizeof(tSirSmeDeauthInd));
+#else
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+#endif
+
+ // sessionId
+ pBuf = (tANI_U8*) &pSirSmeDeauthInd->sessionId;
+ *pBuf++ = smesessionId;
+
+ //transaction ID
+ limCopyU16(pBuf, smetransactionId);
+ pBuf += sizeof(tANI_U16);
+
+ // status code
+ limCopyU32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ //bssId
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ //peerMacAddr
+ palCopyMemory( pMac->hHdd, pSirSmeDeauthInd->peerMacAddr, peerMacAddr, sizeof(tSirMacAddr));
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf += sizeof(tSirMacAddr);
+ limCopyU16(pBuf, aid);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ psessionEntry, 0, (tANI_U16)reasonCode);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+ pMsg = (tANI_U32*)pSirSmeDeauthInd;
+
+ break;
+ }
+
+ /*Delete the PE session created */
+ if(psessionEntry != NULL)
+ {
+ peDeleteSession(pMac,psessionEntry);
+ }
+
+ if( IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) )
+ {
+ //Resume on the first active session channel.
+ peSetResumeChannel( pMac, peGetActiveSessionChannel( pMac ), 0);
+
+ limResumeLink( pMac, limSendSmeDisassocDeauthNtfPostResume,
+ (tANI_U32*) pMsg );
+ }
+ else
+ {
+ limSendSmeDisassocDeauthNtfPostResume( pMac, eHAL_STATUS_SUCCESS,
+ (tANI_U32*) pMsg );
+ }
+} /*** end limSendSmeDeauthNtf() ***/
+
+
+/**
+ * limSendSmeWmStatusChangeNtf()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param statusChangeCode Indicates the change in the wireless medium.
+ * @param statusChangeInfo Indicates the information associated with
+ * change in the wireless medium.
+ * @param infoLen Indicates the length of status change information
+ * being sent.
+ *
+ * @return None
+ */
+void
+limSendSmeWmStatusChangeNtf(tpAniSirGlobal pMac, tSirSmeStatusChangeCode statusChangeCode,
+ tANI_U32 *pStatusChangeInfo, tANI_U16 infoLen, tANI_U8 sessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeWmStatusChangeNtf *pSirSmeWmStatusChangeNtf;
+ eHalStatus status;
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ tANI_U32 bufLen;
+ tANI_U16 length=0;
+ tANI_U8 *pBuf;
+#endif
+
+
+
+ status = palAllocateMemory( pMac->hHdd, (void **)&pSirSmeWmStatusChangeNtf,
+ sizeof(tSirSmeWmStatusChangeNtf));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("call to palAllocateMemory failed for eWNI_SME_WM_STATUS_CHANGE_NTF, status = %d\n"),
+ status);
+ return;
+ }
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf = (tANI_U8 *)pSirSmeWmStatusChangeNtf;
+#endif
+
+ mmhMsg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
+ mmhMsg.bodyval = 0;
+ mmhMsg.bodyptr = pSirSmeWmStatusChangeNtf;
+
+ switch(statusChangeCode)
+ {
+ case eSIR_SME_RADAR_DETECTED:
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ bufLen = sizeof(tSirSmeWmStatusChangeNtf);
+ if ((limSmeWmStatusChangeHeaderSerDes(pMac,
+ statusChangeCode,
+ pBuf,
+ &length,
+ bufLen,
+ sessionId) != eSIR_SUCCESS))
+ {
+ palFreeMemory(pMac->hHdd, (void *) pSirSmeWmStatusChangeNtf);
+ limLog(pMac, LOGP, FL("Header SerDes failed \n"));
+ return;
+ }
+ pBuf += length;
+ bufLen -= length;
+ if ((limRadioInfoSerDes(pMac,
+ (tpSirRadarInfo)pStatusChangeInfo,
+ pBuf,
+ &length,
+ bufLen) != eSIR_SUCCESS))
+ {
+ palFreeMemory(pMac->hHdd, (void *) pSirSmeWmStatusChangeNtf);
+ limLog(pMac, LOGP, FL("Radio Info SerDes failed \n"));
+ return;
+ }
+
+ pBuf = (tANI_U8 *) pSirSmeWmStatusChangeNtf;
+ pBuf += sizeof(tANI_U16);
+ limCopyU16(pBuf, length);
+#endif
+ break;
+
+ case eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP:
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+
+ if( eSIR_SUCCESS != nonTitanBssFoundSerDes( pMac,
+ (tpSirNeighborBssWdsInfo) pStatusChangeInfo,
+ pBuf,
+ &length,
+ sessionId))
+ {
+ palFreeMemory(pMac->hHdd, (void *) pSirSmeWmStatusChangeNtf);
+ limLog( pMac, LOGP,
+ FL("Unable to serialize nonTitanBssFoundSerDes!\n"));
+ return;
+ }
+#endif
+ break;
+
+ case eSIR_SME_BACKGROUND_SCAN_FAIL:
+ limPackBkgndScanFailNotify(pMac,
+ statusChangeCode,
+ (tpSirBackgroundScanInfo)pStatusChangeInfo,
+ pSirSmeWmStatusChangeNtf, sessionId);
+ break;
+
+ default:
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeWmStatusChangeNtf->messageType,
+ eWNI_SME_WM_STATUS_CHANGE_NTF );
+ sirStoreU16N((tANI_U8*)&pSirSmeWmStatusChangeNtf->length,
+ (sizeof(tSirSmeWmStatusChangeNtf)));
+ pSirSmeWmStatusChangeNtf->sessionId = sessionId;
+ sirStoreU32N((tANI_U8*)&pSirSmeWmStatusChangeNtf->statusChangeCode,
+ statusChangeCode);
+#else
+ pSirSmeWmStatusChangeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF;
+ pSirSmeWmStatusChangeNtf->statusChangeCode = statusChangeCode;
+ pSirSmeWmStatusChangeNtf->length = sizeof(tSirSmeWmStatusChangeNtf);
+ pSirSmeWmStatusChangeNtf->sessionId = sessionId;
+#endif
+ if(sizeof(pSirSmeWmStatusChangeNtf->statusChangeInfo) >= infoLen)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)&pSirSmeWmStatusChangeNtf->statusChangeInfo, (tANI_U8 *)pStatusChangeInfo, infoLen);
+ }
+ limLog(pMac, LOGE, FL("***---*** StatusChg: code 0x%x, length %d ***---***\n"),
+ statusChangeCode, infoLen);
+ break;
+ }
+
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ if (eSIR_SUCCESS != limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT))
+ {
+ palFreeMemory(pMac->hHdd, (void *) pSirSmeWmStatusChangeNtf);
+ limLog( pMac, LOGP, FL("limSysProcessMmhMsgApi failed\n"));
+ }
+
+} /*** end limSendSmeWmStatusChangeNtf() ***/
+
+
+/**
+ * limSendSmeSetContextRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_SETCONTEXT_RSP message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * setContext was performed
+ * @param aid Indicates the aid corresponding to the peer MAC
+ * address
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_SETCONTEXT_RSP message
+ *
+ * @return None
+ */
+void
+limSendSmeSetContextRsp(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr, tANI_U16 aid,
+ tSirResultCodes resultCode,
+ tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId)
+{
+
+ tANI_U8 *pBuf;
+ tSirMsgQ mmhMsg;
+ tSirSmeSetContextRsp *pSirSmeSetContextRsp;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeSetContextRsp, sizeof(tSirSmeSetContextRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for SmeSetContextRsp\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeSetContextRsp->messageType,
+ eWNI_SME_SETCONTEXT_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeSetContextRsp->length,
+ sizeof(tSirSmeSetContextRsp));
+#else
+ pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP;
+ pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp);
+#endif
+ pSirSmeSetContextRsp->statusCode = resultCode;
+
+ pBuf = pSirSmeSetContextRsp->peerMacAddr;
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ limCopyU16(pBuf, aid);
+ pBuf += sizeof(tANI_U16);
+#endif
+
+ /* Update SME session and transaction Id*/
+ pSirSmeSetContextRsp->sessionId = smesessionId;
+ pSirSmeSetContextRsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_SETCONTEXT_RSP;
+ mmhMsg.bodyptr = pSirSmeSetContextRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+} /*** end limSendSmeSetContextRsp() ***/
+
+/**
+ * limSendSmeRemoveKeyRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_REMOVEKEY_RSP message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * Removekey was performed
+ * @param aid Indicates the aid corresponding to the peer MAC
+ * address
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_REMOVEKEY_RSP message
+ *
+ * @return None
+ */
+void
+limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirResultCodes resultCode,
+ tpPESession psessionEntry,tANI_U8 smesessionId,
+ tANI_U16 smetransactionId)
+{
+ tANI_U8 *pBuf;
+ tSirMsgQ mmhMsg;
+ tSirSmeRemoveKeyRsp *pSirSmeRemoveKeyRsp;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeRemoveKeyRsp, sizeof(tSirSmeRemoveKeyRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for SmeRemoveKeyRsp\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined(ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSirSmeRemoveKeyRsp->messageType,
+ eWNI_SME_REMOVEKEY_RSP);
+ sirStoreU16N((tANI_U8*)&pSirSmeRemoveKeyRsp->length,
+ sizeof(tSirSmeRemoveKeyRsp));
+
+#endif
+
+
+ if(psessionEntry != NULL)
+ {
+ pBuf = pSirSmeRemoveKeyRsp->peerMacAddr;
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ limCopyU32(pBuf, resultCode);
+ }
+
+ pSirSmeRemoveKeyRsp->messageType = eWNI_SME_REMOVEKEY_RSP;
+ pSirSmeRemoveKeyRsp->length = sizeof(tSirSmeRemoveKeyRsp);
+ pSirSmeRemoveKeyRsp->statusCode = resultCode;
+
+ /* Update SME session and transaction Id*/
+ pSirSmeRemoveKeyRsp->sessionId = smesessionId;
+ pSirSmeRemoveKeyRsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_REMOVEKEY_RSP;
+ mmhMsg.bodyptr = pSirSmeRemoveKeyRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+} /*** end limSendSmeSetContextRsp() ***/
+
+
+/**
+ * limSendSmePromiscuousModeRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_PROMISCUOUS_MODE_RSP message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * This function is used for sending eWNI_SME_PROMISCUOUS_MODE_RSP to
+ * host as a reply to eWNI_SME_PROMISCUOUS_MODE_REQ directive from it.
+ *
+ * @param None
+ * @return None
+ */
+void
+limSendSmePromiscuousModeRsp(tpAniSirGlobal pMac)
+{
+#if 0
+ tSirMsgQ mmhMsg;
+ tSirMbMsg *pMbMsg;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMbMsg, sizeof(tSirMbMsg)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed\n"));
+
+ return;
+ }
+
+ pMbMsg->type = eWNI_SME_PROMISCUOUS_MODE_RSP;
+ pMbMsg->msgLen = 4;
+
+ mmhMsg.type = eWNI_SME_PROMISCUOUS_MODE_RSP;
+ mmhMsg.bodyptr = pMbMsg;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+#endif
+} /*** end limSendSmePromiscuousModeRsp() ***/
+
+
+
+/**
+ * limSendSmeNeighborBssInd()
+ *
+ *FUNCTION:
+ * This function is called by limLookupNaddHashEntry() to send
+ * eWNI_SME_NEIGHBOR_BSS_IND message to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to
+ * host upon detecting new BSS during background scanning if CFG
+ * option is enabled for sending such indication
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limSendSmeNeighborBssInd(tpAniSirGlobal pMac,
+ tLimScanResultNode *pBssDescr)
+{
+ tSirMsgQ msgQ;
+ tANI_U32 val;
+ tSirSmeNeighborBssInd *pNewBssInd;
+
+ if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) ||
+ ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) &&
+ pMac->lim.gLimRspReqd))
+ {
+ // LIM is not in background scan state OR
+ // current scan is initiated by HDD.
+ // No need to send new BSS indication to HDD
+ return;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not get NEIGHBOR_BSS_IND from CFG\n"));
+
+ return;
+ }
+
+ if (val == 0)
+ return;
+
+ /**
+ * Need to indicate new BSSs found during
+ * background scanning to host.
+ * Allocate buffer for sending indication.
+ * Length of buffer is length of BSS description
+ * and length of header itself
+ */
+ val = pBssDescr->bssDescription.length + sizeof(tANI_U16) + sizeof(tANI_U32) + sizeof(tANI_U8);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pNewBssInd, val))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND\n"));
+
+ return;
+ }
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*) &pNewBssInd->messageType,
+ eWNI_SME_NEIGHBOR_BSS_IND);
+ sirStoreU16N((tANI_U8*)&pNewBssInd->length, (tANI_U16)val );
+#else
+ pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND;
+ pNewBssInd->length = (tANI_U16) val;
+#endif
+ pNewBssInd->sessionId = 0;
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pNewBssInd->bssDescription,
+ (tANI_U8 *) &pBssDescr->bssDescription,
+ pBssDescr->bssDescription.length + sizeof(tANI_U16));
+#endif
+
+ msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND;
+ msgQ.bodyptr = pNewBssInd;
+ msgQ.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ limSysProcessMmhMsgApi(pMac, &msgQ, ePROT);
+} /*** end limSendSmeNeighborBssInd() ***/
+
+/** -----------------------------------------------------------------
+ \brief limSendSmeAddtsRsp() - sends SME ADDTS RSP
+ \ This function sends a eWNI_SME_ADDTS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of SME_ADD_TS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry,
+ tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId)
+{
+ tpSirAddtsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ if (! rspReqd)
+ return;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp, sizeof(tSirAddtsRsp)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for ADDTS_RSP"));
+ return;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
+ rsp->messageType = eWNI_SME_ADDTS_RSP;
+ rsp->rc = status;
+ rsp->rsp.status = (enum eSirMacStatusCodes) status;
+ //palCopyMemory( pMac->hHdd, (tANI_U8 *) &rsp->rsp.tspec, (tANI_U8 *) &addts->tspec, sizeof(addts->tspec));
+ rsp->rsp.tspec = tspec;
+
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_ADDTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+void
+limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts)
+{
+ tpSirAddtsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ limLog(pMac, LOGW, "SendSmeAddtsInd (token %d, tsid %d, up %d)\n",
+ addts->dialogToken,
+ addts->tspec.tsinfo.traffic.tsid,
+ addts->tspec.tsinfo.traffic.userPrio);
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp, sizeof(tSirAddtsRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for ADDTS_IND\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
+
+ rsp->messageType = eWNI_SME_ADDTS_IND;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &rsp->rsp, (tANI_U8 *) addts, sizeof(*addts));
+
+ mmhMsg.type = eWNI_SME_ADDTS_IND;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+void
+limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ limLog(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d\n",
+ delts->aid,
+ delts->req.tsinfo.traffic.tsid,
+ delts->req.tsinfo.traffic.userPrio,
+ status);
+ if (! delts->rspReqd)
+ return;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp, sizeof(tSirDeltsRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for DELTS_RSP\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
+
+ if(psessionEntry != NULL)
+ {
+
+ rsp->aid = delts->aid;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &rsp->macAddr[0], (tANI_U8 *) &delts->macAddr[0], 6);
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &rsp->rsp, (tANI_U8 *) &delts->req, sizeof(tSirDeltsReqInfo));
+ }
+
+
+ rsp->messageType = eWNI_SME_DELTS_RSP;
+ rsp->rc = status;
+
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry, (tANI_U16)status, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+void
+limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession psessionEntry)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ limLog(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)\n",
+ aid,
+ delts->tsinfo.traffic.tsid,
+ delts->tsinfo.traffic.userPrio);
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp, sizeof(tSirDeltsRsp)))
+ {
+ // Log error
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for DELTS_IND\n"));
+ return;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
+
+ rsp->messageType = eWNI_SME_DELTS_IND;
+ rsp->rc = eSIR_SUCCESS;
+ rsp->aid = aid;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &rsp->rsp, (tANI_U8 *) delts, sizeof(*delts));
+
+ /* Update SME session Id and SME transaction Id */
+
+ rsp->sessionId = psessionEntry->smeSessionId;
+ rsp->transactionId = psessionEntry->transactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_IND;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * limSendSmeStatsRsp()
+ *
+ *FUNCTION:
+ * This function is called to send 802.11 statistics response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request for statistics.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param p80211Stats Statistics sent in response
+ * @param resultCode TODO:
+ *
+ *
+ * @return none
+ */
+
+void
+limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeRsp *pMsgHdr = (tSirSmeRsp*) stats;
+
+ switch(msgType)
+ {
+ case WDA_STA_STAT_RSP:
+ mmhMsg.type = eWNI_SME_STA_STAT_RSP;
+ break;
+ case WDA_AGGR_STAT_RSP:
+ mmhMsg.type = eWNI_SME_AGGR_STAT_RSP;
+ break;
+ case WDA_GLOBAL_STAT_RSP:
+ mmhMsg.type = eWNI_SME_GLOBAL_STAT_RSP;
+ break;
+ case WDA_STAT_SUMM_RSP:
+ mmhMsg.type = eWNI_SME_STAT_SUMM_RSP;
+ break;
+ default:
+ mmhMsg.type = msgType; //Response from within PE
+ break;
+ }
+
+ pMsgHdr->messageType = mmhMsg.type;
+
+ mmhMsg.bodyptr = stats;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+
+} /*** end limSendSmeStatsRsp() ***/
+
+/**
+ * limSendSmePEStatisticsRsp()
+ *
+ *FUNCTION:
+ * This function is called to send 802.11 statistics response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request for statistics.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param p80211Stats Statistics sent in response
+ * @param resultCode TODO:
+ *
+ *
+ * @return none
+ */
+
+void
+limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats)
+{
+ tSirMsgQ mmhMsg;
+ tANI_U8 sessionId;
+ tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats;
+ tpPESession pPeSessionEntry;
+
+ //Get the Session Id based on Sta Id
+ pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId);
+
+ //Fill the Session Id
+ if(NULL != pPeSessionEntry)
+ {
+ //Fill the Session Id
+ pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+ }
+
+ pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP;
+
+
+ //msgType should be WDA_GET_STATISTICS_RSP
+ mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP;
+
+ mmhMsg.bodyptr = stats;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+
+} /*** end limSendSmePEStatisticsRsp() ***/
+
+
+void
+limSendSmeIBSSPeerInd(
+ tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tANI_U16 staIndex,
+ tANI_U8 ucastIdx,
+ tANI_U8 bcastIdx,
+ tANI_U8 *beacon,
+ tANI_U16 beaconLen,
+ tANI_U16 msgType,
+ tANI_U8 sessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeIbssPeerInd *pNewPeerInd;
+
+ if(eSIR_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,(void * *) &pNewPeerInd,(sizeof(tSmeIbssPeerInd) + beaconLen)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+
+ palZeroMemory(pMac->hHdd, (void *) pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen));
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pNewPeerInd->peerAddr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ pNewPeerInd->staId= staIndex;
+ pNewPeerInd->ucastSig = ucastIdx;
+ pNewPeerInd->bcastSig = bcastIdx;
+ pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen;
+ pNewPeerInd->mesgType = msgType;
+ pNewPeerInd->sessionId = sessionId;
+
+ if ( beacon != NULL )
+ {
+ palCopyMemory(pMac->hHdd, (void*) ((tANI_U8*)pNewPeerInd+sizeof(tSmeIbssPeerInd)), (void*)beacon, beaconLen);
+ }
+
+ mmhMsg.type = msgType;
+// mmhMsg.bodyval = (tANI_U32) pNewPeerInd;
+ mmhMsg.bodyptr = pNewPeerInd;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+}
+
+
+/** -----------------------------------------------------------------
+ \brief limSendExitBmpsInd() - sends exit bmps indication
+
+ This function sends a eWNI_PMC_EXIT_BMPS_IND with a specific reason
+ code to SME. This will trigger SME to get out of BMPS mode.
+
+ \param pMac - global mac structure
+ \param reasonCode - reason for which PE wish to exit BMPS
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode)
+{
+ tSirMsgQ mmhMsg;
+ tANI_U16 msgLen = 0;
+ tpSirSmeExitBmpsInd pExitBmpsInd;
+
+ msgLen = sizeof(tSirSmeExitBmpsInd);
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pExitBmpsInd, msgLen ))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for PMC_EXIT_BMPS_IND \n"));
+ return;
+ }
+ palZeroMemory(pMac->hHdd, pExitBmpsInd, msgLen);
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined (ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pExitBmpsInd->mesgType, eWNI_PMC_EXIT_BMPS_IND);
+ sirStoreU16N((tANI_U8*)&pExitBmpsInd->mesgLen, msgLen);
+#else
+ pExitBmpsInd->mesgType = eWNI_PMC_EXIT_BMPS_IND;
+ pExitBmpsInd->mesgLen = msgLen;
+#endif
+ pExitBmpsInd->exitBmpsReason = reasonCode;
+ pExitBmpsInd->statusCode = eSIR_SME_SUCCESS;
+
+ mmhMsg.type = eWNI_PMC_EXIT_BMPS_IND;
+ mmhMsg.bodyptr = pExitBmpsInd;
+ mmhMsg.bodyval = 0;
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending eWNI_PMC_EXIT_BMPS_IND to SME. \n"));)
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT, peGetValidPowerSaveSession(pMac), 0, (tANI_U16)reasonCode);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ return;
+
+} /*** end limSendExitBmpsInd() ***/
+
+
+
+
+/*--------------------------------------------------------------------------
+ \brief peDeleteSession() - Handle the Delete BSS Response from HAL.
+
+
+ \param pMac - pointer to global adapter context
+ \param sessionId - Message pointer.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ)
+{
+ tpPESession psessionEntry;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams)(MsgQ->bodyptr);
+ if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ {
+ limIbssDelBssRsp(pMac, MsgQ->bodyptr,psessionEntry);
+ }
+ else if(psessionEntry->limSystemRole == eLIM_UNKNOWN_ROLE)
+ {
+ limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry);
+ }
+
+ else
+ limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry);
+
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/** -----------------------------------------------------------------
+ \brief limSendSmeAggrQosRsp() - sends SME FT AGGR QOS RSP
+ \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+ tANI_U8 smesessionId)
+{
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP;
+ mmhMsg.bodyptr = aggrQosRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+#endif
+
+/** -----------------------------------------------------------------
+ \brief limSendSmePreChannelSwitchInd() - sends an indication to SME
+ before switching channels for spectrum manangement.
+
+ This function sends a eWNI_SME_PRE_SWITCH_CHL_IND to SME.
+
+ \param pMac - global mac structure
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac)
+{
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = eWNI_SME_PRE_SWITCH_CHL_IND;
+ mmhMsg.bodyptr = NULL;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief limSendSmePostChannelSwitchInd() - sends an indication to SME
+ after channel switch for spectrum manangement is complete.
+
+ This function sends a eWNI_SME_POST_SWITCH_CHL_IND to SME.
+
+ \param pMac - global mac structure
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac)
+{
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = eWNI_SME_POST_SWITCH_CHL_IND;
+ mmhMsg.bodyptr = NULL;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+
+void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tANI_U8 smesessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeMaxAssocInd *pSmeMaxAssocInd;
+
+ if(eSIR_SUCCESS !=
+ palAllocateMemory(pMac->hHdd,(void **)&pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+ palZeroMemory(pMac->hHdd, (void *) pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd));
+ palCopyMemory( pMac->hHdd, (tANI_U8 *)pSmeMaxAssocInd->peerMac,
+ (tANI_U8 *)peerMacAddr, sizeof(tSirMacAddr));
+ pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED;
+ pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd);
+ pSmeMaxAssocInd->sessionId = smesessionId;
+ mmhMsg.type = pSmeMaxAssocInd->mesgType;
+ mmhMsg.bodyptr = pSmeMaxAssocInd;
+ PELOG1(limLog(pMac, LOG1, FL("msgType %s peerMacAddr %02x-%02x-%02x-%02x-%02x-%02x"
+ "sme session id %d\n"),"eWNI_SME_MAX_ASSOC_EXCEEDED", peerMacAddr[0], peerMacAddr[1],
+ peerMacAddr[2], peerMacAddr[3], peerMacAddr[4], peerMacAddr[5], smesessionId);)
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+ return;
+}
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
new file mode 100644
index 0000000..d5e8050
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSendSmeRspMessages.h contains the definitions for
+ * sending SME response/notification messages to applications above
+ * MAC software.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_SME_RSP_H
+#define __LIM_SEND_SME_RSP_H
+
+#include "sirCommon.h"
+#include "sirApi.h"
+#include "sirMacProtDef.h"
+
+
+// Functions for sending responses to Host
+void limSendSmeRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U8 , tANI_U16);
+void limSendSmeStartBssRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16);
+void limSendSmeScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16);
+void limPostSmeScanRspMessage(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8,tANI_U16);
+void limSendSmeAuthRsp(tpAniSirGlobal, tSirResultCodes,
+ tSirMacAddr, tAniAuthType, tANI_U16,tpPESession,tANI_U8,tANI_U16);
+
+void limSendSmeJoinReassocRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U16,tpPESession,tANI_U8,tANI_U16);
+void limSendSmeDisassocNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16,tANI_U8,tANI_U16,tpPESession);
+void limSendSmeDeauthNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16, tANI_U8, tANI_U16);
+void limSendSmeDisassocInd(tpAniSirGlobal, tpDphHashNode,tpPESession);
+void limSendSmeDeauthInd(tpAniSirGlobal, tpDphHashNode, tpPESession psessionEntry);
+
+
+
+void limSendSmeWmStatusChangeNtf(tpAniSirGlobal, tSirSmeStatusChangeCode, tANI_U32 *, tANI_U16, tANI_U8);
+void limSendSmeSetContextRsp(tpAniSirGlobal,
+ tSirMacAddr, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16);
+void limSendSmePromiscuousModeRsp(tpAniSirGlobal pMac);
+void limSendSmeNeighborBssInd(tpAniSirGlobal,
+ tLimScanResultNode *);
+#if (WNI_POLARIS_FW_PRODUCT == AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+void limSendSmeMeasurementInd(tpAniSirGlobal);
+#endif
+void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+void
+limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+ tANI_U8 smesessionId);
+#endif /*WLAN_FEATURE_VOWIFI_11R*/
+
+
+void limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry, tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId);
+void limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts);
+void limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smessionId,tANI_U16 smetransactionId);
+void limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession);
+void limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats);
+
+void limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats);
+void limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes resultCode,tpPESession,tANI_U8,tANI_U16);
+
+
+void limSendSmeGetTxPowerRsp(tpAniSirGlobal pMac, tANI_U32 power, tANI_U32 status);
+void limSendSmeGetNoiseRsp(tpAniSirGlobal pMac, tSirMacNoise noise);
+void limSendSmeIBSSPeerInd(tpAniSirGlobal pMac,tSirMacAddr peerMacAddr,tANI_U16 staIndex,tANI_U8 ucastIdx,tANI_U8 bcastIdx,
+ tANI_U8 *beacon,tANI_U16 beaconLen, tANI_U16 msgType, tANI_U8 sessionId);
+void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode);
+
+
+void limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac);
+void limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac);
+void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tANI_U8 smesessionId);
+
+#endif /* __LIM_SEND_SME_RSP_H */
+
diff --git a/CORE/MAC/src/pe/lim/limSerDesUtils.c b/CORE/MAC/src/pe/lim/limSerDesUtils.c
new file mode 100644
index 0000000..b663bea
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSerDesUtils.c
@@ -0,0 +1,4279 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ *
+ * This file limSerDesUtils.cc contains the serializer/deserializer
+ * utility functions LIM uses while communicating with upper layer
+ * software entities
+ * Author: Chandra Modumudi
+ * Date: 10/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "aniSystemDefs.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limSerDesUtils.h"
+
+
+
+/**
+ * limCheckRemainingLength()
+ *
+ *FUNCTION:
+ * This function is called while de-serializing received SME_REQ
+ * message.
+ *
+ *LOGIC:
+ * Remaining message length is checked for > 0.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param len - Remaining message length
+ * @return retCode - eSIR_SUCCESS if len > 0, else eSIR_FAILURE
+ */
+
+static inline tSirRetStatus
+limCheckRemainingLength(tpAniSirGlobal pMac, tANI_S16 len)
+{
+ if (len > 0)
+ return eSIR_SUCCESS;
+ else
+ {
+ limLog(pMac, LOGW,
+ FL("Received SME message with invalid rem length=%d\n"),
+ len);
+ return eSIR_FAILURE;
+ }
+} /*** end limCheckRemainingLength(pMac, ) ***/
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+#else
+/**
+ * limGetBssDescription()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * BSS description from a tANI_U8* buffer pointer to tSirBssDescription
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pBssDescription Pointer to the BssDescription to be copied
+ * @param *pBuf Pointer to the source buffer
+ * @param rLen Remaining message length being extracted
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * failure (eSIR_FAILURE).
+ */
+
+static tSirRetStatus
+limGetBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBssDescription,
+ tANI_S16 rLen, tANI_S16 *lenUsed, tANI_U8 *pBuf)
+{
+ tANI_U16 len = 0;
+
+ pBssDescription->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len = pBssDescription->length;
+
+ if (rLen < (tANI_S16) (len + sizeof(tANI_U16)))
+ return eSIR_FAILURE;
+
+ *lenUsed = len + sizeof(tANI_U16);
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBssDescription->bssId,
+ pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract timer
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) (&pBssDescription->scanSysTimeMsec),
+ pBuf, sizeof(v_TIME_t));
+ pBuf += sizeof(v_TIME_t);
+ len -= sizeof(v_TIME_t);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract timeStamp
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBssDescription->timeStamp,
+ pBuf, sizeof(tSirMacTimeStamp));
+ pBuf += sizeof(tSirMacTimeStamp);
+ len -= sizeof(tSirMacTimeStamp);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract beaconInterval
+ pBssDescription->beaconInterval = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract capabilityInfo
+ pBssDescription->capabilityInfo = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract nwType
+ pBssDescription->nwType = (tSirNwType) limGetU32(pBuf);
+ pBuf += sizeof(tSirNwType);
+ len -= sizeof(tSirNwType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract aniIndicator
+ pBssDescription->aniIndicator = *pBuf++;
+ len --;
+
+ // Extract rssi
+ pBssDescription->rssi = (tANI_S8) *pBuf++;
+ len --;
+
+ // Extract sinr
+ pBssDescription->sinr = (tANI_S8) *pBuf++;
+ len --;
+
+ // Extract channelId
+ pBssDescription->channelId = *pBuf++;
+ len --;
+
+ // Extract channelIdSelf
+ pBssDescription->channelIdSelf = *pBuf++;
+ len --;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract reserved bssDescription
+ pBuf += sizeof(pBssDescription->sSirBssDescriptionRsvd);
+ len -= sizeof(pBssDescription->sSirBssDescriptionRsvd);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract the TITAN capability info
+ // NOTE - titanHtCaps is now DWORD aligned
+ pBssDescription->titanHtCaps = limGetU32( pBuf );
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ //pass the timestamp
+ pBssDescription->nReceivedTime = limGetU32( pBuf );
+ pBuf += sizeof(tANI_TIMESTAMP);
+ len -= sizeof(tANI_TIMESTAMP);
+
+#if defined WLAN_FEATURE_VOWIFI
+ //TSF when the beacon received (parent TSF)
+ pBssDescription->parentTSF = limGetU32( pBuf );
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+
+ //start TSF of scan during which this BSS desc was updated.
+ pBssDescription->startTSF[0] = limGetU32( pBuf );
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+
+ //start TSF of scan during which this BSS desc was updated.
+ pBssDescription->startTSF[1] = limGetU32( pBuf );
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // MobilityDomain
+ pBssDescription->mdiePresent = *pBuf++;
+ len --;
+ pBssDescription->mdie[0] = *pBuf++;
+ len --;
+ pBssDescription->mdie[1] = *pBuf++;
+ len --;
+ pBssDescription->mdie[2] = *pBuf++;
+ len --;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(limLog(pMac, LOGE, FL("mdie=%02x %02x %02x\n"),
+ pBssDescription->mdie[0],
+ pBssDescription->mdie[1],
+ pBssDescription->mdie[2]);)
+#endif
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ pBssDescription->QBSSLoad_present = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract QBSSLoad_avail
+ pBssDescription->QBSSLoad_avail = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+ if (pBssDescription->WscIeLen)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBssDescription->WscIeProbeRsp,
+ pBuf,
+ pBssDescription->WscIeLen);
+ }
+
+ pBuf += (sizeof(pBssDescription->WscIeProbeRsp) +
+ sizeof(pBssDescription->WscIeLen) +
+ sizeof(pBssDescription->fProbeRsp) +
+ sizeof(tANI_U32));
+
+ len -= (sizeof(pBssDescription->WscIeProbeRsp) +
+ sizeof(pBssDescription->WscIeLen) +
+ sizeof(pBssDescription->fProbeRsp) +
+ sizeof(tANI_U32));
+
+ if (len)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBssDescription->ieFields,
+ pBuf,
+ len);
+ }
+
+ return eSIR_SUCCESS;
+} /*** end limGetBssDescription() ***/
+#endif
+
+
+
+/**
+ * limCopyBssDescription()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * BSS description to a tANI_U8 buffer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param pBssDescription Pointer to the BssDescription being copied
+ * @return Length of BSSdescription written
+ */
+
+tANI_U16
+limCopyBssDescription(tpAniSirGlobal pMac, tANI_U8 *pBuf, tSirBssDescription *pBssDescription)
+{
+ tANI_U16 len = 0;
+
+ limCopyU16(pBuf, pBssDescription->length);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+
+ palCopyMemory( pMac->hHdd, pBuf,
+ (tANI_U8 *) pBssDescription->bssId,
+ sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len += sizeof(tSirMacAddr);
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("Copying BSSdescr:channel is %d, aniInd is %d, bssId is "),
+ pBssDescription->channelId, pBssDescription->aniIndicator);
+ limPrintMacAddr(pMac, pBssDescription->bssId, LOG3);)
+
+ palCopyMemory( pMac->hHdd, pBuf,
+ (tANI_U8 *) (&pBssDescription->scanSysTimeMsec),
+ sizeof(v_TIME_t));
+ pBuf += sizeof(v_TIME_t);
+ len += sizeof(v_TIME_t);
+
+ limCopyU32(pBuf, pBssDescription->timeStamp[0]);
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pBssDescription->timeStamp[1]);
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+
+ limCopyU16(pBuf, pBssDescription->beaconInterval);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+
+ limCopyU16(pBuf, pBssDescription->capabilityInfo);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, pBssDescription->nwType);
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+
+ *pBuf++ = pBssDescription->aniIndicator;
+ len++;
+
+ *pBuf++ = pBssDescription->rssi;
+ len++;
+
+ *pBuf++ = pBssDescription->sinr;
+ len++;
+
+ *pBuf++ = pBssDescription->channelId;
+ len++;
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssDescription->ieFields),
+ limGetIElenFromBssDescription(pBssDescription));
+
+ return (len + sizeof(tANI_U16));
+} /*** end limCopyBssDescription() ***/
+
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+/**
+ * limCopyLoad()
+ *
+ *fUNCTION:
+ * This function is called by various LIM functions to copy
+ * load information into a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param load load to be copied to destination buffer
+ *
+ * @return None
+ */
+
+static void
+limCopyLoad(tANI_U8 *pBuf, tSirLoad load)
+{
+ limCopyU16(pBuf, load.numStas);
+ pBuf += sizeof(tANI_U16);
+
+ limCopyU16(pBuf, load.channelUtilization);
+ pBuf += sizeof(tANI_U16);
+} /*** end limCopyLoad() ***/
+
+
+
+/**
+ * limGetLoad()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * load information into a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pLoad Pointer to load being copied to
+ * @param *pBuf Pointer to the source buffer
+ *
+ * @return None
+ */
+
+static void
+limGetLoad(tSirLoad *pLoad, tANI_U8 *pBuf)
+{
+ pLoad->numStas = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pLoad->channelUtilization = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+} /*** end limGetLoad() ***/
+
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * limCopyWdsInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * WdsInfo information into a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param wdsInfo WdsInfo to be copied to destination buffer
+ *
+ * @return Length of WDS info copied
+ */
+
+static tANI_U16
+limCopyWdsInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tpSirWdsInfo pWdsInfo)
+{
+ limCopyU16(pBuf, pWdsInfo->wdsLength);
+ pBuf += sizeof(tANI_U16);
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) pWdsInfo->wdsBytes, pWdsInfo->wdsLength);
+ pBuf += pWdsInfo->wdsLength;
+
+ return ((tANI_U16) (sizeof(tANI_U16) + pWdsInfo->wdsLength));
+} /*** end limCopyWdsInfo() ***/
+
+
+
+/**
+ * limGetWdsInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * WdsInfo information from a tANI_U8* buffer pointer to tSirWdsInfo
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param wdsInfo Pointer to the WdsInfo to be copied
+ * @param *pBuf Pointer to the source buffer
+ *
+ * @return true when WDS info extracted successfully else false
+ */
+
+static tANI_U8
+limGetWdsInfo(tpAniSirGlobal pMac, tpSirWdsInfo pWdsInfo, tANI_U8 *pBuf)
+{
+ pWdsInfo->wdsLength = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (pWdsInfo->wdsLength > ANI_WDS_INFO_MAX_LENGTH)
+ return false;
+
+ palCopyMemory( pMac->hHdd, pWdsInfo->wdsBytes, pBuf, pWdsInfo->wdsLength);
+
+ return true;
+} /*** end limGetWdsInfo() ***/
+
+
+
+/**
+ * limGetAlternateRadioList()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * alternateRadio information from a tANI_U8* buffer pointer to
+ * tSirAlternateRadioList
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pRadioList Pointer to the radioList to be copied
+ * @param *pBuf Pointer to the source buffer
+ *
+ * @return len Length of copied alternateRadioList
+ */
+
+static tANI_U16
+limGetAlternateRadioList(tpAniSirGlobal pMac, tpSirMultipleAlternateRadioInfo pRadioList,
+ tANI_U8 *pBuf)
+{
+ tANI_U8 i;
+ tANI_U16 len = sizeof(tANI_U8);
+ tpSirAlternateRadioInfo pRadioInfo;
+
+ pRadioList->numBss = *pBuf++;
+
+ if (pRadioList->numBss > SIR_MAX_NUM_ALTERNATE_RADIOS)
+ pRadioList->numBss = SIR_MAX_NUM_ALTERNATE_RADIOS;
+
+ pRadioInfo = pRadioList->alternateRadio;
+ for (i = 0; i < pRadioList->numBss; i++)
+ {
+ palCopyMemory( pMac->hHdd, pRadioInfo->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ pRadioInfo->channelId = *pBuf++;
+ PELOG3(limLog(pMac, LOG3, FL("Alternate radio[%d] channelId=%d, BssId is \n"),
+ i, pRadioInfo->channelId);
+ limPrintMacAddr(pMac, pRadioInfo->bssId, LOG3);)
+
+ pRadioInfo++;
+ len += sizeof(tSirMacAddr) + sizeof(tANI_U8);
+ }
+
+ return len;
+} /*** end limGetAlternateRadioList() ***/
+#endif
+
+
+
+/**
+ * limCopyNeighborBssInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * Neighbor BSS info into a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param pBssInfo Pointer to neighbor BSS info be copied
+ * to destination buffer
+ *
+ * @return bssInfoLen Length of bssInfo copied
+ */
+
+tANI_U32
+limCopyNeighborBssInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tpSirNeighborBssInfo pBssInfo)
+{
+ tANI_U32 bssInfoLen = 0;
+
+ palCopyMemory( pMac->hHdd, pBuf,
+ (tANI_U8 *) pBssInfo->bssId,
+ sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ bssInfoLen += sizeof(tSirMacAddr);
+ PELOG3(limLog(pMac, LOG3,
+ FL("Copying new NeighborWds node:channel is %d, TITAN HT Caps are %1d, wniIndicator is %d, bssType is %d, bssId is "),
+ pBssInfo->channelId, pBssInfo->titanHtCaps, pBssInfo->wniIndicator,
+ pBssInfo->bssType);
+ limPrintMacAddr(pMac, pBssInfo->bssId, LOG3);)
+
+ *pBuf++ = pBssInfo->channelId;
+ bssInfoLen++;
+
+ *pBuf++ = pBssInfo->titanHtCaps;
+ bssInfoLen++;
+
+ limCopyU32(pBuf, pBssInfo->wniIndicator);
+ pBuf += sizeof(tANI_U32);
+ bssInfoLen += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pBssInfo->bssType);
+ pBuf += sizeof(tANI_U32);
+ bssInfoLen += sizeof(tANI_U32);
+
+ *pBuf++ = pBssInfo->sinr;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->rssi;
+ bssInfoLen++;
+
+ limCopyLoad(pBuf, pBssInfo->load);
+ pBuf += sizeof(tSirLoad);
+ bssInfoLen += sizeof(tSirLoad);
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssInfo->ssId),
+ pBssInfo->ssId.length + 1);
+
+ bssInfoLen += pBssInfo->ssId.length + 1;
+ pBuf += pBssInfo->ssId.length + 1;
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssInfo->apName),
+ pBssInfo->apName.length + 1);
+
+ bssInfoLen += pBssInfo->apName.length + 1;
+ pBuf += pBssInfo->apName.length + 1;
+
+ limCopyU16(pBuf, pBssInfo->rsnIE.length);
+ pBuf += sizeof(tANI_U16);
+ bssInfoLen += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssInfo->rsnIE.rsnIEdata),
+ pBssInfo->rsnIE.length);
+
+ bssInfoLen += pBssInfo->rsnIE.length;
+ pBuf += pBssInfo->rsnIE.length;
+
+ limCopyU32(pBuf, pBssInfo->nwType);
+ pBuf += sizeof(tANI_U32);
+ bssInfoLen += sizeof(tANI_U32);
+
+ // not sure we need to do a sirSwapU16ifNeeded ???
+ limCopyU16(pBuf, pBssInfo->capabilityInfo);
+ pBuf += sizeof(tANI_U16);
+ bssInfoLen += sizeof(tANI_U16);
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssInfo->operationalRateSet),
+ pBssInfo->operationalRateSet.numRates + 1);
+ bssInfoLen += pBssInfo->operationalRateSet.numRates + 1;
+ pBuf += pBssInfo->operationalRateSet.numRates + 1;
+
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pBssInfo->extendedRateSet),
+ pBssInfo->extendedRateSet.numRates + 1);
+ bssInfoLen += pBssInfo->extendedRateSet.numRates + 1;
+ pBuf += pBssInfo->extendedRateSet.numRates + 1;
+
+ limCopyU16(pBuf, pBssInfo->beaconInterval);
+ pBuf += sizeof(tANI_U16);
+ bssInfoLen += sizeof(tANI_U16);
+
+ *pBuf++ = pBssInfo->dtimPeriod;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->HTCapsPresent;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->HTInfoPresent;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->wmeInfoPresent;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->wmeEdcaPresent;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->wsmCapablePresent;
+ bssInfoLen++;
+ *pBuf++ = pBssInfo->hcfEnabled;
+ bssInfoLen++;
+
+ limCopyU16(pBuf, pBssInfo->propIECapability);
+ pBuf += sizeof(tANI_U16);
+ bssInfoLen += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, pBssInfo->localPowerConstraints);
+ pBuf += sizeof(tANI_S32);
+ bssInfoLen += sizeof(tANI_S32);
+
+ limCopyU32(pBuf, pBssInfo->aggrRssi);
+ pBuf += sizeof(tANI_S32);
+ bssInfoLen += sizeof(tANI_S32);
+
+ limCopyU32(pBuf, pBssInfo->dataCount);
+ pBuf += sizeof(tANI_U32);
+ bssInfoLen += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pBssInfo->totalPackets);
+ pBuf += sizeof(tANI_U32);
+ bssInfoLen += sizeof(tANI_U32);
+
+ return bssInfoLen;
+} /*** end limCopyNeighborBssInfo() ***/
+
+
+/**
+ * limCopyNeighborList()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * Neighbor BSS list into a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param neighborList Neighbor BSS list be copied to
+ * destination buffer
+ * @param numBss Number of Neighbor BSS list be copied
+ *
+ * @return listLen Length of Neighbor BSS list
+ */
+
+static tANI_U32
+limCopyNeighborList(tpAniSirGlobal pMac, tANI_U8 *pBuf, tpSirNeighborBssInfo pBssInfo, tANI_U32 numBss)
+{
+ tANI_U32 bssInfoLen = 0, listLen = 0;
+ tANI_U8 i;
+ tANI_U8 *pTemp = (tANI_U8 *) pBssInfo;
+
+ PELOG3(limLog(pMac, LOG3, FL("Going to copy BssInfoList:\n"));)
+ PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3,
+ pTemp, numBss*sizeof(tSirNeighborBssInfo));)
+
+ for (i = 0; i < numBss; i++, bssInfoLen = 0)
+ {
+ bssInfoLen = limCopyNeighborBssInfo(pMac,
+ pBuf,
+ (tpSirNeighborBssInfo) &pBssInfo[i]);
+
+ pBuf += bssInfoLen;
+ listLen += bssInfoLen;
+ }
+
+ return listLen;
+} /*** end limCopyNeighborList(pMac, ) ***/
+
+
+/**
+ * limGetNeighborBssInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to get
+ * Neighbor BSS info from a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pBssInfo Pointer to neighbor BSS info being copied
+ * @param *pBuf Pointer to the source buffer
+ *
+ * @return Size of NeighborBssInfo that is extracted
+ */
+
+tANI_U32
+limGetNeighborBssInfo(tpAniSirGlobal pMac, tpSirNeighborBssInfo pBssInfo, tANI_U8 *pBuf)
+{
+ tANI_U32 len = 0;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pBssInfo->bssId,
+ pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len += sizeof(tSirMacAddr);
+
+ pBssInfo->channelId = *pBuf++;
+ len++;
+
+ pBssInfo->wniIndicator = (tAniBool) limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len += sizeof(tAniBool);
+
+ pBssInfo->bssType = (tSirBssType) limGetU32(pBuf);
+ pBuf += sizeof(tSirBssType);
+ len += sizeof(tSirBssType);
+
+ pBssInfo->sinr = *pBuf++;
+ len++;
+ pBssInfo->rssi = *pBuf++;
+ len++;
+
+ limGetLoad(&pBssInfo->load, pBuf);
+ pBuf += sizeof(tSirLoad);
+ len += sizeof(tSirLoad);
+
+ pBssInfo->ssId.length = *pBuf++;
+ palCopyMemory( pMac->hHdd, pBssInfo->ssId.ssId, pBuf, pBssInfo->ssId.length);
+ pBuf += pBssInfo->ssId.length;
+ len += pBssInfo->ssId.length + 1;
+
+ pBssInfo->apName.length = *pBuf++;
+ palCopyMemory( pMac->hHdd, pBssInfo->apName.name, pBuf, pBssInfo->apName.length);
+ pBuf += pBssInfo->apName.length;
+ len += pBssInfo->apName.length + 1;
+
+ pBssInfo->rsnIE.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pBssInfo->rsnIE.rsnIEdata, pBuf,
+ pBssInfo->rsnIE.length);
+ pBuf += pBssInfo->rsnIE.length;
+ len += pBssInfo->rsnIE.length + 2;
+
+ PELOG2(limLog(pMac, LOG2, FL("BSS type %d channel %d wniInd %d RSN len %d\n"),
+ pBssInfo->bssType, pBssInfo->channelId, pBssInfo->wniIndicator,
+ pBssInfo->rsnIE.length);
+ limPrintMacAddr(pMac, pBssInfo->bssId, LOG2);)
+
+
+ pBssInfo->nwType = (tSirNwType) limGetU32(pBuf);
+ pBuf += sizeof(tSirNwType);
+ len += sizeof(tSirNwType);
+
+ pBssInfo->capabilityInfo = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+
+ pBssInfo->operationalRateSet.numRates = *pBuf++;
+ palCopyMemory( pMac->hHdd, pBssInfo->operationalRateSet.rate, pBuf,
+ pBssInfo->operationalRateSet.numRates);
+ pBuf += pBssInfo->operationalRateSet.numRates;
+ len += pBssInfo->operationalRateSet.numRates + 1;
+
+ pBssInfo->extendedRateSet.numRates = *pBuf++;
+ palCopyMemory( pMac->hHdd, pBssInfo->extendedRateSet.rate, pBuf,
+ pBssInfo->extendedRateSet.numRates);
+ pBuf += pBssInfo->extendedRateSet.numRates;
+ len += pBssInfo->extendedRateSet.numRates + 1;
+
+ pBssInfo->beaconInterval = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+
+ pBssInfo->dtimPeriod = *pBuf++;
+ pBssInfo->HTCapsPresent = *pBuf++;
+ pBssInfo->HTInfoPresent = *pBuf++;
+ pBssInfo->wmeInfoPresent = *pBuf++;
+ pBssInfo->wmeEdcaPresent = *pBuf++;
+ pBssInfo->wsmCapablePresent = *pBuf++;
+ pBssInfo->hcfEnabled = *pBuf++;
+ pBssInfo->propIECapability = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ pBssInfo->localPowerConstraints = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len += 13;
+
+ PELOG2(limLog(pMac, LOG2, FL("rsnIELen %d operRateLen %d extendRateLen %d total %d\n"),
+ pBssInfo->rsnIE.length, pBssInfo->operationalRateSet.numRates,
+ pBssInfo->extendedRateSet.numRates, len);)
+
+
+ return len;
+} /*** end limGetNeighborBssInfo() ***/
+
+
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * limGetNeighborBssList()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to get
+ * Neighbor BSS list from a tANI_U8* buffer pointer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pNeighborList Pointer to neighbor BSS list being copied to
+ * @param *pBuf Pointer to the source buffer
+ * @param rLen Remaining message length being extracted
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * failure (eSIR_FAILURE).
+ */
+
+static tSirRetStatus
+limGetNeighborBssList(tpAniSirGlobal pMac,
+ tSirNeighborBssList *pNeighborList,
+ tANI_S16 rLen, tANI_S16 *lenUsed, tANI_U8 *pBuf)
+{
+ tANI_U8 *pBssInfo = (tANI_U8 *) pNeighborList->bssList;
+ tANI_U32 i, bssInfoLen = 0, len = 0, numBss, numBssList;
+
+ numBssList = numBss = limGetU32(pBuf);
+
+ if (!numBss)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("No Neighbor BSS present in Neighbor list\n"));)
+
+ return eSIR_FAILURE;
+ }
+ PELOG2(limLog(pMac, LOG2,
+ FL("Num of Neighbor BSS present in Neighbor list is %d\n"),
+ numBss);)
+
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+ rLen -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, rLen) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // First neighborInfo is the one we're attempting to join/reassoc
+ bssInfoLen = limGetNeighborBssInfo(pMac, (tSirNeighborBssInfo *) pBssInfo,
+ pBuf);
+ PELOG1(limLog(pMac, LOG1,
+ FL("BSSinfo len to be joined is %d rem %d, numBss = %d\n"),
+ bssInfoLen, rLen, numBss - 1);)
+ pBuf += bssInfoLen;
+ len += bssInfoLen;
+ rLen -= (tANI_S16) bssInfoLen;
+ numBss--;
+ numBssList--;
+
+ if (numBss > 0)
+ {
+ // Store remaining neighbor BSS info
+ if (numBss > SIR_MAX_NUM_NEIGHBOR_BSS)
+ {
+ // Store only MAX number of Neighbor BSS
+ PELOG2(limLog(pMac, LOG2,
+ FL("Pruning number of neighbors to %d from %d\n"),
+ SIR_MAX_NUM_NEIGHBOR_BSS, numBss);)
+ numBss = SIR_MAX_NUM_NEIGHBOR_BSS;
+ }
+
+ pBssInfo = (tANI_U8 *) pMac->lim.gLimNeighborBssList.bssList;
+ for (i = numBss; i > 0; i--)
+ {
+ PELOG3(limLog(pMac, LOG3, FL("pMac = %p, pBssInfo = %p, pBuf = %p\n"), pMac, pBssInfo, pBuf);)
+ bssInfoLen = limGetNeighborBssInfo(pMac,
+ (tSirNeighborBssInfo *) pBssInfo,
+ pBuf);
+
+ pBssInfo += sizeof(tSirNeighborBssInfo);
+ pBuf += bssInfoLen;
+ len += bssInfoLen;
+ rLen -= (tANI_S16) bssInfoLen;
+ numBssList--;
+
+ PELOG1(limLog(pMac, LOG1, FL("BSS info[%d] len %d rem %d\n"),
+ i, bssInfoLen, rLen);)
+ }
+
+ while (numBssList > 0)
+ {
+ tSirNeighborBssInfo pTemp;
+ bssInfoLen = limGetNeighborBssInfo(pMac, &pTemp, pBuf);
+ pBuf += bssInfoLen;
+ len += bssInfoLen;
+ rLen -= (tANI_S16) bssInfoLen;
+ numBssList--;
+ PELOG1(limLog(pMac, LOG1, FL("BSS info[%d] len %d rem %d\n"),
+ numBssList, bssInfoLen, rLen);)
+ }
+ }
+ *lenUsed = len;
+
+ pMac->lim.gLimNeighborBssList.numBss = pNeighborList->numBss
+ = numBss;
+
+ return eSIR_SUCCESS;
+} /*** end limGetNeighborBssList(pMac, ) ***/
+
+
+
+/**
+ * limCopyNeighborWdsInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * detected neighborBssWds info to a tANI_U8 buffer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param *pInfo Pointer to the NeighborWdsInfo being copied
+ * @return Length of Matrix information copied
+ */
+
+static tANI_U16
+limCopyNeighborWdsInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tpSirNeighborBssWdsInfo pInfo)
+{
+ tANI_U16 len = 0;
+
+ len = (tANI_U16) limCopyNeighborBssInfo(pMac, pBuf, &pInfo->neighborBssInfo);
+ pBuf += len;
+ len += limCopyWdsInfo(pMac, pBuf, &pInfo->wdsInfo);
+
+ return len;
+} /*** end limCopyNeighborWdsInfo() ***/
+
+
+
+/**
+ * limCopyMeasMatrixInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * collected Measurement matrix info to a tANI_U8 buffer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pBuf Pointer to the destination buffer
+ * @param *pInfo Pointer to the matrix info being copied
+ * @return Length of Matrix information copied
+ */
+
+static tANI_U16
+limCopyMeasMatrixInfo(tANI_U8 *pBuf, tpLimMeasMatrixNode pInfo)
+{
+ tANI_U16 len = 0;
+
+ *pBuf++ = pInfo->matrix.channelNumber;
+ len++;
+ *pBuf++ = pInfo->matrix.compositeRssi;
+ len++;
+ limCopyU32(pBuf, pInfo->matrix.aggrRssi);
+ pBuf += sizeof(tANI_S32);
+ len += sizeof(tANI_S32);
+ limCopyU32(pBuf, pInfo->matrix.totalPackets);
+ len += sizeof(tANI_U32);
+
+ return len;
+} /*** end limCopyMeasMatrixInfo() ***/
+
+
+
+/**
+ * limCopyMeasMatrixList()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * collected Measurement matrix List to a tANI_U8 buffer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pBuf - Pointer to the destination buffer
+ * @return Length of matrix list copied
+ */
+
+static tANI_U16
+limCopyMeasMatrixList(tpAniSirGlobal pMac, tANI_U8 *pBuf)
+{
+ tANI_U16 len = 0, nodeLen = 0;
+ tANI_U8 numNodes = pMac->lim.gpLimMeasData->numMatrixNodes;
+
+ *pBuf++ = numNodes;
+ len++;
+
+ if (numNodes)
+ {
+ tpLimMeasMatrixNode pInfo =
+ pMac->lim.gpLimMeasData->pMeasMatrixInfo;
+ while (numNodes-- && pInfo) //Safety measure, checking both
+ {
+ nodeLen = limCopyMeasMatrixInfo(pBuf, pInfo);
+ pBuf += nodeLen;
+ len += nodeLen;
+
+ if (pInfo->next)
+ pInfo = pInfo->next;
+ else
+ break;
+ }
+
+ return len;
+ }
+ else
+ {
+ *pBuf = 0;
+ return 1;
+ }
+} /*** end limCopyMeasMatrixList() ***/
+
+
+
+/**
+ * limCopyNeighborWdsList()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * detected neighborBssWds List to a tANI_U8 buffer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pBuf Pointer to the destination buffer
+ * @return Length of matrix list copied
+ */
+
+static tANI_U16
+limCopyNeighborWdsList(tpAniSirGlobal pMac, tANI_U8 *pBuf)
+{
+ tANI_U16 len = 0, nodeLen = 0;
+
+ if (pMac->lim.gpLimMeasData->numBssWds)
+ {
+ limCopyU32(pBuf, pMac->lim.gpLimMeasData->numBssWds);
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+
+ tpLimNeighborBssWdsNode pInfo =
+ pMac->lim.gpLimMeasData->pNeighborWdsInfo;
+ while (pInfo)
+ {
+ nodeLen = limCopyNeighborWdsInfo(pMac, pBuf, &pInfo->info);
+ pBuf += nodeLen;
+ len += nodeLen;
+
+ if (pInfo->next)
+ pInfo = pInfo->next;
+ else
+ break;
+ }
+
+ return len;
+ }
+ else
+ {
+ limCopyU32(pBuf, 0);
+ return (sizeof(tANI_U32));
+ }
+} /*** end limCopyNeighborWdsList() ***/
+#endif
+#endif
+
+
+/**
+ * limGetKeysInfo()
+ *
+ *FUNCTION:
+ * This function is called by various LIM functions to copy
+ * key information from a tANI_U8* buffer pointer to tSirKeys
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param *pKeyInfo Pointer to the keyInfo to be copied
+ * @param *pBuf Pointer to the source buffer
+ *
+ * @return Length of key info extracted
+ */
+
+static tANI_U32
+limGetKeysInfo(tpAniSirGlobal pMac, tpSirKeys pKeyInfo, tANI_U8 *pBuf)
+{
+ tANI_U32 len = 0;
+
+ pKeyInfo->keyId = *pBuf++;
+ len++;
+ pKeyInfo->unicast = *pBuf++;
+ len++;
+ pKeyInfo->keyDirection = (tAniKeyDirection) limGetU32(pBuf);
+ len += sizeof(tAniKeyDirection);
+ pBuf += sizeof(tAniKeyDirection);
+
+ palCopyMemory( pMac->hHdd, pKeyInfo->keyRsc, pBuf, WLAN_MAX_KEY_RSC_LEN);
+ pBuf += WLAN_MAX_KEY_RSC_LEN;
+ len += WLAN_MAX_KEY_RSC_LEN;
+
+ pKeyInfo->paeRole = *pBuf++;
+ len++;
+
+ pKeyInfo->keyLength = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pKeyInfo->key, pBuf, pKeyInfo->keyLength);
+ pBuf += pKeyInfo->keyLength;
+ len += pKeyInfo->keyLength;
+
+ PELOG3(limLog(pMac, LOG3,
+ FL("Extracted keyId=%d, keyLength=%d, Key is :\n"),
+ pKeyInfo->keyId, pKeyInfo->keyLength);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3,
+ pKeyInfo->key, pKeyInfo->keyLength);)
+
+ return len;
+} /*** end limGetKeysInfo() ***/
+
+
+
+/**
+ * limStartBssReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_START_BSS_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pStartBssReq Pointer to tSirSmeStartBssReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limStartBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStartBssReq pStartBssReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ tANI_U8 i;
+#endif
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pStartBssReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pStartBssReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pStartBssReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_START_BSS_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pStartBssReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pStartBssReq->transactionId = limGetU16( pBuf );
+ pBuf += sizeof( tANI_U16 );
+ len -= sizeof( tANI_U16 );
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStartBssReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract selfMacAddr
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStartBssReq->selfMacAddr, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract beaconInterval
+ pStartBssReq->beaconInterval = limGetU16( pBuf );
+ pBuf += sizeof( tANI_U16 );
+ len -= sizeof( tANI_U16 );
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract dot11Mode
+ pStartBssReq->dot11mode = *pBuf++;
+ len --;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssType
+ pStartBssReq->bssType = (tSirBssType) limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract ssId
+ if (*pBuf > SIR_MAC_MAX_SSID_LENGTH)
+ {
+ // SSID length is more than max allowed 32 bytes
+ PELOGW(limLog(pMac, LOGW, FL("Invalid SSID length, len=%d\n"), *pBuf);)
+ return eSIR_FAILURE;
+ }
+
+ pStartBssReq->ssId.length = *pBuf++;
+ len--;
+ if (len < pStartBssReq->ssId.length)
+ {
+ limLog(pMac, LOGW,
+ FL("SSID length is longer that the remaining length. SSID len=%d, remaining len=%d\n"),
+ pStartBssReq->ssId.length, len);
+ return eSIR_FAILURE;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStartBssReq->ssId.ssId,
+ pBuf,
+ pStartBssReq->ssId.length);
+ pBuf += pStartBssReq->ssId.length;
+ len -= pStartBssReq->ssId.length;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract channelId
+ pStartBssReq->channelId = *pBuf++;
+ len--;
+
+ // Extract CB secondary channel info
+ pStartBssReq->cbMode = (tAniCBSecondaryMode)limGetU32( pBuf );
+ pBuf += sizeof( tANI_U32 );
+ len -= sizeof( tANI_U32 );
+
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ tANI_U16 paramLen = 0;
+
+ // Extract alternateRadioList
+ pStartBssReq->alternateRadioList.numBss = *pBuf;
+ paramLen = limGetAlternateRadioList(pMac,
+ &pMac->lim.gLimAlternateRadioList,
+ pBuf);
+ pBuf += paramLen;
+ len -= paramLen;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract powerLevel
+ pStartBssReq->powerLevel = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract wdsInfo
+ if (limGetWdsInfo(pMac, &pStartBssReq->wdsInfo, pBuf) == false)
+ {
+ limLog(pMac, LOGW, FL("Invalid WDS length %d in SME_START_BSS_REQ\n"),
+ pStartBssReq->wdsInfo.wdsLength);
+ return eSIR_FAILURE;
+ }
+
+ pBuf += sizeof(tANI_U16) + pStartBssReq->wdsInfo.wdsLength;
+ len -= (sizeof(tANI_U16) + pStartBssReq->wdsInfo.wdsLength);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+ // Extract privacy setting
+ pStartBssReq->privacy = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ //Extract Uapsd Enable
+ pStartBssReq->apUapsdEnable = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ //Extract SSID hidden
+ pStartBssReq->ssidHidden = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pStartBssReq->fwdWPSPBCProbeReq = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ //Extract HT Protection Enable
+ pStartBssReq->protEnabled = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ //Extract OBSS Protection Enable
+ pStartBssReq->obssProtEnabled = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pStartBssReq->ht_capab = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract AuthType
+ pStartBssReq->authType = (tSirBssType) limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract dtimPeriod
+ pStartBssReq->dtimPeriod = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract wps state
+ pStartBssReq->wps_state = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#endif
+ // Extract bssPersona
+ pStartBssReq->bssPersona = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract rsnIe
+ pStartBssReq->rsnIE.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ // Check for RSN IE length (that includes length of type & length
+ if (pStartBssReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2)
+ {
+ limLog(pMac, LOGW,
+ FL("Invalid RSN IE length %d in SME_START_BSS_REQ\n"),
+ pStartBssReq->rsnIE.length);
+ return eSIR_FAILURE;
+ }
+
+ palCopyMemory( pMac->hHdd, pStartBssReq->rsnIE.rsnIEdata,
+ pBuf, pStartBssReq->rsnIE.length);
+
+ len -= (sizeof(tANI_U16) + pStartBssReq->rsnIE.length);
+ pBuf += pStartBssReq->rsnIE.length;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract nwType
+ pStartBssReq->nwType = (tSirNwType) limGetU32(pBuf);
+ pBuf += sizeof(tSirNwType);
+ len -= sizeof(tSirNwType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract operationalRateSet
+ pStartBssReq->operationalRateSet.numRates = *pBuf++;
+
+ // Check for number of rates
+ if (pStartBssReq->operationalRateSet.numRates >
+ SIR_MAC_MAX_NUMBER_OF_RATES)
+ {
+ limLog(pMac, LOGW, FL("Invalid numRates %d in SME_START_BSS_REQ\n"),
+ pStartBssReq->operationalRateSet.numRates);
+ return eSIR_FAILURE;
+ }
+
+ len--;
+ if (len < pStartBssReq->operationalRateSet.numRates)
+ return eSIR_FAILURE;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStartBssReq->operationalRateSet.rate,
+ pBuf,
+ pStartBssReq->operationalRateSet.numRates);
+ pBuf += pStartBssReq->operationalRateSet.numRates;
+ len -= pStartBssReq->operationalRateSet.numRates;
+
+ // Extract extendedRateSet
+ if ((pStartBssReq->nwType == eSIR_11G_NW_TYPE) ||
+ (pStartBssReq->nwType == eSIR_11N_NW_TYPE ))
+ {
+ pStartBssReq->extendedRateSet.numRates = *pBuf++;
+ len--;
+ palCopyMemory( pMac->hHdd, pStartBssReq->extendedRateSet.rate,
+ pBuf, pStartBssReq->extendedRateSet.numRates);
+ pBuf += pStartBssReq->extendedRateSet.numRates;
+ len -= pStartBssReq->extendedRateSet.numRates;
+ }
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ limLog(pMac,
+ LOGW,
+ FL("Going to parse numSSID in the START_BSS_REQ, len=%d\n"), len);
+ if (len < 2)
+ {
+ // No numSSID parameter in the START_BSS_REQ
+ limLog(pMac,
+ LOGW,
+ FL("No numSSID in the START_BSS_REQ, len=%d\n"), len);
+ return eSIR_FAILURE;
+ }
+
+ // Extract numSSID
+ pStartBssReq->numSSID = *pBuf++;
+ len--;
+
+ // Extract ssIdList[]
+ for (i = 0; (i < pStartBssReq->numSSID) && len; i++)
+ {
+ pStartBssReq->ssIdList[i].length = *pBuf++;
+ len--;
+ if (len < pStartBssReq->ssIdList[i].length)
+ {
+ limLog(pMac, LOGW,
+ FL("SSID length[%d] is more than the rem length[%d]\n"),
+ pStartBssReq->ssIdList[i].length, len);
+ return eSIR_FAILURE;
+ }
+
+ if (pStartBssReq->ssIdList[i].length > SIR_MAC_MAX_SSID_LENGTH)
+ {
+ // SSID length is more than max allowed 32 bytes
+ limLog(pMac,
+ LOGW,
+ FL("Invalid SSID length in the list, len=%d\n"),
+ pStartBssReq->ssIdList[i].length);
+ return eSIR_FAILURE;
+ }
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStartBssReq->ssIdList[i].ssId,
+ pBuf,
+ pStartBssReq->ssIdList[i].length);
+ pBuf += pStartBssReq->ssIdList[i].length;
+ len -= pStartBssReq->ssIdList[i].length;
+ }
+#endif
+
+ if (len)
+ {
+ limLog(pMac, LOGW, FL("Extra bytes left in SME_START_BSS_REQ, len=%d\n"), len);
+ }
+
+ return eSIR_SUCCESS;
+} /*** end limStartBssReqSerDes() ***/
+
+
+
+/**
+ * limStopBssReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_STOP_BSS_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pStopBssReq Pointer to tSirSmeStopBssReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limStopBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStopBssReq pStopBssReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ pStopBssReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pStopBssReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_STOP_BSS_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pStopBssReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pStopBssReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+ // Extract reasonCode
+ pStopBssReq->reasonCode = (tSirResultCodes) limGetU32(pBuf);
+ pBuf += sizeof(tSirResultCodes);
+ len -= sizeof(tSirResultCodes);
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pStopBssReq->bssId, pBuf, sizeof(tSirMacAddr));
+ len -= sizeof(tSirMacAddr);
+
+ if (len)
+ return eSIR_FAILURE;
+ else
+ return eSIR_SUCCESS;
+
+} /*** end limStopBssReqSerDes() ***/
+
+
+
+/**
+ * limJoinReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_JOIN_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pJoinReq Pointer to tSirSmeJoinReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limJoinReqSerDes(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+ tANI_S16 lenUsed = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pJoinReq || !pBuf)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("NULL ptr received\n"));)
+ return eSIR_FAILURE;
+ }
+
+ // Extract messageType
+ pJoinReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ // Extract length
+ len = pJoinReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (pJoinReq->messageType == eWNI_SME_JOIN_REQ)
+ PELOG1(limLog(pMac, LOG3, FL("SME_JOIN_REQ length %d bytes is:\n"), len);)
+ else
+ PELOG1(limLog(pMac, LOG3, FL("SME_REASSOC_REQ length %d bytes is:\n"), len);)
+
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("len too short %d\n"), len);)
+ return eSIR_FAILURE;
+ }
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pJoinReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pJoinReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract ssId
+ pJoinReq->ssId.length = *pBuf++;
+ len--;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->ssId.ssId, pBuf, pJoinReq->ssId.length);
+ pBuf += pJoinReq->ssId.length;
+ len -= pJoinReq->ssId.length;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract selfMacAddr
+ palCopyMemory( pMac->hHdd, pJoinReq->selfMacAddr, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bsstype
+ pJoinReq->bsstype = (tSirBssType) limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract dot11mode
+ pJoinReq->dot11mode= *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssPersona
+ pJoinReq->staPersona = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract uapsdPerAcBitmask
+ pJoinReq->uapsdPerAcBitmask = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ // Extract assocType
+ pJoinReq->assocType = (tSirAssocType) limGetU32(pBuf);
+ pBuf += sizeof(tSirAssocType);
+ len -= sizeof(tSirAssocType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+ // Extract operationalRateSet
+ pJoinReq->operationalRateSet.numRates= *pBuf++;
+ len--;
+ if (pJoinReq->operationalRateSet.numRates)
+ {
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->operationalRateSet.rate, pBuf, pJoinReq->operationalRateSet.numRates);
+ pBuf += pJoinReq->operationalRateSet.numRates;
+ len -= pJoinReq->operationalRateSet.numRates;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+
+ // Extract extendedRateSet
+ pJoinReq->extendedRateSet.numRates = *pBuf++;
+ len--;
+ if (pJoinReq->extendedRateSet.numRates)
+ {
+ palCopyMemory( pMac->hHdd, pJoinReq->extendedRateSet.rate, pBuf, pJoinReq->extendedRateSet.numRates);
+ pBuf += pJoinReq->extendedRateSet.numRates;
+ len -= pJoinReq->extendedRateSet.numRates;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+
+ // Extract RSN IE
+ pJoinReq->rsnIE.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+ if (pJoinReq->rsnIE.length)
+ {
+ // Check for RSN IE length (that includes length of type & length)
+ if ((pJoinReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2) ||
+ (pJoinReq->rsnIE.length != 2 + *(pBuf + 1)))
+ {
+ limLog(pMac, LOGW,
+ FL("Invalid RSN IE length %d in SME_JOIN_REQ\n"),
+ pJoinReq->rsnIE.length);
+ return eSIR_FAILURE;
+ }
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->rsnIE.rsnIEdata,
+ pBuf, pJoinReq->rsnIE.length);
+ pBuf += pJoinReq->rsnIE.length;
+ len -= pJoinReq->rsnIE.length; // skip RSN IE
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+
+#ifdef FEATURE_WLAN_CCX
+ // Extract CCKM IE
+ pJoinReq->cckmIE.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (pJoinReq->cckmIE.length)
+ {
+ // Check for CCKM IE length (that includes length of type & length)
+ if ((pJoinReq->cckmIE.length > SIR_MAC_MAX_IE_LENGTH) ||
+ (pJoinReq->cckmIE.length != (2 + *(pBuf + 1))))
+ {
+ limLog(pMac, LOGW,
+ FL("Invalid CCKM IE length %d/%d in SME_JOIN/REASSOC_REQ\n"),
+ pJoinReq->cckmIE.length, 2 + *(pBuf + 1));
+ return eSIR_FAILURE;
+ }
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->cckmIE.cckmIEdata,
+ pBuf, pJoinReq->cckmIE.length);
+ pBuf += pJoinReq->cckmIE.length;
+ len -= pJoinReq->cckmIE.length; // skip CCKM IE
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+#endif
+
+ // Extract Add IE for scan
+ pJoinReq->addIEScan.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+ if (pJoinReq->addIEScan.length)
+ {
+ // Check for IE length (that includes length of type & length)
+ if (pJoinReq->addIEScan.length > SIR_MAC_MAX_IE_LENGTH + 2)
+ {
+ limLog(pMac, LOGE,
+ FL("Invalid addIE Scan length %d in SME_JOIN_REQ\n"),
+ pJoinReq->addIEScan.length);
+ return eSIR_FAILURE;
+ }
+ // Check for P2P IE length (that includes length of type & length)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->addIEScan.addIEdata,
+ pBuf, pJoinReq->addIEScan.length);
+ pBuf += pJoinReq->addIEScan.length;
+ len -= pJoinReq->addIEScan.length; // skip add IE
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+
+ pJoinReq->addIEAssoc.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+ // Extract Add IE for assoc
+ if (pJoinReq->addIEAssoc.length)
+ {
+ // Check for IE length (that includes length of type & length)
+ if (pJoinReq->addIEAssoc.length > SIR_MAC_MAX_IE_LENGTH + 2)
+ {
+ limLog(pMac, LOGE,
+ FL("Invalid addIE Assoc length %d in SME_JOIN_REQ\n"),
+ pJoinReq->addIEAssoc.length);
+ return eSIR_FAILURE;
+ }
+ // Check for P2P IE length (that includes length of type & length)
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->addIEAssoc.addIEdata,
+ pBuf, pJoinReq->addIEAssoc.length);
+ pBuf += pJoinReq->addIEAssoc.length;
+ len -= pJoinReq->addIEAssoc.length; // skip add IE
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ }
+
+ pJoinReq->MCEncryptionType = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pJoinReq->UCEncryptionType = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ //is11Rconnection;
+ pJoinReq->is11Rconnection = (tAniBool)limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ //isCCXconnection;
+ pJoinReq->isCCXconnection = (tAniBool)limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // TSPEC information
+ pJoinReq->ccxTspecInfo.numTspecs = *pBuf++;
+ len -= sizeof(tANI_U8);
+ palCopyMemory(pMac->hHdd, (void*)&pJoinReq->ccxTspecInfo.tspec[0], pBuf, (sizeof(tTspecInfo)* pJoinReq->ccxTspecInfo.numTspecs));
+ pBuf += sizeof(tTspecInfo)*SIR_CCX_MAX_TSPEC_IES;
+ len -= sizeof(tTspecInfo)*SIR_CCX_MAX_TSPEC_IES;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX
+ //isFastTransitionEnabled;
+ pJoinReq->isFastTransitionEnabled = (tAniBool)limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+ // Extract BP Indicator
+ pJoinReq->bpIndicator = (tAniBool) limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract BP Type
+ pJoinReq->bpType = (tSirBpIndicatorType) limGetU32(pBuf);
+ pBuf += sizeof(tSirBpIndicatorType);
+ len -= sizeof(tSirBpIndicatorType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract Neighbor BSS List
+ if (limGetNeighborBssList(pMac, &pJoinReq->neighborBssList,
+ len, &lenUsed, pBuf) == eSIR_FAILURE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("get neighbor bss list failed\n"));)
+ return eSIR_FAILURE;
+ }
+ pBuf += lenUsed;
+ len -= lenUsed;
+ PELOG1(limLog(pMac, LOG1, FL("Assoc Type %d RSN len %d bp %d type %d bss RSN len %d\n"),
+ pJoinReq->assocType, pJoinReq->rsnIE.length, pJoinReq->bpIndicator,
+ pJoinReq->bpType, pJoinReq->neighborBssList.bssList->rsnIE.length);)
+#endif
+
+ // Extract Titan CB Neighbor BSS info
+ pJoinReq->cbNeighbors.cbBssFoundPri = *pBuf;
+ pBuf++;
+ pJoinReq->cbNeighbors.cbBssFoundSecUp = *pBuf;
+ pBuf++;
+ pJoinReq->cbNeighbors.cbBssFoundSecDown = *pBuf;
+ pBuf++;
+ len -= 3;
+
+ // Extract Spectrum Mgt Indicator
+ pJoinReq->spectrumMgtIndicator = (tAniBool) limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+
+ pJoinReq->powerCap.minTxPower = *pBuf++;
+ pJoinReq->powerCap.maxTxPower = *pBuf++;
+ len -=2;
+ limLog(pMac, LOGE, FL("Power Caps: Min power = %d, Max power = %d\n"), pJoinReq->powerCap.minTxPower, pJoinReq->powerCap.maxTxPower);
+
+ pJoinReq->supportedChannels.numChnl = *pBuf++;
+ len--;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pJoinReq->supportedChannels.channelList,
+ pBuf, pJoinReq->supportedChannels.numChnl);
+ pBuf += pJoinReq->supportedChannels.numChnl;
+ len-= pJoinReq->supportedChannels.numChnl;
+
+ PELOG2(limLog(pMac, LOG2,
+ FL("spectrumInd ON: minPower %d, maxPower %d , numChnls %d\n"),
+ pJoinReq->powerCap.minTxPower,
+ pJoinReq->powerCap.maxTxPower,
+ pJoinReq->supportedChannels.numChnl);)
+
+ // Extract uapsdPerAcBitmask
+ pJoinReq->uapsdPerAcBitmask = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA)
+ //
+ // NOTE - tSirBssDescription is now moved to the end
+ // of tSirSmeJoinReq structure. This is to accomodate
+ // the variable length data member ieFields[1]
+ //
+ if (limGetBssDescription( pMac, &pJoinReq->bssDescription,
+ len, &lenUsed, pBuf) == eSIR_FAILURE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("get bss description failed\n"));)
+ return eSIR_FAILURE;
+ }
+ PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, (tANI_U8 *) &(pJoinReq->bssDescription), pJoinReq->bssDescription.length + 2);)
+ pBuf += lenUsed;
+ len -= lenUsed;
+#endif
+
+ return eSIR_SUCCESS;
+} /*** end limJoinReqSerDes() ***/
+
+
+/**---------------------------------------------------------------
+\fn limAssocIndSerDes
+\brief This function is called by limProcessMlmAssocInd() to
+\ populate the SME_ASSOC_IND message based on the received
+\ MLM_ASSOC_IND.
+\
+\param pMac
+\param pAssocInd - Pointer to the received tLimMlmAssocInd
+\param pBuf - Pointer to serialized buffer
+\param psessionEntry - pointer to PE session entry
+\
+\return None
+------------------------------------------------------------------*/
+void
+limAssocIndSerDes(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd, tANI_U8 *pBuf, tpPESession psessionEntry)
+{
+ tANI_U8 *pLen = pBuf;
+ tANI_U16 mLen = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U32 len = 0;
+#endif
+
+ mLen = sizeof(tANI_U32);
+ mLen += sizeof(tANI_U8);
+ pBuf += sizeof(tANI_U16);
+ *pBuf = psessionEntry->smeSessionId;
+ pBuf += sizeof(tANI_U8);
+
+ // Fill in peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pAssocInd->peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ // Fill in aid
+ limCopyU16(pBuf, pAssocInd->aid);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ // Fill in bssId
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ // Fill in staId
+ limCopyU16(pBuf, psessionEntry->staId);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ // Fill in authType
+ limCopyU32(pBuf, pAssocInd->authType);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+
+ // Fill in ssId
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1);
+ pBuf += (1 + pAssocInd->ssId.length);
+ mLen += (1 + pAssocInd->ssId.length);
+
+ // Fill in rsnIE
+ limCopyU16(pBuf, pAssocInd->rsnIE.length);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata),
+ pAssocInd->rsnIE.length);
+ pBuf += pAssocInd->rsnIE.length;
+ mLen += pAssocInd->rsnIE.length;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+
+ limCopyU16(pBuf, pAssocInd->seqNum);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, pAssocInd->wniIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ limCopyU32(pBuf, pAssocInd->bpIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ limCopyU32(pBuf, pAssocInd->bpType);
+ pBuf += sizeof(tSirBpIndicatorType);
+ mLen += sizeof(tSirBpIndicatorType);
+
+ limCopyU32(pBuf, pAssocInd->assocType);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+
+ limCopyLoad(pBuf, pAssocInd->load);
+ pBuf += sizeof(tSirLoad);
+ mLen += sizeof(tSirLoad);
+
+ limCopyU32(pBuf, pAssocInd->numBss);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+
+ if (pAssocInd->numBss)
+ {
+ len = limCopyNeighborList(pMac,
+ pBuf,
+ pAssocInd->neighborList, pAssocInd->numBss);
+ pBuf += len;
+ mLen += (tANI_U16) len;
+ }
+
+ // place holder to capability and nwType
+
+ limCopyU16(pBuf, *(tANI_U16 *)&pAssocInd->capabilityInfo);
+ pBuf += sizeof(tANI_U16); // capabilityInfo
+ mLen += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, *(tANI_U32 *)&pAssocInd->nwType);
+ pBuf += sizeof(tANI_U32); // nwType
+ mLen += sizeof(tANI_U32);
+
+#endif
+
+ // Copy the new TITAN capabilities
+ *pBuf = pAssocInd->titanHtCaps;
+ pBuf++;
+ mLen++;
+
+ limCopyU32(pBuf, pAssocInd->spectrumMgtIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE)
+ {
+ *pBuf = pAssocInd->powerCap.minTxPower;
+ pBuf++;
+ *pBuf = pAssocInd->powerCap.maxTxPower;
+ pBuf++;
+ mLen += sizeof(tSirMacPowerCapInfo);
+
+ *pBuf = pAssocInd->supportedChannels.numChnl;
+ pBuf++;
+ mLen++;
+
+ palCopyMemory( pMac->hHdd, pBuf,
+ (tANI_U8 *) &(pAssocInd->supportedChannels.channelList),
+ pAssocInd->supportedChannels.numChnl);
+
+
+ pBuf += pAssocInd->supportedChannels.numChnl;
+ mLen += pAssocInd->supportedChannels.numChnl;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ limCopyU32(pBuf, pAssocInd->WmmStaInfoPresent);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+#endif
+ // Fill in length of SME_ASSOC_IND message
+ limCopyU16(pLen, mLen);
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending SME_ASSOC_IND length %d bytes:\n"), mLen);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);)
+} /*** end limAssocIndSerDes() ***/
+
+
+
+/**
+ * limAssocCnfSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() when
+ * SME_ASSOC_CNF or SME_REASSOC_CNF message is received from
+ * upper layer software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pAssocCnf Pointer to tSirSmeAssocCnf being extracted into
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limAssocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeAssocCnf pAssocCnf, tANI_U8 *pBuf)
+{
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pAssocCnf || !pBuf)
+ return eSIR_FAILURE;
+
+ pAssocCnf->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pAssocCnf->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (pAssocCnf->messageType == eWNI_SME_ASSOC_CNF)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("SME_ASSOC_CNF length %d bytes is:\n"), pAssocCnf->length);)
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("SME_REASSOC_CNF length %d bytes is:\n"), pAssocCnf->length);)
+ }
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pAssocCnf->length);)
+
+ // status code
+ pAssocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf);
+ pBuf += sizeof(tSirResultCodes);
+
+ // bssId
+ palCopyMemory( pMac->hHdd, pAssocCnf->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ // peerMacAddr
+ palCopyMemory( pMac->hHdd, pAssocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+
+ pAssocCnf->aid = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ // alternateBssId
+ palCopyMemory( pMac->hHdd, pAssocCnf->alternateBssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ // alternateChannelId
+ pAssocCnf->alternateChannelId = *pBuf;
+ pBuf++;
+
+ return eSIR_SUCCESS;
+} /*** end limAssocCnfSerDes() ***/
+
+
+
+/**
+ * limDisassocCnfSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() when
+ * SME_DISASSOC_CNF message is received from upper layer software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pDisassocCnf Pointer to tSirSmeDisassocCnf being
+ * extracted into
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limDisassocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeDisassocCnf pDisassocCnf, tANI_U8 *pBuf)
+{
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pDisassocCnf || !pBuf)
+ return eSIR_FAILURE;
+
+ pDisassocCnf->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pDisassocCnf->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_CNF length %d bytes is:\n"), pDisassocCnf->length);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pDisassocCnf->length);)
+
+ pDisassocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf);
+ pBuf += sizeof(tSirResultCodes);
+
+ palCopyMemory( pMac->hHdd, pDisassocCnf->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ palCopyMemory( pMac->hHdd, pDisassocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr));
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ pBuf += sizeof(tSirMacAddr);
+ pDisassocCnf->aid = limGetU16(pBuf);
+#endif
+
+ return eSIR_SUCCESS;
+} /*** end limDisassocCnfSerDes() ***/
+
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * limMeasurementReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() when
+ * SME_MEASUREMENT_REQ message is received from upper layer software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMeasReq Pointer to tSirSmeMeasurement being
+ * extracted into
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limMeasurementReqSerDes(tpAniSirGlobal pMac, tpSirSmeMeasurementReq pMeasReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+ PELOG3(tANI_U8 *pTemp = pBuf;)
+
+ if (!pMeasReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pMeasReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pMeasReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG3(limLog(pMac, LOG3, FL("SME_MEASUREMENT_REQ length %d bytes is:\n"), len);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.periodicMeasEnabled = (tAniBool)
+ limGetU32(pBuf);
+
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.involveSTAs = (tAniBool)
+ limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.metricsType = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.scanType = (tSirScanType)
+ limGetU32(pBuf);
+ pBuf += sizeof(tSirScanType);
+ len -= sizeof(tSirScanType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.longChannelScanPeriodicity = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measControl.cb11hEnabled = (tAniBool)limGetU32(pBuf);
+ pBuf += sizeof(tAniBool);
+ len -= sizeof(tAniBool);
+
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measDuration.shortTermPeriod = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ pMeasReq->measDuration.averagingPeriod = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ pMeasReq->measDuration.shortChannelScanDuration = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ pMeasReq->measDuration.longChannelScanDuration = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ len -= sizeof(tSirMeasDuration);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->measIndPeriod = limGetU32(pBuf);
+
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pMeasReq->channelList.numChannels = *pBuf++;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pMeasReq->channelList.channelNumber,
+ pBuf, pMeasReq->channelList.numChannels);
+
+ return eSIR_SUCCESS;
+} /*** end limMeasurementReqSerDes() ***/
+
+
+/**
+ * limWdsReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessLmmMessages() when
+ * SME_SET_WDS_INFO_REQ message is received from upper layer software.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pWdsInfo Pointer to tSirWdsInfo being extracted into
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limWdsReqSerDes(tpAniSirGlobal pMac, tpSirSmeSetWdsInfoReq pWdsInfoReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+ PELOG1(tANI_U8 *pTemp = pBuf;)
+
+ if (!pWdsInfoReq || !pBuf)
+ return eSIR_FAILURE;
+
+ // Extract messageType
+ pWdsInfoReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ // Extract length
+ len = pWdsInfoReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_SET_WDS_INFO_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+
+ // Extract transactionId
+ pWdsInfoReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+ // Extract wdsInfo
+ pWdsInfoReq->wdsInfo.wdsLength = limGetU16(pBuf);
+ len -= sizeof(tANI_U16);
+ pBuf += sizeof(tANI_U16);
+
+ if (pWdsInfoReq->wdsInfo.wdsLength > ANI_WDS_INFO_MAX_LENGTH)
+ return eSIR_FAILURE;
+
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pWdsInfoReq->wdsInfo.wdsBytes,
+ pBuf,
+ pWdsInfoReq->wdsInfo.wdsLength);
+
+ return eSIR_SUCCESS;
+
+} /*** end limWdsReqSerDes() ***/
+
+
+/**
+ * limMeasurementIndSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limSendMeasurementInd() while
+ * sending SME_MEASUREMENT_IND message to WSM.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMeasInd - Pointer to prepared MEASUREMENT_IND message
+ * @return None
+ */
+
+void
+limMeasurementIndSerDes(tpAniSirGlobal pMac, tANI_U8 *pBuf)
+{
+ tANI_U8 *pLen;
+ tANI_U16 len = 0, infoLen = 0;
+ tSirLoad load;
+ PELOG3(tANI_U8 *pTemp = pBuf;)
+
+ limCopyU16(pBuf, eWNI_SME_MEASUREMENT_IND);
+ pBuf += sizeof(tANI_U16);
+
+ pLen = pBuf;
+ pBuf += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, pMac->lim.gpLimMeasData->duration);
+ pBuf += sizeof(tANI_U32);
+ len += sizeof(tANI_U32);
+
+ load.numStas = pMac->lim.gLimNumOfCurrentSTAs;
+ load.channelUtilization =
+ pMac->lim.gpLimMeasData->avgChannelUtilization;
+ limCopyLoad(pBuf, load);
+ pBuf += sizeof(tSirLoad);
+ len += sizeof(tSirLoad);
+
+ infoLen = limCopyMeasMatrixList(pMac, pBuf);
+ pBuf += infoLen;
+ len += infoLen;
+
+ infoLen = limCopyNeighborWdsList(pMac, pBuf);
+ pBuf += infoLen;
+ len += infoLen;
+
+ limCopyU16(pLen, len+4);
+
+ PELOG3(limLog(pMac, LOG3, FL("Sending MEAS_IND length %d bytes:\n"), len);
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);)
+} /*** end limMeasurementIndSerDes() ***/
+#endif
+
+
+/**---------------------------------------------------------------
+\fn limReassocIndSerDes
+\brief This function is called by limProcessMlmReassocInd() to
+\ populate the SME_REASSOC_IND message based on the received
+\ MLM_REASSOC_IND.
+\
+\param pMac
+\param pReassocInd - Pointer to the received tLimMlmReassocInd
+\param pBuf - Pointer to serialized buffer
+\param psessionEntry - pointer to PE session entry
+\
+\return None
+------------------------------------------------------------------*/
+void
+limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, tANI_U8 *pBuf, tpPESession psessionEntry)
+{
+ tANI_U8 *pLen = pBuf;
+ tANI_U16 mLen = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U32 len = 0;
+#endif
+
+ mLen = sizeof(tANI_U32);
+ pBuf += sizeof(tANI_U16);
+ *pBuf++ = psessionEntry->smeSessionId;
+ mLen += sizeof(tANI_U8);
+
+ // Fill in peerMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pReassocInd->peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ // Fill in oldMacAddr
+ palCopyMemory( pMac->hHdd, pBuf, pReassocInd->currentApAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ // Fill in aid
+ limCopyU16(pBuf, pReassocInd->aid);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ // Fill in bssId
+ palCopyMemory( pMac->hHdd, pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ // Fill in staId
+ limCopyU16(pBuf, psessionEntry->staId);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ // Fill in authType
+ limCopyU32(pBuf, pReassocInd->authType);
+ pBuf += sizeof(tAniAuthType);
+ mLen += sizeof(tAniAuthType);
+
+ // Fill in ssId
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pReassocInd->ssId),
+ pReassocInd->ssId.length + 1);
+ pBuf += 1 + pReassocInd->ssId.length;
+ mLen += pReassocInd->ssId.length + 1;
+
+ // Fill in rsnIE
+ limCopyU16(pBuf, pReassocInd->rsnIE.length);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8 *) &(pReassocInd->rsnIE.rsnIEdata),
+ pReassocInd->rsnIE.length);
+ pBuf += pReassocInd->rsnIE.length;
+ mLen += pReassocInd->rsnIE.length;
+
+ // Fill in addIE
+ limCopyU16(pBuf, pReassocInd->addIE.length);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+ palCopyMemory( pMac->hHdd, pBuf, (tANI_U8*) &(pReassocInd->addIE.addIEdata),
+ pReassocInd->addIE.length);
+ pBuf += pReassocInd->addIE.length;
+ mLen += pReassocInd->addIE.length;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+
+ limCopyU16(pBuf, pReassocInd->seqNum);
+ pBuf += sizeof(tANI_U16);
+ mLen += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, pReassocInd->wniIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ limCopyU32(pBuf, pReassocInd->bpIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ limCopyU32(pBuf, pReassocInd->bpType);
+ pBuf += sizeof(tSirBpIndicatorType);
+ mLen += sizeof(tSirBpIndicatorType);
+
+ limCopyU32(pBuf, pReassocInd->reassocType);
+ pBuf += sizeof(tSirAssocType);
+ mLen += sizeof(tSirAssocType);
+
+ limCopyLoad(pBuf, pReassocInd->load);
+ pBuf += sizeof(tSirLoad);
+ mLen += sizeof(tSirLoad);
+
+ limCopyU32(pBuf, pReassocInd->numBss);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+
+ if (pReassocInd->numBss)
+ {
+ len = limCopyNeighborList(pMac,
+ pBuf,
+ pReassocInd->neighborList, pReassocInd->numBss);
+ pBuf += len;
+ mLen += (tANI_U16) len;
+ }
+
+ // place holder to capability and nwType
+ limCopyU16(pBuf, *(tANI_U16 *)&pReassocInd->capabilityInfo);
+ pBuf += sizeof(tANI_U16); // capabilityInfo
+ mLen += sizeof(tANI_U16);
+
+ limCopyU32(pBuf, *(tANI_U32 *)&pReassocInd->nwType);
+ pBuf += sizeof(tANI_U32); // nwType
+ mLen += sizeof(tANI_U32);
+#endif
+
+ // Copy the new TITAN capabilities
+ *pBuf = pReassocInd->titanHtCaps;
+ pBuf++;
+ mLen++;
+
+ limCopyU32(pBuf, pReassocInd->spectrumMgtIndicator);
+ pBuf += sizeof(tAniBool);
+ mLen += sizeof(tAniBool);
+
+ if (pReassocInd->spectrumMgtIndicator == eSIR_TRUE)
+ {
+ *pBuf = pReassocInd->powerCap.minTxPower;
+ pBuf++;
+ *pBuf = pReassocInd->powerCap.maxTxPower;
+ pBuf++;
+ mLen += sizeof(tSirMacPowerCapInfo);
+
+ *pBuf = pReassocInd->supportedChannels.numChnl;
+ pBuf++;
+ mLen++;
+
+ palCopyMemory( pMac->hHdd, pBuf,
+ (tANI_U8 *) &(pReassocInd->supportedChannels.channelList),
+ pReassocInd->supportedChannels.numChnl);
+
+ pBuf += pReassocInd->supportedChannels.numChnl;
+ mLen += pReassocInd->supportedChannels.numChnl;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ limCopyU32(pBuf, pReassocInd->WmmStaInfoPresent);
+ pBuf += sizeof(tANI_U32);
+ mLen += sizeof(tANI_U32);
+#endif
+
+ // Fill in length of SME_REASSOC_IND message
+ limCopyU16(pLen, mLen);
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending SME_REASSOC_IND length %d bytes:\n"), mLen);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);)
+} /*** end limReassocIndSerDes() ***/
+
+
+/**
+ * limAuthIndSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMlmAuthInd() while sending
+ * SME_AUTH_IND to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pAuthInd Pointer to tSirSmeAuthInd being sent
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return None
+ */
+
+void
+limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf)
+{
+ tANI_U8 *pLen = pBuf;
+ tANI_U16 mLen = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ mLen = sizeof(tANI_U32);
+ pBuf += sizeof(tANI_U16);
+ *pBuf++ = pAuthInd->sessionId;
+ mLen += sizeof(tANI_U8);
+
+ // BTAMP TODO: Fill in bssId
+ palZeroMemory(pMac->hHdd, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ palCopyMemory( pMac->hHdd, pBuf, pAuthInd->peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ mLen += sizeof(tSirMacAddr);
+
+ limCopyU32(pBuf, pAuthInd->authType);
+ pBuf += sizeof(tAniAuthType);
+ mLen += sizeof(tAniAuthType);
+
+ limCopyU16(pLen, mLen);
+
+ PELOG1(limLog(pMac, LOG1, FL("Sending SME_AUTH_IND length %d bytes:\n"), mLen);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);)
+} /*** end limAuthIndSerDes() ***/
+
+
+
+/**
+ * limSetContextReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_SETCONTEXT_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pSetContextReq Pointer to tSirSmeSetContextReq being
+ * extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limSetContextReqSerDes(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+ tANI_U16 totalKeySize = sizeof(tANI_U8); // initialized to sizeof numKeys
+ tANI_U8 numKeys;
+ tANI_U8 *pKeys;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+ if (!pSetContextReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pSetContextReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pSetContextReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_SETCONTEXT_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pSetContextReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pSetContextReq->transactionId = sirReadU16N(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pSetContextReq->peerMacAddr,
+ pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ palCopyMemory( pMac->hHdd, pSetContextReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ pSetContextReq->aid = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+// pSetContextReq->qosInfoPresent = limGetU32(pBuf);
+// pBuf += sizeof(tAniBool);
+
+// if (pSetContextReq->qosInfoPresent)
+// {
+// len = limGetQosInfo(&pSetContextReq->qos, pBuf);
+// pBuf += len;
+// }
+
+ pSetContextReq->keyMaterial.length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pSetContextReq->keyMaterial.edType = (tAniEdType) limGetU32(pBuf);
+ pBuf += sizeof(tAniEdType);
+ len -= sizeof(tAniEdType);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ numKeys = pSetContextReq->keyMaterial.numKeys = *pBuf++;
+ len -= sizeof(numKeys);
+
+ if (numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)
+ return eSIR_FAILURE;
+
+ /** Initialize the Default Keys if no Keys are being sent from the upper layer*/
+ if( limCheckRemainingLength(pMac, len) == eSIR_FAILURE) {
+ tpSirKeys pKeyinfo = pSetContextReq->keyMaterial.key;
+
+ pKeyinfo->keyId = 0;
+ pKeyinfo->keyDirection = eSIR_TX_RX;
+ pKeyinfo->keyLength = 0;
+
+ if (!limIsAddrBC(pSetContextReq->peerMacAddr))
+ pKeyinfo->unicast = 1;
+ else
+ pKeyinfo->unicast = 0;
+ }else {
+ pKeys = (tANI_U8 *) pSetContextReq->keyMaterial.key;
+ do {
+ tANI_U32 keySize = limGetKeysInfo(pMac, (tpSirKeys) pKeys,
+ pBuf);
+ pBuf += keySize;
+ pKeys += sizeof(tSirKeys);
+ totalKeySize += (tANI_U16) keySize;
+ if (numKeys == 0)
+ break;
+ numKeys--;
+ }while (numKeys);
+ }
+ return eSIR_SUCCESS;
+} /*** end limSetContextReqSerDes() ***/
+
+/**
+ * limRemoveKeyReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_REMOVEKEY_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pRemoveKeyReq Pointer to tSirSmeRemoveKeyReq being
+ * extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+ if (!pRemoveKeyReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pRemoveKeyReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pRemoveKeyReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_REMOVEKEY_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pRemoveKeyReq->peerMacAddr,
+ pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ pRemoveKeyReq->aid = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+#endif
+
+ pRemoveKeyReq->edType = *pBuf;
+ pBuf += sizeof(tANI_U8);
+ len -= sizeof(tANI_U8);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pRemoveKeyReq->wepType = *pBuf;
+
+ pBuf += sizeof(tANI_U8);
+ len -= sizeof(tANI_U8);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pRemoveKeyReq->keyId = *pBuf;
+
+ pBuf += sizeof(tANI_U8);
+ len -= sizeof(tANI_U8);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pRemoveKeyReq->unicast = *pBuf;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, pRemoveKeyReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pRemoveKeyReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pRemoveKeyReq->transactionId = sirReadU16N(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ return eSIR_SUCCESS;
+} /*** end limRemoveKeyReqSerDes() ***/
+
+
+
+/**
+ * limDisassocReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_DISASSOC_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pDisassocReq Pointer to tSirSmeDisassocReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limDisassocReqSerDes(tpAniSirGlobal pMac, tSirSmeDisassocReq *pDisassocReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pDisassocReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pDisassocReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pDisassocReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionID
+ pDisassocReq->sessionId = *pBuf;
+ pBuf += sizeof(tANI_U8);
+ len -= sizeof(tANI_U8);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionid
+ pDisassocReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pDisassocReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract peerMacAddr
+ palCopyMemory( pMac->hHdd, pDisassocReq->peerMacAddr, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract reasonCode
+ pDisassocReq->reasonCode = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ pDisassocReq->doNotSendOverTheAir = *pBuf;
+ pBuf += sizeof(tANI_U8);
+ len -= sizeof(tANI_U8);
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ pDisassocReq->aid = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ pDisassocReq->seqNum = limGetU16(pBuf);
+#endif
+#endif
+
+ return eSIR_SUCCESS;
+} /*** end limDisassocReqSerDes() ***/
+
+
+
+/**
+ * limDeauthReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_DEAUTH_REQ from host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pDeauthReq Pointer to tSirSmeDeauthReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+tSirRetStatus
+limDeauthReqSerDes(tpAniSirGlobal pMac, tSirSmeDeauthReq *pDeauthReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ if (!pDeauthReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pDeauthReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pDeauthReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_DEAUTH_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pDeauthReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pDeauthReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, pDeauthReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract peerMacAddr
+ palCopyMemory( pMac->hHdd, pDeauthReq->peerMacAddr, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract reasonCode
+ pDeauthReq->reasonCode = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+
+#if defined(ANI_PRODUCT_TYPE_AP)
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+ pDeauthReq->aid = limGetU16(pBuf);
+#endif
+
+ return eSIR_SUCCESS;
+} /*** end limDisassocReqSerDes() ***/
+
+
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * limCopyNeighborInfoToCfg()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_JOIN_REQ/SME_REASSOC_REQ from WSM to convert neighborBssInfo
+ * that is being joined to bssDescription used by MLM
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param neighborBssInfo Neighbor BSS info to be converted
+ *
+ * @return None
+ */
+
+void
+limCopyNeighborInfoToCfg(tpAniSirGlobal pMac, tSirNeighborBssInfo neighborBssInfo, tpPESession psessionEntry)
+{
+ tANI_U32 localPowerConstraints = 0;
+ tANI_U16 caps;
+ tANI_U8 qosCap = 0;
+
+ if(psessionEntry)
+ {
+ psessionEntry->gLimPhyMode = neighborBssInfo.nwType;
+ }
+ else
+ {
+ pMac->lim.gLimPhyMode = neighborBssInfo.nwType;
+ }
+
+ cfgSetCapabilityInfo(pMac, neighborBssInfo.capabilityInfo);
+
+ if (cfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *) &neighborBssInfo.ssId.ssId,
+ neighborBssInfo.ssId.length) != eSIR_SUCCESS)
+ {
+ /// Could not update SSID at CFG. Log error.
+ limLog(pMac, LOGP, FL("could not update SSID at CFG\n"));
+ }
+
+ #if 0
+ if (cfgSetStr(
+ pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &neighborBssInfo.operationalRateSet.rate,
+ neighborBssInfo.operationalRateSet.numRates) != eSIR_SUCCESS)
+ {
+ /// Could not update Operational Rateset at CFG. Log error.
+ limLog(pMac, LOGP,
+ FL("could not update Operational Rateset at CFG\n"));
+ }
+ #endif // TO SUPPORT BT-AMP
+
+ if (neighborBssInfo.nwType == WNI_CFG_PHY_MODE_11G)
+ {
+ if (cfgSetStr(
+ pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (tANI_U8 *) &neighborBssInfo.extendedRateSet.rate,
+ neighborBssInfo.extendedRateSet.numRates) != eSIR_SUCCESS)
+ {
+ /// Could not update Extended Rateset at CFG. Log error.
+ limLog(pMac, LOGP,
+ FL("could not update Extended Rateset at CFG\n"));
+ }
+ }
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (neighborBssInfo.hcfEnabled)
+ LIM_BSS_CAPS_SET(HCF, qosCap);
+#endif
+ if (neighborBssInfo.wmeInfoPresent || neighborBssInfo.wmeEdcaPresent)
+ LIM_BSS_CAPS_SET(WME, qosCap);
+ if (LIM_BSS_CAPS_GET(WME, qosCap) && neighborBssInfo.wsmCapablePresent)
+ LIM_BSS_CAPS_SET(WSM, qosCap);
+
+ pMac->lim.gLimCurrentBssQosCaps = qosCap;
+
+ if (neighborBssInfo.wniIndicator)
+ pMac->lim.gLimCurrentBssPropCap = neighborBssInfo.propIECapability;
+ else
+ pMac->lim.gLimCurrentBssPropCap = 0;
+
+ if (neighborBssInfo.HTCapsPresent)
+ pMac->lim.htCapabilityPresentInBeacon = 1;
+ else
+ pMac->lim.htCapabilityPresentInBeacon = 0;
+ if (neighborBssInfo.localPowerConstraints && pMac->lim.gLim11hEnable)
+ {
+ localPowerConstraints = neighborBssInfo.localPowerConstraints;
+ }
+ if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.\n"));
+ }
+} /*** end limCopyNeighborInfoToCfg() ***/
+#endif
+
+
+/**
+ * limStatSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeDisassocNtf() while sending
+ * SME_DISASSOC_IND/eWNI_SME_DISASSOC_RSP to host
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pAssocInd Pointer to tpAniStaStatStruct being sent
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return None
+ */
+
+void
+limStatSerDes(tpAniSirGlobal pMac, tpAniStaStatStruct pStat, tANI_U8 *pBuf)
+{
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ limCopyU32(pBuf, pStat->sentAesBlksUcastHi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->sentAesBlksUcastLo);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->recvAesBlksUcastHi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->recvAesBlksUcastLo);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->aesFormatErrorUcastCnts);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->aesReplaysUcast);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->aesDecryptErrUcast);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->singleRetryPkts);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->failedTxPkts);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->ackTimeouts);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->multiRetryPkts);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->fragTxCntsHi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->fragTxCntsLo);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->transmittedPktsHi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->transmittedPktsLo);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->phyStatHi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->phyStatLo);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->uplinkRssi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->uplinkSinr);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->uplinkRate);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->downlinkRssi);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->downlinkSinr);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->downlinkRate);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->nRcvBytes);
+ pBuf += sizeof(tANI_U32);
+
+ limCopyU32(pBuf, pStat->nXmitBytes);
+ pBuf += sizeof(tANI_U32);
+
+ PELOG1(limLog(pMac, LOG1, FL("STAT: length %d bytes is:\n"), sizeof(tAniStaStatStruct));)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, sizeof(tAniStaStatStruct));)
+
+} /*** end limStatSerDes() ***/
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+/**
+ * limSmeWmStatusChangeNtfSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeWmStatusChangeNtf()
+ * to serialize the header fields of SME WM Status Change
+ * Notification
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param statusChangeCode Status Change code
+ * @param pBuf Pointer to serialized buffer
+ * @param len Pointer to length actually used
+ * @param buflen Buffer length remaining
+ * @return retCode Indicates whether message is successfully
+ * serialized (eSIR_SUCCESS) or not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limSmeWmStatusChangeHeaderSerDes(tpAniSirGlobal pMac,
+ tSirSmeStatusChangeCode statusChangeCode,
+ tANI_U8 *pBuf,
+ tANI_U16 *len,
+ tANI_U32 buflen,
+ tANI_U8 sessionId)
+{
+ if (buflen < ((sizeof(tANI_U16) * 2) + sizeof(tANI_U32)))
+ {
+ limLog(pMac, LOGE,
+ FL("limSmeWmStatusChangeHeaderSerDes: no enough space (buf %d) \n"), buflen);
+ return eSIR_FAILURE;
+ }
+
+ *len = 0;
+
+ limCopyU16(pBuf, eWNI_SME_WM_STATUS_CHANGE_NTF);
+ pBuf += sizeof(tANI_U16);
+ *len += sizeof(tANI_U16);
+
+ // Actual length value shall be filled later
+ pBuf += sizeof(tANI_U16);
+ *len += sizeof(tANI_U16);
+
+ *pBuf++ = sessionId;
+ *len += sizeof(tANI_U8);
+
+ limCopyU32(pBuf, statusChangeCode);
+ pBuf += sizeof(tANI_U32);
+ *len += sizeof(tANI_U32);
+
+ return eSIR_SUCCESS;
+} /*** end limSmeWmStatusChangeHeaderSerDes() ***/
+
+
+
+/**
+ * limRadioInfoSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeWmStatusChangeNtf()
+ * to serialize the radarInfo message
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pRadarInfo Pointer to tSirRadarInfo
+ * @param pBuf Pointer to serialized buffer
+ * @param len Pointer to length actually used by tSirRadarInfo
+ * @param buflen Length remaining
+ *
+ * @return retCode Indicates whether message is successfully
+ * serialized (eSIR_SUCCESS) or not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limRadioInfoSerDes(tpAniSirGlobal pMac, tpSirRadarInfo pRadarInfo,
+ tANI_U8 *pBuf, tANI_U16 *len, tANI_U32 buflen)
+{
+
+ if (buflen < sizeof(tSirRadarInfo))
+ {
+ limLog(pMac, LOGE,
+ FL("no enough space (buf %d) \n"), buflen);
+ return eSIR_FAILURE;
+ }
+
+ *pBuf = pRadarInfo->channelNumber;
+ pBuf += sizeof(tANI_U8);
+ *len += sizeof(tANI_U8);
+
+ limCopyU16(pBuf, pRadarInfo->radarPulseWidth);
+ pBuf += sizeof(tANI_U16);
+ *len += sizeof(tANI_U16);
+
+ limCopyU16(pBuf, pRadarInfo->numRadarPulse);
+ pBuf += sizeof(tANI_U16);
+ *len += sizeof(tANI_U16);
+
+ return eSIR_SUCCESS;
+} /*** end limRadioInfoSerDes() ***/
+#endif
+
+
+/**
+ * limPackBkgndScanFailNotify()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeWmStatusChangeNtf()
+ * to pack the tSirBackgroundScanInfo message
+ *
+ */
+void
+limPackBkgndScanFailNotify(tpAniSirGlobal pMac,
+ tSirSmeStatusChangeCode statusChangeCode,
+ tpSirBackgroundScanInfo pScanInfo,
+ tSirSmeWmStatusChangeNtf *pSmeNtf,
+ tANI_U8 sessionId)
+{
+
+ tANI_U16 length = (sizeof(tANI_U16) * 2) + sizeof(tANI_U8) +
+ sizeof(tSirSmeStatusChangeCode) +
+ sizeof(tSirBackgroundScanInfo);
+
+#if defined (ANI_PRODUCT_TYPE_AP) && defined(ANI_LITTLE_BYTE_ENDIAN)
+ sirStoreU16N((tANI_U8*)&pSmeNtf->messageType, eWNI_SME_WM_STATUS_CHANGE_NTF );
+ sirStoreU16N((tANI_U8*)&pSmeNtf->length, length);
+ pSmeNtf->sessionId = sessionId;
+ sirStoreU32N((tANI_U8*)&pSmeNtf->statusChangeCode, statusChangeCode);
+
+ sirStoreU32N((tANI_U8*)&pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanSuccess,
+ pScanInfo->numOfScanSuccess);
+ sirStoreU32N((tANI_U8*)&pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanFailure,
+ pScanInfo->numOfScanFailure);
+ sirStoreU32N((tANI_U8*)&pSmeNtf->statusChangeInfo.bkgndScanInfo.reserved,
+ pScanInfo->reserved);
+#else
+ pSmeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF;
+ pSmeNtf->statusChangeCode = statusChangeCode;
+ pSmeNtf->length = length;
+ pSmeNtf->sessionId = sessionId;
+ pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanSuccess = pScanInfo->numOfScanSuccess;
+ pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanFailure = pScanInfo->numOfScanFailure;
+ pSmeNtf->statusChangeInfo.bkgndScanInfo.reserved = pScanInfo->reserved;
+#endif
+}
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+
+/**
+ * nonTitanBssFoundSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limSendSmeWmStatusChangeNtf()
+ * to serialize the following message
+ * Mesg = eWNI_SME_WM_STATUS_CHANGE_NTF
+ * Change code = eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to the global pMAC structure
+ * @param pNewBssInfo Pointer to tpSirNeighborBssWdsInfo
+ * @param pBuf Send data buffer
+ * @param len Length of message
+ * @param buflen Length remaining
+ *
+ * @return retCode Indicates whether message is successfully
+ * serialized (eSIR_SUCCESS) or not (eSIR_FAILURE)
+ */
+
+tSirRetStatus nonTitanBssFoundSerDes( tpAniSirGlobal pMac,
+ tpSirNeighborBssWdsInfo pNewBssInfo,
+ tANI_U8 *pBuf,
+ tANI_U16 *len,
+ tANI_U8 sessionId )
+{
+tANI_U8 *pTemp = pBuf;
+tANI_U16 length = 0;
+tANI_U32 bufLen = sizeof( tSirSmeWmStatusChangeNtf );
+
+ // Serialize the header (length to be filled later)
+ if( eSIR_SUCCESS != limSmeWmStatusChangeHeaderSerDes(
+ pMac,
+ eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP,
+ pBuf,
+ &length,
+ bufLen,
+ sessionId))
+ {
+ limLog( pMac, LOGE,
+ FL("Header SerDes failed \n"));
+ return eSIR_FAILURE;
+ }
+ pBuf += length;
+ bufLen -= length;
+
+ // Serialize tSirNeighborBssWdsInfo
+ length = limCopyNeighborWdsInfo( pMac,
+ pBuf,
+ pNewBssInfo );
+ pBuf += length;
+ bufLen -= length;
+
+ // Update tSirSmeWmStatusChangeNtf.length
+ pBuf = pTemp;
+ pBuf += sizeof(tANI_U16);
+ limCopyU16(pBuf, length);
+
+ // Update the total length to be returned
+ *len = length;
+
+ return eSIR_SUCCESS;
+} /*** end nonTitanBssFoundSerDes() ***/
+
+/**
+ * limIsSmeSwitchChannelReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_SWITCH_CHL_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pBuf - Pointer to a serialized SME_SWITCH_CHL_REQ message
+ * @param pSmeMsg - Pointer to a tSirsmeSwitchChannelReq structure
+ * @return true if SME_SWITCH_CHL_REQ message is formatted correctly
+ * false otherwise
+ */
+
+tANI_BOOLEAN
+limIsSmeSwitchChannelReqValid(tpAniSirGlobal pMac,
+ tANI_U8 *pBuf,
+ tpSirSmeSwitchChannelReq pSmeMsg)
+{
+ pSmeMsg->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pSmeMsg->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pSmeMsg->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ pSmeMsg->channelId = *pBuf;
+ pBuf++;
+
+ pSmeMsg->cbMode = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ pSmeMsg->dtimFactor = limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+
+ if (pSmeMsg->length != SIR_SME_CHANNEL_SWITCH_SIZE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Invalid length %d \n"), pSmeMsg->length);)
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ // dtimFactor should not be too large
+ if (pSmeMsg->dtimFactor > SIR_MAX_DTIM_FACTOR)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Invalid dtimFactor %d \n"), pSmeMsg->dtimFactor);)
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ return eANI_BOOLEAN_TRUE;
+}
+
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+/**
+ * limIsSmeGetAssocSTAsReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_GET_ASSOC_STAS_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pBuf - Pointer to a serialized SME_GET_ASSOC_STAS_REQ message
+ * @param pSmeMsg - Pointer to a tSirSmeGetAssocSTAsReq structure
+ * @return true if SME_GET_ASSOC_STAS_REQ message is formatted correctly
+ * false otherwise
+ */
+tANI_BOOLEAN
+limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+ pGetAssocSTAsReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pGetAssocSTAsReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pGetAssocSTAsReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract modId
+ pGetAssocSTAsReq->modId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract pUsrContext
+ pGetAssocSTAsReq->pUsrContext = (void *)limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract pSapEventCallback
+ pGetAssocSTAsReq->pSapEventCallback = (void *)limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract pAssocStasArray
+ pGetAssocSTAsReq->pAssocStasArray = (void *)limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes \n"), len);)
+
+ if (len < 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("SME_GET_ASSOC_STAS_REQ invalid length\n"));)
+ return eANI_BOOLEAN_FALSE;
+ }
+
+ return eANI_BOOLEAN_TRUE;
+}
+
+/**
+ * limTkipCntrMeasReqSerDes()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * eWNI_SME_TKIP_CNTR_MEAS_REQ from host HDD
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param tpSirSmeTkipCntrMeasReq Pointer to tSirSmeTkipCntrMeasReq being extracted
+ * @param pBuf Pointer to serialized buffer
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+tSirRetStatus
+limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq pTkipCntrMeasReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+#ifdef PE_DEBUG_LOG1
+ tANI_U8 *pTemp = pBuf;
+#endif
+
+ pTkipCntrMeasReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pTkipCntrMeasReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length %d bytes is:\n"), len);)
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);)
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pTkipCntrMeasReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pTkipCntrMeasReq->transactionId = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof(tANI_U16);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pTkipCntrMeasReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bEnable
+ pTkipCntrMeasReq->bEnable = *pBuf++;
+ len --;
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length consumed %d bytes \n"), len);)
+
+ if (len)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("SME_TKIP_CNTR_MEAS_REQ invalid \n"));)
+ return eSIR_FAILURE;
+ }
+ else
+ return eSIR_SUCCESS;
+}
+
+/**
+ * limIsSmeGetWPSPBCSessionsReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeGetWPSPBCSessions() upon
+ * receiving query WPS PBC overlap information message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pBuf - Pointer to a serialized SME_GET_WPSPBC_SESSION_REQ message
+ * @param pGetWPSPBCSessionsReq - Pointer to a tSirSmeGetWPSPBCSessionsReq structure
+ * @return true if SME_GET_WPSPBC_SESSION_REQ message is formatted correctly
+ * false otherwise
+ */
+
+tSirRetStatus
+limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirSmeGetWPSPBCSessionsReq));)
+
+ pGetWPSPBCSessionsReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pGetWPSPBCSessionsReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract pUsrContext
+ pGetWPSPBCSessionsReq->pUsrContext = (void *)limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract pSapEventCallback
+ pGetWPSPBCSessionsReq->pSapEventCallback = (void *)limGetU32(pBuf);
+ pBuf += sizeof(tANI_U32);
+ len -= sizeof(tANI_U32);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pGetWPSPBCSessionsReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+
+ // Extract MAC address of Station to be removed
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pGetWPSPBCSessionsReq->pRemoveMac, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes \n"), len);)
+
+ if (len < 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length\n"));)
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+#endif
+
+/**---------------------------------------------------------------
+\fn limGetSessionInfo
+\brief This function returns the sessionId and transactionId
+\ of a message. This assumes that the message structure
+\ is of format:
+\ tANI_U16 messageType
+\ tANI_U16 messageLength
+\ tANI_U8 sessionId
+\ tANI_U16 transactionId
+\param pMac - pMac global structure
+\param *pBuf - pointer to the message buffer
+\param sessionId - returned session id value
+\param transactionId - returned transaction ID value
+\return None
+------------------------------------------------------------------*/
+void
+limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *sessionId, tANI_U16 *transactionId)
+{
+ if (!pBuf)
+ {
+ limLog(pMac, LOGE, FL("NULL ptr received. \n"));
+ return;
+ }
+
+ pBuf += sizeof(tANI_U16); // skip message type
+ pBuf += sizeof(tANI_U16); // skip message length
+
+ *sessionId = *pBuf; // get sessionId
+ pBuf++;
+ *transactionId = limGetU16(pBuf); // get transactionId
+
+ return;
+}
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+/**
+ * limUpdateAPWPSIEsReqSerDes()
+ *
+ *FUNCTION:
+ * This function is to deserialize UpdateAPWPSIEs message
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pUpdateAPWPSIEsReq Pointer to tSirUpdateAPWPSIEsReq being
+ * extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPSIEsReq));)
+
+ if (!pUpdateAPWPSIEsReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pUpdateAPWPSIEsReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pUpdateAPWPSIEsReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pUpdateAPWPSIEsReq->transactionId = limGetU16( pBuf );
+ pBuf += sizeof( tANI_U16 );
+ len -= sizeof( tANI_U16 );
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pUpdateAPWPSIEsReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pUpdateAPWPSIEsReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract APWPSIEs
+ palCopyMemory( pMac->hHdd, (tSirAPWPSIEs *) &pUpdateAPWPSIEsReq->APWPSIEs, pBuf, sizeof(tSirAPWPSIEs));
+ pBuf += sizeof(tSirAPWPSIEs);
+ len -= sizeof(tSirAPWPSIEs);
+
+ PELOG1(limLog(pMac, LOG1, FL("SME_UPDATE_APWPSIE_REQ length consumed %d bytes \n"), len);)
+
+ if (len < 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("SME_UPDATE_APWPSIE_REQ invalid length\n"));)
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} /*** end limSetContextReqSerDes() ***/
+
+/**
+ * limUpdateAPWPARSNIEsReqSerDes ()
+ *
+ *FUNCTION:
+ * This function is to deserialize UpdateAPWPSIEs message
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pUpdateAPWPARSNIEsReq Pointer to tpSirUpdateAPWPARSNIEsReq being
+ * extracted
+ * @param pBuf Pointer to serialized buffer
+ *
+ * @return retCode Indicates whether message is successfully
+ * de-serialized (eSIR_SUCCESS) or
+ * not (eSIR_FAILURE)
+ */
+
+tSirRetStatus
+limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf)
+{
+ tANI_S16 len = 0;
+
+ PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPARSNIEsReq));)
+
+ if (!pUpdateAPWPARSNIEsReq || !pBuf)
+ return eSIR_FAILURE;
+
+ pUpdateAPWPARSNIEsReq->messageType = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ len = pUpdateAPWPARSNIEsReq->length = limGetU16(pBuf);
+ pBuf += sizeof(tANI_U16);
+
+ if (len < (tANI_S16) sizeof(tANI_U32))
+ return eSIR_FAILURE;
+
+ len -= sizeof(tANI_U32); // skip message header
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract transactionId
+ pUpdateAPWPARSNIEsReq->transactionId = limGetU16( pBuf );
+ pBuf += sizeof(tANI_U16);
+ len -= sizeof( tANI_U16 );
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract bssId
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) pUpdateAPWPARSNIEsReq->bssId, pBuf, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ len -= sizeof(tSirMacAddr);
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract sessionId
+ pUpdateAPWPARSNIEsReq->sessionId = *pBuf++;
+ len--;
+ if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE)
+ return eSIR_FAILURE;
+
+ // Extract APWPARSNIEs
+ palCopyMemory( pMac->hHdd, (tSirRSNie *) &pUpdateAPWPARSNIEsReq->APWPARSNIEs, pBuf, sizeof(tSirRSNie));
+ pBuf += sizeof(tSirRSNie);
+ len -= sizeof(tSirRSNie);
+
+ if (len < 0)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length\n"));)
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} /*** end limUpdateAPWPARSNIEsReqSerDes() ***/
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limSerDesUtils.h b/CORE/MAC/src/pe/lim/limSerDesUtils.h
new file mode 100644
index 0000000..6de920b
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSerDesUtils.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSerDesUtils.h contains the utility definitions
+ * LIM uses while processing messages from upper layer software
+ * modules
+ * Author: Chandra Modumudi
+ * Date: 10/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SERDES_UTILS_H
+#define __LIM_SERDES_UTILS_H
+
+#include "sirApi.h"
+#include "aniSystemDefs.h"
+#include "sirMacProtDef.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limPropExtsUtils.h"
+
+tSirRetStatus limStartBssReqSerDes(tpAniSirGlobal, tpSirSmeStartBssReq, tANI_U8 *);
+tSirRetStatus limStopBssReqSerDes(tpAniSirGlobal, tpSirSmeStopBssReq, tANI_U8 *);
+tSirRetStatus limJoinReqSerDes(tpAniSirGlobal, tpSirSmeJoinReq, tANI_U8 *);
+void limAssocIndSerDes(tpAniSirGlobal, tpLimMlmAssocInd, tANI_U8 *, tpPESession);
+void limReassocIndSerDes(tpAniSirGlobal, tpLimMlmReassocInd, tANI_U8 *, tpPESession psessionEntry);
+tSirRetStatus limAssocCnfSerDes(tpAniSirGlobal, tpSirSmeAssocCnf, tANI_U8 *);
+tSirRetStatus limDisassocCnfSerDes(tpAniSirGlobal, tpSirSmeDisassocCnf, tANI_U8 *);
+tSirRetStatus limSetContextReqSerDes(tpAniSirGlobal, tpSirSmeSetContextReq, tANI_U8 *);
+tSirRetStatus limDisassocReqSerDes(tpAniSirGlobal, tSirSmeDisassocReq *, tANI_U8 *);
+tSirRetStatus limDeauthReqSerDes(tpAniSirGlobal, tSirSmeDeauthReq *, tANI_U8 *);
+void limAuthIndSerDes(tpAniSirGlobal, tpLimMlmAuthInd, tANI_U8 *);
+void limStatSerDes(tpAniSirGlobal, tpAniStaStatStruct, tANI_U8 *);
+void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+tSirRetStatus limMeasurementReqSerDes(tpAniSirGlobal, tpSirSmeMeasurementReq, tANI_U8 *);
+void limMeasurementIndSerDes(tpAniSirGlobal, tANI_U8 *);
+void limCopyNeighborInfoToCfg(tpAniSirGlobal, tSirNeighborBssInfo);
+tSirRetStatus limWdsReqSerDes(tpAniSirGlobal, tpSirSmeSetWdsInfoReq, tANI_U8 *);
+tSirRetStatus limRadioInfoSerDes(tpAniSirGlobal, tpSirRadarInfo, tANI_U8 *, tANI_U16 *, tANI_U32);
+tSirRetStatus limSmeWmStatusChangeHeaderSerDes(tpAniSirGlobal, tSirSmeStatusChangeCode, tANI_U8 *, tANI_U16 *, tANI_U32, tANI_U8);
+tSirRetStatus nonTitanBssFoundSerDes( tpAniSirGlobal, tpSirNeighborBssWdsInfo, tANI_U8 *, tANI_U16 *, tANI_U8 );
+#endif
+
+void limPackBkgndScanFailNotify(tpAniSirGlobal, tSirSmeStatusChangeCode,
+ tpSirBackgroundScanInfo, tSirSmeWmStatusChangeNtf *, tANI_U8);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+tANI_U32 limCopyNeighborBssInfo(tpAniSirGlobal, tANI_U8 *, tpSirNeighborBssInfo);
+tANI_U32 limGetNeighborBssInfo(tpAniSirGlobal, tpSirNeighborBssInfo, tANI_U8 *);
+#endif
+
+tSirRetStatus limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 * pBuf);
+
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_BOOLEAN limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf);
+tSirRetStatus limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq ptkipCntrMeasReq, tANI_U8 *pBuf);
+
+tSirRetStatus limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf);
+tSirRetStatus limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf);
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+tANI_BOOLEAN limIsSmeSwitchChannelReqValid(tpAniSirGlobal, tANI_U8 *, tpSirSmeSwitchChannelReq);
+#endif
+
+// Byte String <--> tANI_U16/tANI_U32 copy functions
+static inline void limCopyU16(tANI_U8 *ptr, tANI_U16 u16Val)
+{
+#if defined(ANI_PRODUCT_TYPE_AP)
+ *ptr++ = (tANI_U8) ((u16Val >> 8) & 0xff);
+ *ptr = (tANI_U8) (u16Val & 0xff);
+#elif ((defined(ANI_OS_TYPE_OSX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_WINDOWS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_AMSS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ *ptr++ = (tANI_U8) (u16Val & 0xff);
+ *ptr = (tANI_U8) ((u16Val >> 8) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline tANI_U16 limGetU16(tANI_U8 *ptr)
+{
+#if defined(ANI_PRODUCT_TYPE_AP)
+ return (((tANI_U16) (*ptr << 8)) |
+ ((tANI_U16) (*(ptr+1))));
+#elif ((defined(ANI_OS_TYPE_OSX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_WINDOWS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_AMSS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ return (((tANI_U16) (*(ptr+1) << 8)) |
+ ((tANI_U16) (*ptr)));
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline void limCopyU32(tANI_U8 *ptr, tANI_U32 u32Val)
+{
+#if defined(ANI_PRODUCT_TYPE_AP)
+ *ptr++ = (tANI_U8) ((u32Val >> 24) & 0xff);
+ *ptr++ = (tANI_U8) ((u32Val >> 16) & 0xff);
+ *ptr++ = (tANI_U8) ((u32Val >> 8) & 0xff);
+ *ptr = (tANI_U8) (u32Val & 0xff);
+#elif ((defined(ANI_OS_TYPE_OSX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_WINDOWS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_AMSS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ *ptr++ = (tANI_U8) (u32Val & 0xff);
+ *ptr++ = (tANI_U8) ((u32Val >> 8) & 0xff);
+ *ptr++ = (tANI_U8) ((u32Val >> 16) & 0xff);
+ *ptr = (tANI_U8) ((u32Val >> 24) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline tANI_U32 limGetU32(tANI_U8 *ptr)
+{
+#if defined(ANI_PRODUCT_TYPE_AP)
+ return ((*(ptr) << 24) |
+ (*(ptr+1) << 16) |
+ (*(ptr+2) << 8) |
+ (*(ptr+3)));
+#elif ((defined(ANI_OS_TYPE_OSX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_WINDOWS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_AMSS) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ return ((*(ptr+3) << 24) |
+ (*(ptr+2) << 16) |
+ (*(ptr+1) << 8) |
+ (*(ptr)));
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+#endif /* __LIM_SERDES_UTILS_H */
+
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
new file mode 100644
index 0000000..e3d665f
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * */
+/**=========================================================================
+
+ \file limSession.c
+
+ \brief implementation for lim Session related APIs
+
+ \author Sunit Bhatia
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+
+ Qualcomm Confidential and Proprietary.
+
+ ========================================================================*/
+
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include "aniGlobal.h"
+#include "limDebug.h"
+#include "limSession.h"
+#include "limUtils.h"
+#ifdef FEATURE_WLAN_CCX
+#include "ccxApi.h"
+#endif
+
+/*--------------------------------------------------------------------------
+
+ \brief peInitBeaconParams() - Initialize the beaconParams structure
+
+
+ \param tpPESession - pointer to the session context or NULL if session can not be created.
+ \return void
+ \sa
+
+ --------------------------------------------------------------------------*/
+
+void peInitBeaconParams(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ psessionEntry->beaconParams.beaconInterval = 0;
+ psessionEntry->beaconParams.fShortPreamble = 0;
+ psessionEntry->beaconParams.llaCoexist = 0;
+ psessionEntry->beaconParams.llbCoexist = 0;
+ psessionEntry->beaconParams.llgCoexist = 0;
+ psessionEntry->beaconParams.ht20Coexist = 0;
+ psessionEntry->beaconParams.llnNonGFCoexist = 0;
+ psessionEntry->beaconParams.fRIFSMode = 0;
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
+ psessionEntry->beaconParams.gHTObssMode = 0;
+
+ // Number of legacy STAs associated
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLim11bParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLim11aParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLim11gParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLimNonGfParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLimHt20Params, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLimLsigTxopParams, sizeof(tLimProtStaParams));
+ palZeroMemory(pMac->hHdd, (void*)&psessionEntry->gLimOlbcParams, sizeof(tLimProtStaParams));
+}
+
+/*--------------------------------------------------------------------------
+
+ \brief peCreateSession() - creates a new PE session given the BSSID
+
+ This function returns the session context and the session ID if the session
+ corresponding to the passed BSSID is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param bssid - BSSID of the new session
+ \param sessionId -session ID is returned here, if session is created.
+
+ \return tpPESession - pointer to the session context or NULL if session can not be created.
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+tpPESession peCreateSession(tpAniSirGlobal pMac, tANI_U8 *bssid , tANI_U8* sessionId, tANI_U16 numSta)
+{
+ tANI_U8 i;
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ /* Find first free room in session table */
+ if(pMac->lim.gpSession[i].valid == FALSE)
+ {
+ palZeroMemory(pMac, (void*)&pMac->lim.gpSession[i], sizeof(tPESession));
+
+ //Allocate space for Station Table for this session.
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->lim.gpSession[i].dph.dphHashTable.pHashTable, sizeof(tpDphHashNode)*numSta))
+ {
+ limLog(pMac, LOGE, FL("memory allocate failed!\n"));
+ return NULL;
+ }
+
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **) &pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray, sizeof(tDphHashNode)*numSta))
+ {
+ limLog(pMac, LOGE, FL("memory allocate failed!\n"));
+ palFreeMemory(pMac->hHdd,pMac->lim.gpSession[i].dph.dphHashTable.pHashTable);
+ return NULL;
+ }
+ pMac->lim.gpSession[i].dph.dphHashTable.size = numSta;
+
+ dphHashTableClassInit(pMac,
+ &pMac->lim.gpSession[i].dph.dphHashTable);
+
+ /* Copy the BSSID to the session table */
+ sirCopyMacAddr(pMac->lim.gpSession[i].bssId, bssid);
+ pMac->lim.gpSession[i].valid = TRUE;
+
+ /* Intialize the SME and MLM states to IDLE */
+ pMac->lim.gpSession[i].limMlmState = eLIM_MLM_IDLE_STATE;
+ pMac->lim.gpSession[i].limSmeState = eLIM_SME_IDLE_STATE;
+ pMac->lim.gpSession[i].limCurrentAuthType = eSIR_OPEN_SYSTEM;
+ peInitBeaconParams(pMac, &pMac->lim.gpSession[i]);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ pMac->lim.gpSession[i].is11Rconnection = FALSE;
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ pMac->lim.gpSession[i].isCCXconnection = FALSE;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX
+ pMac->lim.gpSession[i].isFastTransitionEnabled = FALSE;
+#endif
+ *sessionId = i;
+
+ pMac->lim.gpSession[i].gLimPhyMode = WNI_CFG_PHY_MODE_11G; //TODO :Check with the team what should be default mode
+ return(&pMac->lim.gpSession[i]);
+ }
+ }
+ limLog(pMac, LOGE, FL("Session can not be created.. Reached Max permitted sessions \n "));
+ return NULL;
+}
+
+
+/*--------------------------------------------------------------------------
+ \brief peFindSessionByBssid() - looks up the PE session given the BSSID.
+
+ This function returns the session context and the session ID if the session
+ corresponding to the given BSSID is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param bssid - BSSID of the session
+ \param sessionId -session ID is returned here, if session is found.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_U8* sessionId)
+{
+ tANI_U8 i;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ /* If BSSID matches return corresponding tables address*/
+ if( (pMac->lim.gpSession[i].valid) && (sirCompareMacAddr(pMac->lim.gpSession[i].bssId, bssid)))
+ {
+ *sessionId = i;
+ return(&pMac->lim.gpSession[i]);
+ }
+ }
+
+ limLog(pMac, LOG4, FL("Session lookup fails for BSSID: \n "));
+ limPrintMacAddr(pMac, bssid, LOG4);
+ return(NULL);
+
+}
+
+
+
+/*--------------------------------------------------------------------------
+ \brief peFindSessionBySessionId() - looks up the PE session given the session ID.
+
+ This function returns the session context if the session
+ corresponding to the given session ID is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId -session ID for which session context needs to be looked up.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+ tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac , tANI_U8 sessionId)
+{
+ if(sessionId >= pMac->lim.maxBssId)
+ {
+ limLog(pMac, LOGE, FL("Invalid sessionId: %d \n "), sessionId);
+ return(NULL);
+ }
+ if((pMac->lim.gpSession[sessionId].valid == TRUE))
+ {
+ return(&pMac->lim.gpSession[sessionId]);
+ }
+ limLog(pMac, LOG1, FL("Session %d not active\n "), sessionId);
+ return(NULL);
+
+}
+
+
+/*--------------------------------------------------------------------------
+ \brief peFindSessionByStaId() - looks up the PE session given staid.
+
+ This function returns the session context and the session ID if the session
+ corresponding to the given StaId is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param staid - StaId of the session
+ \param sessionId -session ID is returned here, if session is found.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tpPESession peFindSessionByStaId(tpAniSirGlobal pMac, tANI_U8 staid, tANI_U8* sessionId)
+{
+ tANI_U8 i, j;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid)
+ {
+ for(j = 0; j < pMac->lim.gpSession[i].dph.dphHashTable.size; j++)
+ {
+ if((pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].valid) &&
+ (pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].added) &&
+ (staid == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].staIndex))
+ {
+ *sessionId = i;
+ return(&pMac->lim.gpSession[i]);
+ }
+ }
+ }
+ }
+
+ limLog(pMac, LOG4, FL("Session lookup fails for StaId: \n "));
+ return(NULL);
+}
+
+
+
+/*--------------------------------------------------------------------------
+ \brief peDeleteSession() - deletes the PE session given the session ID.
+
+
+ \param pMac - pointer to global adapter context
+ \param sessionId -session ID of the session which needs to be deleted.
+
+ \sa
+ --------------------------------------------------------------------------*/
+void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tANI_U16 i = 0;
+
+ limLog(pMac, LOGW, FL("Trying to delete a session %d.\n "), psessionEntry->peSessionId);
+
+ if(psessionEntry->pLimStartBssReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimStartBssReq );
+ psessionEntry->pLimStartBssReq = NULL;
+ }
+
+ if(psessionEntry->pLimJoinReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimJoinReq );
+ psessionEntry->pLimJoinReq = NULL;
+ }
+
+ if(psessionEntry->pLimReAssocReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimReAssocReq );
+ psessionEntry->pLimReAssocReq = NULL;
+ }
+
+ if(psessionEntry->pLimMlmJoinReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->pLimMlmJoinReq );
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ if(psessionEntry->dph.dphHashTable.pHashTable != NULL)
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->dph.dphHashTable.pHashTable);
+ psessionEntry->dph.dphHashTable.pHashTable = NULL;
+ }
+
+ if(psessionEntry->dph.dphHashTable.pDphNodeArray != NULL)
+ {
+ palFreeMemory(pMac->hHdd, psessionEntry->dph.dphHashTable.pDphNodeArray);
+ psessionEntry->dph.dphHashTable.pDphNodeArray = NULL;
+ }
+
+ if(psessionEntry->beacon != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->beacon);
+ psessionEntry->beacon = NULL;
+ }
+
+ if(psessionEntry->assocReq != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+ }
+
+ if(psessionEntry->assocRsp != NULL)
+ {
+ palFreeMemory( pMac->hHdd, psessionEntry->assocRsp);
+ psessionEntry->assocRsp = NULL;
+ }
+
+
+ if(psessionEntry->parsedAssocReq != NULL)
+ {
+ // Cleanup the individual allocation first
+ for (i=0; i < psessionEntry->dph.dphHashTable.size; i++)
+ {
+ if ( psessionEntry->parsedAssocReq[i] != NULL )
+ {
+ if( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame )
+ {
+ palFreeMemory(pMac->hHdd,
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame);
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame = NULL;
+ ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrameLength = 0;
+ }
+ palFreeMemory(pMac->hHdd, (void *)psessionEntry->parsedAssocReq[i]);
+ psessionEntry->parsedAssocReq[i] = NULL;
+ }
+ }
+ // Cleanup the whole block
+ palFreeMemory(pMac->hHdd, (void *)psessionEntry->parsedAssocReq);
+ psessionEntry->parsedAssocReq = NULL;
+ }
+
+#ifdef FEATURE_WLAN_CCX
+ limCleanupCcxCtxt(pMac, psessionEntry);
+#endif
+
+ psessionEntry->valid = FALSE;
+ return;
+}
+
+
+/*--------------------------------------------------------------------------
+ \brief peFindSessionByPeerSta() - looks up the PE session given the Station Address.
+
+ This function returns the session context and the session ID if the session
+ corresponding to the given station address is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param sa - Peer STA Address of the session
+ \param sessionId -session ID is returned here, if session is found.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+
+tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac, tANI_U8* sa, tANI_U8* sessionId)
+{
+ tANI_U8 i;
+ tpDphHashNode pSta;
+ tANI_U16 aid;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if( (pMac->lim.gpSession[i].valid))
+ {
+ pSta = dphLookupHashEntry(pMac, sa, &aid, &pMac->lim.gpSession[i].dph.dphHashTable);
+ if (pSta != NULL)
+ {
+ *sessionId = i;
+ return &pMac->lim.gpSession[i];
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+
+
+
+
+
+
+
diff --git a/CORE/MAC/src/pe/lim/limSessionUtils.c b/CORE/MAC/src/pe/lim/limSessionUtils.c
new file mode 100644
index 0000000..a07d0c9
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSessionUtils.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/**=========================================================================
+
+ \file limSessionUtils.c
+
+ \brief implementation for lim Session Utility APIs
+
+ \author Sunit Bhatia
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+ ========================================================================*/
+
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include "aniGlobal.h"
+#include "limDebug.h"
+#include "limSession.h"
+#include "limSessionUtils.h"
+#include "limUtils.h"
+
+
+/*--------------------------------------------------------------------------
+ \brief peValidateJoinReq() - validates the Join request .
+
+ This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present
+ this function returns TRUE else returns FALSE.
+ PE will force SME to first issue ''START_BSS' request for BTAMP_STA, before sending a JOIN request.
+
+ \param pMac - pointer to global adapter context
+ \return - return TRUE if start BSS session is present else return FALSE.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac)
+{
+
+ tANI_U8 i;
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if( (pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].bssType == eSIR_BTAMP_STA_MODE) &&
+ (pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF))
+ {
+ return(TRUE);
+ }
+
+ }
+ return(FALSE);
+
+}
+
+/*--------------------------------------------------------------------------
+ \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave .
+
+ This function is called to check the valid session for power save, if more than one session is active , this function
+ it returns NULL.
+ if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry.
+ For all other cases it returns NULL.
+
+ \param pMac - pointer to global adapter context
+ \return - return session is address if valid session is present else return NULL.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+
+tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+ tANI_U8 sessioncount = 0;
+ tANI_U8 sessionId = 0;
+
+ for(i = 0; i < pMac->lim.maxBssId; i++)
+ {
+ if( (pMac->lim.gpSession[i].valid == TRUE)&&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)&&
+ (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+ sessioncount++;
+ sessionId = i;
+
+ if(sessioncount > 1)
+ {
+ return(NULL);
+ }
+ }
+
+ }
+
+ if( (pMac->lim.gpSession[sessionId].valid == TRUE)&&
+ (pMac->lim.gpSession[sessionId].limSystemRole == eLIM_STA_ROLE)&&
+ (pMac->lim.gpSession[sessionId].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))
+
+ {
+ return(&pMac->lim.gpSession[sessionId]);
+ }
+ return(NULL);
+
+}
+/*--------------------------------------------------------------------------
+ \brief peIsAnySessionActive() - checks for the active session presence .
+
+ This function returns TRUE if atleast one valid session is present else it returns FALSE
+
+ \param pMac - pointer to global adapter context
+ \return - return TRUE if atleast one session is active else return FALSE.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+
+tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ return(TRUE);
+ }
+
+ }
+ return(FALSE);
+
+}
+
+/*--------------------------------------------------------------------------
+ \brief isLimSessionOffChannel() - Determines if the there is any other off channel
+ session.
+
+ This function returns TRUE if the session Id passed needs to be on a different
+ channel than atleast one session already active.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId - session ID of the session to be verified.
+
+ \return tANI_U8 - Boolean value for off-channel operation.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+tANI_U8
+isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId)
+{
+ tANI_U8 i;
+
+ if(sessionId >= pMac->lim.maxBssId)
+ {
+ limLog(pMac, LOGE, FL("Invalid sessionId: %d \n "), sessionId);
+ return FALSE;
+ }
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if( i == sessionId )
+ {
+ //Skip the sessionId that is to be joined.
+ continue;
+ }
+ //if snother ession is valid and it is on different channel
+ //it is an off channel operation.
+ if( (pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].currentOperChannel !=
+ pMac->lim.gpSession[sessionId].currentOperChannel) )
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+
+}
+
+tANI_U8
+peGetActiveSessionChannel (tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ //if snother ession is valid and it is on different channel
+ //it is an off channel operation.
+ if(pMac->lim.gpSession[i].valid)
+ {
+ return pMac->lim.gpSession[i].currentOperChannel;
+ }
+ }
+
+ return 0;
+
+}
+
diff --git a/CORE/MAC/src/pe/lim/limSessionUtils.h b/CORE/MAC/src/pe/lim/limSessionUtils.h
new file mode 100644
index 0000000..4127827
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSessionUtils.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+
+#if!defined( __LIM_SESSION_UTILS_H )
+#define __LIM_SESSION_UTILS_H
+
+
+/**=========================================================================
+
+ \file limSessionUtils.h
+
+ \brief prototype for lim Session Utility related APIs
+
+ \author Sunit Bhatia
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+
+ Qualcomm Confidential and Proprietary.
+
+ ========================================================================*/
+
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+
+
+
+/*--------------------------------------------------------------------------
+ Preprocessor definitions and constants
+ ------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------
+ Type declarations
+ ------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------
+ Function declarations and documenation
+ ------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------
+ \brief peValidateJoinReq() - validates the Join request .
+
+ This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present
+ this function returns TRUE else returns FALSE.
+
+ \param pMac - pointer to global adapter context
+ \return - return TRUE if start BSS session is present else return FALSE.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac);
+
+/* --------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------
+ \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave .
+
+ This function is called to check the valid session for power save, if more than one session is active , this function
+ it returns NULL.
+ if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry.
+ For all other cases it returns NULL.
+
+ \param pMac - pointer to global adapter context
+ \return - return session is address if valid session is present else return NULL.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+
+tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac);
+
+/* --------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------
+ \brief peIsAnySessionActive() - checks for the active session presence .
+
+ This function returns TRUE if atleast one valid session is present else it returns FALSE
+
+ \param pMac - pointer to global adapter context
+ \return - return TRUE if atleast one session is active else return FALSE.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac);
+/* --------------------------------------------------------------------------*/
+
+
+
+/*--------------------------------------------------------------------------
+ \brief isLimSessionOffChannel() - Determines if the session is
+ off channel.
+
+ This function returns TRUE if the session Id passed needs to be on a different
+ channel than atleast one session already active.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId - session ID of the session to be verified.
+
+ \return tANI_U8 - Boolean value for off-channel operation.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tANI_U8
+isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId);
+/* --------------------------------------------------------------------------*/
+
+tANI_U8
+peGetActiveSessionChannel( tpAniSirGlobal pMac );
+#endif //#if !defined( __LIM_SESSION_UTILS_H )
+
diff --git a/CORE/MAC/src/pe/lim/limSmeReqUtils.c b/CORE/MAC/src/pe/lim/limSmeReqUtils.c
new file mode 100644
index 0000000..f0a687e
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSmeReqUtils.c
@@ -0,0 +1,1274 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSmeReqUtils.cc contains the utility functions
+ * for processing SME request messages.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "wniApi.h"
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+#include "wniCfgAp.h"
+#else
+#include "wniCfgSta.h"
+#endif
+#include "cfgApi.h"
+#include "sirApi.h"
+#include "schApi.h"
+#include "utilsApi.h"
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "limSerDesUtils.h"
+
+
+
+/**
+ * limIsRSNieValidInSmeReqMessage()
+ *
+ *FUNCTION:
+ * This function is called to verify if the RSN IE
+ * received in various SME_REQ messages is valid or not
+ *
+ *LOGIC:
+ * RSN IE validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pRSNie Pointer to received RSN IE
+ * @return true when RSN IE is valid, false otherwise
+ */
+
+static tANI_U8
+limIsRSNieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirRSNie pRSNie)
+{
+ tANI_U8 startPos = 0;
+ tANI_U32 privacy, val;
+ int len;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &privacy) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve POI from CFG\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED,
+ &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve RSN_ENABLED from CFG\n"));
+ }
+
+ if (pRSNie->length && (!privacy || !val))
+ {
+ // Privacy & RSN not enabled in CFG.
+ /**
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d\n"),
+ pRSNie->length, privacy, val);)
+ }
+
+ if (pRSNie->length)
+ {
+ if ((pRSNie->rsnIEdata[0] != DOT11F_EID_RSN) &&
+ (pRSNie->rsnIEdata[0] != DOT11F_EID_WPA)
+#ifdef FEATURE_WLAN_WAPI
+ && (pRSNie->rsnIEdata[0] != DOT11F_EID_WAPI)
+#endif
+ )
+ {
+ limLog(pMac, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]\n"),
+ pRSNie->rsnIEdata[0], DOT11F_EID_RSN,
+ DOT11F_EID_WPA);
+ return false;
+ }
+
+ len = pRSNie->length;
+ startPos = 0;
+ while(len > 0)
+ {
+ // Check validity of RSN IE
+ if (pRSNie->rsnIEdata[startPos] == DOT11F_EID_RSN)
+ {
+ if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_RSN_MAX_LEN) ||
+ (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_RSN_MIN_LEN))
+ {
+ limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]\n"),
+ pRSNie->rsnIEdata[startPos+1], DOT11F_IE_RSN_MIN_LEN,
+ DOT11F_IE_RSN_MAX_LEN);
+ return false;
+ }
+ }
+ else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WPA)
+ {
+ // Check validity of WPA IE
+ val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[startPos + 2]);
+ if((pRSNie->rsnIEdata[startPos + 1] < DOT11F_IE_WPA_MIN_LEN) ||
+ (pRSNie->rsnIEdata[startPos + 1] > DOT11F_IE_WPA_MAX_LEN) ||
+ (SIR_MAC_WPA_OUI != val))
+ {
+ limLog(pMac, LOGE,
+ FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x\n"),
+ pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WPA_MIN_LEN,
+ DOT11F_IE_WPA_MAX_LEN, val, SIR_MAC_WPA_OUI);
+
+ return false;
+ }
+ }
+#ifdef FEATURE_WLAN_WAPI
+ else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WAPI)
+ {
+ if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_WAPI_MAX_LEN) ||
+ (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_WAPI_MIN_LEN))
+ {
+ limLog(pMac, LOGE,
+ FL("WAPI IE len %d not [%d,%d]\n"),
+ pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WAPI_MIN_LEN,
+ DOT11F_IE_WAPI_MAX_LEN);
+
+ return false;
+ }
+ }
+#endif
+ else
+ {
+ //we will never be here, simply for completeness
+ return false;
+ }
+ startPos += 2 + pRSNie->rsnIEdata[startPos+1]; //EID + length field + length
+ len -= startPos;
+ }//while
+
+ }
+
+ return true;
+} /*** end limIsRSNieValidInSmeReqMessage() ***/
+
+/**
+ * limIsAddieValidInSmeReqMessage()
+ *
+ *FUNCTION:
+ * This function is called to verify if the Add IE
+ * received in various SME_REQ messages is valid or not
+ *
+ *LOGIC:
+ * Add IE validity checks are performed on only length
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pWSCie Pointer to received WSC IE
+ * @return true when WSC IE is valid, false otherwise
+ */
+
+static tANI_U8
+limIsAddieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirAddie pAddie)
+{
+ int left = pAddie->length;
+ tANI_U8 *ptr = pAddie->addIEdata;
+ tANI_U8 elem_id, elem_len;
+
+ if (left == 0)
+ return true;
+
+ while(left >= 2)
+ {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if(elem_len > left)
+ {
+ limLog( pMac, LOGE,
+ FL("****Invalid Add IEs eid = %d elem_len=%d left=%d*****\n"),
+ elem_id,elem_len,left);
+ return false;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ // there shouldn't be any left byte
+
+
+ return true;
+} /*** end limIsAddieValidInSmeReqMessage() ***/
+
+#ifdef WLAN_SOFTAP_FEATURE
+/**
+ * limSetRSNieWPAiefromSmeStartBSSReqMessage()
+ *
+ *FUNCTION:
+ * This function is called to verify if the RSN IE
+ * received in various SME_REQ messages is valid or not
+ *
+ *LOGIC:
+ * RSN IE validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pRSNie Pointer to received RSN IE
+ * @return true when RSN IE is valid, false otherwise
+ */
+
+tANI_U8
+limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac,
+ tpSirRSNie pRSNie,
+ tpPESession pSessionEntry)
+{
+ tANI_U8 wpaIndex = 0;
+ tANI_U32 privacy, val;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &privacy) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve POI from CFG\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED,
+ &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve RSN_ENABLED from CFG\n"));
+ }
+
+ if (pRSNie->length && (!privacy || !val))
+ {
+ // Privacy & RSN not enabled in CFG.
+ /**
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d\n"),
+ pRSNie->length, privacy, val);)
+ }
+
+ if (pRSNie->length)
+ {
+ if ((pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) &&
+ (pRSNie->rsnIEdata[0] != SIR_MAC_WPA_EID))
+ {
+ limLog(pMac, LOGE, FL("RSN/WPA EID %d not [%d || %d]\n"),
+ pRSNie->rsnIEdata[0], SIR_MAC_RSN_EID,
+ SIR_MAC_WPA_EID);
+ return false;
+ }
+
+ // Check validity of RSN IE
+ if ((pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID) &&
+#if 0 // Comparison always false
+ (pRSNie->rsnIEdata[1] > SIR_MAC_RSN_IE_MAX_LENGTH) ||
+#endif
+ (pRSNie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH))
+ {
+ limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]\n"),
+ pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
+ SIR_MAC_RSN_IE_MAX_LENGTH);
+ return false;
+ }
+
+ if (pRSNie->length > pRSNie->rsnIEdata[1] + 2)
+ {
+ if (pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID)
+ {
+ limLog(pMac,
+ LOGE,
+ FL("First byte[%d] in rsnIEdata is not RSN_EID\n"),
+ pRSNie->rsnIEdata[1]);
+ return false;
+ }
+
+ limLog(pMac,
+ LOG1,
+ FL("WPA IE is present along with WPA2 IE\n"));
+ wpaIndex = 2 + pRSNie->rsnIEdata[1];
+ }
+ else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) &&
+ (pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID))
+ {
+ limLog(pMac,
+ LOG1,
+ FL("Only RSN IE is present\n"));
+ dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2],
+ (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe);
+ }
+ else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) &&
+ (pRSNie->rsnIEdata[0] == SIR_MAC_WPA_EID))
+ {
+ limLog(pMac,
+ LOG1,
+ FL("Only WPA IE is present\n"));
+
+ dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6],(tANI_U8)pRSNie->length-4,
+ &pSessionEntry->gStartBssWPAIe);
+ }
+
+ // Check validity of WPA IE
+ val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[wpaIndex + 2]);
+
+ if ((pRSNie->rsnIEdata[wpaIndex] == SIR_MAC_WPA_EID) &&
+#if 0 // Comparison always false
+ (pRSNie->rsnIEdata[wpaIndex + 1] > SIR_MAC_WPA_IE_MAX_LENGTH) ||
+#endif
+ ((pRSNie->rsnIEdata[wpaIndex + 1] < SIR_MAC_WPA_IE_MIN_LENGTH) ||
+ (SIR_MAC_WPA_OUI != val)))
+ {
+ limLog(pMac, LOGE,
+ FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x\n"),
+ pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
+ SIR_MAC_RSN_IE_MAX_LENGTH, val, SIR_MAC_WPA_OUI);
+
+ return false;
+ }
+ else
+ {
+ /* Both RSN and WPA IEs are present */
+ dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2],
+ (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe);
+
+ dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[wpaIndex + 6],
+ pRSNie->rsnIEdata[wpaIndex + 1]-4,
+ &pSessionEntry->gStartBssWPAIe);
+
+ }
+ }
+
+ return true;
+} /*** end limSetRSNieWPAiefromSmeStartBSSReqMessage() ***/
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+/**
+ * limIsBssInfoValidInSmeReqMessage()
+ *
+ *FUNCTION:
+ * This function is called to verify if the BSS info
+ * received in various SME_REQ messages is valid or not
+ *
+ *LOGIC:
+ * BSS info validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBssInfo Pointer to received Bss Information
+ * @return true when BSS info is valid, false otherwise
+ */
+
+static tANI_U8
+limIsBssInfoValidInSmeReqMessage(tpAniSirGlobal pMac,
+ tpSirNeighborBssInfo pBssInfo)
+{
+ tANI_U8 valid = true;
+
+ if ((pBssInfo->bssType != eSIR_INFRASTRUCTURE_MODE) ||
+ limIsGroupAddr(pBssInfo->bssId) ||
+ !pBssInfo->channelId ||
+ !pBssInfo->ssId.length ||
+ (pBssInfo->ssId.length > SIR_MAC_MAX_SSID_LENGTH) ||
+ !limIsRSNieValidInSmeReqMessage(pMac, &pBssInfo->rsnIE))
+ {
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsBssInfoValidInSmeReqMessage() ***/
+#else
+
+
+
+/**
+ * limIsBssDescrValidInSmeReqMessage()
+ *
+ *FUNCTION:
+ * This function is called to verify if the BSS Descr
+ * received in various SME_REQ messages is valid or not
+ *
+ *LOGIC:
+ * BSS Descritipion validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBssDescr Pointer to received Bss Descritipion
+ * @return true when BSS description is valid, false otherwise
+ */
+
+static tANI_U8
+limIsBssDescrValidInSmeReqMessage(tpAniSirGlobal pMac,
+ tpSirBssDescription pBssDescr)
+{
+ tANI_U8 valid = true;
+
+ if (limIsAddrBC(pBssDescr->bssId) ||
+ !pBssDescr->channelId)
+ {
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsBssDescrValidInSmeReqMessage() ***/
+#endif
+
+
+
+/**
+ * limIsSmeStartReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_START_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMsg - Pointer to received SME_START_BSS_REQ message
+ * @return true when received SME_START_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeStartReqValid(tpAniSirGlobal pMac, tANI_U32 *pMsg)
+{
+ tANI_U8 valid = true;
+
+ if (((tpSirSmeStartReq) pMsg)->length != sizeof(tSirSmeStartReq))
+ {
+ /**
+ * Invalid length in START_REQ message
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("Invalid length %d in eWNI_SME_START_REQ\n"),
+ ((tpSirSmeStartReq) pMsg)->length);
+
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeStartReqValid() ***/
+
+
+
+/**
+ * limIsSmeStartBssReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_START_BSS_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pStartBssReq Pointer to received SME_START_BSS_REQ message
+ * @return true when received SME_START_BSS_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeStartBssReqValid(tpAniSirGlobal pMac,
+ tpSirSmeStartBssReq pStartBssReq)
+{
+ tANI_U8 i = 0;
+ tANI_U8 valid = true;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d, SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d\n"),
+ pStartBssReq->bssType,
+ pStartBssReq->channelId,
+ pStartBssReq->ssId.length,
+ pStartBssReq->rsnIE.length,
+ pStartBssReq->nwType,
+ pStartBssReq->operationalRateSet.numRates);)
+
+ switch (pStartBssReq->bssType)
+ {
+ case eSIR_INFRASTRUCTURE_MODE:
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ /* Check for the AP Role/Station role here and act accordingly.
+ * Currently assuming this as AP and breaks TODO */
+ break;
+#endif
+ /**
+ * Should not have received start BSS req with bssType
+ * Infrastructure on STA.
+ * Log error.
+ */
+ limLog(pMac, LOGE, FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ\n"),pStartBssReq->bssType);
+ valid = false;
+ goto end;
+ break;
+
+ case eSIR_IBSS_MODE:
+ break;
+
+ /* Added for BT AMP support */
+ case eSIR_BTAMP_STA_MODE:
+ break;
+
+ /* Added for BT AMP support */
+ case eSIR_BTAMP_AP_MODE:
+ break;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ /* Added for SoftAP support */
+ case eSIR_INFRA_AP_MODE:
+ break;
+#endif
+
+ default:
+ /**
+ * Should not have received start BSS req with bssType
+ * other than Infrastructure/IBSS.
+ * Log error
+ */
+ limLog(pMac, LOGW,
+ FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ\n"),
+ pStartBssReq->bssType);
+
+ valid = false;
+ goto end;
+ }
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+
+ /* Assumed as AP again, need to check the role and change accordingly */
+ if (pStartBssReq->bssType == eSIR_INFRASTRUCTURE_MODE)
+ {
+ if ((pStartBssReq->numSSID == 1) && pStartBssReq->ssId.length &&
+ ((pStartBssReq->ssId.length != pStartBssReq->ssIdList[0].length) ||
+ ( !palEqualMemory( pMac->hHdd,pStartBssReq->ssId.ssId,
+ pStartBssReq->ssIdList[0].ssId,
+ pStartBssReq->ssId.length) )))
+ {
+ /**
+ * Invalid combination of ssID length
+ * and number of SSIDs present.
+ * Reject START_BSS_REQ.
+ */
+ limLog(pMac, LOGW,
+ FL("Mismatch in SSID length & numSSID in SME_START_BSS_REQ\n"));
+
+ valid = false;
+ goto end;
+ }
+
+ if (!pStartBssReq->numSSID ||
+ (pStartBssReq->ssId.length && (pStartBssReq->numSSID != 1)))
+ {
+ /**
+ * Invalid combination of ssID length
+ * and number of SSIDs present.
+ * Reject START_BSS_REQ.
+ */
+ limLog(pMac, LOGW,
+ FL("Mismatch in SSID length[%d] & numSSID[%d] in SME_START_BSS_REQ\n"),
+ pStartBssReq->ssId.length, pStartBssReq->numSSID);
+
+ valid = false;
+ goto end;
+ }
+ }
+#endif
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ /* This below code is client specific code. TODO */
+ if (pStartBssReq->bssType == eSIR_IBSS_MODE)
+ {
+ if (!pStartBssReq->ssId.length ||
+ (pStartBssReq->ssId.length > SIR_MAC_MAX_SSID_LENGTH))
+ {
+ // Invalid length for SSID.
+ // Reject START_BSS_REQ
+ limLog(pMac, LOGW,
+ FL("Invalid SSID length in eWNI_SME_START_BSS_REQ\n"));
+
+ valid = false;
+ goto end;
+ }
+ }
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ /* Assumed as AP TODO */
+ if (pStartBssReq->bssType == eSIR_INFRASTRUCTURE_MODE)
+ {
+ tpSirAlternateRadioInfo pRadioInfo;
+
+ pRadioInfo = pStartBssReq->alternateRadioList.alternateRadio;
+ for (i = 0; i < pStartBssReq->alternateRadioList.numBss; i++)
+ {
+ if (limIsGroupAddr(pRadioInfo->bssId))
+ {
+ // Invalid mate BSSID.
+ // Reject START_BSS_REQ
+ limLog(pMac, LOGW,
+ FL("Invalid mate BSSID in eWNI_SME_START_BSS_REQ\n"));
+
+ valid = false;
+ goto end;
+ }
+ pRadioInfo += sizeof(tSirAlternateRadioInfo);
+ }
+
+ /*
+ ** check WDS info length
+ **/
+ if (pStartBssReq->wdsInfo.wdsLength > ANI_WDS_INFO_MAX_LENGTH)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Illegal WDS info length\n"));)
+ valid = false;
+ goto end;
+ }
+ }
+#endif
+
+ if (!limIsRSNieValidInSmeReqMessage(pMac, &pStartBssReq->rsnIE))
+ {
+ valid = false;
+ goto end;
+ }
+
+ if (pStartBssReq->nwType != eSIR_11A_NW_TYPE &&
+ pStartBssReq->nwType != eSIR_11B_NW_TYPE &&
+ pStartBssReq->nwType != eSIR_11G_NW_TYPE)
+ {
+ valid = false;
+ goto end;
+ }
+
+ if (pStartBssReq->nwType == eSIR_11A_NW_TYPE)
+ {
+ for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
+ if (!sirIsArate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
+ {
+ // Invalid Operational rates
+ // Reject START_BSS_REQ
+ limLog(pMac, LOGW,
+ FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
+ pStartBssReq->operationalRateSet.rate,
+ pStartBssReq->operationalRateSet.numRates);
+
+ valid = false;
+ goto end;
+ }
+ }
+ // check if all the rates in the operatioal rate set are legal 11G rates
+ else if (pStartBssReq->nwType == eSIR_11G_NW_TYPE)
+ {
+ for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
+ if (!sirIsGrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
+ {
+ // Invalid Operational rates
+ // Reject START_BSS_REQ
+ limLog(pMac, LOGW,
+ FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
+ pStartBssReq->operationalRateSet.rate,
+ pStartBssReq->operationalRateSet.numRates);
+
+ valid = false;
+ goto end;
+ }
+ }
+ else
+ {
+ for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
+ if (!sirIsBrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
+ {
+ // Invalid Operational rates
+ // Reject START_BSS_REQ
+ limLog(pMac, LOGW,
+ FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
+ sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
+ pStartBssReq->operationalRateSet.rate,
+ pStartBssReq->operationalRateSet.numRates);
+
+ valid = false;
+ goto end;
+ }
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeStartBssReqValid() ***/
+
+
+
+/**
+ * limIsSmeJoinReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_JOIN_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pJoinReq Pointer to received SME_JOIN_REQ message
+ * @return true when received SME_JOIN_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeJoinReqValid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
+{
+ tANI_U8 valid = true;
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ if (pJoinReq->assocType > eSIR_TRANSFERRED)
+ {
+ /// Received eWNI_SME_JOIN_REQ with invalid assocType
+ // Log the event
+ limLog(pMac, LOGW,
+ FL("received SME_JOIN_REQ with invalid assocType\n"));
+
+ valid = false;
+ goto end;
+ }
+#endif
+
+ if (!limIsRSNieValidInSmeReqMessage(pMac, &pJoinReq->rsnIE))
+ {
+ limLog(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid RSNIE\n"));
+ valid = false;
+ goto end;
+ }
+
+ if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEScan))
+ {
+ limLog(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid additional IE for scan\n"));
+ valid = false;
+ goto end;
+ }
+
+ if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEAssoc))
+ {
+ limLog(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid additional IE for assoc\n"));
+ valid = false;
+ goto end;
+ }
+
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ if (!limIsBssInfoValidInSmeReqMessage(
+ pMac,
+ pJoinReq->neighborBssList.bssList))
+#else
+ if (!limIsBssDescrValidInSmeReqMessage(pMac,
+ &pJoinReq->bssDescription))
+#endif
+ {
+ /// Received eWNI_SME_JOIN_REQ with invalid BSS Info
+ // Log the event
+ limLog(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid bssInfo\n"));
+
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeJoinReqValid() ***/
+
+
+
+/**
+ * limIsSmeDisassocReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_DISASSOC_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message
+ * @return true When received SME_DISASSOC_REQ is formatted
+ * correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeDisassocReqValid(tpAniSirGlobal pMac,
+ tpSirSmeDisassocReq pDisassocReq, tpPESession psessionEntry)
+{
+ if (limIsGroupAddr(pDisassocReq->peerMacAddr) &&
+ !limIsAddrBC(pDisassocReq->peerMacAddr))
+ return false;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ ((pDisassocReq->aid < 2) || (pDisassocReq->aid > 2007))) ||
+ ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
+ (pDisassocReq->aid != 1)))
+ return false;
+#endif
+
+ return true;
+} /*** end limIsSmeDisassocReqValid() ***/
+
+
+
+/**
+ * limIsSmeDisassocCnfValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_DISASSOC_CNF message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message
+ * @return true When received SME_DISASSOC_CNF is formatted
+ * correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeDisassocCnfValid(tpAniSirGlobal pMac,
+ tpSirSmeDisassocCnf pDisassocCnf, tpPESession psessionEntry)
+{
+ if (limIsGroupAddr(pDisassocCnf->peerMacAddr))
+ return false;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ ((pDisassocCnf->aid < 2) || (pDisassocCnf->aid > 2007))) ||
+ ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
+ (pDisassocCnf->aid != 1)))
+ return false;
+#endif
+ return true;
+} /*** end limIsSmeDisassocCnfValid() ***/
+
+
+
+/**
+ * limIsSmeDeauthReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_DEAUTH_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message
+ * @return true When received SME_DEAUTH_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeDeauthReqValid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq, tpPESession psessionEntry)
+{
+ if (limIsGroupAddr(pDeauthReq->peerMacAddr) &&
+ !limIsAddrBC(pDeauthReq->peerMacAddr))
+ return false;
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+ if (((psessionEntryp->limSystemRole == eLIM_AP_ROLE) &&
+ ((pDeauthReq->aid < 2) || (pDeauthReq->aid > 2007))) ||
+ ((psessionEntryp->limSystemRole == eLIM_STA_ROLE) &&
+ (pDeauthReq->aid != 1)))
+ return false;
+#endif
+ return true;
+} /*** end limIsSmeDeauthReqValid() ***/
+
+
+
+/**
+ * limIsSmeScanReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_SCAN_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pScanReq Pointer to received SME_SCAN_REQ message
+ * @return true when received SME_SCAN_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq)
+{
+ tANI_U8 valid = true;
+ tANI_U8 i = 0;
+
+ for (i = 0; i < pScanReq->numSsid; i++)
+ {
+ if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH)
+ {
+ valid = false;
+ goto end;
+ }
+ }
+ if ((pScanReq->bssType > eSIR_AUTO_MODE) ||
+ (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) ||
+ (!(pScanReq->scanType == eSIR_PASSIVE_SCAN || pScanReq->scanType == eSIR_ACTIVE_SCAN)) ||
+ (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS))
+ {
+ valid = false;
+ goto end;
+ }
+
+ /*
+ ** check min/max channelTime range
+ **/
+
+ if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) &&
+ (pScanReq->maxChannelTime < pScanReq->minChannelTime))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Max Channel Time < Min Channel Time\n"));)
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeScanReqValid() ***/
+
+
+
+/**
+ * limIsSmeAuthReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_AUTH_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pAuthReq Pointer to received SME_AUTH_REQ message
+ * @return true when received SME_AUTH_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeAuthReqValid(tpSirSmeAuthReq pAuthReq)
+{
+ tANI_U8 valid = true;
+
+ if (limIsGroupAddr(pAuthReq->peerMacAddr) ||
+ (pAuthReq->authType > eSIR_AUTO_SWITCH) ||
+ !pAuthReq->channelNumber)
+ {
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeAuthReqValid() ***/
+
+
+
+/**
+ * limIsSmeSetContextReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_SET_CONTEXT_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message
+ * @return true when received SME_SET_CONTEXT_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeSetContextReqValid(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq)
+{
+ tANI_U8 i = 0;
+ tANI_U8 valid = true;
+ tpSirKeys pKey = pSetContextReq->keyMaterial.key;
+
+ if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) &&
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) &&
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) &&
+#ifdef FEATURE_WLAN_WAPI
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) &&
+#endif
+ !pSetContextReq->keyMaterial.numKeys)
+ {
+ /**
+ * No keys present in case of TKIP or CCMP
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("No keys present in SME_SETCONTEXT_REQ for edType=%d\n"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+
+ if (pSetContextReq->keyMaterial.numKeys &&
+ (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE))
+ {
+ /**
+ * Keys present in case of no ED policy
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("Keys present in SME_SETCONTEXT_REQ for edType=%d\n"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+
+ if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED)
+ {
+ /**
+ * Invalid edType in the message
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("Invalid edType=%d in SME_SETCONTEXT_REQ\n"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+ else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE)
+ {
+ tANI_U32 poi;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &poi) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to retrieve POI from CFG\n"));
+ }
+
+ if (!poi)
+ {
+ /**
+ * Privacy is not enabled
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ PELOG1(limLog(pMac, LOG1,
+ FL("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ\n"),
+ pSetContextReq->keyMaterial.edType);)
+ }
+ }
+
+ for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++)
+ {
+ if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) &&
+ (pKey->keyLength != 5)) ||
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) &&
+ (pKey->keyLength != 13)) ||
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) &&
+ (pKey->keyLength != 32)) ||
+#ifdef FEATURE_WLAN_WAPI
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) &&
+ (pKey->keyLength != 32)) ||
+#endif
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) &&
+ (pKey->keyLength != 16)))
+ {
+ /**
+ * Invalid key length for a given ED type
+ * Log error.
+ */
+ limLog(pMac, LOGW,
+ FL("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ\n"),
+ pKey->keyLength, pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+ pKey++;
+ }
+
+end:
+ return valid;
+} /*** end limIsSmeSetContextReqValid() ***/
+
+
+
+/**
+ * limIsSmeStopBssReqValid()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() upon
+ * receiving SME_STOP_BSS_REQ message from application.
+ *
+ *LOGIC:
+ * Message validity checks are performed in this function
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMsg - Pointer to received SME_STOP_BSS_REQ message
+ * @return true when received SME_STOP_BSS_REQ is formatted correctly
+ * false otherwise
+ */
+
+tANI_U8
+limIsSmeStopBssReqValid(tANI_U32 *pMsg)
+{
+ tANI_U8 valid = true;
+
+ return valid;
+} /*** end limIsSmeStopBssReqValid() ***/
+
+
+/**
+ * limGetBssIdFromSmeJoinReqMsg()
+ *
+ *FUNCTION:
+ * This function is called in various places to get BSSID
+ * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/
+ * SME_REASSOC_REQ message.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ
+ * message
+ * @return pBssId - Pointer to BSSID
+ */
+
+tANI_U8*
+limGetBssIdFromSmeJoinReqMsg(tANI_U8 *pBuf)
+{
+ if (!pBuf)
+ return NULL;
+
+ pBuf += sizeof(tANI_U32); // skip message header
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ pBuf += sizeof(tSirAssocType); // skip assocType
+#endif
+
+ pBuf += limGetU16(pBuf) + sizeof(tANI_U16); // skip RSN IE
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
+ pBuf += sizeof(tAniBool); // skip BP indicator
+ pBuf += sizeof(tSirBpIndicatorType); // skip BP indicator type
+ pBuf += sizeof(tANI_U32); // skip number of neighbor BSS
+#else
+ pBuf += sizeof(tANI_U16); // skip length of BSS description
+#endif
+
+ return (pBuf);
+} /*** end limGetBssIdFromSmeJoinReqMsg() ***/
+
+
diff --git a/CORE/MAC/src/pe/lim/limSmeReqUtils.h b/CORE/MAC/src/pe/lim/limSmeReqUtils.h
new file mode 100644
index 0000000..91edf54
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limSmeReqUtils.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limSmeReqUtils.h contains the utility definitions
+ * LIM uses while processing SME request messsages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SME_REQ_UTILS_H
+#define __LIM_SME_REQ_UTILS_H
+
+#include "sirApi.h"
+#include "limTypes.h"
+
+
+// LIM SME requst messages related utilility functions
+tANI_U8 limIsSmeStartReqValid(tpAniSirGlobal, tANI_U32 *);
+tANI_U8 limIsSmeStartBssReqValid(tpAniSirGlobal, tpSirSmeStartBssReq);
+tANI_U8 limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal,
+ tpSirRSNie,
+ tpPESession);
+tANI_U8 limIsSmeScanReqValid(tpAniSirGlobal, tpSirSmeScanReq);
+tANI_U8 limIsSmeJoinReqValid(tpAniSirGlobal, tpSirSmeJoinReq);
+tANI_U8 limIsSmeAuthReqValid(tpSirSmeAuthReq);
+tANI_U8 limIsSmeDisassocReqValid(tpAniSirGlobal, tpSirSmeDisassocReq, tpPESession);
+tANI_U8 limIsSmeDeauthReqValid(tpAniSirGlobal, tpSirSmeDeauthReq, tpPESession);
+tANI_U8 limIsSmeSetContextReqValid(tpAniSirGlobal, tpSirSmeSetContextReq);
+tANI_U8 limIsSmeStopBssReqValid(tANI_U32 *);
+tANI_U8* limGetBssIdFromSmeJoinReqMsg(tANI_U8 *);
+tANI_U8 limIsSmeDisassocCnfValid(tpAniSirGlobal, tpSirSmeDisassocCnf, tpPESession);
+
+#endif /* __LIM_SME_REQ_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limStaHashApi.c b/CORE/MAC/src/pe/lim/limStaHashApi.c
new file mode 100644
index 0000000..27a4078
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limStaHashApi.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * limStaHashApi.c: Provides access functions to get/set values of station hash entry fields.
+ * Author: Sunit Bhatia
+ * Date: 09/19/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#include "limStaHashApi.h"
+
+
+/**
+ * limGetStaHashBssidx()
+ *
+ *FUNCTION:
+ * This function is called to Get the Bss Index of the currently associated Station.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param assocId AssocID of the Station.
+ * @param bssidx pointer to the bss index, which will be returned by the function.
+ *
+ * @return success if GET operation is ok, else Failure.
+ */
+
+tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx, tpPESession psessionEntry)
+{
+ tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("invalid STA %d\n"), assocId);)
+ return eSIR_LIM_INVALID_STA;
+ }
+
+ *bssidx = (tANI_U8)pSta->bssId;
+ return eSIR_SUCCESS;
+}
+
+
+
diff --git a/CORE/MAC/src/pe/lim/limStaHashApi.h b/CORE/MAC/src/pe/lim/limStaHashApi.h
new file mode 100644
index 0000000..9b9a6be
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limStaHashApi.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limStaHashApi.h contains the
+ * function prototypes for accessing station hash entry fields.
+ *
+ * Author: Sunit Bhatia
+ * Date: 09/19/2006
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_STA_HASH_API_H__
+#define __LIM_STA_HASH_API_H__
+
+
+#include "aniGlobal.h"
+#include "limTypes.h"
+
+tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx,tpPESession psessionEntry);
+
+#endif
+
+
+
+
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.c b/CORE/MAC/src/pe/lim/limTimerUtils.c
new file mode 100644
index 0000000..fd0b2a5
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.c
@@ -0,0 +1,2206 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limTimerUtils.cc contains the utility functions
+ * LIM uses for handling various timers.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "limTypes.h"
+#include "limUtils.h"
+#include "limAssocUtils.h"
+#include "limSecurityUtils.h"
+#include "pmmApi.h"
+
+
+// default value 5000 ms for background scan period when it is disabled
+#define LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS 5000
+// channel Switch Timer in ticks
+#define LIM_CHANNEL_SWITCH_TIMER_TICKS 1
+// Lim Quite timer in ticks
+#define LIM_QUIET_TIMER_TICKS 100
+// Lim Quite BSS timer inteval in ticks
+#define LIM_QUIET_BSS_TIMER_TICK 100
+// Lim KeepAlive timer default (3000)ms
+#define LIM_KEEPALIVE_TIMER_MS 3000
+
+//default beacon interval value used in HB timer interval calculation
+#define LIM_HB_TIMER_BEACON_INTERVAL 100
+/**
+ * limCreateTimers()
+ *
+ *FUNCTION:
+ * This function is called upon receiving
+ * 1. SME_START_REQ for STA in ESS role
+ * 2. SME_START_BSS_REQ for AP role & STA in IBSS role
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+
+void
+limCreateTimers(tpAniSirGlobal pMac)
+{
+ tANI_U32 cfgValue, i;
+
+ PELOG1(limLog(pMac, LOG1, FL("Creating Timers used by LIM module in Role %d\n"), pMac->lim.gLimSystemRole);)
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get MinChannelTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP, FL("could not retrieve MinChannelTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create MIN/MAX channel timers and activate them later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimMinChannelTimer,
+ "MIN CHANNEL TIMEOUT",
+ limTimerHandler, SIR_LIM_MIN_CHANNEL_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start min channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create MIN channel timer\n"));
+
+ return;
+ }
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.limTimers.gLimMinChannelTimer, LIM_TIMER_EXPIRY_LIST);
+#endif
+
+ PELOG2(limLog(pMac, LOG2, FL("Created MinChannelTimer\n"));)
+
+ /* Periodic probe request timer value is half of the Min channel
+ * timer. Probe request sends periodically till min/max channel
+ * timer expires
+ */
+
+ cfgValue = cfgValue/2 ;
+ if( cfgValue >= 1)
+ {
+ // Create periodic probe request timer and activate them later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer,
+ "Periodic Probe Request Timer",
+ limTimerHandler, SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start Periodic Probe Req timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create periodic probe timer\n"));
+ return;
+ }
+ }
+
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get MAXChannelTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve MAXChannelTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimMaxChannelTimer,
+ "MAX CHANNEL TIMEOUT",
+ limTimerHandler, SIR_LIM_MAX_CHANNEL_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start max channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create MAX channel timer\n"));
+
+ return;
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.limTimers.gLimMaxChannelTimer, LIM_TIMER_EXPIRY_LIST);
+#endif
+
+ PELOG2(limLog(pMac, LOG2, FL("Created MaxChannelTimer\n"));)
+
+ if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE)
+ {
+ // Create Channel Switch Timer
+ if (tx_timer_create(&pMac->lim.limTimers.gLimChannelSwitchTimer,
+ "CHANNEL SWITCH TIMER",
+ limChannelSwitchTimerHandler,
+ 0, // expiration_input
+ LIM_CHANNEL_SWITCH_TIMER_TICKS, // initial_ticks
+ 0, // reschedule_ticks
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("failed to create Channel Switch timer\n"));
+ return;
+ }
+
+ //
+ // Create Quiet Timer
+ // This is used on the STA to go and shut-off
+ // Tx/Rx "after" the specified quiteInterval
+ //
+ if (tx_timer_create(&pMac->lim.limTimers.gLimQuietTimer,
+ "QUIET TIMER",
+ limQuietTimerHandler,
+ SIR_LIM_QUIET_TIMEOUT, // expiration_input
+ LIM_QUIET_TIMER_TICKS, // initial_ticks
+ 0, // reschedule_ticks
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer\n"));
+ return;
+ }
+
+ //
+ // Create Quiet BSS Timer
+ // After the specified quiteInterval, determined by
+ // gLimQuietTimer, this timer, gLimQuietBssTimer,
+ // trigger and put the STA to sleep for the specified
+ // gLimQuietDuration
+ //
+ if (tx_timer_create(&pMac->lim.limTimers.gLimQuietBssTimer,
+ "QUIET BSS TIMER",
+ limQuietBssTimerHandler,
+ SIR_LIM_QUIET_BSS_TIMEOUT, // expiration_input
+ LIM_QUIET_BSS_TIMER_TICK, // initial_ticks
+ 0, // reschedule_ticks
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer\n"));
+ return;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get JoinFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve JoinFailureTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create Join failure timer and activate it later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimJoinFailureTimer,
+ "JOIN FAILURE TIMEOUT",
+ limTimerHandler, SIR_LIM_JOIN_FAIL_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create Join failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Join failure timer\n"));
+
+ return;
+ }
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(&pMac->lim.limTimers.gLimJoinFailureTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AssocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AssocFailureTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create Association failure timer and activate it later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAssocFailureTimer,
+ "ASSOC FAILURE TIMEOUT",
+ limAssocFailureTimerHandler, LIM_ASSOC,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create Assoc failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not create Association failure timer\n"));
+
+ return;
+ }
+ if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve ReassocFailureTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create Association failure timer and activate it later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimReassocFailureTimer,
+ "REASSOC FAILURE TIMEOUT",
+ limAssocFailureTimerHandler, LIM_REASSOC,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create Reassoc failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not create Reassociation failure timer\n"));
+
+ return;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &cfgValue) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_ADDTS_RSP_TIMEOUT \n"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create Addts response timer and activate it later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAddtsRspTimer,
+ "ADDTS RSP TIMEOUT",
+ limAddtsResponseTimerHandler,
+ SIR_LIM_ADDTS_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create Auth failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Addts response timer\n"));
+
+ return;
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ // Create Auth failure timer and activate it later
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAuthFailureTimer,
+ "AUTH FAILURE TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_AUTH_FAIL_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not create Auth failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Auth failure timer\n"));
+
+ return;
+ }
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(&pMac->lim.limTimers.gLimAuthFailureTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get BEACON_INTERVAL value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve BEACON_INTERVAL value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimHeartBeatTimer,
+ "Heartbeat TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_HEART_BEAT_TIMEOUT,
+ cfgValue,
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start Heartbeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to create heartbeat timer failed\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get PROBE_AFTER_HB_FAILURE
+ * value from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value\n"));
+ }
+
+ // Change timer to reactivate it in future
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+ "Probe after Heartbeat TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_PROBE_HB_FAILURE_TIMEOUT,
+ cfgValue,
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Could not creat wt-probe-after-HeartBeat-failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to create ProbeAfterHBTimer\n"));
+ }
+
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Background scan period value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Background scan period value\n"));
+ }
+
+ /*
+ * setting period to zero means disabling background scans when associated
+ * the way we do this is to set a flag indicating this and keeping
+ * the timer running, since it will be used for PDU leak workarounds
+ * as well as background scanning during SME idle states
+ */
+ if (cfgValue == 0)
+ {
+ cfgValue = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS;
+ pMac->lim.gLimBackgroundScanDisable = true;
+ }
+ else
+ pMac->lim.gLimBackgroundScanDisable = false;
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimBackgroundScanTimer,
+ "Background scan TIMEOUT",
+ limTimerHandler,
+ SIR_LIM_CHANNEL_SCAN_TIMEOUT,
+ cfgValue,
+ cfgValue,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start background scan timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to create background scan timer failed\n"));
+ }
+#endif
+ }
+
+
+ cfgValue = SYS_MS_TO_TICKS(LIM_HASH_MISS_TIMER_MS);
+
+ if (tx_timer_create(
+ &pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer,
+ "Disassoc throttle TIMEOUT",
+ limSendDisassocFrameThresholdHandler,
+ SIR_LIM_HASH_MISS_THRES_TIMEOUT,
+ cfgValue,
+ cfgValue,
+ TX_AUTO_ACTIVATE) != TX_SUCCESS)
+ {
+ /// Could not start Send Disassociate Frame Threshold timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("create Disassociate throttle timer failed\n"));
+ }
+#if defined(ANI_OS_TYPE_RTAI_LINUX)
+ tx_timer_set_expiry_list(
+ &pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer,
+ LIM_TIMER_EXPIRY_LIST);
+#endif
+ PELOG1(limLog(pMac, LOG1,
+ FL("Created Disassociate throttle timer \n"));)
+
+ /**
+ * Create keepalive timer and activate it right away for AP role
+ */
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get keepalive timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve keepalive timeout value\n"));
+ }
+
+ // A value of zero implies keep alive should be disabled
+ if (cfgValue == 0)
+ {
+ cfgValue = LIM_KEEPALIVE_TIMER_MS;
+ pMac->sch.keepAlive = 0;
+ } else
+ pMac->sch.keepAlive = 1;
+
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue + SYS_TICK_DUR_MS - 1);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimKeepaliveTimer,
+ "KEEPALIVE_TIMEOUT",
+ limKeepaliveTmerHandler,
+ 0,
+ cfgValue,
+ cfgValue,
+ (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ?
+ TX_AUTO_ACTIVATE : TX_NO_ACTIVATE)
+ != TX_SUCCESS)
+ {
+ // Cannot create keepalive timer. Log error.
+ limLog(pMac, LOGP, FL("Cannot create keepalive timer.\n"));
+ }
+
+ /**
+ * Create all CNF_WAIT Timers upfront
+ */
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get CNF_WAIT timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve CNF timeout value\n"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ for (i=0; i<pMac->lim.maxStation; i++)
+ {
+ if (tx_timer_create(&pMac->lim.limTimers.gpLimCnfWaitTimer[i],
+ "CNF_MISS_TIMEOUT",
+ limCnfWaitTmerHandler,
+ (tANI_U32)i,
+ cfgValue,
+ 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Cannot create timer. Log error.
+ limLog(pMac, LOGP, FL("Cannot create CNF wait timer.\n"));
+ }
+ }
+
+ /*
+ ** Alloc and init table for the preAuth timer list
+ **
+ **/
+
+ // get max number of Preauthentication
+ if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /*
+ ** Could not get max preauth value
+ ** from CFG. Log error.
+ **/
+ limLog(pMac, LOGP,
+ FL("could not retrieve mac preauth value\n"));
+ }
+#ifdef ANI_AP_SDK_OPT
+ if(cfgValue > SIR_SDK_OPT_MAX_NUM_PRE_AUTH)
+ cfgValue = SIR_SDK_OPT_MAX_NUM_PRE_AUTH;
+#endif // ANI_AP_SDK_OPT
+ pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue;
+ if (palAllocateMemory(pMac->hHdd, (void **) &pMac->lim.gLimPreAuthTimerTable.pTable,
+ cfgValue*sizeof(tLimPreAuthNode)) != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed!\n"));
+ return;
+ }
+
+ limInitPreAuthTimerTable(pMac, &pMac->lim.gLimPreAuthTimerTable);
+ PELOG1(limLog(pMac, LOG1, FL("alloc and init table for preAuth timers\n"));)
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ {
+ /**
+ * Create OLBC cache aging timer
+ */
+ if (wlan_cfgGetInt(pMac, WNI_CFG_OLBC_DETECT_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get OLBC detect timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve OLBD detect timeout value\n"));
+ }
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(
+ &pMac->lim.limTimers.gLimUpdateOlbcCacheTimer,
+ "OLBC UPDATE CACHE TIMEOUT",
+ limUpdateOlbcCacheTimerHandler,
+ SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT,
+ cfgValue,
+ cfgValue,
+ TX_AUTO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Cannot create update OLBC cache timer
+ // Log error
+ limLog(pMac, LOGP, FL("Cannot create update OLBC cache timer\n"));
+ }
+ }
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // In future we need to use the auth timer, cause
+ // the pre auth session will be introduced before sending
+ // Auth frame.
+ // We need to go off channel and come back to home channel
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
+ "FT PREAUTH RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Could not create Join failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Join failure timer\n"));
+ return;
+ }
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ cfgValue = 5000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ if (tx_timer_create(&pMac->lim.limTimers.gLimCcxTsmTimer,
+ "CCX TSM Stats TIMEOUT",
+ limTimerHandler, SIR_LIM_CCX_TSM_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Could not create Join failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Join failure timer\n"));
+ return;
+ }
+#endif
+
+#ifdef WLAN_FEATURE_P2P
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimRemainOnChannelTimer,
+ "FT PREAUTH RSP TIMEOUT",
+ limTimerHandler, SIR_LIM_REMAIN_CHN_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)
+ {
+ // Could not create Join failure timer.
+ // Log error
+ limLog(pMac, LOGP, FL("could not create Join failure timer\n"));
+ return;
+ }
+
+#endif
+ pMac->lim.gLimTimersCreated = 1;
+} /****** end limCreateTimers() ******/
+
+
+
+/**
+ * limTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon
+ * 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning
+ * 2. JOIN_FAILURE timer expiration while joining a BSS
+ * 3. AUTH_FAILURE timer expiration while authenticating with a peer
+ * 4. Heartbeat timer expiration on STA
+ * 5. Background scan timer expiration on STA
+ * 6. AID release, Pre-auth cleanup and Link monitoring timer
+ * expiration on AP
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param param - Message corresponding to the timer that expired
+ *
+ * @return None
+ */
+
+void
+limTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tANI_U32 statusCode;
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ // Prepare and post message to LIM Message Queue
+
+ msg.type = (tANI_U16) param;
+ msg.bodyptr = NULL;
+ msg.bodyval = 0;
+
+ if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
+ limLog(pMac, LOGE,
+ FL("posting message %X to LIM failed, reason=%d\n"),
+ msg.type, statusCode);
+} /****** end limTimerHandler() ******/
+
+
+/**
+ * limAddtsResponseTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon Addts response timer expiration on sta
+ *
+ *LOGIC:
+ * Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void
+limAddtsResponseTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ // Prepare and post message to LIM Message Queue
+
+ msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT;
+ msg.bodyval = param;
+ msg.bodyptr = NULL;
+
+ limPostMsgApi(pMac, &msg);
+} /****** end limAuthResponseTimerHandler() ******/
+
+
+/**
+ * limAuthResponseTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon Auth response timer expiration on AP
+ *
+ *LOGIC:
+ * Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void
+limAuthResponseTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ // Prepare and post message to LIM Message Queue
+
+ msg.type = SIR_LIM_AUTH_RSP_TIMEOUT;
+ msg.bodyptr = NULL;
+ msg.bodyval = (tANI_U32)param;
+
+ limPostMsgApi(pMac, &msg);
+} /****** end limAuthResponseTimerHandler() ******/
+
+
+
+/**
+ * limAssocFailureTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon Re/Assoc failure timer expiration
+ * on STA
+ *
+ *LOGIC:
+ * Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param param - Indicates whether this is assoc or reassoc
+ * failure timeout
+ * @return None
+ */
+
+void
+limAssocFailureTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ // Prepare and post message to LIM Message Queue
+
+ msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+
+ limPostMsgApi(pMac, &msg);
+} /****** end limAssocFailureTimerHandler() ******/
+
+
+/**
+ * limUpdateOlbcCacheTimerHandler()
+ *
+ *FUNCTION:
+ * This function is called upon update olbc cache timer expiration
+ * on STA
+ *
+ *LOGIC:
+ * Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+#ifdef WLAN_SOFTAP_FEATURE
+void
+limUpdateOlbcCacheTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ // Prepare and post message to LIM Message Queue
+
+ msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT;
+ msg.bodyval = 0;
+ msg.bodyptr = NULL;
+
+ limPostMsgApi(pMac, &msg);
+} /****** end limUpdateOlbcCacheTimerHandler() ******/
+#endif
+
+/**
+ * limDeactivateAndChangeTimer()
+ *
+ *FUNCTION:
+ * This function is called to deactivate and change a timer
+ * for future re-activation
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param timerId - enum of timer to be deactivated and changed
+ * This enum is defined in limUtils.h file
+ *
+ * @return None
+ */
+
+void
+limDeactivateAndChangeTimer(tpAniSirGlobal pMac, tANI_U32 timerId)
+{
+ tANI_U32 val=0, val1=0;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, timerId));
+
+ switch (timerId)
+ {
+ case eLIM_ADDTS_RSP_TIMER:
+ pMac->lim.gLimAddtsRspTimerCount++;
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS)
+ {
+ // Could not deactivate AddtsRsp Timer
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate AddtsRsp timer\n"));
+ }
+ break;
+
+ case eLIM_MIN_CHANNEL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate min channel timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate min channel timer\n"));
+ }
+
+ // If a background was triggered via Quiet BSS,
+ // then we need to adjust the MIN and MAX channel
+ // timer's accordingly to the Quiet duration that
+ // was specified
+ if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState &&
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss )
+ {
+ // gLimQuietDuration is already cached in units of
+ // system ticks. No conversion is reqd...
+ val = pMac->lim.gLimSpecMgmt.quietDuration;
+ }
+ else
+ {
+ if(pMac->lim.gpLimMlmScanReq)
+ {
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime);
+ }
+ else
+ {
+ limLog(pMac, LOGE, FL(" gpLimMlmScanReq is NULL "));
+ //No need to change min timer. This is not a scan
+ break;
+ }
+ }
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimMinChannelTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change min channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change min channel timer\n"));
+ }
+
+ break;
+
+ case eLIM_PERIODIC_PROBE_REQ_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate min channel timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate periodic timer\n"));
+ }
+
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime)/2;
+ if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change min channel timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change periodic timer\n"));
+ }
+
+ break;
+
+ case eLIM_MAX_CHANNEL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate max channel timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate max channel timer\n"));
+ }
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ // If a background was triggered via Quiet BSS,
+ // then we need to adjust the MIN and MAX channel
+ // timer's accordingly to the Quiet duration that
+ // was specified
+ if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE)
+ {
+
+ if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState &&
+ pMac->lim.gLimTriggerBackgroundScanDuringQuietBss )
+ {
+ // gLimQuietDuration is already cached in units of
+ // system ticks. No conversion is reqd...
+ val = pMac->lim.gLimSpecMgmt.quietDuration;
+ }
+ else
+ {
+ if(pMac->lim.gpLimMlmScanReq)
+ {
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->maxChannelTime);
+ }
+ else
+ {
+ limLog(pMac, LOGE, FL(" gpLimMlmScanReq is NULL "));
+ //No need to change max timer. This is not a scan
+ break;
+ }
+ }
+ }
+#endif
+#if defined(ANI_PRODUCT_TYPE_AP)
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get max channel value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve max channel value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+ }
+#endif
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change max channel timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to change max channel timer\n"));
+ }
+
+ break;
+
+ case eLIM_JOIN_FAIL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer)
+ != TX_SUCCESS)
+ {
+ /**
+ * Could not deactivate Join Failure
+ * timer. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate Join Failure timer\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get JoinFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve JoinFailureTimeout value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("Unable to change Join Failure timer\n"));
+ }
+
+ break;
+
+ case eLIM_AUTH_FAIL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate Auth failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate auth failure timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AuthFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change Authentication failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change Auth failure timer\n"));
+ }
+
+ break;
+
+ case eLIM_ASSOC_FAIL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer) !=
+ TX_SUCCESS)
+ {
+ // Could not deactivate Association failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate Association failure timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+ if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get AssocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve AssocFailureTimeout value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change Association failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change Assoc failure timer\n"));
+ }
+
+ break;
+
+ case eLIM_REASSOC_FAIL_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) !=
+ TX_SUCCESS)
+ {
+ // Could not deactivate Reassociation failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate Reassoc failure timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+ if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve ReassocFailureTimeout value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change Reassociation failure timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change Reassociation failure timer\n"));
+ }
+
+ break;
+
+ case eLIM_HEART_BEAT_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) !=
+ TX_SUCCESS)
+ {
+ // Could not deactivate Heartbeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate Heartbeat timer\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get BEACON_INTERVAL value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve BEACON_INTERVAL value\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) !=
+ eSIR_SUCCESS)
+ limLog(pMac, LOGP,
+ FL("could not retrieve heartbeat failure value\n"));
+
+ // Change timer to reactivate it in future
+ val = SYS_MS_TO_TICKS(val * val1);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change HeartBeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change HeartBeat timer\n"));
+ }
+
+ break;
+
+ case eLIM_PROBE_AFTER_HB_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) !=
+ TX_SUCCESS)
+ {
+ // Could not deactivate Heartbeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate probeAfterHBTimer\n"));
+ }
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get PROBE_AFTER_HB_FAILURE
+ * value from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value\n"));
+ }
+
+ // Change timer to reactivate it in future
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change HeartBeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change ProbeAfterHBTimer\n"));
+ }
+
+ break;
+
+ case eLIM_KEEPALIVE_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate Keepalive timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate KeepaliveTimer timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get keepalive timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve keepalive timeout value\n"));
+ }
+ if (val == 0)
+ {
+ val = 3000;
+ pMac->sch.keepAlive = 0;
+ } else
+ pMac->sch.keepAlive = 1;
+
+
+
+ val = SYS_MS_TO_TICKS(val + SYS_TICK_DUR_MS - 1);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimKeepaliveTimer,
+ val, val) != TX_SUCCESS)
+ {
+ // Could not change KeepaliveTimer timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change KeepaliveTimer timer\n"));
+ }
+
+ break;
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ case eLIM_BACKGROUND_SCAN_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer)
+ != TX_SUCCESS)
+ {
+ // Could not deactivate BackgroundScanTimer timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate BackgroundScanTimer timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get Background scan period value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve Background scan period value\n"));
+ }
+ if (val == 0)
+ {
+ val = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS;
+ pMac->lim.gLimBackgroundScanDisable = true;
+ }
+ else
+ pMac->lim.gLimBackgroundScanDisable = false;
+
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimBackgroundScanTimer,
+ val, val) != TX_SUCCESS)
+ {
+ // Could not change BackgroundScanTimer timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change BackgroundScanTimer timer\n"));
+ }
+
+ break;
+#endif
+
+#ifdef ANI_PRODUCT_TYPE_AP
+ case eLIM_PRE_AUTH_CLEANUP_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPreAuthClnupTimer) !=
+ TX_SUCCESS)
+ {
+ // Could not deactivate Pre-auth cleanup timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to deactivate Pre-auth cleanup timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+ if (wlan_cfgGetInt(pMac, WNI_CFG_PREAUTH_CLNUP_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get pre-auth cleanup value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve pre-auth cleanup value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimPreAuthClnupTimer,
+ val, val) != TX_SUCCESS)
+ {
+ // Could not change pre-auth cleanup timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("unable to change pre-auth cleanup timer\n"));
+ }
+
+ break;
+
+ case eLIM_LEARN_INTERVAL_TIMER:
+ {
+ // Restart Learn Interval timer
+ tANI_U32 learnInterval =
+ pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod /
+ pMac->lim.gpLimMeasReq->channelList.numChannels;
+
+ if (tx_timer_deactivate(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer) != TX_SUCCESS)
+ {
+ // Could not deactivate Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate Learn Interval timer\n"));
+ }
+
+ if (tx_timer_change(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer,
+ SYS_MS_TO_TICKS(learnInterval), 0) != TX_SUCCESS)
+ {
+ // Could not change Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change Learn Interval timer\n"));
+
+ return;
+ }
+
+ limLog( pMac, LOG3,
+ FL("Setting the Learn Interval TIMER to %d ticks\n"),
+ SYS_MS_TO_TICKS(learnInterval));
+ }
+ break;
+
+#endif
+ case eLIM_CHANNEL_SWITCH_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_deactivate failed!\n"));
+ return;
+ }
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer,
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue,
+ 0) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_change failed \n"));
+ return;
+ }
+ break;
+
+ case eLIM_LEARN_DURATION_TIMER:
+#ifdef ANI_PRODUCT_TYPE_AP
+ if (tx_timer_deactivate(&pMac->lim.gLimMeasParams.learnDurationTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not deactivate learn duration timer\n"));
+ return;
+ }
+
+ if (pMac->lim.gpLimMeasReq->measControl.longChannelScanPeriodicity &&
+ (pMac->lim.gLimMeasParams.shortDurationCount ==
+ pMac->lim.gpLimMeasReq->measControl.longChannelScanPeriodicity))
+ {
+#ifdef ANI_AP_SDK
+ val = pMac->lim.gLimScanDurationConvert.longChannelScanDuration_tick;
+#else
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measDuration.longChannelScanDuration
+ + SYS_TICK_DUR_MS - 1);
+ if(val > 1)
+ val--;
+#endif /* ANI_AP_SDK */
+ // Time to perform measurements for longer term
+ if (tx_timer_change(&pMac->lim.gLimMeasParams.learnDurationTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change Learn duration timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change Learn duration timer\n"));
+ return;
+ }
+ pMac->lim.gLimMeasParams.shortDurationCount = 0;
+ }
+ else
+ {
+#ifdef ANI_AP_SDK
+ val = pMac->lim.gLimScanDurationConvert.shortChannelScanDuration_tick;
+#else
+ val = SYS_MS_TO_TICKS(pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration
+ + SYS_TICK_DUR_MS - 1);
+ if(val > 1)
+ val--;
+#endif /* ANI_AP_SDK */
+ if (tx_timer_change(&pMac->lim.gLimMeasParams.learnDurationTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ // Could not change Learn duration timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change Learn duration timer\n"));
+ }
+ }
+ pMac->lim.gpLimMeasData->duration = val * SYS_TICK_DUR_MS;
+#endif
+ break;
+
+ case eLIM_QUIET_BSS_TIMER:
+ if (TX_SUCCESS !=
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer))
+ {
+ limLog( pMac, LOGE,
+ FL("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway...\n"));
+ }
+
+ // gLimQuietDuration appears to be in units of ticks
+ // Use it as is
+ if (TX_SUCCESS !=
+ tx_timer_change( &pMac->lim.limTimers.gLimQuietBssTimer,
+ pMac->lim.gLimSpecMgmt.quietDuration,
+ 0))
+ {
+ limLog( pMac, LOGE,
+ FL("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway...\n"));
+ }
+ break;
+
+ case eLIM_QUIET_TIMER:
+ if( TX_SUCCESS != tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway...\n" ));
+ }
+
+ // Set the NEW timeout value, in ticks
+ if( TX_SUCCESS != tx_timer_change( &pMac->lim.limTimers.gLimQuietTimer,
+ SYS_MS_TO_TICKS(pMac->lim.gLimSpecMgmt.quietTimeoutValue), 0))
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to change gLimQuietTimer! Will still attempt to re-activate anyway...\n" ));
+ }
+ break;
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+#if 0
+ case eLIM_WPS_OVERLAP_TIMER:
+ {
+ // Restart Learn Interval timer
+
+ tANI_U32 WPSOverlapTimer = SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS);
+
+ if (tx_timer_deactivate(
+ &pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS)
+ {
+ // Could not deactivate Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate WPS overlap timer\n"));
+ }
+
+ if (tx_timer_change(
+ &pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer,
+ WPSOverlapTimer, 0) != TX_SUCCESS)
+ {
+ // Could not change Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change WPS overlap timer\n"));
+
+ return;
+ }
+
+ limLog( pMac, LOGE,
+ FL("Setting WPS overlap TIMER to %d ticks\n"),
+ WPSOverlapTimer);
+ }
+ break;
+#endif
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case eLIM_FT_PREAUTH_RSP_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer) != TX_SUCCESS)
+ {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ limLog(pMac, LOGP, FL("Unable to deactivate Preauth response Failure timer\n"));
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ limLog(pMac, LOGP, FL("Unable to change Join Failure timer\n"));
+ }
+ break;
+#endif
+#ifdef FEATURE_WLAN_CCX
+ case eLIM_TSM_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimCcxTsmTimer)
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("Unable to deactivate TSM timer\n"));
+ }
+ break;
+#endif
+#ifdef WLAN_FEATURE_P2P
+ case eLIM_REMAIN_CHN_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer) != TX_SUCCESS)
+ {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ limLog(pMac, LOGP, FL("Unable to deactivate Remain on Chn timer\n"));
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer,
+ val, 0) != TX_SUCCESS)
+ {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ limLog(pMac, LOGP, FL("Unable to change timer\n"));
+ }
+ break;
+#endif
+
+ default:
+ // Invalid timerId. Log error
+ break;
+ }
+} /****** end limDeactivateAndChangeTimer() ******/
+
+
+
+/**---------------------------------------------------------------
+\fn limHeartBeatDeactivateAndChangeTimer
+\brief This function deactivates and changes the heart beat
+\ timer, eLIM_HEART_BEAT_TIMER.
+\
+\param pMac
+\param psessionEntry
+\return None
+------------------------------------------------------------------*/
+void
+limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tANI_U32 val, val1;
+
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to deactivate HeartBeatTimer \n"));
+
+ /* HB Timer sessionisation: In case of 2 or more sessions, the HB interval keeps
+ changing. to avoid this problem, HeartBeat interval is made constant, by
+ fixing beacon interval to 100ms immaterial of the beacon interval of the session */
+
+ //val = psessionEntry->beaconParams.beaconInterval;
+ val = LIM_HB_TIMER_BEACON_INTERVAL;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to get WNI_CFG_HEART_BEAT_THRESHOLD \n"));
+
+ PELOGW(limLog(pMac,LOGW,
+ FL("HB Timer Int.=100ms * %d, Beacon Int.=%dms,Session Id=%d \n"),
+ val1, psessionEntry->beaconParams.beaconInterval,
+ psessionEntry->peSessionId);)
+
+ // Change timer to reactivate it in future
+ val = SYS_MS_TO_TICKS(val * val1);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, val, 0) != TX_SUCCESS)
+ limLog(pMac, LOGP, FL("Fail to change HeartBeatTimer\n"));
+
+} /****** end limHeartBeatDeactivateAndChangeTimer() ******/
+
+
+/**---------------------------------------------------------------
+\fn limReactivateHeartBeatTimer
+\brief This function s called to deactivate, change and
+\ activate a timer.
+\
+\param pMac - Pointer to Global MAC structure
+\param psessionEntry
+\return None
+------------------------------------------------------------------*/
+void
+limReactivateHeartBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ PELOG3(limLog(pMac, LOG3, FL("Rxed Heartbeat. Count=%d\n"), psessionEntry->LimRxedBeaconCntDuringHB);)
+
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+
+ //only start the hearbeat-timer if the timeout value is non-zero
+ if(pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs > 0) {
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer)!= TX_SUCCESS)
+ {
+ limLog(pMac, LOGP,FL("could not activate Heartbeat timer\n"));
+ }
+ limResetHBPktCount(psessionEntry);
+ }
+
+} /****** end limReactivateHeartBeatTimer() ******/
+
+#if 0
+/******
+ * Note: Use this code once you have converted all
+ * limReactivateHeartBeatTimer() calls to
+ * limReactivateTimer() calls.
+ *
+ ******/
+
+Now, in dev/btamp2,
+here are all the references to limReactivateHeartBeatTimer().
+
+C symbol: limReactivateHeartBeatTimer
+
+ File Function Line
+0 limTimerUtils.h <global> 55 void limReactivateHeartBeatTimer(tpAniSirGlobal , tpPESession);
+1 limIbssPeerMgmt.c limIbssHeartBeatHandle 1282 limReactivateHeartBeatTimer(pMac, psessionEntry);
+2 limLinkMonitoringAlgo.c limHandleHeartBeatFailure 395 limReactivateHeartBeatTimer(pMac, psessionEntry);
+3 limLinkMonitoringAlgo.c limHandleHeartBeatFailure 410 limReactivateHeartBeatTimer(pMac, psessionEntry);
+4 limProcessMlmRspMessages. limProcessStaMlmAddStaRsp 2111 limReactivateHeartBeatTimer(pMac, psessionEntry);
+5 limProcessMlmRspMessages_ limProcessStaMlmAddStaRsp 2350 limReactivateHeartBeatTimer(pMac, psessionEntry);
+6 limProcessMlmRspMessages_ limProcessStaMlmAddStaRsp 2111 limReactivateHeartBeatTimer(pMac, psessionEntry);
+7 limTimerUtils.c limReactivateHeartBeatTim 1473 limReactivateHeartBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry)
+8 limUtils.c limHandleHeartBeatFailure 6743 limReactivateHeartBeatTimer(pMac, psessionEntry);
+9 limUtils.c limHandleHeartBeatFailure 6751 limReactivateHeartBeatTimer(pMac, psessionEntry);
+
+Now, in main/latest, on the other hand,
+here are all the references to limReactivateTimer().
+
+C symbol: limReactivateTimer
+
+ File Function Line
+0 limTimerUtils.h <global> 54 void limReactivateTimer(tpAniSirGlobal, tANI_U32);
+1 limIbssPeerMgmt.c limIbssHeartBeatHandle 1183 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+2 limIbssPeerMgmt.c limIbssHeartBeatHandle 1246 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+3 limLinkMonitoringAlgo.c limHandleHeartBeatFailure 283 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+4 limLinkMonitoringAlgo.c limHandleHeartBeatFailure 320 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+5 limLinkMonitoringAlgo.c limHandleHeartBeatFailure 335 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+6 limProcessMessageQueue.c limProcessMessages 1210 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+7 limProcessMessageQueue.c limProcessMessages 1218 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+8 limProcessMlmRspMessages. limProcessStaMlmAddStaRsp 1726 limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER);
+9 limTimerUtils.c limReactivateTimer 1451 limReactivateTimer(tpAniSirGlobal pMac, tANI_U32 timerId)
+
+
+/**
+ * limReactivateTimer()
+ *
+ *FUNCTION:
+ * This function is called to deactivate, change and
+ * activate a timer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param timerId - enum of timer to be deactivated and changed
+ * This enum is defined in limUtils.h file
+ *
+ * @return None
+ */
+
+void
+limReactivateTimer(tpAniSirGlobal pMac, tANI_U32 timerId)
+{
+ if (timerId == eLIM_HEART_BEAT_TIMER)
+ {
+ PELOG3(limLog(pMac, LOG3, FL("Rxed Heartbeat. Count=%d\n"),
+ pMac->lim.gLimRxedBeaconCntDuringHB);)
+ limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if (limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ {
+ /// Could not activate Heartbeat timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not activate Heartbeat timer\n"));
+ }
+ limResetHBPktCount(pMac);
+ }
+} /****** end limReactivateTimer() ******/
+#endif
+
+
+/**
+ * limActivateHearBeatTimer()
+ *
+ *
+ * @brief: This function is called to activate heartbeat timer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return TX_SUCCESS - timer is activated
+ * errors - fail to start the timer
+ */
+v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac)
+{
+ v_UINT_t status = TX_TIMER_ERROR;
+
+ if(TX_AIRGO_TMR_SIGNATURE == pMac->lim.limTimers.gLimHeartBeatTimer.tmrSignature)
+ {
+ //consider 0 interval a ok case
+ if( pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs )
+ {
+ status = tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer);
+ if( TX_SUCCESS != status )
+ {
+ PELOGE(limLog(pMac, LOGE,
+ FL("could not activate Heartbeat timer status(%d)\n"), status);)
+ }
+ }
+ else
+ {
+ status = TX_SUCCESS;
+ }
+ }
+
+ return (status);
+}
+
+
+
+/**
+ * limDeactivateAndChangePerStaIdTimer()
+ *
+ *
+ * @brief: This function is called to deactivate and change a per STA timer
+ * for future re-activation
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param timerId - enum of timer to be deactivated and changed
+ * This enum is defined in limUtils.h file
+ * @param staId - staId
+ *
+ * @return None
+ */
+
+void
+limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal pMac, tANI_U32 timerId, tANI_U16 staId)
+{
+ tANI_U32 val;
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, timerId));
+
+ switch (timerId)
+ {
+ case eLIM_CNF_WAIT_TIMER:
+
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("unable to deactivate CNF wait timer\n"));
+
+ }
+
+ // Change timer to reactivate it in future
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT,
+ &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get cnf timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve cnf timeout value\n"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId],
+ val, val) != TX_SUCCESS)
+ {
+ // Could not change cnf timer.
+ // Log error
+ limLog(pMac, LOGP, FL("unable to change cnf wait timer\n"));
+ }
+
+ break;
+
+ case eLIM_AUTH_RSP_TIMER:
+ {
+ tLimPreAuthNode *pAuthNode;
+
+ pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, staId);
+
+ if (pAuthNode == NULL)
+ {
+ limLog(pMac, LOGP, FL("Invalid Pre Auth Index passed :%d\n"), staId);
+ break;
+ }
+
+ if (tx_timer_deactivate(&pAuthNode->timer) != TX_SUCCESS)
+ {
+ // Could not deactivate auth response timer.
+ // Log error
+ limLog(pMac, LOGP, FL("unable to deactivate auth response timer\n"));
+ }
+
+ // Change timer to reactivate it in future
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, &val) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get auth rsp timeout value
+ * from CFG. Log error.
+ */
+ limLog(pMac, LOGP,
+ FL("could not retrieve auth response timeout value\n"));
+ }
+
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pAuthNode->timer, val, 0) != TX_SUCCESS)
+ {
+ // Could not change auth rsp timer.
+ // Log error
+ limLog(pMac, LOGP, FL("unable to change auth rsp timer\n"));
+ }
+ }
+ break;
+
+#if (defined(ANI_PRODUCT_TYPE_AP) ||defined(ANI_PRODUCT_TYPE_AP_SDK))
+ case eLIM_LEARN_INTERVAL_TIMER:
+ {
+ // Restart Learn Interval timer
+ tANI_U32 learnInterval =
+ pMac->lim.gpLimMeasReq->measDuration.shortTermPeriod /
+ pMac->lim.gpLimMeasReq->channelList.numChannels;
+
+ if (tx_timer_deactivate(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer) != TX_SUCCESS)
+ {
+ // Could not deactivate Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("Unable to deactivate Learn Interval timer\n"));
+ }
+
+ if (tx_timer_change(
+ &pMac->lim.gLimMeasParams.learnIntervalTimer,
+ SYS_MS_TO_TICKS(learnInterval), 0) != TX_SUCCESS)
+ {
+ // Could not change Learn Interval timer.
+ // Log error
+ limLog(pMac, LOGP, FL("Unable to change Learn Interval timer\n"));
+
+ return;
+ }
+
+ limLog( pMac, LOG3,
+ FL("Setting the Learn Interval TIMER to %d ticks\n"),
+ SYS_MS_TO_TICKS(learnInterval) );
+ }
+ break;
+#endif //#if (defined(ANI_PRODUCT_TYPE_AP) ||defined(ANI_PRODUCT_TYPE_AP_SDK))
+
+ default:
+ // Invalid timerId. Log error
+ break;
+
+ }
+}
+
+
+/**
+ * limActivateCnfTimer()
+ *
+ *FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param StaId - staId
+ *
+ * @return None
+ */
+
+void limActivateCnfTimer(tpAniSirGlobal pMac, tANI_U16 staId, tpPESession psessionEntry)
+{
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_CNF_WAIT_TIMER));
+ pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId = psessionEntry->peSessionId;
+ if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("could not activate cnf wait timer\n"));
+ }
+}
+
+/**
+ * limActivateAuthRspTimer()
+ *
+ *FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param id - id
+ *
+ * @return None
+ */
+
+void limActivateAuthRspTimer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode)
+{
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_AUTH_RESP_TIMER));
+ if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS)
+ {
+ /// Could not activate auth rsp timer.
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not activate auth rsp timer\n"));
+ }
+}
+
+
+/**
+ * limSendDisassocFrameThresholdHandler()
+ *
+ *FUNCTION:
+ * This function reloads the credit to the send disassociate frame bucket
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void
+limSendDisassocFrameThresholdHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tANI_U32 statusCode;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_HASH_MISS_THRES_TIMEOUT;
+ msg.bodyval = 0;
+ msg.bodyptr = NULL;
+
+ if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
+ limLog(pMac, LOGE,
+ FL("posting to LIM failed, reason=%d\n"), statusCode);
+
+}
+
+/**
+ * limAssocCnfWaitTmerHandler()
+ *
+ *FUNCTION:
+ * This function post a message to send a disassociate frame out.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void
+limCnfWaitTmerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tANI_U32 statusCode;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_CNF_WAIT_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+
+ if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
+ limLog(pMac, LOGE,
+ FL("posting to LIM failed, reason=%d\n"), statusCode);
+
+}
+
+/**
+ * limKeepaliveTmerHandler()
+ *
+ *FUNCTION:
+ * This function post a message to send a NULL data frame.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void
+limKeepaliveTmerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tANI_U32 statusCode;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_KEEPALIVE_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+
+ if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
+ limLog(pMac, LOGE,
+ FL("posting to LIM failed, reason=%d\n"), statusCode);
+
+}
+
+void
+limChannelSwitchTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("ChannelSwitch Timer expired. Posting msg to LIM \n"));)
+
+ msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+
+ limPostMsgApi(pMac, &msg);
+}
+
+void
+limQuietTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_QUIET_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Post SIR_LIM_QUIET_TIMEOUT msg. \n"));)
+ limPostMsgApi(pMac, &msg);
+}
+
+void
+limQuietBssTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_QUIET_BSS_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+ PELOG1(limLog(pMac, LOG1,
+ FL("Post SIR_LIM_QUIET_BSS_TIMEOUT msg. \n"));)
+ limPostMsgApi(pMac, &msg);
+}
+#ifdef WLAN_SOFTAP_FEATURE
+#if 0
+void
+limWPSOverlapTimerHandler(void *pMacGlobal, tANI_U32 param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
+
+ msg.type = SIR_LIM_WPS_OVERLAP_TIMEOUT;
+ msg.bodyval = (tANI_U32)param;
+ msg.bodyptr = NULL;
+ PELOG1(limLog(pMac, LOG1,
+ FL("Post SIR_LIM_WPS_OVERLAP_TIMEOUT msg. \n"));)
+ limPostMsgApi(pMac, &msg);
+}
+#endif
+#endif
diff --git a/CORE/MAC/src/pe/lim/limTimerUtils.h b/CORE/MAC/src/pe/lim/limTimerUtils.h
new file mode 100644
index 0000000..1719977
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limTimerUtils.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ *
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limTimerUtils.h contains the utility definitions
+ * LIM uses for timer handling.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_TIMER_UTILS_H
+#define __LIM_TIMER_UTILS_H
+
+#include "limTypes.h"
+
+
+// Timer related functions
+enum
+{
+ eLIM_MIN_CHANNEL_TIMER,
+ eLIM_MAX_CHANNEL_TIMER,
+ eLIM_JOIN_FAIL_TIMER,
+ eLIM_AUTH_FAIL_TIMER,
+ eLIM_AUTH_RESP_TIMER,
+ eLIM_ASSOC_FAIL_TIMER,
+ eLIM_REASSOC_FAIL_TIMER,
+ eLIM_PRE_AUTH_CLEANUP_TIMER,
+ eLIM_HEART_BEAT_TIMER,
+ eLIM_BACKGROUND_SCAN_TIMER,
+#ifdef ANI_PRODUCT_TYPE_AP
+ eLIM_LEARN_INTERVAL_TIMER,
+#endif
+ eLIM_KEEPALIVE_TIMER,
+ eLIM_CNF_WAIT_TIMER,
+ eLIM_AUTH_RSP_TIMER,
+ eLIM_UPDATE_OLBC_CACHE_TIMER,
+ eLIM_PROBE_AFTER_HB_TIMER,
+ eLIM_ADDTS_RSP_TIMER,
+ eLIM_CHANNEL_SWITCH_TIMER,
+ eLIM_LEARN_DURATION_TIMER,
+ eLIM_QUIET_TIMER,
+ eLIM_QUIET_BSS_TIMER,
+#ifdef WLAN_SOFTAP_FEATURE
+ eLIM_WPS_OVERLAP_TIMER,
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ eLIM_FT_PREAUTH_RSP_TIMER,
+#endif
+#ifdef WLAN_FEATURE_P2P
+ eLIM_REMAIN_CHN_TIMER,
+#endif
+ eLIM_PERIODIC_PROBE_REQ_TIMER,
+#ifdef FEATURE_WLAN_CCX
+ eLIM_TSM_TIMER,
+#endif
+};
+
+// Timer Handler functions
+void limCreateTimers(tpAniSirGlobal);
+void limTimerHandler(void *, tANI_U32);
+void limAuthResponseTimerHandler(void *, tANI_U32);
+void limAssocFailureTimerHandler(void *, tANI_U32);
+void limReassocFailureTimerHandler(void *, tANI_U32);
+
+void limDeactivateAndChangeTimer(tpAniSirGlobal, tANI_U32);
+void limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal, tpPESession);
+void limReactivateHeartBeatTimer(tpAniSirGlobal, tpPESession);
+void limDummyPktExpTimerHandler(void *, tANI_U32);
+void limSendDisassocFrameThresholdHandler(void *, tANI_U32);
+void limCnfWaitTmerHandler(void *, tANI_U32);
+void limKeepaliveTmerHandler(void *, tANI_U32);
+void limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal, tANI_U32, tANI_U16);
+void limActivateCnfTimer(tpAniSirGlobal, tANI_U16, tpPESession);
+void limActivateAuthRspTimer(tpAniSirGlobal, tLimPreAuthNode *);
+#ifdef WLAN_SOFTAP_FEATURE
+void limUpdateOlbcCacheTimerHandler(void *, tANI_U32);
+#endif
+void limAddtsResponseTimerHandler(void *, tANI_U32);
+void limChannelSwitchTimerHandler(void *, tANI_U32);
+void limQuietTimerHandler(void *, tANI_U32);
+void limQuietBssTimerHandler(void *, tANI_U32);
+void limCBScanIntervalTimerHandler(void *, tANI_U32);
+void limCBScanDurationTimerHandler(void *, tANI_U32);
+/**
+ * limActivateHearBeatTimer()
+ *
+ *
+ * @brief: This function is called to activate heartbeat timer
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return TX_SUCCESS - timer is activated
+ * errors - fail to start the timer
+ */
+v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac);
+
+#ifdef WLAN_SOFTAP_FEATURE
+#if 0
+void limWPSOverlapTimerHandler(void *pMacGlobal, tANI_U32 param);
+#endif
+#endif
+#endif /* __LIM_TIMER_UTILS_H */
diff --git a/CORE/MAC/src/pe/lim/limTrace.c b/CORE/MAC/src/pe/lim/limTrace.c
new file mode 100644
index 0000000..8e13a02
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limTrace.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/**=========================================================================
+
+ \file limTrace.c
+
+ \brief implementation for trace related APIs
+
+ \author Sunit Bhatia
+
+ Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
+
+ Qualcomm Confidential and Proprietary.
+
+ ========================================================================*/
+
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+#include "aniGlobal.h" //for tpAniSirGlobal
+#endif
+
+#include "limTrace.h"
+#include "limTimerUtils.h"
+
+
+#ifdef LIM_TRACE_RECORD
+tANI_U32 gMgmtFrameStats[14];
+
+
+
+static tANI_U8* __limTraceGetTimerString( tANI_U16 timerId )
+{
+ switch( timerId )
+ {
+ CASE_RETURN_STRING(eLIM_MIN_CHANNEL_TIMER);
+ CASE_RETURN_STRING(eLIM_MAX_CHANNEL_TIMER);
+ CASE_RETURN_STRING(eLIM_JOIN_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_RESP_TIMER);
+ CASE_RETURN_STRING(eLIM_ASSOC_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_REASSOC_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_PRE_AUTH_CLEANUP_TIMER);
+ CASE_RETURN_STRING(eLIM_HEART_BEAT_TIMER);
+ CASE_RETURN_STRING(eLIM_BACKGROUND_SCAN_TIMER);
+#ifdef ANI_PRODUCT_TYPE_AP
+ CASE_RETURN_STRING(eLIM_LEARN_INTERVAL_TIMER);
+#endif
+ CASE_RETURN_STRING(eLIM_KEEPALIVE_TIMER);
+ CASE_RETURN_STRING(eLIM_CNF_WAIT_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_UPDATE_OLBC_CACHE_TIMER);
+ CASE_RETURN_STRING(eLIM_PROBE_AFTER_HB_TIMER);
+ CASE_RETURN_STRING(eLIM_ADDTS_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_CHANNEL_SWITCH_TIMER);
+ CASE_RETURN_STRING(eLIM_LEARN_DURATION_TIMER);
+ CASE_RETURN_STRING(eLIM_QUIET_TIMER);
+ CASE_RETURN_STRING(eLIM_QUIET_BSS_TIMER);
+ default:
+ return( "UNKNOWN" );
+ break;
+ }
+}
+
+
+static tANI_U8* __limTraceGetMgmtDropReasonString( tANI_U16 dropReason )
+{
+
+ switch( dropReason )
+ {
+ CASE_RETURN_STRING(eMGMT_DROP_INFRA_BCN_IN_IBSS);
+ CASE_RETURN_STRING(eMGMT_DROP_INVALID_SIZE);
+ CASE_RETURN_STRING(eMGMT_DROP_NON_SCAN_MODE_FRAME);
+ CASE_RETURN_STRING(eMGMT_DROP_NOT_LAST_IBSS_BCN);
+ CASE_RETURN_STRING(eMGMT_DROP_NO_DROP);
+ CASE_RETURN_STRING(eMGMT_DROP_SCAN_MODE_FRAME);
+
+ default:
+ return( "UNKNOWN" );
+ break;
+ }
+}
+
+
+
+void limTraceInit(tpAniSirGlobal pMac)
+{
+ macTraceRegister(pMac, VOS_MODULE_ID_PE, limTraceDump);
+}
+
+
+
+
+void limTraceDump(tpAniSirGlobal pMac, tpTraceRecord pRecord, tANI_U16 recIndex)
+{
+
+ static char *frameSubtypeStr[14] =
+ {
+ "Association request",
+ "Association response",
+ "Reassociation request",
+ "Reassociation response",
+ "Probe request",
+ "Probe response",
+ NULL,
+ NULL,
+ "Beacon",
+ "ATIM",
+ "Disassocation",
+ "Authentication",
+ "Deauthentication",
+ "Action"
+ };
+
+ switch (pRecord->code) {
+ case TRACE_CODE_MLM_STATE:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "MLM State:", limTraceGetMlmStateString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_SME_STATE:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "SME State:", limTraceGetSmeStateString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_TX_MGMT:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "TX Mgmt:", frameSubtypeStr[pRecord->data], pRecord->data );
+ break;
+
+ case TRACE_CODE_RX_MGMT:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(%d) SN: %d \n", recIndex, pRecord->time, pRecord->session,
+ "RX Mgmt:", frameSubtypeStr[LIM_TRACE_GET_SUBTYPE(pRecord->data)],
+ LIM_TRACE_GET_SUBTYPE(pRecord->data),
+ LIM_TRACE_GET_SSN(pRecord->data) );
+ break;
+ case TRACE_CODE_RX_MGMT_DROP:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(%d) \n", recIndex, pRecord->time, pRecord->session,
+ "Drop RX Mgmt:", __limTraceGetMgmtDropReasonString((tANI_U16)pRecord->data), pRecord->data);
+ break;
+
+
+ case TRACE_CODE_RX_MGMT_TSF:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s0x%x(%d) \n", recIndex, pRecord->time, pRecord->session,
+ "RX Mgmt TSF:", " ", pRecord->data, pRecord->data );
+ break;
+
+ case TRACE_CODE_TX_COMPLETE:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s \n", recIndex, pRecord->time, pRecord->session,
+ "TX Complete" );
+ break;
+
+ case TRACE_CODE_TX_SME_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "TX SME Msg:", macTraceGetSmeMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_RX_SME_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX Sme Msg:",
+ macTraceGetSmeMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+
+ case TRACE_CODE_TX_HAL_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "TX HAL Msg:", macTraceGetHalMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+
+ case TRACE_CODE_RX_HAL_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX HAL Msg:",
+ macTraceGetHalMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+
+ case TRACE_CODE_TX_LIM_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "TX LIM Msg:", macTraceGetLimMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_RX_LIM_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX LIM Msg",
+ macTraceGetLimMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_TX_CFG_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "TX CFG Msg:", macTraceGetCfgMsgString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_RX_CFG_MSG:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) ? "Def/Drp LIM Msg:": "RX CFG Msg:",
+ macTraceGetCfgMsgString((tANI_U16)MAC_TRACE_GET_MSG_ID(pRecord->data)),
+ pRecord->data );
+ break;
+
+ case TRACE_CODE_TIMER_ACTIVATE:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "Timer Actvtd", __limTraceGetTimerString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+ case TRACE_CODE_TIMER_DEACTIVATE:
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s %-30s(0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "Timer DeActvtd", __limTraceGetTimerString((tANI_U16)pRecord->data), pRecord->data );
+ break;
+
+ default :
+ limLog(pMac, LOGE, "%04d %012u S%d %-14s(%d) (0x%x) \n", recIndex, pRecord->time, pRecord->session,
+ "Unknown Code", pRecord->code, pRecord->data );
+ break;
+ }
+}
+
+
+void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data)
+{
+
+ tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data);
+ tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data);
+
+ switch(moduleId)
+ {
+ case SIR_LIM_MODULE_ID:
+ if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ macTrace(pMac, TRACE_CODE_TX_LIM_MSG, session, data);
+ else
+ macTrace(pMac, TRACE_CODE_TX_SME_MSG, session, data);
+ break;
+ case SIR_WDA_MODULE_ID:
+ macTrace(pMac, TRACE_CODE_TX_HAL_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ macTrace(pMac, TRACE_CODE_TX_CFG_MSG, session, data);
+ break;
+ }
+}
+
+
+void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data)
+{
+ tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data);
+ tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data);
+
+ switch(moduleId)
+ {
+ case SIR_LIM_MODULE_ID:
+ if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ macTraceNew(pMac, module, TRACE_CODE_TX_LIM_MSG, session, data);
+ else
+ macTraceNew(pMac, module, TRACE_CODE_TX_SME_MSG, session, data);
+ break;
+ case SIR_WDA_MODULE_ID:
+ macTraceNew(pMac, module, TRACE_CODE_TX_HAL_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ macTraceNew(pMac, module, TRACE_CODE_TX_CFG_MSG, session, data);
+ break;
+ }
+}
+
+/*
+* bit31: Rx message defferred or not
+* bit 0-15: message ID:
+*/
+void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data)
+{
+ tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data);
+ tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data);
+
+
+ switch(moduleId)
+ {
+ case SIR_LIM_MODULE_ID:
+ if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ macTrace(pMac, TRACE_CODE_RX_LIM_MSG, session, data);
+ else
+ macTrace(pMac, TRACE_CODE_RX_SME_MSG, session, data);
+ break;
+ case SIR_WDA_MODULE_ID:
+ macTrace(pMac, TRACE_CODE_RX_HAL_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ macTrace(pMac, TRACE_CODE_RX_CFG_MSG, session, data);
+ break;
+ }
+}
+
+
+
+/*
+* bit31: Rx message defferred or not
+* bit 0-15: message ID:
+*/
+void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data)
+{
+ tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data);
+ tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data);
+
+
+ switch(moduleId)
+ {
+ case SIR_LIM_MODULE_ID:
+ if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ macTraceNew(pMac, module, TRACE_CODE_RX_LIM_MSG, session, data);
+ else
+ macTraceNew(pMac, module, TRACE_CODE_RX_SME_MSG, session, data);
+ break;
+ case SIR_WDA_MODULE_ID:
+ macTraceNew(pMac, module, TRACE_CODE_RX_HAL_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ macTraceNew(pMac, module, TRACE_CODE_RX_CFG_MSG, session, data);
+ break;
+ }
+}
+
+
+
+tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState )
+{
+ switch( mlmState )
+ {
+ CASE_RETURN_STRING( eLIM_MLM_OFFLINE_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_IDLE_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_PROBE_RESP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_PASSIVE_SCAN_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_JOIN_BEACON_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_JOINED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_BSS_STARTED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME2_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME3_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME4_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_AUTH_RSP_TIMEOUT_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_AUTHENTICATED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_REASSOC_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_ASSOCIATED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_REASSOCIATED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_LINK_ESTABLISHED_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_CNF_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_LEARN_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADD_STA_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_DEL_STA_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_SET_BSS_KEY_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_KEY_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_BCASTKEY_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_ADDBA_RSP_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_STA_KEY_STATE);
+ CASE_RETURN_STRING( eLIM_MLM_WT_SET_MIMOPS_STATE);
+ default:
+ return( "UNKNOWN" );
+ break;
+ }
+}
+
+
+tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState )
+{
+ switch( smeState )
+ {
+
+ CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_IDLE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE);
+ default:
+ return( "UNKNOWN" );
+ break;
+ }
+}
+
+
+
+
+
+
+#endif
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
new file mode 100644
index 0000000..cebffee
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -0,0 +1,1087 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limTypes.h contains the definitions used by all
+ * all LIM modules.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_TYPES_H
+#define __LIM_TYPES_H
+
+#include "wniApi.h"
+#include "sirApi.h"
+#include "sirCommon.h"
+#include "sirMacProtDef.h"
+#include "utilsApi.h"
+
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+#include "halCommonApi.h"
+#endif
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+#include "wlan_qct_wdi_ds.h"
+#endif
+
+#include "limApi.h"
+#include "limDebug.h"
+#include "limSendSmeRspMessages.h"
+#include "sysGlobal.h"
+#include "dphGlobal.h"
+#include "parserApi.h"
+
+#define LINK_TEST_DEFER 1
+
+#define TRACE_EVENT_CNF_TIMER_DEACT 0x6600
+#define TRACE_EVENT_CNF_TIMER_ACT 0x6601
+#define TRACE_EVENT_AUTH_RSP_TIMER_DEACT 0x6602
+#define TRACE_EVENT_AUTH_RSP_TIMER_ACT 0x6603
+
+// MLM message types
+#define LIM_MLM_MSG_START 1000
+#define LIM_MLM_SCAN_REQ LIM_MLM_MSG_START
+#define LIM_MLM_SCAN_CNF LIM_MLM_MSG_START + 1
+#define LIM_MLM_START_REQ LIM_MLM_MSG_START + 2
+#define LIM_MLM_START_CNF LIM_MLM_MSG_START + 3
+#define LIM_MLM_JOIN_REQ LIM_MLM_MSG_START + 4
+#define LIM_MLM_JOIN_CNF LIM_MLM_MSG_START + 5
+#define LIM_MLM_AUTH_REQ LIM_MLM_MSG_START + 6
+#define LIM_MLM_AUTH_CNF LIM_MLM_MSG_START + 7
+#define LIM_MLM_AUTH_IND LIM_MLM_MSG_START + 8
+#define LIM_MLM_ASSOC_REQ LIM_MLM_MSG_START + 9
+#define LIM_MLM_ASSOC_CNF LIM_MLM_MSG_START + 10
+#define LIM_MLM_ASSOC_IND LIM_MLM_MSG_START + 11
+#define LIM_MLM_DISASSOC_REQ LIM_MLM_MSG_START + 12
+#define LIM_MLM_DISASSOC_CNF LIM_MLM_MSG_START + 13
+#define LIM_MLM_DISASSOC_IND LIM_MLM_MSG_START + 14
+#define LIM_MLM_REASSOC_REQ LIM_MLM_MSG_START + 15
+#define LIM_MLM_REASSOC_CNF LIM_MLM_MSG_START + 16
+#define LIM_MLM_REASSOC_IND LIM_MLM_MSG_START + 17
+#define LIM_MLM_DEAUTH_REQ LIM_MLM_MSG_START + 18
+#define LIM_MLM_DEAUTH_CNF LIM_MLM_MSG_START + 19
+#define LIM_MLM_DEAUTH_IND LIM_MLM_MSG_START + 20
+#define LIM_MLM_TSPEC_REQ LIM_MLM_MSG_START + 21
+#define LIM_MLM_TSPEC_CNF LIM_MLM_MSG_START + 22
+#define LIM_MLM_TSPEC_IND LIM_MLM_MSG_START + 23
+#define LIM_MLM_SETKEYS_REQ LIM_MLM_MSG_START + 24
+#define LIM_MLM_SETKEYS_CNF LIM_MLM_MSG_START + 25
+#define LIM_MLM_LINK_TEST_STOP_REQ LIM_MLM_MSG_START + 30
+#define LIM_MLM_PURGE_STA_IND LIM_MLM_MSG_START + 31
+#define LIM_MLM_ADDBA_REQ LIM_MLM_MSG_START + 32
+#define LIM_MLM_ADDBA_CNF LIM_MLM_MSG_START + 33
+#define LIM_MLM_ADDBA_IND LIM_MLM_MSG_START + 34
+#define LIM_MLM_ADDBA_RSP LIM_MLM_MSG_START + 35
+#define LIM_MLM_DELBA_REQ LIM_MLM_MSG_START + 36
+#define LIM_MLM_DELBA_CNF LIM_MLM_MSG_START + 37
+#define LIM_MLM_DELBA_IND LIM_MLM_MSG_START + 38
+#define LIM_MLM_REMOVEKEY_REQ LIM_MLM_MSG_START + 39
+#define LIM_MLM_REMOVEKEY_CNF LIM_MLM_MSG_START + 40
+
+
+#define LIM_HASH_ADD 0
+#define LIM_HASH_UPDATE 1
+
+#define LIM_WEP_IN_FC 1
+#define LIM_NO_WEP_IN_FC 0
+
+#define LIM_DECRYPT_ICV_FAIL 1
+
+/// Definitions to distinquish between Association/Reassociaton
+#define LIM_ASSOC 0
+#define LIM_REASSOC 1
+
+/// Minimum Memory blocks require for different scenario
+#define LIM_MIN_MEM_ASSOC 4
+
+/// Verifies whether given mac addr matches the CURRENT Bssid
+#define IS_CURRENT_BSSID(pMac, addr,psessionEntry) (palEqualMemory(pMac->hHdd, addr, \
+ psessionEntry->bssId, \
+ sizeof(psessionEntry->bssId)))
+/// Verifies whether given addr matches the REASSOC Bssid
+#define IS_REASSOC_BSSID(pMac, addr,psessionEntry) (palEqualMemory(pMac->hHdd, addr, \
+ psessionEntry->limReAssocbssId, \
+ sizeof(psessionEntry->limReAssocbssId)))
+
+#define REQ_TYPE_REGISTRAR (0x2)
+#define REQ_TYPE_WLAN_MANAGER_REGISTRAR (0x3)
+
+#define RESP_TYPE_REGISTRAR (0x2)
+#define RESP_TYPE_ENROLLEE_INFO_ONLY (0x0)
+#define RESP_TYPE_ENROLLEE_OPEN_8021X (0x1)
+#define RESP_TYPE_AP (0x3)
+#define LIM_TX_FRAMES_THRESHOLD_ON_CHIP 300
+
+
+// enums used by LIM are as follows
+
+enum eLimDisassocTrigger
+{
+ eLIM_HOST_DISASSOC,
+ eLIM_PEER_ENTITY_DISASSOC,
+ eLIM_LINK_MONITORING_DISASSOC,
+ eLIM_PROMISCUOUS_MODE_DISASSOC,
+ eLIM_HOST_DEAUTH,
+ eLIM_PEER_ENTITY_DEAUTH,
+ eLIM_LINK_MONITORING_DEAUTH,
+ eLIM_JOIN_FAILURE,
+ eLIM_REASSOC_REJECT
+};
+
+/* Reason code to determine the channel change context while sending
+ * WDA_CHNL_SWITCH_REQ message to HAL
+ */
+enum eChannelChangeReasonCodes
+{
+ LIM_SWITCH_CHANNEL_REASSOC,
+ LIM_SWITCH_CHANNEL_JOIN,
+ LIM_SWITCH_CHANNEL_OPERATION, // Generic change channel
+};
+
+typedef struct sLimAuthRspTimeout
+{
+ tSirMacAddr peerMacAddr;
+} tLimAuthRspTimeout;
+
+typedef struct sLimMlmStartReq
+{
+ tSirMacSSid ssId;
+ tSirBssType bssType;
+ tSirMacAddr bssId;
+ tSirMacBeaconInterval beaconPeriod;
+ tANI_U8 dtimPeriod;
+ tSirMacCfParamSet cfParamSet;
+ tSirMacChanNum channelNumber;
+ tAniCBSecondaryMode cbMode;
+ tANI_U16 atimWindow;
+ tSirMacRateSet rateSet;
+ tANI_U8 sessionId; //Added For BT-AMP Support
+
+ // Parameters reqd for new HAL (message) interface
+ tSirNwType nwType;
+ tANI_U8 htCapable;
+ tSirMacHTOperatingMode htOperMode;
+ tANI_U8 dualCTSProtection;
+ tANI_U8 txChannelWidthSet;
+#ifdef WLAN_SOFTAP_FEATURE
+ tANI_U8 ssidHidden;
+ tANI_U8 wps_state;
+ tANI_U8 obssProtEnabled;
+#endif
+} tLimMlmStartReq, *tpLimMlmStartReq;
+
+typedef struct sLimMlmStartCnf
+{
+ tSirResultCodes resultCode;
+ tANI_U8 sessionId;
+} tLimMlmStartCnf, *tpLimMlmStartCnf;
+
+typedef struct sLimMlmScanCnf
+{
+ tSirResultCodes resultCode;
+ tANI_U16 scanResultLength;
+ tSirBssDescription bssDescription[1];
+ tANI_U8 sessionId;
+} tLimMlmScanCnf, *tpLimMlmScanCnf;
+
+typedef struct sLimScanResult
+{
+ tANI_U16 numBssDescriptions;
+ tSirBssDescription bssDescription[1];
+} tLimScanResult;
+
+typedef struct sLimMlmJoinCnf
+{
+ tSirResultCodes resultCode;
+ tANI_U16 protStatusCode;
+ tANI_U8 sessionId;
+} tLimMlmJoinCnf, *tpLimMlmJoinCnf;
+
+typedef struct sLimMlmAssocReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U32 assocFailureTimeout;
+ tANI_U16 capabilityInfo;
+ tSirMacListenInterval listenInterval;
+ tANI_U8 sessionId;
+} tLimMlmAssocReq, *tpLimMlmAssocReq;
+
+typedef struct sLimMlmAssocCnf
+{
+ tSirResultCodes resultCode; //Internal status code.
+ tANI_U16 protStatusCode; //Protocol Status code.
+ tANI_U8 sessionId;
+} tLimMlmAssocCnf, *tpLimMlmAssocCnf;
+
+typedef struct sLimMlmAssocInd
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 aid;
+ tAniAuthType authType;
+ tAniSSID ssId;
+ tSirRSNie rsnIE;
+ tSirAddie addIE; // additional IE recevied from the peer, which possibly includes WSC IE and/or P2P IE.
+ tSirMacCapabilityInfo capabilityInfo;
+ tAniTitanHtCapabilityInfo titanHtCaps;
+
+ tAniBool spectrumMgtIndicator;
+ tSirMacPowerCapInfo powerCap;
+ tSirSupChnl supportedChannels;
+ tANI_U8 sessionId;
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ tAniBool WmmStaInfoPresent;
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U16 seqNum;
+ tAniBool wniIndicator;
+ tAniBool bpIndicator;
+ tSirBpIndicatorType bpType;
+ tSirNwType nwType;
+ tSirAssocType assocType; // Indicates whether STA is LB'ed or not
+ tSirLoad load; // Current load on the radio for LB
+ tANI_U32 numBss; // List received from STA
+ tSirNeighborBssInfo neighborList[1]; // List received from STA
+#endif
+ // Required for indicating the frames to upper layer
+ tANI_U32 beaconLength;
+ tANI_U8* beaconPtr;
+ tANI_U32 assocReqLength;
+ tANI_U8* assocReqPtr;
+} tLimMlmAssocInd, *tpLimMlmAssocInd;
+
+typedef struct sLimMlmReassocReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U32 reassocFailureTimeout;
+ tANI_U16 capabilityInfo;
+ tSirMacListenInterval listenInterval;
+ tANI_U8 sessionId;
+} tLimMlmReassocReq, *tpLimMlmReassocReq;
+
+typedef struct sLimMlmReassocCnf
+{
+ tSirResultCodes resultCode;
+ tANI_U16 protStatusCode; //Protocol Status code.
+ tANI_U8 sessionId;
+} tLimMlmReassocCnf, *tpLimMlmReassocCnf;
+
+typedef struct sLimMlmReassocInd
+{
+ tSirMacAddr peerMacAddr;
+ tSirMacAddr currentApAddr;
+ tANI_U16 aid;
+ tAniAuthType authType;
+ tAniSSID ssId;
+ tSirRSNie rsnIE;
+ tSirAddie addIE; // additional IE recevied from the peer, which can be WSC IE and/or P2P IE.
+ tSirMacCapabilityInfo capabilityInfo;
+ tAniTitanHtCapabilityInfo titanHtCaps;
+
+ tAniBool spectrumMgtIndicator;
+ tSirMacPowerCapInfo powerCap;
+ tSirSupChnl supportedChannels;
+
+#ifdef WLAN_SOFTAP_FEATURE
+ tAniBool WmmStaInfoPresent;
+#endif
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ tANI_U16 seqNum;
+ tAniBool wniIndicator;
+ tAniBool bpIndicator;
+ tSirBpIndicatorType bpType;
+ tSirNwType nwType;
+ tSirAssocType reassocType; // Indicates whether STA is LB'ed or not
+ tSirLoad load; // Current load on the radio for LB
+ tANI_U32 numBss; // List received from STA
+ tSirNeighborBssInfo neighborList[1]; // List received from STA
+#endif
+ // Required for indicating the frames to upper layer
+ tANI_U32 beaconLength;
+ tANI_U8* beaconPtr;
+ tANI_U32 assocReqLength;
+ tANI_U8* assocReqPtr;
+} tLimMlmReassocInd, *tpLimMlmReassocInd;
+
+typedef struct sLimMlmAuthCnf
+{
+ tSirMacAddr peerMacAddr;
+ tAniAuthType authType;
+ tSirResultCodes resultCode;
+ tANI_U16 protStatusCode;
+ tANI_U8 sessionId;
+} tLimMlmAuthCnf, *tpLimMlmAuthCnf;
+
+typedef struct sLimMlmAuthInd
+{
+ tSirMacAddr peerMacAddr;
+ tAniAuthType authType;
+ tANI_U8 sessionId;
+} tLimMlmAuthInd, *tpLimMlmAuthInd;
+
+typedef struct sLimMlmDeauthReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 reasonCode;
+ tANI_U16 deauthTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId; //Added for BT-AMP SUPPORT
+
+} tLimMlmDeauthReq, *tpLimMlmDeauthReq;
+
+typedef struct sLimMlmDeauthCnf
+{
+ tSirMacAddr peerMacAddr;
+ tSirResultCodes resultCode;
+ tANI_U16 deauthTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmDeauthCnf, *tpLimMLmDeauthCnf;
+
+typedef struct sLimMlmDeauthInd
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 reasonCode;
+ tANI_U16 deauthTrigger;
+ tANI_U16 aid;
+} tLimMlmDeauthInd, *tpLimMlmDeauthInd;
+
+typedef struct sLimMlmDisassocReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 reasonCode;
+ tANI_U16 disassocTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmDisassocReq, *tpLimMlmDisassocReq;
+
+typedef struct sLimMlmDisassocCnf
+{
+ tSirMacAddr peerMacAddr;
+ tSirResultCodes resultCode;
+ tANI_U16 disassocTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmDisassocCnf, *tpLimMlmDisassocCnf;
+
+typedef struct sLimMlmDisassocInd
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 reasonCode;
+ tANI_U16 disassocTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmDisassocInd, *tpLimMlmDisassocInd;
+
+typedef struct sLimMlmPurgeStaReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 aid;
+ tANI_U8 sessionId;//Added For BT-AMP Support
+} tLimMlmPurgeStaReq, *tpLimMlmPurgeStaReq;
+
+typedef struct sLimMlmPurgeStaInd
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 reasonCode;
+ tANI_U16 purgeTrigger;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmPurgeStaInd, *tpLimMlmPurgeStaInd;
+
+typedef struct sLimMlmSetKeysReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U8 sessionId; //Added For BT-AMP Support
+ tANI_U16 aid;
+ tAniEdType edType; // Encryption/Decryption type
+ tANI_U8 numKeys;
+ tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS];
+} tLimMlmSetKeysReq, *tpLimMlmSetKeysReq;
+
+typedef struct sLimMlmSetKeysCnf
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 resultCode;
+ tANI_U16 aid;
+ tANI_U8 sessionId;
+} tLimMlmSetKeysCnf, *tpLimMlmSetKeysCnf;
+
+typedef struct sLimMlmRemoveKeyReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U8 sessionId; //Added FOr BT-AMP Support
+ tAniEdType edType; // Encryption/Decryption type
+ tANI_U8 wepType; //STATIC / DYNAMIC specifier
+ tANI_U8 keyId; //Key Id To be removed.
+ tANI_BOOLEAN unicast;
+} tLimMlmRemoveKeyReq, *tpLimMlmRemoveKeyReq;
+
+typedef struct sLimMlmRemoveKeyCnf
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U16 resultCode;
+ tANI_U8 sessionId;
+} tLimMlmRemoveKeyCnf, *tpLimMlmRemoveKeyCnf;
+
+
+typedef struct sLimMlmResetReq
+{
+ tSirMacAddr macAddr;
+ tANI_U8 performCleanup;
+ tANI_U8 sessionId;
+} tLimMlmResetReq, *tpLimMlmResetReq;
+
+typedef struct sLimMlmResetCnf
+{
+ tSirMacAddr macAddr;
+ tSirResultCodes resultCode;
+ tANI_U8 sessionId;
+} tLimMlmResetCnf, *tpLimMlmResetCnf;
+
+
+typedef struct sLimMlmLinkTestStopReq
+{
+ tSirMacAddr peerMacAddr;
+ tANI_U8 sessionId;
+#ifdef ANI_PRODUCT_TYPE_AP
+ tANI_U16 aid;
+#endif
+} tLimMlmLinkTestStopReq, *tpLimMlmLinkTestStopReq;
+
+
+//
+// Block ACK related MLME data structures
+//
+
+typedef struct sLimMlmAddBAReq
+{
+
+ // ADDBA recipient
+ tSirMacAddr peerMacAddr;
+
+ // ADDBA Action Frame dialog token
+ tANI_U8 baDialogToken;
+
+ // ADDBA requested for TID
+ tANI_U8 baTID;
+
+ // BA policy
+ // 0 - Delayed BA (Not supported)
+ // 1 - Immediate BA
+ tANI_U8 baPolicy;
+
+ // BA buffer size - (0..127) max size MSDU's
+ tANI_U16 baBufferSize;
+
+ // BA timeout in TU's
+ // 0 means no timeout will occur
+ tANI_U16 baTimeout;
+
+ // ADDBA failure timeout in TU's
+ // Greater than or equal to 1
+ tANI_U16 addBAFailureTimeout;
+
+ // BA Starting Sequence Number
+ tANI_U16 baSSN;
+
+ tANI_U8 sessionId;
+
+} tLimMlmAddBAReq, *tpLimMlmAddBAReq;
+
+typedef struct sLimMlmAddBACnf
+{
+
+ // ADDBA recipient
+ tSirMacAddr peerMacAddr;
+
+ // ADDBA Action Frame dialog token
+ tANI_U8 baDialogToken;
+
+ // ADDBA requested for TID
+ tANI_U8 baTID;
+
+ // BA status code
+ tSirMacStatusCodes addBAResultCode;
+
+ // BA policy
+ // 0 - Delayed BA (Not supported)
+ // 1 - Immediate BA
+ tANI_U8 baPolicy;
+
+ // BA buffer size - (0..127) max size MSDU's
+ tANI_U16 baBufferSize;
+
+ // BA timeout in TU's
+ // 0 means no timeout will occur
+ tANI_U16 baTimeout;
+
+ // ADDBA direction
+ // 1 - Originator
+ // 0 - Recipient
+ tANI_U8 baDirection;
+ tANI_U8 sessionId;
+
+
+} tLimMlmAddBACnf, *tpLimMlmAddBACnf;
+
+typedef struct sLimMlmAddBAInd
+{
+
+ // ADDBA recipient
+ tSirMacAddr peerMacAddr;
+
+ // ADDBA Action Frame dialog token
+ tANI_U8 baDialogToken;
+
+ // ADDBA requested for TID
+ tANI_U8 baTID;
+
+ // BA policy
+ // 0 - Delayed BA (Not supported)
+ // 1 - Immediate BA
+ tANI_U8 baPolicy;
+
+ // BA buffer size - (0..127) max size MSDU's
+ tANI_U16 baBufferSize;
+
+ // BA timeout in TU's
+ // 0 means no timeout will occur
+ tANI_U16 baTimeout;
+
+} tLimMlmAddBAInd, *tpLimMlmAddBAInd;
+
+typedef struct sLimMlmAddBARsp
+{
+
+ // ADDBA recipient
+ tSirMacAddr peerMacAddr;
+
+ // ADDBA Action Frame dialog token
+ tANI_U8 baDialogToken;
+
+ // ADDBA requested for TID
+ tANI_U8 baTID;
+
+ // BA status code
+ tSirMacStatusCodes addBAResultCode;
+
+ // BA policy
+ // 0 - Delayed BA (Not supported)
+ // 1 - Immediate BA
+ tANI_U8 baPolicy;
+
+ // BA buffer size - (0..127) max size MSDU's
+ tANI_U16 baBufferSize;
+
+ // BA timeout in TU's
+ // 0 means no timeout will occur
+ tANI_U16 baTimeout;
+
+ //reserved for alignment
+ tANI_U8 rsvd[2];
+
+ /* PE session id*/
+ tANI_U8 sessionId;
+
+ } tLimMlmAddBARsp, *tpLimMlmAddBARsp;
+
+//
+// NOTE - Overloading DELBA IND and DELBA CNF
+// to use the same data structure as DELBA REQ
+// as the parameters do not vary too much.
+//
+typedef struct sLimMlmDelBAReq
+{
+
+ // ADDBA recipient
+ tSirMacAddr peerMacAddr;
+
+ // DELBA direction
+ // 1 - Originator
+ // 0 - Recipient
+ tANI_U8 baDirection;
+
+ // DELBA requested for TID
+ tANI_U8 baTID;
+
+ // DELBA reason code
+ tSirMacReasonCodes delBAReasonCode;
+
+ tANI_U8 sessionId;
+
+} tLimMlmDelBAReq, *tpLimMlmDelBAReq, tLimMlmDelBAInd, *tpLimMlmDelBAInd, tLimMlmDelBACnf, *tpLimMlmDelBACnf;
+
+// Function templates
+
+tANI_BOOLEAN limProcessSmeReqMessages(tpAniSirGlobal, tpSirMsgQ);
+void limProcessMlmReqMessages(tpAniSirGlobal, tpSirMsgQ);
+void limProcessMlmRspMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *);
+void limProcessLmmMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *);
+void limProcessSmeDelBssRsp( tpAniSirGlobal , tANI_U32,tpPESession);
+
+void limGetRandomBssid(tpAniSirGlobal pMac ,tANI_U8 *data);
+
+// Function to handle CB CFG parameter updates
+void handleCBCFGChange( tpAniSirGlobal pMac, tANI_U32 cfgId );
+
+// Function to handle HT and HT IE CFG parameter intializations
+void handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac);
+
+// Function to handle CFG parameter updates
+void limHandleCFGparamUpdate(tpAniSirGlobal, tANI_U32);
+
+// Function to apply CFG parameters before join/reassoc/start BSS
+void limApplyConfiguration(tpAniSirGlobal,tpPESession);
+
+#ifdef WLAN_SOFTAP_FEATURE
+void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry);
+#else
+void limSetCfgProtection(tpAniSirGlobal pMac);
+#endif
+
+
+// Function to Initialize MLM state machine on STA
+void limInitMlm(tpAniSirGlobal);
+
+// Function to cleanup MLM state machine
+void limCleanupMlm(tpAniSirGlobal);
+
+// Function to cleanup LMM state machine
+void limCleanupLmm(tpAniSirGlobal);
+
+
+// Management frame handling functions
+void limProcessBeaconFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+void limProcessBeaconFrameNoSession(tpAniSirGlobal, tANI_U8 *);
+void limProcessProbeReqFrame(tpAniSirGlobal, tANI_U8 *, tpPESession);
+void limProcessProbeRspFrame(tpAniSirGlobal, tANI_U8 *, tpPESession);
+void limProcessProbeRspFrameNoSession(tpAniSirGlobal, tANI_U8 *);
+void limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal, tANI_U8 *,tpPESession);
+
+
+// Process Auth frame when we have a session in progress.
+void limProcessAuthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+int limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *, void *body);
+#endif
+
+void limProcessAssocReqFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8, tpPESession);
+void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry);
+
+
+void limProcessAssocRspFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8,tpPESession);
+void limProcessDisassocFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+void limProcessDeauthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+void limProcessActionFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+#if defined WLAN_FEATURE_P2P
+void limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxMetaInfo);
+#endif
+
+
+tSirRetStatus limPopulateMacHeader(tpAniSirGlobal, tANI_U8*, tANI_U8, tANI_U8, tSirMacAddr,tSirMacAddr);
+tSirRetStatus limSendProbeReqMgmtFrame(tpAniSirGlobal, tSirMacSSid *, tSirMacAddr, tANI_U8, tSirMacAddr, tANI_U32, tANI_U32, tANI_U8 *);
+void limSendProbeRspMgmtFrame(tpAniSirGlobal, tSirMacAddr, tpAniSSID, short, tANI_U8, tpPESession, tANI_U8);
+void limSendAuthMgmtFrame(tpAniSirGlobal, tSirMacAuthFrameBody *, tSirMacAddr, tANI_U8,tpPESession);
+void limSendAssocReqMgmtFrame(tpAniSirGlobal, tLimMlmAssocReq *,tpPESession);
+void limSendReassocReqMgmtFrame(tpAniSirGlobal, tLimMlmReassocReq *,tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+void limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry);
+#endif
+void limSendDeltsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peer,
+ tANI_U8 wmmTspecPresent, tSirMacTSInfo *pTsinfo,
+ tSirMacTspecIE *pTspecIe, tpPESession psessionEntry);
+void limSendAddtsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tSirAddtsReqInfo *addts,tpPESession);
+void limSendAddtsRspActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tANI_U16 statusCode, tSirAddtsReqInfo *addts, tSirMacScheduleIE *pSchedule,tpPESession);
+
+#ifdef ANI_PRODUCT_TYPE_AP
+void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr, tANI_U8, tpDphHashNode pSta,tpPESession);
+#endif
+void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr, tANI_U8, tpDphHashNode pSta,tpPESession);
+
+void limSendNullDataFrame(tpAniSirGlobal, tpDphHashNode);
+void limSendDisassocMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr,tpPESession);
+void limSendDeauthMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr,tpPESession);
+
+void limContinueChannelScan(tpAniSirGlobal);
+tSirResultCodes limMlmAddBss(tpAniSirGlobal, tLimMlmStartReq *,tpPESession psessionEntry);
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
+tSirRetStatus limSendChannelSwitchMgmtFrame(tpAniSirGlobal, tSirMacAddr, tANI_U8, tANI_U8, tANI_U8);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus limSendNeighborReportRequestFrame(tpAniSirGlobal, tpSirMacNeighborReportReq, tSirMacAddr, tpPESession);
+tSirRetStatus limSendLinkReportActionFrame(tpAniSirGlobal, tpSirMacLinkReport, tSirMacAddr, tpPESession );
+tSirRetStatus limSendRadioMeasureReportActionFrame(tpAniSirGlobal, tANI_U8, tANI_U8, tpSirMacRadioMeasureReport, tSirMacAddr, tpPESession);
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+void limProcessIappFrame(tpAniSirGlobal, tANI_U8 *,tpPESession);
+#endif
+
+// Algorithms & Link Monitoring related functions
+tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal);
+void limTriggerBackgroundScan(tpAniSirGlobal);
+void limAbortBackgroundScan(tpAniSirGlobal);
+
+/// Function that handles heartbeat failure
+void limHandleHeartBeatFailure(tpAniSirGlobal,tpPESession);
+
+/// Function that triggers link tear down with AP upon HB failure
+void limTearDownLinkWithAp(tpAniSirGlobal,tANI_U8, tSirMacReasonCodes);
+
+#ifdef ANI_PRODUCT_TYPE_AP
+/// Function that performs periodic release of AIDs
+void limReleaseAIDHandler(tpAniSirGlobal);
+
+/// Function that performs periodic cleanup of Pre-auth contexts
+void limPreAuthClnupHandler(tpAniSirGlobal);
+
+/// Function that processes CF-poll response message from SCH
+void limHandleCFpollRsp(tANI_U32);
+
+/// Function that processes PS-poll message from PMM
+void limHandlePSpoll(tANI_U32);
+#endif
+
+/// Function that sends keep alive message to peer(s)
+void limSendKeepAliveToPeer(tpAniSirGlobal);
+
+/// Function that processes Max retries interrupt from TFP
+void limHandleMaxRetriesInterrupt(tANI_U32);
+
+/// Function that processes messages deferred during Learn mode
+void limProcessDeferredMessageQueue(tpAniSirGlobal);
+
+/// Function that defers the messages received
+tANI_U32 limDeferMsg(tpAniSirGlobal, tSirMsgQ *);
+
+/// Function that sets system into scan mode
+void limSetScanMode(tpAniSirGlobal pMac);
+
+/// Function that Switches the Channel and sets the CB Mode
+void limSetChannel(tpAniSirGlobal pMac, tANI_U32 titanHtcap, tANI_U8 channel, tPowerdBm maxTxPower, tANI_U8 peSessionId);
+
+/// Function that completes channel scan
+void limCompleteMlmScan(tpAniSirGlobal, tSirResultCodes);
+
+
+#ifdef ANI_SUPPORT_11H
+/// Function that sends Measurement Report action frame
+tSirRetStatus limSendMeasReportFrame(tpAniSirGlobal, tpSirMacMeasReqActionFrame, tSirMacAddr);
+
+/// Function that sends TPC Report action frame
+tSirRetStatus limSendTpcReportFrame(tpAniSirGlobal, tpSirMacTpcReqActionFrame, tSirMacAddr);
+#endif
+
+/// Function that sends TPC Request action frame
+void limSendTpcRequestFrame(tpAniSirGlobal, tSirMacAddr);
+
+// Function(s) to handle responses received from HAL
+void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQt,tpPESession psessionEntry);
+void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession);
+#ifdef ANI_PRODUCT_TYPE_AP
+void limProcessApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+void limProcessApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+void limProcessApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+#endif
+void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry);
+void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry);
+void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry);
+void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+
+
+
+#ifdef GEN4_SCAN
+// Function to process WDA_INIT_SCAN_RSP message
+void limProcessInitScanRsp(tpAniSirGlobal, void * );
+
+// Function to process WDA_START_SCAN_RSP message
+void limProcessStartScanRsp(tpAniSirGlobal, void * );
+
+// Function to process WDA_END_SCAN_RSP message
+void limProcessEndScanRsp(tpAniSirGlobal, void * );
+
+// Function to process WDA_FINISH_SCAN_RSP message
+void limProcessFinishScanRsp(tpAniSirGlobal, void * );
+
+// Function to process WDA_SWITCH_CHANNEL_RSP message
+void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void * );
+
+void limSendHalInitScanReq( tpAniSirGlobal, tLimLimHalScanState, tSirLinkTrafficCheck);
+void limSendHalStartScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState);
+void limSendHalEndScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState);
+void limSendHalFinishScanReq( tpAniSirGlobal, tLimLimHalScanState);
+
+void limContinuePostChannelScan(tpAniSirGlobal pMac);
+void limContinueChannelLearn( tpAniSirGlobal );
+//WLAN_SUSPEND_LINK Related
+tANI_U8 limIsLinkSuspended(tpAniSirGlobal pMac);
+void limSuspendLink(tpAniSirGlobal, tSirLinkTrafficCheck, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*);
+void limResumeLink(tpAniSirGlobal, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*);
+//end WLAN_SUSPEND_LINK Related
+#endif // GEN4_SCAN
+
+tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac,
+ tpLimMlmAddBAReq pMlmAddBAReq,tpPESession);
+
+tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac,
+ tpLimMlmAddBARsp pMlmAddBARsp,tpPESession);
+
+tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac,
+ tpLimMlmDelBAReq pMlmDelBAReq ,tpPESession psessionEntry);
+#if 0
+tSirRetStatus limSendSMPowerStateFrame( tpAniSirGlobal pMac,
+ tSirMacAddr peer, tSirMacHTMIMOPowerSaveState State );
+#endif
+
+void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ );
+
+void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ );
+
+void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ );
+
+void limProcessLearnIntervalTimeout(tpAniSirGlobal pMac);
+#ifdef WLAN_FEATURE_11W
+//11w SA query request action frame handler
+tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac,
+ tANI_U16 transId, tSirMacAddr peer,tpPESession psessionEntry);
+#endif
+// Inline functions
+
+/**
+ * limPostSmeMessage()
+ *
+ *FUNCTION:
+ * This function is called by limProcessMlmMessages(). In this
+ * function MLM sub-module invokes MLM ind/cnf primitives.
+ *
+ *LOGIC:
+ * Initially MLM makes an SME function call to invoke MLM ind/cnf
+ * primitive. In future this can be enhanced to 'post' messages to SME.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM primitive message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+limPostSmeMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+ tSirMsgQ msg;
+
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+
+ msg.type = (tANI_U16)msgType;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+ if (msgType > eWNI_SME_MSG_TYPES_BEGIN)
+ limProcessSmeReqMessages(pMac, &msg);
+ else
+ limProcessMlmRspMessages(pMac, msgType, pMsgBuf);
+} /*** end limPostSmeMessage() ***/
+
+/**
+ * limPostMlmMessage()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages(). In this
+ * function SME invokes MLME primitives.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ * Initially SME makes an MLM function call to invoke MLM primitive.
+ * In future this can be enhanced to 'post' messages to MLM.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM primitive message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+limPostMlmMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf)
+{
+
+ tSirMsgQ msg;
+ if(pMsgBuf == NULL)
+ {
+ limLog(pMac, LOGE,FL("Buffer is Pointing to NULL\n"));
+ return;
+ }
+ msg.type = (tANI_U16) msgType;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+ limProcessMlmReqMessages(pMac, &msg);
+} /*** end limPostMlmMessage() ***/
+
+
+
+/**
+ * limGetCurrentScanChannel()
+ *
+ *FUNCTION:
+ * This function is called in various places to get current channel
+ * number being scanned.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return Channel number
+ */
+static inline tANI_U8
+limGetCurrentScanChannel(tpAniSirGlobal pMac)
+{
+ tANI_U8 *pChanNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber;
+
+ return (*(pChanNum + pMac->lim.gLimCurrentScanChannelId));
+} /*** end limGetCurrentScanChannel() ***/
+
+
+
+/**
+ * limGetIElenFromBssDescription()
+ *
+ *FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pBssDescr
+ * @return Total IE length
+ */
+
+static inline tANI_U16
+limGetIElenFromBssDescription(tpSirBssDescription pBssDescr)
+{
+ if (!pBssDescr)
+ return 0;
+
+ return ((tANI_U16) (pBssDescr->length + sizeof(tANI_U16) +
+ sizeof(tANI_U32) - sizeof(tSirBssDescription)));
+} /*** end limGetIElenFromBssDescription() ***/
+
+#ifdef WLAN_SOFTAP_FEATURE
+/**
+ * limSendBeaconInd()
+ *
+ *FUNCTION:
+ * This function is called to send the beacon indication
+ * number being scanned.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+*/
+
+void
+limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry);
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr, tANI_U8 *uuid_e, eWPSPBCOverlap *overlap, tpPESession psessionEntry);
+void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry);
+
+
+tSirRetStatus
+limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf);
+
+#define LIM_WPS_OVERLAP_TIMER_MS 10000
+#endif
+
+void
+limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data);
+void
+limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data);
+
+void
+limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel,
+ CHANGE_CHANNEL_CALLBACK callback, tANI_U32 *cbdata, tpPESession psessionEntry);
+
+#ifdef WLAN_FEATURE_P2P
+void limSendSmeMgmtFrameInd(
+ tpAniSirGlobal pMac, tANI_U8 frameType,
+ tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId,
+ tANI_U32 rxChan);
+void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac);
+void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+void limAbortRemainOnChan(tpAniSirGlobal pMac);
+tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf);
+#endif
+#endif /* __LIM_TYPES_H */
+
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
new file mode 100644
index 0000000..976eb3a
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -0,0 +1,8039 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limUtils.cc contains the utility functions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "schApi.h"
+#include "limUtils.h"
+#include "limTypes.h"
+#include "limSecurityUtils.h"
+#include "limPropExtsUtils.h"
+#include "limSendMessages.h"
+#include "limSerDesUtils.h"
+#include "limAdmitControl.h"
+#include "limStaHashApi.h"
+#include "dot11f.h"
+#include "wmmApsd.h"
+#include "limTrace.h"
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "vos_diag_core_event.h"
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+#include "limIbssPeerMgmt.h"
+#include "limSessionUtils.h"
+#include "limSession.h"
+#include "vos_nvitem.h"
+
+/* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET
+ * and limTriggerBackgroundScanDuringQuietBss() returned failure. In this case, we will stop data
+ * traffic instead of going into scan. The recover function limProcessQuietBssTimeout() needs to have
+ * this information. */
+static tAniBool glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE;
+
+/* 11A Channel list to decode RX BD channel information */
+static const tANI_U8 abChannel[]= {36,40,44,48,52,56,60,64,100,104,108,112,116,
+ 120,124,128,132,136,140,149,153,157,161,165};
+
+//#define LIM_MAX_ACTIVE_SESSIONS 3 //defined temporarily for BT-AMP SUPPORT
+#define SUCCESS 1 //defined temporarily for BT-AMP
+
+/** -------------------------------------------------------------
+\fn limAssignDialogueToken
+\brief Assigns dialogue token.
+\param tpAniSirGlobal pMac
+\return tpDialogueToken - dialogueToken data structure.
+ -------------------------------------------------------------*/
+
+tpDialogueToken
+limAssignDialogueToken(tpAniSirGlobal pMac)
+{
+ static tANI_U8 token = 0;
+ tpDialogueToken pCurrNode;
+ if(eHAL_STATUS_SUCCESS !=
+ palAllocateMemory(pMac->hHdd, (void **) &pCurrNode, sizeof(tDialogueToken)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed\n"));)
+ return NULL;
+ }
+
+ palZeroMemory(pMac->hHdd, (void *) pCurrNode, sizeof(tDialogueToken));
+ //first node in the list is being added.
+ if(NULL == pMac->lim.pDialogueTokenHead)
+ {
+ pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenTail = pCurrNode;
+ }
+ else
+ {
+ pMac->lim.pDialogueTokenTail->next = pCurrNode;
+ pMac->lim.pDialogueTokenTail = pCurrNode;
+ }
+ //assocId and tid of the node will be filled in by caller.
+ pCurrNode->next = NULL;
+ pCurrNode->token = token++;
+ PELOG4(limLog(pMac, LOG4, FL("token assigned = %d\n"), token);)
+ return pCurrNode;
+}
+
+/** -------------------------------------------------------------
+\fn limSearchAndDeleteDialogueToken
+\brief search dialogue token in the list and deletes it if found. returns failure if not found.
+\param tpAniSirGlobal pMac
+\param tANI_U8 token
+\param tANI_U16 assocId
+\param tANI_U16 tid
+\return eSirRetStatus - status of the search
+ -------------------------------------------------------------*/
+
+
+tSirRetStatus
+limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid)
+{
+ tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead;
+ tpDialogueToken pPrevNode = pMac->lim.pDialogueTokenHead;
+
+ //if the list is empty
+ if(NULL == pCurrNode)
+ return eSIR_FAILURE;
+
+ // if the matching node is the first node.
+ if(pCurrNode &&
+ (assocId == pCurrNode->assocId) &&
+ (tid == pCurrNode->tid))
+ {
+ pMac->lim.pDialogueTokenHead = pCurrNode->next;
+ //there was only one node in the list. So tail pointer also needs to be adjusted.
+ if(NULL == pMac->lim.pDialogueTokenHead)
+ pMac->lim.pDialogueTokenTail = NULL;
+ palFreeMemory(pMac->hHdd, (void *) pCurrNode);
+ return eSIR_SUCCESS;
+ }
+
+ //first node did not match. so move to the next one.
+ pCurrNode = pCurrNode->next;
+ while(NULL != pCurrNode )
+ {
+ if(token == pCurrNode->token)
+ {
+ break;
+ }
+
+ pPrevNode = pCurrNode;
+ pCurrNode = pCurrNode->next;
+ }
+
+ if(pCurrNode &&
+ (assocId == pCurrNode->assocId) &&
+ (tid == pCurrNode->tid))
+ {
+ pPrevNode->next = pCurrNode->next;
+ //if the node being deleted is the last one then we also need to move the tail pointer to the prevNode.
+ if(NULL == pCurrNode->next)
+ pMac->lim.pDialogueTokenTail = pPrevNode;
+ return eSIR_SUCCESS;
+ }
+
+ PELOGW(limLog(pMac, LOGW, FL("LIM does not have matching dialogue token node\n"));)
+ return eSIR_FAILURE;
+
+}
+
+
+/** -------------------------------------------------------------
+\fn limDeleteDialogueTokenList
+\brief deletes the complete lim dialogue token linked list.
+\param tpAniSirGlobal pMac
+\return None
+ -------------------------------------------------------------*/
+void
+limDeleteDialogueTokenList(tpAniSirGlobal pMac)
+{
+ tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead;
+
+ while(NULL != pMac->lim.pDialogueTokenHead)
+ {
+ pCurrNode = pMac->lim.pDialogueTokenHead;
+ pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenHead->next;
+ palFreeMemory(pMac->hHdd, (void *) pCurrNode);
+ pCurrNode = NULL;
+ }
+ pMac->lim.pDialogueTokenTail = NULL;
+}
+
+void
+limGetBssidFromBD(tpAniSirGlobal pMac, tANI_U8 * pRxPacketInfo, tANI_U8 *bssId, tANI_U32 *pIgnore)
+{
+ tpSirMacDataHdr3a pMh = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo);
+ *pIgnore = 0;
+
+ if (pMh->fc.toDS == 1 && pMh->fc.fromDS == 0)
+ {
+ palCopyMemory( pMac->hHdd, bssId, pMh->addr1, 6);
+ *pIgnore = 1;
+ }
+ else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 1)
+ {
+ palCopyMemory( pMac->hHdd, bssId, pMh->addr2, 6);
+ *pIgnore = 1;
+ }
+ else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 0)
+ {
+ palCopyMemory( pMac->hHdd, bssId, pMh->addr3, 6);
+ *pIgnore = 0;
+ }
+ else
+ {
+ palCopyMemory( pMac->hHdd, bssId, pMh->addr1, 6);
+ *pIgnore = 1;
+ }
+}
+
+char *
+limMlmStateStr(tLimMlmStates state)
+{
+
+#ifdef FIXME_GEN6
+ switch (state)
+ {
+ case eLIM_MLM_OFFLINE_STATE:
+ return "eLIM_MLM_OFFLINE_STATE\n";
+ case eLIM_MLM_IDLE_STATE:
+ return "eLIM_MLM_IDLE_STATE\n";
+ case eLIM_MLM_WT_PROBE_RESP_STATE:
+ return "eLIM_MLM_WT_PROBE_RESP_STATE\n";
+ case eLIM_MLM_PASSIVE_SCAN_STATE:
+ return "eLIM_MLM_PASSIVE_SCAN_STATE\n";
+ case eLIM_MLM_WT_JOIN_BEACON_STATE:
+ return "eLIM_MLM_WT_JOIN_BEACON_STATE\n";
+ case eLIM_MLM_JOINED_STATE:
+ return "eLIM_MLM_JOINED_STATE\n";
+ case eLIM_MLM_BSS_STARTED_STATE:
+ return "eLIM_MLM_BSS_STARTED_STATE\n";
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME2_STATE\n";
+ case eLIM_MLM_WT_AUTH_FRAME3_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME3_STATE\n";
+ case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME4_STATE\n";
+ case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE:
+ return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE\n";
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ return "eLIM_MLM_AUTHENTICATED_STATE\n";
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_ASSOC_RSP_STATE\n";
+ case eLIM_MLM_WT_REASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_REASSOC_RSP_STATE\n";
+ case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE";
+ case eLIM_MLM_WT_DEL_STA_RSP_STATE:
+ return "eLIM_MLM_WT_DEL_STA_RSP_STATE\n";
+ case eLIM_MLM_WT_DEL_BSS_RSP_STATE:
+ return "eLIM_MLM_WT_DEL_BSS_RSP_STATE\n";
+ case eLIM_MLM_WT_ADD_STA_RSP_STATE:
+ return "eLIM_MLM_WT_ADD_STA_RSP_STATE\n";
+ case eLIM_MLM_WT_ADD_BSS_RSP_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_STATE\n";
+ case eLIM_MLM_REASSOCIATED_STATE:
+ return "eLIM_MLM_REASSOCIATED_STATE\n";
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+ return "eLIM_MLM_LINK_ESTABLISHED_STATE\n";
+ case eLIM_MLM_WT_ASSOC_CNF_STATE:
+ return "eLIM_MLM_WT_ASSOC_CNF_STATE\n";
+ case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE\n";
+ case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE\n";
+ case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE";
+ case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE:
+ return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE\n";
+ case eLIM_MLM_WT_SET_BSS_KEY_STATE:
+ return "eLIM_MLM_WT_SET_BSS_KEY_STATE\n";
+ case eLIM_MLM_WT_SET_STA_KEY_STATE:
+ return "eLIM_MLM_WT_SET_STA_KEY_STATE\n";
+ default:
+ return "INVALID MLM state\n";
+ }
+#endif
+return "";
+}
+
+void
+limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state)
+{
+ limLog(pMac, logLevel, limMlmStateStr(state));
+}
+
+char *
+limSmeStateStr(tLimSmeStates state)
+{
+#ifdef FIXME_GEN6
+ switch (state)
+ {
+ case eLIM_SME_OFFLINE_STATE:
+ return "eLIM_SME_OFFLINE_STATE\n";
+ case eLIM_SME_IDLE_STATE:
+ return "eLIM_SME_IDLE_STATE\n";
+ case eLIM_SME_SUSPEND_STATE:
+ return "eLIM_SME_SUSPEND_STATE\n";
+ case eLIM_SME_WT_SCAN_STATE:
+ return "eLIM_SME_WT_SCAN_STATE\n";
+ case eLIM_SME_WT_JOIN_STATE:
+ return "eLIM_SME_WT_JOIN_STATE\n";
+ case eLIM_SME_WT_AUTH_STATE:
+ return "eLIM_SME_WT_AUTH_STATE\n";
+ case eLIM_SME_WT_ASSOC_STATE:
+ return "eLIM_SME_WT_ASSOC_STATE\n";
+ case eLIM_SME_WT_REASSOC_STATE:
+ return "eLIM_SME_WT_REASSOC_STATE\n";
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE:
+ return "eLIM_SME_WT_REASSOC_LINK_FAIL_STATE\n";
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ return "eLIM_SME_JOIN_FAILURE_STATE\n";
+ case eLIM_SME_ASSOCIATED_STATE:
+ return "eLIM_SME_ASSOCIATED_STATE\n";
+ case eLIM_SME_REASSOCIATED_STATE:
+ return "eLIM_SME_REASSOCIATED_STATE\n";
+ case eLIM_SME_LINK_EST_STATE:
+ return "eLIM_SME_LINK_EST_STATE\n";
+ case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+ return "eLIM_SME_LINK_EST_WT_SCAN_STATE\n";
+ case eLIM_SME_WT_PRE_AUTH_STATE:
+ return "eLIM_SME_WT_PRE_AUTH_STATE\n";
+ case eLIM_SME_WT_DISASSOC_STATE:
+ return "eLIM_SME_WT_DISASSOC_STATE\n";
+ case eLIM_SME_WT_DEAUTH_STATE:
+ return "eLIM_SME_WT_DEAUTH_STATE\n";
+ case eLIM_SME_WT_START_BSS_STATE:
+ return "eLIM_SME_WT_START_BSS_STATE\n";
+ case eLIM_SME_WT_STOP_BSS_STATE:
+ return "eLIM_SME_WT_STOP_BSS_STATE\n";
+ case eLIM_SME_NORMAL_STATE:
+ return "eLIM_SME_NORMAL_STATE\n";
+ case eLIM_SME_CHANNEL_SCAN_STATE:
+ return "eLIM_SME_CHANNEL_SCAN_STATE\n";
+ case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+ return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE\n";
+ default:
+ return "INVALID SME state\n";
+ }
+#endif
+return "";
+}
+
+
+char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode)
+{
+#ifdef FIXME_GEN6
+
+ switch(dot11Mode)
+ {
+ case WNI_CFG_DOT11_MODE_ALL:
+ return "ALL\n";
+ case WNI_CFG_DOT11_MODE_11A:
+ return "11A\n";
+ case WNI_CFG_DOT11_MODE_11B:
+ return "11B\n";
+ case WNI_CFG_DOT11_MODE_11G:
+ return "11G\n";
+ case WNI_CFG_DOT11_MODE_11N:
+ return "11N\n";
+ case WNI_CFG_DOT11_MODE_POLARIS:
+ return "Polaris\n";
+ case WNI_CFG_DOT11_MODE_TITAN:
+ return "Titan\n";
+ case WNI_CFG_DOT11_MODE_TAURUS:
+ return "Taurus\n";
+ default:
+ return "Invalid Dot11 Mode\n";
+ }
+#endif
+return "";
+}
+
+
+char* limStaOpRateModeStr(tStaRateMode opRateMode)
+{
+#ifdef FIXME_GEN6
+
+ switch(opRateMode)
+ {
+ case eSTA_TAURUS:
+ return "Taurus\n";
+ case eSTA_11a:
+ return "11A\n";
+ case eSTA_11b:
+ return "11B\n";
+ case eSTA_11bg:
+ return "11G\n";
+ case eSTA_11n:
+ return "11N\n";
+ case eSTA_POLARIS:
+ return "Polaris\n";
+ case eSTA_TITAN:
+ return "Titan\n";
+ default:
+ return "Invalid Dot11 Mode\n";
+ }
+#endif
+return "";
+}
+
+char* limBssTypeStr(tSirBssType bssType)
+{
+ switch(bssType)
+ {
+ case eSIR_INFRASTRUCTURE_MODE:
+ return "eSIR_INFRASTRUCTURE_MODE";
+ case eSIR_IBSS_MODE:
+ return "eSIR_IBSS_MODE";
+ case eSIR_BTAMP_STA_MODE:
+ return "eSIR_BTAMP_STA_MODE";
+ case eSIR_BTAMP_AP_MODE:
+ return "eSIR_BTAMP_AP_MODE";
+ case eSIR_AUTO_MODE:
+ return "eSIR_AUTO_MODE";
+ default:
+ return "Invalid BSS Type";
+ }
+}
+
+void
+limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state)
+{
+ limLog(pMac, logLevel, limSmeStateStr(state));
+}
+
+char *limMsgStr(tANI_U32 msgType)
+{
+#ifdef FIXME_GEN6
+ switch (msgType)
+ {
+ case eWNI_SME_START_REQ:
+ return "eWNI_SME_START_REQ\n";
+ case eWNI_SME_START_RSP:
+ return "eWNI_SME_START_RSP\n";
+ case eWNI_SME_SYS_READY_IND:
+ return "eWNI_SME_SYS_READY_IND\n";
+ case eWNI_SME_SCAN_REQ:
+ return "eWNI_SME_SCAN_REQ\n";
+ case eWNI_SME_SCAN_RSP:
+ return "eWNI_SME_SCAN_RSP\n";
+ case eWNI_SME_JOIN_REQ:
+ return "eWNI_SME_JOIN_REQ\n";
+ case eWNI_SME_JOIN_RSP:
+ return "eWNI_SME_JOIN_RSP\n";
+ case eWNI_SME_SETCONTEXT_REQ:
+ return "eWNI_SME_SETCONTEXT_REQ\n";
+ case eWNI_SME_SETCONTEXT_RSP:
+ return "eWNI_SME_SETCONTEXT_RSP\n";
+ case eWNI_SME_REASSOC_REQ:
+ return "eWNI_SME_REASSOC_REQ\n";
+ case eWNI_SME_REASSOC_RSP:
+ return "eWNI_SME_REASSOC_RSP\n";
+ case eWNI_SME_AUTH_REQ:
+ return "eWNI_SME_AUTH_REQ\n";
+ case eWNI_SME_AUTH_RSP:
+ return "eWNI_SME_AUTH_RSP\n";
+ case eWNI_SME_DISASSOC_REQ:
+ return "eWNI_SME_DISASSOC_REQ\n";
+ case eWNI_SME_DISASSOC_RSP:
+ return "eWNI_SME_DISASSOC_RSP\n";
+ case eWNI_SME_DISASSOC_IND:
+ return "eWNI_SME_DISASSOC_IND\n";
+ case eWNI_SME_DISASSOC_CNF:
+ return "eWNI_SME_DISASSOC_CNF\n";
+ case eWNI_SME_DEAUTH_REQ:
+ return "eWNI_SME_DEAUTH_REQ\n";
+ case eWNI_SME_DEAUTH_RSP:
+ return "eWNI_SME_DEAUTH_RSP\n";
+ case eWNI_SME_DEAUTH_IND:
+ return "eWNI_SME_DEAUTH_IND\n";
+ case eWNI_SME_WM_STATUS_CHANGE_NTF:
+ return "eWNI_SME_WM_STATUS_CHANGE_NTF\n";
+ case eWNI_SME_START_BSS_REQ:
+ return "eWNI_SME_START_BSS_REQ\n";
+ case eWNI_SME_START_BSS_RSP:
+ return "eWNI_SME_START_BSS_RSP\n";
+ case eWNI_SME_AUTH_IND:
+ return "eWNI_SME_AUTH_IND\n";
+ case eWNI_SME_ASSOC_IND:
+ return "eWNI_SME_ASSOC_IND\n";
+ case eWNI_SME_ASSOC_CNF:
+ return "eWNI_SME_ASSOC_CNF\n";
+ case eWNI_SME_REASSOC_IND:
+ return "eWNI_SME_REASSOC_IND\n";
+ case eWNI_SME_REASSOC_CNF:
+ return "eWNI_SME_REASSOC_CNF\n";
+ case eWNI_SME_SWITCH_CHL_REQ:
+ return "eWNI_SME_SWITCH_CHL_REQ\n";
+ case eWNI_SME_SWITCH_CHL_RSP:
+ return "eWNI_SME_SWITCH_CHL_RSP\n";
+ case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ:
+ return "eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ\n";
+ case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ:
+ return "eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ\n";
+ case eWNI_SME_STOP_BSS_REQ:
+ return "eWNI_SME_STOP_BSS_REQ\n";
+ case eWNI_SME_STOP_BSS_RSP:
+ return "eWNI_SME_STOP_BSS_RSP\n";
+ case eWNI_SME_PROMISCUOUS_MODE_REQ:
+ return "eWNI_SME_PROMISCUOUS_MODE_REQ\n";
+ case eWNI_SME_PROMISCUOUS_MODE_RSP:
+ return "eWNI_SME_PROMISCUOUS_MODE_RSP\n";
+ case eWNI_SME_NEIGHBOR_BSS_IND:
+ return "eWNI_SME_NEIGHBOR_BSS_IND\n";
+ case eWNI_SME_MEASUREMENT_REQ:
+ return "eWNI_SME_MEASUREMENT_REQ\n";
+ case eWNI_SME_MEASUREMENT_RSP:
+ return "eWNI_SME_MEASUREMENT_RSP\n";
+ case eWNI_SME_MEASUREMENT_IND:
+ return "eWNI_SME_MEASUREMENT_IND\n";
+ case eWNI_SME_SET_WDS_INFO_REQ:
+ return "eWNI_SME_SET_WDS_INFO_REQ\n";
+ case eWNI_SME_SET_WDS_INFO_RSP:
+ return "eWNI_SME_SET_WDS_INFO_RSP\n";
+ case eWNI_SME_WDS_INFO_IND:
+ return "eWNI_SME_WDS_INFO_IND\n";
+ case eWNI_SME_DEAUTH_CNF:
+ return "eWNI_SME_DEAUTH_CNF\n";
+ case eWNI_SME_MIC_FAILURE_IND:
+ return "eWNI_SME_MIC_FAILURE_IND\n";
+ case eWNI_SME_ADDTS_REQ:
+ return "eWNI_SME_ADDTS_REQ\n";
+ case eWNI_SME_ADDTS_RSP:
+ return "eWNI_SME_ADDTS_RSP\n";
+ case eWNI_SME_ADDTS_CNF:
+ return "eWNI_SME_ADDTS_CNF\n";
+ case eWNI_SME_ADDTS_IND:
+ return "eWNI_SME_ADDTS_IND\n";
+ case eWNI_SME_DELTS_REQ:
+ return "eWNI_SME_DELTS_REQ\n";
+ case eWNI_SME_DELTS_RSP:
+ return "eWNI_SME_DELTS_RSP\n";
+ case eWNI_SME_DELTS_IND:
+ return "eWNI_SME_DELTS_IND\n";
+
+ case SIR_LIM_RESUME_ACTIVITY_NTF:
+ return "SIR_LIM_RESUME_ACTIVITY_NTF\n";
+ case SIR_LIM_SUSPEND_ACTIVITY_REQ:
+ return "SIR_LIM_SUSPEND_ACTIVITY_REQ\n";
+ case WDA_SUSPEND_ACTIVITY_RSP:
+ return "WDA_SUSPEND_ACTIVITY_RSP\n";
+ case SIR_LIM_RETRY_INTERRUPT_MSG:
+ return "SIR_LIM_RETRY_INTERRUPT_MSG\n";
+ case SIR_BB_XPORT_MGMT_MSG:
+ return "SIR_BB_XPORT_MGMT_MSG\n";
+ case SIR_LIM_INV_KEY_INTERRUPT_MSG:
+ return "SIR_LIM_INV_KEY_INTERRUPT_MSG\n";
+ case SIR_LIM_KEY_ID_INTERRUPT_MSG:
+ return "SIR_LIM_KEY_ID_INTERRUPT_MSG\n";
+ case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
+ return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG\n";
+ case SIR_LIM_MIN_CHANNEL_TIMEOUT:
+ return "SIR_LIM_MIN_CHANNEL_TIMEOUT\n";
+ case SIR_LIM_MAX_CHANNEL_TIMEOUT:
+ return "SIR_LIM_MAX_CHANNEL_TIMEOUT\n";
+ case SIR_LIM_JOIN_FAIL_TIMEOUT:
+ return "SIR_LIM_JOIN_FAIL_TIMEOUT\n";
+ case SIR_LIM_AUTH_FAIL_TIMEOUT:
+ return "SIR_LIM_AUTH_FAIL_TIMEOUT\n";
+ case SIR_LIM_AUTH_RSP_TIMEOUT:
+ return "SIR_LIM_AUTH_RSP_TIMEOUT\n";
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+ return "SIR_LIM_ASSOC_FAIL_TIMEOUT\n";
+ case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+ return "SIR_LIM_REASSOC_FAIL_TIMEOUT\n";
+ case SIR_LIM_HEART_BEAT_TIMEOUT:
+ return "SIR_LIM_HEART_BEAT_TIMEOUT\n";
+#ifdef ANI_PRODUCT_TYPE_AP
+ case SIR_LIM_PREAUTH_CLNUP_TIMEOUT:
+ return "SIR_LIM_PREAUTH_CLNUP_TIMEOUT\n";
+#endif
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ return "SIR_LIM_ADDTS_RSP_TIMEOUT\n";
+ case SIR_LIM_CHANNEL_SCAN_TIMEOUT:
+ return "SIR_LIM_CHANNEL_SCAN_TIMEOUT\n";
+#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
+ case SIR_LIM_MEASUREMENT_IND_TIMEOUT:
+ return "SIR_LIM_MEASUREMENT_IND_TIMEOUT\n";
+ case SIR_LIM_LEARN_INTERVAL_TIMEOUT:
+ return "SIR_LIM_LEARN_INTERVAL_TIMEOUT\n";
+ case SIR_LIM_LEARN_DURATION_TIMEOUT:
+ return "SIR_LIM_LEARN_DURATION_TIMEOUT\n";
+#endif
+ case SIR_LIM_LINK_TEST_DURATION_TIMEOUT:
+ return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT\n";
+ case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+ return "SIR_LIM_HASH_MISS_THRES_TIMEOUT\n";
+ case SIR_LIM_KEEPALIVE_TIMEOUT:
+ return "SIR_LIM_KEEPALIVE_TIMEOUT\n";
+ case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+ return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT\n";
+ case SIR_LIM_CNF_WAIT_TIMEOUT:
+ return "SIR_LIM_CNF_WAIT_TIMEOUT\n";
+ case SIR_LIM_RADAR_DETECT_IND:
+ return "SIR_LIM_RADAR_DETECT_IND\n";
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+ return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT\n";
+#endif
+
+ case SIR_HAL_APP_SETUP_NTF:
+ return "SIR_HAL_APP_SETUP_NTF\n";
+ case SIR_HAL_INITIAL_CAL_FAILED_NTF:
+ return "SIR_HAL_INITIAL_CAL_FAILED_NTF\n";
+ case SIR_HAL_NIC_OPER_NTF:
+ return "SIR_HAL_NIC_OPER_NTF\n";
+ case SIR_HAL_INIT_START_REQ:
+ return "SIR_HAL_INIT_START_REQ\n";
+ case SIR_HAL_SHUTDOWN_REQ:
+ return "SIR_HAL_SHUTDOWN_REQ\n";
+ case SIR_HAL_SHUTDOWN_CNF:
+ return "SIR_HAL_SHUTDOWN_CNF\n";
+ case SIR_HAL_RESET_REQ:
+ return "SIR_HAL_RESET_REQ\n";
+ case SIR_HAL_RESET_CNF:
+ return "SIR_HAL_RESET_CNF\n";
+ case SIR_WRITE_TO_TD:
+ return "SIR_WRITE_TO_TD\n";
+
+ case WNI_CFG_PARAM_UPDATE_IND:
+ return "WNI_CFG_PARAM_UPDATE_IND\n";
+ case WNI_CFG_DNLD_REQ:
+ return "WNI_CFG_DNLD_REQ\n";
+ case WNI_CFG_DNLD_CNF:
+ return "WNI_CFG_DNLD_CNF\n";
+ case WNI_CFG_GET_RSP:
+ return "WNI_CFG_GET_RSP\n";
+ case WNI_CFG_SET_CNF:
+ return "WNI_CFG_SET_CNF\n";
+ case WNI_CFG_GET_ATTRIB_RSP:
+ return "WNI_CFG_GET_ATTRIB_RSP\n";
+ case WNI_CFG_ADD_GRP_ADDR_CNF:
+ return "WNI_CFG_ADD_GRP_ADDR_CNF\n";
+ case WNI_CFG_DEL_GRP_ADDR_CNF:
+ return "WNI_CFG_DEL_GRP_ADDR_CNF\n";
+ case ANI_CFG_GET_RADIO_STAT_RSP:
+ return "ANI_CFG_GET_RADIO_STAT_RSP\n";
+ case ANI_CFG_GET_PER_STA_STAT_RSP:
+ return "ANI_CFG_GET_PER_STA_STAT_RSP\n";
+ case ANI_CFG_GET_AGG_STA_STAT_RSP:
+ return "ANI_CFG_GET_AGG_STA_STAT_RSP\n";
+ case ANI_CFG_CLEAR_STAT_RSP:
+ return "ANI_CFG_CLEAR_STAT_RSP\n";
+ case WNI_CFG_DNLD_RSP:
+ return "WNI_CFG_DNLD_RSP\n";
+ case WNI_CFG_GET_REQ:
+ return "WNI_CFG_GET_REQ\n";
+ case WNI_CFG_SET_REQ:
+ return "WNI_CFG_SET_REQ\n";
+ case WNI_CFG_SET_REQ_NO_RSP:
+ return "WNI_CFG_SET_REQ_NO_RSP\n";
+ case eWNI_PMC_ENTER_IMPS_RSP:
+ return "eWNI_PMC_ENTER_IMPS_RSP\n";
+ case eWNI_PMC_EXIT_IMPS_RSP:
+ return "eWNI_PMC_EXIT_IMPS_RSP\n";
+ case eWNI_PMC_ENTER_BMPS_RSP:
+ return "eWNI_PMC_ENTER_BMPS_RSP\n";
+ case eWNI_PMC_EXIT_BMPS_RSP:
+ return "eWNI_PMC_EXIT_BMPS_RSP\n";
+ case eWNI_PMC_EXIT_BMPS_IND:
+ return "eWNI_PMC_EXIT_BMPS_IND\n";
+ default:
+ return "INVALID SME message\n";
+ }
+#endif
+return "";
+}
+
+
+
+char *limResultCodeStr(tSirResultCodes resultCode)
+{
+#ifdef FIXME_GEN6
+ switch (resultCode)
+ {
+ case eSIR_SME_SUCCESS:
+ return "eSIR_SME_SUCCESS\n";
+ case eSIR_EOF_SOF_EXCEPTION:
+ return "eSIR_EOF_SOF_EXCEPTION\n";
+ case eSIR_BMU_EXCEPTION:
+ return "eSIR_BMU_EXCEPTION\n";
+ case eSIR_LOW_PDU_EXCEPTION:
+ return "eSIR_LOW_PDU_EXCEPTION\n";
+ case eSIR_USER_TRIG_RESET:
+ return"eSIR_USER_TRIG_RESET\n";
+ case eSIR_LOGP_EXCEPTION:
+ return "eSIR_LOGP_EXCEPTION\n";
+ case eSIR_CP_EXCEPTION:
+ return "eSIR_CP_EXCEPTION\n";
+ case eSIR_STOP_BSS:
+ return "eSIR_STOP_BSS\n";
+ case eSIR_AHB_HANG_EXCEPTION:
+ return "eSIR_AHB_HANG_EXCEPTION\n";
+ case eSIR_DPU_EXCEPTION:
+ return "eSIR_DPU_EXCEPTION\n";
+ case eSIR_RXP_EXCEPTION:
+ return "eSIR_RXP_EXCEPTION\n";
+ case eSIR_MCPU_EXCEPTION:
+ return "eSIR_MCPU_EXCEPTION\n";
+ case eSIR_MCU_EXCEPTION:
+ return "eSIR_MCU_EXCEPTION\n";
+ case eSIR_MTU_EXCEPTION:
+ return "eSIR_MTU_EXCEPTION\n";
+ case eSIR_MIF_EXCEPTION:
+ return "eSIR_MIF_EXCEPTION\n";
+ case eSIR_FW_EXCEPTION:
+ return "eSIR_FW_EXCEPTION\n";
+ case eSIR_MAILBOX_SANITY_CHK_FAILED:
+ return "eSIR_MAILBOX_SANITY_CHK_FAILED\n";
+ case eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF:
+ return "eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF\n";
+ case eSIR_CFB_FLAG_STUCK_EXCEPTION:
+ return "eSIR_CFB_FLAG_STUCK_EXCEPTION\n";
+ case eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS:
+ return "eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS\n";
+ case eSIR_SME_INVALID_PARAMETERS:
+ return "eSIR_SME_INVALID_PARAMETERS\n";
+ case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE:
+ return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE\n";
+ case eSIR_SME_RESOURCES_UNAVAILABLE:
+ return "eSIR_SME_RESOURCES_UNAVAILABLE\n";
+ case eSIR_SME_SCAN_FAILED:
+ return "eSIR_SME_SCAN_FAILED\n";
+ case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED:
+ return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED\n";
+ case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE:
+ return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE\n";
+ case eSIR_SME_REFUSED:
+ return "eSIR_SME_REFUSED\n";
+ case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE\n";
+ case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE\n";
+ case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE\n";
+ case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE\n";
+ case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED:
+ return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED\n";
+ case eSIR_SME_AUTH_REFUSED:
+ return "eSIR_SME_AUTH_REFUSED\n";
+ case eSIR_SME_INVALID_WEP_DEFAULT_KEY:
+ return "eSIR_SME_INVALID_WEP_DEFAULT_KEY\n";
+ case eSIR_SME_ASSOC_REFUSED:
+ return "eSIR_SME_ASSOC_REFUSED\n";
+ case eSIR_SME_REASSOC_REFUSED:
+ return "eSIR_SME_REASSOC_REFUSED\n";
+ case eSIR_SME_STA_NOT_AUTHENTICATED:
+ return "eSIR_SME_STA_NOT_AUTHENTICATED\n";
+ case eSIR_SME_STA_NOT_ASSOCIATED:
+ return "eSIR_SME_STA_NOT_ASSOCIATED\n";
+ case eSIR_SME_STA_DISASSOCIATED:
+ return "eSIR_SME_STA_DISASSOCIATED\n";
+ case eSIR_SME_ALREADY_JOINED_A_BSS:
+ return "eSIR_SME_ALREADY_JOINED_A_BSS\n";
+ case eSIR_ULA_COMPLETED:
+ return "eSIR_ULA_COMPLETED\n";
+ case eSIR_ULA_FAILURE:
+ return "eSIR_ULA_FAILURE\n";
+ case eSIR_SME_LINK_ESTABLISHED:
+ return "eSIR_SME_LINK_ESTABLISHED\n";
+ case eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS:
+ return "eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS\n";
+ case eSIR_SME_UNABLE_TO_PERFORM_DFS:
+ return "eSIR_SME_UNABLE_TO_PERFORM_DFS\n";
+ case eSIR_SME_DFS_FAILED:
+ return "eSIR_SME_DFS_FAILED\n";
+ case eSIR_SME_TRANSFER_STA:
+ return "eSIR_SME_TRANSFER_STA\n";
+ case eSIR_SME_INVALID_LINK_TEST_PARAMETERS:
+ return "eSIR_SME_INVALID_LINK_TEST_PARAMETERS\n";
+ case eSIR_SME_LINK_TEST_MAX_EXCEEDED:
+ return "eSIR_SME_LINK_TEST_MAX_EXCEEDED\n";
+ case eSIR_SME_UNSUPPORTED_RATE:
+ return "eSIR_SME_UNSUPPORTED_RATE\n";
+ case eSIR_SME_LINK_TEST_TIMEOUT:
+ return "eSIR_SME_LINK_TEST_TIMEOUT\n";
+ case eSIR_SME_LINK_TEST_COMPLETE:
+ return "eSIR_SME_LINK_TEST_COMPLETE\n";
+ case eSIR_SME_LINK_TEST_INVALID_STATE:
+ return "eSIR_SME_LINK_TEST_INVALID_STATE\n";
+ case eSIR_SME_LINK_TEST_INVALID_ADDRESS:
+ return "eSIR_SME_LINK_TEST_INVALID_ADDRESS\n";
+ case eSIR_SME_POLARIS_RESET:
+ return "eSIR_SME_POLARIS_RESET\n";
+ case eSIR_SME_SETCONTEXT_FAILED:
+ return "eSIR_SME_SETCONTEXT_FAILED\n";
+ case eSIR_SME_BSS_RESTART:
+ return "eSIR_SME_BSS_RESTART\n";
+ case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW:
+ return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW\n";
+ case eSIR_SME_INVALID_ASSOC_RSP_RXED:
+ return "eSIR_SME_INVALID_ASSOC_RSP_RXED\n";
+ case eSIR_SME_MIC_COUNTER_MEASURES:
+ return "eSIR_SME_MIC_COUNTER_MEASURES\n";
+ case eSIR_SME_ADDTS_RSP_TIMEOUT:
+ return "eSIR_SME_ADDTS_RSP_TIMEOUT\n";
+ case eSIR_SME_RECEIVED:
+ return "eSIR_SME_RECEIVED\n";
+ case eSIR_SME_CHANNEL_SWITCH_FAIL:
+ return "eSIR_SME_CHANNEL_SWITCH_FAIL\n";
+#ifdef GEN4_SCAN
+ case eSIR_SME_CHANNEL_SWITCH_DISABLED:
+ return "eSIR_SME_CHANNEL_SWITCH_DISABLED\n";
+ case eSIR_SME_HAL_SCAN_INIT_FAILED:
+ return "eSIR_SME_HAL_SCAN_INIT_FAILED\n";
+ case eSIR_SME_HAL_SCAN_START_FAILED:
+ return "eSIR_SME_HAL_SCAN_START_FAILED\n";
+ case eSIR_SME_HAL_SCAN_END_FAILED:
+ return "eSIR_SME_HAL_SCAN_END_FAILED\n";
+ case eSIR_SME_HAL_SCAN_FINISH_FAILED:
+ return "eSIR_SME_HAL_SCAN_FINISH_FAILED\n";
+ case eSIR_SME_HAL_SEND_MESSAGE_FAIL:
+ return "eSIR_SME_HAL_SEND_MESSAGE_FAIL\n";
+#else // GEN4_SCAN
+ case eSIR_SME_CHANNEL_SWITCH_DISABLED:
+ return "eSIR_SME_CHANNEL_SWITCH_DISABLED\n";
+ case eSIR_SME_HAL_SEND_MESSAGE_FAIL:
+ return "eSIR_SME_HAL_SEND_MESSAGE_FAIL\n";
+#endif // GEN4_SCAN
+
+ default:
+ return "INVALID resultCode\n";
+ }
+#endif
+return "";
+}
+
+void
+limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType)
+{
+ limLog(pMac, logLevel, limMsgStr(msgType));
+}
+
+
+#if defined(ANI_MIPS) || defined(ANI_ARM)
+#define LINK 0
+#else
+#define LINK 1
+#endif
+
+void
+limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg)
+{
+ //tSirMacFrameCtl fc; // FIXME_GEN4 - ASAP!!
+#if defined (ANI_OS_TYPE_LINUX) || defined (ANI_OS_TYPE_OSX)
+ tANI_U32 *pRxPacketInfo;
+#endif
+ if (logLevel <= pMac->utils.gLogDbgLevel[SIR_LIM_MODULE_ID - LOG_FIRST_MODULE_ID])
+ {
+ switch (msg->type)
+ {
+ case SIR_BB_XPORT_MGMT_MSG:
+#if defined (ANI_OS_TYPE_LINUX) || defined (ANI_OS_TYPE_OSX)
+#ifndef GEN6_ONWARDS //PAL does not provide this API GEN6 onwards.
+ palGetPacketDataPtr( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, (void *) msg->bodyptr, (void **) &pRxPacketInfo );
+#endif //GEN6_ONWARDS
+#else
+ limPrintMsgName(pMac, logLevel,msg->type);
+#endif
+ break;
+ default:
+ limPrintMsgName(pMac, logLevel,msg->type);
+ break;
+ }
+ }
+}
+
+/**
+ * limInitMlm()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() to
+ * initialize MLM state machine on STA
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+void
+limInitMlm(tpAniSirGlobal pMac)
+{
+ MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState));
+
+ /// Initialize scan result hash table
+ limReInitScanResults(pMac); //sep26th review
+
+
+ /// Initialize number of pre-auth contexts
+ pMac->lim.gLimNumPreAuthContexts = 0;
+
+ /// Initialize MAC based Authentication STA list
+ limInitPreAuthList(pMac);
+
+ //pMac->lim.gpLimMlmJoinReq = NULL;
+
+ if (pMac->lim.gLimTimersCreated)
+ return;
+
+ // Create timers used by LIM
+ limCreateTimers(pMac);
+
+ pMac->lim.gLimTimersCreated = 1;
+} /*** end limInitMlm() ***/
+
+
+
+/**
+ * limCleanupMlm()
+ *
+ *FUNCTION:
+ * This function is called to cleanup any resources
+ * allocated by the MLM state machine.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * It is assumed that BSS is already informed that we're leaving it
+ * before this function is called.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param None
+ * @return None
+ */
+void
+limCleanupMlm(tpAniSirGlobal pMac)
+{
+ tANI_U32 n;
+ tLimPreAuthNode *pAuthNode;
+
+ if (pMac->lim.gLimTimersCreated == 1)
+ {
+ // Deactivate and delete MIN/MAX channel timers.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer);
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimMaxChannelTimer);
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer);
+
+
+ // Deactivate and delete channel switch timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer);
+
+
+ // Deactivate and delete addts response timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer);
+
+ // Deactivate and delete Join failure timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer);
+
+ // Deactivate and delete Association failure timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer);
+
+ // Deactivate and delete Reassociation failure timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer);
+
+ // Deactivate and delete Authentication failure timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer);
+
+ // Deactivate and delete Heartbeat timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimHeartBeatTimer);
+
+ // Deactivate and delete wait-for-probe-after-Heartbeat timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+
+ // Deactivate and delete Quiet timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer);
+
+ // Deactivate and delete Quiet BSS timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer);
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ // Deactivate and delete LIM background scan timer.
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimBackgroundScanTimer);
+#endif
+
+
+ // Deactivate and delete cnf wait timer
+ for (n = 0; n < pMac->lim.maxStation; n++)
+ {
+ tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]);
+ tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]);
+ }
+
+ // Deactivate and delete keepalive timer
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimKeepaliveTimer);
+
+ pAuthNode = pMac->lim.gLimPreAuthTimerTable.pTable;
+
+ //Deactivate any Authentication response timers
+ limDeletePreAuthList(pMac);
+
+ for (n = 0; n < pMac->lim.gLimPreAuthTimerTable.numEntry; n++,pAuthNode++)
+ {
+ // Delete any Authentication response
+ // timers, which might have been started.
+ tx_timer_delete(&pAuthNode->timer);
+ }
+
+#ifdef ANI_PRODUCT_TYPE_AP
+
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ // Deactivate and cleanup the periodic pre-auth
+ // cleanup timer
+
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimPreAuthClnupTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimPreAuthClnupTimer);
+
+ /// Deactivate and delete OLBC cache update timeout
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+
+ }
+#endif
+
+
+ // Deactivate and delete Hash Miss throttle timer
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimPreAuthClnupTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimPreAuthClnupTimer);
+
+#if 0 // The WPS PBC clean up timer is disabled
+ if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
+ {
+ if(pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated == eANI_BOOLEAN_TRUE)
+ {
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer);
+ pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated = eANI_BOOLEAN_FALSE;
+ }
+ }
+#endif
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ // Deactivate and delete FT Preauth response timer
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+#endif
+
+#ifdef WLAN_FEATURE_P2P
+ // Deactivate and delete remain on channel timer
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
+#endif
+
+#ifdef FEATURE_WLAN_CCX
+ // Deactivate and delete TSM
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimCcxTsmTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimCcxTsmTimer);
+#endif
+
+ pMac->lim.gLimTimersCreated = 0;
+ }
+
+ /// Cleanup cached scan list
+ limReInitScanResults(pMac);
+
+} /*** end limCleanupMlm() ***/
+
+
+
+/**
+ * limCleanupLmm()
+ *
+ *FUNCTION:
+ * This function is called to cleanup any resources
+ * allocated by LMM sub-module.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limCleanupLmm(tpAniSirGlobal pMac)
+{
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined (ANI_PRODUCT_TYPE_AP)
+ limCleanupMeasResources(pMac);
+ pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_FALSE;
+#endif
+} /*** end limCleanupLmm() ***/
+
+
+
+/**
+ * limIsAddrBC()
+ *
+ *FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a broadcast or not
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param macAddr Indicates MAC address that need to be determined
+ * whether it is Broadcast address or not
+ *
+ * @return true if passed address is Broadcast address else false
+ */
+
+tANI_U8
+limIsAddrBC(tSirMacAddr macAddr)
+{
+ int i;
+ for (i = 0; i < 6; i++)
+ {
+ if ((macAddr[i] & 0xFF) != 0xFF)
+ return false;
+ }
+
+ return true;
+} /****** end limIsAddrBC() ******/
+
+
+
+/**
+ * limIsGroupAddr()
+ *
+ *FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a group address or not
+ *
+ *LOGIC:
+ * If least significant bit of first octet of the MAC address is
+ * set to 1, it is a Group address.
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param macAddr Indicates MAC address that need to be determined
+ * whether it is Group address or not
+ *
+ * @return true if passed address is Group address else false
+ */
+
+tANI_U8
+limIsGroupAddr(tSirMacAddr macAddr)
+{
+ if ((macAddr[0] & 0x01) == 0x01)
+ return true;
+ else
+ return false;
+} /****** end limIsGroupAddr() ******/
+
+/**
+ * limPostMsgApiNoWait()
+ *
+ *FUNCTION:
+ * This function is called from other thread while posting a
+ * message to LIM message Queue gSirLimMsgQ with NO_WAIT option
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMsg - Pointer to the Global MAC structure
+ * @param pMsg - Pointer to the message structure
+ * @return None
+ */
+
+tANI_U32
+limPostMsgApiNoWait(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+#ifdef ANI_OS_TYPE_WINDOWS
+ tANI_U32 retCode;
+
+ if ((retCode = tx_queue_send(&pMac->sys.gSirLimMsgQ, pMsg, TX_NO_WAIT))
+ != TX_SUCCESS)
+ {
+ // Failure in sending DFS duration timeout indication
+ // to LIM thread
+
+ // Log error
+ limLog(pMac, LOGP,
+ FL("could not post a message %X to LIM msgq, status=%d\n"),
+ pMsg->type, retCode);
+ }
+
+ return retCode;
+#else
+ limProcessMessages(pMac, pMsg);
+ return TX_SUCCESS;
+#endif
+} /*** end limPostMsgApiNoWait() ***/
+
+
+
+/**
+ * limPrintMacAddr()
+ *
+ *FUNCTION:
+ * This function is called to print passed MAC address
+ * in : format.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * @param macAddr - MacAddr to be printed
+ * @param logLevel - Loglevel to be used
+ *
+ * @return None.
+ */
+
+void
+limPrintMacAddr(tpAniSirGlobal pMac, tSirMacAddr macAddr, tANI_U8 logLevel)
+{
+ limLog(pMac, logLevel,
+ FL("%X:%X:%X:%X:%X:%X\n"),
+ macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
+ macAddr[5]);
+} /****** end limPrintMacAddr() ******/
+
+
+
+
+
+
+/*
+ * limResetDeferredMsgQ()
+ *
+ *FUNCTION:
+ * This function resets the deferred message queue parameters.
+ *
+ *PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ *RETURNS:
+ * None
+ */
+
+void limResetDeferredMsgQ(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimDeferredMsgQ.size =
+ pMac->lim.gLimDeferredMsgQ.write =
+ pMac->lim.gLimDeferredMsgQ.read = 0;
+
+}
+
+
+#define LIM_DEFERRED_Q_CHECK_THRESHOLD (MAX_DEFERRED_QUEUE_LEN/2)
+#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2)
+
+/*
+ * limWriteDeferredMsgQ()
+ *
+ *FUNCTION:
+ * This function queues up a deferred message for later processing on the
+ * STA side.
+ *
+ *PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ * @param limMsg - a LIM message
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ *RETURNS:
+ * None
+ */
+
+tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ PELOG1(limLog(pMac, LOG1,
+ FL("** Queue a deferred message (size %d, write %d) - type 0x%x **\n"),
+ pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.write,
+ limMsg->type);)
+
+ /*
+ ** check if the deferred message queue is full
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Deferred Message Queue is full. Msg: %d\n"), limMsg->type);)
+ return TX_QUEUE_FULL;
+ }
+
+ /*
+ ** In the application, there should not be more than 1 message get
+ ** queued up. If happens, flags a warning. In the future, this can
+ ** happen.
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.size > 0)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("%d Deferred messages (type 0x%x, scan %d, sme %d, mlme %d, addts %d)\n"),
+ pMac->lim.gLimDeferredMsgQ.size, limMsg->type,
+ limIsSystemInScanState(pMac),
+ pMac->lim.gLimSmeState, pMac->lim.gLimMlmState,
+ pMac->lim.gLimAddtsSent);)
+ }
+
+ /*
+ ** To prevent the deferred Q is full of management frames, only give them certain space
+ **/
+ if( SIR_BB_XPORT_MGMT_MSG == limMsg->type )
+ {
+ if( LIM_DEFERRED_Q_CHECK_THRESHOLD < pMac->lim.gLimDeferredMsgQ.size )
+ {
+ tANI_U16 idx, count = 0;
+ for(idx = 0; idx < pMac->lim.gLimDeferredMsgQ.size; idx++)
+ {
+ if( SIR_BB_XPORT_MGMT_MSG == pMac->lim.gLimDeferredMsgQ.deferredQueue[idx].type )
+ {
+ count++;
+ }
+ }
+ if( LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count )
+ {
+ //We reach the quota for management frames, drop this one
+ PELOGE(limLog(pMac, LOGE, FL("Cannot deferred. Msg: %d Too many (count=%d) already\n"), limMsg->type, count);)
+ //Return error, caller knows what to do
+ return TX_QUEUE_FULL;
+ }
+ }
+ }
+
+ ++pMac->lim.gLimDeferredMsgQ.size;
+
+ /*
+ ** if the write pointer hits the end of the queue, rewind it
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN)
+ pMac->lim.gLimDeferredMsgQ.write = 0;
+
+ /*
+ ** save the message to the queue and advanced the write pointer
+ **/
+ palCopyMemory(pMac->hHdd,
+ (tANI_U8 *)&pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.gLimDeferredMsgQ.write++],
+ (tANI_U8 *)limMsg,
+ sizeof(tSirMsgQ));
+ return TX_SUCCESS;
+
+}
+
+/*
+ * limReadDeferredMsgQ()
+ *
+ *FUNCTION:
+ * This function dequeues a deferred message for processing on the
+ * STA side.
+ *
+ *PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ *
+ *RETURNS:
+ * Returns the message at the head of the deferred message queue
+ */
+
+tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac)
+{
+ tSirMsgQ *msg;
+
+ /*
+ ** check any messages left. If no, return
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.size <= 0)
+ return NULL;
+
+ /*
+ ** decrement the queue size
+ **/
+ pMac->lim.gLimDeferredMsgQ.size--;
+
+ /*
+ ** retrieve the message from the head of the queue
+ **/
+ msg = &pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.gLimDeferredMsgQ.read];
+
+ /*
+ ** advance the read pointer
+ **/
+ pMac->lim.gLimDeferredMsgQ.read++;
+
+ /*
+ ** if the read pointer hits the end of the queue, rewind it
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN)
+ pMac->lim.gLimDeferredMsgQ.read = 0;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("** DeQueue a deferred message (size %d read %d) - type 0x%x **\n"),
+ pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.read,
+ msg->type);)
+
+ PELOG1(limLog(pMac, LOG1, FL("DQ msg -- scan %d, sme %d, mlme %d, addts %d\n"),
+ limIsSystemInScanState(pMac),
+ pMac->lim.gLimSmeState, pMac->lim.gLimMlmState,
+ pMac->lim.gLimAddtsSent);)
+
+ return(msg);
+}
+
+tSirRetStatus
+limSysProcessMmhMsgApi(tpAniSirGlobal pMac,
+ tSirMsgQ *pMsg,
+ tANI_U8 qType)
+{
+// FIXME
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+ SysProcessMmhMsg(pMac, pMsg);
+ return eSIR_SUCCESS;
+#else
+ return(halMmhPostMsgApi(pMac, pMsg, qType));
+#endif
+}
+
+char *limFrameStr(tANI_U32 type, tANI_U32 subType)
+{
+#ifdef FIXME_GEN6
+
+ if (type == SIR_MAC_MGMT_FRAME)
+ {
+ switch (subType)
+ {
+ case SIR_MAC_MGMT_ASSOC_REQ:
+ return "MAC_MGMT_ASSOC_REQ";
+ case SIR_MAC_MGMT_ASSOC_RSP:
+ return "MAC_MGMT_ASSOC_RSP";
+ case SIR_MAC_MGMT_REASSOC_REQ:
+ return "MAC_MGMT_REASSOC_REQ";
+ case SIR_MAC_MGMT_REASSOC_RSP:
+ return "MAC_MGMT_REASSOC_RSP";
+ case SIR_MAC_MGMT_PROBE_REQ:
+ return "MAC_MGMT_PROBE_REQ";
+ case SIR_MAC_MGMT_PROBE_RSP:
+ return "MAC_MGMT_PROBE_RSP";
+ case SIR_MAC_MGMT_BEACON:
+ return "MAC_MGMT_BEACON";
+ case SIR_MAC_MGMT_ATIM:
+ return "MAC_MGMT_ATIM";
+ case SIR_MAC_MGMT_DISASSOC:
+ return "MAC_MGMT_DISASSOC";
+ case SIR_MAC_MGMT_AUTH:
+ return "MAC_MGMT_AUTH";
+ case SIR_MAC_MGMT_DEAUTH:
+ return "MAC_MGMT_DEAUTH";
+ case SIR_MAC_MGMT_ACTION:
+ return "MAC_MGMT_ACTION";
+ case SIR_MAC_MGMT_RESERVED15:
+ return "MAC_MGMT_RESERVED15";
+ default:
+ return "Unknown MGMT Frame";
+ }
+ }
+
+ else if (type == SIR_MAC_CTRL_FRAME)
+ {
+ switch (subType)
+ {
+ case SIR_MAC_CTRL_RR:
+ return "MAC_CTRL_RR";
+ case SIR_MAC_CTRL_BAR:
+ return "MAC_CTRL_BAR";
+ case SIR_MAC_CTRL_BA:
+ return "MAC_CTRL_BA";
+ case SIR_MAC_CTRL_PS_POLL:
+ return "MAC_CTRL_PS_POLL";
+ case SIR_MAC_CTRL_RTS:
+ return "MAC_CTRL_RTS";
+ case SIR_MAC_CTRL_CTS:
+ return "MAC_CTRL_CTS";
+ case SIR_MAC_CTRL_ACK:
+ return "MAC_CTRL_ACK";
+ case SIR_MAC_CTRL_CF_END:
+ return "MAC_CTRL_CF_END";
+ case SIR_MAC_CTRL_CF_END_ACK:
+ return "MAC_CTRL_CF_END_ACK";
+ default:
+ return "Unknown CTRL Frame";
+ }
+ }
+
+ else if (type == SIR_MAC_DATA_FRAME)
+ {
+ switch (subType)
+ {
+ case SIR_MAC_DATA_DATA:
+ return "MAC_DATA_DATA";
+ case SIR_MAC_DATA_DATA_ACK:
+ return "MAC_DATA_DATA_ACK";
+ case SIR_MAC_DATA_DATA_POLL:
+ return "MAC_DATA_DATA_POLL";
+ case SIR_MAC_DATA_DATA_ACK_POLL:
+ return "MAC_DATA_DATA_ACK_POLL";
+ case SIR_MAC_DATA_NULL:
+ return "MAC_DATA_NULL";
+ case SIR_MAC_DATA_NULL_ACK:
+ return "MAC_DATA_NULL_ACK";
+ case SIR_MAC_DATA_NULL_POLL:
+ return "MAC_DATA_NULL_POLL";
+ case SIR_MAC_DATA_NULL_ACK_POLL:
+ return "MAC_DATA_NULL_ACK_POLL";
+ case SIR_MAC_DATA_QOS_DATA:
+ return "MAC_DATA_QOS_DATA";
+ case SIR_MAC_DATA_QOS_DATA_ACK:
+ return "MAC_DATA_QOS_DATA_ACK";
+ case SIR_MAC_DATA_QOS_DATA_POLL:
+ return "MAC_DATA_QOS_DATA_POLL";
+ case SIR_MAC_DATA_QOS_DATA_ACK_POLL:
+ return "MAC_DATA_QOS_DATA_ACK_POLL";
+ case SIR_MAC_DATA_QOS_NULL:
+ return "MAC_DATA_QOS_NULL";
+ case SIR_MAC_DATA_QOS_NULL_ACK:
+ return "MAC_DATA_QOS_NULL_ACK";
+ case SIR_MAC_DATA_QOS_NULL_POLL:
+ return "MAC_DATA_QOS_NULL_POLL";
+ case SIR_MAC_DATA_QOS_NULL_ACK_POLL:
+ return "MAC_DATA_QOS_NULL_ACK_POLL";
+ default:
+ return "Unknown Data Frame";
+ }
+ }
+ else
+ return "Unknown";
+#endif
+return "";
+}
+
+#ifdef WLAN_SOFTAP_FEATURE
+void limHandleUpdateOlbcCache(tpAniSirGlobal pMac)
+{
+ int i;
+ static int enable;
+ tUpdateBeaconParams beaconParams;
+
+ tpPESession psessionEntry = limIsApSessionActive(pMac);
+
+ if (psessionEntry == NULL)
+ return;
+
+ beaconParams.paramChangeBitmap = 0;
+ /*
+ ** This is doing a 2 pass check. The first pass is to invalidate
+ ** all the cache entries. The second pass is to decide whether to
+ ** disable protection.
+ **/
+ if (!enable)
+ {
+
+ PELOG2(limLog(pMac, LOG2, FL("Resetting OLBC cache\n"));)
+ psessionEntry->gLimOlbcParams.numSta = 0;
+ psessionEntry->gLimOverlap11gParams.numSta = 0;
+ psessionEntry->gLimOverlapHt20Params.numSta = 0;
+ psessionEntry->gLimNonGfParams.numSta = 0;
+ psessionEntry->gLimLsigTxopParams.numSta = 0;
+
+ for (i=0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
+ pMac->lim.protStaOverlapCache[i].active = false;
+
+ enable = 1;
+ }
+ else
+ {
+
+ if (!psessionEntry->gLimOverlap11gParams.numSta)
+ {
+ if (psessionEntry->gLimOlbcParams.protectionEnabled)
+ {
+ if (!psessionEntry->gLim11bParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11B STA detected\n"));)
+ limEnable11gProtection(pMac, false, true, &beaconParams, psessionEntry);
+ }
+ }
+ }
+
+ if (!psessionEntry->gLimOverlap11gParams.numSta)
+ {
+ if (psessionEntry->gLimOverlap11gParams.protectionEnabled)
+ {
+ if (!psessionEntry->gLim11gParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11G STA detected\n"));)
+ limEnableHtProtectionFrom11g(pMac, false, true, &beaconParams,psessionEntry);
+ }
+ }
+ }
+
+ if (!psessionEntry->gLimOverlapHt20Params.numSta)
+ {
+ if (psessionEntry->gLimOverlapHt20Params.protectionEnabled)
+ {
+ if (!psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no HT20 STA detected\n"));)
+ limEnable11gProtection(pMac, false, true, &beaconParams,psessionEntry);
+ }
+ }
+ }
+
+ enable = 0;
+ }
+
+ if(beaconParams.paramChangeBitmap)
+ {
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ limSendBeaconParams(pMac, &beaconParams, psessionEntry);
+ }
+
+ // Start OLBC timer
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("tx_timer_activate failed\n"));
+ }
+}
+#endif
+
+/**
+ * limIsNullSsid()
+ *
+ *FUNCTION:
+ * This function checks if Ssid supplied is Null SSID
+ *
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param tSirMacSSid *
+ *
+ *
+ * @return true if SSID is Null SSID else false
+ */
+
+tANI_U8
+limIsNullSsid( tSirMacSSid *pSsid )
+{
+ tANI_U8 fNullSsid = false;
+ tANI_U32 SsidLength;
+ tANI_U8 *pSsidStr;
+
+ do
+ {
+ if ( 0 == pSsid->length )
+ {
+ fNullSsid = true;
+ break;
+ }
+
+#define ASCII_SPACE_CHARACTER 0x20
+ /* If the first charactes is space, then check if all characters in
+ * SSID are spaces to consider it as NULL SSID*/
+ if( ASCII_SPACE_CHARACTER == pSsid->ssId[0])
+ {
+ SsidLength = pSsid->length;
+ pSsidStr = pSsid->ssId;
+ /* check if all the charactes in SSID are spaces*/
+ while ( SsidLength )
+ {
+ if( ASCII_SPACE_CHARACTER != *pSsidStr )
+ break;
+
+ pSsidStr++;
+ SsidLength--;
+ }
+
+ if( 0 == SsidLength )
+ {
+ fNullSsid = true;
+ break;
+ }
+ }
+ else
+ {
+ /* check if all the charactes in SSID are NULL*/
+ SsidLength = pSsid->length;
+ pSsidStr = pSsid->ssId;
+
+ while ( SsidLength )
+ {
+ if( *pSsidStr )
+ break;
+
+ pSsidStr++;
+ SsidLength--;
+ }
+
+ if( 0 == SsidLength )
+ {
+ fNullSsid = true;
+ break;
+ }
+ }
+ }
+ while( 0 );
+
+ return fNullSsid;
+} /****** end limIsNullSsid() ******/
+
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+
+/** -------------------------------------------------------------
+\fn limUpdateProtStaParams
+\brief updates protection related counters.
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tLimProtStaCacheType protStaCacheType
+\param tHalBitVal gfSupported
+\param tHalBitVal lsigTxopSupported
+\return None
+ -------------------------------------------------------------*/
+void
+limUpdateProtStaParams(tpAniSirGlobal pMac,
+tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType,
+tHalBitVal gfSupported, tHalBitVal lsigTxopSupported,
+tpPESession psessionEntry)
+{
+ tANI_U32 i;
+
+ PELOG1(limLog(pMac,LOG1, FL("A STA is associated:"));
+ limLog(pMac,LOG1, FL("Addr : "));
+ limPrintMacAddr(pMac, peerMacAddr, LOG1);)
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (psessionEntry->protStaCache[i].active)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Addr: "));)
+ PELOG1(limPrintMacAddr(pMac, psessionEntry->protStaCache[i].addr, LOG1);)
+
+ if (palEqualMemory( pMac->hHdd,
+ psessionEntry->protStaCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active.\n"), i);)
+ return;
+ }
+ }
+ }
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+ if (!psessionEntry->protStaCache[i].active)
+ break;
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache\n"));)
+ return;
+ }
+
+ palCopyMemory( pMac->hHdd, psessionEntry->protStaCache[i].addr,
+ peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType;
+ psessionEntry->protStaCache[i].active = true;
+ if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType)
+ {
+ psessionEntry->gLim11bParams.numSta++;
+ limLog(pMac,LOG1, FL("11B, "));
+ }
+ else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType)
+ {
+ psessionEntry->gLim11gParams.numSta++;
+ limLog(pMac,LOG1, FL("11G, "));
+ }
+ else if(eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType)
+ {
+ psessionEntry->gLimHt20Params.numSta++;
+ limLog(pMac,LOG1, FL("HT20, "));
+ }
+
+ if(!gfSupported)
+ {
+ psessionEntry->gLimNonGfParams.numSta++;
+ limLog(pMac,LOG1, FL("NonGf, "));
+ }
+ if(!lsigTxopSupported)
+ {
+ psessionEntry->gLimLsigTxopParams.numSta++;
+ limLog(pMac,LOG1, FL("!lsigTxopSupported\n"));
+ }
+}// ---------------------------------------------------------------------
+
+/** -------------------------------------------------------------
+\fn limDecideApProtection
+\brief Decides all the protection related staiton coexistence and also sets
+\ short preamble and short slot appropriately. This function will be called
+\ when AP is ready to send assocRsp tp the station joining right now.
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\return None
+ -------------------------------------------------------------*/
+void
+limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ tANI_U16 tmpAid;
+ tpDphHashNode pStaDs;
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 phyMode;
+ tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID;
+ tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET;
+
+ pBeaconParams->paramChangeBitmap = 0;
+ // check whether to enable protection or not
+ pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable);
+ if(NULL == pStaDs)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("pStaDs is NULL\n"));)
+ return;
+ }
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ //if we are in 5 GHZ band
+ if(SIR_BAND_5_GHZ == rfBand)
+ {
+ //We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ.
+ //HT20 case is common between both the bands and handled down as common code.
+ if(true == psessionEntry->htCapabality)
+ {
+ //we are 11N and 11A station is joining.
+ //protection from 11A required.
+ if(false == pStaDs->mlmStaContext.htCapability)
+ {
+ limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry);
+ return;
+ }
+ }
+ }
+ else if(SIR_BAND_2_4_GHZ== rfBand)
+ {
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ //We are 11G. Check if we need protection from 11b Stations.
+ if ((phyMode == WNI_CFG_PHY_MODE_11G) &&
+ (false == psessionEntry->htCapabality))
+ {
+
+ if (pStaDs->erpEnabled== eHAL_CLEAR)
+ {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ // enable protection
+ PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B\n"));)
+ limEnable11gProtection(pMac, true, false, pBeaconParams,psessionEntry);
+ }
+ }
+
+ //HT station.
+ if (true == psessionEntry->htCapabality)
+ {
+ //check if we need protection from 11b station
+ if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+ (!pStaDs->mlmStaContext.htCapability))
+ {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ // enable protection
+ PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B\n"));)
+ limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry);
+ }
+ //station being joined is non-11b and non-ht ==> 11g device
+ else if(!pStaDs->mlmStaContext.htCapability)
+ {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG;
+ //enable protection
+ limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams, psessionEntry);
+ }
+ //ERP mode is enabled for the latest station joined
+ //latest station joined is HT capable
+ //This case is being handled in common code (commn between both the bands) below.
+ }
+ }
+
+ //we are HT and HT station is joining. This code is common for both the bands.
+ if((true == psessionEntry->htCapabality) &&
+ (true == pStaDs->mlmStaContext.htCapability))
+ {
+ if(!pStaDs->htGreenfield)
+ {
+ limEnableHTNonGfProtection(pMac, true, false, pBeaconParams, psessionEntry);
+ gfSupported = eHAL_CLEAR;
+ }
+ //Station joining is HT 20Mhz
+ if(eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet)
+ {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20;
+ limEnableHT20Protection(pMac, true, false, pBeaconParams, psessionEntry);
+ }
+ //Station joining does not support LSIG TXOP Protection
+ if(!pStaDs->htLsigTXOPProtection)
+ {
+ limEnableHTLsigTxopProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ lsigTxopSupported = eHAL_CLEAR;
+ }
+ }
+
+ limUpdateProtStaParams(pMac, peerMacAddr, protStaCacheType,
+ gfSupported, lsigTxopSupported, psessionEntry);
+
+ return;
+}
+#endif
+
+
+/** -------------------------------------------------------------
+\fn limEnableOverlap11gProtection
+\brief wrapper function for setting overlap 11g protection.
+\param tpAniSirGlobal pMac
+\param tpUpdateBeaconParams pBeaconParams
+\param tpSirMacMgmtHdr pMh
+\return None
+ -------------------------------------------------------------*/
+void
+limEnableOverlap11gProtection(tpAniSirGlobal pMac,
+tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry)
+{
+ limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOlbcParams));
+
+ if (psessionEntry->gLimOlbcParams.numSta &&
+ !psessionEntry->gLimOlbcParams.protectionEnabled)
+ {
+ // enable protection
+ PELOG1(limLog(pMac, LOG1, FL("OLBC happens!!!\n"));)
+ limEnable11gProtection(pMac, true, true, pBeaconParams,psessionEntry);
+ }
+}
+
+
+/** -------------------------------------------------------------
+\fn limUpdateShortPreamble
+\brief Updates short preamble if needed when a new station joins.
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+void
+limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tANI_U16 tmpAid;
+ tpDphHashNode pStaDs;
+ tANI_U32 phyMode;
+ tANI_U16 i;
+
+ // check whether to enable protection or not
+ pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable);
+
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G)
+
+ {
+ if (pStaDs->shortPreambleEnabled == eHAL_CLEAR)
+ {
+ PELOG1(limLog(pMac,LOG1,FL("Short Preamble is not enabled in Assoc Req from "));
+ limPrintMacAddr(pMac, peerMacAddr, LOG1);)
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ psessionEntry->gLimNoShortParams.staNoShortCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,
+ psessionEntry->gLimNoShortParams.staNoShortCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ return;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ if (pMac->lim.gLimNoShortParams.staNoShortCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,
+ pMac->lim.gLimNoShortParams.staNoShortCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ return;
+ }
+ }
+ }
+
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->gLimNoShortParams.staNoShortCache[i].active)
+ break;
+ else
+#endif
+ {
+ if (!pMac->lim.gLimNoShortParams.staNoShortCache[i].active)
+ break;
+ }
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "),
+ i, psessionEntry->gLimNoShortParams.numNonShortPreambleSta);
+ limPrintMacAddr(pMac, peerMacAddr, LOGE);
+ return;
+ }
+ else
+#endif
+ {
+ limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "),
+ i, pMac->lim.gLimNoShortParams.numNonShortPreambleSta);
+ limPrintMacAddr(pMac, peerMacAddr, LOGE);
+ return;
+ }
+
+ }
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ palCopyMemory( pMac->hHdd, psessionEntry->gLimNoShortParams.staNoShortCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ psessionEntry->gLimNoShortParams.staNoShortCache[i].active = true;
+ psessionEntry->gLimNoShortParams.numNonShortPreambleSta++;
+ }else
+#endif
+ {
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimNoShortParams.staNoShortCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ pMac->lim.gLimNoShortParams.staNoShortCache[i].active = true;
+ pMac->lim.gLimNoShortParams.numNonShortPreambleSta++;
+ }
+
+
+ // enable long preamble
+ PELOG1(limLog(pMac, LOG1, FL("Disabling short preamble\n"));)
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if (limEnableShortPreamble(pMac, false, pBeaconParams, psessionEntry) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Cannot enable long preamble\n"));)
+#else
+ if (limEnableShortPreamble(pMac, false, pBeaconParams) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("Cannot enable long preamble\n"));)
+
+#endif
+ }
+ }
+}
+
+/** -------------------------------------------------------------
+\fn limUpdateShortSlotTime
+\brief Updates short slot time if needed when a new station joins.
+\param tpAniSirGlobal pMac
+\param tSirMacAddr peerMacAddr
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+
+void
+limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tANI_U16 tmpAid;
+ tpDphHashNode pStaDs;
+ tANI_U32 phyMode;
+ tANI_U32 val;
+ tANI_U32 cShortSlot;
+ tANI_U16 i;
+
+ // check whether to enable protection or not
+ pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable);
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G)
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, &cShortSlot) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("unable to get short slot time\n"));
+
+ if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Short Slot Time is not enabled in Assoc Req from "));
+ limPrintMacAddr(pMac, peerMacAddr, LOG1);)
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,
+ psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ return;
+ }
+ else if(psessionEntry->limSystemRole != eLIM_AP_ROLE )
+#endif
+ {
+ if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ {
+ if (palEqualMemory( pMac->hHdd,
+ pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr)))
+ return;
+ }
+ }
+ }
+
+ for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ break;
+ else
+#endif
+ {
+ if (!pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active)
+ break;
+ }
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
+ i, psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta);
+ limPrintMacAddr(pMac, peerMacAddr, LOGE);
+ return;
+ }else
+#endif
+ {
+ limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
+ i, pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta);
+ limPrintMacAddr(pMac, peerMacAddr, LOGE);
+ return;
+ }
+ }
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ palCopyMemory( pMac->hHdd, psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = true;
+ psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta++;
+ }else
+#endif
+ {
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = true;
+ pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta++;
+ }
+ wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val);
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta && cShortSlot))
+ {
+ // enable long slot time
+ pBeaconParams->fShortSlotTime = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
+ PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time.\n"));)
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, false) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
+ }
+ else if ( psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta && cShortSlot)
+ {
+ // enable long slot time
+ pBeaconParams->fShortSlotTime = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
+ PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time.\n"));)
+ if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, false) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
+ }
+ }
+ }
+ }
+}
+
+#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined (ANI_PRODUCT_TYPE_AP)
+/**
+ * limDetectRadar()
+ *
+ *FUNCTION:
+ * This function is invoked when LIM receives
+ * SIR_LIM_RADAR_DETECT_IND in lim mesage queue.
+ * LIM will notify WSM of this event by sending
+ * WSM the wireless medium status change
+ * notification message.
+ *
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param message - a tSirRadarInfo struct type message send by HAL.
+ * This message is not serialized.
+ *
+ * @return None
+ */
+
+void
+limDetectRadar(tpAniSirGlobal pMac, tANI_U32 *pMsg)
+{
+ tpSirRadarInfo pRadarInfo;
+
+ if (!pMsg)
+ {
+ limLog(pMac, LOGP, FL("Message is NULL\n"));
+ return;
+ }
+
+ pRadarInfo = (tpSirRadarInfo)pMsg;
+
+ if ((pMac->lim.gLimCurrentChannelId == pRadarInfo->channelNumber) &&
+ (pMac->lim.gLimSystemRole != eLIM_UNKNOWN_ROLE))
+ {
+ LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_TRUE);
+ limStopMeasTimers(pMac);
+ /* Stop the transmission of all packets except beacons.
+ * This is done here, assuming that we will definitely get a channel switch
+ * request from WSM.
+ */
+ PELOG1(limLog(pMac, LOG1, "Stopping the transmission on AP\n");)
+ limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_STOP_TX);
+ }
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("limDetectRadar():: pulsewidth = %d, numPulse=%d, channelId=%d\n"),
+ pRadarInfo->radarPulseWidth, pRadarInfo->numRadarPulse,
+ pRadarInfo->channelNumber);)
+
+ limSendSmeWmStatusChangeNtf(pMac,
+ eSIR_SME_RADAR_DETECTED,
+ pMsg,
+ (tANI_U16)sizeof(*pRadarInfo),0);
+
+}
+#endif
+
+# if 0
+//TBD_RAJESH :: TO SOLVE LINKING ISSUE
+void
+limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, //dummy to avoid linking problem
+ tpUpdateBeaconParams pBeaconParams)
+{
+
+}
+
+//TBD_RAJESH :: TO SOLVE LINKING ISSUE
+void
+limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, //dummy to avoid linking problem
+ tpUpdateBeaconParams pBeaconParams)
+
+{
+}
+
+//TBD_RAJESH :: TO SOLVE LINKING ISSUE
+
+void //dummy to avoid linking problem
+limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+}
+
+#endif
+
+
+/** -------------------------------------------------------------
+\fn limDecideStaProtectionOnAssoc
+\brief Decide protection related settings on Sta while association.
+\param tpAniSirGlobal pMac
+\param tpSchBeaconStruct pBeaconStruct
+\return None
+ -------------------------------------------------------------*/
+void
+limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry)
+{
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE;
+
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ if(SIR_BAND_5_GHZ == rfBand)
+ {
+ if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode))
+ {
+ if(pMac->lim.cfgProtection.fromlla)
+ psessionEntry->beaconParams.llaCoexist = true;
+ }
+ else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBeaconStruct->HTInfo.opMode)
+ {
+ if(pMac->lim.cfgProtection.ht20)
+ psessionEntry->beaconParams.ht20Coexist = true;
+ }
+
+ }
+ else if(SIR_BAND_2_4_GHZ == rfBand)
+ {
+ //spec 7.3.2.13
+ //UseProtection will be set when nonERP STA is associated.
+ //NonERPPresent bit will be set when:
+ //--nonERP Sta is associated OR
+ //--nonERP Sta exists in overlapping BSS
+ //when useProtection is not set then protection from nonERP stations is optional.
+
+ //CFG protection from 11b is enabled and
+ //11B device in the BSS
+ /* TODO, This is not sessionized */
+ if (phyMode != WNI_CFG_PHY_MODE_11B)
+ {
+ if (pMac->lim.cfgProtection.fromllb &&
+ pBeaconStruct->erpPresent &&
+ (pBeaconStruct->erpIEInfo.useProtection ||
+ pBeaconStruct->erpIEInfo.nonErpPresent))
+ {
+ psessionEntry->beaconParams.llbCoexist = true;
+ }
+ //AP has no 11b station associated.
+ else
+ {
+ psessionEntry->beaconParams.llbCoexist = false;
+ }
+ }
+ //following code block is only for HT station.
+ if((psessionEntry->htCapabality) &&
+ (pBeaconStruct->HTInfo.present))
+ {
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+
+ //Obss Non HT STA present mode
+ psessionEntry->beaconParams.gHTObssMode = (tANI_U8)htInfo.obssNonHTStaPresent;
+
+
+ //CFG protection from 11G is enabled and
+ //our AP has at least one 11G station associated.
+ if(pMac->lim.cfgProtection.fromllg &&
+ ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&&
+ (!psessionEntry->beaconParams.llbCoexist))
+ {
+ if(pMac->lim.cfgProtection.fromllg)
+ psessionEntry->beaconParams.llgCoexist = true;
+ }
+
+ //AP has only HT stations associated and at least one station is HT 20
+ //disable protection from any non-HT devices.
+ //decision for disabling protection from 11b has already been taken above.
+ if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode)
+ {
+ //Disable protection from 11G station.
+ psessionEntry->beaconParams.llgCoexist = false;
+ //CFG protection from HT 20 is enabled.
+ if(pMac->lim.cfgProtection.ht20)
+ psessionEntry->beaconParams.ht20Coexist = true;
+ }
+ //Disable protection from non-HT and HT20 devices.
+ //decision for disabling protection from 11b has already been taken above.
+ if(eSIR_HT_OP_MODE_PURE == htInfo.opMode)
+ {
+ psessionEntry->beaconParams.llgCoexist = false;
+ psessionEntry->beaconParams.ht20Coexist = false;
+ }
+
+ }
+ }
+
+ //protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ.
+ if((psessionEntry->htCapabality) &&
+ (pBeaconStruct->HTInfo.present))
+ {
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+ psessionEntry->beaconParams.fRIFSMode =
+ ( tANI_U8 ) htInfo.rifsMode;
+ psessionEntry->beaconParams.llnNonGFCoexist =
+ ( tANI_U8 )htInfo.nonGFDevicesPresent;
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+ ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport;
+ }
+}
+
+
+/** -------------------------------------------------------------
+\fn limDecideStaProtection
+\brief Decides protection related settings on Sta while processing beacon.
+\param tpAniSirGlobal pMac
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+void
+limDecideStaProtection(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE;
+
+ limGetRfBand(pMac, &rfBand, psessionEntry);
+ limGetPhyMode(pMac, &phyMode, psessionEntry);
+
+ if(SIR_BAND_5_GHZ == rfBand)
+ {
+ //we are HT capable.
+ if((true == psessionEntry->htCapabality) &&
+ (pBeaconStruct->HTInfo.present))
+ {
+ //we are HT capable, AP's HT OPMode is mixed / overlap legacy ==> need protection from 11A.
+ if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode))
+ {
+ limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry);
+ }
+ //we are HT capable, AP's HT OPMode is HT20 ==> disable protection from 11A if enabled. enabled
+ //protection from HT20 if needed.
+ else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT== pBeaconStruct->HTInfo.opMode)
+ {
+ limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry);
+ }
+ else if(eSIR_HT_OP_MODE_PURE == pBeaconStruct->HTInfo.opMode)
+ {
+ limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry);
+ limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ else if(SIR_BAND_2_4_GHZ == rfBand)
+ {
+ /* spec 7.3.2.13
+ * UseProtection will be set when nonERP STA is associated.
+ * NonERPPresent bit will be set when:
+ * --nonERP Sta is associated OR
+ * --nonERP Sta exists in overlapping BSS
+ * when useProtection is not set then protection from nonERP stations is optional.
+ */
+
+ if (phyMode != WNI_CFG_PHY_MODE_11B)
+ {
+ if (pBeaconStruct->erpPresent &&
+ (pBeaconStruct->erpIEInfo.useProtection ||
+ pBeaconStruct->erpIEInfo.nonErpPresent))
+ {
+ limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry);
+ }
+ //AP has no 11b station associated.
+ else
+ {
+ //disable protection from 11b station
+ limEnable11gProtection(pMac, false, false, pBeaconParams, psessionEntry);
+ }
+ }
+
+ //following code block is only for HT station.
+ if((psessionEntry->htCapabality) &&
+ (pBeaconStruct->HTInfo.present))
+ {
+
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+ //AP has at least one 11G station associated.
+ if(((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&&
+ (!psessionEntry->beaconParams.llbCoexist))
+ {
+ limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams,psessionEntry);
+
+ }
+
+ //no HT operating mode change ==> no change in protection settings except for MIXED_MODE/Legacy Mode.
+ //in Mixed mode/legacy Mode even if there is no change in HT operating mode, there might be change in 11bCoexist
+ //or 11gCoexist. that is why this check is being done after mixed/legacy mode check.
+ if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )htInfo.opMode )
+ {
+ pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )htInfo.opMode;
+
+ //AP has only HT stations associated and at least one station is HT 20
+ //disable protection from any non-HT devices.
+ //decision for disabling protection from 11b has already been taken above.
+ if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode)
+ {
+ //Disable protection from 11G station.
+ limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry);
+
+ limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry);
+ }
+ //Disable protection from non-HT and HT20 devices.
+ //decision for disabling protection from 11b has already been taken above.
+ else if(eSIR_HT_OP_MODE_PURE == htInfo.opMode)
+ {
+ limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry);
+ limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry);
+
+ }
+ }
+ }
+ }
+
+ //following code block is only for HT station. ( 2.4 GHZ as well as 5 GHZ)
+ if((psessionEntry->htCapabality) &&
+ (pBeaconStruct->HTInfo.present))
+ {
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+ //Check for changes in protection related factors other than HT operating mode.
+ //Check for changes in RIFS mode, nonGFDevicesPresent, lsigTXOPProtectionFullSupport.
+ if ( psessionEntry->beaconParams.fRIFSMode !=
+ ( tANI_U8 ) htInfo.rifsMode )
+ {
+ pBeaconParams->fRIFSMode =
+ psessionEntry->beaconParams.fRIFSMode =
+ ( tANI_U8 ) htInfo.rifsMode;
+ pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED;
+ }
+
+ if ( psessionEntry->beaconParams.llnNonGFCoexist !=
+ htInfo.nonGFDevicesPresent )
+ {
+ pBeaconParams->llnNonGFCoexist =
+ psessionEntry->beaconParams.llnNonGFCoexist =
+ ( tANI_U8 )htInfo.nonGFDevicesPresent;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+
+ if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport !=
+ ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport )
+ {
+ pBeaconParams->fLsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+ ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+
+ // For Station just update the global lim variable, no need to send message to HAL
+ // Station already taking care of HT OPR Mode=01, meaning AP is seeing legacy
+ //stations in overlapping BSS.
+ if ( psessionEntry->beaconParams.gHTObssMode != ( tANI_U8 )htInfo.obssNonHTStaPresent )
+ psessionEntry->beaconParams.gHTObssMode = ( tANI_U8 )htInfo.obssNonHTStaPresent ;
+
+ }
+}
+
+
+/**
+ * limProcessChannelSwitchTimeout()
+ *
+ *FUNCTION:
+ * This function is invoked when Channel Switch Timer expires at
+ * the STA. Now, STA must stop traffic, and then change/disable
+ * primary or secondary channel.
+ *
+ *
+ *NOTE:
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void limProcessChannelSwitchTimeout(tpAniSirGlobal pMac)
+{
+ tpPESession psessionEntry = NULL;
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ tANI_U8 channel = pMac->lim.gLimChannelSwitch.primaryChannel; // This is received and stored from channelSwitch Action frame
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ {
+ PELOGW(limLog(pMac, LOGW, "Channel switch can be done only in STA role, Current Role = %d\n", psessionEntry->limSystemRole);)
+ return;
+ }
+ /*
+ * This potentially can create issues if the function tries to set
+ * channel while device is in power-save, hence putting an extra check
+ * to verify if the device is in power-save or not
+ */
+ if(!limIsSystemInActiveState(pMac))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Device is not in active state, cannot switch channel\n"));)
+ return;
+ }
+
+ // Restore Channel Switch parameters to default
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue = 0;
+
+ /* Channel-switch timeout has occurred. reset the state */
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END;
+
+ /* Check if the AP is switching to a channel that we support.
+ * Else, just don't bother to switch. Indicate HDD to look for a
+ * better AP to associate
+ */
+ if(!limIsChannelValidForChannelSwitch(pMac, channel))
+ {
+ /* We need to restore pre-channelSwitch state on the STA */
+ if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system\n"));
+ return;
+ }
+
+ /* If the channel-list that AP is asking us to switch is invalid,
+ * then we cannot switch the channel. Just disassociate from AP.
+ * We will find a better AP !!!
+ */
+ limTearDownLinkWithAp(pMac,
+ pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId,
+ eSIR_MAC_UNSPEC_FAILURE_REASON);
+ return;
+ }
+ switch(pMac->lim.gLimChannelSwitch.state)
+ {
+ case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
+ PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_ONLY \n"));)
+ limSwitchPrimaryChannel(pMac, pMac->lim.gLimChannelSwitch.primaryChannel,psessionEntry);
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
+ break;
+
+ case eLIM_CHANNEL_SWITCH_SECONDARY_ONLY:
+ PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_SECONDARY_ONLY \n"));)
+ limSwitchPrimarySecondaryChannel(pMac,
+ psessionEntry->currentOperChannel,
+ pMac->lim.gLimChannelSwitch.secondarySubBand);
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
+ break;
+
+ case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
+ PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY\n"));)
+ limSwitchPrimarySecondaryChannel(pMac,
+ pMac->lim.gLimChannelSwitch.primaryChannel,
+ pMac->lim.gLimChannelSwitch.secondarySubBand);
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
+ break;
+
+ case eLIM_CHANNEL_SWITCH_IDLE:
+ default:
+ PELOGE(limLog(pMac, LOGE, FL("incorrect state \n"));)
+ if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system\n"));
+ }
+ return; /* Please note, this is 'return' and not 'break' */
+ }
+#endif
+ }
+
+/**
+ * limUpdateChannelSwitch()
+ *
+ *FUNCTION:
+ * This function is invoked whenever Station receives
+ * either 802.11h channel switch IE or airgo proprietary
+ * channel switch IE.
+ *
+ *NOTE:
+ * @param pMac - Pointer to Global MAC structure
+ * @return tpSirProbeRespBeacon - Pointer to Beacon/Probe Rsp
+ * @param psessionentry
+ */
+void
+limUpdateChannelSwitch(struct sAniSirGlobal *pMac, tpSirProbeRespBeacon pBeacon, tpPESession psessionEntry)
+{
+
+ tANI_U16 beaconPeriod;
+ tANI_U32 val;
+ tChannelSwitchPropIEStruct *pPropChnlSwitch;
+ tDot11fIEChanSwitchAnn *pChnlSwitch;
+
+
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not retrieve Beacon interval\n"));
+ return;
+ }
+ beaconPeriod = (tANI_U16) val;
+
+ /* STA either received proprietary channel switch IE or 802.11h
+ * standard channel switch IE.
+ */
+ if (pBeacon->propIEinfo.propChannelSwitchPresent)
+ {
+ pPropChnlSwitch = &(pBeacon->propIEinfo.channelSwitch);
+
+ /* Add logic to determine which change this is: */
+ /* primary, secondary, both. For now assume both. */
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ pMac->lim.gLimChannelSwitch.primaryChannel = pPropChnlSwitch->primaryChannel;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = (tAniCBSecondaryMode)pPropChnlSwitch->subBand;
+ pMac->lim.gLimChannelSwitch.switchCount = pPropChnlSwitch->channelSwitchCount;
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue =
+ SYS_MS_TO_TICKS(beaconPeriod)* (pPropChnlSwitch->channelSwitchCount);
+ pMac->lim.gLimChannelSwitch.switchMode = pPropChnlSwitch->mode;
+ }
+ else
+ {
+ pChnlSwitch = &(pBeacon->channelSwitchIE);
+ pMac->lim.gLimChannelSwitch.primaryChannel = pChnlSwitch->newChannel;
+ pMac->lim.gLimChannelSwitch.switchCount = pChnlSwitch->switchCount;
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue =
+ SYS_MS_TO_TICKS(beaconPeriod)* (pChnlSwitch->switchCount);
+ pMac->lim.gLimChannelSwitch.switchMode = pChnlSwitch->switchMode;
+
+ /* Only primary channel switch element is present */
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_NONE;
+
+ /* Do not bother to look and operate on extended channel switch element
+ * if our own channel-bonding state is not enabled
+ */
+ if(GET_CB_ADMIN_STATE(pMac->lim.gCbState))
+ {
+ if (pBeacon->extChannelSwitchPresent)
+ {
+ switch(pBeacon->extChannelSwitchIE.secondaryChannelOffset)
+ {
+ case eHT_SECONDARY_CHANNEL_OFFSET_UP:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_UP;
+ break;
+
+ case eHT_SECONDARY_CHANNEL_OFFSET_DOWN:
+ pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_DOWN;
+ break;
+
+ case eHT_SECONDARY_CHANNEL_OFFSET_NONE:
+ default:
+ /* Nothing to be done here as of now!! */
+ break;
+ }
+ }
+ }
+ }
+
+ if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry))
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Could not start Channel Switch\n"));)
+ }
+
+ limLog(pMac, LOGW,
+ FL("primary chl %d, subband %d, count %d (%d ticks) \n"),
+ pMac->lim.gLimChannelSwitch.primaryChannel,
+ pMac->lim.gLimChannelSwitch.secondarySubBand,
+ pMac->lim.gLimChannelSwitch.switchCount,
+ pMac->lim.gLimChannelSwitch.switchTimeoutValue);
+ return;
+}
+
+/**
+ * limCancelDot11hChannelSwitch
+ *
+ *FUNCTION:
+ * This function is called when STA does not send updated channel-swith IE
+ * after indicating channel-switch start. This will cancel the channel-swith
+ * timer which is already running.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return;
+
+ PELOGW(limLog(pMac, LOGW, FL("Received a beacon without channel switch IE\n"));)
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_CHANNEL_SWITCH_TIMER));
+
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed!\n"));)
+ }
+
+ /* We need to restore pre-channelSwitch state on the STA */
+ if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("LIM: Could not restore pre-channelSwitch (11h) state, reseting the system\n"));)
+
+ }
+#endif
+}
+
+/**----------------------------------------------
+\fn limCancelDot11hQuiet
+\brief Cancel the quieting on Station if latest
+ beacon doesn't contain quiet IE in it.
+
+\param pMac
+\return NONE
+-----------------------------------------------*/
+void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return;
+
+ if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_QUIET_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed\n"));)
+ }
+ }
+ else if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, 0, eLIM_QUIET_BSS_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed\n"));)
+ }
+ /**
+ * If the channel switch is already running in silent mode, dont resume the
+ * transmission. Channel switch timer when timeout, transmission will be resumed.
+ */
+ if(!((pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) &&
+ (pMac->lim.gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT)))
+ {
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+ limRestorePreQuietState(pMac);
+ }
+ }
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+#endif
+}
+
+/**
+ * limProcessQuietTimeout
+ *
+ * FUNCTION:
+ * This function is active only on the STA.
+ * Handles SIR_LIM_QUIET_TIMEOUT
+ *
+ * LOGIC:
+ * This timeout can occur under only one circumstance:
+ *
+ * 1) When gLimQuietState = eLIM_QUIET_BEGIN
+ * This indicates that the timeout "interval" has
+ * expired. This is a trigger for the STA to now
+ * shut-off Tx/Rx for the specified gLimQuietDuration
+ * -> The TIMER object gLimQuietBssTimer is
+ * activated
+ * -> With timeout = gLimQuietDuration
+ * -> gLimQuietState is set to eLIM_QUIET_RUNNING
+ *
+ * ASSUMPTIONS:
+ * Using two TIMER objects -
+ * gLimQuietTimer & gLimQuietBssTimer
+ *
+ * NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void limProcessQuietTimeout(tpAniSirGlobal pMac)
+{
+#ifdef GEN6_TODO
+ //fetch the sessionEntry based on the sessionId
+ //priority - MEDIUM
+ tpPESession sessionEntry;
+
+ if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+#endif
+
+ PELOG1(limLog(pMac, LOG1, FL("quietState = %d\n"), pMac->lim.gLimSpecMgmt.quietState);)
+ switch( pMac->lim.gLimSpecMgmt.quietState )
+ {
+ case eLIM_QUIET_BEGIN:
+ // Time to Stop data traffic for quietDuration
+ limDeactivateAndChangeTimer(pMac, eLIM_QUIET_BSS_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_QUIET_BSS_TIMER));
+#ifdef GEN6_TODO
+ /* revisit this piece of code to assign the appropriate sessionId below
+ * priority - HIGH
+ */
+ pMac->lim.limTimers.gLimQuietBssTimer.sessionId = sessionId;
+#endif
+ if( TX_SUCCESS !=
+ tx_timer_activate( &pMac->lim.limTimers.gLimQuietBssTimer ))
+ {
+ limLog( pMac, LOGW,
+ FL("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS...\n"));
+ }
+ else
+ {
+ // Transition to eLIM_QUIET_RUNNING
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_RUNNING;
+
+ /* If we have sta bk scan triggered and trigger bk scan actually started successfully, */
+ /* print message, otherwise, stop data traffic and stay quiet */
+ if( pMac->lim.gLimTriggerBackgroundScanDuringQuietBss &&
+ (eSIR_TRUE == (glimTriggerBackgroundScanDuringQuietBss_Status = limTriggerBackgroundScanDuringQuietBss( pMac ))) )
+ {
+ limLog( pMac, LOG2,
+ FL("Attempting to trigger a background scan...\n"));
+ }
+ else
+ {
+ // Shut-off Tx/Rx for gLimSpecMgmt.quietDuration
+ /* freeze the transmission */
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX);
+
+ limLog( pMac, LOG2,
+ FL("Quiet BSS: STA shutting down for %d ticks\n"),
+ pMac->lim.gLimSpecMgmt.quietDuration );
+ }
+ }
+ break;
+
+ case eLIM_QUIET_RUNNING:
+ case eLIM_QUIET_INIT:
+ case eLIM_QUIET_END:
+ default:
+ //
+ // As of now, nothing to be done
+ //
+ break;
+ }
+}
+
+/**
+ * limProcessQuietBssTimeout
+ *
+ * FUNCTION:
+ * This function is active on the AP and STA.
+ * Handles SIR_LIM_QUIET_BSS_TIMEOUT
+ *
+ * LOGIC:
+ * On the AP -
+ * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is
+ * an indication for the AP to START sending out the
+ * Quiet BSS IE.
+ * If 802.11H is enabled, the Quiet BSS IE is sent as per
+ * the 11H spec
+ * If 802.11H is not enabled, the Quiet BSS IE is sent as
+ * a Proprietary IE. This will be understood by all the
+ * TITAN STA's
+ * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will
+ * initiate the SCH to include the Quiet BSS IE in all
+ * its subsequent Beacons/PR's.
+ * The Quiet BSS IE will be included in all the Beacons
+ * & PR's until the next DTIM period
+ *
+ * On the STA -
+ * When gLimQuietState = eLIM_QUIET_RUNNING
+ * This indicates that the STA was successfully shut-off
+ * for the specified gLimQuietDuration. This is a trigger
+ * for the STA to now resume data traffic.
+ * -> gLimQuietState is set to eLIM_QUIET_INIT
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void limProcessQuietBssTimeout( tpAniSirGlobal pMac )
+{
+ tpPESession sessionEntry;
+
+ if((sessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietBssTimer.sessionId))== NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+ PELOG1(limLog(pMac, LOG1, FL("quietState = %d\n"), pMac->lim.gLimSpecMgmt.quietState);)
+ if (eLIM_AP_ROLE == sessionEntry->limSystemRole)
+ {
+#ifdef ANI_PRODUCT_TYPE_AP
+ if (!pMac->sys.gSysEnableLearnMode)
+ {
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
+ return;
+ }
+
+ if( eLIM_QUIET_INIT == pMac->lim.gLimSpecMgmt.quietState )
+ {
+ //QuietCount = 0 is reserved
+ pMac->lim.gLimSpecMgmt.quietCount = 2;
+ // In ms.
+ pMac->lim.gLimSpecMgmt.quietDuration =
+ pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration;
+ // TU is in multiples of 1024 (2^10) us.
+ pMac->lim.gLimSpecMgmt.quietDuration_TU =
+ SYS_MS_TO_TU(pMac->lim.gLimSpecMgmt.quietDuration);
+ // Transition to eLIM_QUIET_BEGIN
+ limLog( pMac, LOG2, FL("Quiet BSS state = eLIM_QUIET_BEGIN\n"));
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_BEGIN;
+ }
+#endif
+ }
+ else
+ {
+ // eLIM_STA_ROLE
+ switch( pMac->lim.gLimSpecMgmt.quietState )
+ {
+ case eLIM_QUIET_RUNNING:
+ // Transition to eLIM_QUIET_INIT
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ if( !pMac->lim.gLimTriggerBackgroundScanDuringQuietBss || (glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE) )
+ {
+ // Resume data traffic only if channel switch is not running in silent mode.
+ if (!((pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) &&
+ (pMac->lim.gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT)))
+ {
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+ limRestorePreQuietState(pMac);
+ }
+
+ /* Reset status flag */
+ if(glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE)
+ glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE;
+
+ limLog( pMac, LOG2,
+ FL("Quiet BSS: Resuming traffic...\n"));
+ }
+ else
+ {
+ //
+ // Nothing specific to be done in this case
+ // A background scan that was triggered during
+ // SIR_LIM_QUIET_TIMEOUT will complete on its own
+ //
+ limLog( pMac, LOG2,
+ FL("Background scan should be complete now...\n"));
+ }
+ break;
+
+ case eLIM_QUIET_INIT:
+ case eLIM_QUIET_BEGIN:
+ case eLIM_QUIET_END:
+ PELOG2(limLog(pMac, LOG2, FL("Quiet state not in RUNNING\n"));)
+ /* If the quiet period has ended, then resume the frame transmission */
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+ limRestorePreQuietState(pMac);
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ break;
+
+ default:
+ //
+ // As of now, nothing to be done
+ //
+ break;
+ }
+ }
+}
+#ifdef WLAN_SOFTAP_FEATURE
+/**
+ * limProcessWPSOverlapTimeout
+ *
+ * FUNCTION: This function call limWPSPBCTimeout() to clean WPS PBC probe request entries
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+#if 0
+void limProcessWPSOverlapTimeout(tpAniSirGlobal pMac)
+{
+
+ tpPESession psessionEntry;
+ tANI_U32 sessionId;
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("tx_timer_activate failed\n"));
+ }
+
+ sessionId = pMac->lim.limTimers.gLimWPSOverlapTimerObj.sessionId;
+
+ PELOGE(limLog(pMac, LOGE, FL("WPS overlap timeout, sessionId=%d\n"), sessionId);)
+
+ if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL)
+ {
+ PELOGE(limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));)
+ return;
+ }
+
+ limWPSPBCTimeout(pMac, psessionEntry);
+}
+#endif
+#endif
+
+/**
+ * limUpdateQuietIEFromBeacon
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ * When the Quiet BSS IE is encountered when parsing for
+ * Beacons/PR's, this function is called.
+ * Based on the configuration of the Quiet Interval -
+ * a) A TIMER (gLimQuietTimer) is started for the
+ * specified interval
+ * b) Upon expiry of the TIMER interval, the STA will
+ * shut-off Tx/Rx
+ * c) The STA will then start another TIMER (in this
+ * case, gLimQuietBssTimer TIMER object), with the
+ * timeout duration set to the value specified in the
+ * Quiet BSS IE
+ *
+ * 1) To setup the Quiet BSS "interval". In this case,
+ * this TIMER indicates that the STA has to shut-off its
+ * Tx/Rx AFTER the specified interval
+ * Set gLimQuietState = eLIM_QUIET_BEGIN
+ *
+ * 2) To setup the Quiet BSS "duration". After the said
+ * specified "interval", the STA has to shut-off Tx/Rx
+ * for this duration
+ * Set gLimQuietState = eLIM_QUIET_RUNNING
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pQuietIE - Pointer to tDot11fIEQuiet
+ *
+ * @return None
+ */
+void limUpdateQuietIEFromBeacon( struct sAniSirGlobal *pMac,
+ tDot11fIEQuiet *pQuietIE, tpPESession psessionEntry )
+{
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ tANI_U16 beaconPeriod;
+ tANI_U32 val;
+
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return;
+
+ PELOG1(limLog(pMac, LOG1, FL("Quiet state = %d, Quiet Count = %d\n"),
+ pMac->lim.gLimSpecMgmt.quietState, pQuietIE->count);)
+ if (!pMac->lim.gLim11hEnable)
+ return;
+ // The (Titan) AP is requesting this (Titan) STA to
+ // honor this Quiet IE REQ and shut-off Tx/Rx. If we're
+ // receiving this a second time around (because the AP
+ // could be down-counting the Quiet BSS Count), the STA
+ // will have to reset the timeout interval accordingly
+ //
+
+ if (pQuietIE->count == 0)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Ignoring quiet count == 0->reserved\n"));)
+ return;
+ }
+
+ if( eSIR_SUCCESS !=
+ wlan_cfgGetInt( pMac, WNI_CFG_BEACON_INTERVAL, &val ))
+ beaconPeriod = (tANI_U16) WNI_CFG_BEACON_INTERVAL_APDEF;
+ else
+ beaconPeriod = (tANI_U16) val;
+
+ /* (qd * 2^10)/1000 */
+ pMac->lim.gLimSpecMgmt.quietDuration_TU = pQuietIE->duration;
+ // The STA needs to shut-off Tx/Rx "for" this interval (in milliSeconds)
+ /* Need to convert from TU to system TICKS */
+ pMac->lim.gLimSpecMgmt.quietDuration = SYS_MS_TO_TICKS(
+ SYS_TU_TO_MS(pMac->lim.gLimSpecMgmt.quietDuration_TU));
+
+ if (pMac->lim.gLimSpecMgmt.quietDuration_TU == 0)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Zero duration in quiet IE\n"));)
+ return;
+ }
+
+ // The STA needs to shut-off Tx/Rx "after" this interval
+ pMac->lim.gLimSpecMgmt.quietTimeoutValue =
+ (beaconPeriod * pQuietIE->count) + pQuietIE->offset;
+
+ limLog( pMac, LOG2,
+ FL( "STA shut-off will begin in %d milliseconds & last for %d ticks\n"),
+ pMac->lim.gLimSpecMgmt.quietTimeoutValue,
+ pMac->lim.gLimSpecMgmt.quietDuration );
+
+ /* Disable, Stop background scan if enabled and running */
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+
+ /* Stop heart-beat timer to stop heartbeat disassociation */
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+
+ if(pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE ||
+ pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE)
+ {
+ PELOGW(limLog(pMac, LOGW, FL("Posting finish scan as we are in scan state\n"));)
+ /* Stop ongoing scanning if any */
+ if (GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ {
+ //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);
+ }
+ else
+ {
+ limRestorePreQuietState(pMac);
+ }
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Not in scan state, start quiet timer\n"));)
+ /** We are safe to switch channel at this point */
+ limStartQuietTimer(pMac, psessionEntry->peSessionId);
+ }
+
+ // Transition to eLIM_QUIET_BEGIN
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_BEGIN;
+#endif
+}
+
+
+/**----------------------------------------------
+\fn limStartQuietTimer
+\brief Starts the quiet timer.
+
+\param pMac
+\return NONE
+-----------------------------------------------*/
+void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId)
+{
+ tpPESession psessionEntry;
+ psessionEntry = peFindSessionBySessionId(pMac , sessionId);
+
+ if(psessionEntry == NULL) {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return;
+ // First, de-activate Timer, if its already active
+ limCancelDot11hQuiet(pMac, psessionEntry);
+
+ limDeactivateAndChangeTimer(pMac, eLIM_QUIET_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_QUIET_TIMER));
+
+ pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId;
+ if( TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer))
+ {
+ limLog( pMac, LOGE,
+ FL("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!\n"));
+ limRestorePreQuietState(pMac);
+
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ return;
+ }
+#endif
+}
+
+#ifdef ANI_PRODUCT_TYPE_AP
+
+/**
+ * computeChannelSwitchCount
+ *
+ * FUNCTION:
+ * Function used by limProcessSmeSwitchChlReq()
+ * to compute channel switch count.
+ *
+ * LOGIC:
+ * Channel Switch Count is the number of TBTT until AP switches
+ * to a new channel. The value of Channel Switch Count is computed
+ * in a way, such that channel switch will always take place after
+ * a DTIM. By doing so, it is guaranteed that station in power save
+ * mode can receive the message and switch to new channel accordingly.
+ * AP can also announce the channel switch several dtims ahead of time.
+ * by setting the dtimFactor value greater than 1.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param dtimFactor
+ * @return channel switch count
+ */
+tANI_U32 computeChannelSwitchCount(tpAniSirGlobal pMac, tANI_U32 dtimFactor)
+{
+ tANI_U32 dtimPeriod;
+ tANI_U32 dtimCount;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, &dtimPeriod) != eSIR_SUCCESS)
+ PELOGE(limLog(pMac, LOGE, FL("wlan_cfgGetInt failed for WNI_CFG_DTIM_PERIOD \n"));)
+
+ dtimCount = pMac->pmm.gPmmTim.dtimCount;
+
+ if (dtimFactor <= 1)
+ return (dtimCount + 1);
+ else
+ return (((dtimFactor -1)*dtimPeriod) + 1 + dtimCount);
+}
+#endif
+
+/** ------------------------------------------------------------------------ **/
+/**
+ * keep track of the number of ANI peers associated in the BSS
+ * For the first and last ANI peer, we have to update EDCA params as needed
+ *
+ * When the first ANI peer joins the BSS, we notify SCH
+ * When the last ANI peer leaves the BSS, we notfiy SCH
+ */
+void
+limUtilCountStaAdd(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tpPESession psessionEntry)
+{
+
+ if ((! pSta) || (! pSta->valid) || (! pSta->aniPeer) || (pSta->fAniCount))
+ return;
+
+ pSta->fAniCount = 1;
+
+ if (pMac->lim.gLimNumOfAniSTAs++ != 0)
+ return;
+
+ // get here only if this is the first ANI peer in the BSS
+ schEdcaProfileUpdate(pMac, psessionEntry);
+}
+
+void
+limUtilCountStaDel(
+ tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tpPESession psessionEntry)
+{
+
+ if ((pSta == NULL) || (pSta->aniPeer == eHAL_CLEAR) || (! pSta->fAniCount))
+ return;
+
+ /* Only if sta is invalid and the validInDummyState bit is set to 1,
+ * then go ahead and update the count and profiles. This ensures
+ * that the "number of ani station" count is properly incremented/decremented.
+ */
+ if (pSta->valid == 1)
+ return;
+
+ pSta->fAniCount = 0;
+
+ if (pMac->lim.gLimNumOfAniSTAs <= 0)
+ {
+ limLog(pMac, LOGE, FL("CountStaDel: ignoring Delete Req when AniPeer count is %d\n"),
+ pMac->lim.gLimNumOfAniSTAs);
+ return;
+ }
+
+ pMac->lim.gLimNumOfAniSTAs--;
+
+ if (pMac->lim.gLimNumOfAniSTAs != 0)
+ return;
+
+ // get here only if this is the last ANI peer in the BSS
+ schEdcaProfileUpdate(pMac, psessionEntry);
+}
+
+/** -------------------------------------------------------------
+\fn limGetHtCbAdminState
+\brief provides CB Admin state
+\param tpAniSirGlobal pMac
+\param tDot11fIEHTCaps htCaps,
+\param tANI_U8 *titanHtCaps
+\return none
+ -------------------------------------------------------------*/
+void limGetHtCbAdminState( tpAniSirGlobal pMac,
+ tDot11fIEHTCaps htCaps,
+ tANI_U8 *titanHtCaps )
+{
+ // Extract secondary channel info wrt Channel Bonding
+ if(htCaps.supportedChannelWidthSet)
+ SME_SET_CB_ADMIN_STATE( *titanHtCaps, eHAL_SET );
+ else
+ SME_SET_CB_ADMIN_STATE( *titanHtCaps, eHAL_CLEAR);
+
+
+ // And the final TITAN HT capabilities bitmap is...
+ limLog( pMac, LOG2,
+ FL("TITAN HT capabilities in BSS Description = %1d\n"),
+ *titanHtCaps);
+}
+/** -------------------------------------------------------------
+\fn limGetHtCbOpState
+\brief provides CB operational state
+\param tpAniSirGlobal pMac
+\param tDot11fIEHTInfo htInfo,
+\param tANI_U8 *titanHtCaps
+\return none
+ -------------------------------------------------------------*/
+void limGetHtCbOpState( tpAniSirGlobal pMac,
+ tDot11fIEHTInfo htInfo,
+ tANI_U8 *titanHtCaps )
+{
+ // Extract secondary channel info wrt Channel Bonding
+ if(htInfo.secondaryChannelOffset)
+ {
+ if(PHY_DOUBLE_CHANNEL_LOW_PRIMARY == htInfo.secondaryChannelOffset)
+ SME_SET_CB_OPER_STATE( *titanHtCaps,
+ eANI_CB_SECONDARY_UP );
+ else if(PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == htInfo.secondaryChannelOffset)
+ SME_SET_CB_OPER_STATE( *titanHtCaps,
+ eANI_CB_SECONDARY_DOWN );
+ }
+
+ // And the final TITAN HT capabilities bitmap is...
+ limLog( pMac, LOG2,
+ FL("TITAN HT capabilities in BSS Description = %1d\n"),
+ *titanHtCaps);
+}
+
+/**
+ * limSwitchChannelCback()
+ *
+ *FUNCTION:
+ * This is the callback function registered while requesting to switch channel
+ * after AP indicates a channel switch for spectrum management (11h).
+ *
+ *NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param status Status of channel switch request
+ * @param data User data
+ * @param psessionEntry Session information
+ * @return NONE
+ */
+void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg = {0};
+ tSirSmeSwitchChannelInd *pSirSmeSwitchChInd;
+
+ PELOG1(limLog(pMac, LOG1,FL("Sending message %s with reasonCode %s\n"),
+ limMsgStr(msgType), limResultCodeStr(resultCode));)
+
+ psessionEntry->currentOperChannel = psessionEntry->currentReqChannel;
+
+ /* We need to restore pre-channelSwitch state on the STA */
+ if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system\n"));
+ return;
+ }
+
+ mmhMsg.type = eWNI_SME_SWITCH_CHL_REQ;
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pSirSmeSwitchChInd, sizeof(tSirSmeSwitchChannelInd)))
+ {
+ limLog(pMac, LOGP, FL("Failed to allocate buffer for buffer descriptor\n"));
+ return;
+ }
+
+ pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_REQ;
+ pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd);
+ pSirSmeSwitchChInd->newChannelId = pMac->lim.gLimChannelSwitch.primaryChannel;
+ pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId;
+ //BSS ID
+ palCopyMemory( pMac->hHdd, pSirSmeSwitchChInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+ mmhMsg.bodyptr = pSirSmeSwitchChInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+ SysProcessMmhMsg(pMac, &mmhMsg);
+#else
+ if(halMmhPostMsgApi(pMac, &mmhMsg, ePROT) != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, (void *)msg2Hdd);
+ limLog(pMac, LOGP, FL("Message posting to HAL failed\n"));
+ }
+#endif
+}
+
+/**
+ * limSwitchPrimaryChannel()
+ *
+ *FUNCTION:
+ * This function changes the current operating channel
+ * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL.
+ *
+ *NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param newChannel new chnannel ID
+ * @return NONE
+ */
+void limSwitchPrimaryChannel(tpAniSirGlobal pMac, tANI_U8 newChannel,tpPESession psessionEntry)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ tANI_U32 localPwrConstraint;
+#endif
+
+ PELOG3(limLog(pMac, LOG3, FL("limSwitchPrimaryChannel: old chnl %d --> new chnl %d \n"),
+ psessionEntry->currentOperChannel, newChannel);)
+ psessionEntry->currentReqChannel = newChannel;
+ psessionEntry->limRFBand = limGetRFBand(newChannel);
+
+ psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION;
+
+ pMac->lim.gpchangeChannelCallback = limSwitchChannelCback;
+ pMac->lim.gpchangeChannelData = NULL;
+
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_NONE,
+ psessionEntry->maxTxPower, psessionEntry->peSessionId);
+#else
+ if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS)
+ {
+ limLog( pMac, LOGP, FL( "Unable to read Local Power Constraint from cfg\n" ));
+ return;
+ }
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_NONE,
+ (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId);
+#endif
+ return;
+}
+
+/**
+ * limSwitchPrimarySecondaryChannel()
+ *
+ *FUNCTION:
+ * This function changes the primary and secondary channel.
+ * If 11h is enabled and user provides a "new channel ID"
+ * that is different from the current operating channel,
+ * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL,
+ * assign notify LIM of such change.
+ *
+ *NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param newChannel New chnannel ID (or current channel ID)
+ * @param subband CB secondary info:
+ * - eANI_CB_SECONDARY_NONE
+ * - eANI_CB_SECONDARY_UP
+ * - eANI_CB_SECONDARY_DOWN
+ * @return NONE
+ */
+void limSwitchPrimarySecondaryChannel(tpAniSirGlobal pMac, tANI_U8 newChannel, tAniCBSecondaryMode subband)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ tANI_U32 localPwrConstraint;
+#endif
+
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+#if !defined WLAN_FEATURE_VOWIFI
+ if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
+ limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg\n" ));
+ return;
+ }
+#endif
+
+ switch(subband)
+ {
+ case eANI_CB_SECONDARY_NONE:
+ PELOGW(limLog(pMac, LOGW, FL("Disable CB SECONDARY\n"));)
+ /* If CB was on, turn it off, otherwise, do nothing */
+ if(GET_CB_OPER_STATE(pMac->lim.gCbState))
+ {
+ /* Turn off CB in HW and SW. SW and HW cbstate must match! Otherwise, will hit ASSERT case */
+ SET_CB_OPER_STATE(pMac->lim.gCbState, eHAL_CLEAR);
+ /* Clean up station entry if we're not STA */
+ }
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_NONE) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_NONE, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+#else
+ //Send Message to HAL to update the channel
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_NONE, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId);
+#endif
+ break;
+
+ case eANI_CB_SECONDARY_UP:
+ PELOGW(limLog(pMac, LOGW, FL("Switch CB SECONDARY to UP.\n"));)
+ SET_CB_SEC_CHANNEL(pMac->lim.gCbState, eHAL_SET);
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_HIGHER) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+
+ /* If CB was off, turn it on, otherwise, do nothing */
+ if(!GET_CB_OPER_STATE(pMac->lim.gCbState))
+ {
+ /* Turn on CB in HW and SW. SW and HW cbstate must match! Otherwise, will hit ASSERT case */
+ SET_CB_OPER_STATE(pMac->lim.gCbState, eHAL_SET);
+ }
+ //Send Message to HAL to update the channel
+ //enums for secondary channel offset for Titan and 11n are different
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_UP, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+#else
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_UP, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId);
+#endif
+ break;
+
+ case eANI_CB_SECONDARY_DOWN:
+ PELOGW(limLog(pMac, LOGW, FL("Switch CB SECONDARY to LOWER.\n"));)
+ SET_CB_SEC_CHANNEL(pMac->lim.gCbState, eHAL_CLEAR);
+ if (cfgSetInt(pMac, WNI_CFG_CB_SECONDARY_CHANNEL_STATE, WNI_CFG_CB_SECONDARY_CHANNEL_STATE_LOWER) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("cfgSetInt WNI_CFG_CB_SECONDARY_CHANNEL_STATE failed \n"));
+ /* If CB was off, turn it on, otherwise, do nothing */
+ if(!GET_CB_OPER_STATE(pMac->lim.gCbState))
+ {
+ /* Turn on CB in HW and SW. SW and HW cbstate must match! Otherwise, will hit ASSERT case */
+ SET_CB_OPER_STATE(pMac->lim.gCbState, eHAL_SET);
+ /* Update station entry if we're not STA */
+ }
+ //Send Message to HAL to update the channel
+ //enums for secondary channel offset for Titan and 11n are different
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_NONE, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+#else
+ limSendSwitchChnlParams(pMac, newChannel, eHT_SECONDARY_CHANNEL_OFFSET_DOWN, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId);
+#endif
+ break;
+
+ case eANI_DONOT_USE_SECONDARY_MODE:
+ break;
+ }
+
+
+ // We should only be changing primary and secondary channels on the fly
+ // if this is 11h enabled.
+ if (
+#if 0
+ pMac->lim.gLim11hEnable &&
+#endif
+ psessionEntry->currentOperChannel != newChannel)
+ {
+ limLog(pMac, LOGW,
+ FL("switch old chnl %d --> new chnl %d \n"),
+ psessionEntry->currentOperChannel, newChannel);
+
+ #if 0
+
+ if (cfgSetInt(pMac, WNI_CFG_CURRENT_CHANNEL, newChannel) != eSIR_SUCCESS)
+ limLog(pMac, LOGP, FL("set CURRENT_CHANNEL at CFG fail.\n"));
+ #endif // TO SUPPORT BT-AMP
+
+ psessionEntry->currentOperChannel = newChannel;
+ }
+
+ return;
+}
+
+
+/**
+ * limActiveScanAllowed()
+ *
+ *FUNCTION:
+ * Checks if active scans are permitted on the given channel
+ *
+ *LOGIC:
+ * The config variable SCAN_CONTROL_LIST contains pairs of (channelNum, activeScanAllowed)
+ * Need to check if the channelNum matches, then depending on the corresponding
+ * scan flag, return true (for activeScanAllowed==1) or false (otherwise).
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param channelNum channel number
+ * @return None
+ */
+
+tANI_U8 limActiveScanAllowed(
+ tpAniSirGlobal pMac,
+ tANI_U8 channelNum)
+{
+ tANI_U32 i;
+ tANI_U8 channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
+ tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+ if (wlan_cfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len)
+ != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Unable to get scan control list\n"));)
+ return false;
+ }
+
+ if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN)
+ {
+ limLog(pMac, LOGE, FL("Invalid scan control list length:%d\n"),
+ len);
+ return false;
+ }
+
+ for (i=0; (i+1) < len; i+=2)
+ {
+ if (channelPair[i] == channelNum)
+ return ((channelPair[i+1] == eSIR_ACTIVE_SCAN) ? true : false);
+ }
+ return false;
+}
+
+/**
+ * limTriggerBackgroundScanDuringQuietBss()
+ *
+ *FUNCTION:
+ * This function is applicable to the STA only.
+ * This function is called by limProcessQuietTimeout(),
+ * when it is time to honor the Quiet BSS IE from the AP.
+ *
+ *LOGIC:
+ * If 11H is enabled:
+ * We cannot trigger a background scan. The STA needs to
+ * shut-off Tx/Rx.
+ * If 11 is not enabled:
+ * Determine if the next channel that we are going to
+ * scan is NOT the same channel (or not) on which the
+ * Quiet BSS was requested.
+ * If yes, then we cannot trigger a background scan on
+ * this channel. Return with a false.
+ * If no, then trigger a background scan. Return with
+ * a true.
+ *
+ *ASSUMPTIONS:
+ *
+ *NOTE:
+ * This API is redundant if the existing API,
+ * limTriggerBackgroundScan(), were to return a valid
+ * response instead of returning void.
+ * If possible, try to revisit this API
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return eSIR_TRUE, if a background scan was attempted
+ * eSIR_FALSE, if not
+ */
+tAniBool limTriggerBackgroundScanDuringQuietBss( tpAniSirGlobal pMac )
+{
+ tAniBool bScanTriggered = eSIR_FALSE;
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+
+
+
+ //TBD-RAJESH HOW TO GET sessionEntry?????
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];
+
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return bScanTriggered;
+
+ if( !pMac->lim.gLim11hEnable )
+ {
+ tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN];
+ tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN;
+
+ // Determine the next scan channel
+
+ // Get background scan channel list from CFG
+ if( eSIR_SUCCESS == wlan_cfgGetStr( pMac,
+ WNI_CFG_BG_SCAN_CHANNEL_LIST,
+ (tANI_U8 *) bgScanChannelList,
+ (tANI_U32 *) &len ))
+ {
+ // Ensure that we do not go off scanning on the same
+ // channel on which the Quiet BSS was requested
+ if( psessionEntry->currentOperChannel!=
+ bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId] )
+ {
+ // For now, try and attempt a background scan. It will
+ // be ideal if this API actually returns a success or
+ // failure instead of having a void return type
+ limTriggerBackgroundScan( pMac );
+
+ bScanTriggered = eSIR_TRUE;
+ }
+ else
+ {
+ limLog( pMac, LOGW,
+ FL("The next SCAN channel is the current operating channel on which a Quiet BSS is requested.! A background scan will not be triggered during this Quiet BSS period...\n"));
+ }
+ }
+ else
+ {
+ limLog( pMac, LOGW,
+ FL("Unable to retrieve WNI_CFG_VALID_CHANNEL_LIST from CFG! A background scan will not be triggered during this Quiet BSS period...\n"));
+ }
+ }
+#endif
+ return bScanTriggered;
+}
+
+
+/**
+ * limGetHTCapability()
+ *
+ *FUNCTION:
+ * A utility function that returns the "current HT capability state" for the HT
+ * capability of interest (as requested in the API)
+ *
+ *LOGIC:
+ * This routine will return with the "current" setting of a requested HT
+ * capability. This state info could be retrieved from -
+ * a) CFG (for static entries)
+ * b) Run time info
+ * - Dynamic state maintained by LIM
+ * - Configured at radio init time by SME
+ *
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param htCap The HT capability being queried
+ * @return tANI_U8 The current state of the requested HT capability is returned in a
+ * tANI_U8 variable
+ */
+
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_U8 limGetHTCapability( tpAniSirGlobal pMac,
+ tANI_U32 htCap, tpPESession psessionEntry)
+#else
+tANI_U8 limGetHTCapability( tpAniSirGlobal pMac,
+ tANI_U32 htCap )
+#endif
+{
+tANI_U8 retVal = 0;
+tANI_U8 *ptr;
+tANI_U32 cfgValue;
+tSirMacHTCapabilityInfo macHTCapabilityInfo = {0};
+tSirMacExtendedHTCapabilityInfo macExtHTCapabilityInfo = {0};
+tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = {0};
+tSirMacASCapabilityInfo macASCapabilityInfo = {0};
+
+ //
+ // Determine which CFG to read from. Not ALL of the HT
+ // related CFG's need to be read each time this API is
+ // accessed
+ //
+ if( htCap >= eHT_ANTENNA_SELECTION &&
+ htCap < eHT_SI_GRANULARITY )
+ {
+ // Get Antenna Seletion HT Capabilities
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_AS_CAP, &cfgValue ))
+ cfgValue = 0;
+ ptr = (tANI_U8 *) &macASCapabilityInfo;
+ *((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff);
+ }
+ else
+ {
+ if( htCap >= eHT_TX_BEAMFORMING &&
+ htCap < eHT_ANTENNA_SELECTION )
+ {
+ // Get Transmit Beam Forming HT Capabilities
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TX_BF_CAP, &cfgValue ))
+ cfgValue = 0;
+ ptr = (tANI_U8 *) &macTxBFCapabilityInfo;
+ *((tANI_U32 *)ptr) = (tANI_U32) (cfgValue);
+ }
+ else
+ {
+ if( htCap >= eHT_PCO &&
+ htCap < eHT_TX_BEAMFORMING )
+ {
+ // Get Extended HT Capabilities
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_EXT_HT_CAP_INFO, &cfgValue ))
+ cfgValue = 0;
+ ptr = (tANI_U8 *) &macExtHTCapabilityInfo;
+ *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff);
+ }
+ else
+ {
+ if( htCap < eHT_MAX_RX_AMPDU_FACTOR )
+ {
+ // Get HT Capabilities
+ if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_HT_CAP_INFO, &cfgValue ))
+ cfgValue = 0;
+ ptr = (tANI_U8 *) &macHTCapabilityInfo;
+ // CR 265282 MDM SoftAP 2.4PL: SoftAP boot up crash in 2.4 PL builds while same WLAN SU is working on 2.1 PL
+ *ptr++ = cfgValue & 0xff;
+ *ptr = (cfgValue >> 8) & 0xff;
+ }
+ }
+ }
+ }
+
+ switch( htCap )
+ {
+ case eHT_LSIG_TXOP_PROTECTION:
+ retVal = pMac->lim.gHTLsigTXOPProtection;
+ break;
+
+ case eHT_STBC_CONTROL_FRAME:
+ retVal = (tANI_U8) macHTCapabilityInfo.stbcControlFrame;
+ break;
+
+ case eHT_PSMP:
+ retVal = pMac->lim.gHTPSMPSupport;
+ break;
+
+ case eHT_DSSS_CCK_MODE_40MHZ:
+ retVal = pMac->lim.gHTDsssCckRate40MHzSupport;
+ break;
+
+ case eHT_MAX_AMSDU_LENGTH:
+ retVal = (tANI_U8) macHTCapabilityInfo.maximalAMSDUsize;
+ break;
+
+ case eHT_DELAYED_BA:
+ retVal = (tANI_U8) macHTCapabilityInfo.delayedBA;
+ break;
+
+ case eHT_RX_STBC:
+ retVal = (tANI_U8) macHTCapabilityInfo.rxSTBC;
+ break;
+
+ case eHT_TX_STBC:
+ retVal = (tANI_U8) macHTCapabilityInfo.txSTBC;
+ break;
+
+ case eHT_SHORT_GI_40MHZ:
+ retVal = (tANI_U8) macHTCapabilityInfo.shortGI40MHz;
+ break;
+
+ case eHT_SHORT_GI_20MHZ:
+ retVal = (tANI_U8) macHTCapabilityInfo.shortGI20MHz;
+ break;
+
+ case eHT_GREENFIELD:
+ retVal = (tANI_U8) macHTCapabilityInfo.greenField;
+ break;
+
+ case eHT_MIMO_POWER_SAVE:
+ retVal = (tANI_U8) pMac->lim.gHTMIMOPSState;
+ break;
+
+ case eHT_SUPPORTED_CHANNEL_WIDTH_SET:
+ retVal = (tANI_U8) macHTCapabilityInfo.supportedChannelWidthSet;
+ break;
+
+ case eHT_ADVANCED_CODING:
+ retVal = (tANI_U8) macHTCapabilityInfo.advCodingCap;
+ break;
+
+ case eHT_MAX_RX_AMPDU_FACTOR:
+ retVal = pMac->lim.gHTMaxRxAMpduFactor;
+ break;
+
+ case eHT_MPDU_DENSITY:
+ retVal = pMac->lim.gHTAMpduDensity;
+ break;
+
+ case eHT_PCO:
+ retVal = (tANI_U8) macExtHTCapabilityInfo.pco;
+ break;
+
+ case eHT_TRANSITION_TIME:
+ retVal = (tANI_U8) macExtHTCapabilityInfo.transitionTime;
+ break;
+
+ case eHT_MCS_FEEDBACK:
+ retVal = (tANI_U8) macExtHTCapabilityInfo.mcsFeedback;
+ break;
+
+ case eHT_TX_BEAMFORMING:
+ retVal = (tANI_U8) macTxBFCapabilityInfo.txBF;
+ break;
+
+ case eHT_ANTENNA_SELECTION:
+ retVal = (tANI_U8) macASCapabilityInfo.antennaSelection;
+ break;
+
+ case eHT_SI_GRANULARITY:
+ retVal = pMac->lim.gHTServiceIntervalGranularity;
+ break;
+
+ case eHT_CONTROLLED_ACCESS:
+ retVal = pMac->lim.gHTControlledAccessOnly;
+ break;
+
+ case eHT_RIFS_MODE:
+ retVal = psessionEntry->beaconParams.fRIFSMode;
+ break;
+
+ case eHT_RECOMMENDED_TX_WIDTH_SET:
+ retVal = pMac->lim.gHTRecommendedTxWidthSet;
+ break;
+
+ case eHT_EXTENSION_CHANNEL_OFFSET:
+ retVal = pMac->lim.gHTSecondaryChannelOffset;
+ break;
+
+ case eHT_OP_MODE:
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE )
+ retVal = psessionEntry->htOperMode;
+ else
+#endif
+ retVal = pMac->lim.gHTOperMode;
+ break;
+
+ case eHT_BASIC_STBC_MCS:
+ retVal = pMac->lim.gHTSTBCBasicMCS;
+ break;
+
+ case eHT_DUAL_CTS_PROTECTION:
+ retVal = pMac->lim.gHTDualCTSProtection;
+ break;
+
+ case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT:
+ retVal = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
+ break;
+
+ case eHT_PCO_ACTIVE:
+ retVal = pMac->lim.gHTPCOActive;
+ break;
+
+ case eHT_PCO_PHASE:
+ retVal = pMac->lim.gHTPCOPhase;
+ break;
+
+ default:
+ break;
+ }
+
+ return retVal;
+}
+
+#if 0
+void limSetBssid(tpAniSirGlobal pMac, tANI_U8 *bssId)
+{
+ palCopyMemory( pMac->hHdd, pMac->lim.gLimBssid, bssId, sizeof(tSirMacAddr));
+ return;
+}
+
+void limGetBssid(tpAniSirGlobal pMac, tANI_U8 *bssId)
+{
+ palCopyMemory( pMac->hHdd, bssId, pMac->lim.gLimBssid, sizeof(tSirMacAddr));
+ return;
+}
+
+#endif
+void limGetMyMacAddr(tpAniSirGlobal pMac, tANI_U8 *mac)
+{
+ palCopyMemory( pMac->hHdd, mac, pMac->lim.gLimMyMacAddr, sizeof(tSirMacAddr));
+ return;
+}
+
+
+
+
+/** -------------------------------------------------------------
+\fn limEnable11aProtection
+\brief based on config setting enables\disables 11a protection.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE && !pMac->lim.cfgProtection.overlapFromlla)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11a is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+ //normal protection config check
+ if(!pMac->lim.cfgProtection.fromlla)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from 11a is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+
+ if (enable)
+ {
+ //If we are AP and HT capable, we need to set the HT OP mode
+ //appropriately.
+ if(((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))&&
+ (true == psessionEntry->htCapabality))
+ {
+ if(overlap)
+ {
+ pMac->lim.gLimOverlap11aParams.protectionEnabled = true;
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode))
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ else
+ {
+ psessionEntry->gLim11aParams.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+
+ }
+ }
+ }
+
+ //This part is common for staiton as well.
+ if(false == psessionEntry->beaconParams.llaCoexist)
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => protection from 11A Enabled\n"));)
+ pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ }
+ }
+ else if (true == psessionEntry->beaconParams.llaCoexist)
+ {
+ //for AP role.
+ //we need to take care of HT OP mode change if needed.
+ //We need to take care of Overlap cases.
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ pMac->lim.gLimOverlap11aParams.protectionEnabled = false;
+
+ //We need to take care of HT OP mode iff we are HT AP.
+ if(psessionEntry->htCapabality)
+ {
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(pMac->lim.gLimOverlap11aParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled))
+
+ {
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode)
+ {
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ if(psessionEntry->gLimHt20Params.protectionEnabled)
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11A stations.
+ psessionEntry->gLim11aParams.protectionEnabled = false;
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ //Check if any other non-HT protection enabled.
+ //Right now we are in HT OP Mixed mode.
+ //Change HT op mode appropriately.
+
+ //Change HT OP mode to 01 if any overlap protection enabled
+ if(pMac->lim.gLimOverlap11aParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled)
+
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ else if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ if(!pMac->lim.gLimOverlap11aParams.protectionEnabled &&
+ !psessionEntry->gLim11aParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled\n"));)
+ pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ }
+ }
+ //for station role
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled\n"));)
+ pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limEnable11gProtection
+\brief based on config setting enables\disables 11g protection.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE )) && !pMac->lim.cfgProtection.overlapFromllb)
+ {
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("overlap protection from 11b is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+ //normal protection config check
+#ifdef WLAN_SOFTAP_FEATURE
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->cfgProtection.fromllb)
+ {
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ if(!pMac->lim.cfgProtection.fromllb)
+ {
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (enable)
+ {
+ //If we are AP and HT capable, we need to set the HT OP mode
+ //appropriately.
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ if(overlap)
+ {
+ psessionEntry->gLimOlbcParams.protectionEnabled = true;
+ PELOGE(limLog(pMac, LOGE, FL("protection from olbc is enabled\n"));)
+ if(true == psessionEntry->htCapabality)
+ {
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode))
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS
+ // This fixes issue of OBSS bit not set after 11b, 11g station leaves
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ //Not processing OBSS bit from other APs, as we are already taking care
+ //of Protection from overlapping BSS based on erp IE or useProtection bit
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry);
+ }
+ }
+ else
+ {
+ psessionEntry->gLim11bParams.protectionEnabled = true;
+ PELOGE(limLog(pMac, LOGE, FL("protection from 11b is enabled\n"));)
+ if(true == psessionEntry->htCapabality)
+ {
+ if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ }else if ((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) &&
+ (true == psessionEntry->htCapabality))
+#else
+ if(((eLIM_AP_ROLE == psessionEntry->limSystemRole)|| (eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)) &&
+ (true == psessionEntry->htCapabality))
+#endif
+ {
+ if(overlap)
+ {
+ psessionEntry->gLimOlbcParams.protectionEnabled = true;
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode))
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS
+ // This fixes issue of OBSS bit not set after 11b, 11g station leaves
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ //Not processing OBSS bit from other APs, as we are already taking care
+ //of Protection from overlapping BSS based on erp IE or useProtection bit
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry);
+ }
+ else
+ {
+ psessionEntry->gLim11bParams.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+
+ //This part is common for staiton as well.
+ if(false == psessionEntry->beaconParams.llbCoexist)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("=> 11G Protection Enabled\n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ else if (true == psessionEntry->beaconParams.llbCoexist)
+ {
+ //for AP role.
+ //we need to take care of HT OP mode change if needed.
+ //We need to take care of Overlap cases.
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ psessionEntry->gLimOlbcParams.protectionEnabled = false;
+
+ //We need to take care of HT OP mode if we are HT AP.
+ if(psessionEntry->htCapabality)
+ {
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(psessionEntry->gLimOverlap11gParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled))
+ {
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode)
+ {
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ if(psessionEntry->gLimHt20Params.protectionEnabled){
+ //Commenting out beacuse of CR 258588 WFA cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ else
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11B stations.
+ psessionEntry->gLim11bParams.protectionEnabled = false;
+ PELOGE(limLog(pMac, LOGE, FL("===> 11B Protection Disabled\n"));)
+ //Check if any other non-HT protection enabled.
+ if(!psessionEntry->gLim11gParams.protectionEnabled)
+ {
+ //Right now we are in HT OP Mixed mode.
+ //Change HT op mode appropriately.
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ //Change HT OP mode to 01 if any overlap protection enabled
+ if(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ psessionEntry->gLimOverlap11gParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled)
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled\n"));)
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ else if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ //Commenting because of CR 258588 WFA cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled\n"));)
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ if(!psessionEntry->gLimOlbcParams.protectionEnabled &&
+ !psessionEntry->gLim11bParams.protectionEnabled)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled\n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)
+#else
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole)||((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)))
+#endif
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ psessionEntry->gLimOlbcParams.protectionEnabled = false;
+
+ //We need to take care of HT OP mode iff we are HT AP.
+ if(psessionEntry->htCapabality)
+ {
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(pMac->lim.gLimOverlap11gParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled))
+
+ {
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode)
+ {
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ if(psessionEntry->gLimHt20Params.protectionEnabled)
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11B stations.
+ psessionEntry->gLim11bParams.protectionEnabled = false;
+ //Check if any other non-HT protection enabled.
+ if(!psessionEntry->gLim11gParams.protectionEnabled)
+ {
+ //Right now we are in HT OP Mixed mode.
+ //Change HT op mode appropriately.
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ //Change HT OP mode to 01 if any overlap protection enabled
+ if(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ pMac->lim.gLimOverlap11gParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled)
+
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ else if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ if(!psessionEntry->gLimOlbcParams.protectionEnabled &&
+ !psessionEntry->gLim11bParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled\n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ //for station role
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled\n"));)
+ pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limEnableHtProtectionFrom11g
+\brief based on cofig enables\disables protection from 11g.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // protection from 11g is only for HT stations.
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && (!psessionEntry->cfgProtection.overlapFromllg))
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled\n")););
+ return eSIR_SUCCESS;
+ }else if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) && (!pMac->lim.cfgProtection.overlapFromllg))
+#else
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE ) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && (!pMac->lim.cfgProtection.overlapFromllg))
+#endif
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled\n")););
+ return eSIR_SUCCESS;
+ }
+ }
+ else
+ {
+ //normal protection config check
+#ifdef WLAN_SOFTAP_FEATURE
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->cfgProtection.fromllg){
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE )
+#endif
+ {
+ if(!pMac->lim.cfgProtection.fromllg)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+ if (enable)
+ {
+ //If we are AP and HT capable, we need to set the HT OP mode
+ //appropriately.
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ if(overlap)
+ {
+ psessionEntry->gLimOverlap11gParams.protectionEnabled = true;
+ //11g exists in overlap BSS.
+ //need not to change the operating mode to overlap_legacy
+ //if higher or same protection operating mode is enabled right now.
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode))
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true , overlap, pBeaconParams, psessionEntry);
+ }
+ else
+ {
+ //11g is associated to an AP operating in 11n mode.
+ //Change the HT operating mode to 'mixed mode'.
+ psessionEntry->gLim11gParams.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true , overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)
+#else
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))
+#endif
+ {
+ if(overlap)
+ {
+ pMac->lim.gLimOverlap11gParams.protectionEnabled = true;
+ //11g exists in overlap BSS.
+ //need not to change the operating mode to overlap_legacy
+ //if higher or same protection operating mode is enabled right now.
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode))
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ else
+ {
+ //11g is associated to an AP operating in 11n mode.
+ //Change the HT operating mode to 'mixed mode'.
+ psessionEntry->gLim11gParams.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, true , overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+
+ //This part is common for staiton as well.
+ if(false == psessionEntry->beaconParams.llgCoexist)
+ {
+ pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED;
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ else if (true == psessionEntry->gLimOverlap11gParams.protectionEnabled)
+ {
+ // As operating mode changed after G station assoc some way to update beacon
+ // This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled
+ //pMac->sch.schObject.fBeaconChanged = 1;
+ pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED;
+ }
+#endif
+ }
+ else if (true == psessionEntry->beaconParams.llgCoexist)
+ {
+ //for AP role.
+ //we need to take care of HT OP mode change if needed.
+ //We need to take care of Overlap cases.
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole)
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ if (psessionEntry->gLim11gParams.numSta == 0)
+ psessionEntry->gLimOverlap11gParams.protectionEnabled = false;
+
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled))
+ {
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode)
+ {
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ if(psessionEntry->gLimHt20Params.protectionEnabled){
+ //Commenting because of CR 258588 WFA cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ else
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11G stations.
+ psessionEntry->gLim11gParams.protectionEnabled = false;
+ //Check if any other non-HT protection enabled.
+ if(!psessionEntry->gLim11bParams.protectionEnabled)
+ {
+
+ //Right now we are in HT OP Mixed mode.
+ //Change HT op mode appropriately.
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ //Change HT OP mode to 01 if any overlap protection enabled
+ if(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ psessionEntry->gLimOverlap11gParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled)
+
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ else if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ //Commenting because of CR 258588 WFA cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ if(!psessionEntry->gLimOverlap11gParams.protectionEnabled &&
+ !psessionEntry->gLim11gParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled\n"));)
+ pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED;
+ }
+ }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)
+#else
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))
+#endif
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ pMac->lim.gLimOverlap11gParams.protectionEnabled = false;
+
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled))
+ {
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode)
+ {
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ if(psessionEntry->gLimHt20Params.protectionEnabled)
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11G stations.
+ psessionEntry->gLim11gParams.protectionEnabled = false;
+ //Check if any other non-HT protection enabled.
+ if(!psessionEntry->gLim11bParams.protectionEnabled)
+ {
+
+ //Right now we are in HT OP Mixed mode.
+ //Change HT op mode appropriately.
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+
+ //Change HT OP mode to 01 if any overlap protection enabled
+ if(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ pMac->lim.gLimOverlap11gParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled)
+
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ else if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+ if(!pMac->lim.gLimOverlap11gParams.protectionEnabled &&
+ !psessionEntry->gLim11gParams.protectionEnabled)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled\n"));)
+ pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED;
+ }
+ }
+ //for station role
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled\n"));)
+ pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection.
+//This check will be done at the caller.
+
+/** -------------------------------------------------------------
+\fn limEnableHtObssProtection
+\brief based on cofig enables\disables obss protection.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHtOBSSProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+
+
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // this protection is only for HT stations.
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+ //overlapping protection configuration check.
+ #if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && !pMac->lim.cfgProtection.overlapOBSS)
+ { // ToDo Update this field
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("overlap protection from Obss is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ #endif
+ }
+ else
+ {
+ //normal protection config check
+#ifdef WLAN_SOFTAP_FEATURE
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && !psessionEntry->cfgProtection.obss)
+ { //ToDo Update this field
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ if(!pMac->lim.cfgProtection.obss)
+ { //ToDo Update this field
+ // protection disabled.
+ PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if (eLIM_AP_ROLE == psessionEntry->limSystemRole){
+ if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) )
+ {
+ PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled\n"));)
+ psessionEntry->beaconParams.gHTObssMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE <todo>
+
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled\n"));)
+ psessionEntry->beaconParams.gHTObssMode = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED;
+
+ }
+//CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS
+ if (!enable && !overlap)
+ {
+ psessionEntry->gLimOverlap11gParams.protectionEnabled = false;
+ }
+ } else
+#endif
+ {
+ if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) )
+ {
+ PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled\n"));)
+ psessionEntry->beaconParams.gHTObssMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE <todo>
+
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode))
+ {
+
+ PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled\n"));)
+ psessionEntry->beaconParams.gHTObssMode = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED;
+
+ }
+ }
+ return eSIR_SUCCESS;
+}
+/** -------------------------------------------------------------
+\fn limEnableHT20Protection
+\brief based on cofig enables\disables protection from Ht20.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // this protection is only for HT stations.
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE )||(psessionEntry->limSystemRoleS == eLIM_BT_AMP_AP_ROLE ))&& !pMac->lim.cfgProtection.overlapHt20)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("overlap protection from HT 20 is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+ //normal protection config check
+#ifdef WLAN_SOFTAP_FEATURE
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->cfgProtection.ht20)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE )
+#endif
+ {
+ if(!pMac->lim.cfgProtection.ht20)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (enable)
+ {
+ //If we are AP and HT capable, we need to set the HT OP mode
+ //appropriately.
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole){
+ if(overlap)
+ {
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled = true;
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode))
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ else
+ {
+ psessionEntry->gLimHt20Params.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_PURE == psessionEntry->htOperMode)
+ {
+ //Commenting because of CR 258588 WFA cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)
+#else
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))
+#endif
+ {
+ if(overlap)
+ {
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled = true;
+ if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode))
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ else
+ {
+ psessionEntry->gLimHt20Params.protectionEnabled = true;
+ if(eSIR_HT_OP_MODE_PURE == pMac->lim.gHTOperMode)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ }
+
+ //This part is common for staiton as well.
+ if(false == psessionEntry->beaconParams.ht20Coexist)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("=> Prtection from HT20 Enabled\n"));)
+ pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+ }
+ else if (true == psessionEntry->beaconParams.ht20Coexist)
+ {
+ //for AP role.
+ //we need to take care of HT OP mode change if needed.
+ //We need to take care of Overlap cases.
+#ifdef WLAN_SOFTAP_FEATURE
+ if(eLIM_AP_ROLE == psessionEntry->limSystemRole){
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled = false;
+
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ psessionEntry->gLimOverlap11gParams.protectionEnabled ||
+ psessionEntry->gLimOverlapHt20Params.protectionEnabled ||
+ psessionEntry->gLimOverlapNonGfParams.protectionEnabled))
+ {
+
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode)
+ {
+ if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ //Commented beacuse of CR 258588 for WFA Cert
+ //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11G stations.
+ psessionEntry->gLimHt20Params.protectionEnabled = false;
+
+ //Change HT op mode appropriately.
+ if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == psessionEntry->htOperMode)
+ {
+ psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled\n"));)
+ pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED;
+ }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole)
+#else
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))
+#endif
+ {
+ if(overlap)
+ {
+ //Overlap Legacy protection disabled.
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled = false;
+
+ // no HT op mode change if any of the overlap protection enabled.
+ if(!(psessionEntry->gLimOlbcParams.protectionEnabled ||
+ pMac->lim.gLimOverlap11gParams.protectionEnabled ||
+ pMac->lim.gLimOverlapHt20Params.protectionEnabled ||
+ pMac->lim.gLimOverlapNonGfParams.protectionEnabled))
+ {
+
+ //Check if there is a need to change HT OP mode.
+ if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode)
+ {
+ if(psessionEntry->gLimHt20Params.protectionEnabled)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ else
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ //Disable protection from 11G stations.
+ psessionEntry->gLimHt20Params.protectionEnabled = false;
+
+ //Change HT op mode appropriately.
+ if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pMac->lim.gHTOperMode)
+ {
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry);
+ }
+ }
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled\n"));)
+ pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+ //for station role
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT20 Disabled\n"));)
+ pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limEnableHTNonGfProtection
+\brief based on cofig enables\disables protection from NonGf.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // this protection is only for HT stations.
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && !pMac->lim.cfgProtection.overlapNonGf)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("overlap protection from NonGf is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ //normal protection config check
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->cfgProtection.nonGf)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ //normal protection config check
+ if(!pMac->lim.cfgProtection.nonGf)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled\n"));)
+ pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled\n"));)
+ pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ }else
+#endif
+ {
+ if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled\n"));)
+ pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled\n"));)
+ pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limEnableHTLsigTxopProtection
+\brief based on cofig enables\disables LsigTxop protection.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // this protection is only for HT stations.
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && !pMac->lim.cfgProtection.overlapLsigTxop)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" overlap protection from LsigTxop not supported is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ //normal protection config check
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) &&
+ !psessionEntry->cfgProtection.lsigTxop)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE)
+#endif
+ {
+ //normal protection config check
+ if(!pMac->lim.cfgProtection.lsigTxop)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled\n"));)
+ pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled\n"));)
+ pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ }else
+#endif
+ {
+ if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled\n"));)
+ pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled\n"));)
+ pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection.
+//This check will be done at the caller.
+/** -------------------------------------------------------------
+\fn limEnableHtRifsProtection
+\brief based on cofig enables\disables Rifs protection.
+\param tANI_U8 enable : 1=> enable protection, 0=> disable protection.
+\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context.
+\param tpUpdateBeaconParams pBeaconParams
+\return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable,
+ tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
+{
+ if(!psessionEntry->htCapabality)
+ return eSIR_SUCCESS; // this protection is only for HT stations.
+
+
+ //overlapping protection configuration check.
+ if(overlap)
+ {
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if(((psessionEntry->limSystemRole == eLIM_AP_ROLE) ||(psessionEntry == eLIM_BT_AMP_AP_ROLE))&& !pMac->lim.cfgProtection.overlapRifs)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" overlap protection from Rifs is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+#endif
+ }
+ else
+ {
+#ifdef WLAN_SOFTAP_FEATURE
+ //normal protection config check
+ if((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
+ !psessionEntry->cfgProtection.rifs)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled\n"));)
+ return eSIR_SUCCESS;
+ }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE )
+#endif
+ {
+ //normal protection config check
+ if(!pMac->lim.cfgProtection.rifs)
+ {
+ // protection disabled.
+ PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled\n"));)
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+#ifdef WLAN_SOFTAP_FEATURE
+ if(psessionEntry->limSystemRole == eLIM_AP_ROLE){
+ // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS
+ if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled\n"));)
+ pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED;
+ }
+ // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS
+ else if (enable && (true == psessionEntry->beaconParams.fRIFSMode))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled\n"));)
+ pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED;
+ }
+ }else
+#endif
+ {
+ // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS
+ if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode))
+ {
+ PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled\n"));)
+ pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED;
+ }
+ // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS
+ else if (enable && (true == psessionEntry->beaconParams.fRIFSMode))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled\n"));)
+ pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+// ---------------------------------------------------------------------
+/**
+ * limEnableShortPreamble
+ *
+ * FUNCTION:
+ * Enable/Disable short preamble
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable Flag to enable/disable short preamble
+ * @return None
+ */
+
+tSirRetStatus
+limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
+{
+ tANI_U32 val;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS)
+ {
+ /* Could not get short preamble enabled flag from CFG. Log error. */
+ limLog(pMac, LOGP, FL("could not retrieve short preamble flag\n"));
+ return eSIR_FAILURE;
+ }
+
+ if (!val)
+ return eSIR_SUCCESS;
+
+ if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("could not retrieve 11G short preamble switching enabled flag\n"));
+ return eSIR_FAILURE;
+ }
+
+ if (!val) // 11G short preamble switching is disabled.
+ return eSIR_SUCCESS;
+
+ if ( psessionEntry->limSystemRole == eLIM_AP_ROLE )
+ {
+ if (enable && (psessionEntry->beaconParams.fShortPreamble == 0))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Enabled\n"));)
+ psessionEntry->beaconParams.fShortPreamble = true;
+ pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED;
+ }
+ else if (!enable && (psessionEntry->beaconParams.fShortPreamble == 1))
+ {
+ PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Disabled\n"));)
+ psessionEntry->beaconParams.fShortPreamble = false;
+ pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble;
+ pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+ }
+
+/**
+ * limTxComplete
+ *
+ * Function:
+ * This is LIM's very own "TX MGMT frame complete" completion routine.
+ *
+ * Logic:
+ * LIM wants to send a MGMT frame (broadcast or unicast)
+ * LIM allocates memory using palPktAlloc( ..., **pData, **pPacket )
+ * LIM transmits the MGMT frame using the API:
+ * halTxFrame( ... pPacket, ..., (void *) limTxComplete, pData )
+ * HDD, via halTxFrame/DXE, "transfers" the packet over to BMU
+ * HDD, if it determines that a TX completion routine (in this case
+ * limTxComplete) has been provided, will invoke this callback
+ * LIM will try to free the TX MGMT packet that was earlier allocated, in order
+ * to send this MGMT frame, using the PAL API palPktFree( ... pData, pPacket )
+ *
+ * Assumptions:
+ * Presently, this is ONLY being used for MGMT frames/packets
+ * TODO:
+ * Would it do good for LIM to have some sort of "signature" validation to
+ * ensure that the pData argument passed in was a buffer that was actually
+ * allocated by LIM and/or is not corrupted?
+ *
+ * Note: FIXME and TODO
+ * Looks like palPktFree() is interested in pPacket. But, when this completion
+ * routine is called, only pData is made available to LIM!!
+ *
+ * @param void A pointer to pData. Shouldn't it be pPacket?!
+ *
+ * @return none
+ */
+void limTxComplete( tHalHandle hHal, void *pData )
+{
+ tpAniSirGlobal pMac;
+ pMac = (tpAniSirGlobal)hHal;
+
+#ifdef FIXME_PRIMA
+ /* the trace logic needs to be fixed for Prima. Refer to CR 306075 */
+#ifdef TRACE_RECORD
+ {
+ tpSirMacMgmtHdr mHdr;
+ v_U8_t *pRxBd;
+ vos_pkt_t *pVosPkt;
+ VOS_STATUS vosStatus;
+
+
+
+ pVosPkt = (vos_pkt_t *)pData;
+ vosStatus = vos_pkt_peek_data( pVosPkt, 0, (v_PVOID_t *)&pRxBd, WLANHAL_RX_BD_HEADER_SIZE);
+
+ if(VOS_IS_STATUS_SUCCESS(vosStatus))
+ {
+ mHdr = WDA_GET_RX_MAC_HEADER(pRxBd);
+ MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, 0, mHdr->fc.subType);)
+
+ }
+ }
+#endif
+#endif
+
+ palPktFree( pMac->hHdd,
+ HAL_TXRX_FRM_802_11_MGMT,
+ (void *) NULL, // this is ignored and will likely be removed from this API
+ (void *) pData ); // lim passed in pPacket in the pData pointer that is given in this completion routine
+}
+
+/**
+ * \brief This function updates lim global structure, if CB parameters in the BSS
+ * have changed, and sends an indication to HAL also with the
+ * updated HT Parameters.
+ * This function does not detect the change in the primary channel, that is done as part
+ * of channel Swtich IE processing.
+ * If STA is configured with '20Mhz only' mode, then this function does not do anything
+ * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz'
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or
+ * Probe Response
+ *
+ * \param bssIdx BSS Index of the Bss to which Station is associated.
+ *
+ *
+ */
+
+void limUpdateStaRunTimeHTSwitchChnlParams( tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pHTInfo,
+ tANI_U8 bssIdx,
+ tpPESession psessionEntry)
+{
+ tSirMacHTSecondaryChannelOffset secondaryChnlOffset = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
+#if !defined WLAN_FEATURE_VOWIFI
+ tANI_U32 localPwrConstraint;
+#endif
+
+ //If self capability is set to '20Mhz only', then do not change the CB mode.
+#ifdef WLAN_SOFTAP_FEATURE
+ if( !limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry ))
+#else
+ if( !limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET ))
+#endif
+ return;
+
+#if !defined WLAN_FEATURE_VOWIFI
+ if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) {
+ limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg\n" ));
+ return;
+ }
+#endif
+
+ if ( pMac->lim.gHTSecondaryChannelOffset != ( tANI_U8 ) pHTInfo->secondaryChannelOffset ||
+ pMac->lim.gHTRecommendedTxWidthSet != ( tANI_U8 ) pHTInfo->recommendedTxWidthSet )
+ {
+ pMac->lim.gHTSecondaryChannelOffset = ( tSirMacHTSecondaryChannelOffset ) pHTInfo->secondaryChannelOffset;
+ pMac->lim.gHTRecommendedTxWidthSet = ( tANI_U8 ) pHTInfo->recommendedTxWidthSet;
+ //Also update the Proprietary(Titan) CB mode settings, as this setting is used during
+ //background scanning to set the original channel and CB mode as part of finish scan.
+ setupCBState( pMac, limGetAniCBState(pMac->lim.gHTSecondaryChannelOffset));
+
+ // If the Channel Width is 20Mhz, set the channel offset to
+ // NONE. If the Channel Width is 40Mhz, set the channel offset
+ // to what ever is present in beacon.
+ if ( eHT_CHANNEL_WIDTH_40MHZ == pMac->lim.gHTRecommendedTxWidthSet )
+ secondaryChnlOffset = (tSirMacHTSecondaryChannelOffset)pHTInfo->secondaryChannelOffset;
+
+ // Notify HAL
+ limLog( pMac, LOGW, FL( "Channel Information in HT IE change"
+ "d; sending notification to HAL.\n" ) );
+ limLog( pMac, LOGW, FL( "Primary Channel: %d, Secondary Chan"
+ "nel Offset: %d, Channel Width: %d\n" ),
+ pHTInfo->primaryChannel, secondaryChnlOffset,
+ pMac->lim.gHTRecommendedTxWidthSet );
+
+#if defined WLAN_FEATURE_VOWIFI
+ limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel,
+ secondaryChnlOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId);
+#else
+ limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel,
+ secondaryChnlOffset, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId);
+#endif
+
+ //In case of IBSS, if STA should update HT Info IE in its beacons.
+ if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole)
+ {
+ schSetFixedBeaconFields(pMac,psessionEntry);
+ }
+
+ }
+} // End limUpdateStaRunTimeHTParams.
+
+/**
+ * \brief This function updates the lim global structure, if any of the
+ * HT Capabilities have changed.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pHTCapability Pointer to HT Capability Information Element
+ * obtained from a Beacon or Probe Response
+ *
+ *
+ *
+ */
+
+void limUpdateStaRunTimeHTCapability( tpAniSirGlobal pMac,
+ tDot11fIEHTCaps *pHTCaps )
+{
+
+ if ( pMac->lim.gHTLsigTXOPProtection != ( tANI_U8 ) pHTCaps->lsigTXOPProtection )
+ {
+ pMac->lim.gHTLsigTXOPProtection = ( tANI_U8 ) pHTCaps->lsigTXOPProtection;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTAMpduDensity != ( tANI_U8 ) pHTCaps->mpduDensity )
+ {
+ pMac->lim.gHTAMpduDensity = ( tANI_U8 ) pHTCaps->mpduDensity;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTMaxRxAMpduFactor != ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor )
+ {
+ pMac->lim.gHTMaxRxAMpduFactor = ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor;
+ // Send change notification to HAL
+ }
+
+
+} // End limUpdateStaRunTimeHTCapability.
+
+/**
+ * \brief This function updates lim global structure, if any of the HT
+ * Info Parameters have changed.
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or
+ * Probe Response
+ *
+ *
+ */
+
+void limUpdateStaRunTimeHTInfo( tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pHTInfo , tpPESession psessionEntry)
+{
+ if ( pMac->lim.gHTSecondaryChannelOffset != ( tANI_U8)pHTInfo->secondaryChannelOffset)
+ {
+ pMac->lim.gHTSecondaryChannelOffset = ( tSirMacHTSecondaryChannelOffset )pHTInfo->secondaryChannelOffset;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTRecommendedTxWidthSet != ( tANI_U8 )pHTInfo->recommendedTxWidthSet )
+ {
+ pMac->lim.gHTRecommendedTxWidthSet = ( tANI_U8 )pHTInfo->recommendedTxWidthSet;
+ // Send change notification to HAL
+ }
+
+ if ( psessionEntry->beaconParams.fRIFSMode != ( tANI_U8 )pHTInfo->rifsMode )
+ {
+ psessionEntry->beaconParams.fRIFSMode = ( tANI_U8 )pHTInfo->rifsMode;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTServiceIntervalGranularity != ( tANI_U8 )pHTInfo->serviceIntervalGranularity )
+ {
+ pMac->lim.gHTServiceIntervalGranularity = ( tANI_U8 )pHTInfo->serviceIntervalGranularity;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )pHTInfo->opMode )
+ {
+ pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )pHTInfo->opMode;
+ // Send change notification to HAL
+ }
+
+ if ( psessionEntry->beaconParams.llnNonGFCoexist != pHTInfo->nonGFDevicesPresent )
+ {
+ psessionEntry->beaconParams.llnNonGFCoexist = ( tANI_U8 )pHTInfo->nonGFDevicesPresent;
+ }
+
+ if ( pMac->lim.gHTSTBCBasicMCS != ( tANI_U8 )pHTInfo->basicSTBCMCS )
+ {
+ pMac->lim.gHTSTBCBasicMCS = ( tANI_U8 )pHTInfo->basicSTBCMCS;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTDualCTSProtection != ( tANI_U8 )pHTInfo->dualCTSProtection )
+ {
+ pMac->lim.gHTDualCTSProtection = ( tANI_U8 )pHTInfo->dualCTSProtection;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTSecondaryBeacon != ( tANI_U8 )pHTInfo->secondaryBeacon )
+ {
+ pMac->lim.gHTSecondaryBeacon = ( tANI_U8 )pHTInfo->secondaryBeacon;
+ // Send change notification to HAL
+ }
+
+ if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport != ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport )
+ {
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTPCOActive != ( tANI_U8 )pHTInfo->pcoActive )
+ {
+ pMac->lim.gHTPCOActive = ( tANI_U8 )pHTInfo->pcoActive;
+ // Send change notification to HAL
+ }
+
+ if ( pMac->lim.gHTPCOPhase != ( tANI_U8 )pHTInfo->pcoPhase )
+ {
+ pMac->lim.gHTPCOPhase = ( tANI_U8 )pHTInfo->pcoPhase;
+ // Send change notification to HAL
+ }
+
+} // End limUpdateStaRunTimeHTInfo.
+
+
+/** -------------------------------------------------------------
+\fn limProcessHalIndMessages
+\brief callback function for HAL indication
+\param tpAniSirGlobal pMac
+\param tANI_U32 mesgId
+\param void *mesgParam
+\return tSirRetStatu - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 msgId, void *msgParam )
+{
+ //its PE's responsibility to free msgparam when its done extracting the message parameters.
+ tSirMsgQ msg;
+
+ switch(msgId)
+ {
+ case SIR_LIM_DEL_TS_IND:
+ case SIR_LIM_ADD_BA_IND:
+ case SIR_LIM_DEL_BA_ALL_IND:
+ case SIR_LIM_DELETE_STA_CONTEXT_IND:
+ case SIR_LIM_BEACON_GEN_IND:
+ msg.type = (tANI_U16) msgId;
+ msg.bodyptr = msgParam;
+ msg.bodyval = 0;
+ break;
+
+ default:
+ palFreeMemory(pMac->hHdd, msgParam);
+ limLog(pMac, LOGP, FL("invalid message id = %d received\n"), msgId);
+ return eSIR_FAILURE;
+ }
+
+ if (limPostMsgApi(pMac, &msg) != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, msgParam);
+ limLog(pMac, LOGP, FL("limPostMsgApi failed for msgid = %d"), msg.type);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limValidateDeltsReq
+\brief Validates DelTs req originated by SME or by HAL and also sends halMsg_DelTs to HAL
+\param tpAniSirGlobal pMac
+\param tpSirDeltsReq pDeltsReq
+\param tSirMacAddr peerMacAddr
+\return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry)
+{
+ tpDphHashNode pSta;
+ tANI_U8 tsStatus;
+ tSirMacTSInfo *tsinfo;
+ tANI_U32 i;
+ tANI_U8 tspecIdx;
+ /* if sta
+ * - verify assoc state
+ * - del tspec locally
+ * if ap,
+ * - verify sta is in assoc state
+ * - del sta tspec locally
+ */
+ if(pDeltsReq == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Delete TS request pointer is NULL\n"));)
+ return eSIR_FAILURE;
+ }
+
+ if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+ tANI_U32 val;
+
+ // station always talks to the AP
+ pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+
+ val = sizeof(tSirMacAddr);
+ #if 0
+ if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMacAddr, &val) != eSIR_SUCCESS)
+ {
+ /// Could not get BSSID from CFG. Log error.
+ limLog(pMac, LOGP, FL("could not retrieve BSSID\n"));
+ return eSIR_FAILURE;
+ }
+ #endif// TO SUPPORT BT-AMP
+ sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
+
+ }
+ else
+ {
+ tANI_U16 assocId;
+ tANI_U8 *macaddr = (tANI_U8 *) peerMacAddr;
+
+ assocId = pDeltsReq->aid;
+ if (assocId != 0)
+ pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+ else
+ pSta = dphLookupHashEntry(pMac, pDeltsReq->macAddr, &assocId, &psessionEntry->dph.dphHashTable);
+
+ if (pSta != NULL)
+ // TBD: check sta assoc state as well
+ for (i =0; i < sizeof(tSirMacAddr); i++)
+ macaddr[i] = pSta->staAddr[i];
+ }
+
+ if (pSta == NULL)
+ {
+ PELOGE(limLog(pMac, LOGE, "Cannot find station context for delts req\n");)
+ return eSIR_FAILURE;
+ }
+
+ if ((! pSta->valid) ||
+ (pSta->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE))
+ {
+ PELOGE(limLog(pMac, LOGE, "Invalid Sta (or state) for DelTsReq\n");)
+ return eSIR_FAILURE;
+ }
+
+ pDeltsReq->req.wsmTspecPresent = 0;
+ pDeltsReq->req.wmeTspecPresent = 0;
+ pDeltsReq->req.lleTspecPresent = 0;
+
+ if ((pSta->wsmEnabled) &&
+ (pDeltsReq->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA))
+ pDeltsReq->req.wsmTspecPresent = 1;
+ else if (pSta->wmeEnabled)
+ pDeltsReq->req.wmeTspecPresent = 1;
+ else if (pSta->lleEnabled)
+ pDeltsReq->req.lleTspecPresent = 1;
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL("DELTS_REQ ignore - qos is disabled\n"));)
+ return eSIR_FAILURE;
+ }
+
+ tsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo
+ : &pDeltsReq->req.tsinfo;
+ PELOG1(limLog(pMac, LOG1,
+ FL("received DELTS_REQ message (wmeTspecPresent = %d, lleTspecPresent = %d, wsmTspecPresent = %d, tsid %d, up %d, direction = %d)\n"),
+ pDeltsReq->req.wmeTspecPresent, pDeltsReq->req.lleTspecPresent, pDeltsReq->req.wsmTspecPresent,
+ tsinfo->traffic.tsid, tsinfo->traffic.userPrio, tsinfo->traffic.direction);)
+
+ // if no Access Control, ignore the request
+#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
+ if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA))
+ if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))&&
+ (! psessionEntry->gLimEdcaParamsBC[upToAc(tsinfo->traffic.userPrio)].aci.acm))
+ || (((psessionEntry->limSystemRole != eLIM_AP_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) &&
+ (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm)))
+ {
+ limLog(pMac, LOGW, FL("DelTs with acecssPolicy = %d and UP %d , AC = %d has no AC - ignoring request\n"),
+ tsinfo->traffic.accessPolicy, tsinfo->traffic.userPrio, upToAc(tsinfo->traffic.userPrio));
+ return eSIR_FAILURE;
+ }
+#endif
+
+ if (limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx)
+ != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, "ERROR DELTS request for sta assocId %d (tsid %d, up %d)\n",
+ pSta->assocId, tsinfo->traffic.tsid, tsinfo->traffic.userPrio);)
+ return eSIR_FAILURE;
+ }
+ else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
+ (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))
+ {
+ //edca only now.
+ }
+ else
+ {
+ if((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) &&
+ psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm)
+ {
+ //send message to HAL to delete TS
+ if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, pSta->staIndex, tspecIdx, pDeltsReq->req))
+ {
+ limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request\n"),
+ tsinfo->traffic.userPrio);
+ return eSIR_FAILURE;
+ }
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+\fn limRegisterHalIndCallBack
+\brief registers callback function to HAL for any indication.
+\param tpAniSirGlobal pMac
+\return none.
+ -------------------------------------------------------------*/
+void
+limRegisterHalIndCallBack(tpAniSirGlobal pMac)
+{
+ tSirMsgQ msg;
+ tpHalIndCB pHalCB;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pHalCB, sizeof(tHalIndCB)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory() failed\n"));
+ return;
+ }
+
+ pHalCB->pHalIndCB = limProcessHalIndMessages;
+
+ msg.type = WDA_REGISTER_PE_CALLBACK;
+ msg.bodyptr = pHalCB;
+ msg.bodyval = 0;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msg.type));
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ palFreeMemory(pMac->hHdd, pHalCB);
+ limLog(pMac, LOGP, FL("wdaPostCtrlMsg() failed\n"));
+ }
+
+ return;
+}
+
+
+/** -------------------------------------------------------------
+\fn limProcessAddBaInd
+
+\brief handles the BA activity check timeout indication coming from HAL.
+ Validates the request, posts request for sending addBaReq message for every candidate in the list.
+\param tpAniSirGlobal pMac
+\param tSirMsgQ limMsg
+\return None
+-------------------------------------------------------------*/
+void
+limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tANI_U8 i;
+ tANI_U8 tid;
+ tANI_U16 assocId;
+ tpDphHashNode pSta;
+ tpAddBaCandidate pBaCandidate;
+ tANI_U32 baCandidateCnt;
+ tpBaActivityInd pBaActivityInd;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+
+
+ if(limMsg->bodyptr == NULL)
+ return;
+
+ pBaActivityInd = (tpBaActivityInd)limMsg->bodyptr;
+ baCandidateCnt = pBaActivityInd->baCandidateCnt;
+
+ if((psessionEntry = peFindSessionByBssid(pMac,pBaActivityInd->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given BSSId\n"));
+ palFreeMemory(pMac->hHdd, limMsg->bodyptr);
+ return;
+ }
+
+ //if we are not HT capable we don't need to handle BA timeout indication from HAL.
+ if( (baCandidateCnt > pMac->lim.maxStation) || !psessionEntry->htCapabality )
+ {
+ palFreeMemory(pMac->hHdd, limMsg->bodyptr);
+ return;
+ }
+
+ //delete the complete dialoguetoken linked list
+ limDeleteDialogueTokenList(pMac);
+ pBaCandidate = (tpAddBaCandidate) (((tANI_U8*)pBaActivityInd) + sizeof(tBaActivityInd));
+
+ for(i=0; i<baCandidateCnt; i++, pBaCandidate++)
+ {
+ pSta = dphLookupHashEntry(pMac, pBaCandidate->staAddr, &assocId, &psessionEntry->dph.dphHashTable);
+ if( (NULL == pSta) || (!pSta->valid))
+ continue;
+
+ for (tid=0; tid<STACFG_MAX_TC; tid++)
+ {
+ if( (eBA_DISABLE == pSta->tcCfg[tid].fUseBATx) &&
+ (pBaCandidate->baInfo[tid].fBaEnable))
+ {
+ PELOG2(limLog(pMac, LOG2, FL("BA setup for staId = %d, TID: %d, SSN:%d.\n"),
+ pSta->staIndex, tid, pBaCandidate->baInfo[tid].startingSeqNum);)
+ limPostMlmAddBAReq(pMac, pSta, tid, pBaCandidate->baInfo[tid].startingSeqNum,psessionEntry);
+ }
+ }
+ }
+ palFreeMemory(pMac->hHdd, limMsg->bodyptr);
+ return;
+}
+
+
+/** -------------------------------------------------------------
+\fn limDelAllBASessions
+\brief Deletes all the exisitng BA sessions.
+\ Note : This API is provided for Mac OSx only. The reason for this is that Mac OSx may not
+\ restart after CFG update.
+\param tpAniSirGlobal pMac
+\return None
+-------------------------------------------------------------*/
+
+void
+limDelAllBASessions(tpAniSirGlobal pMac)
+{
+ tANI_U32 i;
+ tANI_U8 tid;
+ tpDphHashNode pSta;
+
+ tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
+ for(tid = 0; tid < STACFG_MAX_TC; tid++)
+ {
+ if((eLIM_AP_ROLE == psessionEntry->limSystemRole) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole))
+ {
+ for(i = 0; i < pMac->lim.maxStation; i++)
+ {
+ pSta = psessionEntry->dph.dphHashTable.pDphNodeArray + i;
+ if (pSta && pSta->added)
+ {
+ if(eBA_ENABLE == pSta->tcCfg[tid].fUseBATx)
+ {
+ limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+ }
+ else if(eBA_ENABLE == pSta->tcCfg[tid].fUseBARx)
+ {
+ limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+ }
+ }
+ }
+ }
+ else if((eLIM_STA_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole))
+ {
+ pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
+ if (pSta && pSta->added)
+ {
+ if(eBA_ENABLE == pSta->tcCfg[tid].fUseBATx)
+ {
+ limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+ }
+ if(eBA_ENABLE == pSta->tcCfg[tid].fUseBARx)
+ {
+ limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry);
+ }
+ }
+ }
+ }
+}
+/** -------------------------------------------------------------
+\fn limProcessDelTsInd
+\brief handles the DeleteTS indication coming from HAL or generated by PE itself in some error cases.
+ Validates the request, sends the DelTs action frame to the Peer and sends DelTs indicatoin to HDD.
+\param tpAniSirGlobal pMac
+\param tSirMsgQ limMsg
+\return None
+-------------------------------------------------------------*/
+void
+limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpDphHashNode pSta;
+ tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr);
+ tpSirDeltsReq pDelTsReq = NULL;
+ tSirMacAddr peerMacAddr;
+ tpSirDeltsReqInfo pDelTsReqInfo;
+ tpLimTspecInfo pTspecInfo;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+
+if((psessionEntry = peFindSessionByBssid(pMac,pDelTsParam->bssId,&sessionId))== NULL)
+ {
+ limLog(pMac, LOGE,FL("session does not exist for given BssId\n"));
+ return;
+ }
+
+ pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]);
+ if(pTspecInfo->inuse == false)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("tspec entry with index %d is not in use\n"), pDelTsParam->tspecIdx);)
+ goto error1;
+ }
+
+ pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable);
+ if(pSta == NULL)
+ {
+ limLog(pMac, LOGE, FL("Could not find entry in DPH table for assocId = %d\n"),
+ pTspecInfo->assocId);
+ goto error1;
+ }
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pDelTsReq, sizeof(tSirDeltsReq)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory() failed\n"));)
+ goto error1;
+ }
+
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pDelTsReq, sizeof(tSirDeltsReq));
+
+ if(pSta->wmeEnabled)
+ palCopyMemory(pMac->hHdd, &(pDelTsReq->req.tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE));
+ else
+ palCopyMemory(pMac->hHdd, &(pDelTsReq->req.tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo));
+
+
+ //validate the req
+ if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDelTsReq, peerMacAddr,psessionEntry))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed\n"));)
+ goto error2;
+ }
+ PELOG1(limLog(pMac, LOG1, "Sent DELTS request to station with assocId = %d MacAddr = %x:%x:%x:%x:%x:%x\n",
+ pDelTsReq->aid, peerMacAddr[0], peerMacAddr[1], peerMacAddr[2],
+ peerMacAddr[3], peerMacAddr[4], peerMacAddr[5]);)
+
+ limSendDeltsReqActionFrame(pMac, peerMacAddr, pDelTsReq->req.wmeTspecPresent, &pDelTsReq->req.tsinfo, &pDelTsReq->req.tspec,
+ psessionEntry);
+
+ // prepare and send an sme indication to HDD
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pDelTsReqInfo, sizeof(tSirDeltsReqInfo)))
+ {
+ PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory() failed\n"));)
+ goto error3;
+ }
+ palZeroMemory( pMac->hHdd, (tANI_U8 *)pDelTsReqInfo, sizeof(tSirDeltsReqInfo));
+
+ if(pSta->wmeEnabled)
+ palCopyMemory(pMac->hHdd, &(pDelTsReqInfo->tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE));
+ else
+ palCopyMemory(pMac->hHdd, &(pDelTsReqInfo->tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo));
+
+ limSendSmeDeltsInd(pMac, pDelTsReqInfo, pDelTsReq->aid,psessionEntry);
+
+error3:
+ palFreeMemory(pMac->hHdd, (void *) pDelTsReqInfo);
+error2:
+ palFreeMemory(pMac->hHdd, (void *) pDelTsReq);
+error1:
+ palFreeMemory(pMac->hHdd, (void *)(limMsg->bodyptr));
+ return;
+}
+
+/**
+ * \brief Setup an A-MPDU/BA session
+ *
+ * \sa limPostMlmAddBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pStaDs DPH Hash Node object of peer STA
+ *
+ * \param tid TID for which a BA is being setup.
+ * If this is set to 0xFFFF, then we retrieve
+ * the default TID from the CFG
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpLimMlmAddBAReq pMlmAddBAReq;
+ tpDialogueToken dialogueTokenNode;
+ tANI_U32 val = 0;
+
+ // Check if the peer is a 11n capable STA
+ // FIXME - Need a 11n peer indication in DPH.
+ // For now, using the taurusPeer attribute
+ //if( 0 == pStaDs->taurusPeer == )
+ //return eSIR_SUCCESS;
+
+ // Allocate for LIM_MLM_ADDBA_REQ
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmAddBAReq,
+ sizeof( tLimMlmAddBAReq )))
+ {
+ limLog( pMac, LOGP, FL("palAllocateMemory failed\n"));
+ status = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pMlmAddBAReq, sizeof( tLimMlmAddBAReq ));
+
+ // Copy the peer MAC
+ palCopyMemory( pMac->hHdd,
+ pMlmAddBAReq->peerMacAddr,
+ pStaDs->staAddr,
+ sizeof( tSirMacAddr ));
+
+ // Update the TID
+ pMlmAddBAReq->baTID = tid;
+
+ // Determine the supported BA policy of local STA
+ // for the TID of interest
+ pMlmAddBAReq->baPolicy = (pStaDs->baPolicyFlag >> tid) & 0x1;
+
+ // BA Buffer Size
+ // Requesting the ADDBA recipient to populate the size.
+ // If ADDBA is accepted, a non-zero buffer size should
+ // be returned in the ADDBA Rsp
+ pMlmAddBAReq->baBufferSize = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Requesting an ADDBA to setup a %s BA session with STA %d for TID %d\n" ),
+ (pMlmAddBAReq->baPolicy ? "Immediate": "Delayed"),
+ pStaDs->staIndex,
+ tid );
+
+ // BA Timeout
+ // pMlmAddBAReq->baTimeout = pMac->hal.halMac.baTimeout; // In TU's
+ if (wlan_cfgGetInt(pMac, WNI_CFG_BA_TIMEOUT, &val) != eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE, FL("could not retrieve BA TIME OUT Param CFG\n"));
+ status = eSIR_FAILURE;
+ goto returnFailure;
+ }
+ pMlmAddBAReq->baTimeout = val; // In TU's
+
+ // ADDBA Failure Timeout
+ // FIXME_AMPDU - Need to retrieve this from CFG.
+ //right now we are not checking for response timeout. so this field is dummy just to be compliant with the spec.
+ pMlmAddBAReq->addBAFailureTimeout = 2000; // In TU's
+
+ // BA Starting Sequence Number
+ pMlmAddBAReq->baSSN = startingSeqNum;
+
+ /* Update PE session Id*/
+ pMlmAddBAReq->sessionId = psessionEntry->peSessionId;
+
+ LIM_SET_STA_BA_STATE(pStaDs, tid, eLIM_BA_STATE_WT_ADD_RSP);
+
+ if( NULL == (dialogueTokenNode = limAssignDialogueToken(pMac)))
+ goto returnFailure;
+
+ pMlmAddBAReq->baDialogToken = dialogueTokenNode->token;
+ //set assocId and tid information in the lim linked list
+ dialogueTokenNode->assocId = pStaDs->assocId;
+ dialogueTokenNode->tid = tid;
+ // Send ADDBA Req to MLME
+ limPostMlmMessage( pMac,
+ LIM_MLM_ADDBA_REQ,
+ (tANI_U32 *) pMlmAddBAReq );
+
+returnFailure:
+
+ return status;
+}
+
+/**
+ * \brief Post LIM_MLM_ADDBA_RSP to MLME. MLME
+ * will then send an ADDBA Rsp to peer MAC entity
+ * with the appropriate ADDBA status code
+ *
+ * \sa limPostMlmAddBARsp
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param peerMacAddr MAC address of peer entity that will
+ * be the recipient of this ADDBA Rsp
+ *
+ * \param baStatusCode ADDBA Rsp status code
+ *
+ * \param baDialogToken ADDBA Rsp dialog token
+ *
+ * \param baTID TID of interest
+ *
+ * \param baPolicy The BA policy
+ *
+ * \param baBufferSize The BA buffer size
+ *
+ * \param baTimeout BA timeout in TU's
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirMacStatusCodes baStatusCode,
+ tANI_U8 baDialogToken,
+ tANI_U8 baTID,
+ tANI_U8 baPolicy,
+ tANI_U16 baBufferSize,
+ tANI_U16 baTimeout,
+ tpPESession psessionEntry)
+{
+tSirRetStatus status = eSIR_SUCCESS;
+tpLimMlmAddBARsp pMlmAddBARsp;
+
+ // Allocate for LIM_MLM_ADDBA_RSP
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmAddBARsp,
+ sizeof( tLimMlmAddBARsp )))
+ {
+ limLog( pMac, LOGE,
+ FL("palAllocateMemory failed with error code %d\n"),
+ status );
+
+ status = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pMlmAddBARsp, sizeof( tLimMlmAddBARsp ));
+
+ // Copy the peer MAC
+ palCopyMemory( pMac->hHdd,
+ pMlmAddBARsp->peerMacAddr,
+ peerMacAddr,
+ sizeof( tSirMacAddr ));
+
+ pMlmAddBARsp->baDialogToken = baDialogToken;
+ pMlmAddBARsp->addBAResultCode = baStatusCode;
+ pMlmAddBARsp->baTID = baTID;
+ pMlmAddBARsp->baPolicy = baPolicy;
+ pMlmAddBARsp->baBufferSize = baBufferSize;
+ pMlmAddBARsp->baTimeout = baTimeout;
+
+ /* UPdate PE session ID*/
+ pMlmAddBARsp->sessionId = psessionEntry->peSessionId;
+
+ // Send ADDBA Rsp to MLME
+ limPostMlmMessage( pMac,
+ LIM_MLM_ADDBA_RSP,
+ (tANI_U32 *) pMlmAddBARsp );
+
+returnFailure:
+
+ return status;
+}
+
+/**
+ * \brief Post LIM_MLM_DELBA_REQ to MLME. MLME
+ * will then send an DELBA Ind to peer MAC entity
+ * with the appropriate DELBA status code
+ *
+ * \sa limPostMlmDelBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pSta DPH Hash Node object of peer MAC entity
+ * for which the BA session is being deleted
+ *
+ * \param baDirection DELBA direction
+ *
+ * \param baTID TID for which the BA session is being deleted
+ *
+ * \param baReasonCode DELBA Req reason code
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baDirection,
+ tANI_U8 baTID,
+ tSirMacReasonCodes baReasonCode,
+ tpPESession psessionEntry)
+{
+tSirRetStatus status = eSIR_SUCCESS;
+tpLimMlmDelBAReq pMlmDelBAReq;
+tLimBAState curBaState;
+
+if(NULL == pSta)
+ return eSIR_FAILURE;
+
+LIM_GET_STA_BA_STATE(pSta, baTID, &curBaState);
+
+ // Need to validate the current BA State.
+ if( eLIM_BA_STATE_IDLE != curBaState)
+ {
+ limLog( pMac, LOGE,
+ FL( "Received unexpected DELBA REQ when STA BA state for tid = %d is %d\n" ),
+ baTID,
+ curBaState);
+
+ status = eSIR_FAILURE;
+ goto returnFailure;
+ }
+
+ // Allocate for LIM_MLM_DELBA_REQ
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **) &pMlmDelBAReq,
+ sizeof( tLimMlmDelBAReq )))
+ {
+ limLog( pMac, LOGE,
+ FL("palAllocateMemory failed with error code %d\n"),
+ status );
+
+ status = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pMlmDelBAReq, sizeof( tLimMlmDelBAReq ));
+
+ // Copy the peer MAC
+ palCopyMemory( pMac->hHdd,
+ pMlmDelBAReq->peerMacAddr,
+ pSta->staAddr,
+ sizeof( tSirMacAddr ));
+
+ pMlmDelBAReq->baDirection = baDirection;
+ pMlmDelBAReq->baTID = baTID;
+ pMlmDelBAReq->delBAReasonCode = baReasonCode;
+
+ /* Update PE session ID*/
+ pMlmDelBAReq->sessionId = psessionEntry->peSessionId;
+
+ //we don't have valid BA session for the given direction.
+ // HDD wants to get the BA session deleted on PEER in this case.
+ // in this case we just need to send DelBA to the peer.
+ if(((eBA_RECIPIENT == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBARx)) ||
+ ((eBA_INITIATOR == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBATx)))
+ {
+ // Send DELBA Ind over the air
+ if( eSIR_SUCCESS !=
+ (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry)))
+ status = eSIR_FAILURE;
+
+ palFreeMemory(pMac->hHdd, (void*) pMlmDelBAReq);
+ return status;
+ }
+
+
+ // Update the BA state in STA
+ LIM_SET_STA_BA_STATE(pSta, pMlmDelBAReq->baTID, eLIM_BA_STATE_WT_DEL_RSP);
+
+ // Send DELBA Req to MLME
+ limPostMlmMessage( pMac,
+ LIM_MLM_DELBA_REQ,
+ (tANI_U32 *) pMlmDelBAReq );
+
+returnFailure:
+
+ return status;
+}
+
+/**
+ * \brief Send WDA_ADDBA_REQ to HAL, in order
+ * to setup a new BA session with a peer
+ *
+ * \sa limPostMsgAddBAReq
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pSta Runtime, STA-related configuration cached
+ * in the HashNode object
+ *
+ * \param baDialogToken The Action Frame dialog token
+ *
+ * \param baTID TID for which the BA session is being setup
+ *
+ * \param baPolicy BA Policy
+ *
+ * \param baBufferSize The requested BA buffer size
+ *
+ * \param baTimeout BA Timeout. 0 indicates no BA timeout enforced
+ *
+ * \param baSSN Starting Sequence Number for this BA session
+ *
+ * \param baDirection BA Direction: 1 - Initiator, 0 - Recipient
+ *
+ * \return none
+ *
+ */
+tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baDialogToken,
+ tANI_U8 baTID,
+ tANI_U8 baPolicy,
+ tANI_U16 baBufferSize,
+ tANI_U16 baTimeout,
+ tANI_U16 baSSN,
+ tANI_U8 baDirection,
+ tpPESession psessionEntry)
+{
+tpAddBAParams pAddBAParams = NULL;
+tSirRetStatus retCode = eSIR_SUCCESS;
+eHalStatus status;
+tSirMsgQ msgQ;
+
+#ifdef WLAN_SOFTAP_VSTA_FEATURE
+ // we can only do BA on "hard" STAs
+ if (!(IS_HWSTA_IDX(pSta->staIndex)))
+ {
+ retCode = eHAL_STATUS_FAILURE;
+ goto returnFailure;
+ }
+#endif //WLAN_SOFTAP_VSTA_FEATURE
+
+ // Allocate for WDA_ADDBA_REQ
+ if( eHAL_STATUS_SUCCESS !=
+ (status = palAllocateMemory( pMac->hHdd,
+ (void **) &pAddBAParams,
+ sizeof( tAddBAParams ))))
+ {
+ limLog( pMac, LOGE,
+ FL("palAllocateMemory failed with error code %d\n"),
+ status );
+
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pAddBAParams, sizeof( tAddBAParams ));
+
+ // Copy the peer MAC address
+ palCopyMemory( pMac->hHdd,
+ (void *) pAddBAParams->peerMacAddr,
+ (void *) pSta->staAddr,
+ sizeof( tSirMacAddr ));
+
+ // Populate the REQ parameters
+ pAddBAParams->staIdx = pSta->staIndex;
+ pAddBAParams->baDialogToken = baDialogToken;
+ pAddBAParams->baTID = baTID;
+ pAddBAParams->baPolicy = baPolicy;
+ pAddBAParams->baBufferSize = baBufferSize;
+ pAddBAParams->baTimeout = baTimeout;
+ pAddBAParams->baSSN = baSSN;
+ pAddBAParams->baDirection = baDirection;
+ pAddBAParams->respReqd = 1;
+
+ /* UPdate PE session ID */
+ pAddBAParams->sessionId = psessionEntry->peSessionId;
+
+ // Post WDA_ADDBA_REQ to HAL.
+ msgQ.type = WDA_ADDBA_REQ;
+ //
+ // FIXME_AMPDU
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBAParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Sending WDA_ADDBA_REQ..." ));
+
+ //defer any other message until we get response back.
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ limLog( pMac, LOGE,
+ FL("Posting WDA_ADDBA_REQ to HAL failed! Reason = %d\n"),
+ retCode );
+ else
+ return retCode;
+
+returnFailure:
+
+ // Clean-up...
+ if( NULL != pAddBAParams )
+ palFreeMemory( pMac->hHdd, (void *) pAddBAParams );
+
+ return retCode;
+
+}
+
+/**
+ * \brief Send WDA_DELBA_IND to HAL, in order
+ * to delete an existing BA session with peer
+ *
+ * \sa limPostMsgDelBAInd
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param pSta Runtime, STA-related configuration cached
+ * in the HashNode object
+ *
+ * \param baTID TID for which the BA session is being setup
+ *
+ * \param baDirection Identifies whether the DELBA Ind was
+ * sent by the BA initiator or recipient
+ *
+ * \return none
+ *
+ */
+tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baTID,
+ tANI_U8 baDirection,
+ tpPESession psessionEntry)
+{
+tpDelBAParams pDelBAParams = NULL;
+tSirRetStatus retCode = eSIR_SUCCESS;
+eHalStatus status;
+tSirMsgQ msgQ;
+
+ // Allocate for SIR_HAL_DELBA_IND
+ if( eHAL_STATUS_SUCCESS !=
+ (status = palAllocateMemory( pMac->hHdd,
+ (void **) &pDelBAParams,
+ sizeof( tDelBAParams ))))
+ {
+ limLog( pMac, LOGE,
+ FL("palAllocateMemory failed with error code %d\n"),
+ status );
+
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ palZeroMemory( pMac->hHdd, (void *) pDelBAParams, sizeof( tDelBAParams ));
+
+ // Populate the REQ parameters
+ pDelBAParams->staIdx = pSta->staIndex;
+ pDelBAParams->baTID = baTID;
+ pDelBAParams->baDirection = baDirection;
+
+ /* Update PE session ID */
+
+
+ //TBD-RAJESH Updating of the session ID is requird for SIR_HAL_DELBA_IND?????
+ //pDelBAParams->sessionId = psessionEntry->peSessionId;
+
+ // Post WDA_DELBA_IND to HAL.
+ msgQ.type = WDA_DELBA_IND;
+ //
+ // FIXME:
+ // A global counter (dialog token) is required to keep track of
+ // all PE <-> HAL communication(s)
+ //
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pDelBAParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOGW,
+ FL( "Sending SIR_HAL_DELBA_IND..." ));
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT
+ limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_DELBA_IND_EVENT, psessionEntry, 0, 0);
+#endif //FEATURE_WLAN_DIAG_SUPPORT
+
+ if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
+ limLog( pMac, LOGE,
+ FL("Posting WDA_DELBA_IND to HAL failed! Reason = %d\n"),
+ retCode );
+ else
+ {
+ // Update LIM's internal cache...
+ if( eBA_INITIATOR == baDirection)
+ {
+ pSta->tcCfg[baTID].fUseBATx = 0;
+ pSta->tcCfg[baTID].txBufSize = 0;
+ }
+ else
+ {
+ pSta->tcCfg[baTID].fUseBARx = 0;
+ pSta->tcCfg[baTID].rxBufSize = 0;
+ }
+
+ return retCode;
+ }
+
+returnFailure:
+
+ // Clean-up...
+ if( NULL != pDelBAParams )
+ palFreeMemory( pMac->hHdd, (void *) pDelBAParams );
+
+ return retCode;
+
+}
+
+/**
+ * @function : limPostSMStateUpdate()
+ *
+ * @brief : This function Updates the HAL and Softmac about the change in the STA's SMPS state.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param limMsg - Lim Message structure object with the MimoPSparam in body
+ * @return None
+ */
+tSirRetStatus
+limPostSMStateUpdate(tpAniSirGlobal pMac,
+ tANI_U16 staIdx, tSirMacHTMIMOPowerSaveState state)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ eHalStatus status;
+ tpSetMIMOPS pMIMO_PSParams;
+
+ msgQ.reserved = 0;
+ msgQ.type = WDA_SET_MIMOPS_REQ;
+
+ // Allocate for WDA_SET_MIMOPS_REQ
+ status = palAllocateMemory( pMac->hHdd, (void **) &pMIMO_PSParams, sizeof( tSetMIMOPS));
+ if( eHAL_STATUS_SUCCESS != status) {
+ limLog( pMac, LOGP,FL(" palAllocateMemory failed with error code %d\n"), status );
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pMIMO_PSParams->htMIMOPSState = state;
+ pMIMO_PSParams->staIdx = staIdx;
+ pMIMO_PSParams->fsendRsp = true;
+ msgQ.bodyptr = pMIMO_PSParams;
+ msgQ.bodyval = 0;
+
+ limLog( pMac, LOG2, FL( "Sending WDA_SET_MIMOPS_REQ..." ));
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ retCode = wdaPostCtrlMsg( pMac, &msgQ );
+ if (eSIR_SUCCESS != retCode)
+ {
+ limLog( pMac, LOGP, FL("Posting WDA_SET_MIMOPS_REQ to HAL failed! Reason = %d\n"), retCode );
+ palFreeMemory(pMac->hHdd, (void *) pMIMO_PSParams);
+ return retCode;
+ }
+
+ return retCode;
+}
+
+void limPktFree (
+ tpAniSirGlobal pMac,
+ eFrameType frmType,
+ tANI_U8 *pRxPacketInfo,
+ void *pBody)
+{
+ (void) pMac; (void) frmType; (void) pRxPacketInfo; (void) pBody;
+#if defined ANI_OS_TYPE_LINUX || defined ANI_OS_TYPE_OSX
+ // Free up allocated SK BUF
+ palPktFree( pMac->hHdd, frmType, pRxPacketInfo, pBody) ;
+#endif
+}
+
+/**
+ * limGetBDfromRxPacket()
+ *
+ *FUNCTION:
+ * This function is called to get pointer to Polaris
+ * Buffer Descriptor containing MAC header & other control
+ * info from the body of the message posted to LIM.
+ *
+ *LOGIC:
+ * NA
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param body - Received message body
+ * @param pRxPacketInfo - Pointer to received BD
+ * @return None
+ */
+
+void
+limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pRxPacketInfo)
+{
+#if defined (ANI_OS_TYPE_LINUX) || defined (ANI_OS_TYPE_OSX)
+#ifndef GEN6_ONWARDS
+ palGetPacketDataPtr( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, (void *) body, (void **) pRxPacketInfo );
+#endif //GEN6_ONWARDS
+#else
+ *pRxPacketInfo = (tANI_U32 *) body;
+#endif
+} /*** end limGetBDfromRxPacket() ***/
+
+
+
+
+
+void limRessetScanChannelInfo(tpAniSirGlobal pMac)
+{
+ palZeroMemory(pMac->hHdd, &pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo));
+}
+
+
+void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId)
+{
+ tANI_U8 i;
+ tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE;
+
+ for(i = 0; i < pMac->lim.scanChnInfo.numChnInfo; i++)
+ {
+ if(pMac->lim.scanChnInfo.scanChn[i].channelId == channelId)
+ {
+ pMac->lim.scanChnInfo.scanChn[i].numTimeScan++;
+ fFound = eANI_BOOLEAN_TRUE;
+ break;
+ }
+ }
+ if(eANI_BOOLEAN_FALSE == fFound)
+ {
+ if(pMac->lim.scanChnInfo.numChnInfo < SIR_MAX_SUPPORTED_CHANNEL_LIST)
+ {
+ pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo].channelId = channelId;
+ pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo++].numTimeScan = 1;
+ }
+ else
+ {
+ PELOGW(limLog(pMac, LOGW, FL(" -- number of channels exceed mac\n"));)
+ }
+ }
+}
+
+
+/**
+ * @function : limIsChannelValidForChannelSwitch()
+ *
+ * @brief : This function checks if the channel to which AP
+ * is expecting us to switch, is a valid channel for us.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param channel - New channel to which we are expected to move
+ * @return None
+ */
+tAniBool
+limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel)
+{
+ tANI_U8 index;
+ tANI_U32 validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+
+ if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+ (tANI_U8 *)validChannelList,
+ (tANI_U32 *)&validChannelListLen) != eSIR_SUCCESS)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list\n"));)
+ return (eSIR_FALSE);
+ }
+
+ for(index = 0; index < validChannelListLen; index++)
+ {
+ if(validChannelList[index] == channel)
+ return (eSIR_TRUE);
+ }
+
+ /* channel does not belong to list of valid channels */
+ return (eSIR_FALSE);
+}
+
+/**------------------------------------------------------
+\fn __limFillTxControlParams
+\brief Fill the message for stopping/resuming tx.
+
+\param pMac
+\param pTxCtrlMsg - Pointer to tx control message.
+\param type - Which way we want to stop/ resume tx.
+\param mode - To stop/resume.
+ -------------------------------------------------------*/
+static eHalStatus
+__limFillTxControlParams(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg,
+ tLimQuietTxMode type, tLimControlTx mode)
+{
+
+ //TBD-RAJESH HOW TO GET sessionEntry?????
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];
+
+ if (mode == eLIM_STOP_TX)
+ pTxCtrlMsg->stopTx = eANI_BOOLEAN_TRUE;
+ else
+ pTxCtrlMsg->stopTx = eANI_BOOLEAN_FALSE;
+
+ switch (type)
+ {
+ case eLIM_TX_ALL:
+ /** Stops/resumes transmission completely */
+ pTxCtrlMsg->fCtrlGlobal = 1;
+ break;
+
+ case eLIM_TX_BSS_BUT_BEACON:
+ /** Stops/resumes transmission on a particular BSS. Stopping BSS, doesnt
+ * stop beacon transmission.
+ */
+ pTxCtrlMsg->ctrlBss = 1;
+ pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx);
+ break;
+
+ case eLIM_TX_STA:
+ /** Memory for station bitmap is allocated dynamically in caller of this
+ * so decode properly here and fill the bitmap. Now not implemented,
+ * fall through.
+ */
+ case eLIM_TX_BSS:
+ //Fall thru...
+ default:
+ PELOGW(limLog(pMac, LOGW, FL("Invalid case: Not Handled\n"));)
+ return eHAL_STATUS_FAILURE;
+ }
+
+ return eHAL_STATUS_SUCCESS;
+}
+
+/**
+ * @function : limFrameTransmissionControl()
+ *
+ * @brief : This API is called by the user to halt/resume any frame
+ * transmission from the device. If stopped, all frames will be
+ * queued starting from hardware. Then back-pressure
+ * is built till the driver.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode)
+{
+
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tpTxControlParams pTxCtrlMsg;
+ tSirMsgQ msgQ;
+ tANI_U8 nBytes = 0; // No of bytes required for station bitmap.
+
+ /** Allocate only required number of bytes for station bitmap
+ * Make it to align to 4 byte boundary */
+ nBytes = (tANI_U8)HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation);
+
+ status = palAllocateMemory(pMac->hHdd, (void **) &pTxCtrlMsg,
+ (sizeof(*pTxCtrlMsg) + nBytes));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory() failed\n"));
+ return;
+ }
+
+ status = palZeroMemory(pMac->hHdd, (void *) pTxCtrlMsg,
+ (sizeof(*pTxCtrlMsg) + nBytes));
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, (void *) pTxCtrlMsg);
+ limLog(pMac, LOGP, FL("palZeroMemory() failed, status = %d\n"), status);
+ return;
+ }
+
+ status = __limFillTxControlParams(pMac, pTxCtrlMsg, type, mode);
+ if (status != eHAL_STATUS_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, (void *) pTxCtrlMsg);
+ limLog(pMac, LOGP, FL("__limFillTxControlParams failed, status = %d\n"), status);
+ return;
+ }
+
+ msgQ.bodyptr = (void *) pTxCtrlMsg;
+ msgQ.bodyval = 0;
+ msgQ.reserved = 0;
+ msgQ.type = WDA_TRANSMISSION_CONTROL_IND;
+
+ MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
+ if(wdaPostCtrlMsg( pMac, &msgQ) != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, (void *) pTxCtrlMsg);
+ limLog( pMac, LOGP, FL("Posting Message to HAL failed\n"));
+ return;
+ }
+
+ if (mode == eLIM_STOP_TX)
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Stopping the transmission of all packets, indicated softmac\n"));)
+ }
+ else
+ {
+ PELOG1(limLog(pMac, LOG1, FL("Resuming the transmission of all packets, indicated softmac\n"));)
+ }
+ return;
+}
+
+
+/**
+ * @function : limRestorePreChannelSwitchState()
+ *
+ * @brief : This API is called by the user to undo any
+ * specific changes done on the device during
+ * channel switch.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+tSirRetStatus
+limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ tSirRetStatus retCode = eSIR_SUCCESS;
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ tANI_U32 val = 0;
+
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return retCode;
+
+ /* Channel switch should be ready for the next time */
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
+
+ /* Restore the frame transmission, all the time. */
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+ /* Free to enter BMPS */
+ limSendSmePostChannelSwitchInd(pMac);
+
+ //Background scan is now enabled by SME
+ if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
+ {
+ /* Enable background scan if already enabled, else don't bother */
+ if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD,
+ &val)) != eSIR_SUCCESS)
+
+ {
+ limLog(pMac, LOGP, FL("could not retrieve Background scan period value\n"));
+ return (retCode);
+ }
+
+ if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_BACKGROUND_SCAN_TIMER));
+ if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP"));
+ return (eSIR_FAILURE);
+ }
+
+ }
+ }
+
+ /* Enable heartbeat timer */
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if(limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP"));
+ return (eSIR_FAILURE);
+ }
+ }
+#endif
+ return (retCode);
+}
+
+
+/**--------------------------------------------
+\fn limRestorePreQuietState
+\brief Restore the pre quiet state
+
+\param pMac
+\return NONE
+---------------------------------------------*/
+tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac)
+{
+
+ tSirRetStatus retCode = eSIR_SUCCESS;
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ tANI_U32 val = 0;
+
+ if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
+ return retCode;
+
+ /* Quiet should be ready for the next time */
+ pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ /* Restore the frame transmission, all the time. */
+ if (pMac->lim.gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
+ limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+
+ //Background scan is now enabled by SME
+ if(pMac->lim.gLimBackgroundScanTerminate == FALSE)
+ {
+ /* Enable background scan if already enabled, else don't bother */
+ if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD,
+ &val)) != eSIR_SUCCESS)
+
+ {
+ limLog(pMac, LOGP, FL("could not retrieve Background scan period value\n"));
+ return (retCode);
+ }
+
+ if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_BACKGROUND_SCAN_TIMER));
+ if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP"));
+ return (eSIR_FAILURE);
+ }
+
+ }
+ }
+
+ /* Enable heartbeat timer */
+ if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer))
+ {
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_HEART_BEAT_TIMER));
+ if(limActivateHearBeatTimer(pMac) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP"));
+ return (eSIR_FAILURE);
+ }
+ }
+#endif
+ return (retCode);
+}
+
+
+/**
+ * @function: limPrepareFor11hChannelSwitch()
+ *
+ * @brief : This API is called by the user to prepare for
+ * 11h channel switch. As of now, the API does
+ * very minimal work. User can add more into the
+ * same API if needed.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param psessionEntry
+ * @return None
+ */
+void
+limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ return;
+
+ /* Flag to indicate 11h channel switch in progress */
+ pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING;
+
+ /* Disable, Stop background scan if enabled and running */
+ limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER);
+
+ /* Stop heart-beat timer to stop heartbeat disassociation */
+ limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
+
+ if(pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE ||
+ pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE)
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Posting finish scan as we are in scan state\n"));)
+ /* Stop ongoing scanning if any */
+ if (GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ {
+ //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);
+ }
+ else
+ {
+ limRestorePreChannelSwitchState(pMac, psessionEntry);
+ }
+ return;
+ }
+ else
+ {
+ PELOGE(limLog(pMac, LOGE, FL("Not in scan state, start channel switch timer\n"));)
+ /** We are safe to switch channel at this point */
+ limStopTxAndSwitchChannel(pMac, psessionEntry->peSessionId);
+ }
+#endif
+}
+
+
+
+/**----------------------------------------------------
+\fn limGetNwType
+
+\brief Get type of the network from data packet or beacon
+\param pMac
+\param channelNum - Channel number
+\param type - Type of packet.
+\param pBeacon - Pointer to beacon or probe response
+
+\return Network type a/b/g.
+-----------------------------------------------------*/
+tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon)
+{
+ tSirNwType nwType = eSIR_11B_NW_TYPE;
+
+ if (type == SIR_MAC_DATA_FRAME)
+ {
+ if ((channelNum > 0) && (channelNum < 15))
+ {
+ nwType = eSIR_11G_NW_TYPE;
+ }
+ else
+ {
+ nwType = eSIR_11A_NW_TYPE;
+ }
+ }
+ else
+ {
+ if ((channelNum > 0) && (channelNum < 15))
+ {
+ int i;
+ // 11b or 11g packet
+ // 11g iff extended Rate IE is present or
+ // if there is an A rate in suppRate IE
+ for (i = 0; i < pBeacon->supportedRates.numRates; i++)
+ {
+ if (sirIsArate(pBeacon->supportedRates.rate[i] & 0x7f))
+ {
+ nwType = eSIR_11G_NW_TYPE;
+ break;
+ }
+ }
+ if (pBeacon->extendedRatesPresent)
+ {
+ PELOG3(limLog(pMac, LOG3, FL("Beacon, nwtype=G\n"));)
+ nwType = eSIR_11G_NW_TYPE;
+ }
+ }
+ else
+ {
+ // 11a packet
+ PELOG3(limLog(pMac, LOG3,FL("Beacon, nwtype=A\n"));)
+ nwType = eSIR_11A_NW_TYPE;
+ }
+ }
+ return nwType;
+}
+
+
+/**---------------------------------------------------------
+\fn limGetChannelFromBeacon
+\brief To extract channel number from beacon
+
+\param pMac
+\param pBeacon - Pointer to beacon or probe rsp
+\return channel number
+-----------------------------------------------------------*/
+tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon)
+{
+ tANI_U8 channelNum = 0;
+
+ if (pBeacon->dsParamsPresent)
+ channelNum = pBeacon->channelNumber;
+ else if(pBeacon->HTInfo.present)
+ channelNum = pBeacon->HTInfo.primaryChannel;
+ else
+ channelNum = pBeacon->channelNumber;
+
+ return channelNum;
+}
+
+
+/** ---------------------------------------------------------
+\fn limSetTspecUapsdMask
+\brief This function sets the PE global variable:
+\ 1) gUapsdPerAcTriggerEnableMask and
+\ 2) gUapsdPerAcDeliveryEnableMask
+\ based on the user priority field and direction field
+\ in the TS Info Fields.
+\
+\ An AC is a trigger-enabled AC if the PSB subfield
+\ is set to 1 in the uplink direction.
+\ An AC is a delivery-enabled AC if the PSB subfield
+\ is set to 1 in the down-link direction.
+\
+\param tpAniSirGlobal pMac
+\param tSirMacTSInfo pTsInfo
+\param tANI_U32 action
+\return None
+ ------------------------------------------------------------*/
+void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action)
+{
+ tANI_U8 userPrio = (tANI_U8)pTsInfo->traffic.userPrio;
+ tANI_U16 direction = pTsInfo->traffic.direction;
+ tANI_U8 ac = upToAc(userPrio);
+
+ PELOG1(limLog(pMac, LOG1, FL(" Set UAPSD mask for AC %d, direction %d, action=%d (1=set,0=clear) \n"),ac, direction, action );)
+
+ /* Converting AC to appropriate Uapsd Bit Mask
+ * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
+ * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
+ * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
+ * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
+ */
+ ac = ((~ac) & 0x3);
+
+ if (action == CLEAR_UAPSD_MASK)
+ {
+ if (direction == SIR_MAC_DIRECTION_UPLINK)
+ pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_DNLINK)
+ pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac);
+ pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac);
+ }
+ }
+ else if (action == SET_UAPSD_MASK)
+ {
+ if (direction == SIR_MAC_DIRECTION_UPLINK)
+ pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_DNLINK)
+ pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_BIDIR)
+ {
+ pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac);
+ pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac);
+ }
+ }
+
+ limLog(pMac, LOGE, FL("New pMac->lim.gUapsdPerAcTriggerEnableMask = 0x%x \n"), pMac->lim.gUapsdPerAcTriggerEnableMask );
+ limLog(pMac, LOGE, FL("New pMac->lim.gUapsdPerAcDeliveryEnableMask = 0x%x \n"), pMac->lim.gUapsdPerAcDeliveryEnableMask );
+
+ return;
+}
+
+
+
+void limHandleHeartBeatTimeout(tpAniSirGlobal pMac )
+{
+
+ tANI_U8 i;
+ for(i =0;i < pMac->lim.maxBssId;i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE )
+ {
+ if(pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)
+ {
+ limIbssHeartBeatHandle(pMac,&pMac->lim.gpSession[i]);
+ break;
+ }
+
+ if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE))
+ {
+ limHandleHeartBeatFailure(pMac,&pMac->lim.gpSession[i]);
+ }
+ }
+ }
+ for(i=0; i< pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE )
+ {
+ if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE))
+ {
+ if(pMac->lim.gpSession[i].LimHBFailureStatus == eANI_BOOLEAN_TRUE)
+ {
+ /* Activate Probe After HeartBeat Timer incase HB Failure detected */
+ PELOGW(limLog(pMac, LOGW,FL("Sending Probe for Session: %d\n"),
+ i);)
+ limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
+ MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PROBE_AFTER_HB_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP, FL("Fail to re-activate Probe-after-heartbeat timer\n"));
+ limReactivateHeartBeatTimer(pMac, &pMac->lim.gpSession[i]);
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+ for(i =0;i < pMac->lim.maxBssId;i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE )
+ {
+ if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE))
+ {
+ return pMac->lim.gpSession[i].currentOperChannel;
+ }
+ }
+ }
+ return 0;
+}
+
+void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ)
+{
+
+ tpPESession psessionEntry;
+// tANI_U8 sessionId;
+ tpAddStaParams pAddStaParams;
+
+ pAddStaParams = (tpAddStaParams)limMsgQ->bodyptr;
+
+ if((psessionEntry = peFindSessionBySessionId(pMac,pAddStaParams->sessionId))==NULL)
+ {
+ limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
+ return;
+ }
+ if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)
+ (void) limIbssAddStaRsp(pMac, limMsgQ->bodyptr,psessionEntry);
+
+ else
+ limProcessMlmAddStaRsp(pMac, limMsgQ,psessionEntry);
+
+}
+
+
+void limUpdateBeacon(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+
+ for(i =0;i < pMac->lim.maxBssId;i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE )
+ {
+ if( ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE) )
+ && (eLIM_SME_NORMAL_STATE == pMac->lim.gpSession[i].limSmeState)
+ )
+ {
+ schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]);
+ limSendBeaconInd(pMac, &pMac->lim.gpSession[i]);
+ }
+ else
+ {
+ if( (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))
+ {
+
+ if(pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF)
+ {
+ schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]);
+ }
+ }
+ }
+ }
+ }
+}
+
+void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+ tpPESession psessionEntry;
+ /* Probe response is not received after HB failure. This is handled by LMM sub module. */
+ for(i =0; i < pMac->lim.maxBssId; i++)
+ {
+ if(pMac->lim.gpSession[i].valid == TRUE)
+ {
+ psessionEntry = &pMac->lim.gpSession[i];
+ if(psessionEntry->LimHBFailureStatus == eANI_BOOLEAN_TRUE)
+ {
+ limLog(pMac, LOGE, FL("Probe_hb_failure: SME %d, MLME %d, HB-Count %d\n"),psessionEntry->limSmeState,
+ psessionEntry->limMlmState, psessionEntry->LimRxedBeaconCntDuringHB);
+ if (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)
+ {
+ if (!LIM_IS_CONNECTION_ACTIVE(psessionEntry))
+ {
+ limLog(pMac, LOGE, FL("Probe_hb_failure: for session:%d \n" ),psessionEntry->peSessionId);
+ /* AP did not respond to Probe Request. Tear down link with it.*/
+ limTearDownLinkWithAp(pMac,
+ psessionEntry->peSessionId,
+ eSIR_BEACON_MISSED);
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt++ ;
+ }
+ else // restart heartbeat timer
+ {
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+ }
+ }
+ else
+ {
+ limLog(pMac, LOGE, FL("Unexpected wt-probe-timeout in state \n"));
+ limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState);
+ limReactivateHeartBeatTimer(pMac, psessionEntry);
+ }
+
+ }
+ }
+ }
+ /* Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer, need not deactivate the timer */
+ // tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+}
+
+
+/*
+* This function assumes there will not be more than one IBSS session active at any time.
+*/
+tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+
+ for(i =0;i < pMac->lim.maxBssId;i++)
+ {
+ if( (pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE))
+ return (&pMac->lim.gpSession[i]);
+ }
+
+ return NULL;
+}
+
+tpPESession limIsApSessionActive(tpAniSirGlobal pMac)
+{
+ tANI_U8 i;
+
+ for(i =0;i < pMac->lim.maxBssId;i++)
+ {
+ if( (pMac->lim.gpSession[i].valid) &&
+ ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ||
+ (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)))
+ return (&pMac->lim.gpSession[i]);
+ }
+
+ return NULL;
+}
+
+/**---------------------------------------------------------
+\fn limHandleDeferMsgError
+\brief handles error scenario, when the msg can not be deferred.
+\param pMac
+\param pLimMsg LIM msg, which could not be deferred.
+\return void
+-----------------------------------------------------------*/
+
+void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg)
+{
+ if(SIR_BB_XPORT_MGMT_MSG == pLimMsg->type)
+ {
+ vos_pkt_return_packet((vos_pkt_t*)pLimMsg->bodyptr);
+ }
+ else if(pLimMsg->bodyptr != NULL)
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pLimMsg->bodyptr);
+
+}
+
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**---------------------------------------------------------
+\fn limDiagEventReport
+\brief This function reports Diag event
+\param pMac
+\param eventType
+\param bssid
+\param status
+\param reasonCode
+\return void
+-----------------------------------------------------------*/
+void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode)
+{
+ tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 };
+ WLAN_VOS_DIAG_EVENT_DEF(peEvent, vos_event_wlan_pe_payload_type);
+
+ palZeroMemory(pMac->hHdd, &peEvent, sizeof(vos_event_wlan_pe_payload_type));
+
+ if (NULL == pSessionEntry)
+ {
+ palCopyMemory(pMac->hHdd, peEvent.bssid, nullBssid, sizeof(tSirMacAddr));
+ peEvent.sme_state = (tANI_U16)pMac->lim.gLimSmeState;
+ peEvent.mlm_state = (tANI_U16)pMac->lim.gLimMlmState;
+
+ }
+ else
+ {
+ palCopyMemory(pMac->hHdd, peEvent.bssid, pSessionEntry->bssId, sizeof(tSirMacAddr));
+ peEvent.sme_state = (tANI_U16)pSessionEntry->limSmeState;
+ peEvent.mlm_state = (tANI_U16)pSessionEntry->limMlmState;
+ }
+ peEvent.event_type = eventType;
+ peEvent.status = status;
+ peEvent.reason_code = reasonCode;
+
+ WLAN_VOS_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE);
+ return;
+}
+
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ)
+{
+
+ tpAddStaSelfParams pAddStaSelfParams;
+ tSirMsgQ mmhMsg;
+ tpSirSmeAddStaSelfRsp pRsp;
+
+
+ pAddStaSelfParams = (tpAddStaSelfParams)limMsgQ->bodyptr;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pRsp, sizeof(tSirSmeAddStaSelfRsp)))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for Add Sta self RSP\n"));
+ return;
+ }
+
+ palZeroMemory(pMac, (tANI_U8*)pRsp, sizeof(tSirSmeAddStaSelfRsp));
+
+ pRsp->mesgType = eWNI_SME_ADD_STA_SELF_RSP;
+ pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeAddStaSelfRsp);
+ pRsp->status = pAddStaSelfParams->status;
+
+ palCopyMemory( pMac->hHdd, pRsp->selfMacAddr, pAddStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) );
+
+ palFreeMemory( pMac->hHdd, (tANI_U8 *)pAddStaSelfParams);
+
+ mmhMsg.type = eWNI_SME_ADD_STA_SELF_RSP;
+ mmhMsg.bodyptr = pRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+}
+
+void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ)
+{
+
+ tpDelStaSelfParams pDelStaSelfParams;
+ tSirMsgQ mmhMsg;
+ tpSirSmeDelStaSelfRsp pRsp;
+
+
+ pDelStaSelfParams = (tpDelStaSelfParams)limMsgQ->bodyptr;
+
+ if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pRsp, sizeof(tSirSmeDelStaSelfRsp)))
+ {
+ /// Buffer not available. Log error
+ limLog(pMac, LOGP, FL("call to palAllocateMemory failed for Add Sta self RSP\n"));
+ return;
+ }
+
+ palZeroMemory(pMac, (tANI_U8*)pRsp, sizeof(tSirSmeDelStaSelfRsp));
+
+ pRsp->mesgType = eWNI_SME_DEL_STA_SELF_RSP;
+ pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeDelStaSelfRsp);
+ pRsp->status = pDelStaSelfParams->status;
+
+ palCopyMemory( pMac->hHdd, pRsp->selfMacAddr, pDelStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) );
+
+ palFreeMemory( pMac->hHdd, (tANI_U8 *)pDelStaSelfParams);
+
+ mmhMsg.type = eWNI_SME_DEL_STA_SELF_RSP;
+ mmhMsg.bodyptr = pRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+}
+
+/***************************************************************
+* tANI_U8 limUnmapChannel(tANI_U8 mapChannel)
+* To unmap the channel to reverse the effect of mapping
+* a band channel in hal .Mapping was done hal to overcome the
+* limitation of the rxbd which use only 4 bit for channel number.
+*****************************************************************/
+tANI_U8 limUnmapChannel(tANI_U8 mapChannel)
+{
+ if( mapChannel > 0 && mapChannel < 25 )
+ return abChannel[mapChannel -1];
+ else
+ return 0;
+}
+
+
+v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field)
+{
+ int left = length;
+ v_U8_t *ptr = pIes;
+ v_U8_t elem_id;
+ v_U16_t elem_len;
+
+ while(left >= (size_of_len_field+1))
+ {
+ elem_id = ptr[0];
+ if (size_of_len_field == TWO_BYTE)
+ {
+ elem_len = ((v_U16_t) ptr[1]) | (ptr[2]<<8);
+ }
+ else
+ {
+ elem_len = ptr[1];
+ }
+
+
+ left -= (size_of_len_field+1);
+ if(elem_len > left)
+ {
+ limLog(pMac, LOGE,
+ "****Invalid IEs eid = %d elem_len=%d left=%d*****\n",
+ eid,elem_len,left);
+ return NULL;
+ }
+ if (elem_id == eid)
+ {
+ return ptr;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + (size_of_len_field+1));
+ }
+ return NULL;
+}
+
+/* return NULL if oui is not found in ie
+ return !NULL pointer to vendor IE (starting from 0xDD) if oui is found
+ */
+v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len)
+{
+ int left = ie_len;
+ v_U8_t *ptr = ie;
+ v_U8_t elem_id, elem_len;
+
+ while(left >= 2)
+ {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if(elem_len > left)
+ {
+ limLog( pMac, LOGE,
+ FL("****Invalid IEs eid = %d elem_len=%d left=%d*****\n"),
+ elem_id,elem_len,left);
+ return NULL;
+ }
+ if (SIR_MAC_EID_VENDOR == elem_id)
+ {
+ if(memcmp(&ptr[2], oui, oui_size)==0)
+ return ptr;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ return NULL;
+}
+
+#ifdef WLAN_FEATURE_P2P
+//Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream
+
+v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len)
+{
+ int length = 0;
+ tANI_U8 *ptr = ie;
+
+ ptr[length++] = SIR_MAC_EID_VENDOR;
+ ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE;
+ palCopyMemory( pMac->hHdd, &ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+ palCopyMemory( pMac->hHdd, &ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len);
+ return (ie_len + SIR_P2P_IE_HEADER_LEN);
+}
+
+//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream
+
+v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen)
+{
+ v_U8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN];
+ palCopyMemory( pMac->hHdd, overFlowP2pStream, noaStream + noaLen - overFlowLen, overFlowLen);
+ noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR;
+ noaStream[noaLen - overFlowLen+1] = overFlowLen + SIR_MAC_P2P_OUI_SIZE;
+ palCopyMemory( pMac->hHdd, noaStream+ noaLen - overFlowLen+2,SIR_MAC_P2P_OUI,SIR_MAC_P2P_OUI_SIZE);
+
+ palCopyMemory( pMac->hHdd, noaStream+ noaLen - overFlowLen+2+SIR_MAC_P2P_OUI_SIZE,overFlowP2pStream,overFlowLen);
+ return (noaLen + SIR_P2P_IE_HEADER_LEN);
+
+}
+
+//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream
+v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry)
+{
+ v_U8_t len=0;
+
+ v_U8_t *pBody = pNoaStream;
+
+
+ if ( (psessionEntry != NULL) && (psessionEntry->valid) &&
+ (psessionEntry->pePersona == VOS_P2P_GO_MODE))
+ {
+ if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration)) && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration))
+ && (!psessionEntry->p2pGoPsUpdate.oppPsFlag)
+ )
+ return 0; //No NoA Descriptor then return 0
+
+
+ pBody[0] = SIR_P2P_NOA_ATTR;
+
+ pBody[3] = psessionEntry->p2pGoPsUpdate.index;
+ pBody[4] = psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->p2pGoPsUpdate.oppPsFlag<<7);
+ len = 5;
+ pBody += len;
+
+
+ if (psessionEntry->p2pGoPsUpdate.uNoa1Duration)
+ {
+ *pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt;
+ pBody += 1;
+ len +=1;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Duration);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Interval);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1StartTime);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ }
+
+ if (psessionEntry->p2pGoPsUpdate.uNoa2Duration)
+ {
+ *pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt;
+ pBody += 1;
+ len +=1;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Duration);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Interval);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2StartTime);
+ pBody += sizeof(tANI_U32);
+ len +=4;
+
+ }
+
+
+ pBody = pNoaStream + 1;
+ *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(len-3);/*one byte for Attr and 2 bytes for length*/
+
+ return (len);
+
+ }
+ return 0;
+
+}
+void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, tANI_U8 cbState)
+{
+
+ pMac->lim.gResumeChannel = channel;
+ //TODO : Save Cb State also.
+
+}
+/*--------------------------------------------------------------------------
+
+ \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session.
+
+ This function itrates the session Table and returns the channel number from first valid session
+ if no sessions are valid/present it returns zero
+
+ \param pMac - pointer to global adapter context
+ \return - channel to scan from valid session else zero.
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+
+tANI_U8 peGetResumeChannel(tpAniSirGlobal pMac)
+
+{
+
+ //Rationale - this could be the suspend/resume for assoc and it is essential that
+ //the new BSS is active for some time. Other BSS was anyway suspended.
+ //TODO: Comeup with a better alternative. Sending NULL with PM=0 on other BSS means
+ //there will be trouble. But since it is sent on current channel, it will be missed by peer
+ //and hence shpuld be ok. Need to discuss this further
+ if( !IS_MCC_SUPPORTED )
+ {
+ //Get current active session channel
+ return peGetActiveSessionChannel(pMac);
+ }
+ else
+ {
+ return pMac->lim.gResumeChannel;
+ }
+
+}
+
+#endif
+
+tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel)
+{
+ if(NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(currentChannel))
+ {
+ return eANI_BOOLEAN_TRUE;
+ }
+ else
+ {
+ return eANI_BOOLEAN_FALSE;
+ }
+}
diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h
new file mode 100644
index 0000000..548370a
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limUtils.h
@@ -0,0 +1,484 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ */
+
+/*
+ * Airgo Networks, Inc proprietary. All rights reserved.
+ * This file limUtils.h contains the utility definitions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_UTILS_H
+#define __LIM_UTILS_H
+
+#include "sirApi.h"
+#include "sirDebug.h"
+#include "cfgApi.h"
+
+#include "limTypes.h"
+#include "limScanResultUtils.h"
+#include "limTimerUtils.h"
+#include "limTrace.h"
+typedef enum
+{
+ ONE_BYTE = 1,
+ TWO_BYTE = 2
+} eSizeOfLenField;
+
+#define LIM_STA_ID_MASK 0x00FF
+#define LIM_AID_MASK 0xC000
+#define LIM_SPECTRUM_MANAGEMENT_BIT_MASK 0x0100
+
+// classifier ID is coded as 0-3: tsid, 4-5:direction
+#define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4))
+
+#define LIM_SET_STA_BA_STATE(pSta, tid, newVal) \
+{\
+ pSta->baState = ((pSta->baState | (0x3 << tid*2)) & ((newVal << tid*2) | ~(0x3 << tid*2)));\
+}
+
+#define LIM_GET_STA_BA_STATE(pSta, tid, pCurVal)\
+{\
+ *pCurVal = (tLimBAState)(((pSta->baState >> tid*2) & 0x3));\
+}
+
+#if defined( FEATURE_WLAN_INTEGRATED_SOC )
+typedef struct sAddBaInfo
+{
+ tANI_U16 fBaEnable : 1;
+ tANI_U16 startingSeqNum: 12;
+ tANI_U16 reserved : 3;
+}tAddBaInfo, *tpAddBaInfo;
+
+typedef struct sAddBaCandidate
+{
+ tSirMacAddr staAddr;
+ tAddBaInfo baInfo[STACFG_MAX_TC];
+}tAddBaCandidate, *tpAddBaCandidate;
+#endif /* FEATURE_WLAN_INTEGRATED_SOC */
+
+// LIM utilility functions
+void limGetBssidFromPkt(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U32 *);
+char * limMlmStateStr(tLimMlmStates state);
+char * limSmeStateStr(tLimSmeStates state);
+char * limMsgStr(tANI_U32 msgType);
+char * limResultCodeStr(tSirResultCodes resultCode);
+char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode);
+char* limStaOpRateModeStr(tStaRateMode opRateMode);
+void limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state);
+void limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state);
+void limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType);
+void limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg);
+char* limBssTypeStr(tSirBssType bssType);
+
+#if defined FEATURE_WLAN_CCX || defined WLAN_FEATURE_VOWIFI
+extern tSirRetStatus limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac,
+ tPowerdBm txPower,
+ tpPESession pSessionEntry );
+extern tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower);
+#endif
+
+tANI_U32 limPostMsgApiNoWait(tpAniSirGlobal, tSirMsgQ *);
+tANI_U8 limIsAddrBC(tSirMacAddr);
+tANI_U8 limIsGroupAddr(tSirMacAddr);
+
+// check for type of scan allowed
+tANI_U8 limActiveScanAllowed(tpAniSirGlobal, tANI_U8);
+
+// AID pool management functions
+void limInitAIDpool(tpAniSirGlobal,tpPESession);
+tANI_U16 limAssignAID(tpAniSirGlobal);
+
+void limEnableOverlap11gProtection(tpAniSirGlobal pMac, tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry);
+void limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams);
+void limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry);
+void limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry);
+
+/*
+ * The below 'product' check tobe removed if 'Association' is
+ * allowed in IBSS.
+ */
+void limReleaseAID(tpAniSirGlobal, tANI_U16);
+
+#if (WNI_POLARIS_FW_PRODUCT == AP)
+// LIM informs WSM that radar is detected
+void limDetectRadar(tpAniSirGlobal, tANI_U32 *);
+#endif
+
+#ifdef WLAN_SOFTAP_FEATURE
+void limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession);
+void
+limDecideApProtectionOnDelete(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry);
+#else
+void limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams);
+#endif
+
+extern tSirRetStatus limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession);
+extern tSirRetStatus limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry);
+extern tSirRetStatus limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry);
+extern tSirRetStatus limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession sessionEntry);
+extern tSirRetStatus limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession);
+extern tSirRetStatus limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry);
+extern tSirRetStatus limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession);
+#ifdef WLAN_SOFTAP_FEATURE
+extern tSirRetStatus limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry);
+#else
+extern tSirRetStatus limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams);
+#endif
+extern tSirRetStatus limEnableHtOBSSProtection (tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams, tpPESession);
+void limDecideStaProtection(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry);
+void limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry);
+void limUpdateStaRunTimeHTSwitchChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo * pHTInfo, tANI_U8 bssIdx, tpPESession psessionEntry);
+// Print MAC address utility function
+void limPrintMacAddr(tpAniSirGlobal, tSirMacAddr, tANI_U8);
+
+
+
+// Deferred Message Queue read/write
+tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac);
+void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg);
+
+// Deferred Message Queue Reset
+void limResetDeferredMsgQ(tpAniSirGlobal pMac);
+
+tSirRetStatus limSysProcessMmhMsgApi(tpAniSirGlobal, tSirMsgQ*, tANI_U8);
+
+#ifdef WLAN_SOFTAP_FEATURE
+void limHandleUpdateOlbcCache(tpAniSirGlobal pMac);
+#endif
+
+tANI_U8 limIsNullSsid( tSirMacSSid *pSsid );
+
+void limProcessAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param);
+
+// 11h Support
+#ifdef ANI_PRODUCT_TYPE_AP
+tANI_U32 computeChannelSwitchCount(tpAniSirGlobal, tANI_U32);
+#endif
+void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId);
+void limProcessChannelSwitchTimeout(tpAniSirGlobal);
+tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limUpdateChannelSwitch(tpAniSirGlobal, tpSirProbeRespBeacon, tpPESession psessionEntry);
+void limProcessQuietTimeout(tpAniSirGlobal);
+void limProcessQuietBssTimeout(tpAniSirGlobal);
+
+#ifdef WLAN_SOFTAP_FEATURE
+#if 0
+void limProcessWPSOverlapTimeout(tpAniSirGlobal pMac);
+#endif
+#endif
+
+void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId);
+void limUpdateQuietIEFromBeacon(tpAniSirGlobal, tDot11fIEQuiet *, tpPESession);
+void limGetHtCbAdminState(tpAniSirGlobal pMac, tDot11fIEHTCaps htCaps, tANI_U8 * titanHtCaps);
+void limGetHtCbOpState(tpAniSirGlobal pMac, tDot11fIEHTInfo htInfo, tANI_U8 * titanHtCaps);
+void limSwitchPrimaryChannel(tpAniSirGlobal, tANI_U8,tpPESession);
+void limSwitchPrimarySecondaryChannel(tpAniSirGlobal, tANI_U8, tAniCBSecondaryMode);
+tAniBool limTriggerBackgroundScanDuringQuietBss(tpAniSirGlobal);
+void limUpdateStaRunTimeHTSwtichChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo *pRcvdHTInfo, tANI_U8 bssIdx);
+void limUpdateStaRunTimeHTCapability(tpAniSirGlobal pMac, tDot11fIEHTCaps *pHTCaps);
+void limUpdateStaRunTimeHTInfo(struct sAniSirGlobal *pMac, tDot11fIEHTInfo *pRcvdHTInfo, tpPESession psessionEntry);
+void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry);
+tAniBool limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel);
+void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode);
+tSirRetStatus limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry);
+tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac);
+
+void limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status,
+ tANI_U32 *data, tpPESession psessionEntry);
+
+static inline tSirRFBand limGetRFBand(tANI_U8 channel)
+{
+ if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+ (channel <= SIR_11A_CHANNEL_END))
+ return SIR_BAND_5_GHZ;
+
+ if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
+ (channel <= SIR_11B_CHANNEL_END))
+ return SIR_BAND_2_4_GHZ;
+
+ return SIR_BAND_UNKNOWN;
+}
+
+
+static inline tSirRetStatus
+limGetMgmtStaid(tpAniSirGlobal pMac, tANI_U16 *staid, tpPESession psessionEntry)
+{
+ if (psessionEntry->limSystemRole == eLIM_AP_ROLE)
+ *staid = 1;
+ else if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
+ *staid = 0;
+ else
+ return eSIR_FAILURE;
+
+ return eSIR_SUCCESS;
+}
+
+static inline tANI_U8
+limIsSystemInSetMimopsState(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gLimMlmState == eLIM_MLM_WT_SET_MIMOPS_STATE)
+ return true;
+ return false;
+}
+
+static inline tANI_U8
+ isEnteringMimoPS(tSirMacHTMIMOPowerSaveState curState, tSirMacHTMIMOPowerSaveState newState)
+ {
+ if (curState == eSIR_HT_MIMO_PS_NO_LIMIT &&
+ (newState == eSIR_HT_MIMO_PS_DYNAMIC ||newState == eSIR_HT_MIMO_PS_STATIC))
+ return TRUE;
+ return FALSE;
+}
+
+/// ANI peer station count management and associated actions
+void limUtilCountStaAdd(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry);
+void limUtilCountStaDel(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry);
+
+#ifdef WLAN_SOFTAP_FEATURE
+tANI_U8 limGetHTCapability( tpAniSirGlobal, tANI_U32, tpPESession);
+#else
+tANI_U8 limGetHTCapability( tpAniSirGlobal, tANI_U32 );
+#endif
+void limTxComplete( tHalHandle hHal, void *pData );
+
+/**********Admit Control***************************************/
+
+//callback function for HAL to issue DelTS request to PE.
+//This function will be registered with HAL for callback when TSPEC inactivity timer fires.
+
+void limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 mesgId, void *mesgParam );
+tSirRetStatus limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry);
+/**********************************************************/
+
+//callback function registration to HAL for any indication.
+void limRegisterHalIndCallBack(tpAniSirGlobal pMac);
+void limPktFree (
+ tpAniSirGlobal pMac,
+ eFrameType frmType,
+ tANI_U8 *pBD,
+ void *body);
+
+
+
+void limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pBD);
+
+/**
+ * \brief Given a base(X) and power(Y), this API will return
+ * the result of base raised to power - (X ^ Y)
+ *
+ * \sa utilsPowerXY
+ *
+ * \param base Base value
+ *
+ * \param power Base raised to this Power value
+ *
+ * \return Result of X^Y
+ *
+ */
+static inline tANI_U32 utilsPowerXY( tANI_U16 base, tANI_U16 power )
+{
+tANI_U32 result = 1, i;
+
+ for( i = 0; i < power; i++ )
+ result *= base;
+
+ return result;
+}
+
+
+
+tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry);
+tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirMacStatusCodes baStatusCode,
+ tANI_U8 baDialogToken,
+ tANI_U8 baTID,
+ tANI_U8 baPolicy,
+ tANI_U16 baBufferSize,
+ tANI_U16 baTimeout,
+ tpPESession psessionEntry);
+tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baDirection,
+ tANI_U8 baTID,
+ tSirMacReasonCodes baReasonCode ,
+ tpPESession psessionEntry);
+tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baDialogToken,
+ tANI_U8 baTID,
+ tANI_U8 baPolicy,
+ tANI_U16 baBufferSize,
+ tANI_U16 baTimeout,
+ tANI_U16 baSSN,
+ tANI_U8 baDirection,
+ tpPESession psessionEntry);
+tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tANI_U8 baTID,
+ tANI_U8 baDirection,
+ tpPESession psessionEntry);
+
+tSirRetStatus limPostSMStateUpdate(tpAniSirGlobal pMac,
+ tANI_U16 StaIdx,
+ tSirMacHTMIMOPowerSaveState MIMOPSState);
+
+void limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+void limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+void limDelAllBASessions(tpAniSirGlobal pMac);
+void limDeleteDialogueTokenList(tpAniSirGlobal pMac);
+tSirRetStatus limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid);
+void limRessetScanChannelInfo(tpAniSirGlobal pMac);
+void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId);
+
+tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon);
+tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon);
+void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action);
+void limHandleHeartBeatTimeout(tpAniSirGlobal pMac);
+//void limProcessBtampAddBssRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ,tpPESession peSession);
+void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ);
+
+void limUpdateBeacon(tpAniSirGlobal pMac);
+
+void limProcessBtAmpApMlmAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ, tpPESession psessionEntry);
+void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry);
+
+void limProcessBtAmpApMlmDelStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ,tpPESession psessionEntry);
+tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac);
+tpPESession limIsApSessionActive(tpAniSirGlobal pMac);
+void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac);
+
+void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ);
+void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ);
+v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field);
+
+tANI_U8 limUnmapChannel(tANI_U8 mapChannel);
+
+#define limGetWscIEPtr(pMac, ie, ie_len) \
+ limGetVendorIEOuiPtr(pMac, SIR_MAC_WSC_OUI, SIR_MAC_WSC_OUI_SIZE, ie, ie_len)
+
+#ifdef WLAN_FEATURE_P2P
+#define limGetP2pIEPtr(pMac, ie, ie_len) \
+ limGetVendorIEOuiPtr(pMac, SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, ie, ie_len)
+
+v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen);
+v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry);
+
+v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len);
+#endif
+v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len);
+tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel);
+tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+
+typedef enum
+{
+ WLAN_PE_DIAG_SCAN_REQ_EVENT = 0,
+ WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT,
+ WLAN_PE_DIAG_SCAN_RSP_EVENT,
+ WLAN_PE_DIAG_JOIN_REQ_EVENT,
+ WLAN_PE_DIAG_JOIN_RSP_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+ WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_REQ_EVENT,
+ WLAN_PE_DIAG_AUTH_RSP_EVENT,
+ WLAN_PE_DIAG_DISASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+ WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_IND_EVENT,
+ WLAN_PE_DIAG_ASSOC_IND_EVENT,
+ WLAN_PE_DIAG_ASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_REASSOC_IND_EVENT,
+ WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT,
+ WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+ WLAN_PE_DIAG_ADDTS_REQ_EVENT,
+ WLAN_PE_DIAG_ADDTS_RSP_EVENT,
+ WLAN_PE_DIAG_DELTS_REQ_EVENT,
+ WLAN_PE_DIAG_DELTS_RSP_EVENT,
+ WLAN_PE_DIAG_DELTS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT,
+ WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT,
+ WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT,
+ WLAN_PE_DIAG_HAL_DELBA_IND_EVENT,
+}WLAN_PE_DIAG_EVENT_TYPE;
+
+void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, tANI_U8 cbState);
+/*--------------------------------------------------------------------------
+
+ \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session.
+
+ This function itrates the session Table and returns the channel number from first valid session
+ if no sessions are valid it returns 0
+
+ \param pMac - pointer to global adapter context
+ \return - channel to scan from valid session else zero.
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+tANI_U8 peGetResumeChannel(tpAniSirGlobal pMac);
+
+
+#endif /* __LIM_UTILS_H */