/*
 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
 *
 * 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 lim_process_assoc_req_frame.c contains the code
 * for processing Re/Association Request Frame.
 */
#include "cds_api.h"
#include "ani_global.h"
#include "wni_cfg.h"
#include "sir_api.h"
#include "cfg_api.h"
#include "cfg_ucfg_api.h"

#include "sch_api.h"
#include "utils_api.h"
#include "lim_types.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 "cds_packet.h"
#include "lim_session_utils.h"
#include "utils_parser.h"

#include "qdf_types.h"
#include "cds_utils.h"
#include "wlan_utility.h"
#include "wlan_crypto_global_api.h"

/**
 * lim_convert_supported_channels - Parses channel support IE
 * @mac_ctx: A pointer to Global MAC structure
 * @assoc_ind: A pointer to SME ASSOC/REASSOC IND
 * @assoc_req: A pointer to ASSOC/REASSOC Request frame
 *
 * This function is called by lim_process_assoc_req_frame() to
 * parse the channel support IE in the Assoc/Reassoc Request
 * frame, and send relevant information in the SME_ASSOC_IND
 *
 * Return: None
 */
static void lim_convert_supported_channels(struct mac_context *mac_ctx,
					   tpLimMlmAssocInd assoc_ind,
					   tSirAssocReq *assoc_req)
{
	uint16_t i, j, index = 0;
	uint8_t first_ch_no;
	uint8_t chn_count;
	uint8_t next_ch_no;
	uint8_t channel_offset = 0;

	if (assoc_req->supportedChannels.length >=
		SIR_MAX_SUPPORTED_CHANNEL_LIST) {
		pe_err("Number of supported channels: %d is more than MAX",
			assoc_req->supportedChannels.length);
		assoc_ind->supportedChannels.numChnl = 0;
		return;
	}

	for (i = 0; i < (assoc_req->supportedChannels.length); i++) {
		/* Get First Channel Number */
		first_ch_no = assoc_req->supportedChannels.supportedChannels[i];
		assoc_ind->supportedChannels.channelList[index] = first_ch_no;
		i++;
		index++;

		/* Get Number of Channels in a Subband */
		chn_count = assoc_req->supportedChannels.supportedChannels[i];
		pe_debug("Rcv assoc_req: chnl: %d numOfChnl: %d",
			first_ch_no, chn_count);
		if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
			pe_warn("Ch count > max supported: %d", chn_count);
			assoc_ind->supportedChannels.numChnl = 0;
			return;
		}
		if (chn_count <= 1)
			continue;
		next_ch_no = first_ch_no;
		if (BAND_5G == lim_get_rf_band(first_ch_no))
			channel_offset =  SIR_11A_FREQUENCY_OFFSET;
		else if (BAND_2G == lim_get_rf_band(first_ch_no))
			channel_offset = SIR_11B_FREQUENCY_OFFSET;
		else
			continue;

		for (j = 1; j < chn_count; j++) {
			next_ch_no += channel_offset;
			assoc_ind->supportedChannels.channelList[index]
				= next_ch_no;
			index++;
			if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
				pe_warn("Ch count > supported: %d", chn_count);
				assoc_ind->supportedChannels.numChnl = 0;
				return;
			}
		}
	}

	assoc_ind->supportedChannels.numChnl = (uint8_t) index;
	pe_debug("Send AssocInd to WSM: minPwr: %d maxPwr: %d numChnl: %d",
		assoc_ind->powerCap.minTxPower,
		assoc_ind->powerCap.maxTxPower,
		assoc_ind->supportedChannels.numChnl);
}

/**
 * lim_check_sta_in_pe_entries() - checks if sta exists in any dph tables.
 * @mac_ctx: Pointer to Global MAC structure
 * @hdr: A pointer to the MAC header
 * @sessionid - session id for which session is initiated
 *
 * This function is called by lim_process_assoc_req_frame() to check if STA
 * entry already exists in any of the PE entries of the AP. If it exists, deauth
 * will be sent on that session and the STA deletion will happen. After this,
 * the ASSOC request will be processed
 *
 * Return: True if duplicate entry found; FALSE otherwise.
 */
static bool lim_check_sta_in_pe_entries(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
				 uint16_t sessionid)
{
	uint8_t i;
	uint16_t assoc_id = 0;
	tpDphHashNode sta_ds = NULL;
	struct pe_session *session = NULL;
	bool dup_entry = false;

	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
		if ((&mac_ctx->lim.gpSession[i] != NULL) &&
		    (mac_ctx->lim.gpSession[i].valid) &&
		    (mac_ctx->lim.gpSession[i].pePersona == QDF_SAP_MODE)) {
			session = &mac_ctx->lim.gpSession[i];
			sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa,
					&assoc_id, &session->dph.dphHashTable);
			if (sta_ds
#ifdef WLAN_FEATURE_11W
				&& (!sta_ds->rmfEnabled ||
				    (sessionid != session->peSessionId))
#endif
			    ) {
				pe_err("Sending Disassoc and Deleting existing STA entry:"
					   MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(session->selfMacAddr));
				lim_send_disassoc_mgmt_frame(mac_ctx,
					eSIR_MAC_UNSPEC_FAILURE_REASON,
					(uint8_t *) hdr->sa, session, false);
				/*
				 * Cleanup Rx path posts eWNI_SME_DISASSOC_RSP
				 * msg to SME after delete sta which will update
				 * the userspace with disconnect
				 */
				sta_ds->mlmStaContext.cleanupTrigger =
							eLIM_DUPLICATE_ENTRY;
				sta_ds->mlmStaContext.disassocReason =
				eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
				lim_send_sme_disassoc_ind(mac_ctx, sta_ds,
					session);
				dup_entry = true;
				break;
			}
		}
	}
	return dup_entry;
}

/**
 * lim_chk_sa_da() - checks source addr to destination addr of assoc req frame
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks source addr to destination addr of assoc req frame
 *
 * Return: true if source and destination address are different
 */
static bool lim_chk_sa_da(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			  struct pe_session *session, uint8_t sub_type)
{
	if (qdf_mem_cmp((uint8_t *) hdr->sa,
					(uint8_t *) hdr->da,
					(uint8_t) (sizeof(tSirMacAddr))))
		return true;

	pe_err("Assoc Req rejected: wlan.sa = wlan.da");
	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
				      1, hdr->sa, sub_type, 0, session);
	return false;
}

/**
 * lim_chk_tkip() - checks TKIP counter measure is active
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks TKIP counter measure is active
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_tkip(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			 struct pe_session *session, uint8_t sub_type)
{
	/*
	 * If TKIP counter measures active send Assoc Rsp frame to station
	 * with eSIR_MAC_MIC_FAILURE_REASON
	 */
	if (!(session->bTkipCntrMeasActive && LIM_IS_AP_ROLE(session)))
		return true;

	pe_err("Assoc Req rejected: TKIP counter measure is active");
	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, 1,
				      hdr->sa, sub_type, 0, session);
	return false;
}

/**
 * lim_chk_assoc_req_parse_error() - checks for error in frame parsing
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @frm_body: frame body
 * @frame_len: frame len
 *
 * Checks for error in frame parsing
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_assoc_req_parse_error(struct mac_context *mac_ctx,
					  tpSirMacMgmtHdr hdr,
					  struct pe_session *session,
					  tpSirAssocReq assoc_req,
					  uint8_t sub_type, uint8_t *frm_body,
					  uint32_t frame_len)
{
	QDF_STATUS status;

	if (sub_type == LIM_ASSOC)
		status = sir_convert_assoc_req_frame2_struct(mac_ctx, frm_body,
							frame_len, assoc_req);
	else
		status = sir_convert_reassoc_req_frame2_struct(mac_ctx,
						frm_body, frame_len, assoc_req);

	if (status == QDF_STATUS_SUCCESS)
		return true;

	pe_warn("Assoc Req rejected: frame parsing error. source addr:"
			MAC_ADDRESS_STR, MAC_ADDR_ARRAY(hdr->sa));
	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
				      1, hdr->sa, sub_type, 0, session);
	return false;
}

/**
 * lim_chk_capab() - checks for capab match
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @local_cap: local capabilities of SAP
 *
 * Checks for capab match
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_capab(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			  struct pe_session *session, tpSirAssocReq assoc_req,
			  uint8_t sub_type, tSirMacCapabilityInfo *local_cap)
{
	uint16_t temp;

	if (cfg_get_capability_info(mac_ctx, &temp, session) != QDF_STATUS_SUCCESS) {
		pe_err("could not retrieve Capabilities");
		return false;
	}

	lim_copy_u16((uint8_t *) local_cap, temp);

	if (lim_compare_capabilities(mac_ctx, assoc_req,
				     local_cap, session) == false) {
		pe_warn("Rcvd %s Req with unsupported capab from"
				MAC_ADDRESS_STR,
			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
			MAC_ADDR_ARRAY(hdr->sa));
		/*
		 * Capabilities of requesting STA does not match with
		 * local capabilities. Respond with 'unsupported capabilities'
		 * status code.
		 */
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
			1, hdr->sa, sub_type, 0, session);
		return false;
	}
	return true;
}

/**
 * lim_chk_ssid() - checks for SSID match
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for SSID match
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_ssid(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			 struct pe_session *session, tpSirAssocReq assoc_req,
			 uint8_t sub_type)
{
	if (lim_cmp_ssid(&assoc_req->ssId, session) != true)
		return true;

	pe_err("%s Req with ssid wrong(Rcvd: %.*s self: %.*s) from "
			MAC_ADDRESS_STR,
		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
		assoc_req->ssId.length, assoc_req->ssId.ssId,
		session->ssId.length, session->ssId.ssId,
		MAC_ADDR_ARRAY(hdr->sa));

	/*
	 * Received Re/Association Request with either Broadcast SSID OR with
	 * SSID that does not match with local one. Respond with unspecified
	 * status code.
	 */
	lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS,
				      1, hdr->sa, sub_type, 0, session);
	return false;
}

/**
 * lim_chk_rates() - checks for supported rates
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for supported rates
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_rates(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			  struct pe_session *session, tpSirAssocReq assoc_req,
			  uint8_t sub_type)
{
	uint8_t i = 0, j = 0;
	tSirMacRateSet basic_rates;
	/*
	 * Verify if the requested rates are available in supported rate
	 * set or Extended rate set. Some APs are adding basic rates in
	 * Extended rateset IE
	 */
	basic_rates.numRates = 0;

	for (i = 0; i < assoc_req->supportedRates.numRates
			&& (i < SIR_MAC_RATESET_EID_MAX); i++) {
		basic_rates.rate[i] = assoc_req->supportedRates.rate[i];
		basic_rates.numRates++;
	}

	for (j = 0; (j < assoc_req->extendedRates.numRates)
			&& (i < SIR_MAC_RATESET_EID_MAX); i++, j++) {
		basic_rates.rate[i] = assoc_req->extendedRates.rate[j];
		basic_rates.numRates++;
	}

	if (lim_check_rx_basic_rates(mac_ctx, basic_rates, session) == true)
		return true;

	pe_warn("Assoc Req rejected: unsupported rates, soruce addr: %s"
			MAC_ADDRESS_STR,
		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
		MAC_ADDR_ARRAY(hdr->sa));
	/*
	 * Requesting STA does not support ALL BSS basic rates. Respond with
	 * 'basic rates not supported' status code.
	 */
	lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1,
				hdr->sa, sub_type, 0, session);
	return false;
}

