/*
 * Copyright (c) 2011-2015 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.
 */

/**
 * \file lim_send_management_frames.c
 *
 * \brief Code for preparing and sending 802.11 Management frames
 *
 *
 */

#include "sir_api.h"
#include "ani_global.h"
#include "sir_mac_prot_def.h"
#include "cfg_api.h"
#include "utils_api.h"
#include "lim_types.h"
#include "lim_utils.h"
#include "lim_security_utils.h"
#include "lim_prop_exts_utils.h"
#include "dot11f.h"
#include "lim_sta_hash_api.h"
#include "sch_api.h"
#include "lim_send_messages.h"
#include "lim_assoc_utils.h"
#include "lim_ft.h"
#ifdef WLAN_FEATURE_11W
#include "wni_cfg.h"
#endif

#ifdef WLAN_FEATURE_VOWIFI_11R
#include "lim_ft_defs.h"
#endif
#include "lim_session.h"
#include "cdf_types.h"
#include "cdf_trace.h"
#include "cds_utils.h"
#include "sme_trace.h"
#if defined WLAN_FEATURE_VOWIFI
#include "rrm_api.h"
#endif

#include "wma_types.h"

/**
 *
 * \brief This function is called to add the sequence number to the
 * management frames
 *
 * \param  pMac Pointer to Global MAC structure
 *
 * \param  pMacHdr Pointer to MAC management header
 *
 * The pMacHdr argument points to the MAC management header. The
 * sequence number stored in the pMac structure will be incremented
 * and updated to the MAC management header. The start sequence
 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
 * number will roll over.
 *
 */
void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
{
	if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
		pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
	}

	pMac->mgmtSeqNum++;

	pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
	pMacHdr->seqControl.seqNumHi =
		((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
}

/**
 *
 * \brief This function is called before sending a p2p action frame
 * inorder to add sequence numbers to action packets
 *
 * \param  pMac Pointer to Global MAC structure
 *
 * \param pBD Pointer to the frame buffer that needs to be populate
 *
 * The pMacHdr argument points to the MAC management header. The
 * sequence number stored in the pMac structure will be incremented
 * and updated to the MAC management header. The start sequence
 * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
 * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
 * number will roll over.
 *
 */
void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
{
	tpSirMacMgmtHdr pMacHdr;

	/* / Prepare MAC management header */
	pMacHdr = (tpSirMacMgmtHdr) (pBD);

	/* Prepare sequence number */
	lim_add_mgmt_seq_num(pMac, pMacHdr);
	lim_log(pMac, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
		pMacHdr->seqControl.seqNumLo,
		pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
}

/**
 * lim_populate_mac_header() - Fill in 802.11 header of frame
 *
 * @mac_ctx: Pointer to Global MAC structure
 * @buf: Pointer to the frame buffer that needs to be populate
 * @type: 802.11 Type of the frame
 * @sub_type: 802.11 Subtype of the frame
 * @peer_addr: dst address
 * @self_mac_addr: local mac address
 *
 * This function is called by various LIM modules to prepare the
 * 802.11 frame MAC header
 *
 * The buf argument points to the beginning of the frame buffer to
 * which - a) The 802.11 MAC header is set b) Following this MAC header
 * will be the MGMT frame payload The payload itself is populated by the
 * caller API
 *
 * Return: None
 */

void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
		uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
		tSirMacAddr self_mac_addr)
{
	tpSirMacMgmtHdr mac_hdr;

	/* Prepare MAC management header */
	mac_hdr = (tpSirMacMgmtHdr) (buf);

	/* Prepare FC */
	mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
	mac_hdr->fc.type = type;
	mac_hdr->fc.subType = sub_type;

	/* Prepare Address 1 */
	cdf_mem_copy((uint8_t *) mac_hdr->da,
		     (uint8_t *) peer_addr, sizeof(tSirMacAddr));

	/* Prepare Address 2 */
	sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);

	/* Prepare Address 3 */
	cdf_mem_copy((uint8_t *) mac_hdr->bssId,
		     (uint8_t *) peer_addr, sizeof(tSirMacAddr));

	/* Prepare sequence number */
	lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
	lim_log(mac_ctx, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
		mac_hdr->seqControl.seqNumLo,
		mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
}

/**
 * lim_send_probe_req_mgmt_frame() - send probe request management frame
 * @mac_ctx: Pointer to Global MAC structure
 * @ssid: SSID to be sent in Probe Request frame
 * @bssid: BSSID to be sent in Probe Request frame
 * @channel: Channel # on which the Probe Request is going out
 * @self_macaddr: self MAC address
 * @dot11mode: self dotllmode
 * @additional_ielen: if non-zero, include additional_ie in the Probe Request
 *                   frame
 * @additional_ie: if additional_ielen is non zero, include this field in the
 *                Probe Request frame
 *
 * This function is called by various LIM modules to send Probe Request frame
 * during active scan/learn phase.
 * Probe request is sent out in the following scenarios:
 * --heartbeat failure:  session needed
 * --join req:           session needed
 * --foreground scan:    no session
 * --background scan:    no session
 * --sch_beacon_processing:  to get EDCA parameters:  session needed
 *
 * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
 */
tSirRetStatus
lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
			      tSirMacSSid *ssid,
			      tSirMacAddr bssid,
			      uint8_t channel,
			      tSirMacAddr self_macaddr,
			      uint32_t dot11mode,
			      uint32_t additional_ielen, uint8_t *additional_ie)
{
	tDot11fProbeRequest pr;
	uint32_t status, bytes, payload;
	uint8_t *frame;
	void *packet;
	CDF_STATUS cdf_status, extcap_status;
	tpPESession pesession;
	uint8_t sessionid;
	uint8_t *p2pie = NULL;
	uint8_t txflag = 0;
	uint8_t sme_sessionid = 0;
	bool is_vht_enabled = false;
	uint8_t txPower;
	uint16_t addn_ielen = additional_ielen;

	/* The probe req should not send 11ac capabilieties if band is 2.4GHz,
	 * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
	 * is false and dot11mode is 11ac set it to 11n.
	 */
	if (channel <= SIR_11B_CHANNEL_END &&
	    (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
	    (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
	     WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
		dot11mode = WNI_CFG_DOT11_MODE_11N;
	/*
	 * session context may or may not be present, when probe request needs
	 * to be sent out. Following cases exist:
	 * --heartbeat failure:  session needed
	 * --join req:           session needed
	 * --foreground scan:    no session
	 * --background scan:    no session
	 * --sch_beacon_processing:  to get EDCA parameters:  session needed
	 * If session context does not exist, some IEs will be populated from
	 * CFGs, e.g. Supported and Extended rate set IEs
	 */
	pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);

	if (pesession != NULL)
		sme_sessionid = pesession->smeSessionId;

	/* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
	/* and then hand it off to 'dot11f_pack_probe_request' (for */
	/* serialization).  We start by zero-initializing the structure: */
	cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);

	/* & delegating to assorted helpers: */
	populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);

	if (addn_ielen && additional_ie)
		p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);

	/*
	 * Don't include 11b rate if it is a P2P serach or probe request is
	 * sent by P2P Client
	 */
	if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
	    (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
	      mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
	     ((pesession != NULL) &&
	      (CDF_P2P_CLIENT_MODE == pesession->pePersona))
	    )
	   ) {
		/*
		 * In the below API pass channel number > 14, do that it fills
		 * only 11a rates in supported rates
		 */
		populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
					   pesession);
	} else {
		populate_dot11f_supp_rates(mac_ctx, channel,
					   &pr.SuppRates, pesession);

		if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
			populate_dot11f_ext_supp_rates1(mac_ctx, channel,
							&pr.ExtSuppRates);
		}
	}

#if defined WLAN_FEATURE_VOWIFI
	/*
	 * Table 7-14 in IEEE Std. 802.11k-2008 says
	 * DS params "can" be present in RRM is disabled and "is" present if
	 * RRM is enabled. It should be ok even if we add it into probe req when
	 * RRM is not enabled.
	 */
	populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
	/* Call RRM module to get the tx power for management used. */
	txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
	populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);

#endif

	if (pesession != NULL) {
		pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
		/* Include HT Capability IE */
		if (pesession->htCapability)
			populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
	} else {                /* pesession == NULL */
		if (IS_DOT11_MODE_HT(dot11mode))
			populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
	}

	/*
	 * Set channelbonding information as "disabled" when tunned to a
	 * 2.4 GHz channel
	 */
	if (channel <= SIR_11B_CHANNEL_END) {
		if (mac_ctx->roam.configParam.channelBondingMode24GHz
		    == PHY_SINGLE_CHANNEL_CENTERED) {
			pr.HTCaps.supportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_20MHZ;
			pr.HTCaps.shortGI40MHz = 0;
		} else {
			pr.HTCaps.supportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
		}
	}
#ifdef WLAN_FEATURE_11AC
	if (pesession != NULL) {
		pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
		/* Include VHT Capability IE */
		if (pesession->vhtCapability) {
			populate_dot11f_vht_caps(mac_ctx, pesession,
						 &pr.VHTCaps);
			is_vht_enabled = true;
		}
	} else {
		if (IS_DOT11_MODE_VHT(dot11mode)) {
			populate_dot11f_vht_caps(mac_ctx, pesession,
						 &pr.VHTCaps);
			is_vht_enabled = true;
		}
	}
#endif
	if (pesession != NULL)
		populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
			pesession);

	/* That's it-- now we pack it.  First, how much space are we going to */
	status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGP, FL("Failed to calculate the packed size for a Probe Request (0x%08x)."), status);
		/* We'll fall back on the worst case scenario: */
		payload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."), status);
	}

	/* Strip extended capability IE (if present). FW will add that IE */
	if (addn_ielen) {
		extcap_status = lim_strip_extcap_ie(mac_ctx, additional_ie,
					&addn_ielen, NULL);
		if (CDF_STATUS_SUCCESS != extcap_status)
			lim_log(mac_ctx, LOGE,
			    FL("Error:%d stripping extcap IE"), extcap_status);
	}

	bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;

	/* Ok-- try to allocate some memory: */
	cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
				      (void **)&packet);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes for a Probe Request."), bytes);
		return eSIR_MEM_ALLOC_FAILED;
	}
	/* Paranoia: */
	cdf_mem_set(frame, bytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);

	/* That done, pack the Probe Request: */
	status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
					    sizeof(tSirMacMgmtHdr),
					    payload, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE,
			FL("Failed to pack a Probe Request (0x%08x)."), status);
		cds_packet_free((void *)packet);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW, FL("There were warnings while packing a Probe Request (0x%08x)."), status);
	}
	/* Append any AddIE if present. */
	if (addn_ielen) {
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     additional_ie, addn_ielen);
		payload += addn_ielen;
	}

	/* If this probe request is sent during P2P Search State, then we need
	 * to send it at OFDM rate.
	 */
	if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
	    || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
		mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
		/*
		 * For unicast probe req mgmt from Join function we don't set
		 * above variables. So we need to add one more check whether it
		 * is pePersona is P2P_CLIENT or not
		 */
	    || ((pesession != NULL) &&
		(CDF_P2P_CLIENT_MODE == pesession->pePersona))
	    ) {
		txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	cdf_status =
		wma_tx_frame(mac_ctx, packet,
			   (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, frame, txflag, sme_sessionid,
			   0);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGE,
			FL("could not send Probe Request frame!"));
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;
} /* End lim_send_probe_req_mgmt_frame. */

tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
					     uint8_t *addIE, uint16_t *addnIELen,
					     uint8_t probeReqP2pIe)
{
	/* If Probe request doesn't have P2P IE, then take out P2P IE
	   from additional IE */
	if (!probeReqP2pIe) {
		uint8_t *tempbuf = NULL;
		uint16_t tempLen = 0;
		int left = *addnIELen;
		uint8_t *ptr = addIE;
		uint8_t elem_id, elem_len;

		if (NULL == addIE) {
			PELOGE(lim_log(pMac, LOGE, FL(" NULL addIE pointer"));)
			return eSIR_FAILURE;
		}

		tempbuf = cdf_mem_malloc(left);
		if (NULL == tempbuf) {
			PELOGE(lim_log(pMac, LOGE,
				       FL
					       ("Unable to allocate memory to store addn IE"));
			       )
			return eSIR_MEM_ALLOC_FAILED;
		}

		while (left >= 2) {
			elem_id = ptr[0];
			elem_len = ptr[1];
			left -= 2;
			if (elem_len > left) {
				lim_log(pMac, LOGE,
					FL
						("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
					elem_id, elem_len, left);
				cdf_mem_free(tempbuf);
				return eSIR_FAILURE;
			}
			if (!((SIR_MAC_EID_VENDOR == elem_id) &&
			      (memcmp
				       (&ptr[2], SIR_MAC_P2P_OUI,
				       SIR_MAC_P2P_OUI_SIZE) == 0))) {
				cdf_mem_copy(tempbuf + tempLen, &ptr[0],
					     elem_len + 2);
				tempLen += (elem_len + 2);
			}
			left -= elem_len;
			ptr += (elem_len + 2);
		}
		cdf_mem_copy(addIE, tempbuf, tempLen);
		*addnIELen = tempLen;
		cdf_mem_free(tempbuf);
	}
	return eSIR_SUCCESS;
}

/**
 * lim_send_probe_rsp_mgmt_frame() - Send probe response
 *
 * @mac_ctx: Handle for mac context
 * @peer_macaddr: Mac address of requesting peer
 * @ssid: SSID for response
 * @n_staid: Station ID, currently unused.
 * @pe_session: PE session id
 * @keepalive: Keep alive flag. Currently unused.
 * @preq_p2pie: P2P IE in incoming probe request
 *
 * Builds and sends probe response frame to the requesting peer
 *
 * Return: void
 */

void
lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
			      tSirMacAddr peer_macaddr,
			      tpAniSSID ssid,
			      short n_staid,
			      uint8_t keepalive,
			      tpPESession pe_session, uint8_t preq_p2pie)
{
	tDot11fProbeResponse *frm;
	tSirRetStatus sir_status;
	uint32_t cfg, payload, bytes, status;
	tpSirMacMgmtHdr mac_hdr;
	uint8_t *frame;
	void *packet;
	CDF_STATUS cdf_status;
	uint32_t addn_ie_present = false;

	uint16_t addn_ie_len = 0;
	uint32_t wps_ap = 0, tmp;
	uint8_t tx_flag = 0;
	uint8_t *add_ie = NULL;
	uint8_t *p2p_ie = NULL;
	uint8_t noalen = 0;
	uint8_t total_noalen = 0;
	uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
	uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
	uint8_t sme_sessionid = 0;
	bool is_vht_enabled = false;
	tDot11fIEExtCap extracted_ext_cap;
	bool extracted_ext_cap_flag = true;

	/* We don't answer requests in this case*/
	if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG)
		return;

	if (NULL == pe_session)
		return;

	/*
	 * In case when cac timer is running for this SAP session then
	 * avoid sending probe rsp out. It is violation of dfs specification.
	 */
	if (((pe_session->pePersona == CDF_SAP_MODE) ||
	    (pe_session->pePersona == CDF_P2P_GO_MODE)) &&
	    (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
			  FL("CAC timer is running, probe response dropped"));
		return;
	}
	sme_sessionid = pe_session->smeSessionId;
	frm = cdf_mem_malloc(sizeof(tDot11fProbeResponse));
	if (NULL == frm) {
		lim_log(mac_ctx, LOGE,
			FL("Unable to allocate memory"));
		return;
	}

	cdf_mem_zero(&extracted_ext_cap, sizeof(extracted_ext_cap));

	/*
	 * Fill out 'frm', after which we'll just hand the struct off to
	 * 'dot11f_pack_probe_response'.
	 */
	cdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);

	/*
	 * Timestamp to be updated by TFP, below.
	 *
	 * Beacon Interval:
	 */
	if (LIM_IS_AP_ROLE(pe_session)) {
		frm->BeaconInterval.interval =
			mac_ctx->sch.schObject.gSchBeaconInterval;
	} else {
		sir_status = wlan_cfg_get_int(mac_ctx,
				WNI_CFG_BEACON_INTERVAL, &cfg);
		if (eSIR_SUCCESS != sir_status) {
			lim_log(mac_ctx, LOGP,
				FL("Failed to get WNI_CFG_BEACON_INTERVAL (%d)."),
				sir_status);
			goto err_ret;
		}
		frm->BeaconInterval.interval = (uint16_t) cfg;
	}

	populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
	populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
		&frm->SuppRates, pe_session);

	populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
		pe_session->currentOperChannel);
	populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);

	if (LIM_IS_AP_ROLE(pe_session)) {
		if (pe_session->wps_state != SAP_WPS_DISABLED)
			populate_dot11f_probe_res_wpsi_es(mac_ctx,
				&frm->WscProbeRes,
				pe_session);
	} else {
		if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
			&tmp) != eSIR_SUCCESS)
			lim_log(mac_ctx, LOGP, "Failed to cfg get id %d",
				WNI_CFG_WPS_ENABLE);

		wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;

		if (wps_ap)
			populate_dot11f_wsc_in_probe_res(mac_ctx,
				&frm->WscProbeRes);

		if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
		    eLIM_WSC_ENROLL_BEGIN) {
			populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
				&frm->WscProbeRes);
			mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
				eLIM_WSC_ENROLL_IN_PROGRESS;
		}

		if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
		    eLIM_WSC_ENROLL_END) {
			de_populate_dot11f_wsc_registrar_info_in_probe_res(
				mac_ctx, &frm->WscProbeRes);
			mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
				eLIM_WSC_ENROLL_NOOP;
		}
	}

	populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
	populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);

	if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
		populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);

	populate_dot11f_ext_supp_rates(mac_ctx,
		POPULATE_DOT11F_RATES_OPERATIONAL,
		&frm->ExtSuppRates, pe_session);

	/* Populate HT IEs, when operating in 11n */
	if (pe_session->htCapability) {
		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
		populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
	}
