/*
 * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*
 * This file lim_assoc_utils.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 "cds_api.h"
#include "ani_global.h"
#include "wni_api.h"
#include "sir_common.h"

#include "wni_cfg.h"
#include "cfg_api.h"

#include "sch_api.h"
#include "utils_api.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_security_utils.h"
#include "lim_ser_des_utils.h"
#include "lim_sta_hash_api.h"
#include "lim_admit_control.h"
#include "lim_send_messages.h"
#include "lim_ibss_peer_mgmt.h"
#ifdef WLAN_FEATURE_VOWIFI_11R
#include "lim_ft_defs.h"
#endif
#include "lim_session.h"

#include "qdf_types.h"
#include "wma_types.h"
#include "lim_types.h"

/*
 * fill up the rate info properly based on what is actually supported by the peer
 * TBD TBD TBD
 */
void
lim_fill_supported_rates_info(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 =
			lim_get_sta_rate_mode((uint8_t) psessionEntry->dot11mode);
	else
		pRates->opRateMode =
			lim_get_sta_peer_type(pMac, pSta, psessionEntry);

}

/**
 * lim_cmp_ssid() - utility function to compare SSIDs
 * @rx_ssid: Received SSID
 * @session_entry: Session entry
 *
 * This function is called in various places within LIM code
 * to determine whether received SSID is same as SSID in use.
 *
 * Return: true if SSID matched, false otherwise.
 */
uint32_t lim_cmp_ssid(tSirMacSSid *rx_ssid, tpPESession session_entry)
{
	return qdf_mem_cmp(rx_ssid, &session_entry->ssId,
				session_entry->ssId.length);
}

/**
 * lim_compare_capabilities()
 *
 ***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.
 */

uint8_t
lim_compare_capabilities(tpAniSirGlobal pMac,
			 tSirAssocReq *pAssocReq,
			 tSirMacCapabilityInfo *pLocalCapabs,
			 tpPESession psessionEntry)
{
	uint32_t val;

	if ((LIM_IS_AP_ROLE(psessionEntry) ||
	     LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
	    (pAssocReq->capabilityInfo.ibss)) {
		/* Requesting STA asserting IBSS capability. */
		lim_log(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 */
		lim_log(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 */
	}

	lim_log(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 */
		lim_log(pMac, LOG1,
			FL
				("Received unmatched QOS but cfg to suppress - continuing"));
	}

	/*
	 * 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_cfg_get_int
			    (pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY,
			    &val) != eSIR_SUCCESS) {
			lim_log(pMac, LOGP,
				FL
					("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY "));
			return false;
		}
		if (val) {
			if (pAssocReq->capabilityInfo.shortSlotTime !=
			    pLocalCapabs->shortSlotTime) {
				lim_log(pMac, LOGE,
					FL
						("AP rejects association as station doesnt support shortslot time"));
				return false;
			}
			return false;
		}
	}

	return true;
} /****** end lim_compare_capabilities() ******/

/**
 * lim_check_rx_basic_rates()
 *
 ***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.
 */

uint8_t
lim_check_rx_basic_rates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,
			 tpPESession psessionEntry)
{
	tSirMacRateSet *pRateSet, basicRate;
	uint8_t i, j, k, match;

	pRateSet = qdf_mem_malloc(sizeof(tSirMacRateSet));
	if (NULL == pRateSet) {
		lim_log(pMac, LOGP,
			FL("call to AllocateMemory failed for RATESET"));

		return false;
	}

	/* Copy operational rate set from session Entry */
	qdf_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 */
			qdf_mem_free((uint8_t *) pRateSet);

			return false;
		}
	}

	/* Free up memory allocated for rateset */
	qdf_mem_free((uint8_t *) pRateSet);

	return true;
} /****** end lim_check_rx_basic_rates() ******/

/**
 * lim_check_mcs_set()
 *
 ***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.
 */

uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet)
{
	uint8_t basicMCSSet[SIZE_OF_BASIC_MCS_SET] = { 0 };
	uint32_t cfgLen = 0;
	uint8_t i;
	uint8_t validBytes;
	uint8_t lastByteMCSMask = 0x1f;

	cfgLen = WNI_CFG_BASIC_MCS_SET_LEN;
	if (wlan_cfg_get_str(pMac, WNI_CFG_BASIC_MCS_SET,
			     (uint8_t *) basicMCSSet,
			     (uint32_t *) &cfgLen) != eSIR_SUCCESS) {
		/* / Could not get Basic MCS rateset from CFG. Log error. */
		lim_log(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 lim_process_assoc_req_frame.c */
			lim_log(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)) {
		lim_log(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

/**
 * lim_check_rx_rsn_ie_match()- validate received rsn ie with supported cipher
 *      suites.
 * @mac_ctx: pointer to global mac structure
 * @rx_rsn_ie: received rsn IE
 * @session_entry: pe session entry
 * @sta_is_ht: peer station HT capability
 * @pmf_connection: set to true if this is pmf connection
 *
 * 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.
 *
 * Return: eSIR_SUCCESS if ALL BSS basic rates are present in the
 *                  received rateset else failure status.
 */

uint8_t
lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx, tDot11fIERSN rx_rsn_ie,
			  tpPESession session_entry, uint8_t sta_is_ht,
			  bool *pmf_connection)
{
	tDot11fIERSN *rsn_ie;
	uint8_t i, j, match, only_non_ht_cipher = 1;
#ifdef WLAN_FEATURE_11W
	bool we_are_pmf_capable;
	bool we_require_pmf;
	bool they_are_pmf_capable;
	bool they_require_pmf;
#endif

	/* RSN IE should be received from PE */
	rsn_ie = &session_entry->gStartBssRSNIe;

	/* Check groupwise cipher suite */
	for (i = 0; i < sizeof(rx_rsn_ie.gp_cipher_suite); i++)
		if (rsn_ie->gp_cipher_suite[i] !=
				 rx_rsn_ie.gp_cipher_suite[i]) {
			lim_log(mac_ctx, 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 < rx_rsn_ie.pwise_cipher_suite_count; i++) {
		for (j = 0; j < rsn_ie->pwise_cipher_suite_count; j++) {
			if (!qdf_mem_cmp(&rx_rsn_ie.pwise_cipher_suites[i],
				&rsn_ie->pwise_cipher_suites[j],
				sizeof(rsn_ie->pwise_cipher_suites[j]))) {
				match = 1;
				break;
			}
		}

		if ((sta_is_ht)
#ifdef ANI_LITTLE_BYTE_ENDIAN
			&&
			((rx_rsn_ie.pwise_cipher_suites[i][3] &
				 SECURITY_SUITE_TYPE_MASK) ==
					SECURITY_SUITE_TYPE_CCMP))
#else
			&&
			((rx_rsn_ie.pwise_cipher_suites[i][0] &
				 SECURITY_SUITE_TYPE_MASK) ==
					SECURITY_SUITE_TYPE_CCMP))
#endif
			only_non_ht_cipher = 0;

	}

	if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
		lim_log(mac_ctx, LOG1, FL("Invalid pairwise cipher suite"));
		return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
	}
	/*
	 * Check RSN capabilities
	 * Bit 0 of First Byte - PreAuthentication Capability
	 */
	if (((rx_rsn_ie.RSN_Cap[0] >> 0) & 0x1) == true) {
		/* this is supported by AP only */
		lim_log(mac_ctx, LOG1,
			FL("Invalid RSN information element capabilities"));
		return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
	}

	*pmf_connection = false;

#ifdef WLAN_FEATURE_11W
	we_are_pmf_capable = session_entry->pLimStartBssReq->pmfCapable;
	we_require_pmf = session_entry->pLimStartBssReq->pmfRequired;
	they_are_pmf_capable = (rx_rsn_ie.RSN_Cap[0] >> 7) & 0x1;
	they_require_pmf = (rx_rsn_ie.RSN_Cap[0] >> 6) & 0x1;

	if ((they_require_pmf && they_are_pmf_capable && !we_are_pmf_capable) ||
	    (we_require_pmf && !they_are_pmf_capable)) {
		lim_log(mac_ctx, LOG1,
			FL("Association fail, robust management frames policy"
				" violation they_require_pmf =%d"
				" theyArePMFCapable %d weArePMFCapable %d"
				" weRequirePMF %d theyArePMFCapable %d"),
			they_require_pmf, they_are_pmf_capable,
			we_are_pmf_capable, we_require_pmf,
			they_are_pmf_capable);
		return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION;
	}

	if (they_are_pmf_capable && we_are_pmf_capable)
		*pmf_connection = true;

	lim_log(mac_ctx, LOG1,
		FL("weAreCapable %d, weRequire %d, theyAreCapable %d,"
			" theyRequire %d, PMFconnection %d"),
		we_are_pmf_capable, we_require_pmf, they_are_pmf_capable,
		they_require_pmf, *pmf_connection);
#endif

	return eSIR_SUCCESS;
}

/**
 * lim_check_rx_wpa_ie_match() - to check supported cipher suites
 *
 * @mac: pointer to global mac structure
 * @rx_wpaie: Received WPA IE in (Re)Assco req
 * @session_entry: pointer to PE session
 * @sta_is_ht: peer station is HT
 *
 * 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.
 *
 * Return: Success if ALL BSS basic rates are present in the
 *                  received rateset else failure status.
 */

uint8_t
lim_check_rx_wpa_ie_match(tpAniSirGlobal mac, tDot11fIEWPA rx_wpaie,
			  tpPESession session_entry, uint8_t sta_is_ht)
{
	tDot11fIEWPA *wpa_ie;
	uint8_t i, j, match, only_non_ht_cipher = 1;

	/* WPA IE should be received from PE */
	wpa_ie = &session_entry->gStartBssWPAIe;

	/* Check groupwise cipher suite */
	for (i = 0; i < 4; i++) {
		if (wpa_ie->multicast_cipher[i] != rx_wpaie.multicast_cipher[i]) {
			lim_log(mac, 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 < rx_wpaie.unicast_cipher_count; i++) {
		for (j = 0; j < wpa_ie->unicast_cipher_count; j++) {
			if (!qdf_mem_cmp(rx_wpaie.unicast_ciphers[i],
					    wpa_ie->unicast_ciphers[j], 4)) {
				match = 1;
				break;
			}
		}

		if ((sta_is_ht)
#ifdef ANI_LITTLE_BYTE_ENDIAN
		    &&
		    ((rx_wpaie.
		      unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) ==
		     SECURITY_SUITE_TYPE_CCMP))
#else
		    &&
		    ((rx_wpaie.
		      unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) ==
		     SECURITY_SUITE_TYPE_CCMP))
#endif
		{
			only_non_ht_cipher = 0;
		}

	}

	if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
		lim_log(mac, LOG1, FL("Invalid pairwise cipher suite"));
		return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
	}

	return eSIR_SUCCESS;
}

/**
 * lim_cleanup_rx_path()
 *
 ***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
lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
		    tpPESession psessionEntry)
{
	tSirRetStatus retCode = eSIR_SUCCESS;

	lim_log(pMac, LOG1, FL("Cleanup Rx Path for AID : %d"
		"psessionEntry->limSmeState : %d, mlmState : %d"),
		pStaDs->assocId, psessionEntry->limSmeState,
		pStaDs->mlmStaContext.mlmState);

	psessionEntry->isCiscoVendorAP = false;

	if (pMac->lim.gLimAddtsSent) {
		MTRACE(mac_trace
			       (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) {
		lim_deactivate_and_change_per_sta_id_timer(pMac, eLIM_CNF_WAIT_TIMER,
							   pStaDs->assocId);

		if (!pStaDs->mlmStaContext.updateContext) {
			/**
			 * There is no context at Polaris to delete.
			 * Release our assigned AID back to the free pool
			 */
			if (LIM_IS_AP_ROLE(psessionEntry) ||
			    LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
				lim_release_peer_idx(pMac, pStaDs->assocId,
						     psessionEntry);
			}
			lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
						  pStaDs->assocId, psessionEntry);

			return retCode;
		}
	}
	/* delete all tspecs associated with this sta. */
	lim_admit_control_delete_sta(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;
	lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
	/* Any roaming related changes should be above this line */
	if (psessionEntry->bRoamSynchInProgress)
		return eSIR_SUCCESS;
	pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;

	if (LIM_IS_STA_ROLE(psessionEntry) ||
	    LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
		MTRACE(mac_trace
		       (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 */
		lim_deactivate_and_change_timer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
		lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
		pMac->lim.gLastBeaconDtimCount = 0;
		pMac->lim.gLastBeaconDtimPeriod = 0;


	}
#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 =
				lim_del_bss(pMac, pStaDs, psessionEntry->bssIdx,
					    psessionEntry);
		} else
			retCode = lim_del_sta(pMac,
					 pStaDs, true, psessionEntry);
	}

	return retCode;

} /*** end lim_cleanup_rx_path() ***/

/**
 * lim_send_del_sta_cnf() - Send Del sta confirmation
 * @pMac: Pointer to Global MAC structure
 * @sta_dsaddr: sta ds address
 * @staDsAssocId: sta ds association id
 * @mlmStaContext: MLM station context
 * @statusCode: Status code
 * @psessionEntry: Session entry
 *
 * This function is called to send appropriate CNF message to SME.
 *
 * Return: None
 */
void
lim_send_del_sta_cnf(tpAniSirGlobal pMac, struct qdf_mac_addr sta_dsaddr,
		     uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
		     tSirResultCodes statusCode, tpPESession psessionEntry)
{
	tLimMlmDisassocCnf mlmDisassocCnf;
	tLimMlmDeauthCnf mlmDeauthCnf;
	tLimMlmPurgeStaInd mlmPurgeStaInd;

	lim_log(pMac, LOG1,
		FL("Sessionid: %d staDsAssocId: %d Trigger: %d statusCode: %d sta_dsaddr: "MAC_ADDRESS_STR),
		psessionEntry->peSessionId, staDsAssocId,
		mlmStaContext.cleanupTrigger, statusCode,
		MAC_ADDR_ARRAY(sta_dsaddr.bytes));

	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 };

		sir_copy_mac_addr(nullAddr, psessionEntry->bssId);

		/* Free up buffer allocated for JoinReq held by */
		/* MLM state machine */
		if (psessionEntry->pLimMlmJoinReq) {
			qdf_mem_free(psessionEntry->pLimMlmJoinReq);
			psessionEntry->pLimMlmJoinReq = NULL;
		}

		psessionEntry->limAID = 0;

	} else if (
		(mlmStaContext.cleanupTrigger ==
			eLIM_LINK_MONITORING_DISASSOC) ||
		(mlmStaContext.cleanupTrigger ==
			eLIM_LINK_MONITORING_DEAUTH)) {
		/* only for non-STA cases PE/SME is serialized */
		return;
	}

	if ((mlmStaContext.cleanupTrigger ==
					eLIM_HOST_DISASSOC) ||
		(mlmStaContext.cleanupTrigger ==
					eLIM_LINK_MONITORING_DISASSOC) ||
		(mlmStaContext.cleanupTrigger ==
					eLIM_PROMISCUOUS_MODE_DISASSOC)) {
		/**
		 * Host or LMM driven Disassociation.
		 * Issue Disassoc Confirm to SME.
		 */
		lim_log(pMac, LOGW,
			FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"),
			mlmStaContext.cleanupTrigger);

		qdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr,
			     (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
		mlmDisassocCnf.resultCode = statusCode;
		mlmDisassocCnf.disassocTrigger = mlmStaContext.cleanupTrigger;
		/* Update PE session Id */
		mlmDisassocCnf.sessionId = psessionEntry->peSessionId;

		lim_post_sme_message(pMac,
				     LIM_MLM_DISASSOC_CNF,
				     (uint32_t *) &mlmDisassocCnf);
	} else if ((mlmStaContext.cleanupTrigger ==
					eLIM_HOST_DEAUTH) ||
			(mlmStaContext.cleanupTrigger ==
					eLIM_LINK_MONITORING_DEAUTH)) {
		/**
		 * Host or LMM driven Deauthentication.
		 * Issue Deauth Confirm to SME.
		 */
		lim_log(pMac, LOGW,
			FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %d"),
			mlmStaContext.cleanupTrigger);
		qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr, &sta_dsaddr);
		mlmDeauthCnf.resultCode = statusCode;
		mlmDeauthCnf.deauthTrigger = mlmStaContext.cleanupTrigger;
		/* PE session Id */
		mlmDeauthCnf.sessionId = psessionEntry->peSessionId;

		lim_post_sme_message(pMac,
				     LIM_MLM_DEAUTH_CNF,
				     (uint32_t *) &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.
		 */
		lim_log(pMac, LOGW,
			FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %d"),
			mlmStaContext.cleanupTrigger);
		qdf_mem_copy((uint8_t *) &mlmPurgeStaInd.peerMacAddr,
			     (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
		mlmPurgeStaInd.reasonCode =
			(uint8_t) mlmStaContext.disassocReason;
		mlmPurgeStaInd.aid = staDsAssocId;
		mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
		mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;

		lim_post_sme_message(pMac,
				     LIM_MLM_PURGE_STA_IND,
				     (uint32_t *) &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. */
		uint8_t smesessionId;
		uint16_t smetransactionId;

		smesessionId = psessionEntry->smeSessionId;
		smetransactionId = psessionEntry->transactionId;

		psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
		MTRACE(mac_trace
			       (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
			       psessionEntry->limSmeState));

		/* if it is a reassoc failure to join new AP */
		if ((mlmStaContext.resultCode ==
		     eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE)
		    || (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE)
		    || (mlmStaContext.resultCode ==
			eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE)) {
			lim_log(pMac, LOG1,
				FL("Lim Posting eWNI_SME_REASSOC_RSP to SME"
				"resultCode: %d, statusCode: %d,"
				"sessionId: %d"),
				mlmStaContext.resultCode,
				mlmStaContext.protStatusCode,
				psessionEntry->peSessionId);

			if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
				pe_delete_session(pMac, psessionEntry);
				psessionEntry = NULL;
			}

			lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP,
						      mlmStaContext.resultCode,
						      mlmStaContext.protStatusCode,
						      psessionEntry, smesessionId,
						      smetransactionId);
		} else {
			qdf_mem_free(psessionEntry->pLimJoinReq);
			psessionEntry->pLimJoinReq = NULL;

			lim_log(pMac, LOG1,
				FL("Lim Posting eWNI_SME_JOIN_RSP to SME."
				"resultCode: %d,statusCode: %d,"
				"sessionId: %d"),
				mlmStaContext.resultCode,
				mlmStaContext.protStatusCode,
				psessionEntry->peSessionId);

			if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
				pe_delete_session(pMac, psessionEntry);
				psessionEntry = NULL;
			}

			lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_JOIN_RSP,
						      mlmStaContext.resultCode,
						      mlmStaContext.protStatusCode,
						      psessionEntry, smesessionId,
						      smetransactionId);
		}

	}

	if (NULL != psessionEntry && !LIM_IS_AP_ROLE(psessionEntry)) {
		pe_delete_session(pMac, psessionEntry);
		psessionEntry = NULL;
	}
}

/**
 * lim_reject_association() - function to reject Re/Association Request
 *
 * @mac_ctx: pointer to global mac structure
 * @peer_addr: mac address of the peer
 * @sub_type: Indicates whether it is Association Request (=0) or
 *            Reassociation Request (=1) frame
 * @add_pre_auth_context:Indicates whether pre-auth context
 *                     to be added for this STA
 * @auth_type: Indicates auth type to be added
 * @sta_id: Indicates staId of the STA being rejected
 *          association
 * @delete_sta: Indicates whether to delete STA context
 *              at Polaris
 * @result_code: Indicates what reasonCode to be sent in
 *          Re/Assoc response to STA
 * @session_entry: pointer to PE session
 *
 * This function is called whenever Re/Association Request need
 * to be rejected due to failure in assigning an AID or failure
 * in adding STA context at Polaris or reject by applications.
 * 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
 *
 * Return: none
 */

void
lim_reject_association(tpAniSirGlobal mac_ctx, tSirMacAddr peer_addr,
			uint8_t sub_type, uint8_t add_pre_auth_context,
			tAniAuthType auth_type, uint16_t sta_id,
			uint8_t delete_sta, tSirResultCodes result_code,
			tpPESession session_entry)
{
	tpDphHashNode sta_ds;

	lim_log(mac_ctx, LOG1,
		FL("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " MAC_ADDRESS_STR),
		session_entry->peSessionId, auth_type, sub_type,
		add_pre_auth_context, sta_id, delete_sta, result_code,
		MAC_ADDR_ARRAY(peer_addr));

	if (add_pre_auth_context) {
		/* Create entry for this STA in pre-auth list */
		struct tLimPreAuthNode *auth_node;

		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
			       &mac_ctx->lim.gLimPreAuthTimerTable);

		if (auth_node) {
			qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
				     peer_addr, sizeof(tSirMacAddr));
			auth_node->fTimerStarted = 0;
			auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
			auth_node->authType = (tAniAuthType) auth_type;
			auth_node->timestamp = qdf_mc_timer_get_system_ticks();
			lim_add_pre_auth_node(mac_ctx, auth_node);
		}
	}

	if (delete_sta == false) {
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
				1, peer_addr, sub_type, 0, session_entry);
		/* Log error */
		lim_log(mac_ctx, LOGW,
			FL("received Re/Assoc req when max associated STAs reached from "));
		lim_print_mac_addr(mac_ctx, peer_addr, LOGW);
		lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr,
					session_entry->smeSessionId);
		return;
	}

	sta_ds = dph_get_hash_entry(mac_ctx, sta_id,
		   &session_entry->dph.dphHashTable);

	if (sta_ds == NULL) {
		lim_log(mac_ctx, LOGW,
			FL("No STA context, yet rejecting Association"));
		return;
	}

	/*
	 * Polaris has state for this STA.
	 * Trigger cleanup.
	 */
	sta_ds->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;

	/* Receive path cleanup */
	lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);

	/*
	 * Send Re/Association Response with
	 * status code to requesting STA.
	 */
	lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr,
					 sub_type, 0, session_entry);

	if (session_entry->parsedAssocReq[sta_ds->assocId] != NULL) {
		uint8_t *assoc_req_frame;

		assoc_req_frame = (uint8_t *)((tpSirAssocReq) (session_entry->
			parsedAssocReq[sta_ds->assocId]))->assocReqFrame;
		/*
		 *Assoction confirmation is complete,
		 *free the copy of association request frame.
		 */
		if (assoc_req_frame) {
			qdf_mem_free(assoc_req_frame);
			assoc_req_frame = NULL;
		}

		qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
		session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
	}
}

/**
 * lim_decide_ap_protection_on_ht20_delete() - function to update protection
 *                                              parameters.
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @beacon_params: ap beacon parameters
 * @session_entry: pe session entry
 *
 * protection related function while HT20 station is getting deleted.
 *
 * Return: none
 */
static void
lim_decide_ap_protection_on_ht20_delete(tpAniSirGlobal mac_ctx,
					tpDphHashNode sta_ds,
					tpUpdateBeaconParams beacon_params,
					tpPESession session_entry)
{
	uint32_t i = 0;

	lim_log(mac_ctx, LOG1,
			FL("(%d) A HT 20 STA is disassociated. Addr is %pM"),
			session_entry->gLimHt20Params.numSta, sta_ds->staAddr);

	if (session_entry->gLimHt20Params.numSta > 0) {
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (!session_entry->protStaCache[i].active)
				continue;

			if (!qdf_mem_cmp(session_entry->protStaCache[i].addr,
				sta_ds->staAddr, sizeof(tSirMacAddr))) {
				session_entry->gLimHt20Params.numSta--;
				session_entry->protStaCache[i].active =
						false;
				break;
			}
		}
	}

	if (session_entry->gLimHt20Params.numSta == 0) {
		/* disable protection */
		lim_log(mac_ctx, LOG1, FL("No 11B STA exists, PESessionID %d"),
					session_entry->peSessionId);
		lim_enable_ht20_protection(mac_ctx, false, false, beacon_params,
					session_entry);
	}
}

/**
 * lim_decide_ap_protection_on_delete() - update SAP protection on station
 *                                       deletion.
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @beacon_params: ap beacon parameters
 * @session_entry: pe session entry
 *
 * Decides about protection related settings when a station is getting deleted.
 *
 * Return: none
 */
void
lim_decide_ap_protection_on_delete(tpAniSirGlobal mac_ctx,
				   tpDphHashNode sta_ds,
				   tpUpdateBeaconParams beacon_params,
				   tpPESession session_entry)
{
	uint32_t phy_mode;
	tHalBitVal erp_enabled = eHAL_CLEAR;
	tSirRFBand rf_band = SIR_BAND_UNKNOWN;
	uint32_t i;

	if (NULL == sta_ds)
		return;

	lim_get_rf_band_new(mac_ctx, &rf_band, session_entry);
	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
	erp_enabled = sta_ds->erpEnabled;

	if ((SIR_BAND_5_GHZ == rf_band) &&
		(true == session_entry->htCapability) &&
		(session_entry->beaconParams.llaCoexist) &&
		(false == sta_ds->mlmStaContext.htCapability)) {
		/*
		 * we are HT. if we are 11A, then protection is not required or
		 * we are HT and 11A station is leaving.
		 * protection consideration required.
		 * HT station leaving ==> this case is commonly handled
		 * between both the bands below.
		 */
		lim_log(mac_ctx, LOG1,
			FL("(%d) A 11A STA is disassociated. Addr is %pM"),
			session_entry->gLim11aParams.numSta, sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->protStaCache[i].active &&
				(!qdf_mem_cmp(
					session_entry->protStaCache[i].addr,
					 sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				session_entry->protStaCache[i].active = false;
				break;
			}
		}

		if (session_entry->gLim11aParams.numSta == 0) {
			/* disable protection */
			lim_update_11a_protection(mac_ctx, false, false,
				beacon_params, session_entry);
		}
	}

	/* we are HT or 11G and 11B station is getting deleted */
	if ((SIR_BAND_2_4_GHZ == rf_band) &&
		(phy_mode == WNI_CFG_PHY_MODE_11G ||
		session_entry->htCapability) &&
		(erp_enabled == eHAL_CLEAR)) {
		lim_log(mac_ctx, LOG1,
			FL("(%d) A legacy STA is disassociated. Addr is %pM"),
			session_entry->gLim11bParams.numSta, sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->protStaCache[i].active &&
				(!qdf_mem_cmp(
					session_entry->protStaCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
					session_entry->gLim11bParams.numSta--;
					session_entry->protStaCache[i].active =
						 false;
				break;
			}
		}

		if (session_entry->gLim11bParams.numSta == 0) {
			/* disable protection */
			lim_enable11g_protection(mac_ctx, false, false,
						 beacon_params, session_entry);
		}
	}

	/*
	 * we are HT AP and non-11B station is leaving.
	 * 11g station is leaving
	 */
	if ((SIR_BAND_2_4_GHZ == rf_band) &&
		session_entry->htCapability &&
		!sta_ds->mlmStaContext.htCapability) {
		lim_log(mac_ctx, LOG1,
			FL("(%d) A 11g STA is disassociated. Addr is %pM"),
			session_entry->gLim11bParams.numSta, sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->protStaCache[i].active &&
				(!qdf_mem_cmp(
					session_entry->protStaCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				 session_entry->gLim11gParams.numSta--;
				 session_entry->protStaCache[i].active = false;
				 break;
			}
		}

		if (session_entry->gLim11gParams.numSta == 0) {
		    /* disable protection */
		    lim_enable_ht_protection_from11g(mac_ctx, false, false,
							 beacon_params,
							 session_entry);
		}
	}

	if (!((true == session_entry->htCapability) &&
		(true == sta_ds->mlmStaContext.htCapability)))
		return;

	/*
	 * Applies to 2.4 as well as 5 GHZ.
	 * HT non-GF leaving
	 */
	if (!sta_ds->htGreenfield) {
		lim_log(mac_ctx, LOG1,
			FL("(%d) A non-GF STA is disassociated. Addr is %pM"),
			session_entry->gLimNonGfParams.numSta, sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->protStaCache[i].active &&
				(!qdf_mem_cmp(
					session_entry->protStaCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				session_entry->protStaCache[i].active = false;
				break;
			}
		}

		if (session_entry->gLimNonGfParams.numSta == 0) {
			/* disable protection */
			lim_enable_ht_non_gf_protection(mac_ctx, false, false,
					beacon_params, session_entry);
		}
	}

	/*
	 * Applies to 2.4 as well as 5 GHZ.
	 * HT 20Mhz station leaving
	 */
	if (session_entry->beaconParams.ht20Coexist &&
		(eHT_CHANNEL_WIDTH_20MHZ ==
			 sta_ds->htSupportedChannelWidthSet)) {
		lim_decide_ap_protection_on_ht20_delete(mac_ctx, sta_ds,
					beacon_params, session_entry);
	}

	/*
	 * Applies to 2.4 as well as 5 GHZ.
	 * LSIG TXOP not supporting staiton leaving
	 */
	if ((false == session_entry->beaconParams.
				fLsigTXOPProtectionFullSupport) &&
		(false == sta_ds->htLsigTXOPProtection)) {
		lim_log(mac_ctx, LOG1,
			FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is %pM"),
			session_entry->gLimLsigTxopParams.numSta,
			sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->protStaCache[i].active &&
				(!qdf_mem_cmp(
					session_entry->protStaCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				session_entry->protStaCache[i].active = false;
				break;
			}
		}

		if (session_entry->gLimLsigTxopParams.numSta == 0) {
			/* disable protection */
			lim_enable_ht_lsig_txop_protection(mac_ctx, true,
				false, beacon_params, session_entry);
		}
	}
}

/**
 * lim_decide_short_preamble() - update short preamble parameters
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @beacon_params: ap beacon parameters
 * @session_entry: pe session entry
 *
 * Decides about any short preamble related change because of new station
 * joining.
 *
 * Return: None
 */
void lim_decide_short_preamble(tpAniSirGlobal mac_ctx,
			       tpDphHashNode sta_ds,
			       tpUpdateBeaconParams beacon_params,
			       tpPESession session_entry)
{
	uint32_t i;

	if (sta_ds->shortPreambleEnabled == eHAL_CLEAR) {
		lim_log(mac_ctx, LOG1,
		       FL("(%d) A non-short preamble STA is disassociated. Addr is %pM"),
		       session_entry->gLimNoShortParams.numNonShortPreambleSta,
			 sta_ds->staAddr);
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->gLimNoShortParams.
				staNoShortCache[i].active &&
				(!qdf_mem_cmp(session_entry->
					gLimNoShortParams.
					staNoShortCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				session_entry->gLimNoShortParams.
					numNonShortPreambleSta--;
				session_entry->gLimNoShortParams.
					staNoShortCache[i].active = false;
				break;
			}
		}

		if (session_entry->gLimNoShortParams.numNonShortPreambleSta)
			return;

		/*
		 * enable short preamble
		 * reset the cache
		 */
		qdf_mem_set((uint8_t *) &session_entry->gLimNoShortParams,
				sizeof(tLimNoShortParams), 0);
		if (lim_enable_short_preamble(mac_ctx, true,
			beacon_params, session_entry) != eSIR_SUCCESS) {
			lim_log(mac_ctx, LOGE,
				FL("Cannot enable short preamble"));
		}
	}
}

/**
 * lim_decide_short_slot() - update short slot time related  parameters
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @beacon_params: ap beacon parameters
 * @session_entry: pe session entry
 *
 * Decides about any short slot time related change because of station leaving
 *        the BSS.
 * Return: None
 */
void
lim_decide_short_slot(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
		      tpUpdateBeaconParams beacon_params,
		      tpPESession session_entry)
{
	uint32_t i, val, non_short_slot_sta_count;

	if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
		return;

	lim_log(mac_ctx, LOG1,
		FL("(%d) A non-short slottime STA is disassociated. Addr is %pM"),
		mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta,
		sta_ds->staAddr);

	wlan_cfg_get_int(mac_ctx, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
			 &val);

	if (LIM_IS_AP_ROLE(session_entry)) {
		non_short_slot_sta_count =
		      session_entry->gLimNoShortSlotParams.numNonShortSlotSta;
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (session_entry->gLimNoShortSlotParams.
				staNoShortSlotCache[i].active &&
				(!qdf_mem_cmp(session_entry->
					gLimNoShortSlotParams.
						staNoShortSlotCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				non_short_slot_sta_count--;
				session_entry->gLimNoShortSlotParams.
					staNoShortSlotCache[i].active = false;
				break;
			}
		}

		if (non_short_slot_sta_count == 0 && val) {
			/*
			 * enable short slot time
			 * reset the cache
			 */
			qdf_mem_set((uint8_t *) &session_entry->
				gLimNoShortSlotParams,
				sizeof(tLimNoShortSlotParams), 0);
			beacon_params->fShortSlotTime = true;
			beacon_params->paramChangeBitmap |=
				PARAM_SHORT_SLOT_TIME_CHANGED;
			session_entry->shortSlotTimeSupported = true;
		}
		session_entry->gLimNoShortSlotParams.numNonShortSlotSta =
			non_short_slot_sta_count;
	} else {
		non_short_slot_sta_count =
			mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta;
		for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
			if (mac_ctx->lim.gLimNoShortSlotParams.
				staNoShortSlotCache[i].active &&
				(!qdf_mem_cmp(
					mac_ctx->lim.gLimNoShortSlotParams.
						staNoShortSlotCache[i].addr,
					sta_ds->staAddr,
					sizeof(tSirMacAddr)))) {
				non_short_slot_sta_count--;
				mac_ctx->lim.gLimNoShortSlotParams.
					staNoShortSlotCache[i].active = false;
				break;
			}
		}

		if (val && !non_short_slot_sta_count) {
			/*
			 * enable short slot time
			 * reset the cache
			 */
			qdf_mem_set(
				(uint8_t *) &mac_ctx->lim.gLimNoShortSlotParams,
				sizeof(tLimNoShortSlotParams), 0);
			/*in case of AP set SHORT_SLOT_TIME to enable*/
			if (LIM_IS_AP_ROLE(session_entry)) {
				beacon_params->fShortSlotTime = true;
				beacon_params->paramChangeBitmap |=
					PARAM_SHORT_SLOT_TIME_CHANGED;
				session_entry->shortSlotTimeSupported = true;
			}
		}
		mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta =
			non_short_slot_sta_count;
	}
}

void
lim_post_reassoc_failure(tpAniSirGlobal pMac,
			 tSirResultCodes resultCode,
			 uint16_t protStatusCode, tpPESession psessionEntry)
{
	tLimMlmReassocCnf mlmReassocCnf;

	psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
	MTRACE(mac_trace
		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
		       eLIM_MLM_LINK_ESTABLISHED_STATE));

	/* 'Change' timer for future activations */
	lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);

	mlmReassocCnf.resultCode = resultCode;
	mlmReassocCnf.protStatusCode = protStatusCode;
	/* Update PE session Id */
	mlmReassocCnf.sessionId = psessionEntry->peSessionId;
	lim_post_sme_message(pMac,
			     LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
} /*** end lim_post_reassoc_failure() ***/

/**
 * lim_restore_pre_reassoc_state()
 *
 ***FUNCTION:
 * This function is called on STA role whenever Reasociation
 * Response with a reject code is received from AP.
 *
 ***LOGIC:
 * Reassociation failure timer is stopped, Old (or current) AP's
 * context is restored both at Polaris & software
 *
 ***ASSUMPTIONS:
 *
 ***NOTE:
 *
 * @param  pMac       - Pointer to Global MAC structure
 * @param  resultCode - Result code that specifies why Reassociation
 *                      attemp failed
 *
 * @return None
 */

void
lim_restore_pre_reassoc_state(tpAniSirGlobal pMac,
			      tSirResultCodes resultCode,
			      uint16_t protStatusCode, tpPESession psessionEntry)
{
	tLimMlmReassocCnf mlmReassocCnf;

	lim_log(pMac, LOG1,
		FL("sessionid: %d protStatusCode: %d resultCode: %d"),
		psessionEntry->smeSessionId, protStatusCode, resultCode);

	psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
	MTRACE(mac_trace
		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
		       eLIM_MLM_LINK_ESTABLISHED_STATE));

	/* 'Change' timer for future activations */
	lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);

	lim_set_channel(pMac, psessionEntry->currentOperChannel,
			psessionEntry->ch_center_freq_seg0,
			psessionEntry->ch_center_freq_seg1,
			psessionEntry->ch_width,
			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;
	lim_post_sme_message(pMac,
			     LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
} /*** end lim_restore_pre_reassoc_state() ***/

/**
 * lim_is_reassoc_in_progress()
 *
 ***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 true  When STA is waiting for Reassoc response from AP \n
 *         else false
 */

bool lim_is_reassoc_in_progress(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
	if (psessionEntry == NULL) {
		return 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 true;

	return false;
} /*** end lim_is_reassoc_in_progress() ***/

#ifdef WLAN_FEATURE_11AC
/**
 * lim_populate_vht_mcs_set - function to populate vht mcs rate set
 * @mac_ctx: pointer to global mac structure
 * @rates: pointer to supported rate set
 * @peer_vht_caps: pointer to peer vht capabilities
 * @session_entry: pe session entry
 *
 * Populates vht mcs rate set based on peer and self capabilities
 *
 * Return: eSIR_SUCCESS on success else eSIR_FAILURE
 */
tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx,
				       tpSirSupportedRates rates,
				       tDot11fIEVHTCaps *peer_vht_caps,
				       tpPESession session_entry)
{
	uint32_t val;
	uint32_t self_sta_dot11mode = 0;
	uint16_t mcs_map_mask = MCSMAPMASK1x1;
	uint16_t mcs_map_mask2x2 = 0;

	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);

	if (!IS_DOT11_MODE_VHT(self_sta_dot11mode))
		return eSIR_SUCCESS;

	if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_RX_MCS_MAP, &val) !=
	    eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGE, FL("could not retrieve VHT RX MCS MAP"));
		goto error;
	}
	rates->vhtRxMCSMap = (uint16_t) val;

	if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_TX_MCS_MAP, &val) !=
		eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGE, FL("could not retrieve VHT TX MCS MAP"));
		goto error;
	}
	rates->vhtTxMCSMap = (uint16_t) val;

	if (wlan_cfg_get_int(mac_ctx,
			WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
			&val) != eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGE,
			FL("couldn't retrieve VHT RX Supported data rate MAP"));
		goto error;
	}
	rates->vhtRxHighestDataRate = (uint16_t) val;

	if (wlan_cfg_get_int(mac_ctx,
			WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
			&val) != eSIR_SUCCESS) {
		lim_log(mac_ctx, LOGE,
			FL("couldn't retrieve VHT RX Supported data rate MAP"));
		goto error;
	}
	rates->vhtTxHighestDataRate = (uint16_t) val;

	if (peer_vht_caps == NULL)
		return eSIR_SUCCESS;

	rates->vhtTxHighestDataRate =
		QDF_MIN(rates->vhtTxHighestDataRate,
			peer_vht_caps->txSupDataRate);
	rates->vhtRxHighestDataRate =
		QDF_MIN(rates->vhtRxHighestDataRate,
			peer_vht_caps->rxHighSupDataRate);

	if (mac_ctx->roam.configParam.enable2x2) {
		if (session_entry && mac_ctx->lteCoexAntShare &&
			IS_24G_CH(session_entry->currentOperChannel)) {
			if (IS_2X2_CHAIN(session_entry->chainMask))
				mcs_map_mask2x2 = MCSMAPMASK2x2;
			else
				lim_log(mac_ctx, LOGE, FL("2x2 not enabled %d"),
					session_entry->chainMask);
		} else {
			mcs_map_mask2x2 = MCSMAPMASK2x2;
		}
	}

	if ((peer_vht_caps->txMCSMap & mcs_map_mask) <
	    (rates->vhtRxMCSMap & mcs_map_mask)) {
		rates->vhtRxMCSMap &= ~(mcs_map_mask);
		rates->vhtRxMCSMap |=
			(peer_vht_caps->txMCSMap & mcs_map_mask);
	}
	if ((peer_vht_caps->rxMCSMap & mcs_map_mask) <
	    (rates->vhtTxMCSMap & mcs_map_mask)) {
		rates->vhtTxMCSMap &= ~(mcs_map_mask);
		rates->vhtTxMCSMap |=
			(peer_vht_caps->rxMCSMap & mcs_map_mask);
	}

	if (mcs_map_mask2x2) {

		uint16_t peer_mcs_map, self_mcs_map;

		peer_mcs_map =
			peer_vht_caps->txMCSMap & mcs_map_mask2x2;
		self_mcs_map =
			rates->vhtRxMCSMap & mcs_map_mask2x2;

		if ((self_mcs_map != mcs_map_mask2x2) &&
		    ((peer_mcs_map == mcs_map_mask2x2) ||
		     (peer_mcs_map < self_mcs_map))) {
			rates->vhtRxMCSMap &= ~mcs_map_mask2x2;
			rates->vhtRxMCSMap |= peer_mcs_map;
		}

		peer_mcs_map =
		 (peer_vht_caps->rxMCSMap & mcs_map_mask2x2);
		self_mcs_map =
			(rates->vhtTxMCSMap & mcs_map_mask2x2);

		if ((self_mcs_map != mcs_map_mask2x2) &&
		    ((peer_mcs_map == mcs_map_mask2x2) ||
		     (peer_mcs_map < self_mcs_map))) {
			rates->vhtTxMCSMap &= ~mcs_map_mask2x2;
			rates->vhtTxMCSMap |= peer_mcs_map;
		}
	}

	lim_log(mac_ctx, LOG1,
		FL("enable2x2 - %d vhtRxMCSMap - %x vhtTxMCSMap - %x\n"),
		mac_ctx->roam.configParam.enable2x2,
		rates->vhtRxMCSMap, rates->vhtTxMCSMap);

	return eSIR_SUCCESS;
error:

	return eSIR_FAILURE;
}
#endif

/**
 * lim_populate_own_rate_set() - comprises the basic and extended rates read
 *                                from CFG
 * @mac_ctx: pointer to global mac structure
 * @rates: pointer to supported rates
 * @supported_mcs_set: pointer to supported mcs rates
 * @basic_only: update only basic rates if set true
 * @session_entry: pe session entry
 * @vht_caps: pointer to vht capability
 *
 * This function is called by limProcessAssocRsp() or
 * lim_add_staInIBSS()
 * - 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
 * 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
 *
 * Return: eSIR_SUCCESS or eSIR_FAILURE.
 */
#ifdef WLAN_FEATURE_11AC
tSirRetStatus
lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
		tpSirSupportedRates rates, uint8_t *supported_mcs_set,
		uint8_t basic_only, tpPESession session_entry,
		tDot11fIEVHTCaps *vht_caps)
#else
tSirRetStatus
lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
			  tpSirSupportedRates rates,
			  uint8_t *supported_mcs_set,
			  uint8_t basic_only, tpPESession session_entry)
#endif
{
	tSirMacRateSet temp_rate_set;
	tSirMacRateSet temp_rate_set2;
	uint32_t i, j, val, min, is_arate;
	uint32_t phy_mode = 0;
	uint32_t self_sta_dot11mode = 0;
	uint8_t a_rate_index = 0;
	uint8_t b_rate_index = 0;


	is_arate = 0;

	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);

	/*
	 * Include 11b rates only when the device configured in
	 *  auto, 11a/b/g or 11b_only
	 */
	if ((self_sta_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
	    (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11B)) {
		val = WNI_CFG_SUPPORTED_RATES_11B_LEN;
		wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11B,
				 (uint8_t *) &temp_rate_set.rate, &val);
		temp_rate_set.numRates = (uint8_t) val;
	} else {
		temp_rate_set.numRates = 0;
	}

	/* Include 11a rates when the device configured in non-11b mode */
	if (!IS_DOT11_MODE_11B(self_sta_dot11mode)) {
		val = WNI_CFG_SUPPORTED_RATES_11A_LEN;
		wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11A,
				 (uint8_t *) &temp_rate_set2.rate, &val);
		temp_rate_set2.numRates = (uint8_t) val;
	} else {
		temp_rate_set2.numRates = 0;
	}

	if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
		/* we are in big trouble */
		lim_log(mac_ctx, LOGP, FL("more than 12 rates in CFG"));
		/* panic */
		goto error;
	}
	/* copy all rates in temp_rate_set, there are 12 rates max */
	for (i = 0; i < temp_rate_set2.numRates; i++)
		temp_rate_set.rate[i + temp_rate_set.numRates] =
			temp_rate_set2.rate[i];

	temp_rate_set.numRates += temp_rate_set2.numRates;

	/**
	 * Sort rates in temp_rate_set (they are likely to be already sorted)
	 * put the result in pSupportedRates
	 */

	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
	for (i = 0; i < temp_rate_set.numRates; i++) {
		min = 0;
		val = 0xff;
		is_arate = 0;

		for (j = 0; (j < temp_rate_set.numRates) &&
			 (j < SIR_MAC_RATESET_EID_MAX); j++) {
			if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) <
					val) {
				val = temp_rate_set.rate[j] & 0x7f;
				min = j;
			}
		}

		if (sirIsArate(temp_rate_set.rate[min] & 0x7f))
			is_arate = 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 (basic_only && temp_rate_set.rate[min] & 0x80) {
			if (is_arate)
				rates->llaRates[a_rate_index++] =
					temp_rate_set.rate[min];
			else
				rates->llbRates[b_rate_index++] =
					temp_rate_set.rate[min];
		} else {
			if (is_arate)
				rates->llaRates[a_rate_index++] =
					temp_rate_set.rate[min];
			else
				rates->llbRates[b_rate_index++] =
					temp_rate_set.rate[min];
		}
		temp_rate_set.rate[min] = 0xff;
	}

	if (IS_DOT11_MODE_HT(self_sta_dot11mode)) {
		val = SIZE_OF_SUPPORTED_MCS_SET;
		if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
				     rates->supportedMCSSet,
				     &val) != eSIR_SUCCESS) {
			/* Could not get rateset from CFG. Log error. */
			lim_log(mac_ctx, LOGE,
				FL("could not retrieve supportedMCSSet"));
			goto error;
		}

		/*
		 * if supported MCS Set of the peer is passed in,
		 * then do the intersection
		 * else use the MCS set from local CFG.
		 */

		if (supported_mcs_set != NULL) {
			for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
				rates->supportedMCSSet[i] &=
					 supported_mcs_set[i];
		}

		lim_log(mac_ctx, LOG2, FL("MCS Rate Set Bitmap: "));
		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
			PELOG2(lim_log(mac_ctx, LOG2, FL("%x "),
				       rates->supportedMCSSet[i]);)
	}
#ifdef WLAN_FEATURE_11AC
	lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, session_entry);
#endif

	return eSIR_SUCCESS;
error:
	return eSIR_FAILURE;
}

#ifdef WLAN_FEATURE_11AC
tSirRetStatus
lim_populate_peer_rate_set(tpAniSirGlobal pMac,
			   tpSirSupportedRates pRates,
			   uint8_t *pSupportedMCSSet,
			   uint8_t basicOnly,
			   tpPESession psessionEntry, tDot11fIEVHTCaps *pVHTCaps)
#else
tSirRetStatus
lim_populate_peer_rate_set(tpAniSirGlobal pMac,
			   tpSirSupportedRates pRates,
			   uint8_t *pSupportedMCSSet,
			   uint8_t basicOnly, tpPESession psessionEntry)
#endif
{
	tSirMacRateSet tempRateSet;
	tSirMacRateSet tempRateSet2;
	uint32_t i, j, val, min, isArate;
	isArate = 0;

	/* copy operational rate set from psessionEntry */
	if (psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX) {
		qdf_mem_copy((uint8_t *) tempRateSet.rate,
			     (uint8_t *) (psessionEntry->rateSet.rate),
			     psessionEntry->rateSet.numRates);
		tempRateSet.numRates = psessionEntry->rateSet.numRates;
	} else {
		lim_log(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) {
			qdf_mem_copy((uint8_t *) tempRateSet2.rate,
				     (uint8_t *) (psessionEntry->extRateSet.
						  rate),
				     psessionEntry->extRateSet.numRates);
			tempRateSet2.numRates =
				psessionEntry->extRateSet.numRates;
		} else {
			lim_log(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 */
		lim_log(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
	 */
	{
		uint8_t aRateIndex = 0;
		uint8_t bRateIndex = 0;
		qdf_mem_set((uint8_t *) 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 ((uint32_t) (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_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
				     pRates->supportedMCSSet,
				     &val) != eSIR_SUCCESS) {
			/* / Could not get rateset from CFG. Log error. */
			PELOGE(lim_log
				       (pMac, LOGE,
				       FL("could not retrieve supportedMCSSet"));
			       )
			goto error;
		}
		/* if supported MCS Set of the peer is passed in, then do the intersection */
		/* else use the MCS set from local CFG. */
		if (pSupportedMCSSet != NULL) {
			for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
				pRates->supportedMCSSet[i] &=
					pSupportedMCSSet[i];
		}
		PELOG2(lim_log(pMac, LOG2, FL("MCS Rate Set Bitmap: "));)
		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
			PELOG2(lim_log
				       (pMac, LOG2, FL("%x "),
				       pRates->supportedMCSSet[i]);
			       )
	}
#ifdef WLAN_FEATURE_11AC
	lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps, psessionEntry);
#endif
	return eSIR_SUCCESS;
error:
	return eSIR_FAILURE;
} /*** lim_populate_peer_rate_set() ***/

/**
 * lim_populate_matching_rate_set() -process the CFG rate sets and
 *          the rate sets received in the Assoc request on AP.
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @oper_rate_set: pointer to operating rate set
 * @ext_rate_set: pointer to extended rate set
 * @supported_mcs_set: pointer to supported rate set
 * @session_entry: pointer to pe session entry
 * @vht_caps: pointer to vht capabilities
 *
 * 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.
 *
 * 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
 *
 * The parser has already ensured unicity of the rates in the
 * association request structure
 *
 * Return: eSIR_SUCCESS on success else eSIR_FAILURE
 */
#ifdef WLAN_FEATURE_11AC
tSirRetStatus
lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
	tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
	uint8_t *supported_mcs_set, tpPESession session_entry,
	tDot11fIEVHTCaps *vht_caps)
#else
tSirRetStatus
lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
	tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
	uint8_t *supported_mcs_set, tpPESession session_entry)
#endif
{
	tSirMacRateSet temp_rate_set;
	tSirMacRateSet temp_rate_set2;
	uint32_t i, j, val, min, is_arate;
	uint32_t phy_mode;
	uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
	tpSirSupportedRates rates;
	uint8_t a_rate_index = 0;
	uint8_t b_rate_index = 0;

	is_arate = 0;

	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);

	/* copy operational rate set from session_entry */
	qdf_mem_copy((temp_rate_set.rate), (session_entry->rateSet.rate),
		     session_entry->rateSet.numRates);
	temp_rate_set.numRates = (uint8_t) session_entry->rateSet.numRates;

	if (phy_mode == WNI_CFG_PHY_MODE_11G) {
		qdf_mem_copy((temp_rate_set2.rate),
			     (session_entry->extRateSet.rate),
			     session_entry->extRateSet.numRates);
		temp_rate_set2.numRates =
			(uint8_t) session_entry->extRateSet.numRates;
	} else {
		temp_rate_set2.numRates = 0;
	}

	if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
		lim_log(mac_ctx, 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 temp_rate_set, there are 12 rates max */
	for (i = 0; i < temp_rate_set2.numRates; i++)
		temp_rate_set.rate[i + temp_rate_set.numRates] =
			temp_rate_set2.rate[i];

	temp_rate_set.numRates += temp_rate_set2.numRates;

	/*
	 * Sort rates in temp_rate_set (they are likely to be already sorted)
	 * put the result in temp_rate_set2
	 */
	temp_rate_set2.numRates = 0;

	for (i = 0; i < temp_rate_set.numRates; i++) {
		min = 0;
		val = 0xff;

		for (j = 0; j < temp_rate_set.numRates; j++)
			if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
				val = temp_rate_set.rate[j] & 0x7f;
				min = j;
			}

		temp_rate_set2.rate[temp_rate_set2.numRates++] =
			temp_rate_set.rate[min];
		temp_rate_set.rate[min] = 0xff;
	}

	/*
	 * Copy received rates in temp_rate_set, the parser has ensured
	 * unicity of the rates so there cannot be more than 12
	 */
	for (i = 0; (i < oper_rate_set->numRates &&
			 i < SIR_MAC_RATESET_EID_MAX); i++)
		temp_rate_set.rate[i] = oper_rate_set->rate[i];

	temp_rate_set.numRates = oper_rate_set->numRates;

	lim_log(mac_ctx, LOG2,
		"Sum of SUPPORTED and EXTENDED Rate Set (%1d)",
		temp_rate_set.numRates + ext_rate_set->numRates);

	if (ext_rate_set->numRates &&
		((temp_rate_set.numRates + ext_rate_set->numRates) > 12) &&
		temp_rate_set.numRates < 12) {
		int found = 0;
		int tail = temp_rate_set.numRates;

		for (i = 0; (i < ext_rate_set->numRates &&
				i < SIR_MAC_RATESET_EID_MAX); i++) {
			found = 0;
			for (j = 0; j < (uint32_t) tail; j++) {
				if ((temp_rate_set.rate[j] & 0x7F) ==
					(ext_rate_set->rate[i] & 0x7F)) {
					found = 1;
					break;
				}
			}

			if (!found) {
				temp_rate_set.rate[temp_rate_set.numRates++] =
						ext_rate_set->rate[i];
				if (temp_rate_set.numRates >= 12)
					break;
			}
		}
	} else if (ext_rate_set->numRates &&
		 ((temp_rate_set.numRates + ext_rate_set->numRates) <= 12)) {
		for (j = 0; ((j < ext_rate_set->numRates) &&
				 (j < SIR_MAC_RATESET_EID_MAX) &&
				 ((i + j) < SIR_MAC_RATESET_EID_MAX)); j++)
			temp_rate_set.rate[i + j] = ext_rate_set->rate[j];

		temp_rate_set.numRates += ext_rate_set->numRates;
	} else if (ext_rate_set->numRates) {
		lim_log(mac_ctx, LOG2,
			 "Relying only on the SUPPORTED Rate Set IE...");
	}


	rates = &sta_ds->supportedRates;
	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
	for (i = 0; (i < temp_rate_set2.numRates &&
			 i < SIR_MAC_RATESET_EID_MAX); i++) {
		for (j = 0; (j < temp_rate_set.numRates &&
				 j < SIR_MAC_RATESET_EID_MAX); j++) {
			if ((temp_rate_set2.rate[i] & 0x7F) !=
				(temp_rate_set.rate[j] & 0x7F))
				continue;

			if (sirIsArate(temp_rate_set2.rate[i] & 0x7f) &&
				a_rate_index < SIR_NUM_11A_RATES) {
				is_arate = 1;
				rates->llaRates[a_rate_index++] =
							temp_rate_set2.rate[i];
			} else if ((b_rate_index < SIR_NUM_11B_RATES) &&
				!(sirIsArate(temp_rate_set2.rate[i] & 0x7f))) {
				rates->llbRates[b_rate_index++] =
					temp_rate_set2.rate[i];
			}
			break;
		}
	}

	/*
	 * Now add the Polaris rates only when Proprietary rates are enabled.
	 * compute the matching MCS rate set, if peer is 11n capable and self
	 * mode is 11n
	 */
#ifdef FEATURE_WLAN_TDLS
	if (sta_ds->mlmStaContext.htCapability)
#else
	if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
		(sta_ds->mlmStaContext.htCapability))
#endif
	{
		val = SIZE_OF_SUPPORTED_MCS_SET;
		if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
				     mcs_set, &val) != eSIR_SUCCESS) {
			/* Could not get rateset from CFG. Log error. */
			lim_log(mac_ctx, LOGP,
				FL("could not retrieve supportedMCSet"));
			goto error;
		}

		for (i = 0; i < val; i++)
			sta_ds->supportedRates.supportedMCSSet[i] =
				mcs_set[i] & supported_mcs_set[i];

		lim_log(mac_ctx, LOG2,
			FL("lim_populate_matching_rate_set: MCS Rate Set Bitmap"
				" from  CFG and DPH : "));
		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
			lim_log(mac_ctx, LOG2, FL("%x %x "), mcs_set[i],
			    sta_ds->supportedRates.supportedMCSSet[i]);
		}
	}
#ifdef WLAN_FEATURE_11AC
	lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps,
				 session_entry);
#endif
	/*
	 * Set the erpEnabled bit if the phy is in G mode and at least
	 * one A rate is supported
	 */
	if ((phy_mode == WNI_CFG_PHY_MODE_11G) && is_arate)
		sta_ds->erpEnabled = eHAL_SET;

	return eSIR_SUCCESS;

error:

	return eSIR_FAILURE;
}

/**
 * lim_populate_vht_caps() - populates vht capabilities based on input
 *        capabilities
 * @input_caps: input capabilities based on which we format the vht
 *      capabilities
 *
 * function to populate the supported vht capabilities.
 *
 * Return: vht capabilities derived based on input parameters.
 */
static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps)
{
	uint32_t vht_caps;

	vht_caps = ((input_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
			(input_caps.supportedChannelWidthSet <<
				 SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
			(input_caps.ldpcCodingCap <<
				SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
			(input_caps.shortGI80MHz <<
				 SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
			(input_caps.shortGI160and80plus80MHz <<
				SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
			(input_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
			(input_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
			(input_caps.suBeamFormerCap <<
				SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
			(input_caps.suBeamformeeCap <<
				SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
			(input_caps.csnofBeamformerAntSup <<
				SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
			(input_caps.numSoundingDim <<
				SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
			(input_caps.muBeamformerCap <<
				SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
			(input_caps.muBeamformeeCap <<
				SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
			(input_caps.vhtTXOPPS <<
				SIR_MAC_VHT_CAP_TXOPPS) |
			(input_caps.htcVHTCap <<
				 SIR_MAC_VHT_CAP_HTC_CAP) |
			(input_caps.maxAMPDULenExp <<
				SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
			(input_caps.vhtLinkAdaptCap <<
				SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
			(input_caps.rxAntPattern <<
				SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
			(input_caps.txAntPattern <<
				SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
			(input_caps.reserved1 <<
				SIR_MAC_VHT_CAP_RESERVED2));

	return vht_caps;
}
/**
 * lim_add_sta()- called to add an STA context at hardware
 * @mac_ctx: pointer to global mac structure
 * @sta_ds: station node
 * @update_entry: set to true for updating the entry
 * @session_entry: pe session entry
 *
 * This function is called to add an STA context at hardware
 * whenever a STA is (Re) Associated.
 *
 * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
 */

tSirRetStatus
lim_add_sta(tpAniSirGlobal mac_ctx,
	tpDphHashNode sta_ds, uint8_t update_entry, tpPESession session_entry)
{
	tpAddStaParams add_sta_params = NULL;
	tSirMsgQ msg_q;
	tSirRetStatus ret_code = eSIR_SUCCESS;
	tSirMacAddr sta_mac, *sta_Addr;
	uint8_t i, nw_type_11b = 0;
	tpSirAssocReq assoc_req;
	tLimIbssPeerNode *peer_node; /* for IBSS mode */
	uint8_t *p2p_ie = NULL;

	sir_copy_mac_addr(sta_mac, session_entry->selfMacAddr);

	lim_log(mac_ctx, LOG1,
		FL("sessionid: %d update_entry = %d limsystemrole = %d "),
		session_entry->smeSessionId, update_entry,
		GET_LIM_SYSTEM_ROLE(session_entry));

	add_sta_params = qdf_mem_malloc(sizeof(tAddStaParams));
	if (NULL == add_sta_params) {
		lim_log(mac_ctx, LOGP,
			FL("Unable to allocate memory during ADD_STA"));
		return eSIR_MEM_ALLOC_FAILED;
	}
	qdf_mem_set((uint8_t *) add_sta_params, sizeof(tAddStaParams), 0);

	if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry) ||
	    LIM_IS_BT_AMP_AP_ROLE(session_entry))
		sta_Addr = &sta_ds->staAddr;
#ifdef FEATURE_WLAN_TDLS
	/* SystemRole shouldn't be matter if staType is TDLS peer */
	else if (STA_ENTRY_TDLS_PEER == sta_ds->staType)
		sta_Addr = &sta_ds->staAddr;
#endif
	else
		sta_Addr = &sta_mac;

	lim_log(mac_ctx, LOG1,
		FL(MAC_ADDRESS_STR ": Subtype(Assoc/Reassoc): %d"),
		MAC_ADDR_ARRAY(*sta_Addr), sta_ds->mlmStaContext.subType);

	qdf_mem_copy((uint8_t *) add_sta_params->staMac,
		     (uint8_t *) *sta_Addr, sizeof(tSirMacAddr));
	qdf_mem_copy((uint8_t *) add_sta_params->bssId,
		     session_entry->bssId, sizeof(tSirMacAddr));
	qdf_mem_copy(&add_sta_params->capab_info,
		     &sta_ds->mlmStaContext.capabilityInfo,
		     sizeof(add_sta_params->capab_info));

	lim_fill_supported_rates_info(mac_ctx, sta_ds, &sta_ds->supportedRates,
				      session_entry);

	/* Copy legacy rates */
	qdf_mem_copy((uint8_t *) &add_sta_params->supportedRates,
		     (uint8_t *) &sta_ds->supportedRates,
		     sizeof(tSirSupportedRates));

	add_sta_params->assocId = sta_ds->assocId;

	add_sta_params->wmmEnabled = sta_ds->qosMode;
	add_sta_params->listenInterval = sta_ds->mlmStaContext.listenInterval;
	add_sta_params->shortPreambleSupported = sta_ds->shortPreambleEnabled;
	if (LIM_IS_AP_ROLE(session_entry) &&
	   (sta_ds->mlmStaContext.subType == LIM_REASSOC)) {
		/*
		 * TBD - need to remove this REASSOC check
		 * after fixinf rmmod issue
		 */
		add_sta_params->updateSta = sta_ds->mlmStaContext.updateContext;
	}
	sta_ds->valid = 0;
	sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;

	lim_log(mac_ctx, LOG2,
		FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d"
		   " shortPreambleSupported: %d "), add_sta_params->assocId,
		add_sta_params->wmmEnabled, add_sta_params->listenInterval,
		add_sta_params->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 == sta_ds->staType) && (true == update_entry))
		add_sta_params->staIdx = sta_ds->staIndex;
	else
#endif
	add_sta_params->staIdx = STA_INVALID_IDX;
	add_sta_params->staType = sta_ds->staType;

	add_sta_params->updateSta = update_entry;

	add_sta_params->status = QDF_STATUS_SUCCESS;
	add_sta_params->respReqd = 1;
	/* Update HT Capability */

	if (LIM_IS_AP_ROLE(session_entry) ||
	    LIM_IS_BT_AMP_AP_ROLE(session_entry) ||
	    LIM_IS_IBSS_ROLE(session_entry)) {
		add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
#ifdef WLAN_FEATURE_11AC
		add_sta_params->vhtCapable =
			 sta_ds->mlmStaContext.vhtCapability;
#endif
	}
#ifdef FEATURE_WLAN_TDLS
	/* SystemRole shouldn't be matter if staType is TDLS peer */
	else if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
		add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
#ifdef WLAN_FEATURE_11AC
		add_sta_params->vhtCapable =
			 sta_ds->mlmStaContext.vhtCapability;
#endif
	}
#endif
	else {
		add_sta_params->htCapable = session_entry->htCapability;
#ifdef WLAN_FEATURE_11AC
		add_sta_params->vhtCapable = session_entry->vhtCapability;
#endif

	}
#ifdef WLAN_FEATURE_11AC
	lim_log(mac_ctx, LOG2, FL("vhtCapable: %d "),
		 add_sta_params->vhtCapable);
#endif
	lim_log(mac_ctx, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
		add_sta_params->staIdx, add_sta_params->updateSta,
		add_sta_params->htCapable);

	add_sta_params->greenFieldCapable = sta_ds->htGreenfield;
	add_sta_params->maxAmpduDensity = sta_ds->htAMpduDensity;
	add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor;
	add_sta_params->fDsssCckMode40Mhz = sta_ds->htDsssCckRate40MHzSupport;
	add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz;
	add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz;
	add_sta_params->lsigTxopProtection = sta_ds->htLsigTXOPProtection;
	add_sta_params->maxAmsduSize = sta_ds->htMaxAmsduLength;
	add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet;
	add_sta_params->mimoPS = sta_ds->htMIMOPSState;

	lim_log(mac_ctx, LOG2,
		FL("greenFieldCapable: %d maxAmpduDensity = %d maxAmpduDensity = %d"),
		add_sta_params->greenFieldCapable,
		 add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize);

	lim_log(mac_ctx, LOG2,
		FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d fShortGI40Mhz: %d"),
		add_sta_params->fDsssCckMode40Mhz,
		 add_sta_params->fShortGI20Mhz,	add_sta_params->fShortGI40Mhz);

	lim_log(mac_ctx, LOG2,
		FL("lsigTxopProtection: %d maxAmsduSize: %d txChannelWidth: %d mimoPS: %d "),
		add_sta_params->lsigTxopProtection,
		add_sta_params->maxAmsduSize, add_sta_params->ch_width,
		add_sta_params->mimoPS);

	if (add_sta_params->vhtCapable) {
		if (sta_ds->vhtSupportedChannelWidthSet)
			add_sta_params->ch_width =
				sta_ds->vhtSupportedChannelWidthSet + 1;

		add_sta_params->vhtSupportedRxNss = sta_ds->vhtSupportedRxNss;
		add_sta_params->vhtTxBFCapable =
#ifdef FEATURE_WLAN_TDLS
			((STA_ENTRY_PEER == sta_ds->staType)
			 || (STA_ENTRY_TDLS_PEER == sta_ds->staType)) ?
					 sta_ds->vhtBeamFormerCapable :
					 session_entry->txBFIniFeatureEnabled;
#else
			(STA_ENTRY_PEER == sta_ds->staType) ?
					 sta_ds->vhtBeamFormerCapable :
					 session_entry->txBFIniFeatureEnabled;
#endif
		add_sta_params->enable_su_tx_bformer =
			sta_ds->vht_su_bfee_capable;
	}

	lim_log(mac_ctx, LOGE, FL("TxChWidth %d vhtTxBFCap %d, su_bfer %d"),
		add_sta_params->ch_width, add_sta_params->vhtTxBFCapable,
		add_sta_params->enable_su_tx_bformer);
#ifdef FEATURE_WLAN_TDLS
	if ((STA_ENTRY_PEER == sta_ds->staType) ||
		(STA_ENTRY_TDLS_PEER == sta_ds->staType))
#else
	if (STA_ENTRY_PEER == sta_ds->staType)
#endif
	{
		/*
		 * peer STA get the LDPC capability from sta_ds,
		 * which populated from
		 * HT/VHT capability
		 */
		if (add_sta_params->vhtTxBFCapable
		    && mac_ctx->lim.disableLDPCWithTxbfAP) {
			add_sta_params->htLdpcCapable = 0;
			add_sta_params->vhtLdpcCapable = 0;
		} else {
			if (session_entry->txLdpcIniFeatureEnabled & 0x1)
				add_sta_params->htLdpcCapable =
						sta_ds->htLdpcCapable;
			else
				add_sta_params->htLdpcCapable = 0;

			if (session_entry->txLdpcIniFeatureEnabled & 0x2)
				add_sta_params->vhtLdpcCapable =
						sta_ds->vhtLdpcCapable;
			else
				add_sta_params->vhtLdpcCapable = 0;
		}
	} else if (STA_ENTRY_SELF == sta_ds->staType) {
		/* For Self STA get the LDPC capability from config.ini */
		add_sta_params->htLdpcCapable =
			(session_entry->txLdpcIniFeatureEnabled & 0x01);
		add_sta_params->vhtLdpcCapable =
			((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
	}

	/* Update PE session ID */
	add_sta_params->sessionId = session_entry->peSessionId;

	/* Update SME session ID */
	add_sta_params->smesessionId = session_entry->smeSessionId;

	add_sta_params->maxTxPower = session_entry->maxTxPower;

	if (session_entry->parsedAssocReq != NULL) {
		uint16_t aid = sta_ds->assocId;
		/* Get a copy of the already parsed Assoc Request */
		assoc_req =
			(tpSirAssocReq) session_entry->parsedAssocReq[aid];
		if (assoc_req && assoc_req->addIEPresent
		    && assoc_req->addIE.length) {
			p2p_ie = limGetP2pIEPtr(mac_ctx,
					assoc_req->addIE.addIEdata,
					assoc_req->addIE.length);
		}

		add_sta_params->p2pCapableSta = (p2p_ie != NULL);
		if (assoc_req && add_sta_params->htCapable) {
			qdf_mem_copy(&add_sta_params->ht_caps,
				     ((uint8_t *) &assoc_req->HTCaps) + 1,
				     sizeof(add_sta_params->ht_caps));
		}

		if (assoc_req && add_sta_params->vhtCapable)
			add_sta_params->vht_caps =
				 lim_populate_vht_caps(assoc_req->VHTCaps);
	} else if (LIM_IS_IBSS_ROLE(session_entry)) {

		/*
		 * in IBSS mode, use peer node as the source of ht_caps
		 * and vht_caps
		 */
		peer_node = lim_ibss_peer_find(mac_ctx, *sta_Addr);
		if (!peer_node) {
			lim_log(mac_ctx, LOGP,
				FL("Can't find IBSS peer node for ADD_STA"));
			return eSIR_HAL_STA_DOES_NOT_EXIST;
		}

		if (peer_node->atimIePresent) {
			add_sta_params->atimIePresent =
				 peer_node->atimIePresent;
			add_sta_params->peerAtimWindowLength =
				peer_node->peerAtimWindowLength;
		}

		add_sta_params->ht_caps =
			(peer_node->htSupportedChannelWidthSet <<
			 SIR_MAC_HT_CAP_CHWIDTH40_S) |
			(peer_node->htGreenfield <<
			 SIR_MAC_HT_CAP_GREENFIELD_S) |
			(peer_node->htShortGI20Mhz <<
			 SIR_MAC_HT_CAP_SHORTGI20MHZ_S) |
			(peer_node->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) |
			(peer_node->htMaxAmsduLength <<
			 SIR_MAC_HT_CAP_MAXAMSDUSIZE_S) |
			(peer_node->htDsssCckRate40MHzSupport <<
			 SIR_MAC_HT_CAP_DSSSCCK40_S);

		add_sta_params->vht_caps =
			 lim_populate_vht_caps(peer_node->VHTCaps);
	}
#ifdef FEATURE_WLAN_TDLS
	if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
		add_sta_params->ht_caps = sta_ds->ht_caps;
		add_sta_params->vht_caps = sta_ds->vht_caps;

		lim_log(mac_ctx, LOG1,
			  FL("Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x"),
			  add_sta_params->ht_caps,
			  add_sta_params->vht_caps);
	}
#endif

#ifdef FEATURE_WLAN_TDLS
	if (sta_ds->wmeEnabled &&
	   (LIM_IS_AP_ROLE(session_entry) ||
	   (STA_ENTRY_TDLS_PEER == sta_ds->staType)))
#else
	if (sta_ds->wmeEnabled && LIM_IS_AP_ROLE(session_entry))
#endif
	{
		add_sta_params->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
		 */
		add_sta_params->uAPSD |=
			sta_ds->qos.capability.qosInfo.acvo_uapsd;
		add_sta_params->uAPSD |=
			(sta_ds->qos.capability.qosInfo.acvi_uapsd << 1);
		add_sta_params->uAPSD |=
			(sta_ds->qos.capability.qosInfo.acbk_uapsd << 2);
		add_sta_params->uAPSD |=
			(sta_ds->qos.capability.qosInfo.acbe_uapsd << 3);
		/*
		 * making delivery enabled and
		 * trigger enabled setting the same.
		 */
		add_sta_params->uAPSD |= add_sta_params->uAPSD << 4;

		add_sta_params->maxSPLen =
			sta_ds->qos.capability.qosInfo.maxSpLen;
		lim_log(mac_ctx, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"),
			add_sta_params->uAPSD, add_sta_params->maxSPLen);
	}
#ifdef WLAN_FEATURE_11W
	add_sta_params->rmfEnabled = sta_ds->rmfEnabled;
	lim_log(mac_ctx, LOG1, FL("PMF enabled %d"),
			 add_sta_params->rmfEnabled);
#endif

	lim_log(mac_ctx, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
			       "p2pCapableSta: %d"),
		add_sta_params->htLdpcCapable, add_sta_params->vhtLdpcCapable,
		add_sta_params->p2pCapableSta);

	if (!add_sta_params->htLdpcCapable)
		add_sta_params->ht_caps &= ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
	if (!add_sta_params->vhtLdpcCapable)
		add_sta_params->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 (add_sta_params->respReqd)
		SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);

	for (i = 0; i < SIR_NUM_11A_RATES; i++) {
		if (sirIsArate(sta_ds->supportedRates.llaRates[i] & 0x7F)) {
			nw_type_11b = 0;
			break;
		} else {
			nw_type_11b = 1;
		}
	}
	if (nw_type_11b)
		add_sta_params->nwType = eSIR_11B_NW_TYPE;
	else
		add_sta_params->nwType = session_entry->nwType;

	msg_q.type = WMA_ADD_STA_REQ;

	msg_q.reserved = 0;
	msg_q.bodyptr = add_sta_params;
	msg_q.bodyval = 0;

	lim_log(mac_ctx, LOG1, FL("Sending WMA_ADD_STA_REQ for assocId %d"),
		sta_ds->assocId);
	MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
			 msg_q.type));

	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
	if (eSIR_SUCCESS != ret_code) {
		if (add_sta_params->respReqd)
			SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
		lim_log(mac_ctx, LOGE,
			FL("ADD_STA_REQ for aId %d failed (reason %X)"),
			sta_ds->assocId, ret_code);
		qdf_mem_free(add_sta_params);
	}

	return ret_code;
}

/**
 * lim_del_sta()
 *
 ***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
lim_del_sta(tpAniSirGlobal pMac,
	    tpDphHashNode pStaDs, bool fRespReqd, tpPESession psessionEntry)
{
	tpDeleteStaParams pDelStaParams = NULL;
	tSirMsgQ msgQ;
	tSirRetStatus retCode = eSIR_SUCCESS;

	pDelStaParams = qdf_mem_malloc(sizeof(tDeleteStaParams));
	if (NULL == pDelStaParams) {
		lim_log(pMac, LOGP,
			FL("Unable to allocate memory during ADD_STA"));
		return eSIR_MEM_ALLOC_FAILED;
	}

	qdf_mem_set((uint8_t *) 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 lim_del_sta 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(mac_trace
				       (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(mac_trace
				       (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;
	qdf_mem_copy((uint8_t *) pDelStaParams->staMac,
		     (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));

	pDelStaParams->status = QDF_STATUS_SUCCESS;
	msgQ.type = WMA_DELETE_STA_REQ;
	msgQ.reserved = 0;
	msgQ.bodyptr = pDelStaParams;
	msgQ.bodyval = 0;

	lim_log(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(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
	retCode = wma_post_ctrl_msg(pMac, &msgQ);
	if (eSIR_SUCCESS != retCode) {
		if (fRespReqd)
			SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
		lim_log(pMac, LOGE,
			FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"),
			retCode);
		qdf_mem_free(pDelStaParams);
	}

	return retCode;
}

#if defined WLAN_FEATURE_VOWIFI_11R
/**
 * lim_add_ft_sta_self()- function to add STA once we have connected with a
 *          new AP
 * @mac_ctx: pointer to global mac structure
 * @assoc_id: association id for the station connection
 * @session_entry: pe session entr
 *
 * 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.
 *
 * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
 */
tSirRetStatus lim_add_ft_sta_self(tpAniSirGlobal mac_ctx, uint16_t assoc_id,
				tpPESession session_entry)
{
	tpAddStaParams add_sta_params = NULL;
	tSirRetStatus ret_code = eSIR_SUCCESS;
	tSirMsgQ msg_q;

	add_sta_params = session_entry->ftPEContext.pAddStaReq;
	add_sta_params->assocId = assoc_id;
	add_sta_params->smesessionId = session_entry->smeSessionId;

	msg_q.type = WMA_ADD_STA_REQ;
	msg_q.reserved = 0;
	msg_q.bodyptr = add_sta_params;
	msg_q.bodyval = 0;

	QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
			"Sending WMA_ADD_STA_REQ (aid %d)",
			 add_sta_params->assocId);
	MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
			 msg_q.type));

	session_entry->limPrevMlmState = session_entry->limMlmState;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
		session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
	session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
	if (eSIR_SUCCESS != ret_code) {
		lim_log(mac_ctx, LOGE,
			FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
			ret_code);
		qdf_mem_free(add_sta_params);
	}

	session_entry->ftPEContext.pAddStaReq = NULL;
	return ret_code;
}
#endif /* WLAN_FEATURE_VOWIFI_11R */

/**
 * lim_add_sta_self()
 *
 ***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
lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
		 tpPESession psessionEntry)
{
	tpAddStaParams pAddStaParams = NULL;
	tSirMsgQ msgQ;
	tSirRetStatus retCode = eSIR_SUCCESS;
	tSirMacAddr staMac;
	uint32_t listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
	uint32_t shortGi20MhzSupport;
	uint32_t shortGi40MhzSupport;
	uint32_t ampduLenExponent = 0;
	/*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.*/
	uint32_t selfStaDot11Mode = 0, selfTxWidth = 0;
	uint32_t val;
	wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
	lim_log(pMac, LOG1, FL("cfgDot11Mode %d"), (int)selfStaDot11Mode);
	wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,
			 &selfTxWidth);
	lim_log(pMac, LOG1, FL("SGI 20 %d"), (int)selfTxWidth);
	lim_log(pMac, LOG1, FL("Roam Channel Bonding Mode %d"),
		(int)pMac->roam.configParam.uCfgDot11Mode);

	sir_copy_mac_addr(staMac, psessionEntry->selfMacAddr);
	lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ": "), MAC_ADDR_ARRAY(staMac));
	pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams));
	if (NULL == pAddStaParams) {
		lim_log(pMac, LOGP,
			FL("Unable to allocate memory during ADD_STA"));
		return eSIR_MEM_ALLOC_FAILED;
	}
	qdf_mem_set((uint8_t *) pAddStaParams, sizeof(tAddStaParams), 0);

	/* / Add STA context at MAC HW (BMU, RHP & TFP) */
	qdf_mem_copy((uint8_t *) pAddStaParams->staMac,
		     (uint8_t *) staMac, sizeof(tSirMacAddr));

	qdf_mem_copy((uint8_t *) pAddStaParams->bssId,
		     psessionEntry->bssId, sizeof(tSirMacAddr));

	pAddStaParams->assocId = psessionEntry->limAID;
	pAddStaParams->staType = STA_ENTRY_SELF;
	pAddStaParams->status = QDF_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_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
			eSIR_SUCCESS) {
		lim_log(pMac, LOGE, FL(
				"Couldn't get SHORT_PREAMBLE, set default"));
		pAddStaParams->shortPreambleSupported = 1;
	} else {
		pAddStaParams->shortPreambleSupported = val;
	}

#ifdef WLAN_FEATURE_11AC
	lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
				  psessionEntry, NULL);
#else
	lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
				  psessionEntry);
#endif
	if (IS_DOT11_MODE_HT(selfStaDot11Mode)) {
		pAddStaParams->htCapable = true;
#ifdef DISABLE_GF_FOR_INTEROP
		if ((psessionEntry->pLimJoinReq != NULL)
		    && (!psessionEntry->pLimJoinReq->bssDescription.
			aniIndicator)) {
			lim_log(pMac, LOGE,
				FL
					(" Turning off Greenfield, when adding self entry"));
			pAddStaParams->greenFieldCapable =
				WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
		} else
#endif
		{
			pAddStaParams->greenFieldCapable =
				lim_get_ht_capability(pMac, eHT_GREENFIELD,
						      psessionEntry);
			pAddStaParams->ch_width =
				pMac->roam.configParam.channelBondingMode5GHz;
			pAddStaParams->mimoPS =
				lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
						      psessionEntry);
			pAddStaParams->rifsMode =
				lim_get_ht_capability(pMac, eHT_RIFS_MODE,
						      psessionEntry);
			pAddStaParams->lsigTxopProtection =
				lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
						      psessionEntry);
			pAddStaParams->maxAmpduDensity =
				lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
						      psessionEntry);
			pAddStaParams->maxAmpduSize =
				lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
						      psessionEntry);
			pAddStaParams->maxAmsduSize =
				lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
						      psessionEntry);
			pAddStaParams->fDsssCckMode40Mhz =
				lim_get_ht_capability(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 (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
							  (pMac, WNI_CFG_SHORT_GI_20MHZ,
							  &shortGi20MhzSupport))) {
				if (true == shortGi20MhzSupport) {
					pAddStaParams->fShortGI20Mhz =
						WNI_CFG_SHORT_GI_20MHZ_STAMAX;
				} else {
					pAddStaParams->fShortGI20Mhz = false;
				}
			} else {
				PELOGE(lim_log
					       (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 (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
							  (pMac, WNI_CFG_SHORT_GI_40MHZ,
							  &shortGi40MhzSupport))) {
				if (true == shortGi40MhzSupport) {
					pAddStaParams->fShortGI40Mhz =
						WNI_CFG_SHORT_GI_40MHZ_STAMAX;
				} else {
					pAddStaParams->fShortGI40Mhz = false;
				}
			} else {
				PELOGE(lim_log
					       (pMac, LOGE,
					       FL("could not retrieve shortGI 40Mhz"
						  "CFG,setting value to default"));
				       )
				pAddStaParams->fShortGI40Mhz =
					WNI_CFG_SHORT_GI_40MHZ_STADEF;
			}
			lim_log(pMac, LOG2,
				FL(" greenFieldCapable: %d maxAmpduDensity = %d "
				   "maxAmpduSize = %d"),
				pAddStaParams->greenFieldCapable,
				pAddStaParams->maxAmpduDensity,
				pAddStaParams->maxAmpduSize);

			lim_log(pMac, LOG2,
				FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
				   "fShortGI40Mhz: %d lsigTxopProtection: %d"),
				pAddStaParams->fDsssCckMode40Mhz,
				pAddStaParams->fShortGI20Mhz,
				pAddStaParams->fShortGI40Mhz,
				pAddStaParams->lsigTxopProtection);

			lim_log(pMac, LOG2,
				FL("maxAmsduSize: %d txChannelWidth: %d mimoPS: %d rifsMode %d"),
				pAddStaParams->maxAmsduSize,
				pAddStaParams->ch_width,
				pAddStaParams->mimoPS, pAddStaParams->rifsMode);
		}
	}
#ifdef WLAN_FEATURE_11AC
	pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode);
	if (pAddStaParams->vhtCapable) {
		pAddStaParams->ch_width =
			psessionEntry->ch_width;
		lim_log(pMac, LOG1, FL("VHT WIDTH SET %d"),
			pAddStaParams->ch_width);
	}
	pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled;
	pAddStaParams->enable_su_tx_bformer =
		psessionEntry->enable_su_tx_bformer;
	lim_log(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d, su_bfer %d"),
		pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable,
		pAddStaParams->enable_su_tx_bformer);

	/* In 11ac mode, the hardware is capable of supporting 128K AMPDU size */
	if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) {
		if (wlan_cfg_get_int
			    (pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &ampduLenExponent)
		    != eSIR_SUCCESS) {
			lim_log(pMac, LOGP,
				FL
					("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
		}
		pAddStaParams->maxAmpduSize = (uint8_t) ampduLenExponent;
	}
	pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee;
	pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
#endif
	pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
	pAddStaParams->enableHtSmps = psessionEntry->enableHtSmps;
	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_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) !=
	    eSIR_SUCCESS)
		lim_log(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
	pAddStaParams->listenInterval = (uint16_t) listenInterval;

	if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona) {
		pAddStaParams->p2pCapableSta = 1;
	}

	pAddStaParams->supportedRates.opRateMode =
		lim_get_sta_rate_mode((uint8_t) selfStaDot11Mode);

	lim_log(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
		pAddStaParams->staIdx, pAddStaParams->updateSta,
		pAddStaParams->htCapable);

	lim_log(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
			       "p2pCapableSta: %d"),
		pAddStaParams->htLdpcCapable, pAddStaParams->vhtLdpcCapable,
		pAddStaParams->p2pCapableSta);

	if (psessionEntry->isNonRoamReassoc) {
		pAddStaParams->nonRoamReassoc = 1;
		psessionEntry->isNonRoamReassoc = 0;
	}
	lim_log(pMac, LOG2, FL("sessionid: %d  Assoc ID: %d listenInterval = %d "
			       "shortPreambleSupported: %d"),
		psessionEntry->smeSessionId, pAddStaParams->assocId,
		pAddStaParams->listenInterval,
		pAddStaParams->shortPreambleSupported);

	msgQ.type = WMA_ADD_STA_REQ;
	msgQ.reserved = 0;
	msgQ.bodyptr = pAddStaParams;
	msgQ.bodyval = 0;

	lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ":Sessionid %d : "
			       "Sending WMA_ADD_STA_REQ. (aid %d)"),
		MAC_ADDR_ARRAY(pAddStaParams->staMac),
		pAddStaParams->sessionId, pAddStaParams->assocId);
	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));

	retCode = wma_post_ctrl_msg(pMac, &msgQ);
	if (eSIR_SUCCESS != retCode) {
		lim_log(pMac, LOGE,
			FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
			retCode);
		qdf_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 lim_teardown_infra_bss(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
	tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

	/**
	 * Send Broadcast Disassociate frame with
	 * 'leaving BSS' reason.
	 */
	lim_send_disassoc_mgmt_frame(pMac,
				     eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
				     bcAddr, psessionEntry, false);
} /*** end lim_teardown_infra_bss() ***/

/**
 * lim_handle_cnf_wait_timeout()
 *
 ***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 lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId)
{
	tpDphHashNode pStaDs;
	tpPESession psessionEntry = NULL;

	psessionEntry = pe_find_session_by_session_id(pMac,
			pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId);
	if (psessionEntry == NULL) {
		lim_log(pMac, LOGP,
			FL("Session Does not exist for given sessionID"));
		return;
	}
	pStaDs = dph_get_hash_entry(pMac, staId, &psessionEntry->dph.dphHashTable);

	if (pStaDs == NULL) {
		PELOGW(lim_log
			       (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(lim_log
			       (pMac, LOGW,
			       FL
				       ("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"),
			       pStaDs->assocId);
		       )
		lim_print_mac_addr(pMac, pStaDs->staAddr, LOGW);

		if (LIM_IS_AP_ROLE(psessionEntry) ||
		    LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
			lim_reject_association(pMac, pStaDs->staAddr,
					       pStaDs->mlmStaContext.subType,
					       true,
					       pStaDs->mlmStaContext.authType,
					       pStaDs->assocId, true,
					       (tSirResultCodes)
					       eSIR_MAC_UNSPEC_FAILURE_STATUS,
					       psessionEntry);
		}
		break;

	default:
		lim_log(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"),
			pStaDs->mlmStaContext.mlmState);
	}
}

/**
 * lim_delete_dph_hash_entry()- function to delete dph hash entry
 * @mac_ctx: pointer to global mac structure
 * @sta_addr: peer station address
 * @sta_id: id assigned to peer station
 * @session_entry: pe session entry
 *
 * This function is called whenever we need to delete
 * the dph hash entry
 *
 * Return: none
 */

void
lim_delete_dph_hash_entry(tpAniSirGlobal mac_ctx, tSirMacAddr sta_addr,
				 uint16_t sta_id, tpPESession session_entry)
{
	uint16_t aid;
	tpDphHashNode sta_ds;
	tUpdateBeaconParams beacon_params;

	qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
	beacon_params.paramChangeBitmap = 0;
	lim_deactivate_and_change_per_sta_id_timer(mac_ctx, eLIM_CNF_WAIT_TIMER,
		 sta_id);
	if (NULL == session_entry) {
		lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
		return;
	}

	beacon_params.bssIdx = session_entry->bssIdx;
	sta_ds = dph_lookup_hash_entry(mac_ctx, sta_addr, &aid,
			 &session_entry->dph.dphHashTable);

	if (sta_ds == NULL) {
		lim_log(mac_ctx, LOGE, FL("sta_ds is NULL"));
		return;
	}

	lim_log(mac_ctx, LOGW, FL("Deleting DPH Hash entry for STAID: %X"),
		 sta_id);
	/*
	 * update the station count and perform associated actions
	 * do this before deleting the dph hash entry
	 */
	lim_util_count_sta_del(mac_ctx, sta_ds, session_entry);

	if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry)) {
		if (LIM_IS_AP_ROLE(session_entry)) {
			if (session_entry->gLimProtectionControl !=
				WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
				lim_decide_ap_protection_on_delete(mac_ctx,
					sta_ds, &beacon_params, session_entry);
		}

		if (LIM_IS_IBSS_ROLE(session_entry))
			lim_ibss_decide_protection_on_delete(mac_ctx, sta_ds,
				     &beacon_params, session_entry);

		lim_decide_short_preamble(mac_ctx, sta_ds, &beacon_params,
					  session_entry);
		lim_decide_short_slot(mac_ctx, sta_ds, &beacon_params,
				      session_entry);

		/* Send message to HAL about beacon parameter change. */
		lim_log(mac_ctx, LOGW, FL("param bitmap = %d "),
				 beacon_params.paramChangeBitmap);
		if (beacon_params.paramChangeBitmap &&
			(false ==
			 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
			sch_set_fixed_beacon_fields(mac_ctx, session_entry);
			lim_send_beacon_params(mac_ctx, &beacon_params,
					       session_entry);
		}
#ifdef WLAN_FEATURE_11W
		tx_timer_delete(&sta_ds->pmfSaQueryTimer);
#endif
	}

	if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id,
		 &session_entry->dph.dphHashTable) != eSIR_SUCCESS)
		lim_log(mac_ctx, LOGP, FL("error deleting hash entry"));
}

/**
 * lim_check_and_announce_join_success()- function to check if the received
 * Beacon/Probe Response is from the BSS that we're attempting to join.
 * @mac: pointer to global mac structure
 * @beacon_probe_rsp: pointer to reveived beacon/probe response frame
 * @header: pointer to received management frame header
 * @session_entry: pe session entry
 *
 * 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.
 * If the Beacon/Probe Response is indeed from the BSS we're
 * attempting to join, join success is sent to SME.
 *
 * Return: none
 */

void
lim_check_and_announce_join_success(tpAniSirGlobal mac_ctx,
		tSirProbeRespBeacon *beacon_probe_rsp, tpSirMacMgmtHdr header,
		tpPESession session_entry)
{
	tSirMacSSid current_ssid;
	tLimMlmJoinCnf mlm_join_cnf;
	uint32_t val = 0;
	uint32_t *noa_duration_from_beacon = NULL;
	uint32_t *noa2_duration_from_beacon = NULL;
	uint32_t noa;
	uint32_t total_num_noa_desc = 0;
	uint32_t selfStaDot11Mode = 0;

	qdf_mem_copy(current_ssid.ssId,
		     session_entry->ssId.ssId, session_entry->ssId.length);

	current_ssid.length = (uint8_t) session_entry->ssId.length;

	/*
	 * Check for SSID only in probe response. Beacons may not carry
	 * SSID information in hidden SSID case
	 */
	if (((SIR_MAC_MGMT_FRAME == header->fc.type) &&
		(SIR_MAC_MGMT_PROBE_RSP == header->fc.subType)) &&
		current_ssid.length &&
		(qdf_mem_cmp((uint8_t *) &beacon_probe_rsp->ssId,
				  (uint8_t *) &current_ssid,
				  (uint8_t) (1 + current_ssid.length)))) {
		/*
		 * Received SSID does not match with the one we've.
		 * Ignore received Beacon frame
		 */
		lim_log(mac_ctx, LOG1,
			 FL("SSID received in Beacon does not match"));
#ifdef WLAN_DEBUG
		mac_ctx->lim.gLimBcnSSIDMismatchCnt++;
#endif
		return;
	}

	if (!(LIM_IS_BT_AMP_STA_ROLE(session_entry) ||
		LIM_IS_STA_ROLE(session_entry)))
		return;

	lim_log(mac_ctx, LOG1,
		 FL("Received Beacon/PR with matching BSSID:%pM PESessionID %d"),
			session_entry->bssId, session_entry->peSessionId);

	/* Deactivate Join Failure timer */
	lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
	/* Deactivate Periodic Join timer */
	lim_deactivate_and_change_timer(mac_ctx,
		eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);

	if (QDF_P2P_CLIENT_MODE == session_entry->pePersona &&
		beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.present) {

		noa_duration_from_beacon = (uint32_t *)
		(beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc + 1);

		if (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.num_NoADesc)
			total_num_noa_desc =
				beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.
				num_NoADesc / SIZE_OF_NOA_DESCRIPTOR;

		noa = *noa_duration_from_beacon;

		if (total_num_noa_desc > 1) {
			noa2_duration_from_beacon = (uint32_t *)
			(beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc +
				SIZE_OF_NOA_DESCRIPTOR + 1);
			noa += *noa2_duration_from_beacon;
		}

		/*
		 * 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_cfg_get_int(mac_ctx,
			WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, &val) ==
			 eSIR_SUCCESS) {
			session_entry->defaultAuthFailureTimeout = val;
			cfg_set_int(mac_ctx,
				WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
				val + noa);
		}
	} else {
		session_entry->defaultAuthFailureTimeout = 0;
	}

	/* Update Beacon Interval at CFG database */

	if (beacon_probe_rsp->HTCaps.present)
		lim_update_sta_run_time_ht_capability(mac_ctx,
			 &beacon_probe_rsp->HTCaps);
	if (beacon_probe_rsp->HTInfo.present)
		lim_update_sta_run_time_ht_info(mac_ctx,
			 &beacon_probe_rsp->HTInfo, session_entry);
	session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
			 session_entry->peSessionId, eLIM_MLM_JOINED_STATE));

	/*
	 * update the capability info based on recently received beacon/probe
	 * response frame
	 */
	session_entry->limCurrentBssCaps =
		lim_get_u16((uint8_t *)&beacon_probe_rsp->capabilityInfo);

	/*
	 * Announce join success by sending
	 * Join confirm to SME.
	 */
	mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
	mlm_join_cnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
	/* Update PE sessionId */
	mlm_join_cnf.sessionId = session_entry->peSessionId;
	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
			     (uint32_t *) &mlm_join_cnf);

	wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);

	if ((IS_DOT11_MODE_VHT(selfStaDot11Mode)) &&
		beacon_probe_rsp->vendor2_ie.VHTCaps.present) {
		session_entry->is_vendor_specific_vhtcaps = true;
		session_entry->vendor_specific_vht_ie_type =
			beacon_probe_rsp->vendor2_ie.type;
		session_entry->vendor_specific_vht_ie_sub_type =
			beacon_probe_rsp->vendor2_ie.sub_type;
		lim_log(mac_ctx, LOG1, FL(
			"VHT caps are present in vendor specific IE"));
	}
}

/**
 * lim_extract_ap_capabilities()
 *
 ***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 lim_extract_ap_capability() 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 lim_extract_ap_capabilities(tpAniSirGlobal pMac,
					  uint8_t *pIE,
					  uint16_t ieLen,
					  tpSirProbeRespBeacon beaconStruct)
{
	qdf_mem_set((uint8_t *) beaconStruct, sizeof(tSirProbeRespBeacon), 0);

	PELOG3(lim_log(pMac, LOG3,
		       FL
			       ("In lim_extract_ap_capabilities: The IE's being received are:"));
	       sir_dump_buf(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 !=
		    sir_parse_beacon_ie(pMac, beaconStruct, pIE,
					(uint32_t) ieLen)) {
			lim_log(pMac, LOGE,
				FL("APCapExtract: Beacon parsing error!"));
			return eSIR_FAILURE;
		}
	}

	return eSIR_SUCCESS;
}

/**
 * lim_del_bss()
 *
 ***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
lim_del_bss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, uint16_t bssIdx,
	    tpPESession psessionEntry)
{
	tpDeleteBssParams pDelBssParams = NULL;
	tSirMsgQ msgQ;
	tSirRetStatus retCode = eSIR_SUCCESS;

	pDelBssParams = qdf_mem_malloc(sizeof(tDeleteBssParams));
	if (NULL == pDelBssParams) {
		lim_log(pMac, LOGP,
			FL("Unable to allocate memory during ADD_BSS"));
		return eSIR_MEM_ALLOC_FAILED;
	}
	qdf_mem_set((uint8_t *) 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(mac_trace
		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
		       eLIM_MLM_WT_DEL_BSS_RSP_STATE));

	if ((psessionEntry->peSessionId ==
	     pMac->lim.limTimers.gLimJoinFailureTimer.sessionId)
	    && (true ==
		tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) {
		lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
	}

	pDelBssParams->status = QDF_STATUS_SUCCESS;
	pDelBssParams->respReqd = 1;
	qdf_mem_copy(pDelBssParams->bssid, psessionEntry->bssId,
		     sizeof(tSirMacAddr));
	pDelBssParams->smesessionId = psessionEntry->smeSessionId;
	PELOGW(lim_log
		       (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 = WMA_DELETE_BSS_REQ;
	msgQ.reserved = 0;
	msgQ.bodyptr = pDelBssParams;
	msgQ.bodyval = 0;

	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));

	retCode = wma_post_ctrl_msg(pMac, &msgQ);
	if (eSIR_SUCCESS != retCode) {
		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
		lim_log(pMac, LOGE,
			FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"),
			retCode);
		qdf_mem_free(pDelBssParams);
	}

	return retCode;
}

/**
 * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response.
 * @mac_ctx Pointer to Global MAC structure
 * @pAddBssParams: parameters required for add bss params.
 * @vht_caps: VHT capabilities.
 * @psessionEntry : session entry.
 *
 * Return : void
 */
void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal mac_ctx,
		tpAddBssParams pAddBssParams,
		tDot11fIEVHTCaps *vht_caps, tpPESession psessionEntry)
{
	pAddBssParams->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));

	pAddBssParams->staContext.maxAmpduSize =
		SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
				pAddBssParams->staContext.vht_caps);

	lim_log(mac_ctx, LOG1,
		FL("Updating VHT caps in assoc Response"));
}

/**
 * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response.
 * @mac_ctx Pointer to Global MAC structure
 * @pAddBssParams: parameters required for add bss params.
 * @vht_oper: VHT Operations to update.
 * @psessionEntry : session entry.
 *
 * Return : void
 */
void lim_update_vht_oper_assoc_resp(tpAniSirGlobal mac_ctx,
		tpAddBssParams pAddBssParams,
		tDot11fIEVHTOperation *vht_oper, tpPESession psessionEntry)
{
	if (vht_oper->chanWidth &&
			psessionEntry->ch_width) {
		pAddBssParams->ch_width = vht_oper->chanWidth + 1;

		pAddBssParams->ch_center_freq_seg0 =
			vht_oper->chanCenterFreqSeg1;

		pAddBssParams->ch_center_freq_seg1 =
			vht_oper->chanCenterFreqSeg2;
	}
	lim_log(mac_ctx, 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 lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
				   tpSchBeaconStruct pBeaconStruct,
				   tpSirBssDescription bssDescription,
				   uint8_t updateEntry, tpPESession psessionEntry)
{
	tSirMsgQ msgQ;
	tpAddBssParams pAddBssParams = NULL;
	uint32_t retCode;
	tpDphHashNode pStaDs = NULL;
	uint8_t chanWidthSupp = 0;
	uint32_t shortGi20MhzSupport;
	uint32_t shortGi40MhzSupport;
	uint32_t enableTxBF20MHz;
	tDot11fIEVHTCaps *vht_caps = NULL;
	tDot11fIEVHTOperation *vht_oper = NULL;
	tAddStaParams *sta_context;

	/* Package SIR_HAL_ADD_BSS_REQ message parameters */
	pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams));
	if (NULL == pAddBssParams) {
		lim_log(pMac, LOGP,
			FL("Unable to allocate memory during ADD_BSS"));
		retCode = eSIR_MEM_ALLOC_FAILED;
		goto returnFailure;
	} else
		qdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams),
			    0);

	qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
		     sizeof(tSirMacAddr));
	/* Fill in tAddBssParams selfMacAddr */
	qdf_mem_copy(pAddBssParams->selfMacAddr,
		     psessionEntry->selfMacAddr, sizeof(tSirMacAddr));

	lim_log(pMac, LOG1,
		FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
		psessionEntry->smeSessionId, updateEntry,
		GET_LIM_SYSTEM_ROLE(psessionEntry));

	lim_log(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;
	qdf_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 =
		(uint8_t) pAssocRsp->capabilityInfo.shortSlotTime;
	pAddBssParams->llaCoexist =
		(uint8_t) psessionEntry->beaconParams.llaCoexist;
	pAddBssParams->llbCoexist =
		(uint8_t) psessionEntry->beaconParams.llbCoexist;
	pAddBssParams->llgCoexist =
		(uint8_t) psessionEntry->beaconParams.llgCoexist;
	pAddBssParams->ht20Coexist =
		(uint8_t) psessionEntry->beaconParams.ht20Coexist;

	lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
			       "cfpCount: %d"), pAddBssParams->bssType,
		pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
		pAddBssParams->cfParamSet.cfpCount);

	lim_log(pMac, LOG2,
		FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
		   " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
		pAddBssParams->cfParamSet.cfpMaxDuration,
		pAddBssParams->cfParamSet.cfpDurRemaining,
		pAddBssParams->rateSet.numRates);

	lim_log(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;
	lim_log(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;
		lim_log(pMac, LOG2, FL("htCapable: %d"),
			pAddBssParams->htCapable);
		if (pBeaconStruct->HTInfo.present) {
			pAddBssParams->htOperMode =
				(tSirMacHTOperatingMode) pAssocRsp->HTInfo.opMode;
			pAddBssParams->dualCTSProtection =
				(uint8_t) pAssocRsp->HTInfo.dualCTSProtection;
			chanWidthSupp =
				lim_get_ht_capability(pMac,
						      eHT_SUPPORTED_CHANNEL_WIDTH_SET,
						      psessionEntry);
			if ((pAssocRsp->HTCaps.supportedChannelWidthSet)
			    && (chanWidthSupp)) {
				pAddBssParams->ch_width = (uint8_t)
					pAssocRsp->HTInfo.recommendedTxWidthSet;
				if (pAssocRsp->HTInfo.secondaryChannelOffset ==
						PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
					pAddBssParams->ch_center_freq_seg0 =
						bssDescription->channelId + 2;
				else if (pAssocRsp->HTInfo.secondaryChannelOffset ==
						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
					pAddBssParams->ch_center_freq_seg0 =
						bssDescription->channelId - 2;
			} else {
				pAddBssParams->ch_width = CH_WIDTH_20MHZ;
				pAddBssParams->ch_center_freq_seg0 = 0;
			}
			pAddBssParams->llnNonGFCoexist =
				(uint8_t) pAssocRsp->HTInfo.nonGFDevicesPresent;
			pAddBssParams->fLsigTXOPProtectionFullSupport =
				(uint8_t) pAssocRsp->HTInfo.
				lsigTXOPProtectionFullSupport;
			pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;

			lim_log(pMac, LOGE,
				FL("htOperMode: %d dualCTSProtection: %d txChannelWidth: %d center_freq_0: %d "),
				pAddBssParams->htOperMode,
				pAddBssParams->dualCTSProtection,
				pAddBssParams->ch_width,
				pAddBssParams->ch_center_freq_seg0);

			lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
					       "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
				pAddBssParams->llnNonGFCoexist,
				pAddBssParams->fLsigTXOPProtectionFullSupport,
				pAddBssParams->fRIFSMode);
		}
	}

	pAddBssParams->currentOperChannel = bssDescription->channelId;
	lim_log(pMac, LOGE, FL("currentOperChannel %d"),
		pAddBssParams->currentOperChannel);
	if (psessionEntry->vhtCapability && (pAssocRsp->VHTCaps.present)) {
		pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present;
		vht_caps =  &pAssocRsp->VHTCaps;
		vht_oper = &pAssocRsp->VHTOperation;
	} else if (psessionEntry->vhtCapability &&
			pAssocRsp->vendor2_ie.VHTCaps.present){
		pAddBssParams->vhtCapable =
			pAssocRsp->vendor2_ie.VHTCaps.present;
		lim_log(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);
	}

	lim_log(pMac, LOGE, FL("vhtCapable %d TxChannelWidth %d center_freq_0 %d center_freq_1 %d"),
			pAddBssParams->vhtCapable, pAddBssParams->ch_width,
			pAddBssParams->ch_center_freq_seg0,
			pAddBssParams->ch_center_freq_seg1);

	/*
	 * Populate the STA-related parameters here
	 * Note that the STA here refers to the AP
	 * staType = PEER
	 */
	sta_context = &pAddBssParams->staContext;
	/* Identifying AP as an STA */
	pAddBssParams->staContext.staType = STA_ENTRY_OTHER;

	qdf_mem_copy(pAddBssParams->staContext.bssId,
			bssDescription->bssId, sizeof(tSirMacAddr));
	pAddBssParams->staContext.listenInterval =
		bssDescription->beaconInterval;

	/* Fill Assoc id from the dph table */
	pStaDs = dph_lookup_hash_entry(pMac, pAddBssParams->staContext.bssId,
				&pAddBssParams->staContext.assocId,
				&psessionEntry->dph.dphHashTable);
	if (pStaDs == NULL) {
		lim_log(pMac, LOGE, FL(
				"Couldn't get assoc id for " "MAC ADDR: "
						MAC_ADDRESS_STR),
				MAC_ADDR_ARRAY(
					pAddBssParams->staContext.staMac));
			return eSIR_FAILURE;
	}

	pAddBssParams->staContext.uAPSD =
		psessionEntry->gUapsdPerAcBitmask;

	pAddBssParams->staContext.maxSPLen = 0;
	pAddBssParams->staContext.shortPreambleSupported =
		(uint8_t) pAssocRsp->capabilityInfo.shortPreamble;
	pAddBssParams->staContext.updateSta = updateEntry;

	lim_log(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 =
			(uint8_t) pAssocRsp->HTCaps.greenField;
		pAddBssParams->staContext.lsigTxopProtection =
			(uint8_t) pAssocRsp->HTCaps.lsigTXOPProtection;
		lim_log(pMac, LOG2, FL(
				"StaCtx: htCap %d GFcap %d lsigTxopProtn %d"),
				pAddBssParams->staContext.htCapable,
				pAddBssParams->staContext.greenFieldCapable,
				pAddBssParams->staContext.lsigTxopProtection);
		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;
				lim_log(pMac, LOG1, FL(
					"VHT Caps are in vendor Specfic IE"));
			}

			if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
						vht_caps->muBeamformerCap) &&
					psessionEntry->txBFIniFeatureEnabled)
				sta_context->vhtTxBFCapable = 1;

			if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
					psessionEntry->txMuBformee)
				sta_context->vhtTxMUBformeeCapable = 1;
			if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
					psessionEntry->enable_su_tx_bformer)
				sta_context->enable_su_tx_bformer = 1;
		}

		if ((pAssocRsp->HTCaps.supportedChannelWidthSet) &&
				(chanWidthSupp)) {
			pAddBssParams->staContext.ch_width = (uint8_t)
				pAssocRsp->HTInfo.recommendedTxWidthSet;
			if (pAssocRsp->VHTCaps.present)
				vht_oper = &pAssocRsp->VHTOperation;
			else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
				vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
				lim_log(pMac, LOG1, FL(
					"VHT Op IE is in vendor Specfic IE"));
			}
			/*
			 * in limExtractApCapability function intersection of FW
			 * advertised channel width and AP advertised channel
			 * width has been taken into account for calculating
			 * psessionEntry->ch_width
			 */
			pAddBssParams->staContext.ch_width =
					psessionEntry->ch_width;

			lim_log(pMac, LOGE, FL(
					"StaCtx: vhtCap %d ChBW %d TxBF %d"),
					pAddBssParams->staContext.vhtCapable,
					pAddBssParams->staContext.ch_width,
					sta_context->vhtTxBFCapable);
			lim_log(pMac, LOGE, FL("StaContext su_tx_bfer %d"),
					sta_context->enable_su_tx_bformer);
		} else {
			sta_context->ch_width =	CH_WIDTH_20MHZ;
			if ((IS_SIR_STATUS_SUCCESS(
				wlan_cfg_get_int(pMac,
					WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
					&enableTxBF20MHz))) &&
					(false == enableTxBF20MHz))
				sta_context->vhtTxBFCapable = 0;
		}
		pAddBssParams->staContext.mimoPS =
			(tSirMacHTMIMOPowerSaveState)
			pAssocRsp->HTCaps.mimoPowerSave;
		pAddBssParams->staContext.maxAmsduSize =
			(uint8_t) pAssocRsp->HTCaps.maximalAMSDUsize;
		pAddBssParams->staContext.maxAmpduDensity =
			pAssocRsp->HTCaps.mpduDensity;
		pAddBssParams->staContext.fDsssCckMode40Mhz =
			(uint8_t) 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 (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
					(pMac, WNI_CFG_SHORT_GI_20MHZ,
					 &shortGi20MhzSupport))) {
			if (true == shortGi20MhzSupport) {
				pAddBssParams->staContext.
					fShortGI20Mhz =
					(uint8_t) pAssocRsp->HTCaps.
					shortGI20MHz;
			} else {
				pAddBssParams->staContext.
					fShortGI20Mhz = false;
			}
		} else {
			lim_log(pMac, LOGE, FL(
				"failed to get shortGI 20Mhz, set default"));
				pAddBssParams->staContext.fShortGI20Mhz =
				WNI_CFG_SHORT_GI_20MHZ_STADEF;
		}

		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
					(pMac, WNI_CFG_SHORT_GI_40MHZ,
					 &shortGi40MhzSupport))) {
			if (true == shortGi40MhzSupport) {
				pAddBssParams->staContext.
					fShortGI40Mhz =
					(uint8_t) pAssocRsp->HTCaps.
					shortGI40MHz;
			} else {
				pAddBssParams->staContext.
					fShortGI40Mhz = false;
			}
		} else {
			lim_log(pMac, LOGE, FL(
				"failed to get shortGI 40Mhz, set default"));
				pAddBssParams->staContext.fShortGI40Mhz =
				WNI_CFG_SHORT_GI_40MHZ_STADEF;
		}

		if (!pAddBssParams->staContext.vhtCapable)
			/* Use max ampd factor advertised in
			 * HTCAP for non-vht connection */
		{
			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 =
				    (uint8_t) pAssocRsp->HTCaps.advCodingCap;
			else
				pAddBssParams->staContext.htLdpcCapable = 0;

			if (pAssocRsp->VHTCaps.present)
				vht_caps = &pAssocRsp->VHTCaps;
			else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
				vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
				lim_log(pMac, LOG1, FL(
					"VHT Caps is in vendor Specfic IE"));
			}
			if (vht_caps != NULL &&
				(psessionEntry->txLdpcIniFeatureEnabled & 0x2))
				pAddBssParams->staContext.vhtLdpcCapable =
					(uint8_t) vht_caps->ldpcCodingCap;
			else
				pAddBssParams->staContext.vhtLdpcCapable = 0;
		}

		if (pBeaconStruct->HTInfo.present)
			pAddBssParams->staContext.rifsMode =
				pAssocRsp->HTInfo.rifsMode;

		lim_log(pMac, LOGE, FL(
				"StaCtx: ChBW %d mimoPS %d maxAmsduSize %d"),
				pAddBssParams->staContext.ch_width,
				pAddBssParams->staContext.mimoPS,
				pAddBssParams->staContext.maxAmsduSize);

		lim_log(pMac, LOG2, FL(
				"maxAmpduDens %d CckMode40Mhz %d SGI20Mhz %d"),
				pAddBssParams->staContext.maxAmpduDensity,
				pAddBssParams->staContext.fDsssCckMode40Mhz,
				pAddBssParams->staContext.fShortGI20Mhz);

		lim_log(pMac, LOG2, FL(
				"SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %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;
	qdf_mem_copy(&pAddBssParams->staContext.capab_info,
			&pAssocRsp->capabilityInfo,
			sizeof(pAddBssParams->staContext.capab_info));
	qdf_mem_copy(&pAddBssParams->staContext.ht_caps,
			(uint8_t *) &pAssocRsp->HTCaps + sizeof(uint8_t),
			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 = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
				&psessionEntry->dph.dphHashTable);
	if (pStaDs != NULL) {
		lim_fill_supported_rates_info(pMac, pStaDs,
				&pStaDs->supportedRates,
				psessionEntry);
		qdf_mem_copy((uint8_t *) &pAddBssParams->staContext.
				supportedRates,
				(uint8_t *) &pStaDs->supportedRates,
				sizeof(tSirSupportedRates));
	} else
		lim_log(pMac, LOGE, FL(
			"could not Update the supported rates"));
	pAddBssParams->staContext.encryptType = psessionEntry->encryptType;

#if defined WLAN_FEATURE_VOWIFI
	pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
	lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
#endif
	/* FIXME_GEN4 - Any other value that can be used for initialization? */
	pAddBssParams->status = QDF_STATUS_SUCCESS;
	pAddBssParams->respReqd = true;
	/* update persona */
	pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona;

	if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona)
		pAddBssParams->staContext.p2pCapableSta = 1;

	pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;

#if defined WLAN_FEATURE_VOWIFI_11R
	pAddBssParams->extSetStaKeyParamValid = 0;
	lim_log(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(mac_trace
		       (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);

	lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
			       "p2pCapableSta: %d"),
		pAddBssParams->staContext.wmmEnabled,
		pAddBssParams->staContext.encryptType,
		pAddBssParams->staContext.p2pCapableSta);

	lim_log(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
			       "LimMlm state to %d"),
		pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
		psessionEntry->limMlmState);
	if (psessionEntry->isNonRoamReassoc)
		pAddBssParams->nonRoamReassoc = 1;
	pAddBssParams->nss = psessionEntry->nss;
	lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);

	/* we need to defer the message until we get the response back from HAL. */
	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);

	msgQ.type = WMA_ADD_BSS_REQ;
	/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
	msgQ.reserved = 0;
	msgQ.bodyptr = pAddBssParams;
	msgQ.bodyval = 0;

	lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
		psessionEntry->peSessionId);
	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));

	retCode = wma_post_ctrl_msg(pMac, &msgQ);
	if (eSIR_SUCCESS != retCode) {
		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
		qdf_mem_free(pAddBssParams);
		lim_log(pMac, LOGE,
			FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
			retCode);
		goto returnFailure;

	} else
		return retCode;

returnFailure:
	/* Clean-up will be done by the caller... */
	return retCode;
}

tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
					     tpPESession psessionEntry)
{
	tSirMsgQ msgQ;
	tpAddBssParams pAddBssParams = NULL;
	uint32_t retCode;
	tSchBeaconStruct *pBeaconStruct;
	uint8_t chanWidthSupp = 0;
	uint32_t shortGi20MhzSupport;
	uint32_t shortGi40MhzSupport;
	tDot11fIEVHTOperation *vht_oper = NULL;
	tDot11fIEVHTCaps *vht_caps = NULL;

	tpSirBssDescription bssDescription =
		&psessionEntry->pLimJoinReq->bssDescription;

	pBeaconStruct = qdf_mem_malloc(sizeof(tSchBeaconStruct));
	if (NULL == pBeaconStruct) {
		lim_log(pMac, LOGE,
			FL("Unable to allocate memory during ADD_BSS"));
		return eSIR_MEM_ALLOC_FAILED;
	}

	/* Package SIR_HAL_ADD_BSS_REQ message parameters */
	pAddBssParams = qdf_mem_malloc(sizeof(tAddBssParams));
	if (NULL == pAddBssParams) {
		lim_log(pMac, LOGP,
			FL("Unable to allocate memory during ADD_BSS"));
		retCode = eSIR_MEM_ALLOC_FAILED;
		goto returnFailure;
	}

	qdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams), 0);

	lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
			lim_get_ielen_from_bss_description(bssDescription),
			pBeaconStruct);

	if (pMac->lim.gLimProtectionControl !=
	    WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
		lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
						   psessionEntry);
	qdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
		     sizeof(tSirMacAddr));

	/* Fill in tAddBssParams selfMacAddr */
	qdf_mem_copy(pAddBssParams->selfMacAddr,
		     psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
	lim_log(pMac, LOG1,
		FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
		psessionEntry->smeSessionId, updateEntry,
		GET_LIM_SYSTEM_ROLE(psessionEntry));

	lim_log(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;
	qdf_mem_copy(pAddBssParams->rateSet.rate,
		     pBeaconStruct->supportedRates.rate,
		     pBeaconStruct->supportedRates.numRates);

	pAddBssParams->nwType = bssDescription->nwType;

	pAddBssParams->shortSlotTimeSupported =
		(uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
	pAddBssParams->llaCoexist =
		(uint8_t) psessionEntry->beaconParams.llaCoexist;
	pAddBssParams->llbCoexist =
		(uint8_t) psessionEntry->beaconParams.llbCoexist;
	pAddBssParams->llgCoexist =
		(uint8_t) psessionEntry->beaconParams.llgCoexist;
	pAddBssParams->ht20Coexist =
		(uint8_t) psessionEntry->beaconParams.ht20Coexist;

	lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
			       "cfpCount: %d"), pAddBssParams->bssType,
		pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
		pAddBssParams->cfParamSet.cfpCount);

	lim_log(pMac, LOG2,
		FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
		   " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
		pAddBssParams->cfParamSet.cfpMaxDuration,
		pAddBssParams->cfParamSet.cfpDurRemaining,
		pAddBssParams->rateSet.numRates);

	lim_log(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;
		lim_log(pMac, LOG2, FL("htCapable: %d"),
			pAddBssParams->htCapable);
		if (pBeaconStruct->HTInfo.present) {
			pAddBssParams->htOperMode =
				(tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
				opMode;
			pAddBssParams->dualCTSProtection =
				(uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;

			chanWidthSupp =
				lim_get_ht_capability(pMac,
						      eHT_SUPPORTED_CHANNEL_WIDTH_SET,
						      psessionEntry);
			if ((pBeaconStruct->HTCaps.supportedChannelWidthSet)
			    && (chanWidthSupp)) {
				pAddBssParams->ch_width =
					(uint8_t) pBeaconStruct->HTInfo.
					recommendedTxWidthSet;
				if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
						PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
					pAddBssParams->ch_center_freq_seg0 =
						bssDescription->channelId + 2;

				if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
						PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
					pAddBssParams->ch_center_freq_seg0 =
						bssDescription->channelId - 2;
			} else {
				pAddBssParams->ch_width = CH_WIDTH_20MHZ;
				pAddBssParams->ch_center_freq_seg0 = 0;
			}
			pAddBssParams->llnNonGFCoexist =
				(uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
			pAddBssParams->fLsigTXOPProtectionFullSupport =
				(uint8_t) pBeaconStruct->HTInfo.
				lsigTXOPProtectionFullSupport;
			pAddBssParams->fRIFSMode =
				pBeaconStruct->HTInfo.rifsMode;

			lim_log(pMac, LOG2,
				FL("htOperMode: %d dualCTSProtection: %d txChannelWidthSet: %d center_freq_seg0: %d "),
				pAddBssParams->htOperMode,
				pAddBssParams->dualCTSProtection,
				pAddBssParams->txChannelWidthSet,
				pAddBssParams->ch_center_freq_seg0);

			lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
					       "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
				pAddBssParams->llnNonGFCoexist,
				pAddBssParams->fLsigTXOPProtectionFullSupport,
				pAddBssParams->fRIFSMode);
		}
	}

	pAddBssParams->currentOperChannel = bssDescription->channelId;
	lim_log(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;
		if (pBeaconStruct->VHTOperation.present)
			vht_oper = &pBeaconStruct->VHTOperation;
		else if (pBeaconStruct->vendor2_ie.VHTOperation.present) {
			vht_oper = &pBeaconStruct->vendor2_ie.VHTOperation;
			lim_log(pMac, LOG1,
					FL("VHT Operation is present in vendor Specfic IE"));
		}


		if ((vht_oper != NULL) &&
			vht_oper->chanWidth &&
			chanWidthSupp) {
			pAddBssParams->ch_center_freq_seg0 =
				vht_oper->chanCenterFreqSeg1;
			pAddBssParams->ch_center_freq_seg1 =
				vht_oper->chanCenterFreqSeg2;
		}
		/*
		 * in limExtractApCapability function intersection of FW
		 * advertised channel width and AP advertised channel width has
		 * been taken into account for calculating
		 * psessionEntry->ch_width
		 */
		pAddBssParams->ch_width =
			psessionEntry->ch_width;
		pAddBssParams->staContext.maxAmpduSize =
			SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
					pAddBssParams->staContext.vht_caps);
	} else {
		pAddBssParams->vhtCapable = 0;
	}
	lim_log(pMac, LOGE, FL("vhtCapable %d vhtTxChannelWidthSet %d center_freq_seg0 - %d, center_freq_seg1 - %d"),
		pAddBssParams->vhtCapable, pAddBssParams->ch_width,
		pAddBssParams->ch_center_freq_seg0,
		pAddBssParams->ch_center_freq_seg1);
#endif

	/*
	 * Populate the STA-related parameters here
	 * Note that the STA here refers to the AP
	 */
	/* Identifying AP as an STA */
	pAddBssParams->staContext.staType = STA_ENTRY_OTHER;

	qdf_mem_copy(pAddBssParams->staContext.bssId,
			bssDescription->bssId, sizeof(tSirMacAddr));
	pAddBssParams->staContext.listenInterval =
		bssDescription->beaconInterval;

	pAddBssParams->staContext.assocId = 0;
	pAddBssParams->staContext.uAPSD = 0;
	pAddBssParams->staContext.maxSPLen = 0;
	pAddBssParams->staContext.shortPreambleSupported =
		(uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
	pAddBssParams->staContext.updateSta = updateEntry;

	lim_log(pMac, LOG2, FL(
			"StaCtx: " MAC_ADDRESS_STR " shortPreamble: %d"),
			MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
			pAddBssParams->staContext.shortPreambleSupported);

	pAddBssParams->dot11_mode = psessionEntry->dot11mode;
	lim_log(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 =
			(uint8_t) pBeaconStruct->HTCaps.greenField;
		pAddBssParams->staContext.lsigTxopProtection =
			(uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
		lim_log(pMac, LOG2, FL(
				"StaCtx: htCap %d GFCap %d lsigTxopProtn %d"),
				pAddBssParams->staContext.htCapable,
				pAddBssParams->staContext.greenFieldCapable,
				pAddBssParams->staContext.lsigTxopProtection);
		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;
			if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
					psessionEntry->enable_su_tx_bformer)
				pAddBssParams->staContext.enable_su_tx_bformer
						= 1;
			lim_log(pMac, LOG2, FL("StaContext: su_tx_bfer %d"),
				pAddBssParams->staContext.enable_su_tx_bformer);
		}
		if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
				(chanWidthSupp)) {
			pAddBssParams->staContext.ch_width =
				(uint8_t) pBeaconStruct->HTInfo.
				recommendedTxWidthSet;
			if ((vht_oper != NULL) &&
					pAddBssParams->staContext.vhtCapable &&
					vht_oper->chanWidth)
				pAddBssParams->staContext.ch_width =
					vht_oper->chanWidth + 1;
			lim_log(pMac, LOG2, FL(
					"StaCtx: vhtCap %d ch_bw %d TxBF %d"),
					pAddBssParams->staContext.vhtCapable,
					pAddBssParams->staContext.ch_width,
					pAddBssParams->staContext.
					vhtTxBFCapable);
		} else {
			pAddBssParams->staContext.ch_width =
				CH_WIDTH_20MHZ;
		}
		pAddBssParams->staContext.mimoPS =
			(tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
			mimoPowerSave;
		pAddBssParams->staContext.maxAmsduSize =
			(uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
		pAddBssParams->staContext.maxAmpduDensity =
			pBeaconStruct->HTCaps.mpduDensity;
		pAddBssParams->staContext.fDsssCckMode40Mhz =
			(uint8_t) 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 (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
					(pMac, WNI_CFG_SHORT_GI_20MHZ,
					 &shortGi20MhzSupport))) {
			if (true == shortGi20MhzSupport)
				pAddBssParams->staContext.fShortGI20Mhz =
				(uint8_t)pBeaconStruct->HTCaps.shortGI20MHz;
			else
				pAddBssParams->staContext.fShortGI20Mhz =
					false;
		} else {
			lim_log(pMac, LOGE, FL(
				"get shortGI 20Mhz failed, set default"));
				pAddBssParams->staContext.fShortGI20Mhz =
				WNI_CFG_SHORT_GI_20MHZ_STADEF;
		}

		if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
					(pMac, WNI_CFG_SHORT_GI_40MHZ,
					 &shortGi40MhzSupport))) {
			if (true == shortGi40MhzSupport) {
				pAddBssParams->staContext.
					fShortGI40Mhz =
					(uint8_t) pBeaconStruct->HTCaps.
					shortGI40MHz;
			} else {
				pAddBssParams->staContext.
					fShortGI40Mhz = false;
			}
		} else {
			lim_log(pMac, LOGE, FL(
				"get shortGI 40Mhz failed, set 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 =
					(uint8_t) pBeaconStruct->HTCaps.
						advCodingCap;
			else
				pAddBssParams->staContext.htLdpcCapable = 0;

			if (pBeaconStruct->VHTCaps.present)
				vht_caps = &pBeaconStruct->VHTCaps;
			else if (pBeaconStruct->vendor2_ie.VHTCaps.present) {
				vht_caps =
					&pBeaconStruct->vendor2_ie.VHTCaps;
				lim_log(pMac, LOG1, FL(
					"VHT Caps are in vendor Specfic IE"));
			}
			if (vht_caps != NULL &&
				(psessionEntry->txLdpcIniFeatureEnabled & 0x2))
				pAddBssParams->staContext.vhtLdpcCapable =
					(uint8_t) vht_caps->ldpcCodingCap;
			else
				pAddBssParams->staContext.vhtLdpcCapable = 0;
		}

		if (pBeaconStruct->HTInfo.present)
			pAddBssParams->staContext.rifsMode =
				pBeaconStruct->HTInfo.rifsMode;
		lim_log(pMac, LOG2,
				FL("StaContext ChannelWidth: %d mimoPS: %d maxAmsduSize: %d"),
				pAddBssParams->staContext.ch_width,
				pAddBssParams->staContext.mimoPS,
				pAddBssParams->staContext.maxAmsduSize);

		lim_log(pMac, LOG2, FL(
				"maxAmpduDensity %d Cck40Mhz %d SGI20Mhz %d"),
				pAddBssParams->staContext.maxAmpduDensity,
				pAddBssParams->staContext.fDsssCckMode40Mhz,
				pAddBssParams->staContext.fShortGI20Mhz);

		lim_log(pMac, LOG2, FL(
				"SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %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
	lim_populate_peer_rate_set(pMac,
			&pAddBssParams->staContext.
			supportedRates,
			pBeaconStruct->HTCaps.supportedMCSSet,
			false, psessionEntry,
			&pBeaconStruct->VHTCaps);
#else
	lim_populate_peer_rate_set(pMac,
			&pAddBssParams->staContext.
			supportedRates,
			pBeaconStruct->HTCaps.supportedMCSSet,
			false, psessionEntry);
#endif
	lim_fill_supported_rates_info(pMac, NULL,
			&pAddBssParams->staContext.
			supportedRates, psessionEntry);


	pAddBssParams->staContext.encryptType = psessionEntry->encryptType;

#if defined WLAN_FEATURE_VOWIFI
	pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
	lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
#endif

	pAddBssParams->status = QDF_STATUS_SUCCESS;
	pAddBssParams->respReqd = true;

	pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
	pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
	pAddBssParams->sessionId = psessionEntry->peSessionId;

	pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona; /* update persona */

	pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;

#if defined WLAN_FEATURE_VOWIFI_11R
	pAddBssParams->extSetStaKeyParamValid = 0;
	lim_log(pMac, LOG2, FL("extSetStaKeyParamValid: %d"),
		pAddBssParams->extSetStaKeyParamValid);
#endif

#ifdef WLAN_FEATURE_11W
	if (psessionEntry->limRmfEnabled) {
		pAddBssParams->rmfEnabled = 1;
		pAddBssParams->staContext.rmfEnabled = 1;
	}
#endif

	pAddBssParams->nss = psessionEntry->nss;
	lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);

	/* Set a new state for MLME */
	psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;

	MTRACE(mac_trace
		       (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
		       psessionEntry->limMlmState));

	lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
			       "p2pCapableSta: %d"),
		pAddBssParams->staContext.wmmEnabled,
		pAddBssParams->staContext.encryptType,
		pAddBssParams->staContext.p2pCapableSta);

	lim_log(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);

	msgQ.type = WMA_ADD_BSS_REQ;
	/** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
	msgQ.reserved = 0;
	msgQ.bodyptr = pAddBssParams;
	msgQ.bodyval = 0;

	lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
		psessionEntry->peSessionId);
	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));

	retCode = wma_post_ctrl_msg(pMac, &msgQ);
	if (eSIR_SUCCESS != retCode) {
		SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
		qdf_mem_free(pAddBssParams);
		lim_log(pMac, LOGE,
			FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
			retCode);
		goto returnFailure;

	} else {
		qdf_mem_free(pBeaconStruct);
		return retCode;
	}

returnFailure:
	/* Clean-up will be done by the caller... */
	qdf_mem_free(pBeaconStruct);
	return retCode;
}

/**
 * lim_prepare_and_send_del_sta_cnf() - prepares and send del sta cnf
 *
 * @pMac:          mac global context
 * @pStaDs:        sta dph node
 * @statusCode:    status code
 * @psessionEntry: session context
 *
 * deletes DPH entry, changes the MLM mode for station, calls
 * lim_send_del_sta_cnf
 *
 * Return: void
 */
void
lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
				 tSirResultCodes statusCode,
				 tpPESession psessionEntry)
{
	uint16_t staDsAssocId = 0;
	struct qdf_mac_addr sta_dsaddr;
	tLimMlmStaContext mlmStaContext;

	if (pStaDs == NULL) {
		PELOGW(lim_log(pMac, LOGW, FL("pStaDs is NULL"));)
		return;
	}
	staDsAssocId = pStaDs->assocId;
	qdf_mem_copy((uint8_t *) sta_dsaddr.bytes,
		     pStaDs->staAddr, QDF_MAC_ADDR_SIZE);

	mlmStaContext = pStaDs->mlmStaContext;
	if (LIM_IS_AP_ROLE(psessionEntry) ||
	    LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
		lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
	}
	lim_delete_dph_hash_entry(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(mac_trace(pMac, TRACE_CODE_MLM_STATE,
				 psessionEntry->peSessionId,
				 psessionEntry->limMlmState));
	}
	lim_send_del_sta_cnf(pMac, sta_dsaddr, staDsAssocId, mlmStaContext,
			     statusCode, psessionEntry);
}

/** -------------------------------------------------------------
   \fn lim_get_sta_rate_mode
   \brief Gets the Station Rate Mode.
   \param     uint8_t dot11Mode
   \return none
   -------------------------------------------------------------*/
tStaRateMode lim_get_sta_rate_mode(uint8_t 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 lim_init_pre_auth_timer_table
   \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 lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
				   tpLimPreAuthTable pPreAuthTimerTable)
{
	uint32_t cfgValue;
	uint32_t authNodeIdx;
	tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable;

	/* Get AUTH_RSP Timers value */

	if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
			     &cfgValue) != eSIR_SUCCESS) {
		/*
		** Could not get AUTH_RSP timeout value
		** from CFG. Log error.
		**/
		lim_log(pMac, LOGP,
			FL("could not retrieve AUTH_RSP timeout value"));
		return;
	}

	cfgValue = SYS_MS_TO_TICKS(cfgValue);
	for (authNodeIdx = 0; authNodeIdx < pPreAuthTimerTable->numEntry;
	     authNodeIdx++, pAuthNode++) {
		if (tx_timer_create(pMac, &pAuthNode->timer,
			"AUTH RESPONSE TIMEOUT",
			lim_auth_response_timer_handler, authNodeIdx,
			cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
			/* Cannot create timer.  Log error. */
			lim_log(pMac, LOGP,
				FL("Cannot create Auth Rsp timer of Index :%d."),
				authNodeIdx);
			return;
		}
		pAuthNode->authNodeIdx = (uint8_t) authNodeIdx;
		pAuthNode->fFree = 1;
	}

}

/** -------------------------------------------------------------
   \fn lim_acquire_free_pre_auth_node
   \brief Retrives a free Pre Auth node from Pre Auth Table.
   \param     tpAniSirGlobal    pMac
   \param     tpLimPreAuthTable pPreAuthTimerTable
   \return none
   -------------------------------------------------------------*/
tLimPreAuthNode *lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
						tpLimPreAuthTable pPreAuthTimerTable)
{
	uint32_t i;
	tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable;
	for (i = 0; i < pPreAuthTimerTable->numEntry; i++, pTempNode++) {
		if (pTempNode->fFree == 1) {
			pTempNode->fFree = 0;
			return pTempNode;
		}
	}

	return NULL;
}

/** -------------------------------------------------------------
   \fn lim_get_pre_auth_node_from_index
   \brief Depending on the Index this retrives the pre auth node.
   \param     tpAniSirGlobal    pMac
   \param     tpLimPreAuthTable pAuthTable
   \param     uint32_t authNodeIdx
   \return none
   -------------------------------------------------------------*/
tLimPreAuthNode *lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
						  tpLimPreAuthTable pAuthTable,
						  uint32_t authNodeIdx)
{
	if ((authNodeIdx >= pAuthTable->numEntry)
	    || (pAuthTable->pTable == NULL)) {
		lim_log(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 lim_is_dot11h_supported_channels_valid(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 lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
							tSirAssocReq *assoc,
							tpPESession psessionEntry)
{
	int8_t localMaxTxPower;
	uint32_t localPwrConstraint;

	localMaxTxPower =
		cfg_get_regulatory_max_transmit_power(pMac,
						      psessionEntry->currentOperChannel);

	if (wlan_cfg_get_int
		    (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
		    &localPwrConstraint) != eSIR_SUCCESS) {
		lim_log(pMac, LOGP,
			FL("Unable to get Local Power Constraint from cfg"));
		return eSIR_FAILURE;
	}
	localMaxTxPower -= (int8_t) 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) {
		lim_log(pMac, LOGW,
			FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"),
			assoc->powerCapability.minTxPower, localMaxTxPower);
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;
}

/** -------------------------------------------------------------
   \fn     lim_fill_rx_highest_supported_rate
   \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  uint8_t*  pSupportedMCSSet
   \return none
   -------------------------------------------------------------*/
void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
					uint16_t *rxHighestRate,
					uint8_t *pSupportedMCSSet)
{
	tSirMacRxHighestSupportRate *pRxHighestRate;
	uint8_t *pBuf;
	uint16_t rate = 0;

	pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
	rate = lim_get_u16(pBuf);

	pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
	*rxHighestRate = pRxHighestRate->rate;

	return;
}

#ifdef WLAN_FEATURE_11W
/** -------------------------------------------------------------
   \fn     lim_send_sme_unprotected_mgmt_frame_ind
   \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 lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
					     uint8_t *frame, uint32_t frameLen,
					     uint16_t sessionId,
					     tpPESession psessionEntry)
{
	tSirMsgQ mmhMsg;
	tSirSmeUnprotMgmtFrameInd *pSirSmeMgmtFrame = NULL;
	uint16_t length;

	length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen;

	pSirSmeMgmtFrame = qdf_mem_malloc(length);
	if (NULL == pSirSmeMgmtFrame) {
		lim_log(pMac, LOGP,
			FL
				("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd"));
		return;
	}
	qdf_mem_set((void *)pSirSmeMgmtFrame, length, 0);

	pSirSmeMgmtFrame->sessionId = sessionId;
	pSirSmeMgmtFrame->frameType = frameType;

	qdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
	pSirSmeMgmtFrame->frameLen = frameLen;

	mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND;
	mmhMsg.bodyptr = pSirSmeMgmtFrame;
	mmhMsg.bodyval = 0;

	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
	return;
}
#endif

#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
/** -------------------------------------------------------------
   \fn     lim_send_sme_tsm_ie_ind
   \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 lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
			     uint8_t tid, uint8_t state, uint16_t measInterval)
{
	tSirMsgQ mmhMsg;
	tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL;

	if (!pMac || !psessionEntry)
		return;

	pSirSmeTsmIeInd = qdf_mem_malloc(sizeof(tSirSmeTsmIEInd));
	if (NULL == pSirSmeTsmIeInd) {
		lim_log(pMac, LOGP,
			FL("AllocateMemory failed for tSirSmeTsmIEInd"));
		return;
	}
	qdf_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;

	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
	return;
}
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