/**
 * lim_chk_11g_only() - checks for non 11g STA
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for non 11g STA
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_11g_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			     struct pe_session *session, tpSirAssocReq assoc_req,
			     uint8_t sub_type)
{
	if (LIM_IS_AP_ROLE(session) &&
	    (session->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
	    (assoc_req->HTCaps.present)) {
		pe_err("SOFTAP was in 11G only mode, rejecting legacy STA: "
				MAC_ADDRESS_STR,
			MAC_ADDR_ARRAY(hdr->sa));
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
				1, hdr->sa, sub_type, 0, session);
		return false;
	}
	return true;
}

/**
 * lim_chk_11n_only() - checks for non 11n STA
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for non 11n STA
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_11n_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			     struct pe_session *session, tpSirAssocReq assoc_req,
			     uint8_t sub_type)
{
	if (LIM_IS_AP_ROLE(session) &&
	    (session->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
	    (!assoc_req->HTCaps.present)) {
		pe_err("SOFTAP was in 11N only mode, rejecting legacy STA: "
				MAC_ADDRESS_STR,
			MAC_ADDR_ARRAY(hdr->sa));
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
			1, hdr->sa, sub_type, 0, session);
		return false;
	}
	return true;
}

/**
 * lim_chk_11ac_only() - checks for non 11ac STA
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for non 11ac STA
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_11ac_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			      struct pe_session *session, tpSirAssocReq assoc_req,
			      uint8_t sub_type)
{
	tDot11fIEVHTCaps *vht_caps;

	if (assoc_req->VHTCaps.present)
		vht_caps = &assoc_req->VHTCaps;
	else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
		 session->vendor_vht_sap)
		vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
	else
		vht_caps = NULL;

	if (LIM_IS_AP_ROLE(session) &&
		(session->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) &&
		((vht_caps == NULL) || ((vht_caps != NULL) && (!vht_caps->present)))) {
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
			1, hdr->sa, sub_type, 0, session);
		pe_err("SOFTAP was in 11AC only mode, reject");
		return false;
	}
	return true;
}

/**
 * lim_chk_11ax_only() - checks for non 11ax STA
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for non 11ax STA
 *
 * Return: true of no error, false otherwise
 */
#ifdef WLAN_FEATURE_11AX
static bool lim_chk_11ax_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			      struct pe_session *session, tpSirAssocReq assoc_req,
			      uint8_t sub_type)
{
	if (LIM_IS_AP_ROLE(session) &&
		(session->dot11mode == WNI_CFG_DOT11_MODE_11AX_ONLY) &&
		 !assoc_req->he_cap.present) {
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
			eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
			1, hdr->sa, sub_type, 0, session);
		pe_err("SOFTAP was in 11AX only mode, reject");
		return false;
	}
	return true;
}

/**
 * lim_check_11ax_basic_mcs() - checks for 11ax basic MCS rates
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for non 11ax STA
 *
 * Return: true of no error, false otherwise
 */
static bool lim_check_11ax_basic_mcs(struct mac_context *mac_ctx,
				     tpSirMacMgmtHdr hdr,
				     struct pe_session *session,
				     tpSirAssocReq assoc_req,
				     uint8_t sub_type)
{
	uint16_t basic_mcs, sta_mcs, rx_mcs, tx_mcs, final_mcs;

	if (LIM_IS_AP_ROLE(session) &&
	    assoc_req->he_cap.present) {
		rx_mcs = assoc_req->he_cap.rx_he_mcs_map_lt_80;
		tx_mcs = assoc_req->he_cap.tx_he_mcs_map_lt_80;
		sta_mcs = HE_INTERSECT_MCS(rx_mcs, tx_mcs);
		basic_mcs =
		(uint16_t)mac_ctx->mlme_cfg->he_caps.he_ops_basic_mcs_nss;
		final_mcs = HE_INTERSECT_MCS(sta_mcs, basic_mcs);
		if (final_mcs != basic_mcs) {
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
				1, hdr->sa, sub_type, 0, session);
			pe_err("STA did not support basic MCS required by SAP");
			return false;
		}
	}
	return true;
}

#else
static bool lim_chk_11ax_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			      struct pe_session *session, tpSirAssocReq assoc_req,
			      uint8_t sub_type)
{
	return true;
}

static bool lim_check_11ax_basic_mcs(struct mac_context *mac_ctx,
				     tpSirMacMgmtHdr hdr,
				     struct pe_session *session,
				     tpSirAssocReq assoc_req,
				     uint8_t sub_type)
{
	return true;
}
#endif

/**
 * lim_process_for_spectrum_mgmt() - process assoc req for spectrum mgmt
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @local_cap: local capabilities of SAP
 *
 * Checks for SSID match
 *
 * process assoc req for spectrum mgmt
 */
static void
lim_process_for_spectrum_mgmt(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			      struct pe_session *session, tpSirAssocReq assoc_req,
			      uint8_t sub_type, tSirMacCapabilityInfo local_cap)
{
	if (local_cap.spectrumMgt) {
		QDF_STATUS status = QDF_STATUS_SUCCESS;
		/*
		 * If station is 11h capable, then it SHOULD send all mandatory
		 * IEs in assoc request frame. Let us verify that
		 */
		if (assoc_req->capabilityInfo.spectrumMgt) {
			if (!((assoc_req->powerCapabilityPresent)
			     && (assoc_req->supportedChannelsPresent))) {
				/*
				 * One or more required information elements are
				 * missing, log the peers error
				 */
				if (!assoc_req->powerCapabilityPresent) {
					pe_warn("LIM Info: Missing Power capability IE in %s Req from "
							MAC_ADDRESS_STR,
						(LIM_ASSOC == sub_type) ?
							"Assoc" : "ReAssoc",
						MAC_ADDR_ARRAY(hdr->sa));
				}
				if (!assoc_req->supportedChannelsPresent) {
					pe_warn("LIM Info: Missing Supported channel IE in %s Req from "
							MAC_ADDRESS_STR,
						(LIM_ASSOC == sub_type) ?
							"Assoc" : "ReAssoc",
						MAC_ADDR_ARRAY(hdr->sa));
				}
			} else {
				/* Assoc request has mandatory fields */
				status =
				    lim_is_dot11h_power_capabilities_in_range(
					mac_ctx, assoc_req, session);
				if (QDF_STATUS_SUCCESS != status) {
					pe_warn("LIM Info: MinTxPower(STA) > MaxTxPower(AP) in %s Req from "
						MAC_ADDRESS_STR,
						(LIM_ASSOC == sub_type) ?
							"Assoc" : "ReAssoc",
						MAC_ADDR_ARRAY(hdr->sa));
				}
				status = lim_is_dot11h_supported_channels_valid(
							mac_ctx, assoc_req);
				if (QDF_STATUS_SUCCESS != status) {
					pe_warn("LIM Info: wrong supported channels (STA) in %s Req from "
						MAC_ADDRESS_STR,
						(LIM_ASSOC == sub_type) ?
							"Assoc" : "ReAssoc",
						MAC_ADDR_ARRAY(hdr->sa));
				}
				/* IEs are valid, use them if needed */
			}
		} /* if(assoc.capabilityInfo.spectrumMgt) */
		else {
			/*
			 * As per the capabiities, the spectrum management is
			 * not enabled on the station. The AP may allow the
			 * associations to happen even if spectrum management
			 * is not allowed, if the transmit power of station is
			 * below the regulatory maximum
			 */

			/*
			 * TODO: presently, this is not handled. In the current
			 * implementation, the AP would allow the station to
			 * associate even if it doesn't support spectrum
			 * management.
			 */
		}
	} /* end of spectrum management related processing */
}

/**
 * lim_chk_mcs() - checks for supported MCS
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 *
 * Checks for supported MCS
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_mcs(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			struct pe_session *session, tpSirAssocReq assoc_req,
			uint8_t sub_type)
{
	if ((assoc_req->HTCaps.present) && (lim_check_mcs_set(mac_ctx,
			assoc_req->HTCaps.supportedMCSSet) == false)) {
		pe_warn("rcvd %s req with unsupported MCS Rate Set from "
				MAC_ADDRESS_STR,
			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
			MAC_ADDR_ARRAY(hdr->sa));
		/*
		 * Requesting STA does not support ALL BSS MCS basic Rate set
		 * rates. Spec does not define any status code for this
		 * scenario.
		 */
		lim_send_assoc_rsp_mgmt_frame(mac_ctx,
					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
					1, hdr->sa, sub_type, 0, session);
		return false;
	}
	return true;
}

/**
 * lim_chk_is_11b_sta_supported() - checks if STA is 11b
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @phy_mode: phy mode
 *
 * Checks if STA is 11b
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_is_11b_sta_supported(struct mac_context *mac_ctx,
					 tpSirMacMgmtHdr hdr,
					 struct pe_session *session,
					 tpSirAssocReq assoc_req,
					 uint8_t sub_type, uint32_t phy_mode)
{
	uint32_t cfg_11g_only;

	if (phy_mode == WNI_CFG_PHY_MODE_11G) {
		cfg_11g_only = mac_ctx->mlme_cfg->sap_cfg.sap_11g_policy;
		if (!assoc_req->extendedRatesPresent && cfg_11g_only) {
			/*
			 * Received Re/Association Request from 11b STA when 11g
			 * only policy option is set. Reject with unspecified
			 * status code.
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
				1, hdr->sa, sub_type, 0, session);

			pe_warn("Rejecting Re/Assoc req from 11b STA:");
			lim_print_mac_addr(mac_ctx, hdr->sa, LOGW);

#ifdef WLAN_DEBUG
			mac_ctx->lim.gLim11bStaAssocRejectCount++;
#endif
			return false;
		}
	}
	return true;
}

/**
 * lim_print_ht_cap() - prints HT caps
 * @mac_ctx: pointer to Global MAC structure
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 *
 * Prints HT caps
 *
 * Return: void
 */
static void lim_print_ht_cap(struct mac_context *mac_ctx, struct pe_session *session,
			     tpSirAssocReq assoc_req)
{
	if (!session->htCapability)
		return;

	if (assoc_req->HTCaps.present) {
		/* The station *does* support 802.11n HT capability... */
		pe_debug("AdvCodingCap:%d ChaWidthSet:%d PowerSave:%d greenField:%d shortGI20:%d shortGI40:%d txSTBC:%d rxSTBC:%d delayBA:%d maxAMSDUsize:%d DSSS/CCK:%d  PSMP:%d stbcCntl:%d lsigTXProt:%d",
			assoc_req->HTCaps.advCodingCap,
			assoc_req->HTCaps.supportedChannelWidthSet,
			assoc_req->HTCaps.mimoPowerSave,
			assoc_req->HTCaps.greenField,
			assoc_req->HTCaps.shortGI20MHz,
			assoc_req->HTCaps.shortGI40MHz,
			assoc_req->HTCaps.txSTBC,
			assoc_req->HTCaps.rxSTBC,
			assoc_req->HTCaps.delayedBA,
			assoc_req->HTCaps.maximalAMSDUsize,
			assoc_req->HTCaps.dsssCckMode40MHz,
			assoc_req->HTCaps.psmp,
			assoc_req->HTCaps.stbcControlFrame,
			assoc_req->HTCaps.lsigTXOPProtection);
		/*
		 * Make sure the STA's caps are compatible with our own:
		 * 11.15.2 Support of DSSS/CCK in 40 MHz the AP shall refuse
		 * association requests from an HT STA that has the DSSS/CCK
		 * Mode in 40 MHz subfield set to 1;
		 */
	}
}

#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT
static tSirMacStatusCodes lim_check_rsn_ie(struct pe_session *session,
					   struct mac_context *mac_ctx,
					   tpSirAssocReq assoc_req,
					   tDot11fIERSN *rsn,
					   bool *pmf_connection)
{
	struct wlan_objmgr_vdev *vdev;

	uint8_t buffer[SIR_MAC_MAX_IE_LENGTH];
	uint32_t dot11f_status, written = 0, nbuffer = SIR_MAC_MAX_IE_LENGTH;
	tSirMacRsnInfo rsn_ie;

	dot11f_status = dot11f_pack_ie_rsn(mac_ctx, rsn, buffer,
					   nbuffer, &written);
	if (DOT11F_FAILED(dot11f_status)) {
		pe_err("Failed to re-pack the RSN IE (0x%0x8)", dot11f_status);
		return eSIR_MAC_INVALID_IE_STATUS;
	}

	rsn_ie.length = (uint8_t) written;
	qdf_mem_copy(&rsn_ie.info[0], buffer, rsn_ie.length);
	if (wlan_crypto_check_rsn_match(mac_ctx->psoc, session->smeSessionId,
					&rsn_ie.info[0], rsn_ie.length)) {
		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
							session->smeSessionId,
							WLAN_LEGACY_MAC_ID);
		if (!vdev) {
			pe_err("vdev is NULL");
			return eSIR_MAC_UNSPEC_FAILURE_STATUS;
		}

		*pmf_connection = wlan_crypto_vdev_is_pmf_enabled(vdev);
		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
	} else {
		return eSIR_MAC_INVALID_IE_STATUS;
	}

	return eSIR_MAC_SUCCESS_STATUS;
}

static tSirMacStatusCodes lim_check_wpa_ie(struct pe_session *session,
					   struct mac_context *mac_ctx,
					   tpSirAssocReq assoc_req,
					   tDot11fIEWPA *wpa)
{
	uint8_t buffer[SIR_MAC_MAX_IE_LENGTH];
	uint32_t dot11f_status, written = 0, nbuffer = SIR_MAC_MAX_IE_LENGTH;
	tSirMacRsnInfo wpa_ie = {0};

	dot11f_status = dot11f_pack_ie_wpa(mac_ctx, wpa, buffer,
					   nbuffer, &written);
	if (DOT11F_FAILED(dot11f_status)) {
		pe_err("Failed to re-pack the RSN IE (0x%0x8)", dot11f_status);
		return eSIR_MAC_INVALID_IE_STATUS;
	}

	wpa_ie.length = (uint8_t) written;
	qdf_mem_copy(&wpa_ie.info[0], buffer, wpa_ie.length);
	if (wlan_crypto_check_wpa_match(mac_ctx->psoc, session->smeSessionId,
					&wpa_ie.info[0], wpa_ie.length))
		return eSIR_MAC_SUCCESS_STATUS;

	return eSIR_MAC_INVALID_IE_STATUS;
}
#else
static tSirMacStatusCodes lim_check_rsn_ie(struct pe_session *session,
					   struct mac_context *mac_ctx,
					   tpSirAssocReq assoc_req,
					   tDot11fIERSN *rsn,
					   bool *pmf_connection)
{
	return lim_check_rx_rsn_ie_match(mac_ctx, rsn, session,
					 assoc_req->HTCaps.present,
					 pmf_connection);
}

static tSirMacStatusCodes lim_check_wpa_ie(struct pe_session *session,
					   struct mac_context *mac_ctx,
					   tpSirAssocReq assoc_req,
					   tDot11fIEWPA *wpa)
{
	return lim_check_rx_wpa_ie_match(mac_ctx, wpa, session,
					 assoc_req->HTCaps.present);
}
#endif
/**
  * lim_check_wpa_rsn_ie() - wpa and rsn ie related checks
  * @session: pointer to pe session entry
  * @mac_ctx: pointer to Global MAC structure
  * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
  * @hdr: pointer to the MAC head
  * @assoc_req: pointer to ASSOC/REASSOC Request frame
  * @pmf_connection: flag indicating pmf connection
  *
  * This function checks if wpa/rsn IE is present and validates
  * ie version, length and mismatch.
  *
  * Return: true if no error, false otherwise
  */
static bool lim_check_wpa_rsn_ie(struct pe_session *session, struct mac_context *mac_ctx,
				 uint8_t sub_type, tpSirMacMgmtHdr hdr,
				 tpSirAssocReq assoc_req, bool *pmf_connection)
{
	uint32_t ret;
	tDot11fIEWPA dot11f_ie_wpa = {0};
	tDot11fIERSN dot11f_ie_rsn = {0};
	tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;

	/*
	 * Clear the buffers so that frame parser knows that there isn't a
	 * previously decoded IE in these buffers
	 */
	qdf_mem_set((uint8_t *) &dot11f_ie_rsn, sizeof(dot11f_ie_rsn), 0);
	qdf_mem_set((uint8_t *) &dot11f_ie_wpa, sizeof(dot11f_ie_wpa), 0);
	pe_err("RSN enabled auth, Re/Assoc req from STA: "
		MAC_ADDRESS_STR, MAC_ADDR_ARRAY(hdr->sa));

	if (assoc_req->rsnPresent) {
		if (!(assoc_req->rsn.length)) {
			pe_warn("Re/Assoc rejected from: "
				MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(hdr->sa));
			/*
			 * rcvd Assoc req frame with RSN IE but
			 * length is zero
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_INVALID_IE_STATUS, 1,
				hdr->sa, sub_type, 0, session);
			return false;
		}

		/* Unpack the RSN IE */
		ret = dot11f_unpack_ie_rsn(mac_ctx,
					   &assoc_req->rsn.info[0],
					   assoc_req->rsn.length,
					   &dot11f_ie_rsn, false);
		if (!DOT11F_SUCCEEDED(ret)) {
			pe_err("Invalid RSN IE");
			lim_send_assoc_rsp_mgmt_frame(
				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
				hdr->sa, sub_type, 0, session);
			return false;
		}

		/* Check if the RSN version is supported */
		if (SIR_MAC_OUI_VERSION_1 == dot11f_ie_rsn.version) {
			/* check the groupwise and pairwise cipher suites */
			status = lim_check_rsn_ie(session, mac_ctx, assoc_req,
						  &dot11f_ie_rsn,
						  pmf_connection);
			if (eSIR_MAC_SUCCESS_STATUS != status) {
				pe_warn("Re/Assoc rejected from: "
					MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(hdr->sa));

				lim_send_assoc_rsp_mgmt_frame(mac_ctx, status,
							 1, hdr->sa, sub_type,
							 0, session);
				return false;
			}
		} else {
			pe_warn("Re/Assoc rejected from: " MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(hdr->sa));
			/*
			 * rcvd Assoc req frame with RSN IE but
			 * IE version is wrong
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
				1, hdr->sa, sub_type, 0, session);
			return false;
		}
	} else if (assoc_req->wpaPresent) {
		if (!(assoc_req->wpa.length)) {
			pe_warn("Re/Assoc rejected from: "
				MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(hdr->sa));

			/* rcvd Assoc req frame with invalid WPA IE length */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_INVALID_IE_STATUS, 1,
				hdr->sa, sub_type, 0, session);
			return false;
		}
		/* Unpack the WPA IE */
		ret = dot11f_unpack_ie_wpa(mac_ctx,
					   &assoc_req->wpa.info[4],
					   (assoc_req->wpa.length - 4),
					   &dot11f_ie_wpa, false);
		if (!DOT11F_SUCCEEDED(ret)) {
			pe_err("Invalid WPA IE");
			lim_send_assoc_rsp_mgmt_frame(
				mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1,
				hdr->sa, sub_type, 0, session);
			return false;
		}

		/* check the groupwise and pairwise cipher suites*/
		status = lim_check_wpa_ie(session, mac_ctx, assoc_req,
					  &dot11f_ie_wpa);
		if (eSIR_MAC_SUCCESS_STATUS != status) {
			pe_warn("Re/Assoc rejected from: "
				MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(hdr->sa));
			/*
			 * rcvd Assoc req frame with WPA IE
			 * but there is mismatch
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1,
					hdr->sa, sub_type, 0, session);
			return false;
		}

	}

	return true;
}

/**
 * lim_chk_n_process_wpa_rsn_ie() - wpa ie related checks
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @pmf_connection: flag indicating pmf connection
 *
 * wpa ie related checks
 *
 * Return: true if no error, false otherwise
 */
static bool lim_chk_n_process_wpa_rsn_ie(struct mac_context *mac_ctx,
					 tpSirMacMgmtHdr hdr,
					 struct pe_session *session,
					 tpSirAssocReq assoc_req,
					 uint8_t sub_type, bool *pmf_connection)
{
	const uint8_t *wps_ie = NULL;

	/* if additional IE is present, check if it has WscIE */
	if (assoc_req->addIEPresent && assoc_req->addIE.length)
		wps_ie = limGetWscIEPtr(mac_ctx, assoc_req->addIE.addIEdata,
					assoc_req->addIE.length);
	else
		pe_debug("Assoc req addIEPresent: %d addIE length: %d",
			 assoc_req->addIEPresent, assoc_req->addIE.length);

	/* when wps_ie is present, RSN/WPA IE is ignored */
	if (wps_ie == NULL) {
		/* check whether RSN IE is present */
		if (LIM_IS_AP_ROLE(session) &&
		    session->pLimStartBssReq->privacy &&
		    session->pLimStartBssReq->rsnIE.length)
			return lim_check_wpa_rsn_ie(session, mac_ctx, sub_type,
						hdr, assoc_req, pmf_connection);
	} else {
		pe_debug("Assoc req WSE IE is present");
	}
	return true;
}

/**
 * lim_process_assoc_req_no_sta_ctx() - process assoc req for no sta ctx present
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @sta_pre_auth_ctx: sta pre auth context
 * @sta_ds: station dph entry
 * @auth_type: indicates security type
 *
 * Process assoc req for no sta ctx present
 *
 * Return: true of no error, false otherwise
 */
static bool lim_process_assoc_req_no_sta_ctx(struct mac_context *mac_ctx,
				tpSirMacMgmtHdr hdr, struct pe_session *session,
				tpSirAssocReq assoc_req, uint8_t sub_type,
				struct tLimPreAuthNode *sta_pre_auth_ctx,
				tpDphHashNode sta_ds, tAniAuthType *auth_type)
{
	/* Requesting STA is not currently associated */
	if (pe_get_current_stas_count(mac_ctx) ==
			mac_ctx->mlme_cfg->sap_cfg.assoc_sta_limit) {
		/*
		 * Maximum number of STAs that AP can handle reached.
		 * Send Association response to peer MAC entity
		 */
		pe_err("Max Sta count reached : %d",
				mac_ctx->lim.maxStation);
		lim_reject_association(mac_ctx, hdr->sa, sub_type, false,
			(tAniAuthType) 0, 0, false,
			eSIR_MAC_UNSPEC_FAILURE_STATUS,
			session);
		return false;
	}
	/* Check if STA is pre-authenticated. */
	if ((sta_pre_auth_ctx == NULL) || (sta_pre_auth_ctx &&
		(sta_pre_auth_ctx->mlmState != eLIM_MLM_AUTHENTICATED_STATE))) {
		/*
		 * STA is not pre-authenticated yet requesting Re/Association
		 * before Authentication. OR STA is in the process of getting
		 * authenticated and sent Re/Association request. Send
		 * Deauthentication frame with 'prior authentication required'
		 * reason code.
		 */
		lim_send_deauth_mgmt_frame(mac_ctx,
				eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON,
				hdr->sa, session, false);

		pe_warn("rcvd %s req, sessionid: %d, without pre-auth ctx"
				MAC_ADDRESS_STR,
			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
			session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
		return false;
	}
	/* Delete 'pre-auth' context of STA */
	*auth_type = sta_pre_auth_ctx->authType;
	lim_delete_pre_auth_node(mac_ctx, hdr->sa);
	/* All is well. Assign AID (after else part) */
	return true;
}

/**
 * lim_process_assoc_req_sta_ctx() - process assoc req for sta context present
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @sta_pre_auth_ctx: sta pre auth context
 * @sta_ds: station dph entry
 * @peer_idx: peer index
 * @auth_type: indicates security type
 * @update_ctx: indicates if STA context already exist
 *
 * Process assoc req for sta context present
 *
 * Return: true of no error, false otherwise
 */
static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx,
				tpSirMacMgmtHdr hdr, struct pe_session *session,
				tpSirAssocReq assoc_req, uint8_t sub_type,
				struct tLimPreAuthNode *sta_pre_auth_ctx,
				tpDphHashNode sta_ds, uint16_t peer_idx,
				tAniAuthType *auth_type, uint8_t *update_ctx)
{
	/* STA context does exist for this STA */
	if (sta_ds->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
		/*
		 * Requesting STA is in some 'transient' state? Ignore the
		 * Re/Assoc Req frame by incrementing debug counter & logging
		 * error.
		 */
		if (sub_type == LIM_ASSOC) {
#ifdef WLAN_DEBUG
			mac_ctx->lim.gLimNumAssocReqDropInvldState++;
#endif
			pe_debug("received Assoc req in state: %X from",
				sta_ds->mlmStaContext.mlmState);
		} else {
#ifdef WLAN_DEBUG
			mac_ctx->lim.gLimNumReassocReqDropInvldState++;
#endif
			pe_debug("received ReAssoc req in state: %X from",
				sta_ds->mlmStaContext.mlmState);
		}
		lim_print_mac_addr(mac_ctx, hdr->sa, LOGD);
		lim_print_mlm_state(mac_ctx, LOGD,
			(tLimMlmStates) sta_ds->mlmStaContext.mlmState);
		return false;
	}

	/* STA sent assoc req frame while already in 'associated' state */

#ifdef WLAN_FEATURE_11W
	pe_debug("Re/Assoc request from station that is already associated");
	pe_debug("PMF enabled: %d, SA Query state: %d",
		sta_ds->rmfEnabled, sta_ds->pmfSaQueryState);
	if (sta_ds->rmfEnabled) {
		switch (sta_ds->pmfSaQueryState) {
		/*
		 * start SA Query procedure, respond to Association Request with
		 * try again later
		 */
		case DPH_SA_QUERY_NOT_IN_PROGRESS:
			/*
			 * We should reset the retry counter before we start
			 * the SA query procedure, otherwise in next set of SA
			 * query procedure we will end up using the stale value.
			 */
			sta_ds->pmfSaQueryRetryCount = 0;
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
					eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa,
					sub_type, sta_ds, session);
			lim_send_sa_query_request_frame(mac_ctx,
				(uint8_t *) &(sta_ds->pmfSaQueryCurrentTransId),
				hdr->sa, session);
			sta_ds->pmfSaQueryStartTransId =
				sta_ds->pmfSaQueryCurrentTransId;
			sta_ds->pmfSaQueryCurrentTransId++;

			/* start timer for SA Query retry */
			if (tx_timer_activate(&sta_ds->pmfSaQueryTimer)
					!= TX_SUCCESS) {
				pe_err("PMF SA Query timer start failed!");
				return false;
			}
			sta_ds->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS;
			return false;
		/*
		 * SA Query procedure still going, respond to Association
		 * Request with try again later
		 */
		case DPH_SA_QUERY_IN_PROGRESS:
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
						eSIR_MAC_TRY_AGAIN_LATER, 1,
						hdr->sa, sub_type, 0, session);
			return false;

		/*
		 * SA Query procedure timed out, accept Association
		 * Request normally
		 */
		case DPH_SA_QUERY_TIMED_OUT:
			sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
			break;
		}
	}
#endif

	/* no change in the capability so drop the frame */
	if ((sub_type == LIM_ASSOC) &&
		(!qdf_mem_cmp(&sta_ds->mlmStaContext.capabilityInfo,
			&assoc_req->capabilityInfo,
			sizeof(tSirMacCapabilityInfo)))) {
		pe_err("Received Assoc req in state: %X STAid: %d",
			sta_ds->mlmStaContext.mlmState, peer_idx);
		return false;
	} else {
		/*
		 * STA sent Re/association Request frame while already in
		 * 'associated' state. Update STA capabilities and send
		 * Association response frame with same AID
		 */
		pe_debug("Rcvd Assoc req from STA already connected");
		sta_ds->mlmStaContext.capabilityInfo =
			assoc_req->capabilityInfo;
		if (sta_pre_auth_ctx && (sta_pre_auth_ctx->mlmState ==
			eLIM_MLM_AUTHENTICATED_STATE)) {
			/* STA has triggered pre-auth again */
			*auth_type = sta_pre_auth_ctx->authType;
			lim_delete_pre_auth_node(mac_ctx, hdr->sa);
		} else {
			*auth_type = sta_ds->mlmStaContext.authType;
		}

		*update_ctx = true;
		if (dph_init_sta_state(mac_ctx, hdr->sa, peer_idx, true,
			&session->dph.dphHashTable) == NULL) {
			pe_err("could not Init STAid: %d", peer_idx);
			return false;
		}
	}
	return true;
}

/**
 * lim_chk_wmm() - wmm related checks
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @qos_mode: qos mode
 *
 * wmm related checks
 *
 * Return: true of no error, false otherwise
 */
static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			struct pe_session *session, tpSirAssocReq assoc_req,
			uint8_t sub_type, tHalBitVal qos_mode)
{
	tHalBitVal wme_mode;

	limGetWmeMode(session, &wme_mode);
	if ((qos_mode == eHAL_SET) || (wme_mode == eHAL_SET)) {
		/*
		 * for a qsta, check if the requested Traffic spec is admissible
		 * for a non-qsta check if the sta can be admitted
		 */
		if (assoc_req->addtsPresent) {
			uint8_t tspecIdx = 0;

			if (lim_admit_control_add_ts(mac_ctx, hdr->sa,
				&(assoc_req->addtsReq),
				&(assoc_req->qosCapability),
				0, false, NULL, &tspecIdx, session) !=
					QDF_STATUS_SUCCESS) {
				pe_warn("AdmitControl: TSPEC rejected");
				lim_send_assoc_rsp_mgmt_frame(mac_ctx,
					eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
					1, hdr->sa, sub_type, 0, session);
#ifdef WLAN_DEBUG
				mac_ctx->lim.gLimNumAssocReqDropACRejectTS++;
#endif
				return false;
			}
		} else if (lim_admit_control_add_sta(mac_ctx, hdr->sa, false)
				!= QDF_STATUS_SUCCESS) {
			pe_warn("AdmitControl: Sta rejected");
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1,
				hdr->sa, sub_type, 0, session);
#ifdef WLAN_DEBUG
			mac_ctx->lim.gLimNumAssocReqDropACRejectSta++;
#endif
			return false;
		}
		/* else all ok */
		pe_debug("AdmitControl: Sta OK!");
	}
	return true;
}

/**
 * lim_update_sta_ds() - updates ds dph entry
 * @mac_ctx: pointer to Global MAC structure
 * @hdr: pointer to the MAC head
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame pointer
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @sta_ds: station dph entry
 * @auth_type: indicates security type
 * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
 * @peer_idx: peer index
 * @qos_mode: qos mode
 * @pmf_connection: flag indicating pmf connection
 *
 * Updates ds dph entry
 *
 * Return: true of no error, false otherwise
 */
static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr,
			      struct pe_session *session, tpSirAssocReq assoc_req,
			      uint8_t sub_type, tpDphHashNode sta_ds,
			      tAniAuthType auth_type,
			      bool *assoc_req_copied, uint16_t peer_idx,
			      tHalBitVal qos_mode, bool pmf_connection)
{
	tHalBitVal wme_mode, wsm_mode;
	uint8_t *ht_cap_ie = NULL;
#ifdef WLAN_FEATURE_11W
	tPmfSaQueryTimerId timer_id;
	uint16_t retry_interval;
#endif
	tDot11fIEVHTCaps *vht_caps;
	tpSirAssocReq tmp_assoc_req;

	if (assoc_req->VHTCaps.present)
		vht_caps = &assoc_req->VHTCaps;
	else if (assoc_req->vendor_vht_ie.VHTCaps.present &&
		 session->vendor_vht_sap)
		vht_caps = &assoc_req->vendor_vht_ie.VHTCaps;
	else
		vht_caps = NULL;

	/*
	 * check here if the parsedAssocReq already pointing to the assoc_req
	 * and free it before assigning this new assoc_req
	 */
	if (session->parsedAssocReq != NULL) {
		tmp_assoc_req = session->parsedAssocReq[sta_ds->assocId];
		if (tmp_assoc_req != NULL) {
			if (tmp_assoc_req->assocReqFrame) {
				qdf_mem_free(tmp_assoc_req->assocReqFrame);
				tmp_assoc_req->assocReqFrame = NULL;
				tmp_assoc_req->assocReqFrameLength = 0;
			}
			qdf_mem_free(tmp_assoc_req);
			tmp_assoc_req = NULL;
		}

		session->parsedAssocReq[sta_ds->assocId] = assoc_req;
		*assoc_req_copied = true;
	}

	sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present;
	if ((vht_caps != NULL) && vht_caps->present)
		sta_ds->mlmStaContext.vhtCapability = vht_caps->present;
	else
		sta_ds->mlmStaContext.vhtCapability = false;
	lim_update_stads_he_capable(sta_ds, assoc_req);
	sta_ds->qos.addtsPresent =
		(assoc_req->addtsPresent == 0) ? false : true;
	sta_ds->qos.addts = assoc_req->addtsReq;
	sta_ds->qos.capability = assoc_req->qosCapability;
	sta_ds->versionPresent = 0;
	/*
	 * short slot and short preamble should be updated before doing
	 * limaddsta
	 */
	sta_ds->shortPreambleEnabled =
		(uint8_t) assoc_req->capabilityInfo.shortPreamble;
	sta_ds->shortSlotTimeEnabled =
		(uint8_t) assoc_req->capabilityInfo.shortSlotTime;

	sta_ds->valid = 0;
	sta_ds->mlmStaContext.authType = auth_type;
	sta_ds->staType = STA_ENTRY_PEER;

	/*
	 * TODO: If listen interval is more than certain limit, reject the
	 * association. Need to check customer requirements and then implement.
	 */
	sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval;
	sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo;

	/*
	 * The following count will be used to knock-off the station if it
	 * doesn't come back to receive the buffered data. The AP will wait
	 * for numTimSent number of beacons after sending TIM information for
	 * the station, before assuming that the station is no more associated
	 * and disassociates it
	 */

	/* timWaitCount used by PMM for monitoring the STA's in PS for LINK */
	sta_ds->timWaitCount =
		(uint8_t) GET_TIM_WAIT_COUNT(assoc_req->listenInterval);

	/* Init the Current successful MPDU's tranfered to this STA count = 0 */
	sta_ds->curTxMpduCnt = 0;

	if (IS_DOT11_MODE_HT(session->dot11mode) &&
	    assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
		sta_ds->htGreenfield = (uint8_t) assoc_req->HTCaps.greenField;
		sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity;
		sta_ds->htDsssCckRate40MHzSupport =
			(uint8_t) assoc_req->HTCaps.dsssCckMode40MHz;
		sta_ds->htLsigTXOPProtection =
			(uint8_t) assoc_req->HTCaps.lsigTXOPProtection;
		sta_ds->htMaxAmsduLength =
			(uint8_t) assoc_req->HTCaps.maximalAMSDUsize;
		sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor;
		sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave;

		/* assoc_req will be copied to session->parsedAssocReq later */
		ht_cap_ie = ((uint8_t *) &assoc_req->HTCaps) + 1;

		if (session->htConfig.ht_sgi20) {
			sta_ds->htShortGI20Mhz =
				(uint8_t)assoc_req->HTCaps.shortGI20MHz;
		} else {
			/* Unset htShortGI20Mhz in ht_caps*/
			*ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S);
			sta_ds->htShortGI20Mhz = 0;
		}

		if (session->htConfig.ht_sgi40) {
			sta_ds->htShortGI40Mhz =
				(uint8_t)assoc_req->HTCaps.shortGI40MHz;
		} else {
			/* Unset htShortGI40Mhz in ht_caps */
			*ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S);
			sta_ds->htShortGI40Mhz = 0;
		}

		sta_ds->htSupportedChannelWidthSet =
			(uint8_t) assoc_req->HTCaps.supportedChannelWidthSet;
		/*
		 * peer just follows AP; so when we are softAP/GO,
		 * we just store our session entry's secondary channel offset
		 * here in peer INFRA STA. However, if peer's 40MHz channel
		 * width support is disabled then secondary channel will be zero
		 */
		sta_ds->htSecondaryChannelOffset =
			(sta_ds->htSupportedChannelWidthSet) ?
				session->htSecondaryChannelOffset : 0;
		if (assoc_req->operMode.present) {
			enum phy_ch_width ch_width;

			ch_width = assoc_req->operMode.chanWidth;
			if (session->ch_width < ch_width)
				ch_width = session->ch_width;

			sta_ds->vhtSupportedChannelWidthSet =
				(uint8_t) ((ch_width == CH_WIDTH_80MHZ) ?
				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
			sta_ds->htSupportedChannelWidthSet =
				(uint8_t) (ch_width ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ);
		} else if ((vht_caps != NULL) && vht_caps->present) {
			/*
			 * Check if STA has enabled it's channel bonding mode.
			 * If channel bonding mode is enabled, we decide based
			 * on SAP's current configuration. else, we set it to
			 * VHT20.
			 */
			sta_ds->vhtSupportedChannelWidthSet =
				(uint8_t) ((sta_ds->htSupportedChannelWidthSet
					== eHT_CHANNEL_WIDTH_20MHZ) ?
					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
					session->ch_width - 1);
			sta_ds->htMaxRxAMpduFactor =
				vht_caps->maxAMPDULenExp;
		}
		/* Lesser among the AP and STA bandwidth of operation. */
		sta_ds->htSupportedChannelWidthSet =
			(sta_ds->htSupportedChannelWidthSet <
			session->htSupportedChannelWidthSet) ?
			sta_ds->htSupportedChannelWidthSet :
			session->htSupportedChannelWidthSet;

		if (!sta_ds->htSupportedChannelWidthSet)
			sta_ds->vhtSupportedChannelWidthSet =
					WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;

		sta_ds->baPolicyFlag = 0xFF;
		sta_ds->htLdpcCapable =
			(uint8_t) assoc_req->HTCaps.advCodingCap;
	}

	if ((vht_caps != NULL) && vht_caps->present &&
	    assoc_req->wmeInfoPresent) {
		sta_ds->vhtLdpcCapable =
			(uint8_t) vht_caps->ldpcCodingCap;
	}

	if (assoc_req->ExtCap.present)
		sta_ds->non_ecsa_capable =
		    !((struct s_ext_cap *)assoc_req->ExtCap.bytes)->
		    ext_chan_switch;
	else
		sta_ds->non_ecsa_capable = 1;

	if (!assoc_req->wmeInfoPresent) {
		sta_ds->mlmStaContext.htCapability = 0;
		sta_ds->mlmStaContext.vhtCapability = 0;
	}

	if (sta_ds->mlmStaContext.vhtCapability && vht_caps) {
		if (session->vht_config.su_beam_formee &&
				vht_caps->suBeamFormerCap)
			sta_ds->vhtBeamFormerCapable = 1;
		else
			sta_ds->vhtBeamFormerCapable = 0;
		if (session->vht_config.su_beam_former &&
				vht_caps->suBeamformeeCap)
			sta_ds->vht_su_bfee_capable = 1;
		else
			sta_ds->vht_su_bfee_capable = 0;

		pe_debug("peer_caps: suBformer: %d, suBformee: %d",
			 vht_caps->suBeamFormerCap,
			 vht_caps->suBeamformeeCap);
		pe_debug("self_cap: suBformer: %d, suBformee: %d",
			 session->vht_config.su_beam_former,
			 session->vht_config.su_beam_formee);
		pe_debug("connection's final cap: suBformer: %d, suBformee: %d",
			 sta_ds->vhtBeamFormerCapable,
			 sta_ds->vht_su_bfee_capable);
	}

	lim_intersect_sta_he_caps(assoc_req, session, sta_ds);

	if (lim_populate_matching_rate_set(mac_ctx, sta_ds,
			&(assoc_req->supportedRates),
			&(assoc_req->extendedRates),
			assoc_req->HTCaps.supportedMCSSet,
			session, vht_caps,
			&assoc_req->he_cap) != QDF_STATUS_SUCCESS) {
		/* Could not update hash table entry at DPH with rateset */
		pe_err("Couldn't update hash entry for aid: %d MacAddr: "
		       MAC_ADDRESS_STR,
		       peer_idx, MAC_ADDR_ARRAY(hdr->sa));

		/* Release AID */
		lim_release_peer_idx(mac_ctx, peer_idx, session);

		lim_reject_association(mac_ctx, hdr->sa,
			sub_type, true, auth_type, peer_idx, false,
			eSIR_MAC_UNSPEC_FAILURE_STATUS,
			session);
		pe_err("Delete dph hash entry");
		if (dph_delete_hash_entry(mac_ctx, hdr->sa, sta_ds->assocId,
			 &session->dph.dphHashTable) != QDF_STATUS_SUCCESS)
			pe_err("error deleting hash entry");
		return false;
	}
	if (assoc_req->operMode.present) {
		sta_ds->vhtSupportedRxNss = assoc_req->operMode.rxNSS + 1;
	} else {
		sta_ds->vhtSupportedRxNss =
			((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
				== MCSMAPMASK2x2) ? 1 : 2;
	}

	/* Add STA context at MAC HW (BMU, RHP & TFP) */
	sta_ds->qosMode = false;
	sta_ds->lleEnabled = false;
	if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET)) {
		sta_ds->lleEnabled = true;
		sta_ds->qosMode = true;
	}

	sta_ds->wmeEnabled = false;
	sta_ds->wsmEnabled = false;
	limGetWmeMode(session, &wme_mode);
	if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent
	    && (wme_mode == eHAL_SET)) {
		sta_ds->wmeEnabled = true;
		sta_ds->qosMode = true;
		limGetWsmMode(session, &wsm_mode);
		/*
		 * WMM_APSD - WMM_SA related processing should be separate;
		 * WMM_SA and WMM_APSD can coexist
		 */
		if (assoc_req->WMMInfoStation.present) {
			/* check whether AP supports or not */
			if (LIM_IS_AP_ROLE(session) &&
				(session->apUapsdEnable == 0) &&
				(assoc_req->WMMInfoStation.acbe_uapsd ||
					assoc_req->WMMInfoStation.acbk_uapsd ||
					assoc_req->WMMInfoStation.acvo_uapsd ||
					assoc_req->WMMInfoStation.acvi_uapsd)) {
				/*
				 * Rcvd Re/Assoc Req from STA when UPASD is
				 * not supported.
				 */
				pe_err("UAPSD not supported, reply accordingly");
				/* update UAPSD and send it to LIM to add STA */
				sta_ds->qos.capability.qosInfo.acbe_uapsd = 0;
				sta_ds->qos.capability.qosInfo.acbk_uapsd = 0;
				sta_ds->qos.capability.qosInfo.acvo_uapsd = 0;
				sta_ds->qos.capability.qosInfo.acvi_uapsd = 0;
				sta_ds->qos.capability.qosInfo.maxSpLen = 0;
			} else {
				/* update UAPSD and send it to LIM to add STA */
				sta_ds->qos.capability.qosInfo.acbe_uapsd =
					assoc_req->WMMInfoStation.acbe_uapsd;
				sta_ds->qos.capability.qosInfo.acbk_uapsd =
					assoc_req->WMMInfoStation.acbk_uapsd;
				sta_ds->qos.capability.qosInfo.acvo_uapsd =
					assoc_req->WMMInfoStation.acvo_uapsd;
				sta_ds->qos.capability.qosInfo.acvi_uapsd =
					assoc_req->WMMInfoStation.acvi_uapsd;
				sta_ds->qos.capability.qosInfo.maxSpLen =
					assoc_req->WMMInfoStation.max_sp_length;
			}
		}
		if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET))
			sta_ds->wsmEnabled = true;
	}
	/* Re/Assoc Response frame to requesting STA */
	sta_ds->mlmStaContext.subType = sub_type;

#ifdef WLAN_FEATURE_11W
	sta_ds->rmfEnabled = (pmf_connection) ? 1 : 0;
	sta_ds->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
	timer_id.fields.sessionId = session->peSessionId;
	timer_id.fields.peerIdx = peer_idx;
	retry_interval = mac_ctx->mlme_cfg->gen.pmf_sa_query_retry_interval;
	if (cfg_min(CFG_PMF_SA_QUERY_RETRY_INTERVAL) > retry_interval) {
		retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL);
	}
	if (sta_ds->rmfEnabled &&
		tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,
			"PMF SA Query timer", lim_pmf_sa_query_timer_handler,
			timer_id.value,
			SYS_MS_TO_TICKS((retry_interval * 1024) / 1000),
			0, TX_NO_ACTIVATE) != TX_SUCCESS) {
		pe_err("could not create PMF SA Query timer");
		lim_reject_association(mac_ctx, hdr->sa, sub_type,
			true, auth_type, peer_idx, false,
			eSIR_MAC_UNSPEC_FAILURE_STATUS,
			session);
		return false;
	}
	if (sta_ds->rmfEnabled)
	    pe_debug("Created pmf timer sta-idx:%d assoc-id:%d",
		     sta_ds->staIndex, sta_ds->assocId);
#endif

	if (assoc_req->ExtCap.present) {
		lim_set_stads_rtt_cap(sta_ds,
			(struct s_ext_cap *) assoc_req->ExtCap.bytes, mac_ctx);
	} else {
		sta_ds->timingMeasCap = 0;
		pe_debug("ExtCap not present");
	}
	return true;
}

/**
 * lim_update_sta_ctx() - add/del sta depending on connection state machine
 * @mac_ctx: pointer to Global MAC structure
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sub_type: Assoc(=0) or Reassoc(=1) Requestframe
 * @sta_ds: station dph entry
 * @update_ctx: indicates if STA context already exist
 *
 * Checks for SSID match
 *
 * Return: true of no error, false otherwise
 */
static bool lim_update_sta_ctx(struct mac_context *mac_ctx, struct pe_session *session,
			       tpSirAssocReq assoc_req, uint8_t sub_type,
			       tpDphHashNode sta_ds, uint8_t update_ctx)
{
	tLimMlmStates mlm_prev_state;
	/*
	 * BTAMP: If STA context already exist (ie. update_ctx = 1) for this STA
	 * then we should delete the old one, and add the new STA. This is taken
	 * care of in the lim_del_sta() routine.
	 *
	 * Prior to BTAMP, we were setting this flag so that when PE receives
	 * SME_ASSOC_CNF, and if this flag is set, then PE shall delete the old
	 * station and then add. But now in BTAMP, we're directly adding station
	 * before waiting for SME_ASSOC_CNF, so we can do this now.
	 */
	if (!(update_ctx)) {
		sta_ds->mlmStaContext.updateContext = 0;

		/*
		 * BTAMP: Add STA context at HW - issue WMA_ADD_STA_REQ to HAL
		 */
		if (lim_add_sta(mac_ctx, sta_ds, false, session) !=
		    QDF_STATUS_SUCCESS) {
			pe_err("could not Add STA with assocId: %d",
				sta_ds->assocId);
			lim_reject_association(mac_ctx, sta_ds->staAddr,
				sta_ds->mlmStaContext.subType, true,
				sta_ds->mlmStaContext.authType,
				sta_ds->assocId, true,
				eSIR_MAC_UNSPEC_FAILURE_STATUS,
				session);

			if (session->parsedAssocReq)
				assoc_req =
				    session->parsedAssocReq[sta_ds->assocId];
			return false;
		}
	} else {
		sta_ds->mlmStaContext.updateContext = 1;
		mlm_prev_state = sta_ds->mlmStaContext.mlmState;

		/*
		 * As per the HAL/FW needs the reassoc req need not be calling
		 * lim_del_sta
		 */
		if (sub_type != LIM_REASSOC) {
			/*
			 * we need to set the mlmState here in order
			 * differentiate in lim_del_sta.
			 */
			sta_ds->mlmStaContext.mlmState =
				eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
			if (lim_del_sta(mac_ctx, sta_ds, true, session)
					!= QDF_STATUS_SUCCESS) {
				pe_err("Couldn't DEL STA, assocId: %d staId: %d",
					sta_ds->assocId, sta_ds->staIndex);
				lim_reject_association(mac_ctx, sta_ds->staAddr,
					sta_ds->mlmStaContext.subType, true,
					sta_ds->mlmStaContext.authType,
					sta_ds->assocId, true,
					eSIR_MAC_UNSPEC_FAILURE_STATUS,
					session);

				/* Restoring the state back. */
				sta_ds->mlmStaContext.mlmState = mlm_prev_state;
				if (session->parsedAssocReq)
					assoc_req = session->parsedAssocReq[
						sta_ds->assocId];
				return false;
			}
		} else {
			/*
			 * mlmState is changed in lim_add_sta context use the
			 * same AID, already allocated
			 */
			if (lim_add_sta(mac_ctx, sta_ds, false, session)
				!= QDF_STATUS_SUCCESS) {
				pe_err("UPASD not supported, REASSOC Failed");
				lim_reject_association(mac_ctx, sta_ds->staAddr,
					sta_ds->mlmStaContext.subType, true,
					sta_ds->mlmStaContext.authType,
					sta_ds->assocId, true,
					eSIR_MAC_WME_REFUSED_STATUS,
					session);

				/* Restoring the state back. */
				sta_ds->mlmStaContext.mlmState = mlm_prev_state;
				if (session->parsedAssocReq)
					assoc_req = session->parsedAssocReq[
							sta_ds->assocId];
				return false;
			}
		}
	}
	return true;
}

/**
 * lim_process_assoc_cleanup() - frees up resources used in function
 * lim_process_assoc_req_frame()
 * @mac_ctx: pointer to Global MAC structure
 * @session: pointer to pe session entry
 * @assoc_req: pointer to ASSOC/REASSOC Request frame
 * @sta_ds: station dph entry
 * @tmp_assoc_req: pointer to tmp ASSOC/REASSOC Request frame
 * @assoc_req_copied: boolean to indicate if assoc req was copied to tmp above
 *
 * Frees up resources used in function lim_process_assoc_req_frame
 *
 * Return: void
 */
static void lim_process_assoc_cleanup(struct mac_context *mac_ctx,
				      struct pe_session *session,
				      tpSirAssocReq assoc_req,
				      tpDphHashNode sta_ds,
				      bool *assoc_req_copied)
{
	tpSirAssocReq tmp_assoc_req;

	if (assoc_req != NULL) {
		if (assoc_req->assocReqFrame) {
			qdf_mem_free(assoc_req->assocReqFrame);
			assoc_req->assocReqFrame = NULL;
			assoc_req->assocReqFrameLength = 0;
		}

		qdf_mem_free(assoc_req);
		/* to avoid double free */
		if (*assoc_req_copied && session->parsedAssocReq)
			session->parsedAssocReq[sta_ds->assocId] = NULL;
	}

	/* If it is not duplicate Assoc request then only make to Null */
	if ((sta_ds != NULL) &&
	    (sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
		if (session->parsedAssocReq != NULL) {
			tmp_assoc_req =
				session->parsedAssocReq[sta_ds->assocId];
			if (tmp_assoc_req != NULL) {
				if (tmp_assoc_req->assocReqFrame) {
					qdf_mem_free(
						tmp_assoc_req->assocReqFrame);
					tmp_assoc_req->assocReqFrame = NULL;
					tmp_assoc_req->assocReqFrameLength = 0;
				}
				qdf_mem_free(tmp_assoc_req);
				session->parsedAssocReq[sta_ds->assocId] = NULL;
			}
		}
	}
}

/**
 * lim_process_assoc_req_frame() - Process RE/ASSOC Request frame.
 * @mac_ctx: Pointer to Global MAC structure
 * @rx_pkt_info: A pointer to Buffer descriptor + associated PDUs
 * @sub_type: Indicates whether it is Association Request(=0) or Reassociation
 *            Request(=1) frame
 * @session: pe session entry
 *
 * This function is called to process RE/ASSOC Request frame.
 *
 * @Return: void
 */
void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
				 uint8_t sub_type, struct pe_session *session)
{
	bool pmf_connection = false, assoc_req_copied = false;
	uint8_t update_ctx, *frm_body;
	uint16_t peer_idx, assoc_id = 0;
	uint32_t frame_len;
	uint32_t phy_mode;
	tHalBitVal qos_mode;
	tpSirMacMgmtHdr hdr;
	struct tLimPreAuthNode *sta_pre_auth_ctx;
	tAniAuthType auth_type;
	tSirMacCapabilityInfo local_cap;
	tpDphHashNode sta_ds = NULL;
	tpSirAssocReq assoc_req;
	bool dup_entry = false;

	lim_get_phy_mode(mac_ctx, &phy_mode, session);

	limGetQosMode(session, &qos_mode);

	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	pe_debug("Rcvd: %s Req Frame sessionid: %d systemrole: %d MlmState: %d from: "
		   MAC_ADDRESS_STR,
		(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
		session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
		session->limMlmState, MAC_ADDR_ARRAY(hdr->sa));

	if (LIM_IS_STA_ROLE(session)) {
		pe_err("Rcvd unexpected ASSOC REQ, sessionid: %d sys sub_type: %d for role: %d from: "
			   MAC_ADDRESS_STR,
			session->peSessionId, sub_type,
			GET_LIM_SYSTEM_ROLE(session),
			MAC_ADDR_ARRAY(hdr->sa));
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
				   WMA_GET_RX_MPDU_DATA(rx_pkt_info),
				   frame_len);
		return;
	}
	if (session->limMlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) {
		pe_err("drop ASSOC REQ on sessionid: %d "
			"role: %d from: "MAC_ADDRESS_STR" in limMlmState: %d",
			session->peSessionId,
			GET_LIM_SYSTEM_ROLE(session),
			MAC_ADDR_ARRAY(hdr->sa),
			eLIM_MLM_WT_DEL_BSS_RSP_STATE);
		return;
	}

	/*
	 * If a STA is already present in DPH and it is initiating a Assoc
	 * re-transmit, do not process it. This can happen when first Assoc Req
	 * frame is received but ACK lost at STA side. The ACK for this dropped
	 * Assoc Req frame should be sent by HW. Host simply does not process it
	 * once the entry for the STA is already present in DPH.
	 */
	sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &assoc_id,
				&session->dph.dphHashTable);
	if (NULL != sta_ds) {
		if (hdr->fc.retry > 0) {
			pe_err("STA is initiating Assoc Req after ACK lost. Do not process sessionid: %d sys sub_type=%d for role=%d from: "
				MAC_ADDRESS_STR, session->peSessionId,
			sub_type, GET_LIM_SYSTEM_ROLE(session),
			MAC_ADDR_ARRAY(hdr->sa));
			return;
		} else if (!sta_ds->rmfEnabled && (sub_type == LIM_REASSOC)) {
			/*
			 * SAP should send reassoc response with reject code
			 * to avoid IOT issues. as per the specification SAP
			 * should do 4-way handshake after reassoc response and
			 * some STA doesn't like 4way handshake after reassoc
			 * where some STA does expect 4-way handshake.
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
					eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
					sta_ds->assocId, sta_ds->staAddr,
					sub_type, sta_ds, session);
			pe_err("Rejecting reassoc req from STA");
			return;
		} else if (!sta_ds->rmfEnabled) {
			/*
			 * Do this only for non PMF case.
			 * STA might have missed the assoc response, so it is
			 * sending assoc request frame again.
			 */
			lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS,
					sta_ds->assocId, sta_ds->staAddr,
					sub_type,
					sta_ds, session);
			pe_err("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type: %d for role: %d from: "
					MAC_ADDRESS_STR,
				session->peSessionId, sub_type,
				session->limSystemRole,
				MAC_ADDR_ARRAY(hdr->sa));
			return;
		}
	}

	dup_entry = lim_check_sta_in_pe_entries(mac_ctx, hdr,
						session->peSessionId);

	/* Get pointer to Re/Association Request frame body */
	frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);

	if (lim_is_group_addr(hdr->sa)) {
		/*
		 * Rcvd Re/Assoc Req frame from BC/MC address Log error and
		 * ignore it
		 */
		pe_err("Rcvd: %s Req, sessionid: %d from a BC/MC address"
				MAC_ADDRESS_STR,
			(LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
			session->peSessionId, MAC_ADDR_ARRAY(hdr->sa));
		return;
	}

	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
				(uint8_t *) frm_body, frame_len);

	if (false == lim_chk_sa_da(mac_ctx, hdr, session, sub_type))
		return;

	if (false == lim_chk_tkip(mac_ctx, hdr, session, sub_type))
		return;

	/* check for the presence of vendor IE */
	if ((session->access_policy_vendor_ie) &&
		(session->access_policy ==
		LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) {
		if (frame_len <= LIM_ASSOC_REQ_IE_OFFSET) {
			pe_debug("Received action frame of invalid len %d",
				 frame_len);
			return;
		}
		if (!wlan_get_vendor_ie_ptr_from_oui(
				&session->access_policy_vendor_ie[2],
				3, frm_body + LIM_ASSOC_REQ_IE_OFFSET,
				 frame_len - LIM_ASSOC_REQ_IE_OFFSET)) {
			pe_err("Vendor ie not present and access policy is %x, Rejected association",
				session->access_policy);
			lim_send_assoc_rsp_mgmt_frame(mac_ctx,
				eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa,
				sub_type, 0, session);
			return;
		}
	}
	/* Allocate memory for the Assoc Request frame */
	assoc_req = qdf_mem_malloc(sizeof(*assoc_req));
	if (!assoc_req)
		return;

	/* Parse Assoc Request frame */
	if (false == lim_chk_assoc_req_parse_error(mac_ctx, hdr, session,
				assoc_req, sub_type, frm_body, frame_len))
		goto error;

	assoc_req->assocReqFrame = qdf_mem_malloc(frame_len);
	if (!assoc_req->assocReqFrame)
		goto error;

	qdf_mem_copy((uint8_t *) assoc_req->assocReqFrame,
		(uint8_t *) frm_body, frame_len);
	assoc_req->assocReqFrameLength = frame_len;

	if (false == lim_chk_capab(mac_ctx, hdr, session, assoc_req,
				sub_type, &local_cap))
		goto error;

	update_ctx = false;

	if (false == lim_chk_ssid(mac_ctx, hdr, session, assoc_req, sub_type))
		goto error;

	if (false == lim_chk_rates(mac_ctx, hdr, session, assoc_req, sub_type))
		goto error;

	if (false == lim_chk_11g_only(mac_ctx, hdr, session, assoc_req,
				sub_type))
		goto error;

	if (false == lim_chk_11n_only(mac_ctx, hdr, session, assoc_req,
				sub_type))
		goto error;

	if (false == lim_chk_11ac_only(mac_ctx, hdr, session, assoc_req,
				sub_type))
		goto error;

	if (false == lim_chk_11ax_only(mac_ctx, hdr, session, assoc_req,
				       sub_type))
		goto error;

	if (false == lim_check_11ax_basic_mcs(mac_ctx, hdr, session, assoc_req,
					      sub_type))
		goto error;

	/* Spectrum Management (11h) specific checks */
	lim_process_for_spectrum_mgmt(mac_ctx, hdr, session,
				assoc_req, sub_type, local_cap);

	if (false == lim_chk_mcs(mac_ctx, hdr, session, assoc_req, sub_type))
		goto error;

	if (false == lim_chk_is_11b_sta_supported(mac_ctx, hdr, session,
				assoc_req, sub_type, phy_mode))
		goto error;

	/*
	 * Check for 802.11n HT caps compatibility; are HT Capabilities
	 * turned on in lim?
	 */
	lim_print_ht_cap(mac_ctx, session, assoc_req);

	if (false == lim_chk_n_process_wpa_rsn_ie(mac_ctx, hdr, session,
				assoc_req, sub_type, &pmf_connection))
		goto error;

	/* Extract 'associated' context for STA, if any. */
	sta_ds = dph_lookup_hash_entry(mac_ctx, hdr->sa, &peer_idx,
				&session->dph.dphHashTable);

	/* Extract pre-auth context for the STA, if any. */
	sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx, hdr->sa);

	if (sta_ds == NULL) {
		if (false == lim_process_assoc_req_no_sta_ctx(mac_ctx, hdr,
				session, assoc_req, sub_type, sta_pre_auth_ctx,
				sta_ds, &auth_type))
			goto error;
	} else {
		if (false == lim_process_assoc_req_sta_ctx(mac_ctx, hdr,
				session, assoc_req, sub_type, sta_pre_auth_ctx,
				sta_ds, peer_idx, &auth_type, &update_ctx))
			goto error;
		goto sendIndToSme;
	}

	/* check if sta is allowed per QoS AC rules */
	if (false == lim_chk_wmm(mac_ctx, hdr, session,
				assoc_req, sub_type, qos_mode))
		goto error;

	/* STA is Associated ! */
	pe_debug("Received: %s Req  successful from " MAC_ADDRESS_STR,
		 (LIM_ASSOC == sub_type) ? "Assoc" : "ReAssoc",
		 MAC_ADDR_ARRAY(hdr->sa));

	/*
	 * AID for this association will be same as the peer Index used in DPH
	 * table. Assign unused/least recently used peer Index from perStaDs.
	 * NOTE: lim_assign_peer_idx() assigns AID values ranging between
	 * 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
	 */

	peer_idx = lim_assign_peer_idx(mac_ctx, session);

	if (!peer_idx) {
		/* Could not assign AID. Reject association */
		pe_err("PeerIdx not avaialble. Reject associaton");
		lim_reject_association(mac_ctx, hdr->sa, sub_type,
				true, auth_type, peer_idx, false,
				eSIR_MAC_UNSPEC_FAILURE_STATUS,
				session);
		goto error;
	}

	/* Add an entry to hash table maintained by DPH module */

	sta_ds = dph_add_hash_entry(mac_ctx, hdr->sa, peer_idx,
				&session->dph.dphHashTable);

	if (sta_ds == NULL) {
		/* Could not add hash table entry at DPH */
		pe_err("couldn't add hash entry at DPH for aid: %d MacAddr:"
			   MAC_ADDRESS_STR, peer_idx, MAC_ADDR_ARRAY(hdr->sa));

		/* Release AID */
		lim_release_peer_idx(mac_ctx, peer_idx, session);

		lim_reject_association(mac_ctx, hdr->sa, sub_type,
			true, auth_type, peer_idx, false,
			eSIR_MAC_UNSPEC_FAILURE_STATUS,
			session);
		goto error;
	}

sendIndToSme:
	if (false == lim_update_sta_ds(mac_ctx, hdr, session, assoc_req,
				sub_type, sta_ds, auth_type,
				&assoc_req_copied, peer_idx, qos_mode,
				pmf_connection))
		goto error;


	/* BTAMP: Storing the parsed assoc request in the session array */
	if (session->parsedAssocReq)
		session->parsedAssocReq[sta_ds->assocId] = assoc_req;
	assoc_req_copied = true;

	/* If it is duplicate entry wait till the peer is deleted */
	if (dup_entry != true) {
		if (false == lim_update_sta_ctx(mac_ctx, session, assoc_req,
					sub_type, sta_ds, update_ctx))
		goto error;
	}

	/* AddSta is success here */
	if (LIM_IS_AP_ROLE(session) && IS_DOT11_MODE_HT(session->dot11mode) &&
		assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) {
		/*
		 * Update in the HAL Sta Table for the Update of the Protection
		 * Mode
		 */
		lim_post_sm_state_update(mac_ctx, sta_ds->staIndex,
					 sta_ds->htMIMOPSState, sta_ds->staAddr,
					 session->smeSessionId);
	}

	return;

error:
	lim_process_assoc_cleanup(mac_ctx, session, assoc_req, sta_ds,
				  &assoc_req_copied);
	return;
}

#ifdef FEATURE_WLAN_WAPI
/**
 * lim_fill_assoc_ind_wapi_info()- Updates WAPI data in assoc indication
 * @mac_ctx: Global Mac context
 * @assoc_req: pointer to association request
 * @assoc_ind: Pointer to association indication
 * @wpsie: WPS IE
 *
 * This function updates WAPI meta data in association indication message
 * sent to SME.
 *
 * Return: None
 */
static void lim_fill_assoc_ind_wapi_info(struct mac_context *mac_ctx,
	tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
	const uint8_t *wpsie)
{
	if (assoc_req->wapiPresent && (NULL == wpsie)) {
		pe_debug("Received WAPI IE length in Assoc Req is %d",
			assoc_req->wapi.length);
		assoc_ind->wapiIE.wapiIEdata[0] = SIR_MAC_WAPI_EID;
		assoc_ind->wapiIE.wapiIEdata[1] = assoc_req->wapi.length;
		qdf_mem_copy(&assoc_ind->wapiIE.wapiIEdata[2],
			assoc_req->wapi.info, assoc_req->wapi.length);
		assoc_ind->wapiIE.length =
			2 + assoc_req->wapi.length;
	}
	return;
}
#endif

/**
 * lim_fill_assoc_ind_vht_info() - Updates VHT information in assoc indication
 * @mac_ctx: Global Mac context
 * @assoc_req: pointer to association request
 * @session_entry: PE session entry
 * @assoc_ind: Pointer to association indication
 *
 * This function updates VHT information in association indication message
 * sent to SME.
 *
 * Return: None
 */
static void lim_fill_assoc_ind_vht_info(struct mac_context *mac_ctx,
					struct pe_session *session_entry,
					tpSirAssocReq assoc_req,
					tpLimMlmAssocInd assoc_ind,
					tpDphHashNode sta_ds)
{
	uint8_t chan;
	uint8_t i;
	bool nw_type_11b = true;

	if (session_entry->limRFBand == BAND_2G) {
		if (session_entry->vhtCapability && assoc_req->VHTCaps.present)
			assoc_ind->chan_info.info = MODE_11AC_VHT20_2G;
		else if (session_entry->htCapability
			    && assoc_req->HTCaps.present)
			assoc_ind->chan_info.info = MODE_11NG_HT20;
		else {
			for (i = 0; i < SIR_NUM_11A_RATES; i++) {
				if (sirIsArate(sta_ds->
					       supportedRates.llaRates[i]
					       & 0x7F)) {
					assoc_ind->chan_info.info = MODE_11G;
					nw_type_11b = false;
					break;
				}
			}
			if (nw_type_11b)
				assoc_ind->chan_info.info = MODE_11B;
		}
		return;
	}

	if (session_entry->vhtCapability && assoc_req->VHTCaps.present) {
		if ((session_entry->ch_width > CH_WIDTH_40MHZ)
		    && assoc_req->HTCaps.supportedChannelWidthSet) {
			chan = session_entry->ch_center_freq_seg0;
			assoc_ind->chan_info.band_center_freq1 =
				cds_chan_to_freq(chan);
			assoc_ind->chan_info.info = MODE_11AC_VHT80;
			return;
		}

		if ((session_entry->ch_width == CH_WIDTH_40MHZ)
			&& assoc_req->HTCaps.supportedChannelWidthSet) {
			assoc_ind->chan_info.info = MODE_11AC_VHT40;
			if (session_entry->htSecondaryChannelOffset ==
			    PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
				assoc_ind->chan_info.band_center_freq1 += 10;
			else
				assoc_ind->chan_info.band_center_freq1 -= 10;
			return;
		}

		assoc_ind->chan_info.info = MODE_11AC_VHT20;
		return;
	}

	if (session_entry->htCapability && assoc_req->HTCaps.present) {
		if ((session_entry->ch_width == CH_WIDTH_40MHZ)
		    && assoc_req->HTCaps.supportedChannelWidthSet) {
			assoc_ind->chan_info.info = MODE_11NA_HT40;
			if (session_entry->htSecondaryChannelOffset ==
			    PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
				assoc_ind->chan_info.band_center_freq1 += 10;
			else
				assoc_ind->chan_info.band_center_freq1 -= 10;
			return;
		}

		assoc_ind->chan_info.info = MODE_11NA_HT20;
		return;
	}

	assoc_ind->chan_info.info = MODE_11A;
	return;
}

static uint8_t lim_get_max_rate_idx(tSirMacRateSet *rateset)
{
	uint8_t maxidx;
	int i;

	maxidx = rateset->rate[0] & 0x7f;
	for (i = 1; i < rateset->numRates; i++) {
		if ((rateset->rate[i] & 0x7f) > maxidx)
			maxidx = rateset->rate[i] & 0x7f;
	}

	return maxidx;
}

static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
		tpDphHashNode stads,
		tpLimMlmAssocInd assocind)
{
	if (stads->mlmStaContext.vhtCapability) {
		/* ampdu */
		assocind->ampdu = true;

		/* sgi */
		if (assocreq->VHTCaps.shortGI80MHz ||
		    assocreq->VHTCaps.shortGI160and80plus80MHz)
			assocind->sgi_enable = true;

		/* stbc */
		assocind->tx_stbc = assocreq->VHTCaps.txSTBC;
		assocind->rx_stbc = assocreq->VHTCaps.rxSTBC;

		/* ch width */
		assocind->ch_width = stads->vhtSupportedChannelWidthSet ?
			eHT_CHANNEL_WIDTH_80MHZ :
			stads->htSupportedChannelWidthSet ?
			eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;

		/* mode */
		assocind->mode = SIR_SME_PHY_MODE_VHT;
		assocind->rx_mcs_map = assocreq->VHTCaps.rxMCSMap & 0xff;
		assocind->tx_mcs_map = assocreq->VHTCaps.txMCSMap & 0xff;
	}
}

/**
 * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
 * @mac_ctx: Global Mac context
 * @sta_ds: Station DPH hash entry
 * @session_entry: PE session entry
 *
 * This function sends either LIM_MLM_ASSOC_IND
 * or LIM_MLM_REASSOC_IND to SME.
 *
 * Return: None
 */
void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx,
	tpDphHashNode sta_ds, struct pe_session *session_entry)
{
	tpLimMlmAssocInd assoc_ind = NULL;
	tpSirAssocReq assoc_req;
	uint16_t temp, rsn_len;
	uint32_t phy_mode;
	uint8_t sub_type;
	const uint8_t *wpsie = NULL;
	uint8_t maxidx, i;
	bool wme_enable;

	if (!session_entry->parsedAssocReq) {
		pe_err(" Parsed Assoc req is NULL");
		return;
	}

	/* Get a copy of the already parsed Assoc Request */
	assoc_req =
		(tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId];

	if (!assoc_req) {
		pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId);
		return;
	}

	/* Get the phy_mode */
	lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);

	/* Determine if its Assoc or ReAssoc Request */
	if (assoc_req->reassocRequest == 1)
		sub_type = LIM_REASSOC;
	else
		sub_type = LIM_ASSOC;

	pe_debug("Sessionid: %d ssid: %s sub_type: %d Associd: %d staAddr: "
		 MAC_ADDRESS_STR, session_entry->peSessionId,
		assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
		MAC_ADDR_ARRAY(sta_ds->staAddr));

	if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
		temp = sizeof(tLimMlmAssocInd);

		assoc_ind = qdf_mem_malloc(temp);
		if (!assoc_ind) {
			lim_release_peer_idx(mac_ctx, sta_ds->assocId,
				session_entry);
			return;
		}
		qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
			(uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
		assoc_ind->aid = sta_ds->assocId;
		qdf_mem_copy((uint8_t *) &assoc_ind->ssId,
			(uint8_t *) &(assoc_req->ssId),
			assoc_req->ssId.length + 1);
		assoc_ind->sessionId = session_entry->peSessionId;
		assoc_ind->authType = sta_ds->mlmStaContext.authType;
		assoc_ind->capabilityInfo = assoc_req->capabilityInfo;

		/* Fill in RSN IE information */
		assoc_ind->rsnIE.length = 0;
		/* if WPS IE is present, ignore RSN IE */
		if (assoc_req->addIEPresent && assoc_req->addIE.length) {
			wpsie = limGetWscIEPtr(mac_ctx,
				assoc_req->addIE.addIEdata,
				assoc_req->addIE.length);
		}
		if (assoc_req->rsnPresent && (NULL == wpsie)) {
			pe_debug("Assoc Req RSN IE len: %d",
				assoc_req->rsn.length);
			assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
			assoc_ind->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
			assoc_ind->rsnIE.rsnIEdata[1] =
				assoc_req->rsn.length;
			qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
				assoc_req->rsn.info,
				assoc_req->rsn.length);
		}
		/* Fill in 802.11h related info */
		if (assoc_req->powerCapabilityPresent
			&& assoc_req->supportedChannelsPresent) {
			assoc_ind->spectrumMgtIndicator = true;
			assoc_ind->powerCap.minTxPower =
				assoc_req->powerCapability.minTxPower;
			assoc_ind->powerCap.maxTxPower =
				assoc_req->powerCapability.maxTxPower;
			lim_convert_supported_channels(mac_ctx, assoc_ind,
				 assoc_req);
		} else {
			assoc_ind->spectrumMgtIndicator = false;
		}

		/* This check is to avoid extra Sec IEs present incase of WPS */
		if (assoc_req->wpaPresent && (NULL == wpsie)) {
			rsn_len = assoc_ind->rsnIE.length;
			if ((rsn_len + assoc_req->wpa.length)
				>= SIR_MAC_MAX_IE_LENGTH) {
				pe_err("rsnIEdata index out of bounds: %d",
					rsn_len);
				qdf_mem_free(assoc_ind);
				return;
			}
			assoc_ind->rsnIE.rsnIEdata[rsn_len] =
				SIR_MAC_WPA_EID;
			assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
				= assoc_req->wpa.length;
			qdf_mem_copy(
				&assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
				assoc_req->wpa.info, assoc_req->wpa.length);
			assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
		}
#ifdef FEATURE_WLAN_WAPI
		lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
			wpsie);
#endif

		assoc_ind->addIE.length = 0;
		if (assoc_req->addIEPresent) {
			qdf_mem_copy(&assoc_ind->addIE.addIEdata,
				assoc_req->addIE.addIEdata,
				assoc_req->addIE.length);
			assoc_ind->addIE.length = assoc_req->addIE.length;
		}
		/*
		 * Add HT Capabilities into addIE for OBSS
		 * processing in hostapd
		 */
		if (assoc_req->HTCaps.present) {
			qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps,
				     sizeof(tDot11fIEHTCaps));

			rsn_len = assoc_ind->addIE.length;
			if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
				+ 2 < SIR_MAC_MAX_IE_LENGTH) {
				assoc_ind->addIE.addIEdata[rsn_len] =
					SIR_MAC_HT_CAPABILITIES_EID;
				assoc_ind->addIE.addIEdata[rsn_len + 1] =
					DOT11F_IE_HTCAPS_MIN_LEN;
				qdf_mem_copy(
					&assoc_ind->addIE.addIEdata[rsn_len+2],
					((uint8_t *)&assoc_req->HTCaps) + 1,
					DOT11F_IE_HTCAPS_MIN_LEN);
				assoc_ind->addIE.length +=
					2 + DOT11F_IE_HTCAPS_MIN_LEN;
			} else {
				pe_err("Fail:HT capabilities IE to addIE");
			}
		}

		if (assoc_req->wmeInfoPresent) {
			/* Set whether AP is enabled with WMM or not */
			wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled;
			assoc_ind->WmmStaInfoPresent = wme_enable;
			/*
			 * Note: we are not rejecting association here
			 * because IOT will fail
			 */
		}
		/* Required for indicating the frames to upper layer */
		assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
		assoc_ind->assocReqPtr = assoc_req->assocReqFrame;

		assoc_ind->beaconPtr = session_entry->beacon;
		assoc_ind->beaconLength = session_entry->bcnLen;

		assoc_ind->chan_info.chan_id =
			session_entry->currentOperChannel;
		assoc_ind->chan_info.mhz =
			cds_chan_to_freq(session_entry->currentOperChannel);
		assoc_ind->chan_info.band_center_freq1 =
			cds_chan_to_freq(session_entry->currentOperChannel);
		assoc_ind->chan_info.band_center_freq2 = 0;
		assoc_ind->chan_info.reg_info_1 =
			(session_entry->maxTxPower << 16);
		assoc_ind->chan_info.reg_info_2 =
			(session_entry->maxTxPower << 8);
		assoc_ind->chan_info.nss = sta_ds->nss;
		assoc_ind->chan_info.rate_flags =
			lim_get_max_rate_flags(mac_ctx, sta_ds);
		assoc_ind->ampdu = false;
		assoc_ind->sgi_enable = false;
		assoc_ind->tx_stbc = false;
		assoc_ind->rx_stbc = false;
		assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
		assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
		assoc_ind->max_supp_idx = 0xff;
		assoc_ind->max_ext_idx = 0xff;
		assoc_ind->max_mcs_idx = 0xff;
		assoc_ind->rx_mcs_map = 0xff;
		assoc_ind->tx_mcs_map = 0xff;

		if (assoc_req->supportedRates.numRates)
			assoc_ind->max_supp_idx =
				lim_get_max_rate_idx(
					&assoc_req->supportedRates);
		if (assoc_req->extendedRates.numRates)
			assoc_ind->max_ext_idx =
				lim_get_max_rate_idx(
					&assoc_req->extendedRates);

		if (sta_ds->mlmStaContext.htCapability) {
			/* ampdu */
			assoc_ind->ampdu = true;

			/* sgi */
			if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
				assoc_ind->sgi_enable = true;

			/* stbc */
			assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
			assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;

			/* ch width */
			assoc_ind->ch_width =
				sta_ds->htSupportedChannelWidthSet ?
				eHT_CHANNEL_WIDTH_40MHZ :
				eHT_CHANNEL_WIDTH_20MHZ;

			/* mode */
			assoc_ind->mode = SIR_SME_PHY_MODE_HT;
			maxidx = 0;
			for (i = 0; i < 8; i++) {
				if (assoc_req->HTCaps.supportedMCSSet[0] &
					(1 << i))
					maxidx = i;
			}
			assoc_ind->max_mcs_idx = maxidx;
		}
		fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
		if (assoc_req->ExtCap.present)
			assoc_ind->ecsa_capable =
			((struct s_ext_cap *)assoc_req->ExtCap.bytes)->
			ext_chan_switch;

		/* updates VHT information in assoc indication */
		 qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps,
			      sizeof(tDot11fIEVHTCaps));
		lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
					    assoc_ind, sta_ds);
		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
			 (uint32_t *) assoc_ind);
		qdf_mem_free(assoc_ind);
	}
	return;
}
