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

/*===========================================================================
 * lim_process_tdls.c
 * OVERVIEW:
 *
 * DEPENDENCIES:
 *
 * Are listed for each API below.
 * ===========================================================================*/

/*===========================================================================

 *                      EDIT HISTORY FOR FILE

 *  This section contains comments describing changes made to the module.
 *  Notice that changes are listed in reverse chronological order.

 *  $Header$$DateTime$$Author$

 *  when        who     what, where, why
 *  ----------    ---    ------------------------------------------------------
 *  05/05/2010   Ashwani    Initial Creation, added TDLS action frame
 *  functionality,TDLS message exchange with SME..etc..

   ===========================================================================*/

/**
 * \file lim_process_tdls.c
 *
 * \brief Code for preparing,processing and sending 802.11z action frames
 *
 */

#ifdef FEATURE_WLAN_TDLS

#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 "dot11f.h"
#include "lim_sta_hash_api.h"
#include "sch_api.h"
#include "lim_send_messages.h"
#include "utils_parser.h"
#include "lim_assoc_utils.h"
#include "lim_prop_exts_utils.h"
#include "dph_hash_table.h"
#include "wma_types.h"
#include "cds_regdomain.h"
#include "cds_utils.h"
#include "wlan_reg_services_api.h"
#include "wlan_tdls_tgt_api.h"
#include "wlan_mlme_public_struct.h"
#include "wlan_mlme_api.h"

/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
   There was IOT issue with cisco 1252 open mode, where it pads
   discovery req/teardown frame with some junk value up to min size.
   To avoid this issue, we pad QCOM_VENDOR_IE.
   If there is other IOT issue because of this bandage, define NO_PAD...
 */
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
#define MIN_IEEE_8023_SIZE              46
#define MIN_VENDOR_SPECIFIC_IE_SIZE     5
#endif

static QDF_STATUS lim_tdls_setup_add_sta(struct mac_context *mac,
		tSirTdlsAddStaReq * pAddStaReq, struct pe_session *pe_session);

/*
 * TDLS data frames will go out/come in as non-qos data.
 * so, eth_890d_header will be aligned access..
 */
static const uint8_t eth_890d_header[] = {
	0xaa, 0xaa, 0x03, 0x00,
	0x00, 0x00, 0x89, 0x0d,
};

/*
 * type of links used in TDLS
 */
enum tdlsLinks {
	TDLS_LINK_AP,
	TDLS_LINK_DIRECT
} e_tdls_link;

/*
 * node status in node searching
 */
enum tdlsLinkNodeStatus {
	TDLS_NODE_NOT_FOUND,
	TDLS_NODE_FOUND
} e_tdls_link_node_status;

enum tdlsReqType {
	TDLS_INITIATOR,
	TDLS_RESPONDER
} e_tdls_req_type;

typedef enum tdlsLinkSetupStatus {
	TDLS_SETUP_STATUS_SUCCESS = 0,
	TDLS_SETUP_STATUS_FAILURE = 37
} etdlsLinkSetupStatus;

/* These maps to Kernel TDLS peer capability
 * flags and should get changed as and when necessary
 */
enum tdls_peer_capability {
	TDLS_PEER_HT_CAP = 0,
	TDLS_PEER_VHT_CAP = 1,
	TDLS_PEER_WMM_CAP = 2
} e_tdls_peer_capability;

/* some local defines */
#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
#define PTI_LINK_IDEN_OFFSET     (5)
#define PTI_BUF_STATUS_OFFSET    (25)

/* TODO, Move this parameters to configuration */
#define PEER_PSM_SUPPORT          (0)
#define TDLS_SUPPORT              (1)
#define TDLS_PROHIBITED           (0)
#define TDLS_CH_SWITCH_PROHIBITED (1)
/** @brief Set bit manipulation macro */
#define SET_BIT(value, mask)       ((value) |= (1 << (mask)))
/** @brief Clear bit manipulation macro */
#define CLEAR_BIT(value, mask)     ((value) &= ~(1 << (mask)))
/** @brief Check bit manipulation macro */
#define CHECK_BIT(value, mask)    ((value) & (1 << (mask)))

#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
	do { \
	if ((aid) < (sizeof(uint32_t) << 3)) \
		SET_BIT(peer_bitmap[0], (aid));	\
	else if ((aid) < (sizeof(uint32_t) << 4)) \
		SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
	} while (0);

#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid)	\
	do { \
	if ((aid) < (sizeof(uint32_t) << 3)) \
		CLEAR_BIT(peer_bitmap[0], (aid)); \
	else if ((aid) < (sizeof(uint32_t) << 4)) \
		CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
	} while (0);

#ifdef FEATURE_WLAN_TDLS
#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT         (800)
#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT         (200)
#endif

#define IS_QOS_ENABLED(pe_session) ((((pe_session)->limQosEnabled) && \
					SIR_MAC_GET_QOS((pe_session)->limCurrentBssCaps)) ||	\
				       (((pe_session)->limWmeEnabled) && \
					LIM_BSS_CAPS_GET(WME, (pe_session)->limCurrentBssQosCaps)))

#define TID_AC_VI                  4
#define TID_AC_BK                  1

static const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
{
	switch (tdlsActionCode) {
		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
		CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
		CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
		CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
		CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
		CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
		CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
		CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
		CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
	}
	return (const uint8_t *)"UNKNOWN";
}

/*
 * initialize TDLS setup list and related data structures.
 */
void lim_init_tdls_data(struct mac_context *mac, struct pe_session *pe_session)
{
	lim_init_peer_idxpool(mac, pe_session);

	return;
}

static void populate_dot11f_tdls_offchannel_params(
				struct mac_context *mac,
				struct pe_session *pe_session,
				tDot11fIESuppChannels *suppChannels,
				tDot11fIESuppOperatingClasses *suppOperClasses)
{
	uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
	uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
	uint8_t i;
	uint8_t valid_count = 0;
	uint8_t chanOffset;
	uint8_t op_class;
	uint8_t numClasses;
	uint8_t classes[REG_MAX_SUPP_OPER_CLASSES];
	uint32_t band;
	uint8_t nss_2g;
	uint8_t nss_5g;

	if (wlan_cfg_get_str(mac, WNI_CFG_VALID_CHANNEL_LIST,
			     validChan, &numChans) != QDF_STATUS_SUCCESS) {
		/**
		 * Could not get Valid channel list from CFG.
		 * Log error.
		 */
		pe_err("could not retrieve Valid channel list");
		return;
	}

	if (IS_5G_CH(pe_session->currentOperChannel))
		band = BAND_5G;
	else
		band = BAND_2G;

	nss_5g = QDF_MIN(mac->vdev_type_nss_5g.tdls,
			 mac->user_configured_nss);
	nss_2g = QDF_MIN(mac->vdev_type_nss_2g.tdls,
			 mac->user_configured_nss);

	/* validating the channel list for DFS and 2G channels */
	for (i = 0U; i < numChans; i++) {
		if ((band == BAND_5G) &&
		    (NSS_2x2_MODE == nss_5g) &&
		    (NSS_1x1_MODE == nss_2g) &&
		    (wlan_reg_is_dfs_ch(mac->pdev, validChan[i]))) {
			pe_debug("skipping channel: %d, nss_5g: %d, nss_2g: %d",
				validChan[i], nss_5g, nss_2g);
			continue;
		} else {
			if (wlan_reg_is_dsrc_chan(mac->pdev, validChan[i])) {
				pe_debug("skipping channel: %d from the valid channel list",
					validChan[i]);
				continue;
			}
		}

		if (valid_count >= ARRAY_SIZE(suppChannels->bands))
			break;
		suppChannels->bands[valid_count][0] = validChan[i];
		suppChannels->bands[valid_count][1] = 1;
		valid_count++;
	}

	suppChannels->num_bands = valid_count;
	suppChannels->present = 1;

	/* find channel offset and get op class for current operating channel */
	switch (pe_session->htSecondaryChannelOffset) {
	case PHY_SINGLE_CHANNEL_CENTERED:
		chanOffset = BW20;
		break;

	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
		chanOffset = BW40_LOW_PRIMARY;
		break;

	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
		chanOffset = BW40_HIGH_PRIMARY;
		break;

	default:
		chanOffset = BWALL;
		break;
	}

	op_class = wlan_reg_dmn_get_opclass_from_channel(
		mac->scan.countryCodeCurrent,
		pe_session->currentOperChannel,
		chanOffset);

	pe_debug("countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d op class: %d",
			mac->scan.countryCodeCurrent,
			pe_session->currentOperChannel,
			pe_session->htSecondaryChannelOffset,
			chanOffset, op_class);
	suppOperClasses->present = 1;
	suppOperClasses->classes[0] = op_class;

	wlan_reg_dmn_get_curr_opclasses(&numClasses, &classes[0]);

	for (i = 0; i < numClasses; i++)
		suppOperClasses->classes[i + 1] = classes[i];

	/* add one for present operating class, added in the beginning */
	suppOperClasses->num_classes = numClasses + 1;

	return;
}

/*
 * FUNCTION: Populate Link Identifier element IE
 *
 */

static void populate_dot11f_link_iden(struct mac_context *mac,
				      struct pe_session *pe_session,
				      tDot11fIELinkIdentifier *linkIden,
				      struct qdf_mac_addr peer_mac,
				      uint8_t reqType)
{
	uint8_t *initStaAddr = NULL;
	uint8_t *respStaAddr = NULL;

	(reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
				       (respStaAddr = linkIden->RespStaAddr))
	: ((respStaAddr = linkIden->InitStaAddr),
	   (initStaAddr = linkIden->RespStaAddr));
	qdf_mem_copy((uint8_t *) linkIden->bssid,
		     (uint8_t *) pe_session->bssId, QDF_MAC_ADDR_SIZE);

	qdf_mem_copy((uint8_t *) initStaAddr,
		     pe_session->selfMacAddr, QDF_MAC_ADDR_SIZE);

	qdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peer_mac.bytes,
		     QDF_MAC_ADDR_SIZE);

	linkIden->present = 1;
	return;

}

static void populate_dot11f_tdls_ext_capability(struct mac_context *mac,
						struct pe_session *pe_session,
						tDot11fIEExtCap *extCapability)
{
	struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;

	p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
	p_ext_cap->tdls_peer_uapsd_buffer_sta = mac->lim.gLimTDLSBufStaEnabled;

	/*
	 * Set TDLS channel switching bits only if offchannel is enabled
	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
	 * IE in assoc/re-assoc response.
	 */
	if ((1 == mac->lim.gLimTDLSOffChannelEnabled) &&
	    (!pe_session->tdls_chan_swit_prohibited)) {
		p_ext_cap->tdls_channel_switching = 1;
		p_ext_cap->tdls_chan_swit_prohibited = 0;
	} else {
	    p_ext_cap->tdls_channel_switching = 0;
	    p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
	}
	p_ext_cap->tdls_support = TDLS_SUPPORT;
	p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;

	extCapability->present = 1;
	extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability);

	return;
}

/*
 * prepare TDLS frame header, it includes
 * |             |              |                |
 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
 * |             |              |                |
 */
static uint32_t lim_prepare_tdls_frame_header(struct mac_context *mac, uint8_t *pFrame,
					      tDot11fIELinkIdentifier *link_iden,
					      uint8_t tdlsLinkType, uint8_t reqType,
					      uint8_t tid,
					      struct pe_session *pe_session)
{
	tpSirMacDataHdr3a pMacHdr;
	uint32_t header_offset = 0;
	uint8_t *addr1 = NULL;
	uint8_t *addr3 = NULL;
	uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
		       ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
	uint8_t *peerMac = (reqType == TDLS_INITIATOR)
			   ? link_iden->RespStaAddr : link_iden->InitStaAddr;
	uint8_t *staMac = (reqType == TDLS_INITIATOR)
			  ? link_iden->InitStaAddr : link_iden->RespStaAddr;
	tpDphHashNode sta_ds;
	uint16_t aid = 0;
	uint8_t qos_mode = 0;

	pMacHdr = (tpSirMacDataHdr3a) (pFrame);

	/*
	 * if TDLS frame goes through the AP link, it follows normal address
	 * pattern, if TDLS frame goes thorugh the direct link, then
	 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
	 */
	(tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
					  (addr3 = (peerMac)))
	: ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
	/*
	 * prepare 802.11 header
	 */
	pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
	pMacHdr->fc.type = SIR_MAC_DATA_FRAME;

	sta_ds = dph_lookup_hash_entry(mac, peerMac, &aid,
					&pe_session->dph.dphHashTable);
	if (sta_ds)
		qos_mode = sta_ds->qosMode;

	pMacHdr->fc.subType =
		((IS_QOS_ENABLED(pe_session) &&
		(tdlsLinkType == TDLS_LINK_AP)) ||
		((tdlsLinkType == TDLS_LINK_DIRECT) && qos_mode))
		? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA;

	/*
	 * TL is not setting up below fields, so we are doing it here
	 */
	pMacHdr->fc.toDS = toDs;
	pMacHdr->fc.powerMgmt = 0;
	pMacHdr->fc.wep = (pe_session->encryptType == eSIR_ED_NONE) ? 0 : 1;

	qdf_mem_copy((uint8_t *) pMacHdr->addr1,
		     (uint8_t *) addr1, sizeof(tSirMacAddr));
	qdf_mem_copy((uint8_t *) pMacHdr->addr2,
		     (uint8_t *) staMac, sizeof(tSirMacAddr));

	qdf_mem_copy((uint8_t *) pMacHdr->addr3,
		     (uint8_t *) (addr3), sizeof(tSirMacAddr));

	pe_debug("Preparing TDLS frame header to %s A1:"
		   MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
		   MAC_ADDRESS_STR,
		(tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
		MAC_ADDR_ARRAY(pMacHdr->addr1),
		MAC_ADDR_ARRAY(pMacHdr->addr2),
		MAC_ADDR_ARRAY(pMacHdr->addr3));

	if (pMacHdr->fc.subType == SIR_MAC_DATA_QOS_DATA) {
		pMacHdr->qosControl.tid = tid;
		header_offset += sizeof(tSirMacDataHdr3a);
	} else
		header_offset += sizeof(tSirMacMgmtHdr);

	/*
	 * Now form RFC1042 header
	 */
	qdf_mem_copy((uint8_t *) (pFrame + header_offset),
		     (uint8_t *) eth_890d_header, sizeof(eth_890d_header));

	header_offset += sizeof(eth_890d_header);

	/* add payload type as TDLS */
	*(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
	header_offset += PAYLOAD_TYPE_TDLS_SIZE;
	return header_offset;
}

/**
 * lim_mgmt_tdls_tx_complete - callback to indicate Tx completion
 * @context: pointer to mac structure
 * @buf: buffer
 * @tx_complete: indicates tx success/failure
 * @params: tx completion params
 *
 * function will be invoked on receiving tx completion indication
 *
 * return: success: eHAL_STATUS_SUCCESS failure: eHAL_STATUS_FAILURE
 */
static QDF_STATUS lim_mgmt_tdls_tx_complete(void *context,
					    qdf_nbuf_t buf,
					    uint32_t tx_complete,
					    void *params)
{
	struct mac_context *mac_ctx = (struct mac_context *)context;

	pe_debug("tdls_frm_session_id: %x tx_complete: %x",
		mac_ctx->lim.tdls_frm_session_id, tx_complete);

	if (NO_SESSION != mac_ctx->lim.tdls_frm_session_id) {
		lim_send_sme_mgmt_tx_completion(mac_ctx,
				mac_ctx->lim.tdls_frm_session_id,
				tx_complete);
		mac_ctx->lim.tdls_frm_session_id = NO_SESSION;
	}

	if (buf)
		qdf_nbuf_free(buf);

	return QDF_STATUS_SUCCESS;
}

/*
 * This function can be used for bacst or unicast discovery request
 * We are not differentiating it here, it will all depnds on peer MAC address,
 */
static QDF_STATUS lim_send_tdls_dis_req_frame(struct mac_context *mac,
						 struct qdf_mac_addr peer_mac,
						 uint8_t dialog,
						 struct pe_session *pe_session,
						 enum wifi_traffic_ac ac)
{
	tDot11fTDLSDisReq tdlsDisReq;
	uint32_t status = 0;
	uint32_t nPayload = 0;
	uint32_t size = 0;
	uint32_t nBytes = 0;
	uint32_t header_offset = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	uint32_t padLen = 0;
#endif
	uint8_t smeSessionId = 0;

	if (NULL == pe_session) {
		pe_err("pe_session is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	smeSessionId = pe_session->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:
	 */
	qdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);

	/*
	 * setup Fixed fields,
	 */
	tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
	tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
	tdlsDisReq.DialogToken.token = dialog;

	size = sizeof(tSirMacAddr);

	populate_dot11f_link_iden(mac, pe_session, &tdlsDisReq.LinkIdentifier,
				  peer_mac, TDLS_INITIATOR);

	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_dis_req_size(mac, &tdlsDisReq, &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fTDLSDisReq);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */

	nBytes = nPayload + ((IS_QOS_ENABLED(pe_session))
			     ? sizeof(tSirMacDataHdr3a) :
			     sizeof(tSirMacMgmtHdr))
		 + sizeof(eth_890d_header)
		 + PAYLOAD_TYPE_TDLS_SIZE;

#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
	 */
	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
		padLen =
			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);

		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;

		nBytes += padLen;
	}
#endif

	/* Ok-- try to allocate memory from MGMT PKT pool */

	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate: %d bytes for a TDLS Discovery Request",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * request frame
	 */

	/* fill out the buffer descriptor */

	header_offset = lim_prepare_tdls_frame_header(mac, pFrame,
			      LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP,
			      TDLS_INITIATOR,
			      (ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
			      pe_session);

	status = dot11f_pack_tdls_dis_req(mac, &tdlsDisReq, pFrame
					  + header_offset, nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS discovery req (0x%08x)",
			status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
			status);
	}

#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	if (padLen != 0) {
		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
		uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
		padVendorSpecific[0] = 221;
		padVendorSpecific[1] = padLen - 2;
		padVendorSpecific[2] = 0x00;
		padVendorSpecific[3] = 0xA0;
		padVendorSpecific[4] = 0xC6;

		pe_debug("Padding Vendor Specific Ie Len: %d", padLen);

		/* padding zero if more than 5 bytes are required */
		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
			qdf_mem_set(pFrame + header_offset + nPayload +
				    MIN_VENDOR_SPECIFIC_IE_SIZE,
				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
	}
#endif

	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_DIS_REQ,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
		MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);
	qdf_status = wma_tx_frameWithTxComplete(mac, pPacket,
					(uint16_t) nBytes,
					TXRX_FRM_802_11_DATA,
					ANI_TXDIR_TODS,
					TID_AC_VI,
					lim_tx_complete, pFrame,
					lim_mgmt_tdls_tx_complete,
					HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME |
					HAL_USE_PEER_STA_REQUESTED_MASK,
					smeSessionId, false, 0, RATEID_DEFAULT);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Discovery Request frame");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;

}

/*
 * This static function is consistent with any kind of TDLS management
 * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
 * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
 */
static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac,
					    uint32_t selfDot11Mode,
					    tDot11fIEHTCaps *htCap,
					    tDot11fIEVHTCaps *vhtCap,
					    struct pe_session *pe_session)
{
	uint8_t nss;
	qdf_size_t val_len;
	struct mlme_vht_capabilities_info *vht_cap_info;

	vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info;

	if (IS_5G_CH(pe_session->currentOperChannel))
		nss = mac->vdev_type_nss_5g.tdls;
	else
		nss = mac->vdev_type_nss_2g.tdls;

	nss = QDF_MIN(nss, mac->user_configured_nss);
	if (IS_DOT11_MODE_HT(selfDot11Mode)) {
		/* Include HT Capability IE */
		populate_dot11f_ht_caps(mac, NULL, htCap);
		val_len = SIZE_OF_SUPPORTED_MCS_SET;
		wlan_mlme_get_cfg_str(&htCap->supportedMCSSet[0],
				      &mac->mlme_cfg->rates.supported_mcs_set,
				      &val_len);
		if (NSS_1x1_MODE == nss)
			htCap->supportedMCSSet[1] = 0;
		/*
		 * Advertise ht capability and max supported channel bandwidth
		 * when populating HT IE in TDLS Setup Request/Setup Response/
		 * Setup Confirmation frames.
		 * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
		 * off-channel direct link may be started if both TDLS peer STAs
		 * indicated 40 MHz support in the Supported Channel Width Set
		 * field of the HT Capabilities element (which is included in
		 * the TDLS Setup Request frame and the TDLS Setup Response
		 * frame). Switching to a 40 MHz off-channel direct link is
		 * achieved by including the following information in the TDLS
		 * Channel Switch Request
		 * 11.21.1 General: The channel width of the TDLS direct link on
		 * the base channel shall not exceed the channel width of the
		 * BSS to which the TDLS peer STAs are associated.
		 */
		htCap->supportedChannelWidthSet = 1;
	} else {
		htCap->present = 0;
	}
	pe_debug("HT present: %hu, Chan Width: %hu",
		htCap->present, htCap->supportedChannelWidthSet);
	if (((pe_session->currentOperChannel <= SIR_11B_CHANNEL_END) &&
	     vht_cap_info->b24ghz_band) ||
	    (pe_session->currentOperChannel >= SIR_11B_CHANNEL_END)) {
		if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
		    IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
			/* Include VHT Capability IE */
			populate_dot11f_vht_caps(mac, pe_session, vhtCap);

			/*
			 * Set to 0 if the TDLS STA does not support either 160
			 * or 80+80 MHz.
			 * Set to 1 if the TDLS STA supports 160 MHz.
			 * Set to 2 if the TDLS STA supports 160 MHz and
			 * 80+80 MHz.
			 * The value 3 is reserved
			 */
			vhtCap->supportedChannelWidthSet = 0;

			vhtCap->suBeamformeeCap = 0;
			vhtCap->suBeamFormerCap = 0;
			vhtCap->muBeamformeeCap = 0;
			vhtCap->muBeamformerCap = 0;

			vhtCap->rxMCSMap = vht_cap_info->rx_mcs_map;

			vhtCap->rxHighSupDataRate =
				vht_cap_info->rx_supp_data_rate;
			vhtCap->txMCSMap = vht_cap_info->tx_mcs_map;
			vhtCap->txSupDataRate = vht_cap_info->tx_supp_data_rate;
			if (nss == NSS_1x1_MODE) {
				vhtCap->txMCSMap |= DISABLE_NSS2_MCS;
				vhtCap->rxMCSMap |= DISABLE_NSS2_MCS;
				vhtCap->txSupDataRate =
					VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
				vhtCap->rxHighSupDataRate =
					VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1;
			}
		} else {
			vhtCap->present = 0;
		}
	} else {
		/* Vht Disable from ini in 2.4 GHz */
		vhtCap->present = 0;
	}
	pe_debug("VHT present: %hu, Chan Width: %hu",
		vhtCap->present, vhtCap->supportedChannelWidthSet);
}

/*
 * Send TDLS discovery response frame on direct link.
 */

static QDF_STATUS lim_send_tdls_dis_rsp_frame(struct mac_context *mac,
						 struct qdf_mac_addr peer_mac,
						 uint8_t dialog,
						 struct pe_session *pe_session,
						 uint8_t *addIe,
						 uint16_t addIeLen)
{
	tDot11fTDLSDisRsp tdlsDisRsp;
	uint16_t caps = 0;
	uint32_t status = 0;
	uint32_t nPayload = 0;
	uint32_t nBytes = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
	uint32_t selfDot11Mode;
/*  Placeholder to support different channel bonding mode of TDLS than AP. */
/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
/*  uint32_t tdlsChannelBondingMode; */
	uint8_t smeSessionId = 0;

	if (NULL == pe_session) {
		pe_err("pe_session is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	smeSessionId = pe_session->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:
	 */
	qdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);

	/*
	 * setup Fixed fields,
	 */
	tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
	tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
	tdlsDisRsp.DialogToken.token = dialog;

	populate_dot11f_link_iden(mac, pe_session,
				  &tdlsDisRsp.LinkIdentifier,
				  peer_mac, TDLS_RESPONDER);

	if (cfg_get_capability_info(mac, &caps, pe_session)
		!= QDF_STATUS_SUCCESS) {
		/*
		 * Could not get Capabilities value
		 * from CFG. Log error.
		 */
		pe_err("could not retrieve Capabilities value");
	}
	swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);

	/* populate supported rate and ext supported rate IE */
	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac,
					&tdlsDisRsp.SuppRates,
					&tdlsDisRsp.ExtSuppRates,
					pe_session->currentOperChannel))
		pe_err("could not populate supported data rates");

	/* populate extended capability IE */
	populate_dot11f_tdls_ext_capability(mac,
					    pe_session,
					    &tdlsDisRsp.ExtCap);

	wlan_cfg_get_int(mac, WNI_CFG_DOT11_MODE, &selfDot11Mode);

	/* Populate HT/VHT Capabilities */
	populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, &tdlsDisRsp.HTCaps,
					&tdlsDisRsp.VHTCaps, pe_session);

	/* Populate TDLS offchannel param only if offchannel is enabled
	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
	 * IE in assoc/re-assoc response.
	 */
	if ((1 == mac->lim.gLimTDLSOffChannelEnabled) &&
	    (!pe_session->tdls_chan_swit_prohibited)) {
		populate_dot11f_tdls_offchannel_params(mac, pe_session,
						       &tdlsDisRsp.SuppChannels,
						       &tdlsDisRsp.
						       SuppOperatingClasses);
		if (mac->mlme_cfg->gen.band_capability != BAND_2G) {
			tdlsDisRsp.ht2040_bss_coexistence.present = 1;
			tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
		}
	} else {
		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
			mac->lim.gLimTDLSOffChannelEnabled,
			pe_session->tdls_chan_swit_prohibited);
	}
	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_dis_rsp_size(mac, &tdlsDisRsp, &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a Discovery Response (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for a Discovery Response (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */

	nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;

	/* Ok-- try to allocate memory from MGMT PKT pool */
	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				(void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate %d bytes for a TDLS Discovery Request",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * response frame
	 */

	/* Make public Action Frame */

	lim_populate_mac_header(mac, pFrame, SIR_MAC_MGMT_FRAME,
				SIR_MAC_MGMT_ACTION, peer_mac.bytes,
				pe_session->selfMacAddr);

	{
		tpSirMacMgmtHdr pMacHdr;

		pMacHdr = (tpSirMacMgmtHdr) pFrame;
		pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
		pMacHdr->fc.powerMgmt = 0;
		sir_copy_mac_addr(pMacHdr->bssId, pe_session->bssId);
	}

	status = dot11f_pack_tdls_dis_rsp(mac, &tdlsDisRsp, pFrame +
					  sizeof(tSirMacMgmtHdr),
					  nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS discovery response (0x%08x)",
			status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Discovery Response (0x%08x)",
			status);
	}

	if (0 != addIeLen) {
		pe_debug("Copy Additional Ie Len: %d", addIeLen);
		qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
			     addIeLen);
	}
	pe_debug("[TDLS] action: %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_DIS_RSP,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
		MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);
	/*
	 * Transmit Discovery response and watch if this is delivered to
	 * peer STA.
	 */
	/* In CLD 2.0, pass Discovery Response as mgmt frame so that
	 * wma does not do header conversion to 802.3 before calling tx/rx
	 * routine and subsequenly target also sends frame as is OTA
	 */
	qdf_status = wma_tx_frameWithTxComplete(mac, pPacket, (uint16_t) nBytes,
					      TXRX_FRM_802_11_MGMT,
					      ANI_TXDIR_IBSS,
					      0,
					      lim_tx_complete, pFrame,
					      lim_mgmt_tdls_tx_complete,
					      HAL_USE_SELF_STA_REQUESTED_MASK,
					      smeSessionId, false, 0,
					      RATEID_DEFAULT);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Discovery Response frame!");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;

}

/*
 * This static function is currently used by lim_send_tdls_link_setup_req_frame and
 * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
 */
static void populate_dotf_tdls_vht_aid(struct mac_context *mac, uint32_t selfDot11Mode,
				       struct qdf_mac_addr peerMac,
				       tDot11fIEAID *Aid,
				       struct pe_session *pe_session)
{
	if (((pe_session->currentOperChannel <= SIR_11B_CHANNEL_END) &&
	     mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band) ||
	    (pe_session->currentOperChannel >= SIR_11B_CHANNEL_END)) {
		if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
		    IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {

			uint16_t aid;
			tpDphHashNode pStaDs;

			pStaDs =
				dph_lookup_hash_entry(mac, peerMac.bytes, &aid,
						      &pe_session->dph.
						      dphHashTable);
			if (NULL != pStaDs) {
				Aid->present = 1;
				Aid->assocId = aid | LIM_AID_MASK;      /* set bit 14 and 15 1's */
			} else {
				Aid->present = 0;
				pe_err("pStaDs is NULL for "
					   MAC_ADDRESS_STR,
					MAC_ADDR_ARRAY(peerMac.bytes));
			}
		}
	} else {
		Aid->present = 0;
		pe_warn("Vht not enable from ini for 2.4GHz");
	}
}

#ifdef CONFIG_HL_SUPPORT

/**
 * wma_tx_frame_with_tx_complete_send() - Send tx frames on Direct link or AP link
 *				       depend on reason code
 * @mac: pointer to MAC Sirius parameter structure
 * @pPacket: pointer to mgmt packet
 * @nBytes: number of bytes to send
 * @tid:tid value for AC
 * @pFrame: pointer to tdls frame
 * @smeSessionId:session id
 * @flag: tdls flag
 *
 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
 *
 * Return: None
 */
static inline QDF_STATUS
wma_tx_frame_with_tx_complete_send(struct mac_context *mac, void *pPacket,
				uint16_t nBytes,
				uint8_t tid,
				uint8_t *pFrame,
				uint8_t smeSessionId, bool flag)
{
	return wma_tx_frameWithTxComplete(mac, pPacket,
					  (uint16_t) nBytes,
					  TXRX_FRM_802_11_DATA,
					  ANI_TXDIR_TODS,
					  tid,
					  lim_tx_complete, pFrame,
					  lim_mgmt_tdls_tx_complete,
					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
					  | HAL_USE_PEER_STA_REQUESTED_MASK,
					  smeSessionId, flag, 0,
					  RATEID_DEFAULT);
}
#else

static inline QDF_STATUS
wma_tx_frame_with_tx_complete_send(struct mac_context *mac, void *pPacket,
				uint16_t nBytes,
				uint8_t tid,
				uint8_t *pFrame,
				uint8_t smeSessionId, bool flag)
{
	return wma_tx_frameWithTxComplete(mac, pPacket,
					  (uint16_t) nBytes,
					  TXRX_FRM_802_11_DATA,
					  ANI_TXDIR_TODS,
					  tid,
					  lim_tx_complete, pFrame,
					  lim_mgmt_tdls_tx_complete,
					  HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME
					  | HAL_USE_PEER_STA_REQUESTED_MASK,
					  smeSessionId, false, 0,
					  RATEID_DEFAULT);
}
#endif

void lim_set_tdls_flags(roam_offload_synch_ind *roam_sync_ind_ptr,
		   struct pe_session *ft_session_ptr)
{
	roam_sync_ind_ptr->join_rsp->tdls_prohibited =
		ft_session_ptr->tdls_prohibited;
	roam_sync_ind_ptr->join_rsp->tdls_chan_swit_prohibited =
		ft_session_ptr->tdls_chan_swit_prohibited;
}

/*
 * TDLS setup Request frame on AP link
 */
static
QDF_STATUS lim_send_tdls_link_setup_req_frame(struct mac_context *mac,
						 struct qdf_mac_addr peer_mac,
						 uint8_t dialog,
						 struct pe_session *pe_session,
						 uint8_t *addIe,
						 uint16_t addIeLen,
						 enum wifi_traffic_ac ac)
{
	tDot11fTDLSSetupReq tdlsSetupReq;
	uint16_t caps = 0;
	uint32_t status = 0;
	uint32_t nPayload = 0;
	uint32_t nBytes = 0;
	uint32_t header_offset = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
	uint32_t selfDot11Mode;
	uint8_t smeSessionId = 0;
	uint8_t sp_length = 0;

/*  Placeholder to support different channel bonding mode of TDLS than AP. */
/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
/*  uint32_t tdlsChannelBondingMode; */

	/*
	 * 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:
	 */
	smeSessionId = pe_session->smeSessionId;

	qdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
	tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
	tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
	tdlsSetupReq.DialogToken.token = dialog;

	populate_dot11f_link_iden(mac, pe_session,
				  &tdlsSetupReq.LinkIdentifier, peer_mac,
				  TDLS_INITIATOR);

	if (cfg_get_capability_info(mac, &caps, pe_session) != QDF_STATUS_SUCCESS) {
		/*
		 * Could not get Capabilities value
		 * from CFG. Log error.
		 */
		pe_err("could not retrieve Capabilities value");
	}
	swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);

	/* populate supported rate and ext supported rate IE */
	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac,
					&tdlsSetupReq.SuppRates,
					&tdlsSetupReq.ExtSuppRates,
					pe_session->currentOperChannel))
		pe_err("could not populate supported data rates");

	/* Populate extended capability IE */
	populate_dot11f_tdls_ext_capability(mac,
					    pe_session,
					    &tdlsSetupReq.ExtCap);

	if (1 == mac->lim.gLimTDLSWmmMode) {

		pe_debug("populate WMM IE in Setup Request Frame");
		sp_length = mac->mlme_cfg->wmm_params.max_sp_length;
		/* include WMM IE */
		tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
		tdlsSetupReq.WMMInfoStation.acvo_uapsd =
			(mac->lim.gLimTDLSUapsdMask & 0x01);
		tdlsSetupReq.WMMInfoStation.acvi_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
		tdlsSetupReq.WMMInfoStation.acbk_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
		tdlsSetupReq.WMMInfoStation.acbe_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
		tdlsSetupReq.WMMInfoStation.max_sp_length = sp_length;
		tdlsSetupReq.WMMInfoStation.present = 1;
	} else {
		/*
		 * TODO: we need to see if we have to support conditions where
		 * we have EDCA parameter info element is needed a) if we need
		 * different QOS parameters for off channel operations or QOS
		 * is not supported on AP link and we wanted to QOS on direct
		 * link.
		 */

		/* Populate QOS info, needed for Peer U-APSD session */

		/*
		 * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
		 * depends on AP's capability, and TDLS doesn't want to depend
		 * on AP's capability
		 */

		pe_debug("populate QOS IE in Setup Request Frame");
		tdlsSetupReq.QOSCapsStation.present = 1;
		tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
		tdlsSetupReq.QOSCapsStation.qack = 0;
		tdlsSetupReq.QOSCapsStation.acbe_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
		tdlsSetupReq.QOSCapsStation.acbk_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
		tdlsSetupReq.QOSCapsStation.acvi_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
		tdlsSetupReq.QOSCapsStation.acvo_uapsd =
			(mac->lim.gLimTDLSUapsdMask & 0x01);
	}

	/*
	 * we will always try to init TDLS link with 11n capabilities
	 * let TDLS setup response to come, and we will set our caps based
	 * of peer caps
	 */

	wlan_cfg_get_int(mac, WNI_CFG_DOT11_MODE, &selfDot11Mode);

	/* Populate HT/VHT Capabilities */
	populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, &tdlsSetupReq.HTCaps,
					&tdlsSetupReq.VHTCaps, pe_session);

	/* Populate AID */
	populate_dotf_tdls_vht_aid(mac, selfDot11Mode, peer_mac,
				   &tdlsSetupReq.AID, pe_session);

	/* Populate TDLS offchannel param only if offchannel is enabled
	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
	 * IE in assoc/re-assoc response.
	 */
	if ((1 == mac->lim.gLimTDLSOffChannelEnabled) &&
	    (!pe_session->tdls_chan_swit_prohibited)) {
		populate_dot11f_tdls_offchannel_params(mac, pe_session,
						     &tdlsSetupReq.SuppChannels,
						     &tdlsSetupReq.
						     SuppOperatingClasses);
		if (mac->mlme_cfg->gen.band_capability != BAND_2G) {
			tdlsSetupReq.ht2040_bss_coexistence.present = 1;
			tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
		}
	} else {
		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
			mac->lim.gLimTDLSOffChannelEnabled,
			pe_session->tdls_chan_swit_prohibited);
	}
	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_setup_req_size(mac, &tdlsSetupReq,
						       &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a Setup Request (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for a Setup Request (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */

	nBytes = nPayload + ((IS_QOS_ENABLED(pe_session))
			     ? sizeof(tSirMacDataHdr3a) :
			     sizeof(tSirMacMgmtHdr))
		 + sizeof(eth_890d_header)
		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;

	/* Ok-- try to allocate memory from MGMT PKT pool */
	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
			(void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate %d bytes for a TDLS Setup Request",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * request frame
	 */

	/* fill out the buffer descriptor */

	header_offset = lim_prepare_tdls_frame_header(mac, pFrame,
			LINK_IDEN_ADDR_OFFSET(tdlsSetupReq),
			TDLS_LINK_AP, TDLS_INITIATOR,
			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
			pe_session);

	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
		tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
		tdlsSetupReq.VHTCaps.rxMCSMap,
		tdlsSetupReq.VHTCaps.txMCSMap,
		tdlsSetupReq.VHTCaps.txSupDataRate);

	status = dot11f_pack_tdls_setup_req(mac, &tdlsSetupReq, pFrame
					    + header_offset, nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS Setup request (0x%08x)",
			status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Setup Request (0x%08x)",
			status);
	}

	/* Copy the additional IE. */
	/* TODO : addIe is added at the end of the frame. This means it doesn't */
	/* follow the order. This should be ok, but we should consider changing this */
	/* if there is any IOT issue. */
	if (addIeLen != 0) {
		pe_debug("Copy Additional Ie Len = %d", addIeLen);
		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
			     addIeLen);
	}

	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_SETUP_REQ,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
		MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);

	qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket,
						     (uint16_t) nBytes,
						     TID_AC_VI,
						     pFrame,
						     smeSessionId, true);

	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Setup Request frame!");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;

}

/*
 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
 */
static
QDF_STATUS lim_send_tdls_teardown_frame(struct mac_context *mac,
					   struct qdf_mac_addr peer_mac,
					   uint16_t reason,
					   uint8_t responder,
					   struct pe_session *pe_session,
					   uint8_t *addIe, uint16_t addIeLen,
					   enum wifi_traffic_ac ac)
{
	tDot11fTDLSTeardown teardown;
	uint32_t status = 0;
	uint32_t nPayload = 0;
	uint32_t nBytes = 0;
	uint32_t header_offset = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	uint32_t padLen = 0;
#endif
	uint8_t smeSessionId = 0;
	tpDphHashNode sta_ds;
	uint16_t aid = 0;
	uint8_t qos_mode = 0;
	uint8_t tdls_link_type;

	if (NULL == pe_session) {
		pe_err("pe_session is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	smeSessionId = pe_session->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:
	 */
	qdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
	teardown.Category.category = SIR_MAC_ACTION_TDLS;
	teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
	teardown.Reason.code = reason;

	populate_dot11f_link_iden(mac, pe_session, &teardown.LinkIdentifier,
				  peer_mac,
				  (responder ==
				   true) ? TDLS_RESPONDER : TDLS_INITIATOR);

	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_teardown_size(mac, &teardown, &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a discovery Request (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for a discovery Request (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */
	sta_ds = dph_lookup_hash_entry(mac, pe_session->bssId, &aid,
					&pe_session->dph.dphHashTable);
	if (sta_ds)
		qos_mode = sta_ds->qosMode;
	tdls_link_type = (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
				? TDLS_LINK_AP : TDLS_LINK_DIRECT;
	nBytes = nPayload + (((IS_QOS_ENABLED(pe_session) &&
			     (tdls_link_type == TDLS_LINK_AP)) ||
			     ((tdls_link_type == TDLS_LINK_DIRECT) && qos_mode))
			     ? sizeof(tSirMacDataHdr3a) :
			     sizeof(tSirMacMgmtHdr))
		 + sizeof(eth_890d_header)
		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;

#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
	 */
	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
		padLen =
			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);

		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;

		nBytes += padLen;
	}
#endif

	/* Ok-- try to allocate memory from MGMT PKT pool */
	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
			(void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate %d bytes for a TDLS Teardown Frame.",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * request frame
	 */

	/* fill out the buffer descriptor */
	pe_debug("Reason of TDLS Teardown: %d", reason);
	header_offset = lim_prepare_tdls_frame_header(mac, pFrame,
			LINK_IDEN_ADDR_OFFSET(teardown),
			(reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ?
			TDLS_LINK_AP : TDLS_LINK_DIRECT,
			(responder == true) ? TDLS_RESPONDER : TDLS_INITIATOR,
			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
			pe_session);

	status = dot11f_pack_tdls_teardown(mac, &teardown, pFrame
					   + header_offset, nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS Teardown frame (0x%08x)",
			status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Teardown frame (0x%08x)",
			status);
	}

	if (addIeLen != 0) {
		pe_debug("Copy Additional Ie Len = %d", addIeLen);
		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
			     addIeLen);
	}
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	if (padLen != 0) {
		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
		uint8_t *padVendorSpecific =
			pFrame + header_offset + nPayload + addIeLen;
		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
		padVendorSpecific[0] = 221;
		padVendorSpecific[1] = padLen - 2;
		padVendorSpecific[2] = 0x00;
		padVendorSpecific[3] = 0xA0;
		padVendorSpecific[4] = 0xC6;

		pe_debug("Padding Vendor Specific Ie Len = %d", padLen);

		/* padding zero if more than 5 bytes are required */
		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
			qdf_mem_set(pFrame + header_offset + nPayload +
				    addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
	}
#endif
	pe_debug("[TDLS] action: %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_TEARDOWN,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
		((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
		    "DIRECT"),
		MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);

	qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket,
						     (uint16_t) nBytes,
						     TID_AC_VI,
						     pFrame,
						     smeSessionId,
						     (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
						     ? true : false);

	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Teardown frame");
		return QDF_STATUS_E_FAILURE;

	}

	return QDF_STATUS_SUCCESS;
}

/*
 * Send Setup RSP frame on AP link.
 */
static QDF_STATUS lim_send_tdls_setup_rsp_frame(struct mac_context *mac,
						   struct qdf_mac_addr peer_mac,
						   uint8_t dialog,
						   struct pe_session *pe_session,
						   etdlsLinkSetupStatus setupStatus,
						   uint8_t *addIe,
						   uint16_t addIeLen,
						   enum wifi_traffic_ac ac)
{
	tDot11fTDLSSetupRsp tdlsSetupRsp;
	uint32_t status = 0;
	uint16_t caps = 0;
	uint32_t nPayload = 0;
	uint32_t header_offset = 0;
	uint32_t nBytes = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
	uint32_t selfDot11Mode;
	uint8_t max_sp_length = 0;
/*  Placeholder to support different channel bonding mode of TDLS than AP. */
/*  Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
/*  To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
/*  As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
/*  uint32_t tdlsChannelBondingMode; */
	uint8_t smeSessionId = 0;

	if (NULL == pe_session) {
		pe_err("pe_session is NULL");
		return QDF_STATUS_E_FAILURE;
	}
	smeSessionId = pe_session->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:
	 */
	qdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);

	/*
	 * setup Fixed fields,
	 */
	tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
	tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
	tdlsSetupRsp.DialogToken.token = dialog;

	populate_dot11f_link_iden(mac, pe_session,
				  &tdlsSetupRsp.LinkIdentifier, peer_mac,
				  TDLS_RESPONDER);

	if (cfg_get_capability_info(mac, &caps, pe_session) != QDF_STATUS_SUCCESS) {
		/*
		 * Could not get Capabilities value
		 * from CFG. Log error.
		 */
		pe_err("could not retrieve Capabilities value");
	}
	swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);

	/* populate supported rate and ext supported rate IE */
	if (QDF_STATUS_E_FAILURE == populate_dot11f_rates_tdls(mac,
					&tdlsSetupRsp.SuppRates,
					&tdlsSetupRsp.ExtSuppRates,
					pe_session->currentOperChannel))
		pe_err("could not populate supported data rates");

	/* Populate extended capability IE */
	populate_dot11f_tdls_ext_capability(mac,
					    pe_session,
					    &tdlsSetupRsp.ExtCap);

	if (1 == mac->lim.gLimTDLSWmmMode) {

		pe_debug("populate WMM IE in Setup Response frame");
		max_sp_length = mac->mlme_cfg->wmm_params.max_sp_length;
		/* include WMM IE */
		tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
		tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
			(mac->lim.gLimTDLSUapsdMask & 0x01);
		tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
		tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
		tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
		tdlsSetupRsp.WMMInfoStation.max_sp_length = max_sp_length;
		tdlsSetupRsp.WMMInfoStation.present = 1;
	} else {
		/*
		 * TODO: we need to see if we have to support conditions where
		 * we have EDCA parameter info element is needed a) if we need
		 * different QOS parameters for off channel operations or QOS
		 * is not supported on AP link and we wanted to QOS on direct
		 * link.
		 */
		/* Populate QOS info, needed for Peer U-APSD session */
		/*
		 * TODO: Now hardcoded, because
		 * populate_dot11f_qos_caps_station() depends on AP's
		 * capability, and TDLS doesn't want to depend on AP's
		 * capability
		 */
		pe_debug("populate QOS IE in Setup Response frame");
		tdlsSetupRsp.QOSCapsStation.present = 1;
		tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
		tdlsSetupRsp.QOSCapsStation.qack = 0;
		tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
		tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
		tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
			((mac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
		tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
			(mac->lim.gLimTDLSUapsdMask & 0x01);
	}

	wlan_cfg_get_int(mac, WNI_CFG_DOT11_MODE, &selfDot11Mode);

	/* Populate HT/VHT Capabilities */
	populate_dot11f_tdls_ht_vht_cap(mac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
					&tdlsSetupRsp.VHTCaps, pe_session);

	/* Populate AID */
	populate_dotf_tdls_vht_aid(mac, selfDot11Mode, peer_mac,
				   &tdlsSetupRsp.AID, pe_session);

	/* Populate TDLS offchannel param only if offchannel is enabled
	 * and TDLS Channel Switching is not prohibited by AP in ExtCap
	 * IE in assoc/re-assoc response.
	 */
	if ((1 == mac->lim.gLimTDLSOffChannelEnabled) &&
	    (!pe_session->tdls_chan_swit_prohibited)) {
		populate_dot11f_tdls_offchannel_params(mac, pe_session,
						    &tdlsSetupRsp.SuppChannels,
						    &tdlsSetupRsp.
						    SuppOperatingClasses);
		if (mac->mlme_cfg->gen.band_capability != BAND_2G) {
			tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
			tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
		}
	} else {
		pe_debug("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled: %d tdls_chan_swit_prohibited: %d",
			mac->lim.gLimTDLSOffChannelEnabled,
			pe_session->tdls_chan_swit_prohibited);
	}
	tdlsSetupRsp.Status.status = setupStatus;
	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_setup_rsp_size(mac, &tdlsSetupRsp,
						       &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a Setup Response (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for Setup Response (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */

	nBytes = nPayload + ((IS_QOS_ENABLED(pe_session))
			     ? sizeof(tSirMacDataHdr3a) :
			     sizeof(tSirMacMgmtHdr))
		 + sizeof(eth_890d_header)
		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;

	/* Ok-- try to allocate memory from MGMT PKT pool */
	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate %d bytes for a TDLS Setup Response",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * request frame
	 */

	/* fill out the buffer descriptor */

	header_offset = lim_prepare_tdls_frame_header(mac, pFrame,
			LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), TDLS_LINK_AP,
			TDLS_RESPONDER,
			(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
			pe_session);

	pe_debug("SupportedChnlWidth: %x rxMCSMap: %x rxMCSMap: %x txSupDataRate: %x",
		tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
		tdlsSetupRsp.VHTCaps.rxMCSMap,
		tdlsSetupRsp.VHTCaps.txMCSMap,
		tdlsSetupRsp.VHTCaps.txSupDataRate);
	status = dot11f_pack_tdls_setup_rsp(mac, &tdlsSetupRsp,
					    pFrame + header_offset,
					    nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS Setup Response (0x%08x)",
			status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Setup Response (0x%08x)",
			status);
	}

	/* Copy the additional IE. */
	/* TODO : addIe is added at the end of the frame. This means it doesn't */
	/* follow the order. This should be ok, but we should consider changing this */
	/* if there is any IOT issue. */
	if (addIeLen != 0) {
		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
			     addIeLen);
	}

	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_SETUP_RSP,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
		MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);

	qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket,
						     (uint16_t) nBytes,
						     TID_AC_VI,
						     pFrame,
						     smeSessionId, true);

	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Dis Request frame!");
		return QDF_STATUS_E_FAILURE;
	}

	return QDF_STATUS_SUCCESS;
}

/*
 * Send TDLS setup CNF frame on AP link
 */
static
QDF_STATUS lim_send_tdls_link_setup_cnf_frame(struct mac_context *mac,
						 struct qdf_mac_addr peer_mac,
						 uint8_t dialog,
						 uint32_t peerCapability,
						 struct pe_session *pe_session,
						 uint8_t *addIe,
						 uint16_t addIeLen,
						 enum wifi_traffic_ac ac)
{
	tDot11fTDLSSetupCnf tdlsSetupCnf;
	uint32_t status = 0;
	uint32_t nPayload = 0;
	uint32_t nBytes = 0;
	uint32_t header_offset = 0;
	uint8_t *pFrame;
	void *pPacket;
	QDF_STATUS qdf_status;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	uint32_t padLen = 0;
#endif
	uint8_t smeSessionId = 0;

	/*
	 * 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:
	 */
	smeSessionId = pe_session->smeSessionId;

	qdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);

	/*
	 * setup Fixed fields,
	 */
	tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
	tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
	tdlsSetupCnf.DialogToken.token = dialog;

	populate_dot11f_link_iden(mac, pe_session,
				  &tdlsSetupCnf.LinkIdentifier, peer_mac,
				  TDLS_INITIATOR);
	/*
	 * TODO: we need to see if we have to support conditions where we have
	 * EDCA parameter info element is needed a) if we need different QOS
	 * parameters for off channel operations or QOS is not supported on
	 * AP link and we wanted to QOS on direct link.
	 */

	/* Check self and peer WMM capable */
	if ((1 == mac->lim.gLimTDLSWmmMode) &&
	    (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
		pe_debug("populate WMM praram in Setup Confirm");
		populate_dot11f_wmm_params(mac, &tdlsSetupCnf.WMMParams,
					   pe_session);
	}

	/* Check peer is VHT capable */
	if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
		populate_dot11f_vht_operation(mac,
					      pe_session,
					      &tdlsSetupCnf.VHTOperation);
		populate_dot11f_ht_info(mac, &tdlsSetupCnf.HTInfo, pe_session);
	} else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) {       /* Check peer is HT capable */
		populate_dot11f_ht_info(mac, &tdlsSetupCnf.HTInfo, pe_session);
	}

	/*
	 * now we pack it.  First, how much space are we going to need?
	 */
	status = dot11f_get_packed_tdls_setup_cnf_size(mac, &tdlsSetupCnf,
						       &nPayload);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to calculate the packed size for a Setup Confirm (0x%08x)",
			status);
		/* We'll fall back on the worst case scenario: */
		nPayload = sizeof(tDot11fProbeRequest);
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while calculating the packed size for Setup Confirm (0x%08x)",
			status);
	}

	/*
	 * This frame is going out from PE as data frames with special ethertype
	 * 89-0d.
	 * 8 bytes of RFC 1042 header
	 */

	nBytes = nPayload + ((IS_QOS_ENABLED(pe_session))
			     ? sizeof(tSirMacDataHdr3a) :
			     sizeof(tSirMacMgmtHdr))
		 + sizeof(eth_890d_header)
		 + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;

#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	/* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
	   Hence AP itself padding some bytes, which caused teardown packet is dropped at
	   receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
	 */
	if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
		padLen =
			MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);

		/* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
		if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
			padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;

		nBytes += padLen;
	}
#endif

	/* Ok-- try to allocate memory from MGMT PKT pool */
	qdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
				      (void **)&pPacket);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		pe_err("Failed to allocate %d bytes for a TDLS Setup Confirm",
			nBytes);
		return QDF_STATUS_E_NOMEM;
	}

	/* zero out the memory */
	qdf_mem_set(pFrame, nBytes, 0);

	/*
	 * IE formation, memory allocation is completed, Now form TDLS discovery
	 * request frame
	 */

	/* fill out the buffer descriptor */

	header_offset = lim_prepare_tdls_frame_header(mac, pFrame,
				LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf),
				TDLS_LINK_AP,
				TDLS_INITIATOR,
				(ac == WIFI_AC_VI) ? TID_AC_VI : TID_AC_BK,
				pe_session);

	status = dot11f_pack_tdls_setup_cnf(mac, &tdlsSetupCnf, pFrame
					    + header_offset, nPayload, &nPayload);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to pack a TDLS discovery req (0x%08x)", status);
		cds_packet_free((void *)pPacket);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("There were warnings while packing TDLS Discovery Request (0x%08x)",
			status);
	}

	/* Copy the additional IE. */
	/* TODO : addIe is added at the end of the frame. This means it doesn't */
	/* follow the order. This should be ok, but we should consider changing this */
	/* if there is any IOT issue. */
	if (addIeLen != 0) {
		qdf_mem_copy(pFrame + header_offset + nPayload, addIe,
			     addIeLen);
	}
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
	if (padLen != 0) {
		/* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
		uint8_t *padVendorSpecific =
			pFrame + header_offset + nPayload + addIeLen;
		/* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
		padVendorSpecific[0] = 221;
		padVendorSpecific[1] = padLen - 2;
		padVendorSpecific[2] = 0x00;
		padVendorSpecific[3] = 0xA0;
		padVendorSpecific[4] = 0xC6;

		pe_debug("Padding Vendor Specific Ie Len: %d", padLen);

		/* padding zero if more than 5 bytes are required */
		if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
			qdf_mem_set(pFrame + header_offset + nPayload +
				    addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
				    padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
	}
#endif

	pe_debug("[TDLS] action: %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR,
		SIR_MAC_TDLS_SETUP_CNF,
		lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
	       MAC_ADDR_ARRAY(peer_mac.bytes));

	mac->lim.tdls_frm_session_id = pe_session->smeSessionId;
	lim_diag_mgmt_tx_event_report(mac, (tpSirMacMgmtHdr) pFrame,
				      pe_session, QDF_STATUS_SUCCESS,
				      QDF_STATUS_SUCCESS);

	qdf_status = wma_tx_frame_with_tx_complete_send(mac, pPacket,
						     (uint16_t) nBytes,
						     TID_AC_VI,
						     pFrame,
						     smeSessionId, true);

	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		mac->lim.tdls_frm_session_id = NO_SESSION;
		pe_err("could not send TDLS Setup Confirm frame");
		return QDF_STATUS_E_FAILURE;

	}

	return QDF_STATUS_SUCCESS;
}

/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
 * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
 */
static QDF_STATUS lim_tdls_populate_dot11f_ht_caps(struct mac_context *mac,
						      struct pe_session *pe_session,
						      tSirTdlsAddStaReq *
						      pTdlsAddStaReq,
						      tDot11fIEHTCaps *pDot11f)
{
	uint32_t nCfgValue;
	uint8_t nCfgValue8;
	tSirMacHTParametersInfo *pHTParametersInfo;
	union {
		uint16_t nCfgValue16;
		struct mlme_ht_capabilities_info ht_cap_info;
		tSirMacExtendedHTCapabilityInfo extHtCapInfo;
	} uHTCapabilityInfo;

	tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
	tSirMacASCapabilityInfo *pASCapabilityInfo;

	nCfgValue = pTdlsAddStaReq->htCap.hc_cap;

	uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;

	pDot11f->advCodingCap = uHTCapabilityInfo.ht_cap_info.adv_coding_cap;
	pDot11f->mimoPowerSave = uHTCapabilityInfo.ht_cap_info.mimo_power_save;
	pDot11f->greenField = uHTCapabilityInfo.ht_cap_info.green_field;
	pDot11f->shortGI20MHz = uHTCapabilityInfo.ht_cap_info.short_gi_20_mhz;
	pDot11f->shortGI40MHz = uHTCapabilityInfo.ht_cap_info.short_gi_40_mhz;
	pDot11f->txSTBC = uHTCapabilityInfo.ht_cap_info.tx_stbc;
	pDot11f->rxSTBC = uHTCapabilityInfo.ht_cap_info.rx_stbc;
	pDot11f->delayedBA = uHTCapabilityInfo.ht_cap_info.delayed_ba;
	pDot11f->maximalAMSDUsize =
		uHTCapabilityInfo.ht_cap_info.maximal_amsdu_size;
	pDot11f->dsssCckMode40MHz =
		uHTCapabilityInfo.ht_cap_info.dsss_cck_mode_40_mhz;
	pDot11f->psmp = uHTCapabilityInfo.ht_cap_info.psmp;
	pDot11f->stbcControlFrame =
		uHTCapabilityInfo.ht_cap_info.stbc_control_frame;
	pDot11f->lsigTXOPProtection =
		uHTCapabilityInfo.ht_cap_info.l_sig_tx_op_protection;

	/*
	 * All sessionized entries will need the check below
	 * Only in case of NO session
	 */
	if (pe_session == NULL) {
		pDot11f->supportedChannelWidthSet =
			uHTCapabilityInfo.ht_cap_info.
			supported_channel_width_set;
	} else {
		pDot11f->supportedChannelWidthSet =
			pe_session->htSupportedChannelWidthSet;
	}

	/* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
	   eHT_CHANNEL_WIDTH_20MHZ */
	if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
		pDot11f->shortGI40MHz = 0;
	}

	pe_debug("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d",
		pDot11f->supportedChannelWidthSet,
		pDot11f->mimoPowerSave,
		pDot11f->greenField,
		pDot11f->shortGI20MHz,
		pDot11f->shortGI40MHz,
		pDot11f->dsssCckMode40MHz);

	nCfgValue = pTdlsAddStaReq->htCap.ampdu_param;

	nCfgValue8 = (uint8_t) nCfgValue;
	pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;

	pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
	pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
	pDot11f->reserved1 = pHTParametersInfo->reserved;

	pe_debug("AMPDU Param: %x", nCfgValue);
	qdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.mcsset,
		     SIZE_OF_SUPPORTED_MCS_SET);

	nCfgValue = pTdlsAddStaReq->htCap.extcap;

	uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;

	pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
	pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
	pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;

	nCfgValue = pTdlsAddStaReq->htCap.txbf_cap;

	pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
	pDot11f->txBF = pTxBFCapabilityInfo->txBF;
	pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
	pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
	pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
	pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
	pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
	pDot11f->calibration = pTxBFCapabilityInfo->calibration;
	pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
	pDot11f->explicitUncompressedSteeringMatrix =
		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
	pDot11f->explicitBFCSIFeedback =
		pTxBFCapabilityInfo->explicitBFCSIFeedback;
	pDot11f->explicitUncompressedSteeringMatrixFeedback =
		pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
	pDot11f->explicitCompressedSteeringMatrixFeedback =
		pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
	pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
	pDot11f->uncompressedSteeringMatrixBFAntennae =
		pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
	pDot11f->compressedSteeringMatrixBFAntennae =
		pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;

	nCfgValue = pTdlsAddStaReq->htCap.antenna;

	nCfgValue8 = (uint8_t) nCfgValue;

	pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
	pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
	pDot11f->explicitCSIFeedbackTx =
		pASCapabilityInfo->explicitCSIFeedbackTx;
	pDot11f->antennaIndicesFeedbackTx =
		pASCapabilityInfo->antennaIndicesFeedbackTx;
	pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
	pDot11f->antennaIndicesFeedback =
		pASCapabilityInfo->antennaIndicesFeedback;
	pDot11f->rxAS = pASCapabilityInfo->rxAS;
	pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;

	pDot11f->present = pTdlsAddStaReq->htcap_present;

	return QDF_STATUS_SUCCESS;

}

static QDF_STATUS
lim_tdls_populate_dot11f_vht_caps(struct mac_context *mac,
				  tSirTdlsAddStaReq *pTdlsAddStaReq,
				  tDot11fIEVHTCaps *pDot11f)
{
	uint32_t nCfgValue = 0;
	union {
		uint32_t nCfgValue32;
		tSirMacVHTCapabilityInfo vhtCapInfo;
	} uVHTCapabilityInfo;
	union {
		uint16_t nCfgValue16;
		tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
		tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
	} uVHTSupDataRateInfo;

	pDot11f->present = pTdlsAddStaReq->vhtcap_present;

	nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
	uVHTCapabilityInfo.nCfgValue32 = nCfgValue;

	pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
	pDot11f->supportedChannelWidthSet =
		uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
	pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
	pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
	pDot11f->shortGI160and80plus80MHz =
		uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
	pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
	pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
	pDot11f->suBeamFormerCap = 0;
	pDot11f->suBeamformeeCap = 0;
	pDot11f->csnofBeamformerAntSup =
		uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
	pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
	pDot11f->muBeamformerCap = 0;
	pDot11f->muBeamformeeCap = 0;
	pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
	pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
	pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
	pDot11f->vhtLinkAdaptCap =
		uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
	pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
	pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
	pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;

	pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;

	nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
	uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
	pDot11f->rxHighSupDataRate =
		uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;

	pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;

	nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
	uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
	pDot11f->txSupDataRate =
		uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;

	pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;

	lim_log_vht_cap(mac, pDot11f);

	return QDF_STATUS_SUCCESS;

}

/**
 * lim_tdls_populate_matching_rate_set() - populate matching rate set
 *
 * @mac_ctx  - global MAC context
 * @stads - station hash entry
 * @supp_rate_set - pointer to supported rate set
 * @supp_rates_len - length of the supported rates
 * @supp_mcs_set - pointer to supported MSC set
 * @session_entry - pointer to PE session entry
 * @vht_caps - pointer to VHT capability
 *
 *
 * This function gets set of available rates from the config and compare them
 * against the set of received supported rates. After the comparison station
 * entry's rates is populated with 11A rates and 11B rates.
 *
 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure.
 */
static QDF_STATUS
lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx, tpDphHashNode stads,
				    uint8_t *supp_rate_set,
				    uint8_t supp_rates_len,
				    uint8_t *supp_mcs_set,
				    struct pe_session *session_entry,
				    tDot11fIEVHTCaps *vht_caps)
{
	tSirMacRateSet temp_rate_set;
	uint32_t i, j, val, min, is_a_rate;
	tSirMacRateSet temp_rate_set2;
	uint32_t phymode;
	uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
	tpSirSupportedRates rates;
	uint8_t a_rateindex = 0;
	uint8_t b_rateindex = 0;
	uint8_t nss;
	qdf_size_t val_len;

	is_a_rate = 0;
	temp_rate_set2.numRates = 0;

	lim_get_phy_mode(mac_ctx, &phymode, NULL);

	/* get own rate set */
	val_len = mac_ctx->mlme_cfg->rates.opr_rate_set.len;
	if (wlan_mlme_get_cfg_str((uint8_t *)&temp_rate_set.rate,
				  &mac_ctx->mlme_cfg->rates.opr_rate_set,
				  &val_len) != QDF_STATUS_SUCCESS) {
		/* Could not get rateset from CFG. Log error. */
		pe_err("could not retrieve rateset");
		val_len = 0;
	}
	temp_rate_set.numRates = val_len;

	if (phymode == WNI_CFG_PHY_MODE_11G) {
		/* get own extended rate set */
		val_len = mac_ctx->mlme_cfg->rates.ext_opr_rate_set.len;
		if (wlan_mlme_get_cfg_str(
			(uint8_t *)&temp_rate_set2.rate,
			&mac_ctx->mlme_cfg->rates.ext_opr_rate_set,
			&val_len) != QDF_STATUS_SUCCESS) {
			/* Could not get rateset from CFG. Log error. */
			pe_err("could not retrieve extrateset");
			val_len = 0;
		}
			temp_rate_set2.numRates = val_len;
	}

	if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
		pe_err("more than 12 rates in CFG");
		return QDF_STATUS_E_FAILURE;
	}

	/**
	 * Handling of the rate set IEs is the following:
	 * - keep only rates that we support and that the station supports
	 * - sort and the rates into the pSta->rate array
	 */

	/* Copy all rates in temp_rate_set, there are 12 rates max */
	for (i = 0; i < temp_rate_set2.numRates; i++)
		temp_rate_set.rate[i + temp_rate_set.numRates] =
			temp_rate_set2.rate[i];

	temp_rate_set.numRates += temp_rate_set2.numRates;

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

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

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

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

	/**
	 * Copy received rates in temp_rate_set, the parser has ensured
	 * unicity of the rates so there cannot be more than 12 .
	 */
	if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
		pe_warn("Supported rates length: %d more than the Max limit, reset to Max",
			supp_rates_len);
		supp_rates_len = SIR_MAC_RATESET_EID_MAX;
	}

	for (i = 0; i < supp_rates_len; i++)
		temp_rate_set.rate[i] = supp_rate_set[i];

	temp_rate_set.numRates = supp_rates_len;

	rates = &stads->supportedRates;
	qdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);

	for (i = 0; i < temp_rate_set2.numRates; i++) {
		for (j = 0; j < temp_rate_set.numRates; j++) {
			if ((temp_rate_set2.rate[i] & 0x7F) !=
				(temp_rate_set.rate[j] & 0x7F))
				continue;

			if ((b_rateindex > SIR_NUM_11B_RATES) ||
			    (a_rateindex > SIR_NUM_11A_RATES)) {
				pe_warn("Invalid number of rates (11b->%d, 11a->%d)",
					b_rateindex, a_rateindex);
				return QDF_STATUS_E_FAILURE;
			}
			if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
				is_a_rate = 1;
				if (a_rateindex < SIR_NUM_11A_RATES)
					rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
			} else {
				if (b_rateindex < SIR_NUM_11B_RATES)
					rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
			}
			break;
		}
	}

	if (IS_5G_CH(session_entry->currentOperChannel))
		nss = mac_ctx->vdev_type_nss_5g.tdls;
	else
		nss = mac_ctx->vdev_type_nss_2g.tdls;

	nss = QDF_MIN(nss, mac_ctx->user_configured_nss);

	/* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
#ifdef FEATURE_WLAN_TDLS
	if (stads->mlmStaContext.htCapability)
#else
	if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
	    (stads->mlmStaContext.htCapability))
#endif
	{
		val_len = SIZE_OF_SUPPORTED_MCS_SET;
		if (wlan_mlme_get_cfg_str(
			mcsSet,
			&mac_ctx->mlme_cfg->rates.supported_mcs_set,
			&val_len) != QDF_STATUS_SUCCESS) {
			/* Could not get rateset from CFG. Log error. */
			pe_err("could not retrieve supportedMCSSet");
			return QDF_STATUS_E_FAILURE;
		}

		if (NSS_1x1_MODE == nss)
			mcsSet[1] = 0;
		for (i = 0; i < val_len; i++)
			stads->supportedRates.supportedMCSSet[i] =
				mcsSet[i] & supp_mcs_set[i];

		pe_debug("MCS Rate Set Bitmap from CFG and DPH");
		for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
			pe_debug("%x %x", mcsSet[i],
				stads->supportedRates.supportedMCSSet[i]);
		}
	}
	lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
				 session_entry, nss);
	/**
	 * Set the erpEnabled bit if the phy is in G mode and at least
	 * one A rate is supported
	 */
	if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
		stads->erpEnabled = eHAL_SET;

	return QDF_STATUS_SUCCESS;
}

/*
 * update HASH node entry info
 */
static void lim_tdls_update_hash_node_info(struct mac_context *mac,
					   tDphHashNode *pStaDs,
					   tSirTdlsAddStaReq *pTdlsAddStaReq,
					   struct pe_session *pe_session)
{
	tDot11fIEHTCaps htCap = {0,};
	tDot11fIEHTCaps *htCaps;
	tDot11fIEVHTCaps *pVhtCaps = NULL;
	tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
	tDot11fIEVHTCaps vhtCap;
	uint8_t cbMode;

	if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
		populate_dot11f_ht_caps(mac, pe_session, &htCap);
	} else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
		lim_tdls_populate_dot11f_ht_caps(mac, NULL, pTdlsAddStaReq, &htCap);
	}
	htCaps = &htCap;
	if (htCaps->present) {
		pStaDs->mlmStaContext.htCapability = 1;
		pStaDs->htGreenfield = htCaps->greenField;
		/*
		 * pStaDs->htSupportedChannelWidthSet should have the base
		 * channel capability. The htSupportedChannelWidthSet of the
		 * TDLS link on base channel should be less than or equal to
		 * channel width of STA-AP link. So take this setting from the
		 * pe_session.
		 */
		pe_debug("supportedChannelWidthSet: 0x%x htSupportedChannelWidthSet: 0x%x",
				htCaps->supportedChannelWidthSet,
				pe_session->htSupportedChannelWidthSet);
		pStaDs->htSupportedChannelWidthSet =
				(htCaps->supportedChannelWidthSet <
				 pe_session->htSupportedChannelWidthSet) ?
				htCaps->supportedChannelWidthSet :
				pe_session->htSupportedChannelWidthSet;
		pe_debug("pStaDs->htSupportedChannelWidthSet: 0x%x",
				pStaDs->htSupportedChannelWidthSet);

		pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
		pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
		pStaDs->htAMpduDensity = htCaps->mpduDensity;
		pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
		pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
		pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
		pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
		lim_fill_rx_highest_supported_rate(mac,
						   &pStaDs->supportedRates.
						   rxHighestDataRate,
						   htCaps->supportedMCSSet);
		pStaDs->baPolicyFlag = 0xFF;
		mac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
		pStaDs->ht_caps = pTdlsAddStaReq->htCap.hc_cap;
	} else {
		pStaDs->mlmStaContext.htCapability = 0;
		mac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
	}
	lim_tdls_populate_dot11f_vht_caps(mac, pTdlsAddStaReq, &vhtCap);
	pVhtCaps = &vhtCap;
	if (pVhtCaps->present) {
		pStaDs->mlmStaContext.vhtCapability = 1;

		/*
		 * 11.21.1 General: The channel width of the TDLS direct
		 * link on the base channel shall not exceed the channel
		 * width of the BSS to which the TDLS peer STAs are
		 * associated.
		 */
		if (pe_session->ch_width)
			pStaDs->vhtSupportedChannelWidthSet =
					pe_session->ch_width - 1;
		else
			pStaDs->vhtSupportedChannelWidthSet =
					pe_session->ch_width;

		pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu",
			pStaDs->vhtSupportedChannelWidthSet,
			pStaDs->htSupportedChannelWidthSet);

		pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
		pStaDs->vhtBeamFormerCapable = 0;
		mac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
		pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
		pVhtCaps_txbf->suBeamformeeCap = 0;
		pVhtCaps_txbf->suBeamFormerCap = 0;
		pVhtCaps_txbf->muBeamformerCap = 0;
		pVhtCaps_txbf->muBeamformeeCap = 0;
		pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
	} else {
		pStaDs->mlmStaContext.vhtCapability = 0;
		pStaDs->vhtSupportedChannelWidthSet =
			WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
	}

	/*
	 * Calculate the Secondary Coannel Offset if our
	 * own channel bonding state is enabled
	 */
	if (pe_session->htSupportedChannelWidthSet) {
		cbMode = lim_select_cb_mode(pStaDs, pe_session,
				    pe_session->currentOperChannel,
				    pStaDs->vhtSupportedChannelWidthSet);

		if (pStaDs->mlmStaContext.vhtCapability)
			pStaDs->htSecondaryChannelOffset =
					lim_get_htcb_state(cbMode);
		else
			pStaDs->htSecondaryChannelOffset = cbMode;
	}
	/* Lets enable QOS parameter */
	pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
				|| pTdlsAddStaReq->htcap_present;
	pStaDs->wmeEnabled = 1;
	pStaDs->lleEnabled = 0;
	/*  TDLS Dummy AddSTA does not have qosInfo , is it OK ??
	 */
	pStaDs->qos.capability.qosInfo =
		(*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);

	/* populate matching rate set */

	/* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
	 */
	lim_tdls_populate_matching_rate_set(mac, pStaDs,
					    pTdlsAddStaReq->supported_rates,
					    pTdlsAddStaReq->
					    supported_rates_length,
					    (uint8_t *)pTdlsAddStaReq->
					    htCap.mcsset,
					    pe_session, pVhtCaps);

	/*  TDLS Dummy AddSTA does not have right capability , is it OK ??
	 */
	pStaDs->mlmStaContext.capabilityInfo =
		(*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);

	return;
}

/*
 * Add STA for TDLS setup procedure
 */
static QDF_STATUS lim_tdls_setup_add_sta(struct mac_context *mac,
					    tSirTdlsAddStaReq *pAddStaReq,
					    struct pe_session *pe_session)
{
	tpDphHashNode pStaDs = NULL;
	QDF_STATUS status = QDF_STATUS_SUCCESS;
	uint16_t aid = 0;

	pStaDs = dph_lookup_hash_entry(mac, pAddStaReq->peermac.bytes, &aid,
				       &pe_session->dph.dphHashTable);

	if (pStaDs && pAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
		pe_err("TDLS entry for peer: "MAC_ADDRESS_STR " already exist, cannot add new entry",
			MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
			return QDF_STATUS_E_FAILURE;
	}

	if (pStaDs && pStaDs->staType != STA_ENTRY_TDLS_PEER) {
		pe_err("Non TDLS entry for peer: "MAC_ADDRESS_STR " already exist",
			MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
			return QDF_STATUS_E_FAILURE;
	}

	if (NULL == pStaDs) {
		aid = lim_assign_peer_idx(mac, pe_session);

		if (!aid) {
			pe_err("No more free AID for peer: "MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
			return QDF_STATUS_E_FAILURE;
		}

		/* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
		SET_PEER_AID_BITMAP(pe_session->peerAIDBitmap, aid);

		pe_debug("Aid: %d, for peer: " MAC_ADDRESS_STR,
			aid, MAC_ADDR_ARRAY(pAddStaReq->peermac.bytes));
		pStaDs =
			dph_get_hash_entry(mac, aid,
					   &pe_session->dph.dphHashTable);

		if (pStaDs) {
			(void)lim_del_sta(mac, pStaDs, false /*asynchronous */,
					  pe_session);
			lim_delete_dph_hash_entry(mac, pStaDs->staAddr, aid,
						  pe_session);
		}

		pStaDs = dph_add_hash_entry(mac, pAddStaReq->peermac.bytes,
					 aid, &pe_session->dph.dphHashTable);

		if (NULL == pStaDs) {
			pe_err("add hash entry failed");
			QDF_ASSERT(0);
			return QDF_STATUS_E_FAILURE;
		}
	}

	lim_tdls_update_hash_node_info(mac, pStaDs, pAddStaReq, pe_session);

	pStaDs->staType = STA_ENTRY_TDLS_PEER;

	status =
		lim_add_sta(mac, pStaDs,
			    (pAddStaReq->tdlsAddOper ==
			     TDLS_OPER_UPDATE) ? true : false, pe_session);

	if (QDF_STATUS_SUCCESS != status) {
		/* should not fail */
		QDF_ASSERT(0);
	}
	return status;
}

/*
 * Del STA, after Link is teardown or discovery response sent on direct link
 */
static QDF_STATUS lim_tdls_del_sta(struct mac_context *mac,
				      struct qdf_mac_addr peerMac,
				      struct pe_session *pe_session,
				      bool resp_reqd)
{
	QDF_STATUS status = QDF_STATUS_E_FAILURE;
	uint16_t peerIdx = 0;
	tpDphHashNode pStaDs;

	pStaDs = dph_lookup_hash_entry(mac, peerMac.bytes, &peerIdx,
				       &pe_session->dph.dphHashTable);

	if (pStaDs) {
		pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR,
			 MAC_ADDR_ARRAY(pStaDs->staAddr));

		pe_debug("STA type: %x, sta idx: %x resp_reqd: %d",
			 pStaDs->staType,
			 pStaDs->staIndex,
			 resp_reqd);

		status = lim_del_sta(mac, pStaDs, resp_reqd, pe_session);
	} else {
		pe_debug("DEL STA peer MAC: "MAC_ADDRESS_STR" not found",
			 MAC_ADDR_ARRAY(peerMac.bytes));
	}

	return status;
}

/*
 * Once Link is setup with PEER, send Add STA ind to SME
 */
static QDF_STATUS lim_send_sme_tdls_add_sta_rsp(struct mac_context *mac,
						uint8_t sessionId,
						tSirMacAddr peerMac,
						uint8_t updateSta,
						tDphHashNode *pStaDs, uint8_t status)
{
	struct scheduler_msg mmhMsg = { 0 };
	tSirTdlsAddStaRsp *addStaRsp = NULL;

	mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;

	addStaRsp = qdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
	if (!addStaRsp)
		return QDF_STATUS_E_NOMEM;

	addStaRsp->sessionId = sessionId;
	addStaRsp->statusCode = status;
	if (pStaDs) {
		addStaRsp->staId = pStaDs->staIndex;
	}
	if (peerMac) {
		qdf_mem_copy(addStaRsp->peermac.bytes,
			     (uint8_t *) peerMac, QDF_MAC_ADDR_SIZE);
	}
	if (updateSta)
		addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
	else
		addStaRsp->tdlsAddOper = TDLS_OPER_ADD;

	addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
	addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
	addStaRsp->psoc = mac->psoc;
	mmhMsg.bodyptr = addStaRsp;
	mmhMsg.callback = tgt_tdls_add_peer_rsp;

	return scheduler_post_message(QDF_MODULE_ID_PE,
				      QDF_MODULE_ID_TDLS,
				      QDF_MODULE_ID_TARGET_IF, &mmhMsg);
}

/*
 * STA RSP received from HAL
 */
QDF_STATUS lim_process_tdls_add_sta_rsp(struct mac_context *mac, void *msg,
					struct pe_session *pe_session)
{
	tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
	uint8_t status = QDF_STATUS_SUCCESS;
	tDphHashNode *pStaDs = NULL;
	uint16_t aid = 0;

	SET_LIM_PROCESS_DEFD_MESGS(mac, true);
	pe_debug("staIdx: %d, staMac: "MAC_ADDRESS_STR,
	       pAddStaParams->staIdx,
	       MAC_ADDR_ARRAY(pAddStaParams->staMac));

	if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
		QDF_ASSERT(0);
		pe_err("Add sta failed ");
		status = QDF_STATUS_E_FAILURE;
		goto add_sta_error;
	}

	pStaDs = dph_lookup_hash_entry(mac, pAddStaParams->staMac, &aid,
				       &pe_session->dph.dphHashTable);
	if (NULL == pStaDs) {
		pe_err("pStaDs is NULL ");
		status = QDF_STATUS_E_FAILURE;
		goto add_sta_error;
	}

	pStaDs->bssId = pAddStaParams->bssIdx;
	pStaDs->staIndex = pAddStaParams->staIdx;
	pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
	pStaDs->valid = 1;
add_sta_error:
	status = lim_send_sme_tdls_add_sta_rsp(mac, pe_session->smeSessionId,
					       pAddStaParams->staMac,
					       pAddStaParams->updateSta, pStaDs,
					       status);
	qdf_mem_free(pAddStaParams);
	return status;
}

/**
 * lim_send_tdls_comp_mgmt_rsp() - Send Response to upper layers
 * @mac_ctx:          Pointer to Global MAC structure
 * @msg_type:         Indicates message type
 * @result_code:       Indicates the result of previously issued
 *                    eWNI_SME_msg_type_REQ message
 *
 * This function is called by lim_process_sme_req_messages() to send
 * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
 * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
 * Software.
 *
 * Return: None
 */

static void
lim_send_tdls_comp_mgmt_rsp(struct mac_context *mac_ctx, uint16_t msg_type,
	 tSirResultCodes result_code, uint8_t sme_session_id,
	 uint16_t sme_transaction_id)
{
	struct scheduler_msg msg = {0};
	tSirSmeRsp *sme_rsp;

	pe_debug("Sending message %s with reasonCode %s",
		lim_msg_str(msg_type), lim_result_code_str(result_code));

	sme_rsp = qdf_mem_malloc(sizeof(tSirSmeRsp));
	if (!sme_rsp)
		return;

	sme_rsp->messageType = msg_type;
	sme_rsp->length = sizeof(tSirSmeRsp);
	sme_rsp->statusCode = result_code;

	sme_rsp->sessionId = sme_session_id;
	sme_rsp->transactionId = sme_transaction_id;

	msg.type = msg_type;
	sme_rsp->psoc = mac_ctx->psoc;
	msg.bodyptr = sme_rsp;
	msg.callback = tgt_tdls_send_mgmt_rsp;
	scheduler_post_message(QDF_MODULE_ID_PE,
			       QDF_MODULE_ID_TDLS,
			       QDF_MODULE_ID_TARGET_IF, &msg);

}

/**
 * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
 *
 * @mac_ctx - global mac context
 * @msg - message buffer received from SME.
 *
 * Process Send Mgmt Request from SME and transmit to AP.
 *
 * Return: QDF_STATUS_SUCCESS on success, error code otherwise
 */
QDF_STATUS lim_process_sme_tdls_mgmt_send_req(struct mac_context *mac_ctx,
						 uint32_t *msg)
{
	/* get all discovery request parameters */
	tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
	struct pe_session *session_entry;
	uint8_t session_id;
	tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;

	pe_debug("Send Mgmt Received");
	session_entry = pe_find_session_by_bssid(mac_ctx,
					 send_req->bssid.bytes, &session_id);
	if (NULL == session_entry) {
		pe_err("PE Session does not exist for given sme session_id %d",
			send_req->sessionId);
		goto lim_tdls_send_mgmt_error;
	}

	/* check if we are in proper state to work as TDLS client */
	if (!LIM_IS_STA_ROLE(session_entry)) {
		pe_err("send mgmt received in wrong system Role: %d",
			  GET_LIM_SYSTEM_ROLE(session_entry));
		goto lim_tdls_send_mgmt_error;
	}

	if (lim_is_roam_synch_in_progress(session_entry)) {
		pe_err("roaming in progress, reject mgmt! for session %d",
		       send_req->sessionId);
		result_code = eSIR_SME_REFUSED;
		goto lim_tdls_send_mgmt_error;
	}

	/*
	 * if we are still good, go ahead and check if we are in proper state to
	 * do TDLS discovery req/rsp/....frames.
	 */
	if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
	    (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
		pe_err("send mgmt received in invalid LIMsme state: %d",
			session_entry->limSmeState);
		goto lim_tdls_send_mgmt_error;
	}

	cds_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS,
		SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION,
		send_req->reqType, send_req->peer_mac.bytes);

	switch (send_req->reqType) {
	case SIR_MAC_TDLS_DIS_REQ:
		pe_debug("Transmit Discovery Request Frame");
		/* format TDLS discovery request frame and transmit it */
		lim_send_tdls_dis_req_frame(mac_ctx, send_req->peer_mac,
					    send_req->dialog, session_entry,
					    send_req->ac);
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_DIS_RSP:
		pe_debug("Transmit Discovery Response Frame");
		/* Send a response mgmt action frame */
		lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peer_mac,
			send_req->dialog, session_entry, &send_req->addIe[0],
			(send_req->length - sizeof(tSirTdlsSendMgmtReq)));
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_SETUP_REQ:
		pe_debug("Transmit Setup Request Frame");
		lim_send_tdls_link_setup_req_frame(mac_ctx,
			send_req->peer_mac, send_req->dialog, session_entry,
			&send_req->addIe[0],
			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
			send_req->ac);
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_SETUP_RSP:
		pe_debug("Transmit Setup Response Frame");
		lim_send_tdls_setup_rsp_frame(mac_ctx,
			send_req->peer_mac, send_req->dialog, session_entry,
			send_req->statusCode, &send_req->addIe[0],
			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
			send_req->ac);
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_SETUP_CNF:
		pe_debug("Transmit Setup Confirm Frame");
		lim_send_tdls_link_setup_cnf_frame(mac_ctx,
			send_req->peer_mac, send_req->dialog,
			send_req->peerCapability, session_entry,
			&send_req->addIe[0],
			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
			send_req->ac);
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_TEARDOWN:
		pe_debug("Transmit Teardown Frame");
		lim_send_tdls_teardown_frame(mac_ctx,
			send_req->peer_mac, send_req->statusCode,
			send_req->responder, session_entry,
			&send_req->addIe[0],
			(send_req->length - sizeof(tSirTdlsSendMgmtReq)),
			send_req->ac);
		result_code = eSIR_SME_SUCCESS;
		break;
	case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
		break;
	case SIR_MAC_TDLS_CH_SWITCH_REQ:
		break;
	case SIR_MAC_TDLS_CH_SWITCH_RSP:
		break;
	case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
		break;
	default:
		break;
	}

lim_tdls_send_mgmt_error:
	lim_send_tdls_comp_mgmt_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
		 result_code, send_req->sessionId,
		 send_req->transactionId);

	return QDF_STATUS_SUCCESS;
}

/*
 * Once link is teardown, send Del Peer Ind to SME
 */
static QDF_STATUS lim_send_sme_tdls_del_sta_rsp(struct mac_context *mac,
						uint8_t sessionId,
						struct qdf_mac_addr peerMac,
						tDphHashNode *pStaDs, uint8_t status)
{
	struct scheduler_msg mmhMsg = { 0 };
	tSirTdlsDelStaRsp *pDelSta = NULL;

	mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;

	pDelSta = qdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
	if (!pDelSta)
		return QDF_STATUS_E_NOMEM;

	pDelSta->sessionId = sessionId;
	pDelSta->statusCode = status;
	if (pStaDs) {
		pDelSta->staId = pStaDs->staIndex;
	} else
		pDelSta->staId = STA_INVALID_IDX;

	qdf_copy_macaddr(&pDelSta->peermac, &peerMac);

	pDelSta->length = sizeof(tSirTdlsDelStaRsp);
	pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
	pDelSta->psoc = mac->psoc;
	mmhMsg.bodyptr = pDelSta;
	mmhMsg.callback = tgt_tdls_del_peer_rsp;
	return scheduler_post_message(QDF_MODULE_ID_PE,
				      QDF_MODULE_ID_TDLS,
				      QDF_MODULE_ID_TARGET_IF, &mmhMsg);
}

/*
 * Process Send Mgmt Request from SME and transmit to AP.
 */
QDF_STATUS lim_process_sme_tdls_add_sta_req(struct mac_context *mac,
					       uint32_t *pMsgBuf)
{
	/* get all discovery request parameters */
	tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
	struct pe_session *pe_session;
	uint8_t sessionId;

	pe_debug("TDLS Add STA Request Received");
	pe_session =
		pe_find_session_by_bssid(mac, pAddStaReq->bssid.bytes,
					 &sessionId);
	if (pe_session == NULL) {
		pe_err("PE Session does not exist for given sme sessionId: %d",
			pAddStaReq->sessionId);
		goto lim_tdls_add_sta_error;
	}

	/* check if we are in proper state to work as TDLS client */
	if (!LIM_IS_STA_ROLE(pe_session)) {
		pe_err("send mgmt received in wrong system Role: %d",
			  GET_LIM_SYSTEM_ROLE(pe_session));
		goto lim_tdls_add_sta_error;
	}

	if (lim_is_roam_synch_in_progress(pe_session)) {
		pe_err("roaming in progress, reject add sta! for session %d",
		       pAddStaReq->sessionId);
		goto lim_tdls_add_sta_error;
	}

	/*
	 * if we are still good, go ahead and check if we are in proper state to
	 * do TDLS discovery req/rsp/....frames.
	 */
	if ((pe_session->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
	    (pe_session->limSmeState != eLIM_SME_LINK_EST_STATE)) {
		pe_err("send mgmt received in invalid LIMsme state: %d",
			pe_session->limSmeState);
		goto lim_tdls_add_sta_error;
	}


	/* To start with, send add STA request to HAL */
	if (QDF_STATUS_E_FAILURE == lim_tdls_setup_add_sta(mac, pAddStaReq, pe_session)) {
		pe_err("Add TDLS Station request failed");
		goto lim_tdls_add_sta_error;
	}
	return QDF_STATUS_SUCCESS;
lim_tdls_add_sta_error:
	lim_send_sme_tdls_add_sta_rsp(mac,
				      pAddStaReq->sessionId,
				      pAddStaReq->peermac.bytes,
				      (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
				      NULL, QDF_STATUS_E_FAILURE);

	return QDF_STATUS_SUCCESS;
}

/*
 * Process Del Sta Request from SME .
 */
QDF_STATUS lim_process_sme_tdls_del_sta_req(struct mac_context *mac,
					       uint32_t *pMsgBuf)
{
	/* get all discovery request parameters */
	tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
	struct pe_session *pe_session;
	uint8_t sessionId;
	QDF_STATUS status = QDF_STATUS_E_FAILURE;

	pe_debug("TDLS Delete STA Request Received");
	pe_session =
		pe_find_session_by_bssid(mac, pDelStaReq->bssid.bytes,
					 &sessionId);
	if (pe_session == NULL) {
		pe_err("PE Session does not exist for given sme sessionId: %d",
			pDelStaReq->sessionId);
		lim_send_sme_tdls_del_sta_rsp(mac, pDelStaReq->sessionId,
					      pDelStaReq->peermac, NULL,
					      QDF_STATUS_E_FAILURE);
		return QDF_STATUS_E_FAILURE;
	}

	/* check if we are in proper state to work as TDLS client */
	if (!LIM_IS_STA_ROLE(pe_session)) {
		pe_err("Del sta received in wrong system Role %d",
			  GET_LIM_SYSTEM_ROLE(pe_session));
		goto lim_tdls_del_sta_error;
	}

	if (lim_is_roam_synch_in_progress(pe_session)) {
		pe_err("roaming in progress, reject del sta! for session %d",
		       pDelStaReq->sessionId);
		lim_send_sme_tdls_del_sta_rsp(mac, pDelStaReq->sessionId,
					      pDelStaReq->peermac, NULL,
					      QDF_STATUS_E_FAILURE);
		return QDF_STATUS_E_FAILURE;
	}

	/*
	 * if we are still good, go ahead and check if we are in proper state to
	 * do TDLS discovery req/rsp/....frames.
	 */
	if ((pe_session->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
	    (pe_session->limSmeState != eLIM_SME_LINK_EST_STATE)) {

		pe_err("Del Sta received in invalid LIMsme state: (%d",
			pe_session->limSmeState);
		goto lim_tdls_del_sta_error;
	}

	status = lim_tdls_del_sta(mac, pDelStaReq->peermac,
				  pe_session, true);
	if (status == QDF_STATUS_SUCCESS)
		return status;

lim_tdls_del_sta_error:
	lim_send_sme_tdls_del_sta_rsp(mac, pe_session->smeSessionId,
				      pDelStaReq->peermac, NULL, QDF_STATUS_E_FAILURE);

	return status;
}

/**
 * lim_check_aid_and_delete_peer() - Function to check aid and delete peer
 * @p_mac: pointer to mac context
 * @session_entry: pointer to PE session
 *
 * This function verifies aid and delete's peer with that aid from hash table
 *
 * Return: None
 */
static void lim_check_aid_and_delete_peer(struct mac_context *p_mac,
					  struct pe_session *session_entry)
{
	tpDphHashNode stads = NULL;
	int i, aid;
	size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
	struct qdf_mac_addr mac_addr;
	QDF_STATUS status;

	/*
	 * Check all the set bit in peerAIDBitmap and delete the peer
	 * (with that aid) entry from the hash table and add the aid
	 * in free pool
	 */
	pe_debug("Delete all the TDLS peer connected");
	for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
		for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
			if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
				continue;
			stads = dph_get_hash_entry(p_mac,
					(aid + i * (sizeof(uint32_t) << 3)),
					&session_entry->dph.dphHashTable);

			if (NULL == stads)
				goto skip;

			pe_debug("Deleting "MAC_ADDRESS_STR,
				MAC_ADDR_ARRAY(stads->staAddr));

			if (!lim_is_roam_synch_in_progress(session_entry)) {
				lim_send_deauth_mgmt_frame(p_mac,
					eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
					stads->staAddr, session_entry, false);

				/* Delete TDLS peer */
				qdf_mem_copy(mac_addr.bytes, stads->staAddr,
					     QDF_MAC_ADDR_SIZE);

				status = lim_tdls_del_sta(p_mac, mac_addr,
							 session_entry, false);
				if (status != QDF_STATUS_SUCCESS)
					pe_debug("peer "MAC_ADDRESS_STR" not found",
						MAC_ADDR_ARRAY(stads->staAddr));
			}

			dph_delete_hash_entry(p_mac,
				stads->staAddr, stads->assocId,
				&session_entry->dph.dphHashTable);
skip:
			lim_release_peer_idx(p_mac,
				(aid + i * (sizeof(uint32_t) << 3)),
				session_entry);
			CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
		}
	}
}

/**
 * lim_delete_tdls_peers() - delete tdls peers
 *
 * @mac_ctx - global MAC context
 * @session_entry - PE session entry
 *
 * Delete all the TDLS peer connected before leaving the BSS
 *
 * Return: QDF_STATUS_SUCCESS on success, error code otherwise
 */
QDF_STATUS lim_delete_tdls_peers(struct mac_context *mac_ctx,
				    struct pe_session *session_entry)
{
	pe_debug("Enter");

	if (NULL == session_entry) {
		pe_err("NULL session_entry");
		return QDF_STATUS_E_FAILURE;
	}

	lim_check_aid_and_delete_peer(mac_ctx, session_entry);

	if (lim_is_roam_synch_in_progress(session_entry))
		return QDF_STATUS_SUCCESS;

	tgt_tdls_peers_deleted_notification(mac_ctx->psoc,
					    session_entry->smeSessionId);

	tgt_tdls_delete_all_peers_indication(mac_ctx->psoc,
					     session_entry->smeSessionId);

	pe_debug("Exit");
	return QDF_STATUS_SUCCESS;
}

/**
 * lim_process_sme_del_all_tdls_peers(): process delete tdls peers
 * @p_mac: pointer to mac context
 * @msg_buf: message buffer
 *
 * This function processes request to delete tdls peers
 *
 * Return: Success: QDF_STATUS_SUCCESS Failure: Error value
 */
QDF_STATUS lim_process_sme_del_all_tdls_peers(struct mac_context *p_mac,
						 uint32_t *msg_buf)
{
	struct sir_del_all_tdls_peers *msg;
	struct pe_session *session_entry;
	uint8_t session_id;

	msg = (struct sir_del_all_tdls_peers *)msg_buf;
	if (msg == NULL) {
		pe_err("NULL msg");
		return QDF_STATUS_E_FAILURE;
	}

	session_entry = pe_find_session_by_bssid(p_mac,
						 msg->bssid.bytes, &session_id);
	if (NULL == session_entry) {
		pe_err("NULL pe_session");
		return QDF_STATUS_E_FAILURE;
	}

	lim_check_aid_and_delete_peer(p_mac, session_entry);

	tgt_tdls_peers_deleted_notification(p_mac->psoc,
					    session_entry->smeSessionId);

	return QDF_STATUS_SUCCESS;
}

/**
 * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS
 * @mac_ctx: Global MAC context
 * @lim_msg: LIM message
 * @pe_session: PE session
 *
 * Return: None
 */
void lim_process_tdls_del_sta_rsp(struct mac_context *mac_ctx,
				  struct scheduler_msg *lim_msg,
				  struct pe_session *session_entry)
{
	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
	tpDphHashNode sta_ds;
	uint16_t peer_idx = 0;
	struct qdf_mac_addr peer_mac;

	if (!del_sta_params) {
		pe_err("del_sta_params is NULL");
		return;
	}

	sta_ds = dph_lookup_hash_entry(mac_ctx, del_sta_params->staMac,
			&peer_idx, &session_entry->dph.dphHashTable);
	if (!sta_ds) {
		pe_err("DPH Entry for STA: %X is missing",
			DPH_STA_HASH_INDEX_PEER);
		goto skip_event;
	}

	qdf_mem_copy(peer_mac.bytes,
			del_sta_params->staMac, QDF_MAC_ADDR_SIZE);

	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
		pe_err("DEL STA failed!");
		lim_send_sme_tdls_del_sta_rsp(mac_ctx,
				      session_entry->smeSessionId,
				      peer_mac, NULL, QDF_STATUS_E_FAILURE);
		goto skip_event;
	}

	pe_debug("DEL STA success");

	/* now send indication to SME-->HDD->TL to remove STA from TL */

	lim_send_sme_tdls_del_sta_rsp(mac_ctx, session_entry->smeSessionId,
				      peer_mac, sta_ds,
				      QDF_STATUS_SUCCESS);
	lim_release_peer_idx(mac_ctx, sta_ds->assocId, session_entry);

	/* Clear the aid in peerAIDBitmap as this aid is now in freepool */
	CLEAR_PEER_AID_BITMAP(session_entry->peerAIDBitmap,
			      sta_ds->assocId);
	lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
				  session_entry);

skip_event:
	qdf_mem_free(del_sta_params);
	lim_msg->bodyptr = NULL;
}


#endif