#ifdef WLAN_FEATURE_11AC
	if (pe_session->vhtCapability) {
		lim_log(mac_ctx, LOG1, FL("Populate VHT IE in Probe Response"));
		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
		populate_dot11f_vht_operation(mac_ctx, pe_session,
			&frm->VHTOperation);
		/*
		 * we do not support multi users yet.
		 * populate_dot11f_vht_ext_bss_load( mac_ctx,
		 *         &frm.VHTExtBssLoad );
		 */
		is_vht_enabled = true;
	}
#endif

	populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
		pe_session);

	if (pe_session->pLimStartBssReq) {
		populate_dot11f_wpa(mac_ctx,
			&(pe_session->pLimStartBssReq->rsnIE),
			&frm->WPA);
		populate_dot11f_rsn_opaque(mac_ctx,
			&(pe_session->pLimStartBssReq->rsnIE),
			&frm->RSNOpaque);
	}

	populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
		&frm->WMMCaps, pe_session);

#if defined(FEATURE_WLAN_WAPI)
	if (pe_session->pLimStartBssReq)
		populate_dot11f_wapi(mac_ctx,
			&(pe_session->pLimStartBssReq->rsnIE),
			&frm->WAPI);
#endif /* defined(FEATURE_WLAN_WAPI) */

	status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGP,
			FL("Probe Response size error (0x%08x)."),
			status);
		/* We'll fall back on the worst case scenario: */
		payload = sizeof(tDot11fProbeResponse);
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Probe Response size warning (0x%08x)."),
			status);
	}

	bytes = payload + sizeof(tSirMacMgmtHdr);

	if (mac_ctx->lim.gpLimRemainOnChanReq)
		bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
			 sizeof(tSirRemainOnChnReq));
	else
		/*
		 * Only use CFG for non-listen mode. This CFG is not working for
		 * concurrency. In listening mode, probe rsp IEs is passed in
		 * the message from SME to PE.
		 */
		addn_ie_present =
			(pe_session->addIeParams.probeRespDataLen != 0);

	if (addn_ie_present) {

		add_ie = cdf_mem_malloc(
				pe_session->addIeParams.probeRespDataLen);
		if (NULL == add_ie) {
			lim_log(mac_ctx, LOGE,
				FL("add_ie allocation failed"));
			goto err_ret;
		}

		cdf_mem_copy(add_ie,
			     pe_session->addIeParams.probeRespData_buff,
			     pe_session->addIeParams.probeRespDataLen);
		addn_ie_len = pe_session->addIeParams.probeRespDataLen;

		if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
					add_ie, &addn_ie_len, preq_p2pie)) {
			lim_log(mac_ctx, LOGP,
				FL("Unable to get addn_ie"));
			goto err_ret;
		}

		sir_status = lim_strip_extcap_update_struct(mac_ctx,
					add_ie, &addn_ie_len,
					&extracted_ext_cap);
		if (eSIR_SUCCESS != sir_status) {
			extracted_ext_cap_flag = false;
			lim_log(mac_ctx, LOG1,
				FL("Unable to strip off ExtCap IE"));
		}

		bytes = bytes + addn_ie_len;

		if (preq_p2pie)
			p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
					addn_ie_len);

		if (p2p_ie != NULL) {
			/* get NoA attribute stream P2P IE */
			noalen = lim_get_noa_attr_stream(mac_ctx,
					noa_stream, pe_session);
			if (noalen != 0) {
				total_noalen =
					lim_build_p2p_ie(mac_ctx, &noa_ie[0],
						&noa_stream[0], noalen);
				bytes = bytes + total_noalen;
			}
		}
	}

	cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
				      (void **)&packet);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGP, FL("Probe Response allocation failed"));
		goto err_ret;
	}
	/* Paranoia: */
	cdf_mem_set(frame, bytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
		pe_session->selfMacAddr);

	mac_hdr = (tpSirMacMgmtHdr) frame;

	sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);

	/* merge ExtCap IE */
	if (extracted_ext_cap_flag)
		lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap);

	/* That done, pack the Probe Response: */
	status =
		dot11f_pack_probe_response(mac_ctx, frm,
			frame + sizeof(tSirMacMgmtHdr),
			payload, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE,
			FL("Probe Response pack failure (0x%08x)."),
			status);
			goto err_ret;
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Probe Response pack warning (0x%08x)."),
			status);
	}

	lim_log(mac_ctx, LOG3, FL("Sending Probe Response frame to "));
	lim_print_mac_addr(mac_ctx, peer_macaddr, LOG3);

	mac_ctx->sys.probeRespond++;

	if (mac_ctx->lim.gpLimRemainOnChanReq)
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
			     (mac_ctx->lim.gpLimRemainOnChanReq->length -
			      sizeof(tSirRemainOnChnReq)));

	if (addn_ie_present)
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     &add_ie[0], addn_ie_len);

	if (noalen != 0) {
		if (total_noalen >
		    (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
			lim_log(mac_ctx, LOGE,
				FL("Not able to insert NoA, total len=%d"),
				total_noalen);
			goto err_ret;
		} else {
			cdf_mem_copy(&frame[bytes - (total_noalen)],
				     &noa_ie[0], total_noalen);
		}
	}

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
	    || (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (pe_session->pePersona == CDF_P2P_GO_MODE)
	    )
		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;

	/* Queue Probe Response frame in high priority WQ */
	cdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
				(uint16_t) bytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, frame, tx_flag,
				sme_sessionid, 0);

	/* Pkt will be freed up by the callback */
	if (!CDF_IS_STATUS_SUCCESS(cdf_status))
		lim_log(mac_ctx, LOGE, FL("Could not send Probe Response."));

	if (add_ie != NULL)
		cdf_mem_free(add_ie);

	cdf_mem_free(frm);
	return;

err_ret:
	if (add_ie != NULL)
		cdf_mem_free(add_ie);
	if (frm != NULL)
		cdf_mem_free(frm);
	if (packet != NULL)
		cds_packet_free((void *)packet);
	return;

} /* End lim_send_probe_rsp_mgmt_frame. */

void
lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
				tSirMacAddr peerMacAddr,
				tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
{
	uint16_t i;
	uint8_t *pFrame;
	tDot11fAddTSRequest AddTSReq;
	tDot11fWMMAddTSRequest WMMAddTSReq;
	uint32_t nPayload, nBytes, nStatus;
	tpSirMacMgmtHdr pMacHdr;
	void *pPacket;
#ifdef FEATURE_WLAN_ESE
	uint32_t phyMode;
#endif
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	if (NULL == psessionEntry) {
		return;
	}

	smeSessionId = psessionEntry->smeSessionId;

	if (!pAddTS->wmeTspecPresent) {
		cdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);

		AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
		AddTSReq.DialogToken.token = pAddTS->dialogToken;
		AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
		if (pAddTS->lleTspecPresent) {
			populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
		} else {
			populate_dot11f_wmmtspec(&pAddTS->tspec,
						 &AddTSReq.WMMTSPEC);
		}

		if (pAddTS->lleTspecPresent) {
			AddTSReq.num_WMMTCLAS = 0;
			AddTSReq.num_TCLAS = pAddTS->numTclas;
			for (i = 0; i < pAddTS->numTclas; ++i) {
				populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
						      &AddTSReq.TCLAS[i]);
			}
		} else {
			AddTSReq.num_TCLAS = 0;
			AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
			for (i = 0; i < pAddTS->numTclas; ++i) {
				populate_dot11f_wmmtclas(pMac,
							 &pAddTS->tclasInfo[i],
							 &AddTSReq.WMMTCLAS[i]);
			}
		}

		if (pAddTS->tclasProcPresent) {
			if (pAddTS->lleTspecPresent) {
				AddTSReq.TCLASSPROC.processing =
					pAddTS->tclasProc;
				AddTSReq.TCLASSPROC.present = 1;
			} else {
				AddTSReq.WMMTCLASPROC.version = 1;
				AddTSReq.WMMTCLASPROC.processing =
					pAddTS->tclasProc;
				AddTSReq.WMMTCLASPROC.present = 1;
			}
		}

		nStatus =
			dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGP,
				FL("Failed to calculate the packed size f"
				   "or an Add TS Request (0x%08x)."), nStatus);
			/* We'll fall back on the worst case scenario: */
			nPayload = sizeof(tDot11fAddTSRequest);
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while calculating"
				   "the packed size for an Add TS Request"
				   " (0x%08x)."), nStatus);
		}
	} else {
		cdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);

		WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
		WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
		WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;

		/* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
		WMMAddTSReq.StatusCode.statusCode = 0;

		populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
#ifdef FEATURE_WLAN_ESE
		lim_get_phy_mode(pMac, &phyMode, psessionEntry);

		if (phyMode == WNI_CFG_PHY_MODE_11G
		    || phyMode == WNI_CFG_PHY_MODE_11A) {
			pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
		} else {
			pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
		}
		populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
				      &WMMAddTSReq.ESETrafStrmRateSet,
				      sizeof(uint8_t));
#endif
		/* fillWmeTspecIE */

		nStatus =
			dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
								  &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGP,
				FL("Failed to calculate the packed size f"
				   "or a WMM Add TS Request (0x%08x)."),
				nStatus);
			/* We'll fall back on the worst case scenario: */
			nPayload = sizeof(tDot11fAddTSRequest);
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while calculating"
				   "the packed size for a WMM Add TS Requ"
				   "est (0x%08x)."), nStatus);
		}
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
				       "d TS Request."), nBytes);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
#endif

	/* That done, pack the struct: */
	if (!pAddTS->wmeTspecPresent) {
		nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
						     pFrame +
						     sizeof(tSirMacMgmtHdr),
						     nPayload, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGE,
				FL("Failed to pack an Add TS Request "
				   "(0x%08x)."), nStatus);
			cds_packet_free((void *)pPacket);
			return; /* allocated! */
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while packing "
				   "an Add TS Request (0x%08x)."), nStatus);
		}
	} else {
		nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
							 pFrame +
							 sizeof(tSirMacMgmtHdr),
							 nPayload, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGE,
				FL("Failed to pack a WMM Add TS Reque"
				   "st (0x%08x)."), nStatus);
			cds_packet_free((void *)pPacket);
			return; /* allocated! */
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while packing "
				   "a WMM Add TS Request (0x%08x)."), nStatus);
		}
	}

	PELOG3(lim_log(pMac, LOG3, FL("Sending an Add TS Request frame to "));
	       lim_print_mac_addr(pMac, peerMacAddr, LOG3);
	       )

	if ((SIR_BAND_5_GHZ ==
	     lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
	    || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));

	/* Queue Addts Response frame in high priority WQ */
	cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE, FL("*** Could not send an Add TS Request"
				       " (%X) ***"), cdf_status);
		/* Pkt will be freed up by the callback */
	}

} /* End lim_send_addts_req_action_frame. */

/**
 * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
 * @mac_ctx: Handle for mac context
 * @status_code: Status code for assoc response frame
 * @aid: Association ID
 * @peer_addr: Mac address of requesting peer
 * @subtype: Assoc/Reassoc
 * @sta: Pointer to station node
 * @pe_session: PE session id.
 *
 * Builds and sends association response frame to the requesting peer.
 *
 * Return: void
 */

void
lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
	uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
	uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
{
	static tDot11fAssocResponse frm;
	uint8_t *frame;
	tpSirMacMgmtHdr mac_hdr;
	tSirRetStatus sir_status;
	uint8_t lle_mode = 0, addts;
	tHalBitVal qos_mode, wme_mode;
	uint32_t payload, bytes, status;
	void *packet;
	CDF_STATUS cdf_status;
	tUpdateBeaconParams beacon_params;
	uint8_t tx_flag = 0;
	uint32_t addn_ie_len = 0;
	uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
	tpSirAssocReq assoc_req = NULL;
	uint8_t sme_session = 0;
	bool is_vht = false;
	uint16_t stripoff_len = 0;
	tDot11fIEExtCap extracted_ext_cap;
	bool extracted_flag = false;
#ifdef WLAN_FEATURE_11W
	uint32_t retry_int;
	uint32_t max_retries;
#endif

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

	sme_session = pe_session->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	limGetQosMode(pe_session, &qos_mode);
	limGetWmeMode(pe_session, &wme_mode);

	/*
	 * An Add TS IE is added only if the AP supports it and
	 * the requesting STA sent a traffic spec.
	 */
	addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;

	frm.Status.status = status_code;

	frm.AID.associd = aid | LIM_AID_MASK;

	if (NULL == sta) {
		populate_dot11f_supp_rates(mac_ctx,
			POPULATE_DOT11F_RATES_OPERATIONAL,
			&frm.SuppRates, pe_session);
		populate_dot11f_ext_supp_rates(mac_ctx,
			POPULATE_DOT11F_RATES_OPERATIONAL,
			&frm.ExtSuppRates, pe_session);
	} else {
		populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
			&frm.ExtSuppRates,
			sta->supportedRates.llbRates,
			sta->supportedRates.llaRates);
	}

	if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
	    eSIR_SUCCESS == status_code) {
		assoc_req = (tpSirAssocReq)
			pe_session->parsedAssocReq[sta->assocId];
		/*
		 * populate P2P IE in AssocRsp when assocReq from the peer
		 * includes P2P IE
		 */
		if (assoc_req != NULL && assoc_req->addIEPresent)
			populate_dot11_assoc_res_p2p_ie(mac_ctx,
				&frm.P2PAssocRes,
				assoc_req);
	}

	if (NULL != sta) {
		if (eHAL_SET == qos_mode) {
			if (sta->lleEnabled) {
				lle_mode = 1;
				populate_dot11f_edca_param_set(mac_ctx,
					&frm.EDCAParamSet, pe_session);
			}
		}

		if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
			populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
				pe_session);

			if (sta->wsmEnabled)
				populate_dot11f_wmm_caps(&frm.WMMCaps);
		}

		if (sta->mlmStaContext.htCapability &&
		    pe_session->htCapability) {
			lim_log(mac_ctx, LOG1,
				FL("Populate HT IEs in Assoc Response"));
			populate_dot11f_ht_caps(mac_ctx, pe_session,
				&frm.HTCaps);
			populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
				pe_session);
		}
#ifdef WLAN_FEATURE_11AC
		if (sta->mlmStaContext.vhtCapability &&
		    pe_session->vhtCapability) {
			lim_log(mac_ctx, LOG1,
				FL("Populate VHT IEs in Assoc Response"));
			populate_dot11f_vht_caps(mac_ctx, pe_session,
				&frm.VHTCaps);
			populate_dot11f_vht_operation(mac_ctx, pe_session,
				&frm.VHTOperation);
			is_vht = true;
		}
#endif

		populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
			pe_session);

#ifdef WLAN_FEATURE_11W
		if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
			if (wlan_cfg_get_int
				    (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
				    &max_retries) != eSIR_SUCCESS)
				lim_log(mac_ctx, LOGE,
					FL("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure"));
			else if (wlan_cfg_get_int
					 (mac_ctx,
					 WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
					 &retry_int) != eSIR_SUCCESS)
				lim_log(mac_ctx, LOGE,
					FL("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure"));
			else
				populate_dot11f_timeout_interval(mac_ctx,
					&frm.TimeoutInterval,
					SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
					(max_retries -
						sta->pmfSaQueryRetryCount)
						* retry_int);
		}
#endif
	}

	cdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);

	if (LIM_IS_AP_ROLE(pe_session) &&
		(pe_session->gLimProtectionControl !=
		    WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
			lim_decide_ap_protection(mac_ctx, peer_addr,
				&beacon_params, pe_session);

	lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
		pe_session);
	lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
		pe_session);

	/*
	 * Populate Do11capabilities after updating session with
	 * Assos req details
	 */
	populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);

	beacon_params.bssIdx = pe_session->bssIdx;

	/* Send message to HAL about beacon parameter change. */
	if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
	    && beacon_params.paramChangeBitmap) {
		sch_set_fixed_beacon_fields(mac_ctx, pe_session);
		lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
	}
	/* Allocate a buffer for this frame: */
	status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE,
			FL("get Association Response size failure (0x%08x)."),
			status);
		return;
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("get Association Response size warning (0x%08x)."),
			status);
	}

	bytes = sizeof(tSirMacMgmtHdr) + payload;

	if (assoc_req != NULL) {
		addn_ie_len = (pe_session->addIeParams.assocRespDataLen != 0);

		/* Nonzero length indicates Assoc rsp IE available */
		if (addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN
		    && (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
			cdf_mem_copy(add_ie,
				pe_session->addIeParams.assocRespData_buff,
				pe_session->addIeParams.assocRespDataLen);

			cdf_mem_set((uint8_t *) &extracted_ext_cap,
				    sizeof(extracted_ext_cap), 0);

			stripoff_len = addn_ie_len;
			sir_status =
				lim_strip_extcap_update_struct
					(mac_ctx, &add_ie[0], &stripoff_len,
					&extracted_ext_cap);
			if (eSIR_SUCCESS != sir_status) {
				lim_log(mac_ctx, LOG1,
					FL("strip off extcap IE failed"));
			} else {
				addn_ie_len = stripoff_len;
				extracted_flag = true;
			}
			bytes = bytes + addn_ie_len;
		}
		lim_log(mac_ctx, LOG1,
			FL("addn_ie_len = %d for Assoc Resp : %d"),
			addn_ie_len, assoc_req->addIEPresent);
	}
	cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
				      (void **)&packet);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGP, FL("cds_packet_alloc failed."));
		return;
	}
	/* Paranoia: */
	cdf_mem_set(frame, bytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		(LIM_ASSOC == subtype) ?
			SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
			peer_addr,
			pe_session->selfMacAddr);
	mac_hdr = (tpSirMacMgmtHdr) frame;

	sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);

	/* merge the ExtCap struct */
	if (extracted_flag)
		lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap);
	status = dot11f_pack_assoc_response(mac_ctx, &frm,
					     frame + sizeof(tSirMacMgmtHdr),
					     payload, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE,
			FL("Association Response pack failure(0x%08x)."),
			status);
		cds_packet_free((void *)packet);
		return;
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Association Response pack warning (0x%08x)."),
			status);
	}

	if (subtype == LIM_ASSOC)
		lim_log(mac_ctx, LOG1,
			FL("*** Sending Assoc Resp status %d aid %d to "),
			status_code, aid);
	else
		lim_log(mac_ctx, LOG1,
			FL("*** Sending ReAssoc Resp status %d aid %d to "),
			status_code, aid);

	lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);

	if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     &add_ie[0], addn_ie_len);

	if ((SIR_BAND_5_GHZ ==
		lim_get_rf_band(pe_session->currentOperChannel)) ||
			(pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
			(pe_session->pePersona == CDF_P2P_GO_MODE))
		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 pe_session->peSessionId, mac_hdr->fc.subType));
	/* Queue Association Response frame in high priority WQ */
	cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, frame, tx_flag,
				sme_session, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 pe_session->peSessionId, cdf_status));

	/* Pkt will be freed up by the callback */
	if (!CDF_IS_STATUS_SUCCESS(cdf_status))
		lim_log(mac_ctx, LOGE,
			FL("*** Could not Send Re/AssocRsp, retCode=%X ***"),
			cdf_status);

	/*
	 * update the ANI peer station count.
	 * FIXME_PROTECTION : take care of different type of station
	 * counter inside this function.
	 */
	lim_util_count_sta_add(mac_ctx, sta, pe_session);

}

void
lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
				tSirMacAddr peer,
				uint8_t wmmTspecPresent,
				tSirMacTSInfo *pTsinfo,
				tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
{
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	tDot11fDelTS DelTS;
	tDot11fWMMDelTS WMMDelTS;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	if (NULL == psessionEntry) {
		return;
	}

	smeSessionId = psessionEntry->smeSessionId;

	if (!wmmTspecPresent) {
		cdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);

		DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
		DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
		populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);

		nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGP,
				FL("Failed to calculate the packed si"
				   "ze for a Del TS (0x%08x)."), nStatus);
			/* We'll fall back on the worst case scenario: */
			nPayload = sizeof(tDot11fDelTS);
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while calcula"
				   "ting the packed size for a Del TS"
				   " (0x%08x)."), nStatus);
		}
	} else {
		cdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);

		WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
		WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
		WMMDelTS.DialogToken.token = 0;
		WMMDelTS.StatusCode.statusCode = 0;
		populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
		nStatus =
			dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGP,
				FL("Failed to calculate the packed si"
				   "ze for a WMM Del TS (0x%08x)."), nStatus);
			/* We'll fall back on the worst case scenario: */
			nPayload = sizeof(tDot11fDelTS);
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while calcula"
				   "ting the packed size for a WMM De"
				   "l TS (0x%08x)."), nStatus);
		}
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
				       "d TS Response."), nBytes);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	/* That done, pack the struct: */
	if (!wmmTspecPresent) {
		nStatus = dot11f_pack_del_ts(pMac, &DelTS,
					     pFrame + sizeof(tSirMacMgmtHdr),
					     nPayload, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGE,
				FL("Failed to pack a Del TS frame (0x%08x)."),
				nStatus);
			cds_packet_free((void *)pPacket);
			return; /* allocated! */
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while packing "
				   "a Del TS frame (0x%08x)."), nStatus);
		}
	} else {
		nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
						 pFrame + sizeof(tSirMacMgmtHdr),
						 nPayload, &nPayload);
		if (DOT11F_FAILED(nStatus)) {
			lim_log(pMac, LOGE,
				FL
					("Failed to pack a WMM Del TS frame (0x%08x)."),
				nStatus);
			cds_packet_free((void *)pPacket);
			return; /* allocated! */
		} else if (DOT11F_WARNED(nStatus)) {
			lim_log(pMac, LOGW,
				FL("There were warnings while packing "
				   "a WMM Del TS frame (0x%08x)."), nStatus);
		}
	}

	PELOG1(lim_log
		       (pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
	       lim_print_mac_addr(pMac, pMacHdr->da, LOG1);
	       )

	if ((SIR_BAND_5_GHZ ==
	     lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
	    || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	/* Pkt will be freed up by the callback */
	if (!CDF_IS_STATUS_SUCCESS(cdf_status))
		lim_log(pMac, LOGE, FL("Failed to send Del TS (%X)!"),
			cdf_status);

} /* End lim_send_delts_req_action_frame. */

/**
 * lim_send_assoc_req_mgmt_frame() - Send association request
 * @mac_ctx: Handle to MAC context
 * @mlm_assoc_req: Association request information
 * @pe_session: PE session information
 *
 * Builds and transmits association request frame to AP.
 *
 * Return: Void
 */

void
lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
			      tLimMlmAssocReq *mlm_assoc_req,
			      tpPESession pe_session)
{
	tDot11fAssocRequest *frm;
	uint16_t caps;
	uint8_t *frame;
	tSirRetStatus sir_status;
	tLimMlmAssocCnf assoc_cnf;
	uint32_t bytes, payload, status;
	uint8_t qos_enabled, wme_enabled, wsm_enabled;
	void *packet;
	CDF_STATUS cdf_status;
	uint16_t add_ie_len;
	uint8_t *add_ie;
	uint8_t *wps_ie = NULL;
#if defined WLAN_FEATURE_VOWIFI
	uint8_t power_caps = false;
#endif
	uint8_t tx_flag = 0;
	uint8_t sme_sessionid = 0;
	bool vht_enabled = false;
	tDot11fIEExtCap extr_ext_cap;
	bool extr_ext_flag = true;
	tpSirMacMgmtHdr mac_hdr;

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

	sme_sessionid = pe_session->smeSessionId;

	/* check this early to avoid unncessary operation */
	if (NULL == pe_session->pLimJoinReq) {
		lim_log(mac_ctx, LOGE, FL("pe_session->pLimJoinReq is NULL"));
		return;
	}
	add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
	add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;

	frm = cdf_mem_malloc(sizeof(tDot11fAssocRequest));
	if (NULL == frm) {
		lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
		return;
	}

	cdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);

	if (add_ie_len) {
		cdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
			    0);
		sir_status = lim_strip_extcap_update_struct(mac_ctx,
					add_ie, &add_ie_len, &extr_ext_cap);
		if (eSIR_SUCCESS != sir_status) {
			extr_ext_flag = false;
			lim_log(mac_ctx, LOG1,
			    FL("Unable to Stripoff ExtCap IE from Assoc Req"));
		} else {
			struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
							extr_ext_cap.bytes;

			if (p_ext_cap->interworking_service)
				p_ext_cap->qos_map = 1;
			else {
			/*
			 * No need to merge the EXT Cap from Supplicant
			 * if interworkingService is not set, as currently
			 * driver is only interested in interworkingService
			 * capability from supplicant. if in future any other
			 * EXT Cap info is required from supplicant
			 * it needs to be handled here.
			 */
				extr_ext_flag = false;
			}
		}
	} else {
		lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req"));
		extr_ext_flag = false;
	}

	caps = mlm_assoc_req->capabilityInfo;
#if defined(FEATURE_WLAN_WAPI)
	/*
	 * According to WAPI standard:
	 * 7.3.1.4 Capability Information field
	 * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
	 * in transmitted Association or Reassociation management frames.
	 * APs ignore the Privacy subfield within received Association and
	 * Reassociation management frames.
	 */
	if (pe_session->encryptType == eSIR_ED_WPI)
		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
#endif
	swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);

	frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
	populate_dot11f_ssid2(mac_ctx, &frm->SSID);
	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
		&frm->SuppRates, pe_session);

	qos_enabled = (pe_session->limQosEnabled) &&
		      SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);

	wme_enabled = (pe_session->limWmeEnabled) &&
		      LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);

	/* We prefer .11e asociations: */
	if (qos_enabled)
		wme_enabled = false;

	wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
		      LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);

	if (pe_session->lim11hEnable &&
	    pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
#if defined WLAN_FEATURE_VOWIFI
		power_caps = true;

		populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
			LIM_ASSOC, pe_session);
#endif
		populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
			LIM_ASSOC, pe_session);

	}
#if defined WLAN_FEATURE_VOWIFI
	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
		if (power_caps == false) {
			power_caps = true;
			populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
				LIM_ASSOC, pe_session);
		}
	}
#endif

	if (qos_enabled)
		populate_dot11f_qos_caps_station(mac_ctx, &frm->QOSCapsStation);

	populate_dot11f_ext_supp_rates(mac_ctx,
		POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
		pe_session);

#if defined WLAN_FEATURE_VOWIFI
	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
		populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
			pe_session);
#endif
	/*
	 * The join request *should* contain zero or one of the WPA and RSN
	 * IEs.  The payload send along with the request is a
	 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
	 *     typedef struct sSirRSNie
	 *     {
	 *         uint16_t       length;
	 *         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
	 *     } tSirRSNie, *tpSirRSNie;
	 * So, we should be able to make the following two calls harmlessly,
	 * since they do nothing if they don't find the given IE in the
	 * bytestream with which they're provided.
	 * The net effect of this will be to faithfully transmit whatever
	 * security IE is in the join request.
	 * However, if we're associating for the purpose of WPS
	 * enrollment, and we've been configured to indicate that by
	 * eliding the WPA or RSN IE, we just skip this:
	 */
	if (add_ie_len && add_ie)
		wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);

	if (NULL == wps_ie) {
		populate_dot11f_rsn_opaque(mac_ctx,
			&(pe_session->pLimJoinReq->rsnIE),
			&frm->RSNOpaque);
		populate_dot11f_wpa_opaque(mac_ctx,
			&(pe_session->pLimJoinReq->rsnIE),
			&frm->WPAOpaque);
#if defined(FEATURE_WLAN_WAPI)
		populate_dot11f_wapi_opaque(mac_ctx,
			&(pe_session->pLimJoinReq->rsnIE),
			&frm->WAPIOpaque);
#endif /* defined(FEATURE_WLAN_WAPI) */
	}
	/* include WME EDCA IE as well */
	if (wme_enabled) {
		populate_dot11f_wmm_info_station_per_session(mac_ctx,
			pe_session, &frm->WMMInfoStation);

		if (wsm_enabled)
			populate_dot11f_wmm_caps(&frm->WMMCaps);
	}

	/*
	 * Populate HT IEs, when operating in 11n and
	 * when AP is also operating in 11n mode
	 */
	if (pe_session->htCapability &&
	    mac_ctx->lim.htCapabilityPresentInBeacon) {
		lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
	}
#ifdef WLAN_FEATURE_11AC
	if (pe_session->vhtCapability &&
	    pe_session->vhtCapabilityPresentInBeacon) {
		lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
		vht_enabled = true;
	}
	if (!vht_enabled &&
			pe_session->is_vendor_specific_vhtcaps) {
		lim_log(mac_ctx, LOG1,
			FL("Populate Vendor VHT IEs in Assoc Request"));
		frm->vendor2_ie.present = 1;
		frm->vendor2_ie.type =
			pe_session->vendor_specific_vht_ie_type;
		frm->vendor2_ie.sub_type =
			pe_session->vendor_specific_vht_ie_sub_type;

		frm->vendor2_ie.VHTCaps.present = 1;
		populate_dot11f_vht_caps(mac_ctx, pe_session,
				&frm->vendor2_ie.VHTCaps);
		vht_enabled = true;
	}

#endif

	populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);

#if defined WLAN_FEATURE_VOWIFI_11R
	if (pe_session->pLimJoinReq->is11Rconnection) {
#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
		tSirBssDescription *bssdescr;

		bssdescr = &pe_session->pLimJoinReq->bssDescription;
		lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
			(unsigned int) bssdescr->mdie[0],
			(unsigned int) bssdescr->mdie[1],
			(unsigned int) bssdescr->mdie[2]);
#endif
		populate_mdie(mac_ctx, &frm->MobilityDomain,
			pe_session->pLimJoinReq->bssDescription.mdie);
	} else {
		/* No 11r IEs dont send any MDIE */
		lim_log(mac_ctx, LOG1, FL("MDIE not present"));
	}
#endif

#ifdef FEATURE_WLAN_ESE
	/*
	 * ESE Version IE will be included in association request
	 * when ESE is enabled on DUT through ini and it is also
	 * advertised by the peer AP to which we are trying to
	 * associate to.
	 */
	if (pe_session->is_ese_version_ie_present &&
		mac_ctx->roam.configParam.isEseIniFeatureEnabled)
		populate_dot11f_ese_version(&frm->ESEVersion);
	/* For ESE Associations fill the ESE IEs */
	if (pe_session->isESEconnection &&
	    pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
#ifndef FEATURE_DISABLE_RM
		populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
#endif
	}
#endif

	status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGP,
			FL("Association Request packet size failure(0x%08x)."),
			status);
		/* We'll fall back on the worst case scenario: */
		payload = sizeof(tDot11fAssocRequest);
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Association request packet size warning (0x%08x)."),
			status);
	}

	bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;

	cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
				(void **)&packet);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
			bytes);

		pe_session->limMlmState = pe_session->limPrevMlmState;
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
				 pe_session->peSessionId,
				 pe_session->limMlmState));

		/* Update PE session id */
		assoc_cnf.sessionId = pe_session->peSessionId;

		assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;

		cds_packet_free((void *)packet);

		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
			(uint32_t *) &assoc_cnf);

		cdf_mem_free(frm);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(frame, bytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
		pe_session->selfMacAddr);
	/* merge the ExtCap struct */
	if (extr_ext_flag)
		lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
	/* That done, pack the Assoc Request: */
	status = dot11f_pack_assoc_request(mac_ctx, frm,
			frame + sizeof(tSirMacMgmtHdr), payload, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE,
			FL("Assoc request pack failure (0x%08x)"), status);
		cds_packet_free((void *)packet);
		cdf_mem_free(frm);
		return;
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Assoc request pack warning (0x%08x)"), status);
	}

	lim_log(mac_ctx, LOG1,
		FL("*** Sending Association Request length %d to "), bytes);
	if (pe_session->assocReq != NULL) {
		cdf_mem_free(pe_session->assocReq);
		pe_session->assocReq = NULL;
	}

	if (add_ie_len) {
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     add_ie, add_ie_len);
		payload += add_ie_len;
	}

	pe_session->assocReq = cdf_mem_malloc(payload);
	if (NULL == pe_session->assocReq) {
		lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
	} else {
		/*
		 * Store the Assoc request. This is sent to csr/hdd in
		 * join cnf response.
		 */
		cdf_mem_copy(pe_session->assocReq,
			     frame + sizeof(tSirMacMgmtHdr), payload);
		pe_session->assocReqLen = payload;
	}

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
	    || (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
	    || (pe_session->pePersona == CDF_P2P_GO_MODE)
	    )
		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;

	if (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
		tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;

#ifdef FEATURE_WLAN_DIAG_SUPPORT
	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
			      pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
#endif
	mac_hdr = (tpSirMacMgmtHdr) frame;
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 pe_session->peSessionId, mac_hdr->fc.subType));
	cdf_status =
		wma_tx_frame(mac_ctx, packet,
			   (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
	MTRACE(cdf_trace
		       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       pe_session->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGE,
			FL("Failed to send Association Request (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		cdf_mem_free(frm);
		return;
	}
	/* Free up buffer allocated for mlm_assoc_req */
	cdf_mem_free(mlm_assoc_req);
	mlm_assoc_req = NULL;
	cdf_mem_free(frm);
	return;
}

#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
/**
 * lim_send_reassoc_req_with_ft_ies_mgmt_frame() - Send Reassoc Req with FTIEs.
 *
 * @mac_ctx: Handle to mac context
 * @mlm_reassoc_req: Original reassoc request
 * @pe_session: PE session information
 *
 * It builds a reassoc request with FT IEs and sends it to AP through WMA.
 * Then it creates assoc request and stores it for sending after join
 * confirmation.
 *
 * Return: void
 */

void
lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
	tLimMlmReassocReq *mlm_reassoc_req,
	tpPESession pe_session)
{
	static tDot11fReAssocRequest frm;
	uint16_t caps;
	uint8_t *frame;
	uint32_t bytes, payload, status;
	uint8_t qos_enabled, wme_enabled, wsm_enabled;
	void *packet;
	CDF_STATUS cdf_status;
#if defined WLAN_FEATURE_VOWIFI
	uint8_t power_caps_populated = false;
#endif
	uint16_t ft_ies_length = 0;
	uint8_t *body;
	uint16_t add_ie_len;
	uint8_t *add_ie;
#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
	uint8_t *wps_ie = NULL;
#endif
	uint8_t tx_flag = 0;
	uint8_t sme_sessionid = 0;
	bool vht_enabled = false;
	tpSirMacMgmtHdr mac_hdr;
	tftSMEContext *ft_sme_context;

	if (NULL == pe_session)
		return;

	sme_sessionid = pe_session->smeSessionId;

	/* check this early to avoid unncessary operation */
	if (NULL == pe_session->pLimReAssocReq)
		return;

	add_ie_len = pe_session->pLimReAssocReq->addIEAssoc.length;
	add_ie = pe_session->pLimReAssocReq->addIEAssoc.addIEdata;
	lim_log(mac_ctx, LOG1,
		FL("called in state (%d)."), pe_session->limMlmState);

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	caps = mlm_reassoc_req->capabilityInfo;
#if defined(FEATURE_WLAN_WAPI)
	/*
	 * According to WAPI standard:
	 * 7.3.1.4 Capability Information field
	 * In WAPI, non-AP STAs within an ESS set the Privacy subfield
	 * to 0 in transmitted Association or Reassociation management
	 * frames. APs ignore the Privacy subfield within received
	 * Association and Reassociation management frames.
	 */
	if (pe_session->encryptType == eSIR_ED_WPI)
		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
#endif
	swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);

	frm.ListenInterval.interval = mlm_reassoc_req->listenInterval;

	/*
	 * Get the old bssid of the older AP.
	 * The previous ap bssid is stored in the FT Session
	 * while creating the PE FT Session for reassociation.
	 */
	cdf_mem_copy((uint8_t *)frm.CurrentAPAddress.mac,
			pe_session->prev_ap_bssid, sizeof(tSirMacAddr));

	populate_dot11f_ssid2(mac_ctx, &frm.SSID);
	populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
		&frm.SuppRates, pe_session);

	qos_enabled = (pe_session->limQosEnabled) &&
		      SIR_MAC_GET_QOS(pe_session->limReassocBssCaps);

	wme_enabled = (pe_session->limWmeEnabled) &&
		      LIM_BSS_CAPS_GET(WME, pe_session->limReassocBssQosCaps);

	wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
		      LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);

	if (pe_session->lim11hEnable &&
	    pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
#if defined WLAN_FEATURE_VOWIFI
		power_caps_populated = true;

		populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
					   LIM_REASSOC, pe_session);
		populate_dot11f_supp_channels(mac_ctx, &frm.SuppChannels,
			LIM_REASSOC, pe_session);
#endif
	}
#if defined WLAN_FEATURE_VOWIFI
	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
		if (power_caps_populated == false) {
			power_caps_populated = true;
			populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
				LIM_REASSOC, pe_session);
		}
	}
#endif

	if (qos_enabled)
		populate_dot11f_qos_caps_station(mac_ctx, &frm.QOSCapsStation);

	populate_dot11f_ext_supp_rates(mac_ctx,
		POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates,
		pe_session);

#if defined WLAN_FEATURE_VOWIFI
	if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(pe_session->limReassocBssCaps)) {
		populate_dot11f_rrm_ie(mac_ctx, &frm.RRMEnabledCap, pe_session);
	}
#endif

	/*
	 * Ideally this should be enabled for 11r also. But 11r does
	 * not follow the usual norm of using the Opaque object
	 * for rsnie and fties. Instead we just add the rsnie and fties
	 * at the end of the pack routine for 11r.
	 * This should ideally! be fixed.
	 */
#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
	/*
	 * The join request *should* contain zero or one of the WPA and RSN
	 * IEs.  The payload send along with the request is a
	 * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
	 *
	 *     typedef struct sSirRSNie
	 *     {
	 *         uint16_t       length;
	 *         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
	 *     } tSirRSNie, *tpSirRSNie;
	 *
	 * So, we should be able to make the following two calls harmlessly,
	 * since they do nothing if they don't find the given IE in the
	 * bytestream with which they're provided.
	 *
	 * The net effect of this will be to faithfully transmit whatever
	 * security IE is in the join request.

	 * However, if we're associating for the purpose of WPS
	 * enrollment, and we've been configured to indicate that by
	 * eliding the WPA or RSN IE, we just skip this:
	 */
	if (!pe_session->is11Rconnection) {
		if (add_ie_len && add_ie)
			wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
		if (NULL == wps_ie) {
			populate_dot11f_rsn_opaque(mac_ctx,
				&(pe_session->pLimReAssocReq->rsnIE),
				&frm.RSNOpaque);
			populate_dot11f_wpa_opaque(mac_ctx,
				&(pe_session->pLimReAssocReq->rsnIE),
				&frm.WPAOpaque);
		}
#ifdef FEATURE_WLAN_ESE
		if (pe_session->pLimReAssocReq->cckmIE.length) {
			populate_dot11f_ese_cckm_opaque(mac_ctx,
				&(pe_session->pLimReAssocReq->cckmIE),
				&frm.ESECckmOpaque);
		}
#endif
	}
#ifdef FEATURE_WLAN_ESE
	/*
	 * ESE Version IE will be included in re-association request
	 * when ESE is enabled on DUT through ini and it is also
	 * advertised by the peer AP to which we are trying to
	 * associate to.
	 */
	if (pe_session->is_ese_version_ie_present &&
		mac_ctx->roam.configParam.isEseIniFeatureEnabled)
		populate_dot11f_ese_version(&frm.ESEVersion);
	/* For ESE Associations fill the ESE IEs */
	if (pe_session->isESEconnection &&
	    pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
#ifndef FEATURE_DISABLE_RM
		populate_dot11f_ese_rad_mgmt_cap(&frm.ESERadMgmtCap);
#endif
	}
#endif /* FEATURE_WLAN_ESE */
#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */

	/* include WME EDCA IE as well */
	if (wme_enabled) {
		populate_dot11f_wmm_info_station_per_session(mac_ctx,
			pe_session, &frm.WMMInfoStation);
		if (wsm_enabled)
			populate_dot11f_wmm_caps(&frm.WMMCaps);
#ifdef FEATURE_WLAN_ESE
		if (pe_session->isESEconnection) {
			uint32_t phymode;
			uint8_t rate;

			populate_dot11f_re_assoc_tspec(mac_ctx, &frm,
				pe_session);

			/*
			 * Populate the TSRS IE if TSPEC is included in
			 * the reassoc request
			 */
			lim_get_phy_mode(mac_ctx, &phymode, pe_session);
			if (phymode == WNI_CFG_PHY_MODE_11G ||
			    phymode == WNI_CFG_PHY_MODE_11A)
				rate = TSRS_11AG_RATE_6MBPS;
			else
				rate = TSRS_11B_RATE_5_5MBPS;

			if (pe_session->pLimReAssocReq->eseTspecInfo.
			    numTspecs) {
				tSirMacESETSRSIE tsrs_ie;

				tsrs_ie.tsid = 0;
				tsrs_ie.rates[0] = rate;
				populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
					&frm.ESETrafStrmRateSet,
					sizeof(uint8_t));
			}
		}
#endif
	}

	ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
	if (pe_session->htCapability &&
	    mac_ctx->lim.htCapabilityPresentInBeacon) {
		populate_dot11f_ht_caps(mac_ctx, pe_session, &frm.HTCaps);
	}
#if defined WLAN_FEATURE_VOWIFI_11R
	if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
	    (ft_sme_context->addMDIE == true)
#if defined FEATURE_WLAN_ESE
	    && !pe_session->isESEconnection
#endif
	    ) {
		populate_mdie(mac_ctx, &frm.MobilityDomain,
			pe_session->pLimReAssocReq->bssDescription.mdie);
	}
#endif

#ifdef WLAN_FEATURE_11AC
	if (pe_session->vhtCapability &&
	    pe_session->vhtCapabilityPresentInBeacon) {
		lim_log(mac_ctx, LOG1,
			FL("Populate VHT IEs in Re-Assoc Request"));
		populate_dot11f_vht_caps(mac_ctx, pe_session, &frm.VHTCaps);
		vht_enabled = true;
		populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm.ExtCap,
			pe_session);
	}
	if (!vht_enabled &&
			pe_session->is_vendor_specific_vhtcaps) {
		lim_log(mac_ctx, LOG1,
			FL("Populate Vendor VHT IEs in Re-Assoc Request"));
		frm.vendor2_ie.present = 1;
		frm.vendor2_ie.type =
			pe_session->vendor_specific_vht_ie_type;
		frm.vendor2_ie.sub_type =
			pe_session->vendor_specific_vht_ie_sub_type;
		frm.vendor2_ie.VHTCaps.present = 1;
		populate_dot11f_vht_caps(mac_ctx, pe_session,
				&frm.vendor2_ie.VHTCaps);
		vht_enabled = true;
	}
#endif

	status = dot11f_get_packed_re_assoc_request_size(mac_ctx, &frm,
			&payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGP,
			FL("Failure in size calculation (0x%08x)."), status);
		/* We'll fall back on the worst case scenario: */
		payload = sizeof(tDot11fReAssocRequest);
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW,
			FL("Warnings in size calculation(0x%08x)."), status);
	}

	bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;

#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
	lim_log(mac_ctx, LOG1, FL("FT IE Reassoc Req (%d)."),
		ft_sme_context->reassoc_ft_ies_length);
#endif

#if defined WLAN_FEATURE_VOWIFI_11R
	if (pe_session->is11Rconnection)
		ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
#endif

	cdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
				 (void **)&frame, (void **)&packet);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		pe_session->limMlmState = pe_session->limPrevMlmState;
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
				 pe_session->peSessionId,
				 pe_session->limMlmState));
		lim_log(mac_ctx, LOGP, FL("Failed to alloc memory %d"), bytes);
		goto end;
	}
	/* Paranoia: */
	cdf_mem_set(frame, bytes + ft_ies_length, 0);

#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
	lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOG1);
#endif
	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
		pe_session->selfMacAddr);
	mac_hdr = (tpSirMacMgmtHdr) frame;
	/* That done, pack the ReAssoc Request: */
	status = dot11f_pack_re_assoc_request(mac_ctx, &frm, frame +
					       sizeof(tSirMacMgmtHdr),
					       payload, &payload);
	if (DOT11F_FAILED(status)) {
		lim_log(mac_ctx, LOGE, FL("Failure in pack (0x%08x)."), status);
		cds_packet_free((void *)packet);
		goto end;
	} else if (DOT11F_WARNED(status)) {
		lim_log(mac_ctx, LOGW, FL("Warnings in pack (0x%08x)."),
			status);
	}

	lim_log(mac_ctx, LOG3,
		       FL("*** Sending Re-Assoc Request length %d %d to "),
		       bytes, payload);

	if (pe_session->assocReq != NULL) {
		cdf_mem_free(pe_session->assocReq);
		pe_session->assocReq = NULL;
	}

	if (add_ie_len) {
		cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
			     add_ie, add_ie_len);
		payload += add_ie_len;
	}

	pe_session->assocReq = cdf_mem_malloc(payload);
	if (NULL == pe_session->assocReq) {
		lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
	} else {
		/*
		 * Store the Assoc request. This is sent to csr/hdd in
		 * join cnf response.
		 */
		cdf_mem_copy(pe_session->assocReq,
			     frame + sizeof(tSirMacMgmtHdr), payload);
		pe_session->assocReqLen = payload;
	}

	if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
		int i = 0;

		body = frame + bytes;
		for (i = 0; i < ft_ies_length; i++) {
			*body = ft_sme_context->reassoc_ft_ies[i];
			body++;
		}
	}
#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
	PELOGE(lim_log(mac_ctx, LOG1, FL("Re-assoc Req Frame is: "));
	       sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG1,
			    (uint8_t *) frame, (bytes + ft_ies_length));
	       )
#endif
	if ((SIR_BAND_5_GHZ ==
	     lim_get_rf_band(pe_session->currentOperChannel)) ||
	    (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (pe_session->pePersona == CDF_P2P_GO_MODE)) {
		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	if (NULL != pe_session->assocReq) {
		cdf_mem_free(pe_session->assocReq);
		pe_session->assocReq = NULL;
	}

	pe_session->assocReq = cdf_mem_malloc(ft_ies_length);
	if (NULL == pe_session->assocReq) {
		lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
		pe_session->assocReqLen = 0;
	} else {
		/*
		 * Store the Assoc request. This is sent to csr/hdd in
		 * join cnf response.
		 */
		cdf_mem_copy(pe_session->assocReq,
			     ft_sme_context->reassoc_ft_ies, (ft_ies_length));
		pe_session->assocReqLen = (ft_ies_length);
	}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
			      pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
#endif
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 pe_session->peSessionId, mac_hdr->fc.subType));
	cdf_status = wma_tx_frame(mac_ctx, packet,
				(uint16_t) (bytes + ft_ies_length),
				TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
				lim_tx_complete, frame, tx_flag, sme_sessionid,
				0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       pe_session->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGE,
			FL("Failed to send Re-Assoc Request (%X)!"),
			cdf_status);
	}

end:
	/* Free up buffer allocated for mlmAssocReq */
	cdf_mem_free(mlm_reassoc_req);
	pe_session->pLimMlmReassocReq = NULL;

}

void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
				      tLimMlmReassocReq *pMlmReassocReq,
				      tpPESession psessionEntry)
{
	tLimMlmReassocCnf mlmReassocCnf;        /* keep sme */
	tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
	if (NULL == pTmpMlmReassocReq) {
		pTmpMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
		if (NULL == pTmpMlmReassocReq)
			goto end;
		cdf_mem_set(pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0);
		cdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
			     sizeof(tLimMlmReassocReq));
	}
	/* Prepare and send Reassociation request frame */
	/* start reassoc timer. */
	pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
		psessionEntry->peSessionId;
	/* Start reassociation failure timer */
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
			 psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
	if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
	    != TX_SUCCESS) {
		/* Could not start reassoc failure timer. */
		/* Log error */
		lim_log(pMac, LOGP,
			FL("could not start Reassociation failure timer"));
		/* Return Reassoc confirm with */
		/* Resources Unavailable */
		mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
		mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
		goto end;
	}

	lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
						    psessionEntry);
	return;

end:
	/* Free up buffer allocated for reassocReq */
	if (pMlmReassocReq != NULL) {
		cdf_mem_free(pMlmReassocReq);
		pMlmReassocReq = NULL;
	}
	if (pTmpMlmReassocReq != NULL) {
		cdf_mem_free(pTmpMlmReassocReq);
		pTmpMlmReassocReq = NULL;
	}
	mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
	mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
	/* Update PE sessio Id */
	mlmReassocCnf.sessionId = psessionEntry->peSessionId;

	lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
			     (uint32_t *) &mlmReassocCnf);
}

#endif /* WLAN_FEATURE_VOWIFI_11R */

void
lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
				tLimMlmReassocReq *pMlmReassocReq,
				tpPESession psessionEntry)
{
	static tDot11fReAssocRequest frm;
	uint16_t caps;
	uint8_t *pFrame;
	uint32_t nBytes, nPayload, nStatus;
	uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint16_t nAddIELen;
	uint8_t *pAddIE;
	uint8_t *wpsIe = NULL;
	uint8_t txFlag = 0;
#if defined WLAN_FEATURE_VOWIFI
	uint8_t PowerCapsPopulated = false;
#endif
	uint8_t smeSessionId = 0;
	bool isVHTEnabled = false;
	tpSirMacMgmtHdr pMacHdr;

	if (NULL == psessionEntry) {
		return;
	}

	smeSessionId = psessionEntry->smeSessionId;

	/* check this early to avoid unncessary operation */
	if (NULL == psessionEntry->pLimReAssocReq) {
		return;
	}
	nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
	pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	caps = pMlmReassocReq->capabilityInfo;
#if defined(FEATURE_WLAN_WAPI)
	/* CR: 262463 :
	   According to WAPI standard:
	   7.3.1.4 Capability Information field
	   In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
	   Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
	   Reassociation management frames. */
	if (psessionEntry->encryptType == eSIR_ED_WPI)
		((tSirMacCapabilityInfo *) &caps)->privacy = 0;
#endif
	swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);

	frm.ListenInterval.interval = pMlmReassocReq->listenInterval;

	cdf_mem_copy((uint8_t *) frm.CurrentAPAddress.mac,
		     (uint8_t *) psessionEntry->bssId, 6);

	populate_dot11f_ssid2(pMac, &frm.SSID);
	populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
				   &frm.SuppRates, psessionEntry);

	fQosEnabled = (psessionEntry->limQosEnabled) &&
		      SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);

	fWmeEnabled = (psessionEntry->limWmeEnabled) &&
		      LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);

	fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
		      LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);

	if (psessionEntry->lim11hEnable &&
	    psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
#if defined WLAN_FEATURE_VOWIFI
		PowerCapsPopulated = true;
		populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
					   psessionEntry);
		populate_dot11f_supp_channels(pMac, &frm.SuppChannels, LIM_REASSOC,
					      psessionEntry);
#endif
	}
#if defined WLAN_FEATURE_VOWIFI
	if (pMac->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
		if (PowerCapsPopulated == false) {
			PowerCapsPopulated = true;
			populate_dot11f_power_caps(pMac, &frm.PowerCaps,
						   LIM_REASSOC, psessionEntry);
		}
	}
#endif

	if (fQosEnabled)
		populate_dot11f_qos_caps_station(pMac, &frm.QOSCapsStation);

	populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
				       &frm.ExtSuppRates, psessionEntry);

#if defined WLAN_FEATURE_VOWIFI
	if (pMac->rrm.rrmPEContext.rrmEnable &&
	    SIR_MAC_GET_RRM(psessionEntry->limReassocBssCaps)) {
		populate_dot11f_rrm_ie(pMac, &frm.RRMEnabledCap, psessionEntry);
	}
#endif
	/* The join request *should* contain zero or one of the WPA and RSN */
	/* IEs.  The payload send along with the request is a */
	/* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */

	/*     typedef struct sSirRSNie */
	/*     { */
	/*         uint16_t       length; */
	/*         uint8_t        rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
	/*     } tSirRSNie, *tpSirRSNie; */

	/* So, we should be able to make the following two calls harmlessly, */
	/* since they do nothing if they don't find the given IE in the */
	/* bytestream with which they're provided. */

	/* The net effect of this will be to faithfully transmit whatever */
	/* security IE is in the join request. */

	/**However*, if we're associating for the purpose of WPS */
	/* enrollment, and we've been configured to indicate that by */
	/* eliding the WPA or RSN IE, we just skip this: */
	if (nAddIELen && pAddIE) {
		wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
	}
	if (NULL == wpsIe) {
		populate_dot11f_rsn_opaque(pMac,
					   &(psessionEntry->pLimReAssocReq->rsnIE),
					   &frm.RSNOpaque);
		populate_dot11f_wpa_opaque(pMac,
					   &(psessionEntry->pLimReAssocReq->rsnIE),
					   &frm.WPAOpaque);
#if defined(FEATURE_WLAN_WAPI)
		populate_dot11f_wapi_opaque(pMac,
					    &(psessionEntry->pLimReAssocReq->
					      rsnIE), &frm.WAPIOpaque);
#endif /* defined(FEATURE_WLAN_WAPI) */
	}
	/* include WME EDCA IE as well */
	if (fWmeEnabled) {
		populate_dot11f_wmm_info_station_per_session(pMac,
							     psessionEntry,
							     &frm.WMMInfoStation);

		if (fWsmEnabled)
			populate_dot11f_wmm_caps(&frm.WMMCaps);
	}

	if (psessionEntry->htCapability &&
	    pMac->lim.htCapabilityPresentInBeacon) {
		populate_dot11f_ht_caps(pMac, psessionEntry, &frm.HTCaps);
	}
#ifdef WLAN_FEATURE_11AC
	if (psessionEntry->vhtCapability &&
	    psessionEntry->vhtCapabilityPresentInBeacon) {
		lim_log(pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request"));
		populate_dot11f_vht_caps(pMac, psessionEntry, &frm.VHTCaps);
		isVHTEnabled = true;
	}
#endif

	populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry);

	nStatus = dot11f_get_packed_re_assoc_request_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Re-Association Request (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fReAssocRequest);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Re-Association Re "
				       "quest(0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;

	cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
				 psessionEntry->peSessionId,
				 psessionEntry->limMlmState));
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a Re-As"
			   "sociation Request."), nBytes);
		goto end;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
		psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	/* That done, pack the Probe Request: */
	nStatus = dot11f_pack_re_assoc_request(pMac, &frm, pFrame +
					       sizeof(tSirMacMgmtHdr),
					       nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE, FL("Failed to pack a Re-Association Reque"
				       "st (0x%08x)."), nStatus);
		cds_packet_free((void *)pPacket);
		goto end;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a R"
				       "e-Association Request (0x%08x)."),
			nStatus);
	}

	PELOG1(lim_log
		       (pMac, LOG1,
		       FL("*** Sending Re-Association Request length %d" "to "),
		       nBytes);
	       )

	if (psessionEntry->assocReq != NULL) {
		cdf_mem_free(psessionEntry->assocReq);
		psessionEntry->assocReq = NULL;
	}

	if (nAddIELen) {
		cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
			     pAddIE, nAddIELen);
		nPayload += nAddIELen;
	}

	psessionEntry->assocReq = cdf_mem_malloc(nPayload);
	if (NULL == psessionEntry->assocReq) {
		PELOGE(lim_log
			       (pMac, LOGE,
			       FL("Unable to allocate memory to store assoc request"));
		       )
	} else {
		/* Store the Assoc request. This is sent to csr/hdd in join cnf response. */
		cdf_mem_copy(psessionEntry->assocReq,
			     pFrame + sizeof(tSirMacMgmtHdr), nPayload);
		psessionEntry->assocReqLen = nPayload;
	}

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	if (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) {
		txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
	}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
	lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
			      psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
#endif
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status =
		wma_tx_frame(pMac, pPacket,
			   (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
	MTRACE(cdf_trace
		       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       psessionEntry->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send Re-Association Request (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
	}

end:
	/* Free up buffer allocated for mlmAssocReq */
	cdf_mem_free(pMlmReassocReq);
	psessionEntry->pLimMlmReassocReq = NULL;

} /* lim_send_reassoc_req_mgmt_frame */

/**
 * lim_send_auth_mgmt_frame() - Send an Authentication frame
 *
 * @mac_ctx: Pointer to Global MAC structure
 * @auth_frame: Pointer to Authentication frame structure
 * @peer_addr: MAC address of destination peer
 * @wep_bit: wep bit in frame control for Authentication frame3
 * @session: PE session information
 *
 * This function is called by lim_process_mlm_messages(). Authentication frame
 * is formatted and sent when this function is called.
 *
 * Return: void
 */

void
lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
			 tpSirMacAuthFrameBody auth_frame,
			 tSirMacAddr peer_addr,
			 uint8_t wep_bit, tpPESession session)
{
	uint8_t *frame, *body;
	uint32_t frame_len = 0, body_len = 0;
	tpSirMacMgmtHdr mac_hdr;
	void *packet;
	CDF_STATUS cdf_status;
	uint8_t tx_flag = 0;
	uint8_t sme_sessionid = 0;
	uint16_t ft_ies_length = 0;

	if (NULL == session) {
		lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
		return;
	}

	sme_sessionid = session->smeSessionId;

	lim_log(mac_ctx, LOG1,
		FL("Sending Auth seq# %d status %d (%d) to " MAC_ADDRESS_STR),
		auth_frame->authTransactionSeqNumber,
		auth_frame->authStatusCode,
		(auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
		MAC_ADDR_ARRAY(peer_addr));

	switch (auth_frame->authTransactionSeqNumber) {
	case SIR_MAC_AUTH_FRAME_1:
		/*
		 * Allocate buffer for Authenticaton frame of size
		 * equal to management frame header length plus 2 bytes
		 * each for auth algorithm number, transaction number
		 * and status code.
		 */

		frame_len = sizeof(tSirMacMgmtHdr) +
			   SIR_MAC_AUTH_CHALLENGE_OFFSET;
		body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;

#if defined WLAN_FEATURE_VOWIFI_11R
		if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
			if (NULL != session->ftPEContext.pFTPreAuthReq &&
			    0 != session->ftPEContext.pFTPreAuthReq->
				ft_ies_length) {
				ft_ies_length = session->ftPEContext.
					pFTPreAuthReq->ft_ies_length;
				frame_len += ft_ies_length;
				lim_log(mac_ctx, LOG3,
					FL("Auth frame, FTIES length added=%d"),
					ft_ies_length);
			} else {
				lim_log(mac_ctx, LOG3,
					FL("Auth frame, Does not contain FTIES!!!"));
				frame_len += (2 + SIR_MDIE_SIZE);
			}
		}
#endif
		break;

	case SIR_MAC_AUTH_FRAME_2:
		if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
		    ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
			(auth_frame->authStatusCode !=
			 eSIR_MAC_SUCCESS_STATUS))) {
			/*
			 * Allocate buffer for Authenticaton frame of size
			 * equal to management frame header length plus
			 * 2 bytes each for auth algorithm number,
			 * transaction number and status code.
			 */

			frame_len = sizeof(tSirMacMgmtHdr) +
				   SIR_MAC_AUTH_CHALLENGE_OFFSET;
			body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
		} else {
			/*
			 * Shared Key algorithm with challenge text
			 * to be sent.
			 *
			 * Allocate buffer for Authenticaton frame of size
			 * equal to management frame header length plus
			 * 2 bytes each for auth algorithm number,
			 * transaction number, status code and 128 bytes
			 * for challenge text.
			 */

			frame_len = sizeof(tSirMacMgmtHdr) +
				   sizeof(tSirMacAuthFrame);
			body_len = sizeof(tSirMacAuthFrameBody);
		}
		break;

	case SIR_MAC_AUTH_FRAME_3:
		if (wep_bit == LIM_WEP_IN_FC) {
			/*
			 * Auth frame3 to be sent with encrypted framebody
			 *
			 * Allocate buffer for Authenticaton frame of size
			 * equal to management frame header length plus 2 bytes
			 * each for auth algorithm number, transaction number,
			 * status code, 128 bytes for challenge text and
			 * 4 bytes each for IV & ICV.
			 */

			frame_len = sizeof(tSirMacMgmtHdr) +
					LIM_ENCR_AUTH_BODY_LEN;
			body_len = LIM_ENCR_AUTH_BODY_LEN;
		} else {

			/*
			 * Auth frame3 to be sent without encrypted framebody
			 *
			 * Allocate buffer for Authenticaton frame of size equal
			 * to management frame header length plus 2 bytes each
			 * for auth algorithm number, transaction number and
			 * status code.
			 */

			frame_len = sizeof(tSirMacMgmtHdr) +
				   SIR_MAC_AUTH_CHALLENGE_OFFSET;
			body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
		}
		break;

	case SIR_MAC_AUTH_FRAME_4:
		/*
		 * Allocate buffer for Authenticaton frame of size equal
		 * to management frame header length plus 2 bytes each
		 * for auth algorithm number, transaction number and
		 * status code.
		 */

		frame_len = sizeof(tSirMacMgmtHdr) +
			   SIR_MAC_AUTH_CHALLENGE_OFFSET;
		body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;

		break;
	} /* switch (auth_frame->authTransactionSeqNumber) */

	cdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
				 (void **)&packet);

	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(mac_ctx, LOGP,
			FL("call to bufAlloc failed for AUTH frame"));
		return;
	}

	cdf_mem_zero(frame, frame_len);

	/* Prepare BD */
	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
	mac_hdr = (tpSirMacMgmtHdr) frame;
	mac_hdr->fc.wep = wep_bit;

	/* Prepare BSSId */
	if (LIM_IS_AP_ROLE(session) ||
	    LIM_IS_BT_AMP_AP_ROLE(session))
		cdf_mem_copy((uint8_t *) mac_hdr->bssId,
			     (uint8_t *) session->bssId,
			     sizeof(tSirMacAddr));

	/* Prepare Authentication frame body */
	body = frame + sizeof(tSirMacMgmtHdr);

	if (wep_bit == LIM_WEP_IN_FC) {
		cdf_mem_copy(body, (uint8_t *) auth_frame, body_len);

		lim_log(mac_ctx, LOG1,
			FL("*** Sending Auth seq# 3 status %d (%d) to"
				MAC_ADDRESS_STR),
			auth_frame->authStatusCode,
			(auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
			MAC_ADDR_ARRAY(mac_hdr->da));

	} else {
		*((uint16_t *) (body)) =
			sir_swap_u16if_needed(auth_frame->authAlgoNumber);
		body += sizeof(uint16_t);
		body_len -= sizeof(uint16_t);

		*((uint16_t *) (body)) =
			sir_swap_u16if_needed(
				auth_frame->authTransactionSeqNumber);
		body += sizeof(uint16_t);
		body_len -= sizeof(uint16_t);

		*((uint16_t *) (body)) =
			sir_swap_u16if_needed(auth_frame->authStatusCode);
		body += sizeof(uint16_t);
		body_len -= sizeof(uint16_t);
		if (body_len <= (sizeof(auth_frame->type) +
				sizeof(auth_frame->length) +
				sizeof(auth_frame->challengeText)))
			cdf_mem_copy(body, (uint8_t *) &auth_frame->type,
				     body_len);

#if defined WLAN_FEATURE_VOWIFI_11R
		if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
		    (auth_frame->authTransactionSeqNumber ==
		     SIR_MAC_AUTH_FRAME_1) &&
		     (session->ftPEContext.pFTPreAuthReq != NULL)) {

			if (ft_ies_length > 0) {
				cdf_mem_copy(body,
					session->ftPEContext.
						pFTPreAuthReq->ft_ies,
					ft_ies_length);
#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
				lim_log(mac_ctx, LOG2,
					FL("Auth1 Frame FTIE is: "));
				sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
					(uint8_t *) body,
					ft_ies_length);
#endif
			} else if (NULL != session->ftPEContext.
					pFTPreAuthReq->pbssDescription) {
				/* MDID attr is 54 */
				*body = SIR_MDIE_ELEMENT_ID;
				body++;
				*body = SIR_MDIE_SIZE;
				body++;
				cdf_mem_copy(body,
					&session->ftPEContext.pFTPreAuthReq->
						pbssDescription->mdie[0],
					SIR_MDIE_SIZE);
			}
		}
#endif

		lim_log(mac_ctx, LOG1,
			FL("*** Sending Auth seq# %d status %d (%d) to "
				MAC_ADDRESS_STR),
			auth_frame->authTransactionSeqNumber,
			auth_frame->authStatusCode,
			(auth_frame->authStatusCode ==
				eSIR_MAC_SUCCESS_STATUS),
			MAC_ADDR_ARRAY(mac_hdr->da));
	}
	sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
	    || (session->pePersona == CDF_P2P_CLIENT_MODE)
	    || (session->pePersona == CDF_P2P_GO_MODE)
#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
	    || ((NULL != session->ftPEContext.pFTPreAuthReq) &&
		(SIR_BAND_5_GHZ ==
		 lim_get_rf_band(session->ftPEContext.pFTPreAuthReq->
				 preAuthchannelNum)))
#endif
	    )
		tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;


	if (session->pePersona == CDF_P2P_CLIENT_MODE)
		tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;


	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 session->peSessionId, mac_hdr->fc.subType));
	/* Queue Authentication frame in high priority WQ */
	cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS, 7, lim_tx_complete,
				frame, tx_flag, sme_sessionid, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 session->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status))
		lim_log(mac_ctx, LOGE,
			FL("*** Could not send Auth frame, retCode=%X ***"),
			cdf_status);

	return;
}

CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
{
	uint16_t aid;
	tpDphHashNode pStaDs;
	tLimMlmDeauthReq *pMlmDeauthReq;
	tLimMlmDeauthCnf mlmDeauthCnf;
	tpPESession psessionEntry;

	pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
	if (pMlmDeauthReq) {
		if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
			lim_deactivate_and_change_timer(pMac,
							eLIM_DEAUTH_ACK_TIMER);
		}

		psessionEntry = pe_find_session_by_session_id(pMac,
				pMlmDeauthReq->sessionId);
		if (psessionEntry == NULL) {
			PELOGE(lim_log(pMac, LOGE,
				       FL
					       ("session does not exist for given sessionId"));
			       )
			mlmDeauthCnf.resultCode =
				eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}

		pStaDs =
			dph_lookup_hash_entry(pMac, pMlmDeauthReq->peerMacAddr, &aid,
					      &psessionEntry->dph.dphHashTable);
		if (pStaDs == NULL) {
			mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}

		/* / Receive path cleanup with dummy packet */
		lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
		lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
		/* / Free up buffer allocated for mlmDeauthReq */
		cdf_mem_free(pMlmDeauthReq);
		pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
	}
	return CDF_STATUS_SUCCESS;
end:
	cdf_mem_copy((uint8_t *) &mlmDeauthCnf.peerMacAddr,
		     (uint8_t *) pMlmDeauthReq->peerMacAddr,
		     sizeof(tSirMacAddr));
	mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
	mlmDeauthCnf.aid = pMlmDeauthReq->aid;
	mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;

	/* Free up buffer allocated */
	/* for mlmDeauthReq */
	cdf_mem_free(pMlmDeauthReq);

	lim_post_sme_message(pMac,
			     LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
	return CDF_STATUS_SUCCESS;
}

/**
 * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
 *
 * @mac_ctx: Handle to MAC context
 *
 * Sends disassoc confirmation to SME. Removes disassoc request stored
 * in lim.
 *
 * Return: CDF_STATUS_SUCCESS
 */

CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
{
	uint16_t aid;
	tpDphHashNode sta_ds;
	tLimMlmDisassocCnf disassoc_cnf;
	tpPESession pe_session;
	tLimMlmDisassocReq *disassoc_req;

	disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
	if (disassoc_req) {
		if (tx_timer_running(
			&mac_ctx->lim.limTimers.gLimDisassocAckTimer))
			lim_deactivate_and_change_timer(mac_ctx,
				eLIM_DISASSOC_ACK_TIMER);

		pe_session = pe_find_session_by_session_id(
					mac_ctx, disassoc_req->sessionId);
		if (pe_session == NULL) {
			lim_log(mac_ctx, LOGE,
				       FL("No session for given sessionId"));
			disassoc_cnf.resultCode =
				eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}

		sta_ds = dph_lookup_hash_entry(mac_ctx,
				disassoc_req->peerMacAddr, &aid,
				&pe_session->dph.dphHashTable);
		if (sta_ds == NULL) {
			lim_log(mac_ctx, LOGE, FL("StaDs Null"));
			disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
			goto end;
		}
		/* Receive path cleanup with dummy packet */
		if (eSIR_SUCCESS !=
		    lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
			disassoc_cnf.resultCode =
				eSIR_SME_RESOURCES_UNAVAILABLE;
			lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
			goto end;
		}
#ifdef WLAN_FEATURE_VOWIFI_11R
		if (LIM_IS_STA_ROLE(pe_session) && (
#ifdef FEATURE_WLAN_ESE
			    (pe_session->isESEconnection) ||
#endif
#ifdef FEATURE_WLAN_LFR
			    (pe_session->isFastRoamIniFeatureEnabled) ||
#endif
			    (pe_session->is11Rconnection)) &&
			    (disassoc_req->reasonCode !=
				eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
			lim_log(mac_ctx, LOGE,
				FL("FT Preauth Session (%p,%d) Clean up"),
				pe_session, pe_session->peSessionId);

#if defined WLAN_FEATURE_VOWIFI_11R
			/* Delete FT session if there exists one */
			lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
#endif
		} else {
			lim_log(mac_ctx, LOGE,
				FL("No FT Preauth Session Clean up in role %d"
#ifdef FEATURE_WLAN_ESE
				" isESE %d"
#endif
#ifdef FEATURE_WLAN_LFR
				" isLFR %d"
#endif
				" is11r %d reason %d"),
				GET_LIM_SYSTEM_ROLE(pe_session),
#ifdef FEATURE_WLAN_ESE
				pe_session->isESEconnection,
#endif
#ifdef FEATURE_WLAN_LFR
				pe_session->isFastRoamIniFeatureEnabled,
#endif
				pe_session->is11Rconnection,
				disassoc_req->reasonCode);
		}
#endif
		/* Free up buffer allocated for mlmDisassocReq */
		cdf_mem_free(disassoc_req);
		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
		return CDF_STATUS_SUCCESS;
	} else {
		return CDF_STATUS_SUCCESS;
	}
end:
	cdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
		     (uint8_t *) disassoc_req->peerMacAddr,
		     sizeof(tSirMacAddr));
	disassoc_cnf.aid = disassoc_req->aid;
	disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;

	/* Update PE session ID */
	disassoc_cnf.sessionId = disassoc_req->sessionId;

	if (disassoc_req != NULL) {
		/* / Free up buffer allocated for mlmDisassocReq */
		cdf_mem_free(disassoc_req);
		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
	}

	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
		(uint32_t *) &disassoc_cnf);
	return CDF_STATUS_SUCCESS;
}

CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
					uint32_t txCompleteSuccess)
{
	return lim_send_disassoc_cnf(pMac);
}

CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
				      uint32_t txCompleteSuccess)
{
	return lim_send_deauth_cnf(pMac);
}

/**
 * \brief This function is called to send Disassociate frame.
 *
 *
 * \param pMac Pointer to Global MAC structure
 *
 * \param nReason Indicates the reason that need to be sent in
 * Disassociation frame
 *
 * \param peerMacAddr MAC address of the STA to which Disassociation frame is
 * sent
 *
 *
 */

void
lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
			     uint16_t nReason,
			     tSirMacAddr peer,
			     tpPESession psessionEntry, bool waitForAck)
{
	tDot11fDisassociation frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint32_t val = 0;
	uint8_t smeSessionId = 0;
	if (NULL == psessionEntry) {
		return;
	}

	/*
	 * In case when cac timer is running for this SAP session then
	 * avoid sending disassoc out. It is violation of dfs specification.
	 */
	if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
	    (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
			  FL
				  ("CAC timer is running, drop disassoc from going out"));
		return;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Reason.code = nReason;

	nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Disassociation (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fDisassociation);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Disassociation "
				       "(0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
				       "association."), nBytes);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	/* Prepare the BSSID */
	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
					     sizeof(tSirMacMgmtHdr),
					     nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a Disassociation (0x%08x)."),
			nStatus);
		cds_packet_free((void *)pPacket);
		return;         /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a D"
				       "isassociation (0x%08x)."), nStatus);
	}

	lim_log(pMac, LOG1,
		FL("***Sessionid %d Sending Disassociation frame with "
		   "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
		   MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
		waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
		MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
		txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
	}

	if (waitForAck) {
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
				 psessionEntry->peSessionId,
				 pMacHdr->fc.subType));
		/* Queue Disassociation frame in high priority WQ */
		/* get the duration from the request */
		cdf_status =
			wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
					 TXRX_FRM_802_11_MGMT,
					 ANI_TXDIR_TODS, 7, lim_tx_complete,
					 pFrame, lim_disassoc_tx_complete_cnf,
					 txFlag, smeSessionId, false, 0);
		MTRACE(cdf_trace
			       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			       psessionEntry->peSessionId, cdf_status));

		val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);

		if (tx_timer_change
			    (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
		    != TX_SUCCESS) {
			lim_log(pMac, LOGP,
				FL("Unable to change Disassoc ack Timer val"));
			return;
		} else if (TX_SUCCESS !=
			   tx_timer_activate(&pMac->lim.limTimers.
					     gLimDisassocAckTimer)) {
			lim_log(pMac, LOGP,
				FL("Unable to activate Disassoc ack Timer"));
			lim_deactivate_and_change_timer(pMac,
							eLIM_DISASSOC_ACK_TIMER);
			return;
		}
	} else {
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
				 psessionEntry->peSessionId,
				 pMacHdr->fc.subType));
		/* Queue Disassociation frame in high priority WQ */
		cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
					TXRX_FRM_802_11_MGMT,
					ANI_TXDIR_TODS,
					7,
					lim_tx_complete, pFrame, txFlag,
					smeSessionId, 0);
		MTRACE(cdf_trace
			       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			       psessionEntry->peSessionId, cdf_status));
		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
			lim_log(pMac, LOGE,
				FL("Failed to send Disassociation (%X)!"),
				cdf_status);
			/* Pkt will be freed up by the callback */
		}
	}
} /* End lim_send_disassoc_mgmt_frame. */

/**
 * \brief This function is called to send a Deauthenticate frame
 *
 *
 * \param pMac Pointer to global MAC structure
 *
 * \param nReason Indicates the reason that need to be sent in the
 * Deauthenticate frame
 *
 * \param peeer address of the STA to which the frame is to be sent
 *
 *
 */

void
lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
			   uint16_t nReason,
			   tSirMacAddr peer,
			   tpPESession psessionEntry, bool waitForAck)
{
	tDot11fDeAuth frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint32_t val = 0;
#ifdef FEATURE_WLAN_TDLS
	uint16_t aid;
	tpDphHashNode pStaDs;
#endif
	uint8_t smeSessionId = 0;

	if (NULL == psessionEntry) {
		return;
	}

	/*
	 * In case when cac timer is running for this SAP session then
	 * avoid deauth frame out. It is violation of dfs specification.
	 */
	if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
	    (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
			  FL
				  ("CAC timer is running, drop the deauth from going out"));
		return;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Reason.code = nReason;

	nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a De-Authentication (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fDeAuth);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a De-Authentication "
				       "(0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
				       "Authentication."), nBytes);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	/* Prepare the BSSID */
	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
				      sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a DeAuthentication (0x%08x)."),
			nStatus);
		cds_packet_free((void *)pPacket);
		return;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a D"
				       "e-Authentication (0x%08x)."), nStatus);
	}
	lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
			       "reason %u and waitForAck %d to " MAC_ADDRESS_STR
			       " ,From " MAC_ADDRESS_STR),
		psessionEntry->peSessionId, nReason, waitForAck,
		MAC_ADDR_ARRAY(pMacHdr->da),
		MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
		txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
	}
#ifdef FEATURE_WLAN_TDLS
	pStaDs =
		dph_lookup_hash_entry(pMac, peer, &aid,
				      &psessionEntry->dph.dphHashTable);
#endif

	if (waitForAck) {
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
				 psessionEntry->peSessionId,
				 pMacHdr->fc.subType));
		/* Queue Disassociation frame in high priority WQ */
		cdf_status =
			wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
					 TXRX_FRM_802_11_MGMT,
					 ANI_TXDIR_TODS, 7, lim_tx_complete,
					 pFrame, lim_deauth_tx_complete_cnf,
					 txFlag, smeSessionId, false, 0);
		MTRACE(cdf_trace
			       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			       psessionEntry->peSessionId, cdf_status));
		/* Pkt will be freed up by the callback lim_tx_complete */
		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
			lim_log(pMac, LOGE,
				FL("Failed to send De-Authentication (%X)!"),
				cdf_status);

			/* Call lim_process_deauth_ack_timeout which will send
			 * DeauthCnf for this frame
			 */
			lim_process_deauth_ack_timeout(pMac);
			return;
		}

		val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);

		if (tx_timer_change
			    (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
		    != TX_SUCCESS) {
			lim_log(pMac, LOGP,
				FL("Unable to change Deauth ack Timer val"));
			return;
		} else if (TX_SUCCESS !=
			   tx_timer_activate(&pMac->lim.limTimers.
					     gLimDeauthAckTimer)) {
			lim_log(pMac, LOGP,
				FL("Unable to activate Deauth ack Timer"));
			lim_deactivate_and_change_timer(pMac,
							eLIM_DEAUTH_ACK_TIMER);
			return;
		}
	} else {
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
				 psessionEntry->peSessionId,
				 pMacHdr->fc.subType));
#ifdef FEATURE_WLAN_TDLS
		if ((NULL != pStaDs)
		    && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
			/* Queue Disassociation frame in high priority WQ */
			cdf_status =
				wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
					   TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
					   7, lim_tx_complete, pFrame, txFlag,
					   smeSessionId, 0);
		} else {
#endif
		/* Queue Disassociation frame in high priority WQ */
		cdf_status =
			wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
				   7, lim_tx_complete, pFrame, txFlag,
				   smeSessionId, 0);
#ifdef FEATURE_WLAN_TDLS
	}
#endif
		MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
				 psessionEntry->peSessionId, cdf_status));
		if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
			lim_log(pMac, LOGE,
				FL("Failed to send De-Authentication (%X)!"),
				cdf_status);
			/* Pkt will be freed up by the callback */
		}
	}

} /* End lim_send_deauth_mgmt_frame. */

#ifdef ANI_SUPPORT_11H
/**
 * \brief Send a Measurement Report Action frame
 *
 *
 * \param pMac Pointer to the global MAC structure
 *
 * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_meas_report_frame(tpAniSirGlobal pMac,
			   tpSirMacMeasReqActionFrame pMeasReqFrame,
			   tSirMacAddr peer, tpPESession psessionEntry)
{
	tDot11fMeasurementReport frm;
	uint8_t *pFrame;
	tSirRetStatus nSirStatus;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
	frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
	frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;

	switch (pMeasReqFrame->measReqIE.measType) {
	case SIR_MAC_BASIC_MEASUREMENT_TYPE:
		nSirStatus =
			populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
							    &frm.MeasurementReport);
		break;
	case SIR_MAC_CCA_MEASUREMENT_TYPE:
		nSirStatus =
			populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
							    &frm.MeasurementReport);
		break;
	case SIR_MAC_RPI_MEASUREMENT_TYPE:
		nSirStatus =
			populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
							    &frm.MeasurementReport);
		break;
	default:
		lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
				       "dMeasReportFrame."),
			pMeasReqFrame->measReqIE.measType);
		return eSIR_FAILURE;
	}

	if (eSIR_SUCCESS != nSirStatus)
		return eSIR_FAILURE;

	nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Measurement Report (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fMeasurementReport);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Measurement Rep"
				       "ort (0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				 (uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
				       "Authentication."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
						 sizeof(tSirMacMgmtHdr),
						 nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a Measurement Report (0x%08x)."),
			nStatus);
		cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				(void *)pFrame, (void *)pPacket);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a M"
				       "easurement Report (0x%08x)."), nStatus);
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 ((psessionEntry) ? psessionEntry->
			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
	cdf_status =
		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, pFrame, 0, 0);
	MTRACE(cdf_trace
		       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
		       cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a Measurement Report  (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;    /* just allocated... */
	}

	return eSIR_SUCCESS;

} /* End lim_send_meas_report_frame. */

/**
 * \brief Send a TPC Request Action frame
 *
 *
 * \param pMac Pointer to the global MAC datastructure
 *
 * \param peer MAC address to which the frame should be sent
 *
 *
 */

void
lim_send_tpc_request_frame(tpAniSirGlobal pMac,
			   tSirMacAddr peer, tpPESession psessionEntry)
{
	tDot11fTPCRequest frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
	frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
	frm.DialogToken.token = 1;
	frm.TPCRequest.present = 1;

	nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a TPC Request (0x%08x)."), nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fTPCRequest);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a TPC Request (0x"
				       "%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				 (uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
				       " Request."), nBytes);
		return;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
					  sizeof(tSirMacMgmtHdr),
					  nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
			nStatus);
		cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				(void *)pFrame, (void *)pPacket);
		return;         /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a T"
				       "PC Request (0x%08x)."), nStatus);
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 ((psessionEntry) ? psessionEntry->
			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
	cdf_status =
		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, pFrame, 0, 0);
	MTRACE(cdf_trace
		       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
		       cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a TPC Request (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
	}

} /* End lim_send_tpc_request_frame. */

/**
 * \brief Send a TPC Report Action frame
 *
 *
 * \param pMac Pointer to the global MAC datastructure
 *
 * \param pTpcReqFrame Pointer to the received TPC Request
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_tpc_report_frame(tpAniSirGlobal pMac,
			  tpSirMacTpcReqActionFrame pTpcReqFrame,
			  tSirMacAddr peer, tpPESession psessionEntry)
{
	tDot11fTPCReport frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
	frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
	frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;

	frm.TPCReport.tx_power = 0;
	frm.TPCReport.link_margin = 0;
	frm.TPCReport.present = 1;

	nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a TPC Report (0x%08x)."), nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fTPCReport);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a TPC Report (0x"
				       "%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				 (uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
				       " Report."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer);

	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
					 sizeof(tSirMacMgmtHdr),
					 nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
			nStatus);
		cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
				(void *)pFrame, (void *)pPacket);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a T"
				       "PC Report (0x%08x)."), nStatus);
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 ((psessionEntry) ? psessionEntry->
			  peSessionId : NO_SESSION), pMacHdr->fc.subType));
	cdf_status =
		wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
			   TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
			   lim_tx_complete, pFrame, 0, 0);
	MTRACE(cdf_trace
		       (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
		       ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
		       cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a TPC Report (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;    /* just allocated... */
	}

	return eSIR_SUCCESS;

} /* End lim_send_tpc_report_frame. */
#endif /* ANI_SUPPORT_11H */

/**
 * \brief Send a Channel Switch Announcement
 *
 *
 * \param pMac Pointer to the global MAC datastructure
 *
 * \param peer MAC address to which this frame will be sent
 *
 * \param nMode
 *
 * \param nNewChannel
 *
 * \param nCount
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
				   tSirMacAddr peer,
				   uint8_t nMode,
				   uint8_t nNewChannel,
				   uint8_t nCount, tpPESession psessionEntry)
{
	tDot11fChannelSwitch frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;     /* , nCfg; */
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;

	uint8_t smeSessionId = 0;

	if (psessionEntry == NULL) {
		PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
		return eSIR_FAILURE;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
	frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
	frm.ChanSwitchAnn.switchMode = nMode;
	frm.ChanSwitchAnn.newChannel = nNewChannel;
	frm.ChanSwitchAnn.switchCount = nCount;
	frm.ChanSwitchAnn.present = 1;

	nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Channel Switch (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fChannelSwitch);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Channel Switch (0x"
				       "%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
				       " Report."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer,
		psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;
	cdf_mem_copy((uint8_t *) pMacHdr->bssId,
		     (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
					     sizeof(tSirMacMgmtHdr),
					     nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a Channel Switch (0x%08x)."),
			nStatus);
		cds_packet_free((void *)pPacket);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a C"
				       "hannel Switch (0x%08x)."), nStatus);
	}

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a Channel Switch (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;

} /* End lim_send_channel_switch_mgmt_frame. */

#ifdef WLAN_FEATURE_11AC
tSirRetStatus
lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
				       tSirMacAddr peer,
				       uint8_t nMode, tpPESession psessionEntry)
{
	tDot11fOperatingMode frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;

	uint8_t smeSessionId = 0;

	if (psessionEntry == NULL) {
		PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
		return eSIR_FAILURE;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_VHT;
	frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
	frm.OperatingMode.chanWidth = nMode;
	frm.OperatingMode.rxNSS = 0;
	frm.OperatingMode.rxNSSType = 0;

	nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Operating Mode (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fOperatingMode);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Operating Mode (0x"
				       "%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a Operating Mode"
			   " Report."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	if (psessionEntry->pePersona == CDF_SAP_MODE)
		lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
			SIR_MAC_MGMT_ACTION, peer,
			psessionEntry->selfMacAddr);
	else
		lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
			SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
			psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;
	cdf_mem_copy((uint8_t *) pMacHdr->bssId,
		     (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
	nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
					     sizeof(tSirMacMgmtHdr),
					     nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a Operating Mode (0x%08x)."),
			nStatus);
		cds_packet_free((void *)pPacket);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL("There were warnings while packing a Operating Mode"
			   " (0x%08x)."), nStatus);
	}
	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a Channel Switch (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;
}

/**
 * \brief Send a VHT Channel Switch Announcement
 *
 *
 * \param pMac Pointer to the global MAC datastructure
 *
 * \param peer MAC address to which this frame will be sent
 *
 * \param nChanWidth
 *
 * \param nNewChannel
 *
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_vht_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
				       tSirMacAddr peer,
				       uint8_t nChanWidth,
				       uint8_t nNewChannel,
				       uint8_t ncbMode, tpPESession psessionEntry)
{
	tDot11fChannelSwitch frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;     /* , nCfg; */
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;

	uint8_t smeSessionId = 0;

	if (psessionEntry == NULL) {
		PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
		return eSIR_FAILURE;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
	frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
	frm.ChanSwitchAnn.switchMode = 1;
	frm.ChanSwitchAnn.newChannel = nNewChannel;
	frm.ChanSwitchAnn.switchCount = 1;
	frm.sec_chan_offset_ele.secondaryChannelOffset =
						lim_get_htcb_state(ncbMode);
	frm.sec_chan_offset_ele.present = 1;
	frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth;
	frm.WiderBWChanSwitchAnn.newCenterChanFreq0 =
		lim_get_center_channel(pMac, nNewChannel, ncbMode, nChanWidth);
	frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0;
	frm.ChanSwitchAnn.present = 1;
	frm.WiderBWChanSwitchAnn.present = 1;

	nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Channel Switch (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fChannelSwitch);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Channel Switch (0x"
				       "%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
				       " Report."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Next, we fill out the buffer descriptor: */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
	pMacHdr = (tpSirMacMgmtHdr) pFrame;
	cdf_mem_copy((uint8_t *) pMacHdr->bssId,
		     (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
	nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
					     sizeof(tSirMacMgmtHdr),
					     nPayload, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack a Channel Switch (0x%08x)."),
			nStatus);
		cds_packet_free((void *)pPacket);
		return eSIR_FAILURE;    /* allocated! */
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while packing a C"
				       "hannel Switch (0x%08x)."), nStatus);
	}

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGE,
			FL("Failed to send a Channel Switch (%X)!"),
			cdf_status);
		/* Pkt will be freed up by the callback */
		return eSIR_FAILURE;
	}

	return eSIR_SUCCESS;

} /* End lim_send_vht_channel_switch_mgmt_frame. */

#endif

#if defined WLAN_FEATURE_VOWIFI

/**
 * \brief Send a Neighbor Report Request Action frame
 *
 *
 * \param pMac Pointer to the global MAC structure
 *
 * \param pNeighborReq Address of a tSirMacNeighborReportReq
 *
 * \param peer mac address of peer station.
 *
 * \param psessionEntry address of session entry.
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
				       tpSirMacNeighborReportReq pNeighborReq,
				       tSirMacAddr peer, tpPESession psessionEntry)
{
	tSirRetStatus statusCode = eSIR_SUCCESS;
	tDot11fNeighborReportRequest frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	if (psessionEntry == NULL) {
		lim_log(pMac, LOGE,
			FL
				("(psession == NULL) in Request to send Neighbor Report request action frame"));
		return eSIR_FAILURE;
	}
	smeSessionId = psessionEntry->smeSessionId;
	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_RRM;
	frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
	frm.DialogToken.token = pNeighborReq->dialogToken;

	if (pNeighborReq->ssid_present) {
		populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
	}

	nStatus =
		dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Neighbor Report Request(0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fNeighborReportRequest);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Neighbor Rep"
				       "ort Request(0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a Neighbor "
			   "Report Request."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Copy necessary info to BD */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);

	/* Update A3 with the BSSID */
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	/* Now, we're ready to "pack" the frames */
	nStatus = dot11f_pack_neighbor_report_request(pMac,
						      &frm,
						      pFrame +
						      sizeof(tSirMacMgmtHdr),
						      nPayload, &nPayload);

	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL
				("Failed to pack an Neighbor Report Request (0x%08x)."),
			nStatus);

		/* FIXME - Need to convert to tSirRetStatus */
		statusCode = eSIR_FAILURE;
		goto returnAfterError;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL("There were warnings while packing Neighbor Report "
			   "Request (0x%08x)."), nStatus);
	}

	lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
	lim_print_mac_addr(pMac, peer, LOGW);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac,
				pPacket,
				(uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (CDF_STATUS_SUCCESS != cdf_status) {
		PELOGE(lim_log
			       (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
			       cdf_status);
		       )
		statusCode = eSIR_FAILURE;
		/* Pkt will be freed up by the callback */
		return statusCode;
	} else
		return eSIR_SUCCESS;

returnAfterError:
	cds_packet_free((void *)pPacket);

	return statusCode;
} /* End lim_send_neighbor_report_request_frame. */

/**
 * \brief Send a Link Report Action frame
 *
 *
 * \param pMac Pointer to the global MAC structure
 *
 * \param pLinkReport Address of a tSirMacLinkReport
 *
 * \param peer mac address of peer station.
 *
 * \param psessionEntry address of session entry.
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_link_report_action_frame(tpAniSirGlobal pMac,
				  tpSirMacLinkReport pLinkReport,
				  tSirMacAddr peer, tpPESession psessionEntry)
{
	tSirRetStatus statusCode = eSIR_SUCCESS;
	tDot11fLinkMeasurementReport frm;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	if (psessionEntry == NULL) {
		lim_log(pMac, LOGE,
			FL
				("(psession == NULL) in Request to send Link Report action frame"));
		return eSIR_FAILURE;
	}

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);

	frm.Category.category = SIR_MAC_ACTION_RRM;
	frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
	frm.DialogToken.token = pLinkReport->dialogToken;

	/* IEEE Std. 802.11 7.3.2.18. for the report element. */
	/* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
	/* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
	/* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
	/* such case this way than changing the frame parser. */
	frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
	frm.TPCEleLen.TPCLen = 2;
	frm.TxPower.txPower = pLinkReport->txPower;
	frm.LinkMargin.linkMargin = 0;

	frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
	frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
	frm.RCPI.rcpi = pLinkReport->rcpi;
	frm.RSNI.rsni = pLinkReport->rsni;

	nStatus =
		dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Link Report (0x%08x)."), nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fLinkMeasurementReport);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Link Rep"
				       "ort (0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
				       "Report."), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Copy necessary info to BD */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);

	/* Update A3 with the BSSID */
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	/* Now, we're ready to "pack" the frames */
	nStatus = dot11f_pack_link_measurement_report(pMac,
						      &frm,
						      pFrame +
						      sizeof(tSirMacMgmtHdr),
						      nPayload, &nPayload);

	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack an Link Report (0x%08x)."), nStatus);

		/* FIXME - Need to convert to tSirRetStatus */
		statusCode = eSIR_FAILURE;
		goto returnAfterError;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL
				("There were warnings while packing Link Report (0x%08x)."),
			nStatus);
	}

	lim_log(pMac, LOGW, FL("Sending a Link Report to "));
	lim_print_mac_addr(pMac, peer, LOGW);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac,
				pPacket,
				(uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (CDF_STATUS_SUCCESS != cdf_status) {
		PELOGE(lim_log
			       (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
			       cdf_status);
		       )
		statusCode = eSIR_FAILURE;
		/* Pkt will be freed up by the callback */
		return statusCode;
	} else
		return eSIR_SUCCESS;

returnAfterError:
	cds_packet_free((void *)pPacket);

	return statusCode;
} /* End lim_send_link_report_action_frame. */

/**
 * \brief Send a Beacon Report Action frame
 *
 *
 * \param pMac Pointer to the global MAC structure
 *
 * \param dialog_token dialog token to be used in the action frame.
 *
 * \param num_report number of reports in pRRMReport.
 *
 * \param pRRMReport Address of a tSirMacRadioMeasureReport.
 *
 * \param peer mac address of peer station.
 *
 * \param psessionEntry address of session entry.
 *
 * \return eSIR_SUCCESS on success, eSIR_FAILURE else
 *
 *
 */

tSirRetStatus
lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
					   uint8_t dialog_token,
					   uint8_t num_report,
					   tpSirMacRadioMeasureReport pRRMReport,
					   tSirMacAddr peer,
					   tpPESession psessionEntry)
{
	tSirRetStatus statusCode = eSIR_SUCCESS;
	uint8_t *pFrame;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t i;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	tDot11fRadioMeasurementReport *frm =
		cdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
	if (!frm) {
		lim_log(pMac, LOGE,
			FL
				("Not enough memory to allocate tDot11fRadioMeasurementReport"));
		return eSIR_MEM_ALLOC_FAILED;
	}

	if (psessionEntry == NULL) {
		lim_log(pMac, LOGE,
			FL
				("(psession == NULL) in Request to send Beacon Report action frame"));
		cdf_mem_free(frm);
		return eSIR_FAILURE;
	}
	cdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);

	frm->Category.category = SIR_MAC_ACTION_RRM;
	frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
	frm->DialogToken.token = dialog_token;

	frm->num_MeasurementReport =
		(num_report >
		 RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
		num_report;

	for (i = 0; i < frm->num_MeasurementReport; i++) {
		frm->MeasurementReport[i].type = pRRMReport[i].type;
		frm->MeasurementReport[i].token = pRRMReport[i].token;
		frm->MeasurementReport[i].late = 0;     /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
		switch (pRRMReport[i].type) {
		case SIR_MAC_RRM_BEACON_TYPE:
			populate_dot11f_beacon_report(pMac,
						      &frm->MeasurementReport[i],
						      &pRRMReport[i].report.
						      beaconReport);
			frm->MeasurementReport[i].incapable =
				pRRMReport[i].incapable;
			frm->MeasurementReport[i].refused =
				pRRMReport[i].refused;
			frm->MeasurementReport[i].present = 1;
			break;
		default:
			frm->MeasurementReport[i].incapable =
				pRRMReport[i].incapable;
			frm->MeasurementReport[i].refused =
				pRRMReport[i].refused;
			frm->MeasurementReport[i].present = 1;
			break;
		}
	}

	nStatus =
		dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a Radio Measure Report (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fLinkMeasurementReport);
		cdf_mem_free(frm);
		return eSIR_FAILURE;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for a Radio Measure Rep"
				       "ort (0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);

	cdf_status =
		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				 (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a Radio Measure "
			   "Report."), nBytes);
		cdf_mem_free(frm);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Copy necessary info to BD */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);

	/* Update A3 with the BSSID */
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

#ifdef WLAN_FEATURE_11W
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
#endif

	/* Now, we're ready to "pack" the frames */
	nStatus = dot11f_pack_radio_measurement_report(pMac,
						       frm,
						       pFrame +
						       sizeof(tSirMacMgmtHdr),
						       nPayload, &nPayload);

	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack an Radio Measure Report (0x%08x)."),
			nStatus);

		/* FIXME - Need to convert to tSirRetStatus */
		statusCode = eSIR_FAILURE;
		goto returnAfterError;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL("There were warnings while packing Radio "
			   "Measure Report (0x%08x)."), nStatus);
	}

	lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
	lim_print_mac_addr(pMac, peer, LOGW);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac,
				pPacket,
				(uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (CDF_STATUS_SUCCESS != cdf_status) {
		PELOGE(lim_log
			       (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
			       cdf_status);
		       )
		statusCode = eSIR_FAILURE;
		/* Pkt will be freed up by the callback */
		cdf_mem_free(frm);
		return statusCode;
	} else {
		cdf_mem_free(frm);
		return eSIR_SUCCESS;
	}

returnAfterError:
	cdf_mem_free(frm);
	cds_packet_free((void *)pPacket);
	return statusCode;
}

#endif

#ifdef WLAN_FEATURE_11W
/**
 * \brief Send SA query request action frame to peer
 *
 * \sa lim_send_sa_query_request_frame
 *
 *
 * \param pMac    The global tpAniSirGlobal object
 *
 * \param transId Transaction identifier
 *
 * \param peer    The Mac address of the station to which this action frame is addressed
 *
 * \param psessionEntry The PE session entry
 *
 * \return eSIR_SUCCESS if setup completes successfully
 *         eSIR_FAILURE is some problem is encountered
 */

tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
					      tSirMacAddr peer,
					      tpPESession psessionEntry)
{

	tDot11fSaQueryReq frm;  /* SA query request action frame */
	uint8_t *pFrame;
	tSirRetStatus nSirStatus;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
	frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
	/* 11w action  field is :
	   action: 0 --> SA Query Request action frame
	   action: 1 --> SA Query Response action frame */
	frm.Action.action = SIR_MAC_SA_QUERY_REQ;
	/* 11w SA Query Request transId */
	cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);

	nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
				       "for an SA Query Request (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fSaQueryReq);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for an SA Query Request"
				       " (0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
	cdf_status =
		cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a SA Query Request "
			   "action frame"), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Copy necessary info to BD */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);

	/* Update A3 with the BSSID */
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

	/* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
	/* in the FC */
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);

	/* Pack 11w SA Query Request frame */
	nStatus = dot11f_pack_sa_query_req(pMac,
					   &frm,
					   pFrame + sizeof(tSirMacMgmtHdr),
					   nPayload, &nPayload);

	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack an SA Query Request (0x%08x)."),
			nStatus);
		/* FIXME - Need to convert to tSirRetStatus */
		nSirStatus = eSIR_FAILURE;
		goto returnAfterError;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL
				("There were warnings while packing SA Query Request (0x%08x)."),
			nStatus);
	}

	lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
	lim_print_mac_addr(pMac, peer, LOG1);
	lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
	lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
#ifdef WLAN_FEATURE_P2P
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
#endif
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}
	smeSessionId = psessionEntry->smeSessionId;

	cdf_status = wma_tx_frame(pMac,
				pPacket,
				(uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	if (CDF_STATUS_SUCCESS != cdf_status) {
		PELOGE(lim_log
			       (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
			       cdf_status);
		       )
		nSirStatus = eSIR_FAILURE;
		/* Pkt will be freed up by the callback */
		return nSirStatus;
	} else {
		return eSIR_SUCCESS;
	}

returnAfterError:
	cds_packet_free((void *)pPacket);
	return nSirStatus;
} /* End lim_send_sa_query_request_frame */

/**
 * \brief Send SA query response action frame to peer
 *
 * \sa lim_send_sa_query_response_frame
 *
 *
 * \param pMac    The global tpAniSirGlobal object
 *
 * \param transId Transaction identifier received in SA query request action frame
 *
 * \param peer    The Mac address of the AP to which this action frame is addressed
 *
 * \param psessionEntry The PE session entry
 *
 * \return eSIR_SUCCESS if setup completes successfully
 *         eSIR_FAILURE is some problem is encountered
 */

tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
					       uint8_t *transId, tSirMacAddr peer,
					       tpPESession psessionEntry)
{

	tDot11fSaQueryRsp frm;  /* SA query reponse action frame */
	uint8_t *pFrame;
	tSirRetStatus nSirStatus;
	tpSirMacMgmtHdr pMacHdr;
	uint32_t nBytes, nPayload, nStatus;
	void *pPacket;
	CDF_STATUS cdf_status;
	uint8_t txFlag = 0;
	uint8_t smeSessionId = 0;

	smeSessionId = psessionEntry->smeSessionId;

	cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
	frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
	/*11w action  field is :
	   action: 0 --> SA query request action frame
	   action: 1 --> SA query response action frame */
	frm.Action.action = SIR_MAC_SA_QUERY_RSP;
	/*11w SA query response transId is same as
	   SA query request transId */
	cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);

	nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
				       "or a SA Query Response (0x%08x)."),
			nStatus);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fSaQueryRsp);
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW, FL("There were warnings while calculating "
				       "the packed size for an SA Query Response"
				       " (0x%08x)."), nStatus);
	}

	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
	cdf_status =
		cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
		lim_log(pMac, LOGP,
			FL("Failed to allocate %d bytes for a SA query response"
			   " action frame"), nBytes);
		return eSIR_FAILURE;
	}
	/* Paranoia: */
	cdf_mem_set(pFrame, nBytes, 0);

	/* Copy necessary info to BD */
	lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
		SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);

	/* Update A3 with the BSSID */
	pMacHdr = (tpSirMacMgmtHdr) pFrame;

	sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);

	/* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
	/* in the FC */
	lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);

	/* Pack 11w SA query response frame */
	nStatus = dot11f_pack_sa_query_rsp(pMac,
					   &frm,
					   pFrame + sizeof(tSirMacMgmtHdr),
					   nPayload, &nPayload);

	if (DOT11F_FAILED(nStatus)) {
		lim_log(pMac, LOGE,
			FL("Failed to pack an SA Query Response (0x%08x)."),
			nStatus);
		/* FIXME - Need to convert to tSirRetStatus */
		nSirStatus = eSIR_FAILURE;
		goto returnAfterError;
	} else if (DOT11F_WARNED(nStatus)) {
		lim_log(pMac, LOGW,
			FL
				("There were warnings while packing SA Query Response (0x%08x)."),
			nStatus);
	}

	lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
	lim_print_mac_addr(pMac, peer, LOGW);

	if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
#ifdef WLAN_FEATURE_P2P
	    || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
	    (psessionEntry->pePersona == CDF_P2P_GO_MODE)
#endif
	    ) {
		txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
	}

	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
			 psessionEntry->peSessionId, pMacHdr->fc.subType));
	cdf_status = wma_tx_frame(pMac,
				pPacket,
				(uint16_t) nBytes,
				TXRX_FRM_802_11_MGMT,
				ANI_TXDIR_TODS,
				7, lim_tx_complete, pFrame, txFlag,
				smeSessionId, 0);
	MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
			 psessionEntry->peSessionId, cdf_status));
	if (CDF_STATUS_SUCCESS != cdf_status) {
		PELOGE(lim_log
			       (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
			       cdf_status);
		       )
		nSirStatus = eSIR_FAILURE;
		/* Pkt will be freed up by the callback */
		return nSirStatus;
	} else {
		return eSIR_SUCCESS;
	}

returnAfterError:
	cds_packet_free((void *)pPacket);
	return nSirStatus;
} /* End lim_send_sa_query_response_frame */
#endif
