| /* |
| * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| /* |
| * 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" |
| |
| #include "wni_cfg.h" |
| #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" |
| #ifdef WLAN_FEATURE_VOWIFI_11R |
| #include "limFTDefs.h" |
| #endif |
| #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 (vos_mem_compare((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 ((LIM_IS_AP_ROLE(psessionEntry)|| |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) && |
| (pAssocReq->capabilityInfo.ibss)) { |
| // Requesting STA asserting IBSS capability. |
| limLog(pMac, LOG1,FL("Requesting STA asserting IBSS capability")); |
| return false; |
| } |
| |
| // Compare CF capabilities |
| if (pAssocReq->capabilityInfo.cfPollable || |
| pAssocReq->capabilityInfo.cfPollReq) |
| { |
| // AP does not support PCF functionality |
| limLog(pMac, LOG1,FL(" AP does not support PCF functionality")); |
| return false; |
| } |
| |
| // Compare short preamble capability |
| if (pAssocReq->capabilityInfo.shortPreamble && |
| (pAssocReq->capabilityInfo.shortPreamble != |
| pLocalCapabs->shortPreamble)) |
| { |
| // Allowing a STA requesting short preamble while |
| // AP does not support it |
| } |
| |
| |
| limLog(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d", |
| 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")); |
| } |
| else |
| { |
| // AP does not support QoS capability |
| limLog(pMac, LOG1, FL("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 ((LIM_IS_AP_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) && |
| (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 ")); |
| return false; |
| } |
| if(val) |
| { |
| if (pAssocReq->capabilityInfo.shortSlotTime != pLocalCapabs->shortSlotTime) |
| { |
| limLog(pMac, LOGE, |
| FL("AP rejects association as station doesnt support shortslot time")); |
| return false; |
| } |
| 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; |
| |
| pRateSet = vos_mem_malloc(sizeof(tSirMacRateSet)); |
| if (NULL == pRateSet) |
| { |
| limLog(pMac, LOGP, FL("call to AllocateMemory failed for RATESET")); |
| |
| return false; |
| } |
| |
| /* Copy operational rate set from session Entry */ |
| vos_mem_copy(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 < SIR_MAC_RATESET_EID_MAX)) ; 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 < SIR_MAC_RATESET_EID_MAX)); i++) |
| { |
| if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k]) |
| match = 1; |
| } |
| |
| if (!match) |
| { |
| // Free up memory allocated for rateset |
| vos_mem_free((tANI_U8 *)pRateSet); |
| |
| return false; |
| } |
| } |
| |
| // Free up memory allocated for rateset |
| vos_mem_free((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")); |
| 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]) |
| { |
| //Log is avaiable in calling function in file limProcessAssocReqFrame.c |
| 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)) |
| { |
| limLog(pMac, LOGW, |
| FL("One of Basic MCS Set Rates is not supported by the Station.")); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| #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, tANI_BOOLEAN *pmfConnection) |
| { |
| tDot11fIERSN *pRSNIe; |
| tANI_U8 i, j, match, onlyNonHtCipher = 1; |
| #ifdef WLAN_FEATURE_11W |
| tANI_BOOLEAN weArePMFCapable; |
| tANI_BOOLEAN weRequirePMF; |
| tANI_BOOLEAN theyArePMFCapable; |
| tANI_BOOLEAN theyRequirePMF; |
| #endif |
| |
| |
| //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]) |
| { |
| limLog(pMac, LOG3, FL("Invalid groupwise cipher suite")); |
| 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 (vos_mem_compare(&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)) |
| { |
| limLog(pMac, LOG1, FL("Invalid pairwise cipher suite")); |
| return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS; |
| } |
| /* Check RSN capabilities |
| * Bit 0 of First Byte - PreAuthentication Capability |
| */ |
| if(((rxRSNIe.RSN_Cap[0] >> 0) & 0x1) == true) //this is supported by AP only |
| { |
| limLog(pMac, LOG1, FL("Invalid RSN information element capabilities")); |
| return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS; |
| } |
| |
| *pmfConnection = eANI_BOOLEAN_FALSE; |
| |
| #ifdef WLAN_FEATURE_11W |
| weArePMFCapable = pSessionEntry->pLimStartBssReq->pmfCapable; |
| weRequirePMF = pSessionEntry->pLimStartBssReq->pmfRequired; |
| theyArePMFCapable = (rxRSNIe.RSN_Cap[0] >> 7) & 0x1; |
| theyRequirePMF = (rxRSNIe.RSN_Cap[0] >> 6) & 0x1; |
| |
| if ((theyRequirePMF && theyArePMFCapable && !weArePMFCapable) || |
| (weRequirePMF && !theyArePMFCapable)) |
| { |
| limLog(pMac, LOG1, FL("Association fail, robust management frames " |
| "policy violation theyRequirePMF =%d theyArePMFCapable %d " |
| "weArePMFCapable %d weRequirePMF %d theyArePMFCapable %d"), |
| theyRequirePMF,theyArePMFCapable,weArePMFCapable,weRequirePMF, |
| theyArePMFCapable); |
| return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION; |
| } |
| |
| if(theyArePMFCapable && weArePMFCapable) |
| *pmfConnection = eANI_BOOLEAN_TRUE; |
| |
| limLog(pMac, LOG1, FL("weAreCapable %d, weRequire %d, theyAreCapable %d, " |
| "theyRequire %d, PMFconnection %d"), |
| weArePMFCapable, weRequirePMF, theyArePMFCapable, theyRequirePMF, *pmfConnection); |
| #endif |
| |
| 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]) |
| { |
| limLog(pMac, LOG1, FL("Invalid groupwise cipher suite")); |
| 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 (vos_mem_compare(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)) |
| { |
| limLog(pMac, LOG1, FL("Invalid pairwise cipher suite")); |
| return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS; |
| } |
| |
| return eSIR_SUCCESS; |
| } /****** end limCheckRxWPAIeMatch() ******/ |
| |
| |
| /** |
| * 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; |
| |
| |
| limLog( pMac, LOG1, FL("Cleanup Rx Path for AID : %d" |
| "psessionEntry->limSmeState : %d, mlmState : %d"), |
| pStaDs->assocId, psessionEntry->limSmeState, |
| pStaDs->mlmStaContext.mlmState); |
| |
| limAbortBackgroundScan( pMac ); |
| psessionEntry->isCiscoVendorAP = FALSE; |
| |
| if (pMac->lim.gLimAddtsSent) |
| { |
| MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, 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 to delete. |
| * Release our assigned AID back to the free pool |
| */ |
| if (LIM_IS_AP_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) { |
| limDelSta(pMac, pStaDs, false, psessionEntry); |
| limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); |
| } |
| limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry); |
| return retCode; |
| } |
| } |
| |
| //delete all tspecs associated with this sta. |
| limAdmitControlDeleteSta(pMac, pStaDs->assocId); |
| |
| |
| /** |
| * 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 (LIM_IS_STA_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); |
| psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; |
| /* Deactivating probe after heart beat timer */ |
| limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); |
| limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); |
| limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); |
| limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER); |
| pMac->lim.gLastBeaconDtimCount = 0; |
| pMac->lim.gLastBeaconDtimPeriod = 0; |
| |
| #ifdef FEATURE_WLAN_ESE |
| #ifdef FEATURE_WLAN_ESE_UPLOAD |
| limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); |
| #else |
| limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); |
| #endif /* FEATURE_WLAN_ESE_UPLOAD */ |
| #endif |
| |
| /** |
| * Update the status for PMM module |
| */ |
| pmmResetPmmState(pMac); |
| } |
| #ifdef WLAN_DEBUG |
| // increment a debug count |
| pMac->lim.gLimNumRxCleanup++; |
| #endif |
| /* Do DEL BSS or DEL STA only if ADD BSS was success */ |
| if (!psessionEntry->add_bss_failed) { |
| 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; |
| |
| limLog(pMac, LOG1, FL("Sessionid: %d staDsAssocId: %d Trigger: %d " |
| "statusCode: %d staDsAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, |
| staDsAssocId, mlmStaContext.cleanupTrigger, statusCode, |
| MAC_ADDR_ARRAY(staDsAddr)); |
| |
| if (LIM_IS_STA_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { |
| // Set BSSID at CFG to null |
| tSirMacAddr nullAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| |
| sirCopyMacAddr(nullAddr,psessionEntry->bssId); |
| |
| // Free up buffer allocated for JoinReq held by |
| // MLM state machine |
| if (psessionEntry->pLimMlmJoinReq) |
| { |
| vos_mem_free(psessionEntry->pLimMlmJoinReq); |
| psessionEntry->pLimMlmJoinReq = NULL; |
| } |
| |
| psessionEntry->limAID = 0; |
| } |
| |
| if ((mlmStaContext.cleanupTrigger == |
| eLIM_HOST_DISASSOC) || |
| (mlmStaContext.cleanupTrigger == |
| eLIM_PROMISCUOUS_MODE_DISASSOC) || |
| (mlmStaContext.cleanupTrigger == |
| eLIM_LINK_MONITORING_DISASSOC)) |
| { |
| /** |
| * Host or LMM driven Disassociation. |
| * Issue Disassoc Confirm to SME. |
| */ |
| limLog( pMac, LOGW, FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"), |
| mlmStaContext.cleanupTrigger); |
| |
| |
| vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr, |
| (tANI_U8 *) staDsAddr, |
| sizeof(tSirMacAddr)); |
| mlmDisassocCnf.resultCode = statusCode; |
| 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: %d"), |
| mlmStaContext.cleanupTrigger); |
| vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr, |
| (tANI_U8 *) staDsAddr, |
| sizeof(tSirMacAddr)); |
| mlmDeauthCnf.resultCode = statusCode; |
| 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: %d"), |
| mlmStaContext.cleanupTrigger) ; |
| vos_mem_copy((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; |
| tLimSmeStates tempLimSmeState = eLIM_SME_IDLE_STATE; |
| |
| smesessionId = psessionEntry->smeSessionId; |
| smetransactionId = psessionEntry->transactionId; |
| tempLimSmeState = psessionEntry->limSmeState; |
| |
| psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; |
| MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); |
| |
| //if it is a reassoc failure to join new AP |
| //eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA result code is used |
| //during assoc and reassoc, so sme state req to distinguish them |
| if((mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE) || |
| (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE) || |
| (mlmStaContext.resultCode == eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE) || |
| (mlmStaContext.resultCode == eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA && |
| tempLimSmeState == eLIM_SME_WT_REASSOC_STATE) |
| ) |
| { |
| limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_REASSOC_RSP to SME" |
| "resultCode: %d, statusCode: %d," |
| "sessionId: %d"), |
| mlmStaContext.resultCode, |
| mlmStaContext.protStatusCode, |
| psessionEntry->peSessionId); |
| |
| limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, |
| mlmStaContext.resultCode, mlmStaContext.protStatusCode, psessionEntry, |
| smesessionId, smetransactionId); |
| if(mlmStaContext.resultCode != eSIR_SME_SUCCESS ) |
| { |
| peDeleteSession(pMac, psessionEntry); |
| psessionEntry = NULL; |
| } |
| } |
| else |
| { |
| vos_mem_free(psessionEntry->pLimJoinReq); |
| psessionEntry->pLimJoinReq = NULL; |
| |
| limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_JOIN_RSP to SME." |
| "resultCode: %d,statusCode: %d," |
| "sessionId: %d"), |
| mlmStaContext.resultCode, |
| mlmStaContext.protStatusCode, |
| psessionEntry->peSessionId); |
| |
| |
| limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, |
| mlmStaContext.resultCode, |
| mlmStaContext.protStatusCode, |
| psessionEntry, smesessionId, |
| smetransactionId); |
| if(mlmStaContext.resultCode != eSIR_SME_SUCCESS) |
| { |
| peDeleteSession(pMac,psessionEntry); |
| psessionEntry = NULL; |
| } |
| } |
| |
| } |
| |
| if ((NULL != psessionEntry) && (!LIM_IS_AP_ROLE(psessionEntry))) { |
| 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 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 |
| * @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; |
| |
| limLog(pMac, LOG1, FL("Sessionid: %d authType: %d subType: %d " |
| "addPreAuthContext: %d staId: %d deleteSta: %d rCode : %d " |
| "peerAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, |
| authType, subType, addPreAuthContext, staId, deleteSta, rCode, |
| MAC_ADDR_ARRAY(peerAddr)); |
| |
| if (addPreAuthContext) |
| { |
| // Create entry for this STA in pre-auth list |
| struct tLimPreAuthNode *pAuthNode; |
| |
| pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); |
| |
| if (pAuthNode) |
| { |
| vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, |
| peerAddr, |
| sizeof(tSirMacAddr)); |
| pAuthNode->fTimerStarted = 0; |
| pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE; |
| pAuthNode->authType = (tAniAuthType) authType; |
| pAuthNode->timestamp = vos_timer_get_system_ticks(); |
| 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")); |
| |
| return; |
| } |
| |
| /** |
| * 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) |
| { |
| vos_mem_free(((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); |
| ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; |
| } |
| vos_mem_free(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 ")); |
| limPrintMacAddr(pMac, peerAddr, LOGW); |
| limSendSmeMaxAssocExceededNtf(pMac, peerAddr, psessionEntry->smeSessionId); |
| } |
| } /*** end limRejectAssociation() ***/ |
| |
| |
| /** ------------------------------------------------------------- |
| \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 (vos_mem_compare(psessionEntry->protStaCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLimHt20Params.numSta--; |
| psessionEntry->protStaCache[i].active = false; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (psessionEntry->gLimHt20Params.numSta == 0) |
| { |
| // disable protection |
| limLog(pMac, LOG1, FL("No 11B STA exists, PESessionID %d"), |
| psessionEntry->peSessionId); |
| 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->htCapability) |
| { |
| //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 (vos_mem_compare( psessionEntry->protStaCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLim11aParams.numSta--; |
| 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->htCapability) && |
| (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 (vos_mem_compare( psessionEntry->protStaCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLim11bParams.numSta--; |
| psessionEntry->protStaCache[i].active = false; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (psessionEntry->gLim11bParams.numSta == 0) |
| { |
| // disable protection |
| limEnable11gProtection(pMac, false, false, pBeaconParams,psessionEntry); |
| } |
| } |
| //(non-11B station is leaving) or (we are not 11G or HT AP) |
| else if(psessionEntry->htCapability) |
| { //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 (vos_mem_compare( 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->htCapability) && |
| (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 (vos_mem_compare( psessionEntry->protStaCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLimNonGfParams.numSta--; |
| 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 (vos_mem_compare( psessionEntry->protStaCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLimLsigTxopParams.numSta--; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (psessionEntry->gLimLsigTxopParams.numSta == 0) |
| { |
| // disable protection |
| limEnableHTLsigTxopProtection(pMac, true, false, pBeaconParams,psessionEntry); |
| } |
| } |
| } |
| } |
| |
| |
| |
| /** ------------------------------------------------------------- |
| \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 (vos_mem_compare( 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 |
| //reset the cache |
| vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortParams, |
| sizeof(tLimNoShortParams), 0); |
| if (limEnableShortPreamble(pMac, true, pBeaconParams, psessionEntry) != eSIR_SUCCESS) |
| PELOGE(limLog(pMac, LOGE, FL("Cannot enable short preamble"));) |
| } |
| } |
| } |
| |
| /** ------------------------------------------------------------- |
| \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);) |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) && |
| psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta > 0) { |
| for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++) |
| { |
| if (psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active) |
| { |
| if (vos_mem_compare(psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, |
| pStaDs->staAddr, sizeof(tSirMacAddr))) |
| { |
| psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta--; |
| psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = false; |
| break; |
| } |
| } |
| } |
| } else { |
| if (pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta> 0) |
| { |
| for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++) |
| { |
| if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) |
| { |
| if (vos_mem_compare(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); |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) && |
| (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta == 0)) { |
| // enable short slot time |
| //reset the cache |
| vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortSlotParams, |
| sizeof(tLimNoShortSlotParams), 0); |
| // in case of AP set SHORT_SLOT_TIME to enable |
| pBeaconParams->fShortSlotTime = true; |
| pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; |
| psessionEntry->shortSlotTimeSupported = true; |
| } else { |
| if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta == 0) { |
| // enable short slot time |
| //reset the cache |
| vos_mem_set((tANI_U8 *)&pMac->lim.gLimNoShortSlotParams, |
| sizeof(tLimNoShortSlotParams), 0); |
| // in case of AP set SHORT_SLOT_TIME to enable |
| if (LIM_IS_AP_ROLE(psessionEntry)) { |
| pBeaconParams->fShortSlotTime = true; |
| pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; |
| psessionEntry->shortSlotTimeSupported = true; |
| } |
| } |
| } |
| } |
| } |
| |
| void |
| limPostReassocFailure(tpAniSirGlobal pMac, |
| tSirResultCodes resultCode, |
| tANI_U16 protStatusCode,tpPESession psessionEntry) |
| { |
| tLimMlmReassocCnf mlmReassocCnf; |
| |
| psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); |
| |
| // 'Change' timer for future activations |
| limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); |
| |
| mlmReassocCnf.resultCode = resultCode; |
| mlmReassocCnf.protStatusCode = protStatusCode; |
| /* Update PE session Id */ |
| mlmReassocCnf.sessionId = psessionEntry->peSessionId; |
| limPostSmeMessage(pMac, |
| LIM_MLM_REASSOC_CNF, |
| (tANI_U32 *) &mlmReassocCnf); |
| } /*** end limPostReassocFailure() ***/ |
| |
| /** |
| * 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 at 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, secChanOffset; |
| tLimMlmReassocCnf mlmReassocCnf; |
| |
| limLog(pMac, LOG1, FL("sessionid: %d protStatusCode: %d resultCode: %d"), |
| psessionEntry->smeSessionId, protStatusCode, resultCode); |
| |
| psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); |
| |
| // 'Change' timer for future activations |
| limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); |
| |
| /* To support BT-AMP */ |
| chanNum = psessionEntry->currentOperChannel; |
| secChanOffset = psessionEntry->htSecondaryChannelOffset; |
| |
| limSetChannel(pMac, chanNum, secChanOffset, 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 == NULL) |
| { |
| return eANI_BOOLEAN_FALSE; |
| } |
| if ((LIM_IS_STA_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) && |
| ((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() ***/ |
| |
| #ifdef WLAN_FEATURE_11AC |
| tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, |
| tpSirSupportedRates pRates, |
| tDot11fIEVHTCaps *pPeerVHTCaps, |
| tpPESession psessionEntry, |
| uint8_t nss) |
| { |
| tANI_U32 val; |
| tANI_U32 selfStaDot11Mode=0; |
| wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); |
| |
| if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) |
| { |
| if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_MCS_MAP,&val) != |
| eSIR_SUCCESS ) |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX MCS MAP"));) |
| goto error; |
| } |
| pRates->vhtRxMCSMap = (tANI_U16)val; |
| |
| if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_MCS_MAP,&val ) != |
| eSIR_SUCCESS ) |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT TX MCS MAP"));) |
| goto error; |
| } |
| pRates->vhtTxMCSMap = (tANI_U16)val; |
| |
| if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != |
| eSIR_SUCCESS ) |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) |
| goto error; |
| } |
| pRates->vhtRxHighestDataRate = (tANI_U16)val; |
| |
| if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != |
| eSIR_SUCCESS ) |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) |
| goto error; |
| } |
| pRates->vhtTxHighestDataRate = (tANI_U16)val; |
| |
| if (NSS_1x1_MODE == nss) { |
| pRates->vhtRxMCSMap |= VHT_MCS_1x1; |
| pRates->vhtTxMCSMap |= VHT_MCS_1x1; |
| pRates->vhtTxHighestDataRate = |
| VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1; |
| pRates->vhtRxHighestDataRate = |
| VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1; |
| } |
| |
| if( pPeerVHTCaps != NULL) |
| { |
| tANI_U16 mcsMapMask = MCSMAPMASK1x1; |
| tANI_U16 mcsMapMask2x2 = 0; |
| pRates->vhtTxHighestDataRate = SIR_MIN(pRates->vhtTxHighestDataRate, pPeerVHTCaps->txSupDataRate); |
| pRates->vhtRxHighestDataRate = SIR_MIN(pRates->vhtRxHighestDataRate, pPeerVHTCaps->rxHighSupDataRate); |
| |
| if (!pMac->per_band_chainmask_supp) { |
| if (pMac->roam.configParam.enable2x2) { |
| if (psessionEntry) { |
| if ((pMac->lteCoexAntShare) && (IS_24G_CH( |
| psessionEntry->currentOperChannel))) { |
| if (IS_2X2_CHAIN(psessionEntry->chainMask)) |
| mcsMapMask2x2 = MCSMAPMASK2x2; |
| else |
| limLog(pMac, LOGE,FL( |
| "2x2 not enabled %d"), |
| psessionEntry->chainMask); |
| } else { |
| mcsMapMask2x2 = MCSMAPMASK2x2; |
| } |
| } else { |
| mcsMapMask2x2 = MCSMAPMASK2x2; |
| } |
| } |
| } else { |
| if (psessionEntry && (psessionEntry->vdev_nss == NSS_2x2_MODE)) |
| mcsMapMask2x2 = MCSMAPMASK2x2; |
| } |
| |
| if ((pPeerVHTCaps->txMCSMap & mcsMapMask) < (pRates->vhtRxMCSMap & mcsMapMask)) { |
| pRates->vhtRxMCSMap &= ~(mcsMapMask); |
| pRates->vhtRxMCSMap |= (pPeerVHTCaps->txMCSMap & mcsMapMask); |
| } |
| if ((pPeerVHTCaps->rxMCSMap & mcsMapMask) < (pRates->vhtTxMCSMap & mcsMapMask)) { |
| pRates->vhtTxMCSMap &= ~(mcsMapMask); |
| pRates->vhtTxMCSMap |= (pPeerVHTCaps->rxMCSMap & mcsMapMask); |
| } |
| |
| if (mcsMapMask2x2) { |
| |
| tANI_U16 peerMcsMap, selfMcsMap; |
| |
| peerMcsMap = pPeerVHTCaps->txMCSMap & mcsMapMask2x2; |
| selfMcsMap = pRates->vhtRxMCSMap & mcsMapMask2x2; |
| |
| if ((selfMcsMap != mcsMapMask2x2) && |
| ((peerMcsMap == mcsMapMask2x2) || |
| (peerMcsMap < selfMcsMap))) { |
| pRates->vhtRxMCSMap &= ~mcsMapMask2x2; |
| pRates->vhtRxMCSMap |= peerMcsMap; |
| } |
| |
| peerMcsMap = (pPeerVHTCaps->rxMCSMap & mcsMapMask2x2); |
| selfMcsMap = (pRates->vhtTxMCSMap & mcsMapMask2x2); |
| |
| if ((selfMcsMap != mcsMapMask2x2) && |
| ((peerMcsMap == mcsMapMask2x2) || |
| (peerMcsMap < selfMcsMap))) { |
| pRates->vhtTxMCSMap &= ~mcsMapMask2x2; |
| pRates->vhtTxMCSMap |= peerMcsMap; |
| } |
| } |
| |
| limLog(pMac, LOG1, FL( |
| "enable2x2 %d nss %d vhtRxMCSMap %x vhtTxMCSMap %x\n"), |
| pMac->roam.configParam.enable2x2, nss, |
| pRates->vhtRxMCSMap, pRates->vhtTxMCSMap); |
| |
| /* Check if VHT caps present to determine session NSS */ |
| if ((psessionEntry) && (pPeerVHTCaps->present)) { |
| psessionEntry->supported_nss_1x1 = |
| ((pRates->vhtTxMCSMap & VHT_MCS_1x1) == |
| VHT_MCS_1x1) ? true : false; |
| limLog(pMac, LOG1, FL("VHT supported nss 1x1 : %d "), |
| psessionEntry->supported_nss_1x1); |
| } |
| } |
| } |
| return eSIR_SUCCESS; |
| error: |
| |
| return eSIR_FAILURE; |
| |
| } |
| #endif |
| |
| /** |
| * 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 |
| * |
| */ |
| #ifdef WLAN_FEATURE_11AC |
| tSirRetStatus |
| limPopulateOwnRateSet(tpAniSirGlobal pMac, |
| tpSirSupportedRates pRates, |
| tANI_U8* pSupportedMCSSet, |
| tANI_U8 basicOnly, |
| tpPESession psessionEntry, |
| tDot11fIEVHTCaps *pVHTCaps) |
| #else |
| tSirRetStatus |
| limPopulateOwnRateSet(tpAniSirGlobal pMac, |
| tpSirSupportedRates pRates, |
| tANI_U8* pSupportedMCSSet, |
| tANI_U8 basicOnly, |
| tpPESession psessionEntry) |
| #endif |
| |
| { |
| tSirMacRateSet tempRateSet; |
| tSirMacRateSet tempRateSet2; |
| tANI_U32 i,j,val,min,isArate; |
| tANI_U32 phyMode = 0; |
| tANI_U32 selfStaDot11Mode=0; |
| |
| isArate = 0; |
| |
| wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); |
| limGetPhyMode(pMac, &phyMode, psessionEntry); |
| |
| /* Include 11b rates only when the device configured in |
| auto, 11a/b/g or 11b_only */ |
| if ( (selfStaDot11Mode == WNI_CFG_DOT11_MODE_ALL) || |
| (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11A) || |
| (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11AC) || |
| (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11N) || |
| (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11G) || |
| (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11B) ) |
| { |
| val = WNI_CFG_SUPPORTED_RATES_11B_LEN; |
| wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11B, |
| (tANI_U8 *)&tempRateSet.rate, &val ); |
| tempRateSet.numRates = (tANI_U8) val; |
| } |
| else |
| tempRateSet.numRates = 0; |
| |
| /* Include 11a rates when the device configured in non-11b mode */ |
| if (!IS_DOT11_MODE_11B(selfStaDot11Mode)) |
| { |
| val = WNI_CFG_SUPPORTED_RATES_11A_LEN; |
| wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11A, |
| (tANI_U8 *)&tempRateSet2.rate, &val ); |
| tempRateSet2.numRates = (tANI_U8) val; |
| } |
| 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")); |
| //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; |
| |
| vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); |
| for(i = 0;i < tempRateSet.numRates; i++) |
| { |
| min = 0; |
| val = 0xff; |
| isArate = 0; |
| for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); 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(selfStaDot11Mode)) |
| { |
| 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"));) |
| goto error; |
| } |
| |
| if (psessionEntry->vdev_nss == NSS_1x1_MODE) |
| pRates->supportedMCSSet[1] = 0; |
| |
| //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: "));) |
| for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) |
| PELOG2(limLog(pMac, LOG2,FL("%x ") , pRates->supportedMCSSet[i]);) |
| } |
| |
| #ifdef WLAN_FEATURE_11AC |
| limPopulateVhtMcsSet(pMac, pRates , pVHTCaps, psessionEntry, |
| psessionEntry->vdev_nss); |
| #endif |
| |
| return eSIR_SUCCESS; |
| |
| error: |
| |
| return eSIR_FAILURE; |
| } /*** limPopulateOwnRateSet() ***/ |
| |
| #ifdef WLAN_FEATURE_11AC |
| tSirRetStatus |
| limPopulatePeerRateSet(tpAniSirGlobal pMac, |
| |
| tpSirSupportedRates pRates, |
| tANI_U8* pSupportedMCSSet, |
| tANI_U8 basicOnly, |
| tpPESession psessionEntry, |
| tDot11fIEVHTCaps *pVHTCaps) |
| #else |
| tSirRetStatus |
| limPopulatePeerRateSet(tpAniSirGlobal pMac, |
| tpSirSupportedRates pRates, |
| tANI_U8* pSupportedMCSSet, |
| tANI_U8 basicOnly, |
| tpPESession psessionEntry) |
| #endif |
| { |
| tSirMacRateSet tempRateSet; |
| tSirMacRateSet tempRateSet2; |
| tANI_U32 i,j,val,min,isArate; |
| isArate = 0; |
| |
| /* copy operational rate set from psessionEntry */ |
| if ( psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX ) |
| { |
| vos_mem_copy((tANI_U8 *)tempRateSet.rate, |
| (tANI_U8*)(psessionEntry->rateSet.rate), |
| psessionEntry->rateSet.numRates); |
| tempRateSet.numRates = psessionEntry->rateSet.numRates; |
| } |
| else |
| { |
| limLog(pMac, LOGE, FL("more than SIR_MAC_RATESET_EID_MAX rates\n")); |
| goto error; |
| } |
| if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) || |
| (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) || |
| (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC) || |
| (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N)) |
| { |
| |
| if (psessionEntry->extRateSet.numRates <= SIR_MAC_RATESET_EID_MAX) |
| { |
| vos_mem_copy((tANI_U8 *)tempRateSet2.rate, |
| (tANI_U8*)(psessionEntry->extRateSet.rate), |
| psessionEntry->extRateSet.numRates); |
| tempRateSet2.numRates = psessionEntry->extRateSet.numRates; |
| } |
| else { |
| limLog(pMac, LOGE, FL("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n")); |
| goto error; |
| } |
| } |
| else |
| tempRateSet2.numRates = 0; |
| if ((tempRateSet.numRates + tempRateSet2.numRates) > SIR_MAC_RATESET_EID_MAX) |
| { |
| //we are in big trouble |
| limLog(pMac, LOGP, FL("more than 12 rates in CFG")); |
| 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; |
| vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); |
| for(i = 0;i < tempRateSet.numRates; i++) |
| { |
| min = 0; |
| val = 0xff; |
| isArate = 0; |
| for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); 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"));) |
| goto error; |
| } |
| if (psessionEntry->vdev_nss == NSS_1x1_MODE) |
| pRates->supportedMCSSet[1] = 0; |
| |
| //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: "));) |
| for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) |
| PELOG2(limLog(pMac, LOG2, FL("%x "), pRates->supportedMCSSet[i]);) |
| |
| psessionEntry->supported_nss_1x1 = |
| ((pRates->supportedMCSSet[1] != 0) ? false : true); |
| limLog(pMac, LOG1, FL("HT supported nss 1x1 : %d "), |
| psessionEntry->supported_nss_1x1); |
| |
| } |
| #ifdef WLAN_FEATURE_11AC |
| limPopulateVhtMcsSet(pMac, pRates , pVHTCaps, psessionEntry, |
| psessionEntry->vdev_nss); |
| #endif |
| return eSIR_SUCCESS; |
| error: |
| return eSIR_FAILURE; |
| } /*** limPopulatePeerRateSet() ***/ |
| |
| /** |
| * 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 |
| */ |
| #ifdef WLAN_FEATURE_11AC |
| tSirRetStatus |
| limPopulateMatchingRateSet(tpAniSirGlobal pMac, |
| tpDphHashNode pStaDs, |
| tSirMacRateSet *pOperRateSet, |
| tSirMacRateSet *pExtRateSet, |
| tANI_U8* pSupportedMCSSet, |
| tpPESession psessionEntry, |
| tDot11fIEVHTCaps *pVHTCaps) |
| |
| #else |
| tSirRetStatus |
| limPopulateMatchingRateSet(tpAniSirGlobal pMac, |
| tpDphHashNode pStaDs, |
| tSirMacRateSet *pOperRateSet, |
| tSirMacRateSet *pExtRateSet, |
| tANI_U8* pSupportedMCSSet, |
| tpPESession psessionEntry) |
| #endif |
| { |
| 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, psessionEntry); |
| |
| /* copy operational rate set from psessionEntry */ |
| vos_mem_copy((tempRateSet.rate), (psessionEntry->rateSet.rate), |
| psessionEntry->rateSet.numRates); |
| tempRateSet.numRates = (tANI_U8) psessionEntry->rateSet.numRates; |
| |
| if (phyMode == WNI_CFG_PHY_MODE_11G) |
| { |
| vos_mem_copy((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"));) |
| 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 < SIR_MAC_RATESET_EID_MAX) ; 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 < SIR_MAC_RATESET_EID_MAX); 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 < SIR_MAC_RATESET_EID_MAX) && ((i+j) < SIR_MAC_RATESET_EID_MAX)); j++) |
| tempRateSet.rate[i+j] = pExtRateSet->rate[j]; |
| |
| tempRateSet.numRates += pExtRateSet->numRates; |
| } |
| } |
| |
| { |
| tpSirSupportedRates rates = &pStaDs->supportedRates; |
| tANI_U8 aRateIndex = 0; |
| tANI_U8 bRateIndex = 0; |
| vos_mem_set((tANI_U8 *) rates, sizeof(tSirSupportedRates), 0); |
| for(i = 0;(i < tempRateSet2.numRates && i < SIR_MAC_RATESET_EID_MAX ); i++) |
| { |
| for(j = 0;(j < tempRateSet.numRates && j < SIR_MAC_RATESET_EID_MAX); j++) |
| { |
| if ((tempRateSet2.rate[i] & 0x7F) == |
| (tempRateSet.rate[j] & 0x7F)) |
| { |
| if (sirIsArate(tempRateSet2.rate[i] & 0x7f)) |
| { |
| isArate=1; |
| if (aRateIndex < SIR_NUM_11A_RATES) |
| rates->llaRates[aRateIndex++] = tempRateSet2.rate[i]; |
| } |
| else |
| { |
| if (bRateIndex < SIR_NUM_11B_RATES) |
| rates->llbRates[bRateIndex++] = tempRateSet2.rate[i]; |
| } |
| break; |
| } |
| } |
| } |
| } |
| |
| |
| //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n |
| #ifdef FEATURE_WLAN_TDLS |
| if(pStaDs->mlmStaContext.htCapability) |
| #else |
| if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && |
| (pStaDs->mlmStaContext.htCapability)) |
| #endif |
| { |
| 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")); |
| goto error; |
| } |
| if (psessionEntry->vdev_nss == NSS_1x1_MODE) |
| mcsSet[1] = 0; |
| |
| 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 : "));) |
| for(i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) |
| { |
| PELOG2(limLog(pMac, LOG2,FL("%x %x "), mcsSet[i], pStaDs->supportedRates.supportedMCSSet[i]);) |
| } |
| } |
| |
| #ifdef WLAN_FEATURE_11AC |
| limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, |
| psessionEntry, psessionEntry->vdev_nss); |
| #endif |
| /** |
| * 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, tANI_U8 updateEntry, tpPESession psessionEntry) |
| { |
| tpAddStaParams pAddStaParams = NULL; |
| tSirMsgQ msgQ; |
| tSirRetStatus retCode = eSIR_SUCCESS; |
| tSirMacAddr staMac, *pStaAddr; |
| tANI_U8 i, nwType11b = 0; |
| tpSirAssocReq pAssocReq; |
| tLimIbssPeerNode *pPeerNode; /* for IBSS mode */ |
| tDot11fIEVHTCaps vht_caps; /* for IBSS mode */ |
| tANI_U8 *p2pIe = NULL; |
| |
| sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); |
| |
| limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), |
| psessionEntry->smeSessionId, updateEntry, |
| GET_LIM_SYSTEM_ROLE(psessionEntry)); |
| |
| pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); |
| if (NULL == pAddStaParams) |
| { |
| limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) |
| pStaAddr = &pStaDs->staAddr; |
| #ifdef FEATURE_WLAN_TDLS |
| /* SystemRole shouldn't be matter if staType is TDLS peer */ |
| else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) |
| pStaAddr = &pStaDs->staAddr ; |
| #endif |
| else if (STA_ENTRY_NDI_PEER == pStaDs->staType) |
| pStaAddr = &pStaDs->staAddr; |
| else |
| pStaAddr = &staMac; |
| |
| limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": Subtype(Assoc/Reassoc): %d "), |
| MAC_ADDR_ARRAY(*pStaAddr), pStaDs->mlmStaContext.subType); |
| |
| vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, |
| (tANI_U8 *) *pStaAddr, sizeof(tSirMacAddr)); |
| vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, |
| psessionEntry->bssId, sizeof(tSirMacAddr)); |
| vos_mem_copy(&pAddStaParams->capab_info, |
| &pStaDs->mlmStaContext.capabilityInfo, |
| sizeof(pAddStaParams->capab_info)); |
| |
| limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry); |
| |
| //Copy legacy rates |
| vos_mem_copy ((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; |
| if (LIM_IS_AP_ROLE(psessionEntry) && |
| (pStaDs->mlmStaContext.subType == LIM_REASSOC)) { |
| /* TBD - need to remove this REASSOC check after fixing rmmod issue */ |
| pAddStaParams->updateSta = pStaDs->mlmStaContext.updateContext; |
| } |
| pStaDs->valid = 0; |
| pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; |
| |
| limLog(pMac, LOG2, FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d" |
| " shortPreambleSupported: %d "), pAddStaParams->assocId, |
| pAddStaParams->wmmEnabled, pAddStaParams->listenInterval, |
| pAddStaParams->shortPreambleSupported); |
| // This will indicate HAL to "allocate" a new STA index |
| #ifdef FEATURE_WLAN_TDLS |
| /* As there is corner case in-between add_sta and change_sta,if del_sta for other staIdx happened, |
| * firmware return wrong staIdx (recently removed staIdx). Until we get a confirmation from the |
| * firmware team it is now return correct staIdx for same sta_mac_addr for update case, we want |
| * to get around it by passing valid staIdx given by add_sta time. |
| */ |
| if((STA_ENTRY_TDLS_PEER == pStaDs->staType) && |
| (true == updateEntry)) |
| pAddStaParams->staIdx = pStaDs->staIndex; |
| else |
| #endif |
| pAddStaParams->staIdx = HAL_STA_INVALID_IDX; |
| pAddStaParams->staType = pStaDs->staType; |
| |
| pAddStaParams->updateSta = updateEntry; |
| |
| pAddStaParams->status = eHAL_STATUS_SUCCESS; |
| pAddStaParams->respReqd = 1; |
| //Update HT Capability |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_BT_AMP_AP_ROLE(psessionEntry) || |
| LIM_IS_IBSS_ROLE(psessionEntry)) { |
| pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; |
| #ifdef WLAN_FEATURE_11AC |
| pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; |
| #endif |
| } |
| #ifdef FEATURE_WLAN_TDLS |
| /* SystemRole shouldn't be matter if staType is TDLS peer */ |
| else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) |
| { |
| pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; |
| #ifdef WLAN_FEATURE_11AC |
| pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; |
| #endif |
| } |
| #endif |
| else |
| { |
| pAddStaParams->htCapable = psessionEntry->htCapability; |
| #ifdef WLAN_FEATURE_11AC |
| pAddStaParams->vhtCapable = psessionEntry->vhtCapability; |
| #endif |
| |
| } |
| #ifdef WLAN_FEATURE_11AC |
| limLog(pMac, LOG2, FL("vhtCapable: %d "),pAddStaParams->vhtCapable); |
| #endif |
| limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "), |
| pAddStaParams->staIdx,pAddStaParams->updateSta, |
| pAddStaParams->htCapable); |
| |
| 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; |
| |
| limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d " |
| "maxAmpduDensity = %d"), pAddStaParams->greenFieldCapable, |
| pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); |
| |
| limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " |
| "fShortGI40Mhz: %d"), pAddStaParams->fDsssCckMode40Mhz, |
| pAddStaParams->fShortGI20Mhz, pAddStaParams->fShortGI40Mhz); |
| |
| limLog(pMac, LOG2, FL("lsigTxopProtection: %d maxAmsduSize: %d " |
| "txChannelWidthSet: %d mimoPS: %d "), pAddStaParams->lsigTxopProtection, |
| pAddStaParams->maxAmsduSize,pAddStaParams->txChannelWidthSet, |
| pAddStaParams->mimoPS); |
| |
| #ifdef WLAN_FEATURE_11AC |
| if(pAddStaParams->vhtCapable) |
| { |
| pAddStaParams->vhtTxChannelWidthSet = pStaDs->vhtSupportedChannelWidthSet; |
| pAddStaParams->vhtSupportedRxNss = pStaDs->vhtSupportedRxNss; |
| pAddStaParams->vhtTxBFCapable = |
| #ifdef FEATURE_WLAN_TDLS |
| (( STA_ENTRY_PEER == pStaDs->staType ) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ? |
| pStaDs->vhtBeamFormerCapable : psessionEntry->txBFIniFeatureEnabled ; |
| #else |
| ( STA_ENTRY_PEER == pStaDs->staType ) ? pStaDs->vhtBeamFormerCapable : |
| psessionEntry->txBFIniFeatureEnabled ; |
| #endif |
| limLog(pMac, LOG2, FL("vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), |
| pAddStaParams->vhtTxChannelWidthSet,pAddStaParams->vhtTxBFCapable); |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_TDLS |
| if((STA_ENTRY_PEER == pStaDs->staType) || |
| (STA_ENTRY_TDLS_PEER == pStaDs->staType)) |
| #else |
| if (STA_ENTRY_PEER == pStaDs->staType) |
| #endif |
| { |
| /* peer STA get the LDPC capability from pStaDs, which populated from |
| * HT/VHT capability*/ |
| if(pAddStaParams->vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP) |
| { |
| pAddStaParams->htLdpcCapable = 0; |
| pAddStaParams->vhtLdpcCapable = 0; |
| } |
| else |
| { |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) |
| pAddStaParams->htLdpcCapable = pStaDs->htLdpcCapable; |
| else |
| pAddStaParams->htLdpcCapable = 0; |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) |
| pAddStaParams->vhtLdpcCapable = pStaDs->vhtLdpcCapable; |
| else |
| pAddStaParams->vhtLdpcCapable = 0; |
| } |
| } |
| else if( STA_ENTRY_SELF == pStaDs->staType) |
| { |
| /* For Self STA get the LDPC capability from config.ini*/ |
| pAddStaParams->htLdpcCapable = |
| (psessionEntry->txLdpcIniFeatureEnabled & 0x01); |
| pAddStaParams->vhtLdpcCapable = |
| ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); |
| } |
| |
| /* Update PE session ID*/ |
| pAddStaParams->sessionId = psessionEntry->peSessionId; |
| |
| /* Update SME session ID */ |
| pAddStaParams->smesessionId = psessionEntry->smeSessionId; |
| |
| pAddStaParams->maxTxPower = psessionEntry->maxTxPower; |
| |
| if (psessionEntry->parsedAssocReq != NULL) |
| { |
| // 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); |
| if ( pAssocReq && pAddStaParams->htCapable ) { |
| vos_mem_copy(&pAddStaParams->ht_caps, ((tANI_U8 *) &pAssocReq->HTCaps) + 1, |
| sizeof(pAddStaParams->ht_caps)); |
| } |
| if ( pAssocReq && pAddStaParams->vhtCapable) { |
| pAddStaParams->vht_caps = |
| ((pAssocReq->VHTCaps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | |
| (pAssocReq->VHTCaps.supportedChannelWidthSet << |
| SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | |
| (pAssocReq->VHTCaps.ldpcCodingCap << |
| SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | |
| (pAssocReq->VHTCaps.shortGI80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | |
| (pAssocReq->VHTCaps.shortGI160and80plus80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | |
| (pAssocReq->VHTCaps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | |
| (pAssocReq->VHTCaps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | |
| (pAssocReq->VHTCaps.suBeamFormerCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | |
| (pAssocReq->VHTCaps.suBeamformeeCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | |
| (pAssocReq->VHTCaps.csnofBeamformerAntSup << |
| SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | |
| (pAssocReq->VHTCaps.numSoundingDim << |
| SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | |
| (pAssocReq->VHTCaps.muBeamformerCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| |
| (pAssocReq->VHTCaps.muBeamformeeCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | |
| (pAssocReq->VHTCaps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | |
| (pAssocReq->VHTCaps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | |
| (pAssocReq->VHTCaps.maxAMPDULenExp << |
| SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | |
| (pAssocReq->VHTCaps.vhtLinkAdaptCap << |
| SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | |
| (pAssocReq->VHTCaps.rxAntPattern << |
| SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | |
| (pAssocReq->VHTCaps.txAntPattern << |
| SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | |
| (pAssocReq->VHTCaps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); |
| } |
| } else if (LIM_IS_IBSS_ROLE(psessionEntry)) { |
| /* in IBSS mode, use peer node as the source of ht_caps and vht_caps */ |
| pPeerNode = limIbssPeerFind(pMac, *pStaAddr); |
| if (!pPeerNode) { |
| limLog( pMac, LOGP, FL("Can't find IBSS peer node for ADD_STA")); |
| vos_mem_free(pAddStaParams); |
| return eSIR_HAL_STA_DOES_NOT_EXIST; |
| } |
| |
| if (pPeerNode->atimIePresent) |
| { |
| pAddStaParams->atimIePresent = pPeerNode->atimIePresent; |
| pAddStaParams->peerAtimWindowLength = |
| pPeerNode->peerAtimWindowLength; |
| } |
| |
| pAddStaParams->ht_caps = |
| ( pPeerNode->htSupportedChannelWidthSet << |
| SIR_MAC_HT_CAP_CHWIDTH40_S ) | |
| ( pPeerNode->htGreenfield << |
| SIR_MAC_HT_CAP_GREENFIELD_S ) | |
| ( pPeerNode->htShortGI20Mhz << |
| SIR_MAC_HT_CAP_SHORTGI20MHZ_S ) | |
| ( pPeerNode->htShortGI40Mhz << |
| SIR_MAC_HT_CAP_SHORTGI40MHZ_S ) | |
| ( SIR_MAC_TXSTBC << |
| SIR_MAC_HT_CAP_TXSTBC_S ) | |
| ( SIR_MAC_RXSTBC << |
| SIR_MAC_HT_CAP_RXSTBC_S ) | |
| ( pPeerNode->htMaxAmsduLength << |
| SIR_MAC_HT_CAP_MAXAMSDUSIZE_S ) | |
| ( pPeerNode->htDsssCckRate40MHzSupport << |
| SIR_MAC_HT_CAP_DSSSCCK40_S ); |
| |
| vht_caps = pPeerNode->VHTCaps; |
| pAddStaParams->vht_caps = |
| ((vht_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | |
| (vht_caps.supportedChannelWidthSet << |
| SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | |
| (vht_caps.ldpcCodingCap << |
| SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | |
| (vht_caps.shortGI80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | |
| (vht_caps.shortGI160and80plus80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | |
| (vht_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | |
| (vht_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | |
| (vht_caps.suBeamFormerCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | |
| (vht_caps.suBeamformeeCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | |
| (vht_caps.csnofBeamformerAntSup << |
| SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | |
| (vht_caps.numSoundingDim << |
| SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | |
| (vht_caps.muBeamformerCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| |
| (vht_caps.muBeamformeeCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | |
| (vht_caps.vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | |
| (vht_caps.htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | |
| (vht_caps.maxAMPDULenExp << |
| SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | |
| (vht_caps.vhtLinkAdaptCap << |
| SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | |
| (vht_caps.rxAntPattern << |
| SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | |
| (vht_caps.txAntPattern << |
| SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | |
| (vht_caps.reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); |
| } |
| |
| #ifdef FEATURE_WLAN_TDLS |
| if (STA_ENTRY_TDLS_PEER == pStaDs->staType) |
| { |
| pAddStaParams->ht_caps = pStaDs->ht_caps; |
| pAddStaParams->vht_caps = pStaDs->vht_caps; |
| |
| VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, |
| "%s: Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x", |
| __func__, pAddStaParams->ht_caps, pAddStaParams->vht_caps); |
| } |
| #endif |
| |
| #ifdef FEATURE_WLAN_TDLS |
| if(pStaDs->wmeEnabled && |
| (LIM_IS_AP_ROLE(psessionEntry) || |
| (STA_ENTRY_TDLS_PEER == pStaDs->staType))) |
| #else |
| if (pStaDs->wmeEnabled && LIM_IS_AP_ROLE(psessionEntry)) |
| #endif |
| { |
| 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, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"), |
| pAddStaParams->uAPSD, pAddStaParams->maxSPLen); |
| } |
| |
| #ifdef WLAN_FEATURE_11W |
| pAddStaParams->rmfEnabled = pStaDs->rmfEnabled; |
| limLog( pMac, LOG1, FL( "PMF enabled %d"), pAddStaParams->rmfEnabled); |
| #endif |
| |
| limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d " |
| "p2pCapableSta: %d"), pAddStaParams->htLdpcCapable, |
| pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta); |
| |
| if (!pAddStaParams->htLdpcCapable) |
| pAddStaParams->ht_caps &= ~(1 << SIR_MAC_HT_CAP_ADVCODING_S); |
| |
| if (!pAddStaParams->vhtLdpcCapable) |
| pAddStaParams->vht_caps &= ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP); |
| //we need to defer the message until we get the response back from HAL. |
| if (pAddStaParams->respReqd) |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, false); |
| |
| for (i = 0; i < SIR_NUM_11A_RATES; i++) |
| { |
| if (sirIsArate(pStaDs->supportedRates.llaRates[i] & 0x7F)) |
| { |
| nwType11b = 0; |
| break; |
| } |
| else |
| { |
| nwType11b = 1; |
| } |
| } |
| if (nwType11b) |
| { |
| pAddStaParams->nwType = eSIR_11B_NW_TYPE; |
| } |
| else |
| { |
| pAddStaParams->nwType = psessionEntry->nwType; |
| } |
| |
| msgQ.type = WDA_ADD_STA_REQ; |
| |
| msgQ.reserved = 0; |
| msgQ.bodyptr = pAddStaParams; |
| msgQ.bodyval = 0; |
| |
| limLog(pMac, LOG1, FL("Sending WDA_ADD_STA_REQ for assocId %d"), |
| pStaDs->assocId); |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| |
| retCode = wdaPostCtrlMsg( pMac, &msgQ ); |
| if( eSIR_SUCCESS != retCode) |
| { |
| if (pAddStaParams->respReqd) |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| limLog( pMac, LOGE, FL("ADD_STA_REQ for aId %d failed (reason %X)"), |
| pStaDs->assocId, retCode ); |
| vos_mem_free(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; |
| |
| pDelStaParams = vos_mem_malloc(sizeof( tDeleteStaParams )); |
| if (NULL == pDelStaParams) |
| { |
| limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| |
| vos_mem_set((tANI_U8 *) pDelStaParams, sizeof(tDeleteStaParams), 0); |
| |
| // |
| // 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 |
| // |
| |
| #ifdef FEATURE_WLAN_TDLS |
| if ((LIM_IS_STA_ROLE(psessionEntry) && |
| (pStaDs->staType != STA_ENTRY_TDLS_PEER)) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) |
| #else |
| if (LIM_IS_STA_ROLE(psessionEntry) || LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) |
| #endif |
| 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, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); |
| SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, eLIM_MLM_WT_DEL_STA_RSP_STATE); |
| } |
| if (LIM_IS_STA_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, 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->smesessionId = psessionEntry->smeSessionId; |
| |
| pDelStaParams->staType = pStaDs->staType; |
| vos_mem_copy((tANI_U8 *)pDelStaParams->staMac, |
| (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); |
| |
| pDelStaParams->status = eHAL_STATUS_SUCCESS; |
| msgQ.type = WDA_DELETE_STA_REQ; |
| msgQ.reserved = 0; |
| msgQ.bodyptr = pDelStaParams; |
| msgQ.bodyval = 0; |
| |
| limLog( pMac, LOG1, FL( "Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ " |
| "for STAID: %X and AssocID: %d MAC : "MAC_ADDRESS_STR ), |
| pDelStaParams->sessionId, |
| pDelStaParams->staIdx, pDelStaParams->assocId, |
| MAC_ADDR_ARRAY(pStaDs->staAddr)); |
| |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| retCode = wdaPostCtrlMsg( pMac, &msgQ ); |
| if( eSIR_SUCCESS != retCode) |
| { |
| if(fRespReqd) |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| limLog( pMac, LOGE, FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"), |
| retCode ); |
| vos_mem_free(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; |
| tSirRetStatus retCode = eSIR_SUCCESS; |
| tSirMsgQ msgQ; |
| |
| pAddStaParams = psessionEntry->ftPEContext.pAddStaReq; |
| pAddStaParams->assocId = assocId; |
| pAddStaParams->smesessionId = psessionEntry->smeSessionId; |
| |
| msgQ.type = WDA_ADD_STA_REQ; |
| msgQ.reserved = 0; |
| msgQ.bodyptr = pAddStaParams; |
| msgQ.bodyval = 0; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R_DEBUG |
| VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, |
| "%s: Sending WDA_ADD_STA_REQ (aid %d)", |
| __func__, pAddStaParams->assocId); |
| #endif |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| |
| psessionEntry->limPrevMlmState = psessionEntry->limMlmState; |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, |
| eLIM_MLM_WT_ADD_STA_RSP_STATE)); |
| psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; |
| if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) { |
| limLog(pMac, LOGE, |
| FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode); |
| vos_mem_free(pAddStaParams); |
| } |
| psessionEntry->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; |
| tANI_U32 shortGi20MhzSupport; |
| tANI_U32 shortGi40MhzSupport; |
| tANI_U32 ampduLenExponent = 0; |
| tANI_U32 val; |
| /*This self Sta dot 11 mode comes from the cfg and the expectation here is |
| * that cfg carries the systemwide capability that device under |
| * consideration can support. This capability gets plumbed into the cfg |
| * cache at system initialization time via the .dat and .ini file override |
| * mechanisms and will not change. If it does change, it is the |
| * responsibility of SME to evict the selfSta and reissue a new AddStaSelf |
| * command.*/ |
| tANI_U32 selfStaDot11Mode=0, selfTxWidth=0; |
| wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); |
| limLog( pMac, LOG1, FL("cfgDot11Mode %d"),(int)selfStaDot11Mode); |
| wlan_cfgGetInt(pMac,WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,&selfTxWidth); |
| limLog( pMac, LOG1, FL("SGI 20 %d"),(int)selfTxWidth); |
| limLog( pMac, LOG1, FL("Roam Channel Bonding Mode %d"),(int)pMac->roam.configParam.uCfgDot11Mode); |
| |
| sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); |
| limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": "),MAC_ADDR_ARRAY(staMac)); |
| pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); |
| if (NULL == pAddStaParams) |
| { |
| limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); |
| |
| /// Add STA context at MAC HW (BMU, RHP & TFP) |
| vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, |
| (tANI_U8 *) staMac, sizeof(tSirMacAddr)); |
| |
| vos_mem_copy((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; |
| |
| /* Update SME session ID */ |
| pAddStaParams->smesessionId = psessionEntry->smeSessionId; |
| |
| pAddStaParams->maxTxPower = psessionEntry->maxTxPower; |
| |
| // This will indicate HAL to "allocate" a new STA index |
| pAddStaParams->staIdx = staIdx; |
| pAddStaParams->updateSta = updateSta; |
| |
| if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != |
| eSIR_SUCCESS) { |
| limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE, set default")); |
| pAddStaParams->shortPreambleSupported = 1; |
| } |
| pAddStaParams->shortPreambleSupported = val; |
| |
| #ifdef WLAN_FEATURE_11AC |
| limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry,NULL); |
| #else |
| limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry); |
| #endif |
| if ( IS_DOT11_MODE_HT(selfStaDot11Mode) ) |
| { |
| pAddStaParams->htCapable = TRUE ; |
| { |
| pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); |
| pAddStaParams->txChannelWidthSet = |
| pMac->roam.configParam.channelBondingMode5GHz; |
| 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->max_amsdu_num = limGetHTCapability(pMac, |
| eHT_MAX_AMSDU_NUM, |
| psessionEntry); |
| pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); |
| /* |
| * We will read the gShortGI20Mhz from ini file, and if it is set |
| * to 1 then we will tell Peer that we support 40Mhz short GI |
| */ |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_20MHZ, |
| &shortGi20MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi20MhzSupport) |
| { |
| pAddStaParams->fShortGI20Mhz = |
| WNI_CFG_SHORT_GI_20MHZ_STAMAX; |
| } |
| else |
| { |
| pAddStaParams->fShortGI20Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" |
| "CFG,setting value to default"));) |
| pAddStaParams->fShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF; |
| } |
| |
| /* |
| * We will read the gShortGI40Mhz from ini file, and if it is set |
| * to 1 then we will tell Peer that we support 40Mhz short GI |
| */ |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_40MHZ, |
| &shortGi40MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi40MhzSupport) |
| { |
| pAddStaParams->fShortGI40Mhz = |
| WNI_CFG_SHORT_GI_40MHZ_STAMAX; |
| } |
| else |
| { |
| pAddStaParams->fShortGI40Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" |
| "CFG,setting value to default"));) |
| pAddStaParams->fShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF; |
| } |
| limLog(pMac, LOG2, FL(" greenFieldCapable: %d maxAmpduDensity = %d " |
| "maxAmpduSize = %d"), pAddStaParams->greenFieldCapable, |
| pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); |
| |
| limLog(pMac, LOG2, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " |
| "fShortGI40Mhz: %d lsigTxopProtection: %d"), |
| pAddStaParams->fDsssCckMode40Mhz, pAddStaParams->fShortGI20Mhz, |
| pAddStaParams->fShortGI40Mhz, pAddStaParams->lsigTxopProtection); |
| |
| limLog(pMac, LOG2, FL(" maxAmsduSize: %d txChannelWidthSet: %d " |
| "mimoPS: %d rifsMode %d delBASupport %d"), |
| pAddStaParams->maxAmsduSize, |
| pAddStaParams->txChannelWidthSet, pAddStaParams->mimoPS, |
| pAddStaParams->rifsMode, pAddStaParams->delBASupport ); |
| } |
| } |
| #ifdef WLAN_FEATURE_11AC |
| pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode); |
| if (pAddStaParams->vhtCapable){ |
| pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; |
| limLog( pMac, LOG1, FL("VHT WIDTH SET %d"),pAddStaParams->vhtTxChannelWidthSet); |
| } |
| pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled; |
| limLog(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d "), |
| pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable); |
| |
| // In 11ac mode, the hardware is capable of supporting 128K AMPDU size |
| if ( IS_DOT11_MODE_VHT(selfStaDot11Mode) ) |
| { |
| if(wlan_cfgGetInt(pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &duLenExponent) |
| != eSIR_SUCCESS) |
| { |
| limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT")); |
| } |
| pAddStaParams->maxAmpduSize = (tANI_U8)ampduLenExponent; |
| } |
| pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee; |
| pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid; |
| #endif |
| pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs; |
| pAddStaParams->enableHtSmps = (psessionEntry->enableHtSmps && |
| (!psessionEntry->supported_nss_1x1)); |
| pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue; |
| |
| /* For Self STA get the LDPC capability from session i.e config.ini*/ |
| pAddStaParams->htLdpcCapable = |
| (psessionEntry->txLdpcIniFeatureEnabled & 0x01); |
| pAddStaParams->vhtLdpcCapable = |
| ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); |
| |
| if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) |
| limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); |
| pAddStaParams->listenInterval = (tANI_U16)listenInterval; |
| |
| if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) |
| { |
| pAddStaParams->p2pCapableSta = 1; |
| } |
| |
| pAddStaParams->supportedRates.opRateMode = |
| limGetStaRateMode((tANI_U8)selfStaDot11Mode); |
| |
| limLog(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "), |
| pAddStaParams->staIdx,pAddStaParams->updateSta, |
| pAddStaParams->htCapable); |
| |
| limLog(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d " |
| "p2pCapableSta: %d"), |
| pAddStaParams->htLdpcCapable,pAddStaParams->vhtLdpcCapable, |
| pAddStaParams->p2pCapableSta); |
| /* As part of HS2.0 certification need to send reassoc |
| * to the same AP to which STA connected .in this case |
| * we are not sending delsta but sending only addsta |
| * which is causing target asssert. to fix this |
| * set pAddStaParams->nonRoamReassoc = 1 and using this |
| * skip sending the addsta to firmware |
| */ |
| if (psessionEntry->isNonRoamReassoc) { |
| pAddStaParams->nonRoamReassoc = 1; |
| psessionEntry->isNonRoamReassoc = 0; |
| } |
| limLog(pMac, LOG2, FL("sessionid: %d Assoc ID: %d listenInterval = %d " |
| "shortPreambleSupported: %d"), psessionEntry->smeSessionId, |
| pAddStaParams->assocId, pAddStaParams->listenInterval, |
| pAddStaParams->shortPreambleSupported); |
| |
| msgQ.type = WDA_ADD_STA_REQ; |
| msgQ.reserved = 0; |
| msgQ.bodyptr = pAddStaParams; |
| msgQ.bodyval = 0; |
| |
| limLog(pMac, LOG1, FL(MAC_ADDRESS_STR":Sessionid %d : " |
| "Sending WDA_ADD_STA_REQ. (aid %d)"), |
| MAC_ADDR_ARRAY(pAddStaParams->staMac), |
| pAddStaParams->sessionId, |
| pAddStaParams->assocId); |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| |
| if (eSIR_SUCCESS != (retCode = wdaPostCtrlMsg(pMac, &msgQ))) { |
| limLog(pMac, LOGE, |
| FL("Posting WDA_ADD_STA_REQ to HAL failed, reason=%X"), retCode); |
| vos_mem_free(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, FALSE); |
| } /*** 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; |
| 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")); |
| return; |
| } |
| pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); |
| |
| if (pStaDs == NULL) |
| { |
| PELOGW(limLog(pMac, LOGW, FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));) |
| 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"), pStaDs->assocId);) |
| limPrintMacAddr(pMac, pStaDs->staAddr, LOGW); |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) { |
| 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"), |
| 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; |
| |
| vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); |
| beaconParams.paramChangeBitmap = 0; |
| limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, staId); |
| if (NULL == psessionEntry) |
| { |
| PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));) |
| return; |
| } |
| 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"), staId);) |
| // update the station count and perform associated actions |
| // do this before deleting the dph hash entry |
| limUtilCountStaDel(pMac, pStaDs, psessionEntry); |
| |
| if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry)) { |
| if (LIM_IS_AP_ROLE(psessionEntry)) { |
| if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE){ |
| limDecideApProtectionOnDelete(pMac, pStaDs, &beaconParams,psessionEntry); |
| } |
| } |
| |
| if (pStaDs->non_ecsa_capable) { |
| if (psessionEntry->lim_non_ecsa_cap_num == 0) { |
| limLog(pMac, LOGE, |
| FL("Non ECSA sta cnt 0, sta: %d is ecsa\n"), |
| staId); |
| } else { |
| psessionEntry->lim_non_ecsa_cap_num--; |
| limLog(pMac, LOGE, |
| FL("reducing the non ECSA num to %d"), |
| psessionEntry->lim_non_ecsa_cap_num); |
| } |
| } |
| |
| if (LIM_IS_IBSS_ROLE(psessionEntry)) |
| 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 "), beaconParams.paramChangeBitmap);) |
| if((VOS_FALSE == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) |
| && beaconParams.paramChangeBitmap) |
| { |
| schSetFixedBeaconFields(pMac,psessionEntry); |
| limSendBeaconParams(pMac, &beaconParams, psessionEntry ); |
| } |
| |
| #ifdef WLAN_FEATURE_11W |
| tx_timer_delete(&pStaDs->pmfSaQueryTimer); |
| #endif |
| } |
| if (dphDeleteHashEntry(pMac, staAddr, staId, &psessionEntry->dph.dphHashTable) != eSIR_SUCCESS) |
| limLog(pMac, LOGP, FL("error deleting hash entry")); |
| #ifdef SAP_AUTH_OFFLOAD |
| lim_pop_sap_deferred_msg(pMac, psessionEntry); |
| #endif |
| } |
| } |
| |
| /** |
| * 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; |
| tANI_U32 val = 0; |
| tANI_U32 *noa1DurationFromBcn = NULL; |
| tANI_U32 *noa2DurationFromBcn = NULL; |
| tANI_U32 noa; |
| tANI_U32 TotalNum_NoADesc = 0; |
| |
| vos_mem_copy(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 && |
| (!vos_mem_compare((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"));) |
| #ifdef WLAN_DEBUG |
| pMac->lim.gLimBcnSSIDMismatchCnt++; |
| #endif |
| return; |
| } |
| |
| if (LIM_IS_BT_AMP_STA_ROLE(psessionEntry) || |
| LIM_IS_STA_ROLE(psessionEntry)) { |
| limLog(pMac, LOG1, FL("Received Beacon/PR with matching BSSID" |
| MAC_ADDRESS_STR "PESessionID %d"), |
| MAC_ADDR_ARRAY(psessionEntry->bssId), |
| psessionEntry->peSessionId ); |
| |
| // Deactivate Join Failure timer |
| limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); |
| // Deactivate Periodic Join timer |
| limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); |
| |
| if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && |
| pBPR->P2PProbeRes.NoticeOfAbsence.present) |
| { |
| |
| noa1DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + 1); |
| |
| if(pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc) |
| TotalNum_NoADesc = pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc/SIZE_OF_NOA_DESCRIPTOR; |
| |
| noa = *noa1DurationFromBcn; |
| |
| if(TotalNum_NoADesc > 1) |
| { |
| noa2DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + SIZE_OF_NOA_DESCRIPTOR + 1); |
| noa += *noa2DurationFromBcn; |
| } |
| |
| /*If MAX Noa exceeds 3 secs we will consider only 3 secs to |
| * avoid arbitary values in noa duration field |
| */ |
| noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ? MAX_NOA_PERIOD_IN_MICROSECS : noa; |
| noa = noa/1000; //Convert to ms |
| |
| if( wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,&val) == eSIR_SUCCESS ) |
| { |
| psessionEntry->defaultAuthFailureTimeout = val; |
| ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT ,val + noa, NULL, eANI_BOOLEAN_FALSE); |
| } |
| } |
| else |
| { |
| psessionEntry->defaultAuthFailureTimeout = 0; |
| } |
| |
| // 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, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE)); |
| |
| |
| /* |
| * update the capability info based on recently |
| * received beacon/probe response frame |
| */ |
| psessionEntry->limCurrentBssCaps = |
| limGetU16((tANI_U8 *)&pBPR->capabilityInfo); |
| |
| /** |
| * 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.... |
| |
| if (psessionEntry->vhtCapability && pBPR->vendor2_ie.VHTCaps.present) { |
| psessionEntry->is_vendor_specific_vhtcaps = true; |
| psessionEntry->vendor_specific_vht_ie_type = |
| pBPR->vendor2_ie.type; |
| psessionEntry->vendor_specific_vht_ie_sub_type = |
| pBPR->vendor2_ie.sub_type; |
| limLog(pMac, LOG1, FL( |
| "VHT caps are present in vendor specific IE")); |
| } |
| |
| /* Update HS 2.0 Information Element */ |
| sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie, &pBPR->hs20vendor_ie); |
| } |
| |
| /** |
| * 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 ) |
| { |
| vos_mem_set((tANI_U8 *) beaconStruct, sizeof( tSirProbeRespBeacon ), 0); |
| |
| PELOG3(limLog( pMac, LOG3, |
| FL( "In limExtractApCapabilities: The IE's being received are:" )); |
| 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!")); |
| 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; |
| |
| pDelBssParams = vos_mem_malloc(sizeof(tDeleteBssParams)); |
| if (NULL == pDelBssParams) |
| { |
| limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_BSS" )); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| vos_mem_set((tANI_U8 *) pDelBssParams, sizeof(tDeleteBssParams), 0); |
| |
| |
| 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, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE)); |
| |
| if((psessionEntry->peSessionId == pMac->lim.limTimers.gLimJoinFailureTimer.sessionId) && |
| (VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) |
| { |
| limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); |
| } |
| |
| pDelBssParams->status= eHAL_STATUS_SUCCESS; |
| pDelBssParams->respReqd = 1; |
| vos_mem_copy(pDelBssParams->bssid, psessionEntry->bssId, sizeof(tSirMacAddr)); |
| pDelBssParams->smesessionId = psessionEntry->smeSessionId; |
| PELOGW(limLog( pMac, LOGW, FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ " |
| "for bss idx: %X BSSID:"MAC_ADDRESS_STR), pDelBssParams->sessionId, |
| pDelBssParams->bssIdx, |
| MAC_ADDR_ARRAY(psessionEntry->bssId));) |
| |
| //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, psessionEntry->peSessionId, msgQ.type)); |
| |
| if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) |
| { |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| limLog( pMac, LOGE, FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), retCode ); |
| vos_mem_free(pDelBssParams); |
| } |
| |
| return retCode; |
| } |
| |
| /* lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response. |
| * @pMac Pointer to Global MAC structure |
| * @add_bss_params: parameters required for add bss params. |
| * @vht_caps: VHT capabilities. |
| * @session_entry : session entry. |
| * |
| * Return : void |
| */ |
| void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal pMac, |
| tpAddBssParams add_bss_params, |
| tDot11fIEVHTCaps *vht_caps, tpPESession session_entry) |
| { |
| add_bss_params->currentExtChannel = limGet11ACPhyCBState(pMac, |
| add_bss_params->currentOperChannel, |
| add_bss_params->currentExtChannel, |
| session_entry->apCenterChan, |
| session_entry); |
| |
| add_bss_params->staContext.vht_caps = |
| ((vht_caps->maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) | |
| (vht_caps->supportedChannelWidthSet << |
| SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) | |
| (vht_caps->ldpcCodingCap << |
| SIR_MAC_VHT_CAP_LDPC_CODING_CAP) | |
| (vht_caps->shortGI80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_80MHZ) | |
| (vht_caps->shortGI160and80plus80MHz << |
| SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) | |
| (vht_caps->txSTBC << SIR_MAC_VHT_CAP_TXSTBC) | |
| (vht_caps->rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) | |
| (vht_caps->suBeamFormerCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) | |
| (vht_caps->suBeamformeeCap << |
| SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) | |
| (vht_caps->csnofBeamformerAntSup << |
| SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) | |
| (vht_caps->numSoundingDim << |
| SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) | |
| (vht_caps->muBeamformerCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP)| |
| (vht_caps->muBeamformeeCap << |
| SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) | |
| (vht_caps->vhtTXOPPS << SIR_MAC_VHT_CAP_TXOPPS) | |
| (vht_caps->htcVHTCap << SIR_MAC_VHT_CAP_HTC_CAP) | |
| (vht_caps->maxAMPDULenExp << |
| SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) | |
| (vht_caps->vhtLinkAdaptCap << |
| SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) | |
| (vht_caps->rxAntPattern << |
| SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) | |
| (vht_caps->txAntPattern << |
| SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) | |
| (vht_caps->reserved1 << SIR_MAC_VHT_CAP_RESERVED2)); |
| |
| add_bss_params->staContext.maxAmpduSize = |
| SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( |
| add_bss_params->staContext.vht_caps); |
| |
| limLog(pMac, LOG1, |
| FL("Updating VHT Caps in assoc Response")); |
| } |
| |
| /** |
| * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response. |
| * @pMac Pointer to Global MAC structure |
| * @add_bss_params: parameters required for add bss params. |
| * @vht_oper: VHT Operations to update. |
| * @session_entry : session entry. |
| * |
| * Return : void |
| */ |
| void lim_update_vht_oper_assoc_resp(tpAniSirGlobal pMac, |
| tpAddBssParams add_bss_params, |
| tDot11fIEVHTOperation *vht_oper, tpPESession session_entry) |
| { |
| if (vht_oper->chanWidth) |
| add_bss_params->vhtTxChannelWidthSet = vht_oper->chanWidth; |
| limLog(pMac, LOG1, |
| FL("Updating VHT Operation in assoc Response")); |
| } |
| |
| |
| /** |
| * 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; |
| tSirRetStatus retCode = eSIR_SUCCESS; |
| tpDphHashNode pStaDs = NULL; |
| tANI_U8 chanWidthSupp = 0; |
| tANI_U8 isVHTCapInVendorIE = 0; |
| tANI_U32 shortGi20MhzSupport; |
| tANI_U32 shortGi40MhzSupport; |
| tANI_U32 enableTxBF20MHz; |
| tDot11fIEVHTCaps *vht_caps = NULL; |
| tDot11fIEVHTOperation *vht_oper = NULL; |
| |
| |
| // Package SIR_HAL_ADD_BSS_REQ message parameters |
| pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); |
| if (NULL == pAddBssParams) |
| { |
| limLog( pMac, LOGP, |
| FL( "Unable to allocate memory during ADD_BSS" )); |
| retCode = eSIR_MEM_ALLOC_FAILED; |
| goto returnFailure; |
| } |
| else |
| vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); |
| |
| vos_mem_copy(pAddBssParams->bssId,bssDescription->bssId, |
| sizeof(tSirMacAddr)); |
| // Fill in tAddBssParams selfMacAddr |
| vos_mem_copy(pAddBssParams->selfMacAddr, |
| psessionEntry->selfMacAddr, |
| sizeof(tSirMacAddr)); |
| |
| limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), |
| psessionEntry->smeSessionId, updateEntry, |
| GET_LIM_SYSTEM_ROLE(psessionEntry)); |
| |
| limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pAddBssParams->bssId)); |
| |
| 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; |
| vos_mem_copy(pAddBssParams->rateSet.rate, |
| pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates); |
| |
| if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) && |
| bssDescription->nwType != eSIR_11B_NW_TYPE) { |
| pAddBssParams->nwType = eSIR_11B_NW_TYPE; |
| } else { |
| 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; |
| |
| limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " |
| "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, |
| pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); |
| |
| limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" |
| " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, |
| pAddBssParams->cfParamSet.cfpMaxDuration, |
| pAddBssParams->cfParamSet.cfpDurRemaining, |
| pAddBssParams->rateSet.numRates); |
| |
| limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d" |
| "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), |
| pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, |
| pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, |
| pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); |
| |
| pAddBssParams->dot11_mode = psessionEntry->dot11mode; |
| limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode); |
| |
| // Use the advertised capabilities from the received beacon/PR |
| |
| |
| if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present )) |
| { |
| pAddBssParams->htCapable = pAssocRsp->HTCaps.present; |
| limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable); |
| if ( pBeaconStruct->HTInfo.present ) |
| { |
| pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pAssocRsp->HTInfo.opMode; |
| pAddBssParams->dualCTSProtection = ( tANI_U8 ) pAssocRsp->HTInfo.dualCTSProtection; |
| chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); |
| 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 = PHY_SINGLE_CHANNEL_CENTERED; |
| } |
| pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent; |
| pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport; |
| pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode; |
| |
| limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d " |
| "txChannelWidthSet: %d currentExtChannel: %d "), |
| pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, |
| pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); |
| |
| limLog(pMac, LOG2, FL("llnNonGFCoexist: %d " |
| "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), |
| pAddBssParams->llnNonGFCoexist, |
| pAddBssParams->fLsigTXOPProtectionFullSupport, |
| pAddBssParams->fRIFSMode); |
| } |
| } |
| |
| pAddBssParams->currentOperChannel = bssDescription->channelId; |
| limLog(pMac, LOG2, FL("currentOperChannel %d"), |
| pAddBssParams->currentOperChannel); |
| #ifdef WLAN_FEATURE_11AC |
| if (psessionEntry->vhtCapability && ( pAssocRsp->VHTCaps.present )) |
| { |
| pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present; |
| pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, |
| pAddBssParams->currentOperChannel, |
| pAddBssParams->currentExtChannel, |
| psessionEntry->apCenterChan, |
| psessionEntry); |
| vht_caps = &pAssocRsp->VHTCaps; |
| vht_oper = &pAssocRsp->VHTOperation; |
| } else if (psessionEntry->vhtCapability && |
| pAssocRsp->vendor2_ie.VHTCaps.present) { |
| pAddBssParams->vhtCapable = |
| pAssocRsp->vendor2_ie.VHTCaps.present; |
| limLog(pMac, LOG1, |
| FL("VHT Caps and Operation are present in vendor Specfic IE")); |
| vht_caps = &pAssocRsp->vendor2_ie.VHTCaps; |
| vht_oper = &pAssocRsp->vendor2_ie.VHTOperation; |
| } |
| else |
| pAddBssParams->vhtCapable = 0; |
| |
| if (pAddBssParams->vhtCapable) { |
| if (vht_oper != NULL) |
| lim_update_vht_oper_assoc_resp(pMac, pAddBssParams, |
| vht_oper, psessionEntry); |
| if (vht_caps != NULL) |
| lim_update_vhtcaps_assoc_resp(pMac, pAddBssParams, |
| vht_caps, psessionEntry); |
| } |
| |
| limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d " |
| "currentExtChannel %d"),pAddBssParams->vhtCapable, |
| pAddBssParams->vhtTxChannelWidthSet, |
| pAddBssParams->currentExtChannel); |
| #endif |
| |
| |
| // 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 |
| |
| vos_mem_copy(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: " MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac));) |
| retCode = eSIR_FAILURE; |
| goto returnFailure; |
| } |
| |
| if(!pMac->psOffloadEnabled) |
| { |
| pAddBssParams->staContext.uAPSD = 0; |
| } |
| else |
| { |
| pAddBssParams->staContext.uAPSD = |
| psessionEntry->gUapsdPerAcBitmask; |
| } |
| |
| pAddBssParams->staContext.maxSPLen = 0; |
| pAddBssParams->staContext.shortPreambleSupported = |
| psessionEntry->beaconParams.fShortPreamble; |
| pAddBssParams->staContext.updateSta = updateEntry; |
| |
| limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR |
| " shortPreambleSupported: %d"), |
| MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), |
| pAddBssParams->staContext.shortPreambleSupported); |
| |
| 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; |
| limLog(pMac, LOG2,FL("StaContext htCapable: %d greenFieldCapable: %d " |
| "lsigTxopProtection: %d"), pAddBssParams->staContext.htCapable, |
| pAddBssParams->staContext.greenFieldCapable, |
| pAddBssParams->staContext.lsigTxopProtection); |
| #ifdef WLAN_FEATURE_11AC |
| if (psessionEntry->vhtCapability && |
| (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || |
| IS_BSS_VHT_CAPABLE( |
| pBeaconStruct->vendor2_ie.VHTCaps))) { |
| pAddBssParams->staContext.vhtCapable = 1; |
| pAddBssParams->staContext.vhtSupportedRxNss = pStaDs->vhtSupportedRxNss; |
| if (pAssocRsp->VHTCaps.present) |
| vht_caps = &pAssocRsp->VHTCaps; |
| else if (pAssocRsp->vendor2_ie.VHTCaps.present) { |
| vht_caps = |
| &pAssocRsp->vendor2_ie.VHTCaps; |
| limLog(pMac, LOG1, |
| FL("VHT Caps is present in vendor Specfic IE")); |
| isVHTCapInVendorIE = 1; |
| } |
| if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap || |
| vht_caps->muBeamformerCap) && |
| psessionEntry->txBFIniFeatureEnabled) |
| pAddBssParams->staContext.vhtTxBFCapable = 1; |
| if ((vht_caps != NULL) && |
| vht_caps->muBeamformerCap && |
| psessionEntry->txMuBformee) |
| pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; |
| } |
| #endif |
| if( (pAssocRsp->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp) ) |
| { |
| pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet; |
| #ifdef WLAN_FEATURE_11AC |
| if (pAssocRsp->VHTCaps.present) |
| vht_oper = &pAssocRsp->VHTOperation; |
| else if (pAssocRsp->vendor2_ie.VHTCaps.present) { |
| vht_oper = &pAssocRsp->vendor2_ie.VHTOperation; |
| limLog(pMac, LOG1, FL("VHT Operation is present in vendor Specfic IE")); |
| } |
| |
| if ((vht_oper != NULL) && |
| pAddBssParams->staContext.vhtCapable) |
| pAddBssParams->staContext.vhtTxChannelWidthSet = vht_oper->chanWidth; //pMac->lim.apChanWidth; |
| |
| |
| limLog(pMac, LOG2,FL("StaContext vhtCapable %d " |
| "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), |
| pAddBssParams->staContext.vhtCapable, |
| pAddBssParams->staContext.vhtTxChannelWidthSet, |
| pAddBssParams->staContext.vhtTxBFCapable); |
| #endif |
| } |
| else |
| { |
| pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, |
| WNI_CFG_VHT_ENABLE_TXBF_20MHZ, |
| &enableTxBF20MHz))) { |
| if (VOS_FALSE == enableTxBF20MHz) { |
| pAddBssParams->staContext.vhtTxBFCapable = 0; |
| } |
| } |
| } |
| 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; |
| /* |
| * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. |
| * if they are set then we will use what ever Assoc response coming |
| * from AP supports. If these values are set as 0 in ini file then |
| * we will hardcode this values to 0. |
| */ |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_20MHZ, |
| &shortGi20MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi20MhzSupport) |
| { |
| pAddBssParams->staContext.fShortGI20Mhz = |
| (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz; |
| } |
| else |
| { |
| pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" |
| "CFG,setting value to default"));) |
| pAddBssParams->staContext.fShortGI20Mhz = |
| WNI_CFG_SHORT_GI_20MHZ_STADEF; |
| } |
| |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_40MHZ, |
| &shortGi40MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi40MhzSupport) |
| { |
| pAddBssParams->staContext.fShortGI40Mhz = |
| (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz; |
| } |
| else |
| { |
| pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" |
| "CFG,setting value to default"));) |
| pAddBssParams->staContext.fShortGI40Mhz = |
| WNI_CFG_SHORT_GI_40MHZ_STADEF; |
| } |
| |
| #ifdef WLAN_FEATURE_11AC |
| if (!pAddBssParams->staContext.vhtCapable) |
| // Use max ampd factor advertised in HTCAP for non-vht connection |
| #endif |
| { |
| pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor; |
| } |
| else if (pAddBssParams->staContext.maxAmpduSize < pAssocRsp->HTCaps.maxRxAMPDUFactor) |
| { |
| pAddBssParams->staContext.maxAmpduSize = pAssocRsp->HTCaps.maxRxAMPDUFactor; |
| } |
| if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) |
| { |
| pAddBssParams->staContext.htLdpcCapable = 0; |
| pAddBssParams->staContext.vhtLdpcCapable = 0; |
| } |
| else |
| { |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) |
| pAddBssParams->staContext.htLdpcCapable = |
| (tANI_U8)pAssocRsp->HTCaps.advCodingCap; |
| else |
| pAddBssParams->staContext.htLdpcCapable = 0; |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) { |
| if (!isVHTCapInVendorIE) |
| pAddBssParams->staContext.vhtLdpcCapable = |
| (tANI_U8)pAssocRsp->VHTCaps.ldpcCodingCap; |
| else |
| pAddBssParams->staContext.vhtLdpcCapable = |
| (tANI_U8)vht_caps->ldpcCodingCap; |
| } else { |
| pAddBssParams->staContext.vhtLdpcCapable = 0; |
| } |
| } |
| |
| if( pBeaconStruct->HTInfo.present ) |
| pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode; |
| |
| limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d" |
| " delBASupport: %d maxAmsduSize: %d"), |
| pAddBssParams->staContext.txChannelWidthSet, |
| pAddBssParams->staContext.mimoPS, |
| pAddBssParams->staContext.delBASupport, |
| pAddBssParams->staContext.maxAmsduSize); |
| |
| limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " |
| "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, |
| pAddBssParams->staContext.fDsssCckMode40Mhz, |
| pAddBssParams->staContext.fShortGI20Mhz); |
| |
| limLog(pMac, LOG2, FL("fShortGI40Mh: %d maxAmpduSize: %d " |
| "htLdpcCapable: %d vhtLdpcCapable: %d"), |
| pAddBssParams->staContext.fShortGI40Mhz, |
| pAddBssParams->staContext.maxAmpduSize, |
| pAddBssParams->staContext.htLdpcCapable, |
| pAddBssParams->staContext.vhtLdpcCapable); |
| } |
| pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId; |
| pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent; |
| pAddBssParams->staContext.wpa_rsn |= (pBeaconStruct->wpaPresent << 1); |
| /* For OSEN Connection AP does not advertise RSN or WPA IE |
| * so from the IEs we get from supplicant we get this info |
| * so for FW to transmit EAPOL message 4 we shall set |
| * wpa_rsn |
| */ |
| if ((!pAddBssParams->staContext.wpa_rsn) && (psessionEntry->isOSENConnection)) |
| pAddBssParams->staContext.wpa_rsn = 1; |
| vos_mem_copy(&pAddBssParams->staContext.capab_info, |
| &pAssocRsp->capabilityInfo, |
| sizeof(pAddBssParams->staContext.capab_info)); |
| vos_mem_copy(&pAddBssParams->staContext.ht_caps, |
| (tANI_U8 *)&pAssocRsp->HTCaps + sizeof(tANI_U8), |
| sizeof(pAddBssParams->staContext.ht_caps)); |
| |
| //If WMM IE or 802.11E IE is present then enable WMM |
| 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); |
| vos_mem_copy((tANI_U8*)&pAddBssParams->staContext.supportedRates, |
| (tANI_U8*)&pStaDs->supportedRates, |
| sizeof(tSirSupportedRates)); |
| } |
| else |
| PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates."));) |
| |
| } |
| |
| pAddBssParams->staContext.encryptType = psessionEntry->encryptType; |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| pAddBssParams->maxTxPower = psessionEntry->maxTxPower; |
| limLog(pMac, LOG2,FL("maxTxPower: %d"), |
| pAddBssParams->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 (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) |
| { |
| pAddBssParams->staContext.p2pCapableSta = 1; |
| } |
| |
| pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; |
| |
| #if defined WLAN_FEATURE_VOWIFI_11R |
| pAddBssParams->extSetStaKeyParamValid = 0; |
| limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"), |
| pAddBssParams->extSetStaKeyParamValid); |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| if (psessionEntry->limRmfEnabled) |
| { |
| pAddBssParams->rmfEnabled = 1; |
| pAddBssParams->staContext.rmfEnabled = 1; |
| } |
| #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, psessionEntry->peSessionId, psessionEntry->limMlmState)); |
| |
| if (!pAddBssParams->staContext.htLdpcCapable) |
| pAddBssParams->staContext.ht_caps &= |
| ~(1 << SIR_MAC_HT_CAP_ADVCODING_S); |
| if (!pAddBssParams->staContext.vhtLdpcCapable) |
| pAddBssParams->staContext.vht_caps &= |
| ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP); |
| |
| limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d " |
| "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, |
| pAddBssParams->staContext.encryptType, |
| pAddBssParams->staContext.p2pCapableSta); |
| |
| limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " |
| "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, |
| pAddBssParams->halPersona, psessionEntry->limMlmState); |
| if (psessionEntry->isNonRoamReassoc) { |
| pAddBssParams->nonRoamReassoc = 1; |
| } |
| //we need to defer the message until we get the response back from HAL. |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, false); |
| |
| if (psessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ) |
| pAddBssParams->channelwidth = CH_WIDTH_5MHZ; |
| else if (psessionEntry->sub20_channelwidth == SUB20_MODE_10MHZ) |
| pAddBssParams->channelwidth = CH_WIDTH_10MHZ; |
| |
| 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("SessionId:%d Sending WDA_ADD_BSS_REQ"), |
| psessionEntry->peSessionId); |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| |
| retCode = wdaPostCtrlMsg( pMac, &msgQ ); |
| if( eSIR_SUCCESS != retCode) |
| { |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), |
| retCode ); |
| goto returnFailure; |
| |
| } |
| else |
| return retCode; |
| |
| returnFailure: |
| if (pAddBssParams != NULL) |
| vos_mem_free(pAddBssParams); |
| // 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; |
| tSchBeaconStruct *pBeaconStruct; |
| tANI_U8 chanWidthSupp = 0; |
| tANI_U32 shortGi20MhzSupport; |
| tANI_U32 shortGi40MhzSupport; |
| tpSirBssDescription bssDescription = &psessionEntry->pLimJoinReq->bssDescription; |
| tDot11fIEVHTCaps *vht_caps = NULL; |
| |
| pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); |
| if (NULL == pBeaconStruct) |
| { |
| limLog(pMac, LOGE, FL("Unable to allocate memory during ADD_BSS") ); |
| return eSIR_MEM_ALLOC_FAILED; |
| } |
| |
| |
| // Package SIR_HAL_ADD_BSS_REQ message parameters |
| pAddBssParams = vos_mem_malloc(sizeof(tAddBssParams)); |
| if (NULL == pAddBssParams) |
| { |
| limLog( pMac, LOGP, |
| FL( "Unable to allocate memory during ADD_BSS" )); |
| retCode = eSIR_MEM_ALLOC_FAILED; |
| goto returnFailure; |
| } |
| |
| vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); |
| |
| |
| limExtractApCapabilities(pMac, |
| (tANI_U8 *) bssDescription->ieFields, |
| GET_IE_LEN_IN_BSS(bssDescription->length), |
| pBeaconStruct); |
| |
| if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) |
| limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); |
| vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId, |
| sizeof(tSirMacAddr)); |
| |
| // Fill in tAddBssParams selfMacAddr |
| vos_mem_copy(pAddBssParams->selfMacAddr, |
| psessionEntry->selfMacAddr, |
| sizeof(tSirMacAddr)); |
| limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d"), |
| psessionEntry->smeSessionId, updateEntry, |
| GET_LIM_SYSTEM_ROLE(psessionEntry)); |
| |
| limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), |
| MAC_ADDR_ARRAY(pAddBssParams->bssId)); |
| /* 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 = 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 = pBeaconStruct->supportedRates.numRates; |
| vos_mem_copy(pAddBssParams->rateSet.rate, |
| pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); |
| |
| pAddBssParams->nwType = bssDescription->nwType; |
| |
| pAddBssParams->shortSlotTimeSupported = (tANI_U8)pBeaconStruct->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; |
| |
| limLog(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " |
| "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, |
| pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); |
| |
| limLog(pMac, LOG2, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" |
| " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, |
| pAddBssParams->cfParamSet.cfpMaxDuration, |
| pAddBssParams->cfParamSet.cfpDurRemaining, |
| pAddBssParams->rateSet.numRates); |
| |
| limLog(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d" |
| "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), |
| pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, |
| pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, |
| pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); |
| // Use the advertised capabilities from the received beacon/PR |
| if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) |
| { |
| pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; |
| limLog(pMac, LOG2, FL("htCapable: %d"),pAddBssParams->htCapable); |
| if ( pBeaconStruct->HTInfo.present ) |
| { |
| pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode; |
| pAddBssParams->dualCTSProtection = ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection; |
| |
| chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); |
| if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp) ) |
| { |
| pAddBssParams->txChannelWidthSet = ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet; |
| pAddBssParams->currentExtChannel = pBeaconStruct->HTInfo.secondaryChannelOffset; |
| } |
| else |
| { |
| pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; |
| pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; |
| } |
| pAddBssParams->llnNonGFCoexist = (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent; |
| pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport; |
| pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode; |
| |
| limLog(pMac, LOG2, FL("htOperMode: %d dualCTSProtection: %d " |
| "txChannelWidthSet: %d currentExtChannel: %d "), |
| pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, |
| pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); |
| |
| limLog(pMac, LOG2, FL("llnNonGFCoexist: %d " |
| "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), |
| pAddBssParams->llnNonGFCoexist, |
| pAddBssParams->fLsigTXOPProtectionFullSupport, |
| pAddBssParams->fRIFSMode); |
| } |
| } |
| |
| pAddBssParams->currentOperChannel = bssDescription->channelId; |
| limLog(pMac, LOG2, FL("currentOperChannel %d"), |
| pAddBssParams->currentOperChannel); |
| #ifdef WLAN_FEATURE_11AC |
| if (psessionEntry->vhtCapability && |
| (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || |
| IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) { |
| pAddBssParams->vhtCapable = 1; |
| /* |
| * in limExtractApCapability function intersection of FW advertised |
| * channel width and AP advertised channel width has been taken into |
| * account for calculating psessionEntry->apChanWidth |
| */ |
| pAddBssParams->vhtTxChannelWidthSet = psessionEntry->apChanWidth; |
| |
| pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, |
| pAddBssParams->currentOperChannel, |
| pAddBssParams->currentExtChannel, |
| psessionEntry->apCenterChan, |
| psessionEntry); |
| pAddBssParams->staContext.maxAmpduSize = |
| SIR_MAC_GET_VHT_MAX_AMPDU_EXPO( |
| pAddBssParams->staContext.vht_caps); |
| } |
| else |
| { |
| pAddBssParams->vhtCapable = 0; |
| } |
| limLog(pMac, LOG2, FL("vhtCapable %d vhtTxChannelWidthSet %d " |
| "currentExtChannel %d"),pAddBssParams->vhtCapable, |
| pAddBssParams->vhtTxChannelWidthSet, |
| pAddBssParams->currentExtChannel); |
| #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 |
| |
| vos_mem_copy(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)pBeaconStruct->capabilityInfo.shortPreamble; |
| pAddBssParams->staContext.updateSta = updateEntry; |
| |
| limLog(pMac, LOG2, FL("StaContext: "MAC_ADDRESS_STR |
| " shortPreambleSupported: %d"), |
| MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), |
| pAddBssParams->staContext.shortPreambleSupported); |
| |
| pAddBssParams->dot11_mode = psessionEntry->dot11mode; |
| limLog(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode); |
| |
| if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) |
| { |
| pAddBssParams->staContext.us32MaxAmpduDuration = 0; |
| pAddBssParams->staContext.htCapable = 1; |
| pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) pBeaconStruct->HTCaps.greenField; |
| pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection; |
| limLog(pMac, LOG2, FL("StaContext htCapable: %d " |
| "greenFieldCapable: %d lsigTxopProtection: %d"), |
| pAddBssParams->staContext.htCapable, |
| pAddBssParams->staContext.greenFieldCapable, |
| pAddBssParams->staContext.lsigTxopProtection); |
| #ifdef WLAN_FEATURE_11AC |
| if (psessionEntry->vhtCapability && |
| (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) || |
| IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) { |
| pAddBssParams->staContext.vhtCapable = 1; |
| if (pBeaconStruct->VHTCaps.present) |
| vht_caps = &pBeaconStruct->VHTCaps; |
| else if ( |
| pBeaconStruct->vendor2_ie.VHTCaps.present) |
| vht_caps = |
| &pBeaconStruct->vendor2_ie.VHTCaps; |
| |
| if ((vht_caps != NULL) && |
| (vht_caps->suBeamFormerCap || |
| vht_caps->muBeamformerCap) && |
| psessionEntry->txBFIniFeatureEnabled) |
| pAddBssParams->staContext.vhtTxBFCapable = 1; |
| if ((vht_caps != NULL) && vht_caps->muBeamformerCap && |
| psessionEntry->txMuBformee) |
| pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; |
| |
| } |
| #endif |
| if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && |
| (chanWidthSupp) ) |
| { |
| pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; |
| #ifdef WLAN_FEATURE_11AC |
| if (pAddBssParams->staContext.vhtCapable) |
| { |
| /* |
| * in limExtractApCapability function intersection of FW |
| * advertised channel width and AP advertised channel width |
| * has been taken into account for calculating |
| * psessionEntry->apChanWidth |
| */ |
| pAddBssParams->staContext.vhtTxChannelWidthSet = |
| psessionEntry->apChanWidth; |
| } |
| limLog(pMac, LOG2,FL("StaContext vhtCapable %d " |
| "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), |
| pAddBssParams->staContext.vhtCapable, |
| pAddBssParams->staContext.vhtTxChannelWidthSet, |
| pAddBssParams->staContext.vhtTxBFCapable); |
| #endif |
| } |
| else |
| { |
| pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; |
| } |
| pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave; |
| pAddBssParams->staContext.delBASupport = ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA; |
| pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize; |
| pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; |
| pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz; |
| /* |
| * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. |
| * if they are set then we will use what ever Beacon coming from AP |
| * supports. If these values are set as 0 in ini file then |
| * we will hardcode this values to 0. |
| */ |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_20MHZ, |
| &shortGi20MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi20MhzSupport) |
| { |
| pAddBssParams->staContext.fShortGI20Mhz = |
| (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz; |
| } |
| else |
| { |
| pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" |
| "CFG,setting value to default"));) |
| pAddBssParams->staContext.fShortGI20Mhz = |
| WNI_CFG_SHORT_GI_20MHZ_STADEF; |
| } |
| |
| if (HAL_STATUS_SUCCESS(ccmCfgGetInt |
| (pMac, WNI_CFG_SHORT_GI_40MHZ, |
| &shortGi40MhzSupport))) |
| { |
| if (VOS_TRUE == shortGi40MhzSupport) |
| { |
| pAddBssParams->staContext.fShortGI40Mhz = |
| (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz; |
| } |
| else |
| { |
| pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; |
| } |
| } |
| else |
| { |
| PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" |
| "CFG,setting value to default"));) |
| pAddBssParams->staContext.fShortGI40Mhz = |
| WNI_CFG_SHORT_GI_40MHZ_STADEF; |
| } |
| |
| pAddBssParams->staContext.maxAmpduSize= pBeaconStruct->HTCaps.maxRxAMPDUFactor; |
| if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) |
| { |
| pAddBssParams->staContext.htLdpcCapable = 0; |
| pAddBssParams->staContext.vhtLdpcCapable = 0; |
| } |
| else |
| { |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) |
| pAddBssParams->staContext.htLdpcCapable = |
| (tANI_U8)pBeaconStruct->HTCaps.advCodingCap; |
| else |
| pAddBssParams->staContext.htLdpcCapable = 0; |
| if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) |
| pAddBssParams->staContext.vhtLdpcCapable = |
| (tANI_U8)pBeaconStruct->VHTCaps.ldpcCodingCap; |
| else |
| pAddBssParams->staContext.vhtLdpcCapable = 0; |
| } |
| |
| if( pBeaconStruct->HTInfo.present ) |
| pAddBssParams->staContext.rifsMode = pBeaconStruct->HTInfo.rifsMode; |
| limLog(pMac, LOG2, FL("StaContext txChannelWidthSet: %d mimoPS: %d" |
| " delBASupport: %d maxAmsduSize: %d"), |
| pAddBssParams->staContext.txChannelWidthSet, |
| pAddBssParams->staContext.mimoPS, |
| pAddBssParams->staContext.delBASupport, |
| pAddBssParams->staContext.maxAmsduSize); |
| |
| limLog(pMac, LOG2, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " |
| "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, |
| pAddBssParams->staContext.fDsssCckMode40Mhz, |
| pAddBssParams->staContext.fShortGI20Mhz); |
| |
| limLog(pMac, LOG2, FL("fShortGI40Mh: %d maxAmpduSize: %d " |
| "htLdpcCapable: %d vhtLdpcCapable: %d"), |
| pAddBssParams->staContext.fShortGI40Mhz, |
| pAddBssParams->staContext.maxAmpduSize, |
| pAddBssParams->staContext.htLdpcCapable, |
| pAddBssParams->staContext.vhtLdpcCapable); |
| } |
| |
| //If WMM IE or 802.11E IE is not present and AP is HT AP then enable WMM |
| if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent || pAddBssParams->staContext.htCapable)) || |
| (psessionEntry->limQosEnabled && (pBeaconStruct->edcaPresent || pAddBssParams->staContext.htCapable))) |
| pAddBssParams->staContext.wmmEnabled = 1; |
| else |
| pAddBssParams->staContext.wmmEnabled = 0; |
| |
| //Update the rates |
| #ifdef WLAN_FEATURE_11AC |
| limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, |
| pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry, |
| &pBeaconStruct->VHTCaps); |
| #else |
| limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, |
| pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry); |
| #endif |
| limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,psessionEntry); |
| |
| } |
| |
| pAddBssParams->staContext.encryptType = psessionEntry->encryptType; |
| |
| #if defined WLAN_FEATURE_VOWIFI |
| pAddBssParams->maxTxPower = psessionEntry->maxTxPower; |
| limLog(pMac, LOG2,FL("maxTxPower: %d"), |
| pAddBssParams->maxTxPower); |
| #endif |
| |
| pAddBssParams->status = eHAL_STATUS_SUCCESS; |
| pAddBssParams->respReqd = true; |
| |
| pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId; |
| 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; |
| limLog(pMac, LOG2,FL("extSetStaKeyParamValid: %d"), |
| pAddBssParams->extSetStaKeyParamValid); |
| #endif |
| |
| #ifdef WLAN_FEATURE_11W |
| if (psessionEntry->limRmfEnabled) |
| { |
| pAddBssParams->rmfEnabled = 1; |
| pAddBssParams->staContext.rmfEnabled = 1; |
| } |
| #endif |
| |
| // Set a new state for MLME |
| psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE; |
| |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); |
| |
| limLog(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d " |
| "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, |
| pAddBssParams->staContext.encryptType, |
| pAddBssParams->staContext.p2pCapableSta); |
| |
| limLog(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " |
| "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, |
| pAddBssParams->halPersona, psessionEntry->limMlmState); |
| |
| //we need to defer the message until we get the response back from HAL. |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, false); |
| |
| if (psessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ) |
| pAddBssParams->channelwidth = CH_WIDTH_5MHZ; |
| else if (psessionEntry->sub20_channelwidth == SUB20_MODE_10MHZ) |
| pAddBssParams->channelwidth = CH_WIDTH_10MHZ; |
| |
| 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("SessionId:%d Sending WDA_ADD_BSS_REQ"), |
| psessionEntry->peSessionId); |
| MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); |
| |
| retCode = wdaPostCtrlMsg( pMac, &msgQ ); |
| if( eSIR_SUCCESS != retCode) |
| { |
| SET_LIM_PROCESS_DEFD_MESGS(pMac, true); |
| vos_mem_free(pAddBssParams); |
| limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), |
| retCode ); |
| goto returnFailure; |
| |
| } |
| else |
| { |
| vos_mem_free(pBeaconStruct); |
| return retCode; |
| } |
| |
| returnFailure: |
| // Clean-up will be done by the caller... |
| vos_mem_free(pBeaconStruct); |
| return retCode; |
| } |
| |
| |
| |
| |
| |
| |
| /** ------------------------------------------------------------- |
| \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"));) |
| return; |
| } |
| staDsAssocId = pStaDs->assocId; |
| vos_mem_copy((tANI_U8 *)staDsAddr, |
| pStaDs->staAddr, |
| sizeof(tSirMacAddr)); |
| |
| mlmStaContext = pStaDs->mlmStaContext; |
| if (LIM_IS_AP_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) { |
| limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); |
| } |
| limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry); |
| |
| if (LIM_IS_STA_ROLE(psessionEntry) || |
| LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { |
| psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; |
| MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, |
| psessionEntry->peSessionId, psessionEntry->limMlmState)); |
| } |
| 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; |
| #ifdef WLAN_FEATURE_11AC |
| case WNI_CFG_DOT11_MODE_11AC: |
| return eSTA_11ac; |
| #endif |
| 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; |
| tLimPreAuthNode **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")); |
| return; |
| } |
| |
| cfgValue = SYS_MS_TO_TICKS(cfgValue); |
| for(authNodeIdx=0; authNodeIdx<pPreAuthTimerTable->numEntry; authNodeIdx++) |
| { |
| if (tx_timer_create(&(pAuthNode[authNodeIdx]->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."), authNodeIdx); |
| return; |
| } |
| pAuthNode[authNodeIdx]->authNodeIdx = (tANI_U8)authNodeIdx; |
| pAuthNode[authNodeIdx]->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++) { |
| if (pTempNode[i]->fFree == 1) { |
| pTempNode[i]->fFree = 0; |
| return pTempNode[i]; |
| } |
| } |
| |
| 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"), |
| 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" )); |
| 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"), |
| 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; |
| } |
| |
| #ifdef WLAN_FEATURE_11W |
| /** ------------------------------------------------------------- |
| \fn limSendSmeUnprotectedMgmtFrameInd |
| \brief Forwards the unprotected management frame to SME. |
| \param tpAniSirGlobal pMac |
| \param frameType - 802.11 frame type |
| \param frame - frame buffer |
| \param sessionId - id for the current session |
| \param psessionEntry - PE session context |
| \return none |
| -------------------------------------------------------------*/ |
| void limSendSmeUnprotectedMgmtFrameInd( |
| tpAniSirGlobal pMac, tANI_U8 frameType, |
| tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, |
| tpPESession psessionEntry) |
| { |
| tSirMsgQ mmhMsg; |
| tSirSmeUnprotMgmtFrameInd * pSirSmeMgmtFrame = NULL; |
| tANI_U16 length; |
| |
| length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen; |
| |
| pSirSmeMgmtFrame = vos_mem_malloc(length); |
| if (NULL == pSirSmeMgmtFrame) |
| { |
| limLog(pMac, LOGP, |
| FL("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd")); |
| return; |
| } |
| vos_mem_set((void*)pSirSmeMgmtFrame, length, 0); |
| |
| pSirSmeMgmtFrame->sessionId = sessionId; |
| pSirSmeMgmtFrame->frameType = frameType; |
| |
| vos_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen); |
| pSirSmeMgmtFrame->frameLen = frameLen; |
| |
| mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND; |
| mmhMsg.bodyptr = pSirSmeMgmtFrame; |
| mmhMsg.bodyval = 0; |
| |
| limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); |
| return; |
| } |
| #endif |
| |
| #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) |
| /** ------------------------------------------------------------- |
| \fn limSendSmeTsmIEInd |
| \brief Forwards the TSM IE information to SME. |
| \param tpAniSirGlobal pMac |
| \param psessionEntry - PE session context |
| \param tid - traffic id |
| \param state - tsm state (enabled/disabled) |
| \param measurementInterval - measurement interval |
| \return none |
| -------------------------------------------------------------*/ |
| void limSendSmeTsmIEInd(tpAniSirGlobal pMac, tpPESession psessionEntry, |
| tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval) |
| { |
| tSirMsgQ mmhMsg; |
| tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL; |
| |
| if (!pMac || !psessionEntry) |
| { |
| return; |
| } |
| pSirSmeTsmIeInd = vos_mem_malloc(sizeof(tSirSmeTsmIEInd)); |
| if (NULL == pSirSmeTsmIeInd) |
| { |
| limLog(pMac, LOGP, |
| FL("AllocateMemory failed for tSirSmeTsmIEInd")); |
| return; |
| } |
| vos_mem_set((void*)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0); |
| |
| pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId; |
| pSirSmeTsmIeInd->tsmIe.tsid = tid; |
| pSirSmeTsmIeInd->tsmIe.state= state; |
| pSirSmeTsmIeInd->tsmIe.msmt_interval= measInterval; |
| |
| mmhMsg.type = eWNI_SME_TSM_IE_IND; |
| mmhMsg.bodyptr = pSirSmeTsmIeInd; |
| mmhMsg.bodyval = 0; |
| |
| limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); |
| return; |
| } |
| #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ |