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

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

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

                      limProcessTdls.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 limProcessTdls.c
 *
 * \brief Code for preparing,processing and sending 802.11z action frames
 *
 */

#ifdef FEATURE_WLAN_TDLS

#include "sirApi.h"
#include "aniGlobal.h"
#include "sirMacProtDef.h"
#include "cfgApi.h"
#include "utilsApi.h"
#include "limTypes.h"
#include "limUtils.h"
#include "limSecurityUtils.h"
#include "dot11f.h"
#include "limStaHashApi.h"
#include "schApi.h"
#include "limSendMessages.h"
#include "utilsParser.h"
#include "limAssocUtils.h"
#include "dphHashTable.h"
#include "wlan_qct_wda.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
#ifdef WLAN_FEATURE_TDLS_DEBUG
#define TDLS_DEBUG_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
#else
#define TDLS_DEBUG_LOG_LEVEL VOS_TRACE_LEVEL_INFO
#endif

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/* forword declarations */
static tSirRetStatus limTdlsDisAddSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
                   tSirTdlsPeerInfo *peerInfo, tpPESession psessionEntry) ;
static eHalStatus limSendSmeTdlsLinkSetupInd(tpAniSirGlobal pMac, 
                                   tSirMacAddr peerMac, tANI_U8 status);
static eHalStatus limSendSmeTdlsDelPeerInd(tpAniSirGlobal pMac, 
                 tANI_U8 sessionId, tDphHashNode   *pStaDs, tANI_U8 status) ;
static tSirTdlsPeerInfo *limTdlsFindDisPeerByState(tpAniSirGlobal pMac, 
                                                            tANI_U8 state);
static tANI_U8 limTdlsFindSetupPeerByState(tpAniSirGlobal pMac, tANI_U8 state, 
                                     tLimTdlsLinkSetupPeer **setupPeer) ;
static tSirRetStatus limTdlsLinkEstablish(tpAniSirGlobal pMac, tSirMacAddr peer_mac);

static tSirRetStatus limTdlsLinkTeardown(tpAniSirGlobal pMac, tSirMacAddr peer_mac);
static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac, 
                                                 tpPESession psessionEntry) ;

#endif
static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac,
                                        tSirTdlsAddStaReq *pAddStaReq,
                                        tpPESession psessionEntry) ;
void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
                          tDot11fIELinkIdentifier *linkIden, 
                             tSirMacAddr peerMac, tANI_U8 reqType) ;
void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, 
                                    tDot11fIEExtCap *extCapability) ;

void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac,
          tpPESession psessionEntry,
          tDot11fIESuppChannels *suppChannels,
          tDot11fIESuppOperatingClasses *suppOperClasses);

void limLogVHTCap(tpAniSirGlobal pMac,
                              tDot11fIEVHTCaps *pDot11f);
tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac,
                                  tpSirSupportedRates pRates,
                                  tDot11fIEVHTCaps *pPeerVHTCaps,
                                  tpPESession psessionEntry);
ePhyChanBondState  limGetHTCBState(ePhyChanBondState aniCBMode);
/*
 * TDLS data frames will go out/come in as non-qos data.
 * so, eth_890d_header will be aligned access..
 */
static const tANI_U8 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
} eTdlsLink ;

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


enum tdlsReqType
{
    TDLS_INITIATOR,
    TDLS_RESPONDER
} eTdlsReqType ;

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

/* some local defines */
#define LINK_IDEN_BSSID_OFFSET      (0)
#define PEER_MAC_OFFSET   (12) 
#define STA_MAC_OFFSET    (6)
#define LINK_IDEN_ELE_ID  (101)
//#define LINK_IDEN_LENGTH   (18) 
#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 PEER_BUFFER_STA_SUPPORT   (0)
#define CH_SWITCH_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) \
                                if ((aid) < (sizeof(tANI_U32) << 3)) \
                                        SET_BIT(peer_bitmap[0], (aid)); \
                                else if ((aid) < (sizeof(tANI_U32) << 4)) \
                                        SET_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3)));

#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
                                if ((aid) < (sizeof(tANI_U32) << 3)) \
                                        CLEAR_BIT(peer_bitmap[0], (aid)); \
                                else if ((aid) < (sizeof(tANI_U32) << 4)) \
                                        CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3)));


#ifdef LIM_DEBUG_TDLS

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

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

#define TID_AC_VI                  4
#define TID_AC_BK                  1

const tANI_U8* limTraceTdlsActionString( tANI_U8 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 tANI_U8*)"UNKNOWN";
}
#endif
#if 0
static void printMacAddr(tSirMacAddr macAddr)
{
    int i = 0 ;
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, (" Mac Addr: "));

    for(i = 0 ; i < 6; i++)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                                 (" %02x "), macAddr[i]);
    }
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, (""));
    return ;
}
#endif
/*
 * initialize TDLS setup list and related data structures.
 */
void limInitTdlsData(tpAniSirGlobal pMac, tpPESession pSessionEntry)
{
#ifdef FEATURE_WLAN_TDLS_INTERNAL
    pMac->lim.gLimTdlsDisResultList = NULL ;
    pMac->lim.gLimTdlsDisStaCount = 0 ;
    vos_mem_set(&pMac->lim.gLimTdlsDisReq, sizeof(tSirTdlsDisReq), 0);
    vos_mem_set(&pMac->lim.gLimTdlsLinkSetupInfo, sizeof(tLimTdlsLinkSetupInfo), 0);
    pMac->lim.gAddStaDisRspWait = 0 ;

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    /* when reassociated, negative behavior will not be kept */
    /* you have to explicitly enable negative behavior per (re)association */
    pMac->lim.gLimTdlsNegativeBehavior = 0;
#endif
#endif
    limInitPeerIdxpool(pMac, pSessionEntry) ;

    return ;
}
#ifdef FEATURE_WLAN_TDLS_NEGATIVE
void limTdlsSetNegativeBehavior(tpAniSirGlobal pMac, tANI_U8 value, tANI_BOOLEAN on)
{
    if(on) {
        if(value == 255)
            pMac->lim.gLimTdlsNegativeBehavior = 0XFFFFFFFF;
        else
            pMac->lim.gLimTdlsNegativeBehavior |= (1 << (value-1));
    }
    else {
        if(value == 255)
            pMac->lim.gLimTdlsNegativeBehavior = 0;
        else
            pMac->lim.gLimTdlsNegativeBehavior &= ~(1 << (value-1));
    }
    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,("%d %d -> gLimTdlsNegativeBehavior= 0x%lx"),
        value, on, pMac->lim.gLimTdlsNegativeBehavior));
}
#endif
#if 0
/*
 * This function is used for creating TDLS public Action frame to
 * transmit on Direct link
 */
static void limPreparesActionFrameHdr(tpAniSirGlobal pMac, tANI_U8 *pFrame,
                                         tANI_U8 type, tANI_U8 subType,
                                                   tANI_U8 *link_iden )
{
    tpSirMacMgmtHdr pMacHdr ;
    tANI_U8 *bssid = link_iden ;
#if 0     
    tANI_U8 *staMac = (tANI_U8 *)(bssid + sizeof(tSirMacAddr)) ;
    tANI_U8 *peerMac = (tANI_U8 *) (staMac + sizeof(tSirMacAddr)) ;
#else    
   tANI_U8 *peerMac = (tANI_U8 *) (bssid + sizeof(tSirMacAddr)) ;
   tANI_U8 *staMac = (tANI_U8 *)(peerMac + sizeof(tSirMacAddr)) ;
#endif    
    tANI_U8 toDs =  ANI_TXDIR_IBSS  ;

    pMacHdr = (tpSirMacMgmtHdr) (pFrame);

    /*
     * prepare 802.11 header
     */ 
    pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
    pMacHdr->fc.type    = type ;
    pMacHdr->fc.subType = subType ;
    /*
     * TL is not setting up below fields, so we are doing it here
     */
    pMacHdr->fc.toDS    = toDs ;
    pMacHdr->fc.powerMgmt = 0 ;

     
    vos_mem_copy( (tANI_U8 *) pMacHdr->da, peerMac, sizeof( tSirMacAddr ));
    vos_mem_copy( (tANI_U8 *) pMacHdr->sa,
                   staMac, sizeof( tSirMacAddr ));

    vos_mem_copy( (tANI_U8 *) pMacHdr->bssId,
                                bssid, sizeof( tSirMacAddr ));
   
   LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN, ("Preparing TDLS action frame\n%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x"),
       pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5],
       pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5],
       pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2],
       pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5]));

    return ; 
}
#endif
/*
 * prepare TDLS frame header, it includes
 * |             |              |                |
 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
 * |             |              |                |
 */
static tANI_U32 limPrepareTdlsFrameHeader(tpAniSirGlobal pMac, tANI_U8* pFrame, 
           tDot11fIELinkIdentifier *link_iden, tANI_U8 tdlsLinkType, tANI_U8 reqType,
           tANI_U8 tid, tpPESession psessionEntry)
{
    tpSirMacDataHdr3a pMacHdr ;
    tANI_U32 header_offset = 0 ;
    tANI_U8 *addr1 = NULL ;
    tANI_U8 *addr3 = NULL ;
    tANI_U8 toDs = (tdlsLinkType == TDLS_LINK_AP) 
                                       ? ANI_TXDIR_TODS :ANI_TXDIR_IBSS  ;
    tANI_U8 *peerMac = (reqType == TDLS_INITIATOR) 
                                       ? link_iden->RespStaAddr : link_iden->InitStaAddr; 
    tANI_U8 *staMac = (reqType == TDLS_INITIATOR) 
                                       ? link_iden->InitStaAddr : link_iden->RespStaAddr; 
   
    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 ;
    pMacHdr->fc.subType = IS_QOS_ENABLED(psessionEntry) ? 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 = (psessionEntry->encryptType == eSIR_ED_NONE)? 0 : 1;

     
    vos_mem_copy( (tANI_U8 *) pMacHdr->addr1,
                  (tANI_U8 *)addr1,
                  sizeof( tSirMacAddr ));
    vos_mem_copy( (tANI_U8 *) pMacHdr->addr2,
                  (tANI_U8 *) staMac,
                  sizeof( tSirMacAddr ));

    vos_mem_copy( (tANI_U8 *) pMacHdr->addr3,
                  (tANI_U8 *) (addr3),
                  sizeof( tSirMacAddr ));

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN, ("Preparing TDLS frame header to %s\n%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x"),
       (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "TD",
        pMacHdr->addr1[0], pMacHdr->addr1[1], pMacHdr->addr1[2], pMacHdr->addr1[3], pMacHdr->addr1[4], pMacHdr->addr1[5],
        pMacHdr->addr2[0], pMacHdr->addr2[1], pMacHdr->addr2[2], pMacHdr->addr2[3], pMacHdr->addr2[4], pMacHdr->addr2[5],
        pMacHdr->addr3[0], pMacHdr->addr3[1], pMacHdr->addr3[2], pMacHdr->addr3[3], pMacHdr->addr3[4], pMacHdr->addr3[5]));

    //printMacAddr(pMacHdr->bssId) ;
    //printMacAddr(pMacHdr->sa) ;
    //printMacAddr(pMacHdr->da) ;

    if (IS_QOS_ENABLED(psessionEntry))
    {
        pMacHdr->qosControl.tid = tid;
        header_offset += sizeof(tSirMacDataHdr3a);
    }
    else
        header_offset += sizeof(tSirMacMgmtHdr);

    /* 
     * Now form RFC1042 header
     */
    vos_mem_copy((tANI_U8 *)(pFrame + header_offset),
                 (tANI_U8 *)eth_890d_header, sizeof(eth_890d_header)) ;

    header_offset += sizeof(eth_890d_header) ; 

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

    return(header_offset += PAYLOAD_TYPE_TDLS_SIZE) ; 
}

/*
 * TX Complete for Management frames
 */
 eHalStatus limMgmtTXComplete(tpAniSirGlobal pMac,
                                   tANI_U32 txCompleteSuccess)
{
    tpPESession psessionEntry = NULL ;

    if (0xff != pMac->lim.mgmtFrameSessionId)
    {
        psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.mgmtFrameSessionId);
        if (NULL == psessionEntry)
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                      ("%s: sessionID %d is not found"), __func__, pMac->lim.mgmtFrameSessionId);
            return eHAL_STATUS_FAILURE;
        }
        limSendSmeMgmtTXCompletion(pMac, psessionEntry, txCompleteSuccess);
        pMac->lim.mgmtFrameSessionId = 0xff;
    }
    return eHAL_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,
 */
tSirRetStatus limSendTdlsDisReqFrame(tpAniSirGlobal pMac, tSirMacAddr peer_mac,
                                      tANI_U8 dialog, tpPESession psessionEntry)
{
    tDot11fTDLSDisReq   tdlsDisReq ;
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            size = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
    tANI_U32            padLen = 0;
#endif

    /* 
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set( (tANI_U8*)&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) ;
   
    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisReq.LinkIdentifier, 
                                                 peer_mac, TDLS_INITIATOR) ;

    /* 
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSDisReqSize( pMac, &tdlsDisReq, &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fTDLSDisReq );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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(psessionEntry))
                              ? 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 */

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, 
           LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP, TDLS_INITIATOR, TID_AC_VI, psessionEntry) ;

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_REQ)
    {
        tdlsDisReq.LinkIdentifier.bssid[4] = 0xde;
        tdlsDisReq.LinkIdentifier.bssid[5] = 0xad; 
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Discovery Req"),
        MAC_ADDR_ARRAY(tdlsDisReq.LinkIdentifier.bssid));
    }
#endif
    status = dot11fPackTDLSDisReq( pMac, &tdlsDisReq, pFrame 
                               + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req "
                               "(0x%08x)."), status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, 
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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 }; */
        tANI_U8 *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;

        LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
                padLen ));

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

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA "),
            SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) ));

    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_TODS,
                            TID_AC_VI,
                            limTxComplete, pFrame,
                            limMgmtTXComplete,
                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME);
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;
    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;

    return eSIR_SUCCESS;

}

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * Once Discovery response is sent successfully (or failure) on air, now send
 * response to PE and send del STA to HAL.
 */
eHalStatus limTdlsDisRspTxComplete(tpAniSirGlobal pMac, 
                                           tANI_U32 txCompleteSuccess)
{
    eHalStatus status = eHAL_STATUS_SUCCESS ;
    tpDphHashNode pStaDs = NULL ;
    tSirTdlsPeerInfo *peerInfo = 0 ;

    /* find peer by looking into the list by expected state */
    peerInfo = limTdlsFindDisPeerByState(pMac, TDLS_DIS_RSP_SENT_WAIT_STATE) ;

    if(NULL == peerInfo)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                       ("DisRspTxComplete: No TDLS state machine waits for this event"));
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }

    peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_DONE_STATE ;

    if(peerInfo->delStaNeeded)
    {
        tpPESession psessionEntry;
        
        peerInfo->delStaNeeded = false ;
        psessionEntry = peFindSessionBySessionId (pMac, peerInfo->sessionId);

        if(NULL == psessionEntry) 
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                           ("DisRspTxComplete: sessionID %d is not found"), peerInfo->sessionId);
            return eHAL_STATUS_FAILURE;
        }
        /* send del STA to remove context for this TDLS STA */
        pStaDs = limTdlsDelSta(pMac, peerInfo->peerMac, psessionEntry) ;

        /* now send indication to SME-->HDD->TL to remove STA from TL */
        if(pStaDs)
        {
            limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId, 
                                                     pStaDs, eSIR_SUCCESS) ;
        }
        else
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                           ("DisRspTxComplete: staDs not found for " MAC_ADDRESS_STR),
                           MAC_ADDR_ARRAY((peerInfo)->peerMac));
            VOS_ASSERT(0) ;
            return eHAL_STATUS_FAILURE;
        }
    }
 
    if(!txCompleteSuccess)
     {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                       ("TX complete failure for Dis RSP"));
        limSendSmeTdlsDisRsp(pMac, eSIR_FAILURE, 
                                     eWNI_SME_TDLS_DISCOVERY_START_IND) ;
        status = eHAL_STATUS_FAILURE;
    }
    else
    {
        limSendSmeTdlsDisRsp(pMac, eSIR_SUCCESS, 
                                     eWNI_SME_TDLS_DISCOVERY_START_IND) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                       ("TX complete Success for Dis RSP"));
        status = eHAL_STATUS_SUCCESS ;
    }
    //pMac->hal.pCBackFnTxComp = NULL ;
    return status ;

}
#endif

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * Once setup CNF is sent successfully (or failure) on air, now send
 * response to PE and send del STA to HAL.
 */
eHalStatus limTdlsSetupCnfTxComplete(tpAniSirGlobal pMac,
                                           tANI_U32 txCompleteSuccess)
{
    eHalStatus status = eHAL_STATUS_SUCCESS ;
    tLimTdlsLinkSetupPeer *peerInfo = 0 ;
    /* find peer by looking into the list by expected state */
    limTdlsFindSetupPeerByState(pMac, 
                             TDLS_LINK_SETUP_RSP_WAIT_STATE, &peerInfo) ;
  
    if(NULL == peerInfo)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                       ("limTdlsSetupCnfTxComplete: No TDLS state machine waits for this event"));
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }
 
    (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
    (peerInfo)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ; 

    if(!txCompleteSuccess)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                   ("TX complete Failure for setup CNF"));
        limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE, (peerInfo)->peerMac,
                                               eWNI_SME_TDLS_LINK_START_RSP) ;
        status = eHAL_STATUS_FAILURE;
    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
              ("RSP-->SME peer MAC = " MAC_ADDRESS_STR),
               MAC_ADDR_ARRAY((peerInfo)->peerMac));
    
        limSendSmeTdlsLinkStartRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
                                               eWNI_SME_TDLS_LINK_START_RSP) ;

        /* tdls_hklee: prepare PTI template and send it to HAL */
        limTdlsLinkEstablish(pMac, (peerInfo)->peerMac);

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                 ("TX complete Success for setup CNF"));
        status = eHAL_STATUS_SUCCESS ;
    }
    //pMac->hal.pCBackFnTxComp = NULL ;
    return status ;
}
#endif

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * Tx Complete for Teardown frame
 */
eHalStatus limTdlsTeardownTxComplete(tpAniSirGlobal pMac,
                                           tANI_U32 txCompleteSuccess)  
{
    eHalStatus status = eHAL_STATUS_SUCCESS ;
    tpDphHashNode pStaDs = NULL ;
    tLimTdlsLinkSetupPeer *peerInfo = 0 ;
    tpPESession psessionEntry = NULL ;
    //tANI_U16 msgType = 0 ;

    //tSirMacAddr peerMac = {0} ;
    /* find peer by looking into the list by expected state */
    limTdlsFindSetupPeerByState(pMac, 
                             TDLS_LINK_TEARDOWN_START_STATE, &peerInfo) ;
  
    if(NULL == peerInfo)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                       ("limTdlsTeardownTxComplete: No TDLS state machine waits for this event"));
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                  ("teardown peer Mac = " MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY((peerInfo)->peerMac));
             

    //pMac->hal.pCBackFnTxComp = NULL ;

    psessionEntry = peFindSessionBySessionId(pMac, (peerInfo)->tdls_sessionId);

    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                       ("limTdlsTeardownTxComplete: sessionID %d is not found"), (peerInfo)->tdls_sessionId);
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }

    if(!txCompleteSuccess)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                         ("TX complete failure for Teardown  ")) ;

        /* 
         * we should be sending Teradown to AP with status code 
         * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, we are not worried if 
         * that is delivered or not, any way we removing this peer STA from our
         * list
         */
        if(NULL != psessionEntry)
        {
            limSendTdlsTeardownFrame(pMac, (peerInfo)->peerMac, 
                     eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, psessionEntry, NULL, 0) ;
        }
    }

    if(TDLS_LINK_SETUP_WAIT_STATE != (peerInfo)->tdls_prev_link_state)
    {
        (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
        (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ; 
        /* send del STA to remove context for this TDLS STA */
        if(NULL != psessionEntry)
        {
            /* tdls_hklee: send message to HAL before it is deleted */
            limTdlsLinkTeardown(pMac, (peerInfo)->peerMac) ;

            pStaDs = limTdlsDelSta(pMac, (peerInfo)->peerMac, psessionEntry) ;
        }

        /* now send indication to SME-->HDD->TL to remove STA from TL */
        if(!pStaDs)
        {
            VOS_ASSERT(0) ;
            return eSIR_FAILURE ;
        }
        limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId, 
                                                pStaDs, eSIR_SUCCESS) ;
 
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                      ("TX complete SUCCESS for Teardown")) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                      ("Prev State = %d"), (peerInfo)->tdls_prev_link_state) ;
        limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
                                                     eWNI_SME_TDLS_TEARDOWN_RSP) ;
        /* Delete Peer for Link Peer List */
        limTdlsDelLinkPeer(pMac, (peerInfo)->peerMac) ;
    }
    else
    {
        (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
        (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ; 
        limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
                                                eWNI_SME_TDLS_TEARDOWN_IND) ;
    }


#if 0
    /* if previous state is link restart, then restart link setup again */
    if(TDLS_LINK_SETUP_RESTART_STATE == (peerInfo)->tdls_prev_link_state)
    {
        tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
        limTdlsPrepareSetupReqFrame(pMac, setupInfo, 37, 
                                                   peerMac, psessionEntry) ;
    }
#endif  
    status = eHAL_STATUS_SUCCESS ;
    return status ;
}
#endif

/*
 * This static function is consistent with any kind of TDLS management
 * frames we are sending. Currently it is being used by limSendTdlsDisRspFrame,
 * limSendTdlsLinkSetupReqFrame and limSendTdlsSetupRspFrame
 */
static void PopulateDot11fTdlsHtVhtCap(tpAniSirGlobal pMac, uint32 selfDot11Mode,
                                        tDot11fIEHTCaps *htCap, tDot11fIEVHTCaps *vhtCap,
                                        tpPESession psessionEntry)
{
    if (IS_DOT11_MODE_HT(selfDot11Mode))
    {
        /* Include HT Capability IE */
        PopulateDot11fHTCaps( pMac, NULL, htCap );
        htCap->present = 1;
        if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END)
        {
            /* hardcode NO channel bonding in 2.4Ghz */
            htCap->supportedChannelWidthSet = 0;
        }
        else
        {
            //Placeholder to support different channel bonding mode of TDLS than AP.
            //wlan_cfgGetInt(pMac,WNI_CFG_TDLS_CHANNEL_BONDING_MODE,&tdlsChannelBondingMode);
            //htCap->supportedChannelWidthSet = tdlsChannelBondingMode ? 1 : 0;
            htCap->supportedChannelWidthSet = 1; // hardcode it to max
        }
    }
    else
    {
        htCap->present = 0;
    }
#ifdef WLAN_FEATURE_11AC
    if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
          pMac->roam.configParam.enableVhtFor24GHz) ||
         (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END))
    {
        if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
            IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
        {
            /* Include VHT Capability IE */
            PopulateDot11fVHTCaps( pMac, vhtCap );
        }
        else
        {
            vhtCap->present = 0;
        }
    }
    else
    {
        /* Vht Disable from ini in 2.4 GHz */
        vhtCap->present = 0;
    }
#endif
}

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

static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac, 
                     tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry)
{
    tDot11fTDLSDisRsp   tdlsDisRsp ;
    tANI_U16            caps = 0 ;            
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
    uint32              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 tdlsChannelBondingMode;

    /* 
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set( ( tANI_U8* )&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 ;

    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisRsp.LinkIdentifier, 
                                           peerMac, TDLS_RESPONDER) ;

    if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
    {
        /*
         * Could not get Capabilities value
         * from CFG. Log error.
         */
         limLog(pMac, LOGP,
                   FL("could not retrieve Capabilities value"));
    }
    swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities );

    /* populate supported rate IE */
    PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, 
                                     &tdlsDisRsp.SuppRates, psessionEntry );
   
    /* Populate extended supported rates */
    PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                                &tdlsDisRsp.ExtSuppRates, psessionEntry );

    /* Populate extended supported rates */
    PopulateDot11fTdlsExtCapability( pMac, &tdlsDisRsp.ExtCap );

    wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode);

    /* Populate HT/VHT Capabilities */
    PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
                               &tdlsDisRsp.VHTCaps, psessionEntry );

    if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled )
        PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry,
                                            &tdlsDisRsp.SuppChannels,
                                            &tdlsDisRsp.SuppOperatingClasses);
    /* 
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSDisRspSize( pMac, &tdlsDisRsp, &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fProbeRequest );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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 + sizeof( tSirMacMgmtHdr ) ;

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

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* Make public Action Frame */

#if 0
    limPreparesActionFrameHdr(pMac, pFrame, SIR_MAC_MGMT_FRAME,
                                          SIR_MAC_MGMT_ACTION, 
                                            LINK_IDEN_ADDR_OFFSET(tdlsDisRsp)) ;
#endif
    limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
              SIR_MAC_MGMT_ACTION, peerMac, psessionEntry->selfMacAddr);

    {
        tpSirMacMgmtHdr     pMacHdr;
        pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
        pMacHdr->fc.toDS    = ANI_TXDIR_IBSS;
        pMacHdr->fc.powerMgmt = 0 ;
        sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
    }

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_RSP)
    {
        tdlsDisRsp.LinkIdentifier.bssid[4] = 0xde;
        tdlsDisRsp.LinkIdentifier.bssid[5] = 0xad; 
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Discovery Rsp"),
         MAC_ADDR_ARRAY(tdlsDisRsp.LinkIdentifier.bssid));
    }
#endif
    status = dot11fPackTDLSDisRsp( pMac, &tdlsDisRsp, pFrame + 
                                              sizeof( tSirMacMgmtHdr ),
                                                  nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req "
                               "(0x%08x)."), status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, 
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while packing TDLS "
                               "Discovery Request (0x%08x)."), status );
    }

#if 0
    if(pMac->hal.pCBackFnTxComp == NULL) 
    {
        pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsDisRspTxComplete;

        if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer)) 
        {
            status = eHAL_STATUS_FAILURE;
            return status;
                
        }
    }
#endif
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                 ("transmitting Discovery response on direct link")) ;

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -DIRECT-> OTA"),
            SIR_MAC_TDLS_DIS_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_RSP) ));


    /*
     * Transmit Discovery response and watch if this is delivered to
     * peer STA.
     */
    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_IBSS,
                            0,
                            limTxComplete, pFrame, 
                            limMgmtTXComplete,
                            HAL_USE_SELF_STA_REQUESTED_MASK );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;
    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;

    return eSIR_SUCCESS;

}

/*
 * This static function is currently used by limSendTdlsLinkSetupReqFrame and
 * limSendTdlsSetupRspFrame to populate the AID if device is 11ac capable.
 */
static void PopulateDotfTdlsVhtAID(tpAniSirGlobal pMac, uint32 selfDot11Mode,
                                   tSirMacAddr peerMac, tDot11fIEAID *Aid,
                                   tpPESession psessionEntry)
{
    if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
          pMac->roam.configParam.enableVhtFor24GHz) ||
         (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END))
    {
        if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
            IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
        {

            tANI_U16 aid;
            tpDphHashNode       pStaDs;

            pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->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;
                limLog( pMac, LOGE, FL("pStaDs is NULL for " MAC_ADDRESS_STR ),
                        MAC_ADDR_ARRAY(peerMac));
            }
        }
    }
    else
    {
        Aid->present = 0;
        limLog( pMac, LOGW, FL("Vht not enable from ini for 2.4GHz."));
    }
}

/*
 * TDLS setup Request frame on AP link
 */

tSirRetStatus limSendTdlsLinkSetupReqFrame(tpAniSirGlobal pMac,
            tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry,
            tANI_U8 *addIe, tANI_U16 addIeLen)
{
    tDot11fTDLSSetupReq    tdlsSetupReq ;
    tANI_U16            caps = 0 ;
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
    uint32              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 tdlsChannelBondingMode;

    /*
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set(( tANI_U8* )&tdlsSetupReq, sizeof( tDot11fTDLSSetupReq ), 0);
    tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS ;
    tdlsSetupReq.Action.action     = SIR_MAC_TDLS_SETUP_REQ ;
    tdlsSetupReq.DialogToken.token = dialog ;


    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupReq.LinkIdentifier,
                                                    peerMac, TDLS_INITIATOR) ;

    if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
    {
        /*
         * Could not get Capabilities value
         * from CFG. Log error.
         */
         limLog(pMac, LOGP,
                   FL("could not retrieve Capabilities value"));
    }
    swapBitField16(caps, ( tANI_U16* )&tdlsSetupReq.Capabilities );

    /* populate supported rate IE */
    PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                              &tdlsSetupReq.SuppRates, psessionEntry );

    /* Populate extended supported rates */
    PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                                &tdlsSetupReq.ExtSuppRates, psessionEntry );

    /* Populate extended supported rates */
    PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupReq.ExtCap );

    if ( 1 == pMac->lim.gLimTDLSWmmMode )
    {
        /* include WMM IE */
        PopulateDot11fWMMInfoStation( pMac, &tdlsSetupReq.WMMInfoStation );
    }
    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 PopulateDot11fQOSCapsStation() depends on AP's capability, and
         TDLS doesn't want to depend on AP's capability */
        tdlsSetupReq.QOSCapsStation.present = 1;
        tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
        tdlsSetupReq.QOSCapsStation.qack = 0;
        tdlsSetupReq.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
        tdlsSetupReq.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
        tdlsSetupReq.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
        tdlsSetupReq.QOSCapsStation.acvo_uapsd = (pMac->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_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode);

    /* Populate HT/VHT Capabilities */
    PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
                               &tdlsSetupReq.VHTCaps, psessionEntry );

    /* Populate AID */
    PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac,
                            &tdlsSetupReq.AID, psessionEntry );

    if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled )
        PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry,
                                            &tdlsSetupReq.SuppChannels,
                                            &tdlsSetupReq.SuppOperatingClasses);
    /*
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSSetupReqSize( pMac, &tdlsSetupReq,
                                                              &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fProbeRequest );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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(psessionEntry))
                              ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr))
                      + sizeof( eth_890d_header )
                      + PAYLOAD_TYPE_TDLS_SIZE
                      + addIeLen;

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

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
                     LINK_IDEN_ADDR_OFFSET(tdlsSetupReq), TDLS_LINK_AP, TDLS_INITIATOR, TID_AC_BK, psessionEntry) ;

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_REQ)
    {
        tdlsSetupReq.LinkIdentifier.bssid[4] = 0xde;
        tdlsSetupReq.LinkIdentifier.bssid[5] = 0xad;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
        ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Setup Req"),
         MAC_ADDR_ARRAY(tdlsSetupReq.LinkIdentifier.bssid));
    }
#endif
    limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"),
            __func__, tdlsSetupReq.VHTCaps.supportedChannelWidthSet, tdlsSetupReq.VHTCaps.rxMCSMap,
            tdlsSetupReq.VHTCaps.txMCSMap, tdlsSetupReq.VHTCaps.txSupDataRate );

    status = dot11fPackTDLSSetupReq( pMac, &tdlsSetupReq, pFrame
                               + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req "
                               "(0x%08x)."), status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, 
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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 doesnt
    //follow the order. This should be ok, but we should consider changing this
    //if there is any IOT issue.
    if( addIeLen != 0 )
    {
    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
            addIeLen ));
       vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen );
    }

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"),
            SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) ));

    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_TODS,
                            TID_AC_BK,
                            limTxComplete, pFrame,
                            limMgmtTXComplete,
                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );

    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;
    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;

    return eSIR_SUCCESS;

}
/*
 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
 */

tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac,
            tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry,
            tANI_U8 *addIe, tANI_U16 addIeLen)
{
    tDot11fTDLSTeardown teardown ;
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
    tANI_U32            padLen = 0;
#endif
    /*
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set( ( tANI_U8* )&teardown, sizeof( tDot11fTDLSTeardown ), 0 );
    teardown.Category.category = SIR_MAC_ACTION_TDLS ;
    teardown.Action.action     = SIR_MAC_TDLS_TEARDOWN ;
    teardown.Reason.code       = reason ;

    PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier,
                                                peerMac, (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR) ;


    /*
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSTeardownSize( pMac, &teardown, &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fProbeRequest );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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(psessionEntry))
                              ? 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 */

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, 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,
                              TID_AC_VI, psessionEntry) ;

    status = dot11fPackTDLSTeardown( pMac, &teardown, pFrame
                               + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS Teardown req (0x%08x)."),
                status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while packing TDLS "
                               "Teardown Request (0x%08x)."), status );
    }
#if 0
    if(pMac->hal.pCBackFnTxComp == NULL)
    {
        pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsTeardownTxComplete;
        if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
        {
            status = eHAL_STATUS_FAILURE;
            return status;
                
        }
    }
    else
    {
        VOS_ASSERT(0) ;
        return status ;
    }
#endif

    if( addIeLen != 0 )
    {
    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
            addIeLen ));
       vos_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 }; */
        tANI_U8 *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;

        LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
                padLen ));

        /* padding zero if more than 5 bytes are required */
        if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
            vos_mem_set( pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
                         padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
    }
#endif
    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -%s-> OTA"),
         SIR_MAC_TDLS_TEARDOWN, limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN),
         (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP": "DIRECT" ));

    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_TODS,
                            TID_AC_VI,
                            limTxComplete, pFrame,
                            limMgmtTXComplete,
                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;

    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
    return eSIR_SUCCESS;

}

/*
 * Send Setup RSP frame on AP link.
 */
static tSirRetStatus limSendTdlsSetupRspFrame(tpAniSirGlobal pMac, 
                    tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry, 
                    etdlsLinkSetupStatus setupStatus, tANI_U8 *addIe, tANI_U16 addIeLen )
{
    tDot11fTDLSSetupRsp  tdlsSetupRsp ;
    tANI_U32            status = 0 ;
    tANI_U16            caps = 0 ;            
    tANI_U32            nPayload = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
    uint32             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 tdlsChannelBondingMode;

    /* 
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set( ( tANI_U8* )&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;

    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupRsp.LinkIdentifier,
                 peerMac, TDLS_RESPONDER) ;

    if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
    {
        /*
         * Could not get Capabilities value
         * from CFG. Log error.
         */
         limLog(pMac, LOGP,
                   FL("could not retrieve Capabilities value"));
    }
    swapBitField16(caps, ( tANI_U16* )&tdlsSetupRsp.Capabilities );

    /* ipopulate supported rate IE */
    PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, 
                                &tdlsSetupRsp.SuppRates, psessionEntry );
   
    /* Populate extended supported rates */
    PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                                &tdlsSetupRsp.ExtSuppRates, psessionEntry );

    /* Populate extended supported rates */
    PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupRsp.ExtCap );

    if ( 1 == pMac->lim.gLimTDLSWmmMode )
    {
        /* include WMM IE */
        PopulateDot11fWMMInfoStation( pMac, &tdlsSetupRsp.WMMInfoStation );
    }
    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 PopulateDot11fQOSCapsStation() depends on AP's capability, and
         TDLS doesn't want to depend on AP's capability */
        tdlsSetupRsp.QOSCapsStation.present = 1;
        tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
        tdlsSetupRsp.QOSCapsStation.qack = 0;
        tdlsSetupRsp.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
        tdlsSetupRsp.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
        tdlsSetupRsp.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
        tdlsSetupRsp.QOSCapsStation.acvo_uapsd = (pMac->lim.gLimTDLSUapsdMask & 0x01);
    }

    wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode);

    /* Populate HT/VHT Capabilities */
    PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
                                &tdlsSetupRsp.VHTCaps, psessionEntry );

    /* Populate AID */
    PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac,
                            &tdlsSetupRsp.AID, psessionEntry );

    if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled )
        PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry,
                                            &tdlsSetupRsp.SuppChannels,
                                            &tdlsSetupRsp.SuppOperatingClasses);

    tdlsSetupRsp.Status.status = setupStatus ;

    /* 
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSSetupRspSize( pMac, &tdlsSetupRsp, 
                                                     &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fProbeRequest );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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(psessionEntry))
                              ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr))
                      + sizeof( eth_890d_header )
                      + PAYLOAD_TYPE_TDLS_SIZE
                      + addIeLen;

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

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, 
                                 LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), 
                                       TDLS_LINK_AP, TDLS_RESPONDER,
                                       TID_AC_BK, psessionEntry) ;

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_RSP)
    {
        tdlsSetupRsp.LinkIdentifier.bssid[4] = 0xde;
        tdlsSetupRsp.LinkIdentifier.bssid[5] = 0xad; 
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Setup Rsp"),
         MAC_ADDR_ARRAY(tdlsSetupRsp.LinkIdentifier.bssid));
    }
#endif
    limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"),
            __func__, tdlsSetupRsp.VHTCaps.supportedChannelWidthSet, tdlsSetupRsp.VHTCaps.rxMCSMap,
            tdlsSetupRsp.VHTCaps.txMCSMap, tdlsSetupRsp.VHTCaps.txSupDataRate );
    status = dot11fPackTDLSSetupRsp( pMac, &tdlsSetupRsp, pFrame 
                               + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req "
                               "(0x%08x)."), status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, 
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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 doesnt
    //follow the order. This should be ok, but we should consider changing this
    //if there is any IOT issue.
    if( addIeLen != 0 )
    {
       vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen );
    }

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"),
         SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) ));

    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_TODS,
                            //ANI_TXDIR_IBSS,
                            TID_AC_BK,
                            limTxComplete, pFrame,
                            limMgmtTXComplete,
                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;
    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;

    return eSIR_SUCCESS;

}

/*
 * Send TDLS setup CNF frame on AP link
 */

tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, tSirMacAddr peerMac,
                    tANI_U8 dialog, tANI_U32 peerCapability, tpPESession psessionEntry, tANI_U8* addIe, tANI_U16 addIeLen)
{
    tDot11fTDLSSetupCnf  tdlsSetupCnf ;
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U8            *pFrame;
    void               *pPacket;
    eHalStatus          halstatus;
#ifndef NO_PAD_TDLS_MIN_8023_SIZE
    tANI_U32            padLen = 0;
#endif

    /* 
     * The scheme here is to fill out a 'tDot11fProbeRequest' structure
     * and then hand it off to 'dot11fPackProbeRequest' (for
     * serialization).  We start by zero-initializing the structure:
     */
    vos_mem_set( ( tANI_U8* )&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 ;

#if 1
    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupCnf.LinkIdentifier,
                      peerMac, TDLS_INITIATOR) ;
#else
    vos_mem_copy( (tANI_U8 *)&tdlsSetupCnf.LinkIdentifier,
                  (tANI_U8 *)&setupRsp->LinkIdentifier, sizeof(tDot11fIELinkIdentifier)) ;
#endif

    /* 
     * 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 == pMac->lim.gLimTDLSWmmMode) && (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP)))
    {
       PopulateDot11fWMMParams(pMac, &tdlsSetupCnf.WMMParams, psessionEntry);
    }

     /* Check peer is VHT capable*/
    if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP))
    {
       PopulateDot11fVHTOperation( pMac, &tdlsSetupCnf.VHTOperation);
       PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry );
    }
    else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) /* Check peer is HT capable */
    {
       PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry );
    }

    /* 
     * now we pack it.  First, how much space are we going to need?
     */
    status = dot11fGetPackedTDLSSetupCnfSize( pMac, &tdlsSetupCnf, 
                                                     &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
                               "or a discovery Request (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tDot11fProbeRequest );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("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(psessionEntry))
                              ? 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 */

    halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
                             ( tANI_U16 )nBytes, ( void** ) &pFrame,
                             ( void** ) &pPacket );
    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
                               "Discovery Request."), nBytes );
        return eSIR_MEM_ALLOC_FAILED;
    }

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

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

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, 
                     LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf), TDLS_LINK_AP, TDLS_INITIATOR,
                     TID_AC_VI, psessionEntry) ;

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_STATUS_37_IN_SETUP_CNF) {
        tdlsSetupCnf.StatusCode.statusCode = 37;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: StatusCode = 37 in TDLS Setup Cnf"));
    }
#endif
    status = dot11fPackTDLSSetupCnf( pMac, &tdlsSetupCnf, pFrame 
                               + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req "
                               "(0x%08x)."), status );
        palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, 
                                   ( void* ) pFrame, ( void* ) pPacket );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while packing TDLS "
                               "Discovery Request (0x%08x)."), status );
    }
#if 0
    if(pMac->hal.pCBackFnTxComp == NULL) 
    {
        pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsSetupCnfTxComplete;
        if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer)) 
        {
            status = eHAL_STATUS_FAILURE;
            return status;
                
        }
    }
    else
    {
        VOS_ASSERT(0) ;
        return status ;
    }
#endif
    //Copy the additional IE. 
    //TODO : addIe is added at the end of the frame. This means it doesnt
    //follow the order. This should be ok, but we should consider changing this
    //if there is any IOT issue.
    if( addIeLen != 0 )
    {
       vos_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 }; */
        tANI_U8 *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;

        LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
                padLen ));

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


    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -AP-> OTA"),
         SIR_MAC_TDLS_SETUP_CNF, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_CNF) ));

    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
                            HAL_TXRX_FRM_802_11_DATA,
                            ANI_TXDIR_TODS,
                            TID_AC_VI,
                            limTxComplete, pFrame, 
                            limMgmtTXComplete,
                            HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );


    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
    {
        pMac->lim.mgmtFrameSessionId = 0xff;
        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!" ));
        return eSIR_FAILURE;

    }
    pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;

    return eSIR_SUCCESS;
}

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * Convert HT caps to lim based HT caps 
 */
static void limTdlsCovertHTCaps(tpAniSirGlobal pMac,
                         tSirTdlsPeerInfo *peerInfo, tDot11fIEHTCaps *HTCaps)
{

    /* HT Capability Info */
    peerInfo->tdlsPeerHtCaps.advCodingCap = HTCaps->advCodingCap ;
    peerInfo->tdlsPeerHtCaps.supportedChannelWidthSet = 
                                            HTCaps->supportedChannelWidthSet ;
    peerInfo->tdlsPeerHtCaps.mimoPowerSave = HTCaps->mimoPowerSave ;
    peerInfo->tdlsPeerHtCaps.greenField = HTCaps->greenField ;
    peerInfo->tdlsPeerHtCaps.shortGI20MHz = HTCaps->shortGI20MHz ;
    peerInfo->tdlsPeerHtCaps.shortGI40MHz = HTCaps->shortGI40MHz ;
    peerInfo->tdlsPeerHtCaps.txSTBC = HTCaps->txSTBC ;
    peerInfo->tdlsPeerHtCaps.rxSTBC = HTCaps->rxSTBC ;
    peerInfo->tdlsPeerHtCaps.delayedBA = HTCaps->delayedBA;
    peerInfo->tdlsPeerHtCaps.maximalAMSDUsize = HTCaps->maximalAMSDUsize ;
    peerInfo->tdlsPeerHtCaps.dsssCckMode40MHz = HTCaps->dsssCckMode40MHz ;
    peerInfo->tdlsPeerHtCaps.psmp = HTCaps->stbcControlFrame ;
    peerInfo->tdlsPeerHtCaps.stbcControlFrame = HTCaps->stbcControlFrame ;
    peerInfo->tdlsPeerHtCaps.lsigTXOPProtection = 
                                                 HTCaps->lsigTXOPProtection ;

    /* HT Capa parameters */
    peerInfo->tdlsPeerHtParams.maxRxAMPDUFactor = HTCaps->maxRxAMPDUFactor ;
    peerInfo->tdlsPeerHtParams.mpduDensity = HTCaps->mpduDensity ;
    peerInfo->tdlsPeerHtParams.reserved = HTCaps->reserved1 ;
    
    /* Extended HT caps */
    peerInfo->tdlsPeerHtExtCaps.pco = HTCaps->pco ;
    peerInfo->tdlsPeerHtExtCaps.transitionTime = HTCaps->transitionTime ;
    peerInfo->tdlsPeerHtExtCaps.mcsFeedback = HTCaps->mcsFeedback ;
    vos_mem_copy( peerInfo->supportedMCSSet,
                      HTCaps->supportedMCSSet, SIZE_OF_SUPPORTED_MCS_SET) ;

    return ;
}

/*
 * update capability info..
 */
void tdlsUpdateCapInfo(tSirMacCapabilityInfo *capabilityInfo, 
                                tDot11fFfCapabilities *Capabilities)
{

    capabilityInfo->ess            = Capabilities->ess;
    capabilityInfo->ibss           = Capabilities->ibss;
    capabilityInfo->cfPollable     = Capabilities->cfPollable;
    capabilityInfo->cfPollReq      = Capabilities->cfPollReq;
    capabilityInfo->privacy        = Capabilities->privacy;
    capabilityInfo->shortPreamble  = Capabilities->shortPreamble;
    capabilityInfo->pbcc           = Capabilities->pbcc;
    capabilityInfo->channelAgility = Capabilities->channelAgility;
    capabilityInfo->spectrumMgt    = Capabilities->spectrumMgt;
    capabilityInfo->qos            = Capabilities->qos;
    capabilityInfo->shortSlotTime  = Capabilities->shortSlotTime;
    capabilityInfo->apsd           = Capabilities->apsd;
    capabilityInfo->rrm            = Capabilities->rrm;
    capabilityInfo->dsssOfdm       = Capabilities->dsssOfdm;
    capabilityInfo->immediateBA    = Capabilities->immediateBA;

    return ;
}

/*
 * update Peer info from the link request frame recieved from Peer..
 * in list of STA participating in TDLS link setup
 */
void limTdlsUpdateLinkReqPeerInfo(tpAniSirGlobal pMac, 
                                 tLimTdlsLinkSetupPeer *setupPeer, 
                                             tDot11fTDLSSetupReq *setupReq)
{

    /* Populate peer info of tdls discovery result */

    tdlsUpdateCapInfo(&setupPeer->capabilityInfo, &setupReq->Capabilities) ;

    if(setupReq->SuppRates.present)
    {
        ConvertSuppRates( pMac, &setupPeer->supportedRates, 
                                            &setupReq->SuppRates );
    }

    /* update QOS info, needed for Peer U-APSD session */
    if(setupReq->QOSCapsStation.present)
    {
       ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps, 
                   &setupReq->QOSCapsStation) ;
       LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,("setupReq->SPLen=%d (be %d %d %d %d vo) more %d qack %d."),
         setupReq->QOSCapsStation.max_sp_length, setupReq->QOSCapsStation.acbe_uapsd,
         setupReq->QOSCapsStation.acbk_uapsd, setupReq->QOSCapsStation.acvi_uapsd,
         setupReq->QOSCapsStation.acvo_uapsd, setupReq->QOSCapsStation.more_data_ack,
         setupReq->QOSCapsStation.qack));
    }
    
    if (setupReq->ExtSuppRates.present)
    {
        setupPeer->ExtRatesPresent = 1;
        ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
                                                &setupReq->ExtSuppRates );
    }
    /* update HT caps */
    if (setupReq->HTCaps.present)
    {
        vos_mem_copy( &setupPeer->tdlsPeerHTCaps,
                    &setupReq->HTCaps, sizeof(tDot11fIEHTCaps)) ;
    }
    /* Update EXT caps */
    if (setupReq->ExtCap.present)
    {
        vos_mem_copy( &setupPeer->tdlsPeerExtCaps,
                    &setupReq->ExtCap, sizeof(tDot11fIEExtCap)) ;
    }    

    return ;
}

/*
 * update peer Info recieved with TDLS setup RSP 
 */
void limTdlsUpdateLinkRspPeerInfo(tpAniSirGlobal pMac, 
                                   tLimTdlsLinkSetupPeer *setupPeer, 
                                             tDot11fTDLSSetupRsp *setupRsp)
{

    /* Populate peer info of tdls discovery result */
    tdlsUpdateCapInfo(&setupPeer->capabilityInfo, &setupRsp->Capabilities) ;

    if(setupRsp->SuppRates.present)
    {
        tDot11fIESuppRates *suppRates = &setupRsp->SuppRates ;
        ConvertSuppRates( pMac, &setupPeer->supportedRates, suppRates);
    }

    /* update QOS info, needed for Peer U-APSD session */
    if(setupRsp->QOSCapsStation.present)
    {
       ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps, 
                   &setupRsp->QOSCapsStation) ;
       LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("setupRsp->SPLen=%d (be %d %d %d %d vo) more %d qack %d."),
         setupRsp->QOSCapsStation.max_sp_length, setupRsp->QOSCapsStation.acbe_uapsd,
         setupRsp->QOSCapsStation.acbk_uapsd, setupRsp->QOSCapsStation.acvi_uapsd,
         setupRsp->QOSCapsStation.acvo_uapsd, setupRsp->QOSCapsStation.more_data_ack,
         setupRsp->QOSCapsStation.qack));
    }
    
    if(setupRsp->ExtSuppRates.present)
    {
        setupPeer->ExtRatesPresent = 1;
        ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
                                                &setupRsp->ExtSuppRates );
    }
    /* update HT caps */
    if (setupRsp->HTCaps.present)
    {
        vos_mem_copy(&setupPeer->tdlsPeerHTCaps,
                    &setupRsp->HTCaps, sizeof(tDot11fIEHTCaps)) ;
    }

    /* update EXT caps */
    if (setupRsp->ExtCap.present)
    {
        vos_mem_copy( &setupPeer->tdlsPeerExtCaps,
                    &setupRsp->ExtCap, sizeof(tDot11fIEExtCap)) ;
    }

    return ;
}
#endif

/* This Function is similar to PopulateDot11fHTCaps, except that the HT Capabilities
 * are considered from the AddStaReq rather from the cfg.dat as in PopulateDot11fHTCaps
 */
static tSirRetStatus limTdlsPopulateDot11fHTCaps(tpAniSirGlobal pMac, tpPESession psessionEntry,
            tSirTdlsAddStaReq *pTdlsAddStaReq, tDot11fIEHTCaps *pDot11f)
{
    tANI_U32                         nCfgValue;
    tANI_U8                          nCfgValue8;
    tSirMacHTParametersInfo         *pHTParametersInfo;
    union {
        tANI_U16                        nCfgValue16;
        tSirMacHTCapabilityInfo         htCapInfo;
        tSirMacExtendedHTCapabilityInfo extHtCapInfo;
    } uHTCapabilityInfo;

    tSirMacTxBFCapabilityInfo       *pTxBFCapabilityInfo;
    tSirMacASCapabilityInfo         *pASCapabilityInfo;

    nCfgValue = pTdlsAddStaReq->htCap.capInfo;

    uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;

    pDot11f->advCodingCap             = uHTCapabilityInfo.htCapInfo.advCodingCap;
    pDot11f->mimoPowerSave            = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
    pDot11f->greenField               = uHTCapabilityInfo.htCapInfo.greenField;
    pDot11f->shortGI20MHz             = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
    pDot11f->shortGI40MHz             = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
    pDot11f->txSTBC                   = uHTCapabilityInfo.htCapInfo.txSTBC;
    pDot11f->rxSTBC                   = uHTCapabilityInfo.htCapInfo.rxSTBC;
    pDot11f->delayedBA                = uHTCapabilityInfo.htCapInfo.delayedBA;
    pDot11f->maximalAMSDUsize         = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
    pDot11f->dsssCckMode40MHz         = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
    pDot11f->psmp                     = uHTCapabilityInfo.htCapInfo.psmp;
    pDot11f->stbcControlFrame         = uHTCapabilityInfo.htCapInfo.stbcControlFrame;
    pDot11f->lsigTXOPProtection       = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;

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

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

    dot11fLog(pMac, LOG2, FL("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.ampduParamsInfo;

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

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

    dot11fLog( pMac, LOG2, FL( "AMPDU Param: %x" ), nCfgValue);

    vos_mem_copy( pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
                  SIZE_OF_SUPPORTED_MCS_SET);

    nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;

    uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;

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

    nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;

    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.antennaSelectionInfo;

    nCfgValue8 = ( tANI_U8 ) 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 eSIR_SUCCESS;

}

tSirRetStatus
limTdlsPopulateDot11fVHTCaps(tpAniSirGlobal pMac,
                      tSirTdlsAddStaReq *pTdlsAddStaReq,
                      tDot11fIEVHTCaps  *pDot11f)
{
    tANI_U32             nCfgValue=0;
    union {
        tANI_U32                       nCfgValue32;
        tSirMacVHTCapabilityInfo       vhtCapInfo;
    } uVHTCapabilityInfo;
    union {
        tANI_U16                       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 =  uVHTCapabilityInfo.vhtCapInfo.suBeamFormerCap;
    pDot11f->suBeamformeeCap =  uVHTCapabilityInfo.vhtCapInfo.suBeamformeeCap;
    pDot11f->csnofBeamformerAntSup =  uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
    pDot11f->numSoundingDim =  uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
    pDot11f->muBeamformerCap =  uVHTCapabilityInfo.vhtCapInfo.muBeamformerCap;
    pDot11f->muBeamformeeCap =  uVHTCapabilityInfo.vhtCapInfo.muBeamformeeCap;
    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;

    limLogVHTCap(pMac, pDot11f);

    return eSIR_SUCCESS;

}

static tSirRetStatus
limTdlsPopulateMatchingRateSet(tpAniSirGlobal pMac,
                           tpDphHashNode pStaDs,
                           tANI_U8 *pSupportedRateSet,
                           tANI_U8 supporteRatesLength,
                           tANI_U8* pSupportedMCSSet,
                           tSirMacPropRateSet *pAniLegRateSet,
                           tpPESession  psessionEntry,
                           tDot11fIEVHTCaps *pVHTCaps)

{
    tSirMacRateSet    tempRateSet;
    tANI_U32          i,j,val,min,isArate;
    tSirMacRateSet    tempRateSet2;
    tANI_U32 phyMode;
    tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
    isArate=0;
    tempRateSet2.numRates = 0;

    // limGetPhyMode(pMac, &phyMode);
    limGetPhyMode(pMac, &phyMode, NULL);

    // get own rate set
    val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
    if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
                                          (tANI_U8 *) &tempRateSet.rate,
                                          &val) != eSIR_SUCCESS)
    {
        /// Could not get rateset from CFG. Log error.
        limLog(pMac, LOGP, FL("could not retrieve rateset"));
        val = 0;
    }
    tempRateSet.numRates = val;

    if (phyMode == WNI_CFG_PHY_MODE_11G)
    {

        // get own extended rate set
        val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
        if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
                                                  (tANI_U8 *) &tempRateSet2.rate,
                                                  &val) != eSIR_SUCCESS)
        tempRateSet2.numRates = val;
    }

    if ((tempRateSet.numRates + tempRateSet2.numRates) > 12)
    {
        PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG"));)
        goto error;
    }

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

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

    tempRateSet.numRates += tempRateSet2.numRates;

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

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

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

        tempRateSet2.rate[tempRateSet2.numRates++] = tempRateSet.rate[min];
        tempRateSet.rate[min] = 0xff;
    }

    /**
     * Copy received rates in tempRateSet, the parser has ensured
     * unicity of the rates so there cannot be more than 12 . Need to Check this
     * TODO Sunil.
     */
    if (supporteRatesLength > SIR_MAC_RATESET_EID_MAX)
    {
       limLog( pMac, LOGW, FL("Supported rates length %d more than "
                              "the Max limit, reset to Max"),
                               supporteRatesLength);
       supporteRatesLength = SIR_MAC_RATESET_EID_MAX;
    }
    for (i = 0; i < supporteRatesLength; i++)
    {
        tempRateSet.rate[i] = pSupportedRateSet[i];
    }
    tempRateSet.numRates = supporteRatesLength;

    {
        tpSirSupportedRates  rates = &pStaDs->supportedRates;
        tANI_U8 aRateIndex = 0;
        tANI_U8 bRateIndex = 0;
        vos_mem_set( (tANI_U8 *) rates, sizeof(tSirSupportedRates), 0);

        for (i = 0;i < tempRateSet2.numRates; i++)
        {
            for (j = 0;j < tempRateSet.numRates; j++)
            {
                if ((tempRateSet2.rate[i] & 0x7F) ==
                    (tempRateSet.rate[j] & 0x7F))
                {
#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
                    if ((bRateIndex > HAL_NUM_11B_RATES) || (aRateIndex > HAL_NUM_11A_RATES))
                    {
                        limLog(pMac, LOGE, FL("Invalid number of rates (11b->%d, 11a->%d)"),
                               bRateIndex, aRateIndex);
                        return eSIR_FAILURE;
                    }
#endif
                    if (sirIsArate(tempRateSet2.rate[i] & 0x7f))
                    {
                        isArate=1;
                        rates->llaRates[aRateIndex++] = tempRateSet2.rate[i];
                    }
                    else
                        rates->llbRates[bRateIndex++] = tempRateSet2.rate[i];
                    break;
                }
            }
        }
    }


    //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n
#ifdef FEATURE_WLAN_TDLS
    if (pStaDs->mlmStaContext.htCapability)
#else
    if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
       (pStaDs->mlmStaContext.htCapability))
#endif
    {
        val = SIZE_OF_SUPPORTED_MCS_SET;
        if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
                           mcsSet,
                           &val) != eSIR_SUCCESS)
        {
            /// Could not get rateset from CFG. Log error.
            limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet"));
            goto error;
        }

        for (i=0; i<val; i++)
            pStaDs->supportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i];

        PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from CFG and DPH :"));)
        for (i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
        {
            PELOG2(limLog(pMac, LOG2,FL("%x %x "), mcsSet[i], pStaDs->supportedRates.supportedMCSSet[i]);)
        }
    }

#ifdef WLAN_FEATURE_11AC
    limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry);
#endif
    /**
         * Set the erpEnabled bit iff the phy is in G mode and at least
         * one A rate is supported
         */
    if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate)
        pStaDs->erpEnabled = eHAL_SET;



    return eSIR_SUCCESS;

 error:

    return eSIR_FAILURE;
}

static int limTdlsSelectCBMode(tDphHashNode *pStaDs, tpPESession psessionEntry)
{
    tANI_U8 channel = psessionEntry->currentOperChannel;

    if ( pStaDs->mlmStaContext.vhtCapability )
    {
        if ( channel== 36 || channel == 52 || channel == 100 ||
             channel == 116 || channel == 149 )
        {
           return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
        }
        else if ( channel == 40 || channel == 56 || channel == 104 ||
             channel == 120 || channel == 153 )
        {
           return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
        }
        else if ( channel == 44 || channel == 60 || channel == 108 ||
                  channel == 124 || channel == 157 )
        {
           return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
        }
        else if ( channel == 48 || channel == 64 || channel == 112 ||
             channel == 128 || channel == 161 )
        {
            return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
        }
        else if ( channel == 165 )
        {
            return 0;
        }
    }
    else if ( pStaDs->mlmStaContext.htCapability )
    {
        if ( channel== 40 || channel == 48 || channel == 56 ||
             channel == 64 || channel == 104 || channel == 112 ||
             channel == 120 || channel == 128 || channel == 136 ||
             channel == 144 || channel == 153 || channel == 161 )
        {
           return 1;
        }
        else if ( channel== 36 || channel == 44 || channel == 52 ||
             channel == 60 || channel == 100 || channel == 108 ||
             channel == 116 || channel == 124 || channel == 132 ||
             channel == 140 || channel == 149 || channel == 157 )
        {
           return 2;
        }
        else if ( channel == 165 )
        {
           return 0;
        }
    }
    return 0;
}

/*
 * update HASH node entry info
 */
static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs,
              tSirTdlsAddStaReq *pTdlsAddStaReq, tpPESession psessionEntry)
{
    //tDot11fIEHTCaps *htCaps = &setupPeerInfo->tdlsPeerHTCaps ;
    tDot11fIEHTCaps htCap, *htCaps;
    tDot11fIEVHTCaps *pVhtCaps = NULL;
#ifdef WLAN_FEATURE_11AC
    tDot11fIEVHTCaps vhtCap;
    tANI_U8 cbMode;
#endif
    tpDphHashNode pSessStaDs = NULL;
    tANI_U16 aid;

    if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD)
    {
        PopulateDot11fHTCaps(pMac, psessionEntry, &htCap);
    }
    else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE)
    {
        limTdlsPopulateDot11fHTCaps(pMac, NULL, pTdlsAddStaReq, &htCap);
    }
    htCaps = &htCap;
    if (htCaps->present)
    {
        pStaDs->mlmStaContext.htCapability = 1 ;
        pStaDs->htGreenfield = htCaps->greenField ;
        pStaDs->htSupportedChannelWidthSet =  htCaps->supportedChannelWidthSet ;
        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;
        limFillRxHighestSupportedRate(pMac, 
                             &pStaDs->supportedRates.rxHighestDataRate, 
                                                 htCaps->supportedMCSSet);
        pStaDs->baPolicyFlag = 0xFF;
        pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N ;
    }
    else
    {
        pStaDs->mlmStaContext.htCapability = 0 ;
        pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG ;
    }
#ifdef WLAN_FEATURE_11AC
    limTdlsPopulateDot11fVHTCaps(pMac, pTdlsAddStaReq, &vhtCap);
    pVhtCaps = &vhtCap;
    if (pVhtCaps->present)
    {
        pStaDs->mlmStaContext.vhtCapability = 1 ;

        if ((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
            pMac->roam.configParam.enableVhtFor24GHz)
        {
            pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
            pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
        }
        else
        {
            pStaDs->vhtSupportedChannelWidthSet =  WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
            pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ ;
        }

        pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
        pStaDs->vhtBeamFormerCapable= pVhtCaps->suBeamFormerCap;
        // TODO , is it necessary , Sunil???
        pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
    }
    else
    {
        pStaDs->mlmStaContext.vhtCapability = 0 ;
        pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
    }
#endif
    /*Calculate the Secondary Coannel Offset */
    cbMode = limTdlsSelectCBMode(pStaDs, psessionEntry);

    pStaDs->htSecondaryChannelOffset = cbMode;

#ifdef WLAN_FEATURE_11AC
    if ( pStaDs->mlmStaContext.vhtCapability )
    {
        pStaDs->htSecondaryChannelOffset = limGetHTCBState(cbMode);
    }
#endif
    
    pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid, 
                                          &psessionEntry->dph.dphHashTable) ;

    /* Lets enable QOS parameter */
    pStaDs->qosMode    = 1;
    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 ??
     */
    limTdlsPopulateMatchingRateSet(pMac, pStaDs, pTdlsAddStaReq->supported_rates,
                                   pTdlsAddStaReq->supported_rates_length,
                                   (tANI_U8 *)pTdlsAddStaReq->htCap.suppMcsSet,
                                   &pStaDs->mlmStaContext.propRateSet,
                                   psessionEntry, pVhtCaps);

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

    return ; 
}

#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * find Peer in setup link list.
 */
 
tANI_U8 limTdlsFindLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac, 
                                            tLimTdlsLinkSetupPeer  **setupPeer)
{
    tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
    tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
    tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ; 

    while (linkSetupList != NULL)
    {
        if (vos_mem_compare((tANI_U8 *) peerMac,
                            (tANI_U8 *) linkSetupList->peerMac,
                            sizeof(tSirMacAddr)) )
        {
            checkNode = TDLS_NODE_FOUND ;
            *setupPeer = linkSetupList ;
            break ;
        }
        linkSetupList = linkSetupList->next;
    }

    return ((TDLS_NODE_FOUND ==  checkNode) ? eSIR_SUCCESS : eSIR_FAILURE ) ;
}

/*
 * find peer in Discovery list.
 * Dicovery list get populated in two instances, a) Recieved responses in reply
 * to discovery request b) If discover request is received from TDLS peer STA
 */
tSirTdlsPeerInfo *limTdlsFindDisPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
{
    tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
    tSirTdlsPeerInfo *peerInfo = NULL ;

    while (discoveryList != NULL)
    {
        peerInfo = &discoveryList->tdlsDisPeerInfo ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
         ("Peer in discovery list = " MAC_ADDRESS_STR),
          MAC_ADDR_ARRAY(peerInfo->peerMac));

        if (vos_mem_compare((tANI_U8 *) peerMac,
                       (tANI_U8 *) &peerInfo->peerMac, sizeof(tSirMacAddr)) )
        {
            break ;
        }
        discoveryList = discoveryList->next;
    }

    return peerInfo ;
}

/*
 * find peer in Discovery list by looking into peer state.
 * Dicovery list get populated in two instances, a) Recieved responses in reply
 * to discovery request b) If discover request is received from TDLS peer STA
 */
static tSirTdlsPeerInfo *limTdlsFindDisPeerByState(tpAniSirGlobal pMac, 
                                                                tANI_U8 state)
{
    tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
    tSirTdlsPeerInfo *peerInfo = NULL ;

    while (discoveryList != NULL)
    {
        peerInfo = &discoveryList->tdlsDisPeerInfo ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                     ("peerInfo Mac = " MAC_ADDRESS_STR),
                      MAC_ADDR_ARRAY(peerInfo->peerMac));

        if (peerInfo->tdlsPeerState == state)
        {
            break ;
        }
        discoveryList = discoveryList->next;
    }

    return peerInfo ;
}

/*
 * find peer in Setup list by looking into peer state.
 * setup list get populated in two instances, a) Recieved responses in reply
 * to setup request b) If discover request is received from TDLS peer STA
 */
static tANI_U8 limTdlsFindSetupPeerByState(tpAniSirGlobal pMac, tANI_U8 state, 
                                              tLimTdlsLinkSetupPeer **setupPeer)
{    

    tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
    tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
    tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ; 

    while (linkSetupList != NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                 ("peer state = %02x"), (linkSetupList)->tdls_link_state) ;
        if((linkSetupList)->tdls_link_state == state) 
        {
            checkNode = TDLS_NODE_FOUND ;
            *setupPeer = linkSetupList ;
            break ;
        }
        linkSetupList = (linkSetupList)->next;
    }

    return ((TDLS_NODE_FOUND == checkNode) ? eSIR_SUCCESS: eSIR_FAILURE) ;
}


/*
 * delete Peer from Setup Link
 */
void limTdlsDelLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
{
    tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
    tLimTdlsLinkSetupPeer **linkSetupList = &setupInfo->tdlsLinkSetupList ;
    tLimTdlsLinkSetupPeer *currentNode = NULL ;
    tLimTdlsLinkSetupPeer *prevNode = NULL ;

    for(currentNode = *linkSetupList ; currentNode != NULL ;
                    prevNode = currentNode, currentNode = currentNode->next)
    {
        if (vos_mem_compare( (tANI_U8 *) peerMac,
                        (tANI_U8 *) currentNode->peerMac, 
                                                 sizeof(tSirMacAddr)) )
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                    ("Del Node for Peer = " MAC_ADDRESS_STR),
                     MAC_ADDR_ARRAY(currentNode->peerMac));
            /* if it's first Node */
            if(NULL == prevNode)
            {
                *linkSetupList = currentNode->next ;
            }
            else
            {
                prevNode->next = currentNode->next ;
            }
            vos_mem_free(currentNode) ;
            return ;
        }
    }
        
    return ;
}
   


/*
 * TDLS discovery request frame received from TDLS peer STA..
 */
static tSirRetStatus limProcessTdlsDisReqFrame(tpAniSirGlobal pMac, 
                                    tANI_U8 *pBody, tANI_U32 frmLen )
{
    tDot11fTDLSDisReq tdlsDisReq = {{0}} ;
    tANI_U32 status = 0 ;
    tLimDisResultList *tdlsDisResult = NULL ; 
    tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
    tSirMacAddr peerMac = {0} ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tSirTdlsPeerInfo *peerInfo = NULL ;
    tpPESession psessionEntry = NULL ;
    tANI_U8 sessionId = 0 ;

    status = dot11fUnpackTDLSDisReq(pMac, pBody, frmLen, &tdlsDisReq) ;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN, 
            ("TDLS dis request dialog = %d"), tdlsDisReq.DialogToken.token);

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                               "discovery Request frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
    }

    /*
     * find session entry using BSSID in link identifier, not using MAC
     * header beacuse, there is cases in TDLS, there may be BSSID will not
     * be present in header
     */
    psessionEntry = peFindSessionByBssid(pMac, 
                         &tdlsDisReq.LinkIdentifier.bssid[0], &sessionId) ;
    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                 ("no Session entry for TDLS session (bssid "MAC_ADDR_ARRAY")"),
                  MAC_ADDR_ARRAY(tdlsDisReq.LinkIdentifier.bssid));

        //VOS_ASSERT(0) ;
        return eSIR_FAILURE;
    }
 
    /* varify BSSID */
    status = vos_mem_compare( &psessionEntry->bssId[0],
                    &tdlsDisReq.LinkIdentifier.bssid[0], sizeof(tSirMacAddr)) ;
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
            ("lim BSSID "MAC_ADDRESS_STR),
             MAC_ADDR_ARRAY( psessionEntry->bssId));

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
            ("Dis req from BSSID "MAC_ADDRESS_STR),
             MAC_ADDR_ARRAY(tdlsDisReq.LinkIdentifier.bssid));
    if(!status)
    {
        limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter")) ;

        return eSIR_FAILURE ; 
    }

    /*
     * check if this is echo of our transmitted discovery request
     * drop it here, TODO: better to drop this in TL.
     */    
    status = vos_mem_compare( psessionEntry->selfMacAddr,
                    &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
                                                     sizeof(tSirMacAddr)) ;
    if(status)
    {
        limLog( pMac, LOGE, FL("Echo of our TDLS discovery request frame")) ;
        return eSIR_FAILURE ; 
    }

    /*
     * while processing Discovery request from Peer,
     * STA_MAC--> MAC of TDLS discovery initiator
     * STA_PEER_MAC--> MAC of TDLS discovery responder.
     */
    vos_mem_copy( peerMac,
                        &tdlsDisReq.LinkIdentifier.InitStaAddr[0], 
                                                     sizeof(tSirMacAddr)) ;
    /* TODO, do more validation */
    
    /* see if discovery is already in progress */
    peerInfo = limTdlsFindDisPeer(pMac, peerMac) ;

    if(NULL == peerInfo)
    {    
        /*
         * we are allocating peer info for individual peers found in TDLS
         * discovery, we need to keep adding TDLS peers till we have timed
         * out. We are freeing this memory at the time we are sending this
         * collected peer info to SME.
         */
        tdlsDisResult = vos_mem_malloc(sizeof(tLimDisResultList));
        if ( NULL == tdlsDisResult )
        {
            limLog(pMac, LOGP, FL("alloc fail for TDLS discovery "
                                  "reponse info")) ;
            return eSIR_FAILURE ;
        }

 
        peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;
        peerInfo->tdlsPeerState = TDLS_DIS_REQ_PROCESS_STATE ;
        peerInfo->dialog = tdlsDisReq.DialogToken.token ;

        peerInfo->sessionId = psessionEntry->peSessionId;
        
        /* Populate peer info of tdls discovery result */
        vos_mem_copy( peerInfo->peerMac, peerMac, sizeof(tSirMacAddr)) ;

         /*
         * Now, as per D13, there will not be any Supp rates, ext Supp rates
         * info in Discovery request frames, so we are populating this info
         * locally to pass it to ADD STA.
         */
        do
        {
            tDot11fIESuppRates suppRates = {0} ;
            tDot11fIEExtSuppRates extSuppRates = {0} ;
            tANI_U16 caps = 0 ;
            tDot11fFfCapabilities capsInfo = {0} ;
            tDot11fIEHTCaps HTCaps = {0} ;
            /* populate supported rate IE */
            PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, 
                                                  &suppRates, psessionEntry );
            ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates, 
                                                            &suppRates);
            /* Populate extended supported rates */
            PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
                                &extSuppRates, psessionEntry );

            peerInfo->ExtRatesPresent = 1;
            ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates, 
                                                          &extSuppRates);
 
            if(cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
            {
                /*
                 * Could not get Capabilities value
                 * from CFG. Log error.
                 */
                 limLog(pMac, LOGP,
                   FL("could not retrieve Capabilities value"));
            }
            swapBitField16(caps, ( tANI_U16* )&capsInfo );
            /* update Caps Info */
            tdlsUpdateCapInfo(&peerInfo->capabilityInfo, &capsInfo) ;

            PopulateDot11fHTCaps( pMac, psessionEntry, &HTCaps );
            limTdlsCovertHTCaps(pMac, peerInfo, &HTCaps) ;

        } while (0) ;
    
        /* now add this new found discovery node into tdls discovery list */
        tdlsDisResult->next = *disResultList ;
        *disResultList = tdlsDisResult ;
        pMac->lim.gLimTdlsDisStaCount++ ; 

        /* See if for this peer already entry in setup Link */ 
        limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;

        /* 
         * if there is no entry for this peer in setup list, we need to 
         * do add sta for this peer to transmit discovery rsp.
         */ 
        if(NULL == setupPeer)
        {
            /* To start with, send add STA request to HAL */
            pMac->lim.gLimAddStaTdls = true ;
            peerInfo->delStaNeeded = true ;

            if(eSIR_FAILURE == limTdlsDisAddSta(pMac, peerMac, 
                                                     peerInfo, psessionEntry))
            {
                VOS_ASSERT(0) ;
                limLog(pMac, LOGE, "Add STA for dis response is failed ") ;
                return eSIR_FAILURE ;
            }
        } /* use setup link sta ID for discovery rsp */
        else
        {
            peerInfo->delStaNeeded = false ;
            limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
            peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
        }

    }
    else
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                    ("discovery procedure in progress for this peer")) ;
    } 

    return eSIR_SUCCESS ;
}

/* Process TDLS setup Request Frame */

static tSirRetStatus limProcessTdlsSetupReqFrame(tpAniSirGlobal pMac, 
                                         tANI_U8 *pBody, tANI_U32 frmLen)
{

    tDot11fTDLSSetupReq tdlsSetupReq = {{0}} ;
    tANI_U32 status = 0 ;
    tpPESession psessionEntry = NULL ;
    tANI_U8 sessionId = 0 ;
    tANI_U8 currentState = TDLS_LINK_SETUP_WAIT_STATE ;
    tANI_U8 previousState = TDLS_LINK_IDLE_STATE ;
    /* create node for Link setup */
    tLimTdlsLinkSetupInfo *linkSetupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tLimTdlsLinkSetupPeer *tmpSetupPeer = NULL ;

    status = dot11fUnpackTDLSSetupReq(pMac, pBody, frmLen, &tdlsSetupReq) ;

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                      "setup Request frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
    }
    /*
     * find session entry using BSSID in link identifier, not using MAC
     * header beacuse, there is cases in TDLS, there may be BSSID will not
     * be present in header
     */
    psessionEntry = peFindSessionByBssid(pMac, 
                         &tdlsSetupReq.LinkIdentifier.bssid[0], &sessionId) ;
    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                 ("no Session entry for TDLS session (bssid "
                  MAC_ADDRESS_STR")"),
                  MAC_ADDR_ARRAY(tdlsSetupReq.LinkIdentifier.bssid));

        //VOS_ASSERT(0) ;
        return eSIR_FAILURE ;
    }
    /* TODO: we don;t need this check now, varify BSSID */
    status = vos_mem_compare( psessionEntry->bssId,
                    &tdlsSetupReq.LinkIdentifier.bssid[0], 
                                                     sizeof(tSirMacAddr)) ;
     
    if(!status)
    {
        limLog( pMac, LOGE, FL("TDLS setup request frame from other BSS -> something wrong. Check RXP filter")) ;

        limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
                                 tdlsSetupReq.DialogToken.token, psessionEntry,
                                 TDLS_SETUP_STATUS_FAILURE, NULL, 0 ) ;
        return eSIR_FAILURE ; 
    }

#ifdef FEATURE_WLAN_TDLS_NEGATIVE
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_RSP_TIMEOUT_TO_SETUP_REQ) 
    {
        /* simply ignore this setup request packet */
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: ignore TDLS Setup Req packet"));
        return eSIR_SUCCESS ;
    }
    if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
        ("TDLS negative running: send TDLS Setup Req to peer TDLS Setup Req"));
        /* format TDLS discovery request frame and transmit it */
        limSendTdlsLinkSetupReqFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, tdlsSetupReq.DialogToken.token, psessionEntry,
            NULL, 0) ;
    }    
#endif
    /* TODO, do more validation */
    
    if(!limTdlsFindLinkPeer(pMac, 
                  &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
                                                  &tmpSetupPeer))
    {
        tANI_U32 tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                        ("Link is already setup with this peer" )) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                        ("state = %d"), tmpSetupPeer->tdls_link_state) ;
        //return eSIR_FAILURE ; 

        if(tmpSetupPeer == NULL)
        {
            VOS_ASSERT(0) ;
            return eSIR_FAILURE ; 
            
        }
        switch(tmpSetupPeer->tdls_link_state)
        {

            case TDLS_LINK_SETUP_START_STATE:
            {
                v_SINT_t macCompare = 0 ;
                macCompare= vos_mem_compare2(tmpSetupPeer->peerMac, 
                           psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
                VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                        ("MAC comparison Rslt = %d"), macCompare ) ;
                if(0 > macCompare)
                {
                    /* 
                     * Delete our Setup Request/Peer info and honour Peer 
                     * Setup Request, go ahead and respond for this 
                     */
                    /* Deactivate the timer */
                    tx_timer_deactivate(&tmpSetupPeer->gLimTdlsLinkSetupRspTimeoutTimer) ;
#ifdef FEATURE_WLAN_TDLS_NEGATIVE
                    if((pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ) 
                        != LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
#endif
                    limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE, 
                            tmpSetupPeer->peerMac, eWNI_SME_TDLS_LINK_START_RSP);

                    limTdlsDelLinkPeer(pMac, tmpSetupPeer->peerMac) ;
                    tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
                }
                else if(0 < macCompare)
                {
                    /* 
                     * Go ahead with current setup as peer is going to 
                     * respond for setup request 
                     */
                    tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;
                }
                else
                {
                    /* same MAC, not possible */
                    VOS_ASSERT(0) ;
                }
            
                break ;
            }
#if 1
            case TDLS_LINK_SETUP_DONE_STATE:
            {
                tpDphHashNode pStaDs = NULL ;

                previousState = TDLS_LINK_SETUP_WAIT_STATE ;
                currentState = TDLS_LINK_TEARDOWN_START_STATE ;
                VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                        ("link Setup Done state "  )) ;
                tmpSetupPeer->tdls_prev_link_state =  previousState ;
                tmpSetupPeer->tdls_link_state = currentState ;
                setupPeer = tmpSetupPeer ;
#if 0                
                /* Send Teardown to this Peer and Initiate new TDLS Setup */
                limSendTdlsTeardownFrame(pMac, 
                      &tdlsSetupReq.LinkIdentifier.InitStaAddr[0], 
                        eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON, psessionEntry) ;
#else
                
                /* tdls_hklee: send message to HAL before it is deleted, cause  */
                limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;

                /* send del STA to remove context for this TDLS STA */
                pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;

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

                if(pStaDs)
                {
                    limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
                                                           pStaDs, eSIR_SUCCESS) ;

                    /* send Teardown Ind to SME */
                    limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
                                                  eWNI_SME_TDLS_TEARDOWN_IND) ;
                    /* remove node from setup list */
                    limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
                }
#endif
                //setupPeer->tdls_prev_link_state = TDLS_LINK_SETUP_RESTART_STATE;
                tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
                break ;

            }
            default:
            {
                VOS_ASSERT(0) ;
                VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                        ("link Setup is Recieved in unknown state" )) ;
                break ;
            }
#endif
        }
        if(tdlsStateStatus == TDLS_LINK_SETUP_START_STATE) 
            return eSIR_FAILURE ;
    }

    if(currentState != TDLS_LINK_TEARDOWN_START_STATE)
    {  
        /* 
         * Now we are sure to send discovery response frame to TDLS discovery 
         * initiator, we don't care, if this request is unicast ro broadcast,
         * we simply, send discovery response frame on direct link.
         */
        setupPeer = vos_mem_malloc(sizeof( tLimTdlsLinkSetupPeer ));
        if ( NULL == setupPeer )
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                                 ( "Unable to allocate memory during ADD_STA" ));
            return eSIR_MEM_ALLOC_FAILED;
        }

        setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
        //setupPeer->tdls_prev_link_state =  setupPeer->tdls_link_state ;
        //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
        setupPeer->tdls_prev_link_state =  previousState ;
        setupPeer->tdls_link_state = currentState ;
        /* TDLS_sessionize: remember sessionId for future */
        setupPeer->tdls_sessionId = psessionEntry->peSessionId;
        setupPeer->tdls_bIsResponder = 0;

        vos_mem_copy(setupPeer->peerMac,
                     &tdlsSetupReq.LinkIdentifier.InitStaAddr[0], 
                                                     sizeof(tSirMacAddr)) ;

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                   ("Setup REQ MAC = " MAC_ADDRESS_STR),
                    MAC_ADDR_ARRAY(setupPeer->peerMac));
 
        limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
        pMac->lim.gLimAddStaTdls = true ;

        /* To start with, send add STA request to HAL */
        if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, setupPeer->peerMac, 
                                                  setupPeer, psessionEntry))
        {
            VOS_ASSERT(0) ;
            vos_mem_free((void **) &setupPeer) ;
            return eSIR_FAILURE ;
        }

        limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
                                  tdlsSetupReq.DialogToken.token, psessionEntry,
                                  TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;

        limStartTdlsTimer(pMac, psessionEntry->peSessionId, 
                                  &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
                               (tANI_U32)setupPeer->peerMac,
                                 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
                                   SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;

        /* update setup peer list */
        setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
        linkSetupInfo->tdlsLinkSetupList = setupPeer ;
    }
    else
    {
        setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
        //setupPeer->tdls_prev_link_state =  setupPeer->tdls_link_state ;
        //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
        setupPeer->tdls_prev_link_state =  previousState ;
        setupPeer->tdls_link_state = currentState ;
        /* TDLS_sessionize: remember sessionId for future */
        setupPeer->tdls_sessionId = psessionEntry->peSessionId;
        setupPeer->tdls_bIsResponder = 0;

        vos_mem_copy( setupPeer->peerMac,
                     &tdlsSetupReq.LinkIdentifier.InitStaAddr[0], 
                                                     sizeof(tSirMacAddr)) ;

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                   ("Setup REQ MAC = "MAC_ADDRESS_STR),
                    MAC_ADDR_ARRAY(setupPeer->peerMac));
 
        limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
        limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, 
                                 tdlsSetupReq.DialogToken.token, psessionEntry,
                                 TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;

        limStartTdlsTimer(pMac, psessionEntry->peSessionId, 
                                  &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
                               (tANI_U32)setupPeer->peerMac,
                                 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
                                   SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;
    }
 
   
    return eSIR_SUCCESS ;

}

/*
 * TDLS discovery request frame received from TDLS peer STA..
 */
static tSirRetStatus limProcessTdlsSetupRspFrame(tpAniSirGlobal pMac, 
                                            tANI_U8 *pBody, tANI_U32 frmLen )
{
    tDot11fTDLSSetupRsp tdlsSetupRsp = {{0}} ;
    tANI_U32 status = 0 ;
    tSirMacAddr peerMac = {0} ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tpPESession psessionEntry = NULL ;
    tANI_U8 sessionId = 0 ;

    status = dot11fUnpackTDLSSetupRsp(pMac, pBody, frmLen, &tdlsSetupRsp) ;

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                               "discovery Request frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
    }

    /*
     * find session entry using BSSID in link identifier, not using MAC
     * header beacuse, there is cases in TDLS, there may be BSSID will not
     * be present in header
     */
    psessionEntry = peFindSessionByBssid(pMac, 
                         &tdlsSetupRsp.LinkIdentifier.bssid[0], &sessionId) ;
    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("no Session entry for TDLS session (bssid "
                  MAC_ADDRESS_STR")"),
                  MAC_ADDR_ARRAY(tdlsSetupRsp.LinkIdentifier.bssid));

        //VOS_ASSERT(0) ;
        return eSIR_FAILURE;
    }
  
    /* varify BSSID */
    status = vos_mem_compare( psessionEntry->bssId,
                    &tdlsSetupRsp.LinkIdentifier.bssid[0], 
                                                  sizeof(tSirMacAddr)) ;
     
    if(!status)
    {
        limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter")) ;

        VOS_ASSERT(0) ;
        return eSIR_FAILURE ; 
    }
    vos_mem_copy( peerMac,
                      &tdlsSetupRsp.LinkIdentifier.RespStaAddr[0], 
                                                     sizeof(tSirMacAddr)) ;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
             ("TDLS setup RSP peer = "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerMac));
    limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;

    if(NULL == setupPeer)
    {
        limLog( pMac, LOGE, FL("unknown setup Response frame other BSS")) ;
        return eSIR_FAILURE ;
    }
                                                
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                      ("deactivating Setup RSP timer")) ;

    /* Deactivate the timer */
    tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupRspTimeoutTimer) ;

    /*
     * TDLS Setup RSP is recieved with Failure, Delete this STA entry
     * don't respond with TDLS CNF frame.
     */
    if(TDLS_SETUP_STATUS_SUCCESS != tdlsSetupRsp.Status.status)
    {
        limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                    ("setup RSP with Failure Code")) ;
        return eSIR_FAILURE ;
    }    
    
    /* update Link Info */
    limTdlsUpdateLinkRspPeerInfo(pMac, setupPeer, &tdlsSetupRsp) ;
 
    /* TODO, do more validation */
    

    /* 
     * Now we are sure to send link setup CNF  frame to TDLS link setup 
     * reponded, now we will create dph hash entry and send add STA to HAL
     */

    pMac->lim.gLimAddStaTdls = true ;
    if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, peerMac,  
                                                 setupPeer, psessionEntry))
    {
       /* through error */
       VOS_ASSERT(0) ;
       return eSIR_FAILURE ;
    } 
    /* TDLS_HKLEE_FIXME: now we add some delay for AddSta_Rsp comes */
    
         
    /* send TDLS confim frame to TDLS Peer STA */           
    limSendTdlsLinkSetupCnfFrame(pMac, peerMac, tdlsSetupRsp.DialogToken.token, 0, psessionEntry, NULL, 0) ;

    /* 
     * set the tdls_link_state to TDLS_LINK_SETUP_RSP_WAIT_STATE, and
     * wait for Setup CNF transmission on air, once we receive tx complete
     * message, we will change the peer state and send message to SME 
     * callback..
     */
    (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
    (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_RSP_WAIT_STATE ;

    return eSIR_SUCCESS ;
}
/*
 * TDLS setup CNF  frame processing ..
 */

static tSirRetStatus limProcessTdlsSetupCnfFrame(tpAniSirGlobal pMac, 
                                            tANI_U8 *pBody, tANI_U32 frmLen)
{
    tDot11fTDLSSetupCnf tdlsSetupCnf = {{0}} ;
    tANI_U32 status = 0 ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tpPESession psessionEntry = NULL ;
    tANI_U8 sessionId = 0 ;

    status = dot11fUnpackTDLSSetupCnf(pMac, pBody, frmLen, &tdlsSetupCnf) ;

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                               "discovery Response frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
    }
    /*
     * find session entry using BSSID in link identifier, not using MAC
     * header beacuse, there is cases in TDLS, there may be BSSID will not
     * be present in header
     */
    psessionEntry = peFindSessionByBssid(pMac, 
                         &tdlsSetupCnf.LinkIdentifier.bssid[0], &sessionId) ;
    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("no Session entry for TDLS session (bssid "
                  MAC_ADDRESS_STR")"),
                  MAC_ADDR_ARRAY(tdlsSetupCnf.LinkIdentifier.bssid));

        //VOS_ASSERT(0) ;
        return eSIR_FAILURE;
    }
 
    /* varify BSSID */
    status = vos_mem_compare( psessionEntry->bssId,
                    &tdlsSetupCnf.LinkIdentifier.bssid[0], 
                                                     sizeof(tSirMacAddr)) ;

    if(!status)
    {
        limLog( pMac, LOGE, FL("TDLS setup CNF frame other BSS -> something wrong. Check RXP filter")) ;

        VOS_ASSERT(0) ;
        return eSIR_FAILURE ; 
    }
    /* TODO, do more validation */
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
               ("setup Cnf peer MAc = "MAC_ADDRESS_STR),
                MAC_ADDR_ARRAY(tdlsSetupCnf.LinkIdentifier.InitStaAddr));
    
    limTdlsFindLinkPeer(pMac, 
                   &tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
                            &setupPeer) ;

    if(NULL == setupPeer)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                          (" unknown setup CNF frame")) ;
        VOS_ASSERT(0) ;
        return eSIR_FAILURE ;
    }
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                   ("setup CNF peer MAC = "MAC_ADDRESS_STR),
                    MAC_ADDR_ARRAY((setupPeer)->peerMac));
    /*T match dialog token, before proceeding further */
    if((setupPeer)->dialog != tdlsSetupCnf.DialogToken.token)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                          ("setup CNF frame not matching with setup RSP")) ;
        VOS_ASSERT(0) ;
        return eSIR_FAILURE ;
    }

    /* 
     * Now we are sure that, this set CNF is for us, now stop 
     * the running timer..
     */
    tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupCnfTimeoutTimer) ;

    /* change TDLS peer State */
    (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
    (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ; 

    /* send indication to SME that, new link is setup */
    limSendSmeTdlsLinkSetupInd(pMac, (setupPeer)->peerMac, eSIR_SUCCESS) ;

    /* tdls_hklee: prepare PTI template and send it to HAL */
    limTdlsLinkEstablish(pMac, (setupPeer)->peerMac);

    return eSIR_SUCCESS ; 

}

/*
 * TDLS discovery response frame processing ..
 */

static tSirRetStatus limProcessTdlsDisRspFrame(tpAniSirGlobal pMac, 
                              tANI_U8 *pBody, tANI_U32 frmLen, 
                                 tANI_S8 rssi, tpPESession psessionEntry)
{
    tDot11fTDLSDisRsp tdlsDisRsp = {{0}} ;
    tANI_U32 status = 0 ;
    tLimDisResultList *tdlsDisResult = NULL ; 
    tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
    tSirTdlsDisReq *prevDisReq = &pMac->lim.gLimTdlsDisReq ;

    status = dot11fUnpackTDLSDisRsp(pMac, pBody, frmLen, &tdlsDisRsp) ;

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                               "discovery Response frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);)
    }
    /*TODO:  match dialog token, before proceeding further */

    /* varify BSSID */
    status = vos_mem_compare( psessionEntry->bssId,
                    &tdlsDisRsp.LinkIdentifier.bssid[0], 
                                                     sizeof(tSirMacAddr)) ;

    if(!status)
    {
        limLog( pMac, LOGW, FL(" TDLS discovery Response frame other BSS")) ;
        return eSIR_FAILURE ; 
    }
    /* TODO, do more validation */
  
    if(tdlsDisRsp.DialogToken.token != prevDisReq->dialog)
    {
        limLog( pMac, LOGW, FL(" wrong TDLS discovery Response frame")) ;
        return eSIR_FAILURE ;
    } 

    pMac->lim.gLimTdlsDisStaCount++ ;

    /*
     * we are allocating peer info for individual peers found in TDLS
     * discovery, we need to keep adding TDLS peers till we have timed
     * out. We are freeing this memory at the time we are sending this
     * collected peer info to SME.
     */
    tdlsDisResult = vos_mem_malloc(sizeof(tLimDisResultList));
    if ( NULL == tdlsDisResult )
    {
        limLog(pMac, LOGP, FL("alloc fail for TDLS discovery reponse info")) ;
        return eSIR_FAILURE ;
    }

    do
    {
        tSirTdlsPeerInfo *peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;

        /* Populate peer info of tdls discovery result */
        peerInfo->sessionId = psessionEntry->peSessionId;
        /*
         * When we receive DIS RSP from peer MAC,
         * STA_MAC_OFFSET will carry peer MAC address and PEER MAC OFFSET
         * will carry our MAC.
         */
        vos_mem_copy( peerInfo->peerMac,
                    &tdlsDisRsp.LinkIdentifier.RespStaAddr[0], 
                                                     sizeof(tSirMacAddr)) ;

        /* update RSSI for this TDLS peer STA */
        peerInfo->tdlsPeerRssi = rssi ;

        /* update Caps Info */
        tdlsUpdateCapInfo(&peerInfo->capabilityInfo,
                                          &tdlsDisRsp.Capabilities) ;

        /* update Supp rates */
        if(tdlsDisRsp.SuppRates.present)
        { 
            ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates, 
                                             &tdlsDisRsp.SuppRates );
        }

        /* update EXT supp rates */
        if(tdlsDisRsp.ExtSuppRates.present) 
        {
            peerInfo->ExtRatesPresent = 1;
            ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates, 
                                                    &tdlsDisRsp.ExtSuppRates );
        }
        /* update HT caps */
        if (tdlsDisRsp.HTCaps.present)
        {
            vos_mem_copy( &peerInfo->tdlsPeerHtCaps, &tdlsDisRsp.HTCaps,
                                               sizeof( tDot11fIEHTCaps ) );
        }
    } while(0) ;

    /* now add this new found discovery node into tdls discovery list */
    tdlsDisResult->next = *disResultList ;
    *disResultList = tdlsDisResult ; 

    return eSIR_SUCCESS ; 
}

/* 
 * Process TDLS Teardown request frame from TDLS peer STA
 */
static tSirRetStatus limProcessTdlsTeardownFrame(tpAniSirGlobal pMac, 
                                      tANI_U8 *pBody, tANI_U32 frmLen )
{
    tDot11fTDLSTeardown tdlsTeardown = {{0}} ;
    tANI_U32 status = 0 ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tpPESession psessionEntry = NULL ;
    tANI_U8 sessionId = 0 ;

    status = dot11fUnpackTDLSTeardown(pMac, pBody, frmLen, &tdlsTeardown) ;

    if ( DOT11F_FAILED( status ) )
    {
        limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response "
                              "frame (0x%08x, %d bytes):"),status, frmLen);
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while unpacking a TDLS "
                               "discovery Response frame (0x%08x, %d bytes):"),
                   status, frmLen );
        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
    }

    /*
     * find session entry using BSSID in link identifier, not using MAC
     * header beacuse, there is cases in TDLS, there may be BSSID will not
     * be present in header
     */
    psessionEntry = peFindSessionByBssid(pMac, 
                         &tdlsTeardown.LinkIdentifier.bssid[0], &sessionId) ;
    if(NULL == psessionEntry)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("no Session entry for TDLS session (bssid "
                  MAC_ADDRESS_STR")"),
                  MAC_ADDR_ARRAY(tdlsTeardown.LinkIdentifier.bssid));

        //VOS_ASSERT(0) ;
        return eSIR_FAILURE;
    }
 
    /* varify BSSID */
    status = vos_mem_compare( psessionEntry->bssId,
                                  &tdlsTeardown.LinkIdentifier.bssid[0], 
                                                     sizeof(tSirMacAddr)) ;


    if(!status)
    {
        limLog( pMac, LOGE, FL("Teardown from other BSS -> something wrong. Check RXP filter")) ;
        VOS_ASSERT(0) ;
        return eSIR_FAILURE ; 
    }
    
    limTdlsFindLinkPeer(pMac, 
                     &tdlsTeardown.LinkIdentifier.InitStaAddr[0],
                                            &setupPeer) ;

    if(NULL == setupPeer)
    {
        //ignore
        //VOS_ASSERT(0) ;
        limLog( pMac, LOGE, FL("Teardown from unknown peer. --> ignored") );
        
        return eSIR_FAILURE ;
    }
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                     ("teardown for peer "MAC_ADDRESS_STR),
                          MAC_ADDR_ARRAY((setupPeer)->peerMac));

    switch(tdlsTeardown.Reason.code)
    {
        case eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON:
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                 ("teardown with unspecified reason")) ;
            break ;
        }
        case eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE:
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                       (" Teardown from AP, TDLS peer unreachable")) ;
            break ;
        }
        default:
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                            (" unknown teardown")) ;
            break ;
        }
    }

    /* change TDLS peer State */
    (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
    (setupPeer)->tdls_link_state = TDLS_LINK_TEARDOWN_START_STATE ; 

    do
    {
        tpDphHashNode pStaDs = NULL ;

        /* tdls_hklee: send message to HAL before it is deleted, cause  */
        limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;

        /* send del STA to remove context for this TDLS STA */
        pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;

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

        if(pStaDs)
        {
            limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
                                                   pStaDs, eSIR_SUCCESS) ;
      
            /* send Teardown Ind to SME */
            limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
                                          eWNI_SME_TDLS_TEARDOWN_IND) ;
            /* remove node from setup list */
            limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
        }

    }while(0) ;
    
    return status ;
}

/*
 * Common processing of TDLS action frames recieved 
 */
void limProcessTdlsFrame(tpAniSirGlobal pMac, tANI_U32 *pBd)
{
    tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
    tANI_U8 pOffset = ((0 == WDA_GET_RX_FT_DONE(pBd)) 
                         ? (( sizeof( eth_890d_header ))) :(0)) ;

    tANI_U8 category   = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[0] ; 
    tANI_U8 action     =   (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[1] ; 
    tANI_U32 frameLen  = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
    tANI_U8 *tdlsFrameBody = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
    //tANI_S8 rssi = (tANI_S8)SIR_MAC_BD_TO_RSSI_DB(pBd);

    if(category != SIR_MAC_ACTION_TDLS)
    {
        limLog( pMac, LOGE, FL("Invalid TDLS action frame=(%d). Ignored"), category );
        return ; 
    }

    frameLen -= (pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Received TDLS action %d (%s)"),
        action, limTraceTdlsActionString(action) ));

    switch(action)
    {

        case SIR_MAC_TDLS_SETUP_REQ:
        {
            limProcessTdlsSetupReqFrame(pMac, tdlsFrameBody, frameLen) ;
            break ;
        }
        case SIR_MAC_TDLS_SETUP_RSP:
        {
            limProcessTdlsSetupRspFrame(pMac, tdlsFrameBody, frameLen) ;
            break ;
        }
        case SIR_MAC_TDLS_SETUP_CNF:
        {
            limProcessTdlsSetupCnfFrame(pMac, tdlsFrameBody, frameLen) ; 
            break ;
        }
        case SIR_MAC_TDLS_TEARDOWN: 
        {
            limProcessTdlsTeardownFrame(pMac, tdlsFrameBody, frameLen) ; 
            break ;
        }
        case SIR_MAC_TDLS_DIS_REQ:
        {
            limProcessTdlsDisReqFrame(pMac, tdlsFrameBody, frameLen) ;
            break ;
        }
        case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
        case SIR_MAC_TDLS_CH_SWITCH_REQ:      
        case SIR_MAC_TDLS_CH_SWITCH_RSP:    
        case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
        default:
        {
            break ;
        }
    }
    
    return ;    
}

/*
 * ADD sta for dis response fame sent on direct link
 */
static tSirRetStatus limTdlsDisAddSta(tpAniSirGlobal pMac, tSirMacAddr peerMac, 
                          tSirTdlsPeerInfo *peerInfo, tpPESession psessionEntry)
{
    tpDphHashNode pStaDs = NULL ;
    tSirRetStatus status = eSIR_SUCCESS ;
    tANI_U16 aid = 0 ;

    if(NULL == peerInfo)
    {
        VOS_ASSERT(0) ;
        return status ;

    } 
    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
               ("ADD STA peer MAC: "MAC_ADDRESS_STR),
                MAC_ADDR_ARRAY(peerMac));


    if(NULL != dphLookupHashEntry(pMac, peerMac, 
                                  &aid, &psessionEntry->dph.dphHashTable))
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                    (" there is hash entry for this client")) ;
        status = eSIR_FAILURE ;
        VOS_ASSERT(0) ;
        return status ;
    }

    aid = limAssignPeerIdx(pMac, psessionEntry) ;

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

    pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);

    if (pStaDs)
    {
        (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
        limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
    }
    pStaDs = dphAddHashEntry(pMac, peerMac, aid, 
                                         &psessionEntry->dph.dphHashTable) ;

    if(NULL == pStaDs)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                    (" add hash entry failed")) ;
        status = eSIR_FAILURE ;
        VOS_ASSERT(0) ;
        return status;
    }
    if(eSIR_SUCCESS == status)
    {
#ifdef TDLS_RATE_DEBUG
        tSirMacRateSet *suppRates = &peerInfo->tdlsPeerSuppRates ;
        tSirMacRateSet *extRates = &peerInfo->tdlsPeerExtRates ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                                  ("pSta DS [%p] "), pStaDs) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                   ("peerInfo->tdlsPeerSuppRates = [%p]"),
                        (tANI_U8 *)&peerInfo->tdlsPeerSuppRates) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
               ("peerInfo->tdlsPeerExtRates = [%p]"),
                        (tANI_U8 *)&peerInfo->tdlsPeerExtRates) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
              ("peerInfo->tdlsPeerPropRates = [%p]"),
                        (tANI_U8 *)&pStaDs->mlmStaContext.propRateSet) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
              ("peerInfo->mcs = [%p]"),
                        (tANI_U8 *)peerInfo->supportedMCSSet) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                  ("num of supp rates = %02x"), suppRates->numRates) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
                      ("num of ext rates = %01x"), extRates->numRates) ;
#endif

        /* Populate matching rate set */
#ifdef WLAN_FEATURE_11AC
        if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs, 
                                    &peerInfo->tdlsPeerSuppRates,
                                      &peerInfo->tdlsPeerExtRates, 
                                        peerInfo->supportedMCSSet,
                                         &pStaDs->mlmStaContext.propRateSet, 
                                                              psessionEntry, NULL))
#else
        if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs, 
                                    &peerInfo->tdlsPeerSuppRates,
                                      &peerInfo->tdlsPeerExtRates, 
                                        peerInfo->supportedMCSSet,
                                         &pStaDs->mlmStaContext.propRateSet, 
                                                              psessionEntry))
#endif
        {
            VOS_ASSERT(0) ;
        }


        pStaDs->mlmStaContext.capabilityInfo = peerInfo->capabilityInfo;
        vos_mem_copy( pStaDs->staAddr, peerMac, sizeof(tSirMacAddr)) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                ("Add STA for Peer: "MAC_ADDRESS_STR),
                 MAC_ADDR_ARRAY(pStaDs->staAddr));
    

        pStaDs->staType = STA_ENTRY_TDLS_PEER ;

        status = limAddSta(pMac, pStaDs, false, psessionEntry);

        if(eSIR_SUCCESS != status)
        {
            /* should not fail */
            VOS_ASSERT(0) ;
        }
    }
  
    return status ;
}
#endif
/*
 * Add STA for TDLS setup procedure 
 */ 
static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac,
                                        tSirTdlsAddStaReq *pAddStaReq,
                                        tpPESession psessionEntry)
{
    tpDphHashNode pStaDs = NULL ;
    tSirRetStatus status = eSIR_SUCCESS ;
    tANI_U16 aid = 0 ;

    pStaDs = dphLookupHashEntry(pMac, pAddStaReq->peerMac, &aid,
                                      &psessionEntry->dph.dphHashTable);
    if(NULL == pStaDs)
    {
        aid = limAssignPeerIdx(pMac, psessionEntry) ;

        if( !aid )
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
              ("%s: No more free AID for peer " MAC_ADDRESS_STR),
                __func__, MAC_ADDR_ARRAY(pAddStaReq->peerMac)) ;
            return eSIR_FAILURE;
        }

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

        VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
              ("limTdlsSetupAddSta: Aid = %d, for peer =" MAC_ADDRESS_STR),
                aid, MAC_ADDR_ARRAY(pAddStaReq->peerMac));
        pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);

        if (pStaDs)
        {
            (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
            limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
        }

        pStaDs = dphAddHashEntry(pMac, pAddStaReq->peerMac, aid,
                                             &psessionEntry->dph.dphHashTable) ;

        if(NULL == pStaDs)
        {
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                        (" add hash entry failed")) ;
            VOS_ASSERT(0) ;
            return eSIR_FAILURE;
        }
    }

    limTdlsUpdateHashNodeInfo(pMac, pStaDs, pAddStaReq, psessionEntry) ;

    pStaDs->staType = STA_ENTRY_TDLS_PEER ;

    status = limAddSta(pMac, pStaDs, (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) ? true: false, psessionEntry);

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

/*
 * Del STA, after Link is teardown or discovery response sent on direct link
 */
static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac, 
                                                    tpPESession psessionEntry)
{
    tSirRetStatus status = eSIR_SUCCESS ;
    tANI_U16 peerIdx = 0 ;
    tpDphHashNode pStaDs = NULL ;
 
    pStaDs = dphLookupHashEntry(pMac, peerMac, &peerIdx, 
                                         &psessionEntry->dph.dphHashTable) ;

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

        VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
                   ("limTdlsDelSta: STA type = %x, sta idx = %x"),pStaDs->staType,
                                                           pStaDs->staIndex) ;
 
        status = limDelSta(pMac, pStaDs, false, psessionEntry) ;
#ifdef FEATURE_WLAN_TDLS_INTERNAL
        if(eSIR_SUCCESS == status)
        {
            limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx, psessionEntry) ;
            limReleasePeerIdx(pMac, peerIdx, psessionEntry) ;
        }
        else
        {
            VOS_ASSERT(0) ;
        }
#endif
    }
           
    return pStaDs ;
}
     
#ifdef FEATURE_WLAN_TDLS_INTERNAL
/* 
* Prepare link establish message for HAL, construct PTI template.
*
*/   
static tSirRetStatus limTdlsLinkEstablish(tpAniSirGlobal pMac, tSirMacAddr peerMac)
{
    tANI_U8             pFrame[64] ;
    tDot11fTDLSPeerTrafficInd tdlsPtiTemplate ;
    tANI_U32            status = 0 ;
    tANI_U32            nPayload = 0 ;
    tANI_U32            nBytes = 0 ;
    tANI_U32            header_offset = 0 ;
    tANI_U16            aid = 0 ;
    tDphHashNode        *pStaDs = NULL ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tpPESession psessionEntry = NULL ;


    limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
    if(NULL == setupPeer) {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
            ("limTdlsLinkEstablish: cannot find peer mac "
             "in tdls linksetup list: "MAC_ADDRESS_STR),
             MAC_ADDR_ARRAY(peerMac));
        return eSIR_FAILURE;
    }

    psessionEntry = peFindSessionBySessionId(pMac, 
                         setupPeer->tdls_sessionId) ;

    if(NULL == psessionEntry) 
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
             ("limTdlsLinkEstablish: sessionID %d is not found"), setupPeer->tdls_sessionId);
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }


    pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable) ;
    if(pStaDs == NULL) {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("limTdlsLinkEstablish: cannot find peer mac "
                   "in tdls linksetup list: "MAC_ADDRESS_STR),
                   MAC_ADDR_ARRAY(peerMac));
        return eSIR_FAILURE;
    }

    vos_mem_set( ( tANI_U8* )&tdlsPtiTemplate,
               sizeof( tDot11fTDLSPeerTrafficInd ), 0 );

    /*
    * setup Fixed fields,
    */
    tdlsPtiTemplate.Category.category = SIR_MAC_ACTION_TDLS;
    tdlsPtiTemplate.Action.action     = SIR_MAC_TDLS_PEER_TRAFFIC_IND;
    tdlsPtiTemplate.DialogToken.token = 0 ; /* filled by firmware at the time of transmission */
#if 1 
    /* CHECK_PTI_LINK_IDENTIFIER_INITIATOR_ADDRESS: initator address should be TDLS link setup's initiator address, 
    then below code makes such an way */
    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
        peerMac, !setupPeer->tdls_bIsResponder) ;
#else
   /* below code will make PTI's linkIdentifier's initiator address be selfAddr */
    PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
        peerMac, TDLS_INITIATOR) ;
#endif

    /* PUBufferStatus will be filled by firmware at the time of transmission */
    tdlsPtiTemplate.PUBufferStatus.present = 1;

    /* TODO: get ExtendedCapabilities IE */

    /* 
    * now we pack it.  First, how much space are we going to need?
    */
    status = dot11fGetPackedTDLSPeerTrafficIndSize ( pMac, &tdlsPtiTemplate, &nPayload);
    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGP, FL("Failed to calculate the packed size for a PTI template (0x%08x)."), status );
        /* We'll fall back on the worst case scenario: */
        nPayload = sizeof( tdlsPtiTemplate );
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while calculating the packed size for a PTI template (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 ) 
            + sizeof( eth_890d_header ) 
            + PAYLOAD_TYPE_TDLS_SIZE ;

    if(nBytes > 64) {
        limLog( pMac, LOGE, FL("required memory for PTI frame is %ld, but reserved only 64."), nBytes);
        nBytes = 64;
    }
    /* zero out the memory */
    vos_mem_set( pFrame, sizeof(pFrame), 0 );

    /* fill out the buffer descriptor */

    header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, 
        LINK_IDEN_ADDR_OFFSET(tdlsPtiTemplate), TDLS_LINK_AP, !setupPeer->tdls_bIsResponder, psessionEntry) ;

    status = dot11fPackTDLSPeerTrafficInd ( pMac, &tdlsPtiTemplate, pFrame 
        + header_offset, nPayload, &nPayload );

    if ( DOT11F_FAILED( status ) )
    {
        limLog( pMac, LOGE, FL("Failed to pack a PTI template (0x%08x)."),
                status );
        return eSIR_FAILURE;
    }
    else if ( DOT11F_WARNED( status ) )
    {
        limLog( pMac, LOGW, FL("There were warnings while packing TDLS "
                               "Peer Traffic Indication (0x%08x)."), status );
    }

    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("bIsResponder=%d, header_offset=%ld, linkIdenOffset=%d, ptiBufStatusOffset=%d "),
        setupPeer->tdls_bIsResponder, header_offset, PTI_LINK_IDEN_OFFSET, PTI_BUF_STATUS_OFFSET));

    limSendTdlsLinkEstablish(pMac, setupPeer->tdls_bIsResponder, 
        header_offset+PTI_LINK_IDEN_OFFSET, header_offset+PTI_BUF_STATUS_OFFSET, 
      nBytes, pFrame, (tANI_U8 *)&setupPeer->tdlsPeerExtCaps);

    return eSIR_SUCCESS;
}

/* 
* Prepare link teardown message for HAL from peer_mac
*
*/   
static tSirRetStatus limTdlsLinkTeardown(tpAniSirGlobal pMac, tSirMacAddr peerMac)
{
    tDphHashNode        *pStaDs = NULL ;
    tANI_U16            aid = 0 ;
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;
    tpPESession psessionEntry = NULL ;


    limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
    if(NULL == setupPeer) {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("limTdlsLinkTeardown: cannot find peer mac "
                   "in tdls linksetup list: "
                   MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerMac));
        return eSIR_FAILURE;
    }

    psessionEntry = peFindSessionBySessionId(pMac, 
                         setupPeer->tdls_sessionId) ;

    if(NULL == psessionEntry) 
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
             ("limTdlsLinkTeardown: sessionID %d is not found"), setupPeer->tdls_sessionId);
        VOS_ASSERT(0) ;
        return eHAL_STATUS_FAILURE;
    }



    pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable);

    if(pStaDs == NULL) {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  ("limTdlsLinkTeardown: cannot find peer mac "
                   "in hash table: "
                   MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerMac));
        return eSIR_FAILURE;
    }

    limSendTdlsLinkTeardown(pMac, pStaDs->staIndex);

    return eSIR_SUCCESS;
}

/* 
 * Prepare Discovery RSP message for SME, collect peerINfo for all the 
 * peers discovered and delete/clean discovery lists in PE.
 */   
 
static tSirTdlsDisRsp *tdlsPrepareTdlsDisRsp(tpAniSirGlobal pMac, 
                                 tSirTdlsDisRsp *disRsp, tANI_U8 disStaCount) 
{
    tANI_U32 disMsgRspSize = sizeof(tSirTdlsDisRsp);
    tANI_U8 status = eHAL_STATUS_SUCCESS ;

    /*
     * allocate memory for tdls discovery response, allocated memory should
     * be alloc_mem = tdlsStaCount * sizeof(peerinfo) 
     *                              + siezeof tSirTdlsDisRsp.
     */
    disMsgRspSize += (disStaCount * sizeof(tSirTdlsPeerInfo));
        
    /* now allocate memory */

    disRsp = vos_mem_malloc(disMsgRspSize);
    if ( NULL == disRsp )
    {
        limLog(pMac, LOGP, FL("AllocateMemory failed for DIS RSP"));
        return NULL ;
    }
        
    if(disStaCount)
    { 
        tLimDisResultList *tdlsDisRspList = pMac->lim.gLimTdlsDisResultList ;
        tSirTdlsPeerInfo *peerInfo = &disRsp->tdlsDisPeerInfo[0] ;
            
        tLimDisResultList *currentNode = tdlsDisRspList ;
        while(tdlsDisRspList != NULL)
        {

            vos_mem_copy( (tANI_U8 *)peerInfo,
                          (tANI_U8 *) &tdlsDisRspList->tdlsDisPeerInfo, 
                                                 sizeof(tSirTdlsPeerInfo));
        
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
            ("Msg Sent to PE, peer MAC: "MAC_ADDRESS_STR),
                                  MAC_ADDR_ARRAY(peerInfo->peerMac));
            disStaCount-- ;
            peerInfo++ ;
            currentNode = tdlsDisRspList ;
            tdlsDisRspList = tdlsDisRspList->next ;
            vos_mem_free(currentNode) ;
            /* boundary condition check, may be fatal */
            if(((!disStaCount) && (tdlsDisRspList)) 
                            || ((!tdlsDisRspList) && disStaCount))
            {
                limLog(pMac, LOG1, FL("mismatch in dis sta count and "
                                      "number of nodes in list")) ;
                VOS_ASSERT(0) ;
                return NULL ;
            } 
        } /* end  of while */

        /* All discovery STA processed */
        pMac->lim.gLimTdlsDisResultList = NULL ;

    } /* end of if dis STA count */
    
    return (disRsp) ;
}

/* Send Teardown response back to PE */

void limSendSmeTdlsTeardownRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
                                        tSirMacAddr peerMac, tANI_U16 msgType)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsTeardownRsp *teardownRspMsg = NULL ;
    tANI_U8 status = eHAL_STATUS_SUCCESS ;
    
    mmhMsg.type = msgType ;

    teardownRspMsg = vos_mem_malloc(sizeof(tSirTdlsTeardownRsp));
    if ( NULL == teardownRspMsg )
    {
        VOS_ASSERT(0) ;
    } 
    vos_mem_copy( teardownRspMsg->peerMac, (tANI_U8 *)peerMac,
                                                   sizeof(tSirMacAddr)) ;
    teardownRspMsg->statusCode =  statusCode ;
    mmhMsg.bodyptr = teardownRspMsg ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

    return ;

}

/*
 * Send Link start RSP back to SME after link is setup or failed
 */
void limSendSmeTdlsLinkStartRsp(tpAniSirGlobal pMac,
                                         tSirResultCodes statusCode,
                                          tSirMacAddr peerMac, 
                                                 tANI_U16 msgType)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsLinksetupRsp *setupRspMsg = NULL ;
    tANI_U8 status = eHAL_STATUS_SUCCESS ;

    mmhMsg.type = msgType ;

    setupRspMsg = vos_mem_malloc(sizeof(tSirTdlsLinksetupRsp));
    if ( NULL == setupRspMsg )
    {
        VOS_ASSERT(0) ;
    } 

    vos_mem_copy( setupRspMsg->peerMac, (tANI_U8 *)peerMac,
                                                   sizeof(tSirMacAddr)) ;
    setupRspMsg->statusCode =  statusCode ;
    mmhMsg.bodyptr = setupRspMsg ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

    return ;
}

/*
 * Send TDLS discovery RSP back to SME 
 */
void limSendSmeTdlsDisRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
                                                          tANI_U16 msgType)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsDisRsp *tdlsDisRsp = NULL ;

    mmhMsg.type = msgType ;

    if(eSIR_SME_SUCCESS == statusCode)
    {
        tANI_U8 tdlsStaCount = pMac->lim.gLimTdlsDisStaCount ;

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                    ("no of TDLS STA discovered: %d"), tdlsStaCount) ;
        tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, tdlsStaCount) ;

        if(tdlsDisRsp)
        {
            tdlsDisRsp->numDisSta = tdlsStaCount ;
        }
        else
        {
            limLog(pMac, LOGP, FL("fatal failure for TDLS DIS RSP"));
            VOS_ASSERT(0) ; 
            return ;
        }
        /* all Discovery STA is processed */
        pMac->lim.gLimTdlsDisStaCount = 0 ;
    }
    else
    {
        tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, 0) ;
    }

    tdlsDisRsp->statusCode =  statusCode ;
    mmhMsg.bodyptr = tdlsDisRsp ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

     return ;
}

/* 
 * Once Link is setup with PEER, send Add STA ind to SME
 */
static eHalStatus limSendSmeTdlsAddPeerInd(tpAniSirGlobal pMac, 
                   tANI_U8 sessionId, tDphHashNode   *pStaDs, tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsPeerInd *peerInd = NULL ;
    mmhMsg.type = eWNI_SME_ADD_TDLS_PEER_IND ;

    peerInd = vos_mem_malloc(sizeof(tSirTdlsPeerInd));
    if ( NULL == peerInd )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return eSIR_FAILURE;
    }

    vos_mem_copy( peerInd->peerMac,
                           (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
    peerInd->sessionId = sessionId;
    peerInd->staId = pStaDs->staIndex ;
    peerInd->ucastSig = pStaDs->ucUcastSig ;
    peerInd->bcastSig = pStaDs->ucBcastSig ;
    peerInd->length = sizeof(tSmeIbssPeerInd) ;

    mmhMsg.bodyptr = peerInd ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

    return eSIR_SUCCESS ;

}

/*
 * Once link is teardown, send Del Peer Ind to SME
 */
static eHalStatus limSendSmeTdlsDelPeerInd(tpAniSirGlobal pMac, 
                    tANI_U8 sessionId, tDphHashNode   *pStaDs, tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsPeerInd *peerInd = NULL ;
    mmhMsg.type = eWNI_SME_DELETE_TDLS_PEER_IND ;

    peerInd = vos_mem_malloc(sizeof(tSirTdlsPeerInd));
    if ( NULL == peerInd )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return eSIR_FAILURE;
    }

    vos_mem_copy( peerInd->peerMac,
                           (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
    peerInd->sessionId = sessionId;
    peerInd->staId = pStaDs->staIndex ;
    peerInd->ucastSig = pStaDs->ucUcastSig ;
    peerInd->bcastSig = pStaDs->ucBcastSig ;
    peerInd->length = sizeof(tSmeIbssPeerInd) ;

    mmhMsg.bodyptr = peerInd ;

    //peerInd->statusCode =  status ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return eSIR_SUCCESS ;

}

/*
 * Send Link setup Ind to SME, This is the case where, link setup is 
 * initiated by peer STA
 */
static eHalStatus limSendSmeTdlsLinkSetupInd(tpAniSirGlobal pMac, 
                                   tSirMacAddr peerMac, tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsLinkSetupInd *setupInd = NULL ;

    mmhMsg.type = eWNI_SME_TDLS_LINK_START_IND ;
    setupInd = vos_mem_malloc(sizeof(tSirTdlsLinkSetupInd));
    if ( NULL == setupInd )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return eSIR_FAILURE;
    }

    vos_mem_copy( setupInd->peerMac,
                           (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
    setupInd->length = sizeof(tSirTdlsLinkSetupInd);
    setupInd->statusCode = status ;
    mmhMsg.bodyptr = setupInd ;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

    return eSIR_SUCCESS ;

}

/*
 * Setup RSP timer handler 
 */
void limTdlsLinkSetupRspTimerHandler(void *pMacGlobal, tANI_U32 timerId)
{

    tANI_U32         statusCode;
    tSirMsgQ    msg;
    tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;

    /* Prepare and post message to LIM Message Queue */

    msg.type = SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT;
    msg.bodyptr = NULL ;
    msg.bodyval = timerId ;

    if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
        limLog(pMac, LOGE,
               FL("posting message %X to LIM failed, reason=%d"),
               msg.type, statusCode);
    return ;
}

/*
 * Link setup CNF timer
 */
void limTdlsLinkSetupCnfTimerHandler(void *pMacGlobal, tANI_U32 timerId)
{

    tANI_U32         statusCode;
    tSirMsgQ    msg;
    tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;

    // Prepare and post message to LIM Message Queue

    msg.type = SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT;
    msg.bodyptr = NULL ;
    msg.bodyval = timerId ;

    if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
        limLog(pMac, LOGE,
               FL("posting message %X to LIM failed, reason=%d"),
               msg.type, statusCode);
    return ;
}

/*
 * start TDLS timer
 */
void limStartTdlsTimer(tpAniSirGlobal pMac, tANI_U8 sessionId, TX_TIMER *timer,
                        tANI_U32 timerId, tANI_U16 timerType, tANI_U32 timerMsg)
{
    tANI_U32 cfgValue = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
                           ? WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT
                            : WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT ;

    void *timerFunc = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
                                ? (limTdlsLinkSetupRspTimerHandler) 
                                    : limTdlsLinkSetupCnfTimerHandler ;

    /* TODO: Read timer vals from CFG */

    cfgValue = SYS_MS_TO_TICKS(cfgValue);
    /*
     * create TDLS discovery response wait timer and activate it
     */
    if (tx_timer_create(timer, "TDLS link setup timers", timerFunc,
                        timerId, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS)
    {
        limLog(pMac, LOGP,
           FL("could not create TDLS discovery response wait timer"));
        return;
    }

    //assign appropriate sessionId to the timer object
    timer->sessionId = sessionId; 
    
     MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0,
                                             eLIM_TDLS_DISCOVERY_RSP_WAIT));
    if (tx_timer_activate(timer) != TX_SUCCESS)
    {
        limLog(pMac, LOGP, FL("TDLS link setup timer activation failed!"));
        return ;
    }

    return ;

}
#endif

/* 
 * Once Link is setup with PEER, send Add STA ind to SME
 */
static eHalStatus limSendSmeTdlsAddStaRsp(tpAniSirGlobal pMac, 
                   tANI_U8 sessionId, tSirMacAddr peerMac, tANI_U8 updateSta,
                   tDphHashNode  *pStaDs, tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsAddStaRsp *addStaRsp = NULL ;
    mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ;

    addStaRsp = vos_mem_malloc(sizeof(tSirTdlsAddStaRsp));
    if ( NULL == addStaRsp )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return eSIR_FAILURE;
    }

    addStaRsp->sessionId = sessionId;
    addStaRsp->statusCode = status;
    if( pStaDs )
    {
        addStaRsp->staId = pStaDs->staIndex ;
        addStaRsp->ucastSig = pStaDs->ucUcastSig ;
        addStaRsp->bcastSig = pStaDs->ucBcastSig ;
    }
    if( peerMac )
    {
        vos_mem_copy( addStaRsp->peerMac,
                (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
    }
    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 ;

    mmhMsg.bodyptr = addStaRsp;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);

    return eSIR_SUCCESS ;

}
/* 
 * STA RSP received from HAL
 */
eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, 
                                                   tpPESession psessionEntry)
{
    tAddStaParams  *pAddStaParams = (tAddStaParams *) msg ;
    tANI_U8        status = eSIR_SUCCESS ;
    tDphHashNode   *pStaDs = NULL ;
    tANI_U16        aid = 0 ;

    SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
    VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
            ("limTdlsAddStaRsp: staIdx=%d, staMac="MAC_ADDRESS_STR), pAddStaParams->staIdx,
                            MAC_ADDR_ARRAY(pAddStaParams->staMac));

    if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
    {
        VOS_ASSERT(0) ;
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                                                   ("Add sta failed ")) ;
        status = eSIR_FAILURE;
        goto add_sta_error;
    }

    pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid, 
                                         &psessionEntry->dph.dphHashTable);
    if(NULL == pStaDs)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                                                   ("pStaDs is NULL ")) ;
        status = eSIR_FAILURE;
        goto add_sta_error;
    }

    pStaDs->bssId                  = pAddStaParams->bssIdx;
    pStaDs->staIndex               = pAddStaParams->staIdx;
    pStaDs->ucUcastSig             = pAddStaParams->ucUcastSig;
    pStaDs->ucBcastSig             = pAddStaParams->ucBcastSig;
    pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
    pStaDs->valid                  = 1 ;
#ifdef FEATURE_WLAN_TDLS_INTERNAL    
    status = limSendSmeTdlsAddPeerInd(pMac, psessionEntry->smeSessionId, 
                                                    pStaDs, eSIR_SUCCESS ) ;
    if(eSIR_FAILURE == status)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                                         ("Peer IND msg to SME failed")) ;
        vos_mem_free( pAddStaParams );
        return eSIR_FAILURE ;
    }

    /* 
     * Now, there is two things a) ADD STA RSP for ADD STA request sent
     * after recieving discovery request from Peer.
     * now we have to send discovery response, if there is any pending
     * discovery equest..
     */
    do
    {
        tSirTdlsPeerInfo *peerInfo = limTdlsFindDisPeer(pMac,
                                            pAddStaParams->staMac) ;

    
        if(peerInfo)
        {
            /* 
             * send TDLS discovery response frame on direct link, state machine
             * is rolling.., once discovery response is get Acked, we will 
             * send response to SME based on TxComplete callback results
             */ 
            limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
            peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
        }
    } while(0) ;
#endif
add_sta_error:
    status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId, 
                                        pAddStaParams->staMac, pAddStaParams->updateSta, pStaDs, status) ;
    vos_mem_free( pAddStaParams );
    return status ;
}

void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac,
                             tpPESession psessionEntry,
                             tDot11fIESuppChannels *suppChannels,
                             tDot11fIESuppOperatingClasses *suppOperClasses)
{
    tANI_U32   numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
    tANI_U8    validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
    tANI_U8    i;
    if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
                          validChan, &numChans) != eSIR_SUCCESS)
    {
        /**
         * Could not get Valid channel list from CFG.
         * Log error.
         */
         limLog(pMac, LOGP,
                FL("could not retrieve Valid channel list"));
    }
    suppChannels->num_bands = (tANI_U8) numChans;

    for ( i = 0U; i < suppChannels->num_bands; i++)
    {
        suppChannels->bands[i][0] = validChan[i];
        suppChannels->bands[i][1] = 1;
    }
    suppChannels->present = 1 ;
    return ;
}


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

 
void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry, 
                                 tDot11fIELinkIdentifier *linkIden,
                                       tSirMacAddr peerMac, tANI_U8 reqType)
{
    //tANI_U32 size = sizeof(tSirMacAddr) ;
    tANI_U8 *initStaAddr = NULL ;
    tANI_U8 *respStaAddr = NULL ;

    (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
                                   (respStaAddr = linkIden->RespStaAddr))
                                : ((respStaAddr = linkIden->InitStaAddr ),
                                   (initStaAddr = linkIden->RespStaAddr)) ;
    vos_mem_copy( (tANI_U8 *)linkIden->bssid,
                     (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ; 

    vos_mem_copy( (tANI_U8 *)initStaAddr,
                          psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;

    vos_mem_copy( (tANI_U8 *)respStaAddr, (tANI_U8 *) peerMac,
                                                       sizeof( tSirMacAddr ));

    linkIden->present = 1 ;
    return ;

}

void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, 
                                        tDot11fIEExtCap *extCapability)
{
    extCapability->TDLSPeerPSMSupp = PEER_PSM_SUPPORT ;
    extCapability->TDLSPeerUAPSDBufferSTA = pMac->lim.gLimTDLSBufStaEnabled;
    extCapability->TDLSChannelSwitching = pMac->lim.gLimTDLSOffChannelEnabled ;
    extCapability->TDLSSupport = TDLS_SUPPORT ;
    extCapability->TDLSProhibited = TDLS_PROHIBITED ;
    extCapability->TDLSChanSwitProhibited = TDLS_CH_SWITCH_PROHIBITED ;
    extCapability->present = 1 ;
    return ;
}
                                     
#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
 * Public Action frame common processing
 * This Function will be moved/merged to appropriate place
 * once other public action frames (particularly 802.11k)
 * is in place
 */
void limProcessTdlsPublicActionFrame(tpAniSirGlobal pMac, tANI_U32 *pBd, 
                                                  tpPESession psessionEntry)
{
    tANI_U32 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
    tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd) ;
    tANI_S8 rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pBd) ;

    limProcessTdlsDisRspFrame(pMac, pBody, frameLen, rssi, psessionEntry) ;
    return ; 
}

eHalStatus limTdlsPrepareSetupReqFrame(tpAniSirGlobal pMac, 
                              tLimTdlsLinkSetupInfo *linkSetupInfo,
                                 tANI_U8 dialog, tSirMacAddr peerMac,
                                                 tpPESession psessionEntry)
{
    tLimTdlsLinkSetupPeer *setupPeer = NULL ;

    /*
    * we allocate the TDLS setup Peer Memory here, we will free'd this
    * memory after teardown, if the link is successfully setup or
    * free this memory if any timeout is happen in link setup procedure
    */

    setupPeer = vos_mem_malloc(sizeof( tLimTdlsLinkSetupPeer ));
    if ( NULL == setupPeer )
    {
        limLog( pMac, LOGP, 
                  FL( "Unable to allocate memory during ADD_STA" ));
         VOS_ASSERT(0) ;
         return eSIR_MEM_ALLOC_FAILED;
    }
    setupPeer->dialog = dialog ;
    setupPeer->tdls_prev_link_state =  setupPeer->tdls_link_state ;
    setupPeer->tdls_link_state = TDLS_LINK_SETUP_START_STATE ;

    /* TDLS_sessionize: remember sessionId for future */
    setupPeer->tdls_sessionId = psessionEntry->peSessionId;
    setupPeer->tdls_bIsResponder = 1;

    /* 
    * we only populate peer MAC, so it can assit us to find the
    * TDLS peer after response/or after response timeout
    */
    vos_mem_copy(setupPeer->peerMac, peerMac,
                                              sizeof(tSirMacAddr)) ;
    /* format TDLS discovery request frame and transmit it */
    limSendTdlsLinkSetupReqFrame(pMac, peerMac, dialog, psessionEntry, NULL, 0) ;

    limStartTdlsTimer(pMac, psessionEntry->peSessionId, 
                        &setupPeer->gLimTdlsLinkSetupRspTimeoutTimer,
                            (tANI_U32)setupPeer->peerMac, 
                               WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT,
                                 SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT) ;
    /* update setup peer list */
    setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
    linkSetupInfo->tdlsLinkSetupList = setupPeer ;

    /* in case of success, eWNI_SME_TDLS_LINK_START_RSP is sent back to 
     * SME later when TDLS setup cnf TX complete is successful. --> see 
     * limTdlsSetupCnfTxComplete() 
     */
    return eSIR_SUCCESS ; 
}
#endif

/*
 * Process Send Mgmt Request from SME and transmit to AP.
 */
tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac, 
                                                           tANI_U32 *pMsgBuf)
{
    /* get all discovery request parameters */
    tSirTdlsSendMgmtReq *pSendMgmtReq = (tSirTdlsSendMgmtReq*) pMsgBuf ;
    tpPESession psessionEntry;
    tANI_U8      sessionId;
    tSirResultCodes resultCode = eSIR_SME_INVALID_PARAMETERS;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
            ("Send Mgmt Recieved")) ;

    if((psessionEntry = peFindSessionByBssid(pMac, pSendMgmtReq->bssid, &sessionId)) 
            == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                "PE Session does not exist for given sme sessionId %d",
                pSendMgmtReq->sessionId);
        goto lim_tdls_send_mgmt_error;
    }

    /* check if we are in proper state to work as TDLS client */ 
    if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                "send mgmt received in wrong system Role %d",
                psessionEntry->limSystemRole);
        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 ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
            (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
    {

        limLog(pMac, LOGE, "send mgmt received in invalid LIMsme "
                "state (%d)", psessionEntry->limSmeState);
        goto lim_tdls_send_mgmt_error;
    }

    switch( pSendMgmtReq->reqType )
    {
        case SIR_MAC_TDLS_DIS_REQ:
            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                    "Transmit Discovery Request Frame") ;
            /* format TDLS discovery request frame and transmit it */
            limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, 
                    psessionEntry) ;
            resultCode = eSIR_SME_SUCCESS;
            break;
        case SIR_MAC_TDLS_DIS_RSP:
            {
                //Send a response mgmt action frame
                limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac,
                        pSendMgmtReq->dialog, psessionEntry) ;
                resultCode = eSIR_SME_SUCCESS;
            }
            break;
        case SIR_MAC_TDLS_SETUP_REQ:
            {
                limSendTdlsLinkSetupReqFrame(pMac,
                        pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry,
                        &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); 
                resultCode = eSIR_SME_SUCCESS;
            }
            break;
        case SIR_MAC_TDLS_SETUP_RSP:
            {
                limSendTdlsSetupRspFrame(pMac, 
                        pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode,
                        &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
                resultCode = eSIR_SME_SUCCESS;
            }
            break;
        case SIR_MAC_TDLS_SETUP_CNF:
            {
                limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, pSendMgmtReq->peerCapability,
                        psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));  
                resultCode = eSIR_SME_SUCCESS;
            }
            break;
        case SIR_MAC_TDLS_TEARDOWN:
            {
                limSendTdlsTeardownFrame(pMac,
                        pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, pSendMgmtReq->responder, psessionEntry,
                        &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); 
                resultCode = 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:

    limSendSmeRsp( pMac, eWNI_SME_TDLS_SEND_MGMT_RSP,
            resultCode, pSendMgmtReq->sessionId, pSendMgmtReq->transactionId);

    return eSIR_SUCCESS;
}

/*
 * Send Response to Link Establish Request to SME
 */
void limSendSmeTdlsLinkEstablishReqRsp(tpAniSirGlobal pMac,
                    tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode   *pStaDs,
                    tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;

    tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL ;

    pTdlsLinkEstablishReqRsp = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp));
    if ( NULL == pTdlsLinkEstablishReqRsp )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return ;
    }
    pTdlsLinkEstablishReqRsp->statusCode = status ;
    if ( peerMac )
    {
        vos_mem_copy(pTdlsLinkEstablishReqRsp->peerMac, peerMac, sizeof(tSirMacAddr));
    }
    pTdlsLinkEstablishReqRsp->sessionId = sessionId;
    mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP ;
    mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp;
    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return ;


}

/*
 * Once link is teardown, send Del Peer Ind to SME
 */
static eHalStatus limSendSmeTdlsDelStaRsp(tpAniSirGlobal pMac, 
                    tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode   *pStaDs,
                    tANI_U8 status)
{
    tSirMsgQ  mmhMsg = {0} ;
    tSirTdlsDelStaRsp *pDelSta = NULL ;
    mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP ;

    pDelSta = vos_mem_malloc(sizeof(tSirTdlsDelStaRsp));
    if ( NULL == pDelSta )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
            return eSIR_FAILURE;
    }

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

    if( peerMac )
    {
        vos_mem_copy(pDelSta->peerMac, peerMac, sizeof(tSirMacAddr));
    }

    pDelSta->length = sizeof(tSirTdlsDelStaRsp) ;
    pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP ;

    mmhMsg.bodyptr = pDelSta;

    mmhMsg.bodyval = 0;
    limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
    return eSIR_SUCCESS ;

}

/*
 * Process Send Mgmt Request from SME and transmit to AP.
 */
tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac, 
                                                           tANI_U32 *pMsgBuf)
{
    /* get all discovery request parameters */
    tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq*) pMsgBuf ;
    tpPESession psessionEntry;
    tANI_U8      sessionId;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
                                  ("Send Mgmt Recieved")) ;

    if((psessionEntry = peFindSessionByBssid(pMac, pAddStaReq->bssid, &sessionId)) 
                                                                        == NULL)
    {
         VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                    "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 (psessionEntry->limSystemRole != eLIM_STA_ROLE)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                         "send mgmt received in wrong system Role %d",
                                             psessionEntry->limSystemRole);
        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 ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
                (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
     {
     
         limLog(pMac, LOGE, "send mgmt received in invalid LIMsme "
                "state (%d)", psessionEntry->limSmeState);
         goto lim_tdls_add_sta_error;
     }

     pMac->lim.gLimAddStaTdls = true ;

     /* To start with, send add STA request to HAL */
     if (eSIR_FAILURE == limTdlsSetupAddSta(pMac, pAddStaReq, psessionEntry))
     {
         limLog(pMac, LOGE, "%s: Add TDLS Station request failed ", __func__);
         goto lim_tdls_add_sta_error;
     }
     return eSIR_SUCCESS;
lim_tdls_add_sta_error:
     limSendSmeTdlsAddStaRsp(pMac, 
                   pAddStaReq->sessionId, pAddStaReq->peerMac,
                   (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE), NULL, eSIR_FAILURE );

   return eSIR_SUCCESS;
}
/*
 * Process Del Sta Request from SME .
 */
tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, 
                                                           tANI_U32 *pMsgBuf)
{
    /* get all discovery request parameters */
    tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq*) pMsgBuf ;
    tpPESession psessionEntry;
    tANI_U8      sessionId;
    tpDphHashNode pStaDs = NULL ;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
            ("Send Mgmt Recieved")) ;

    if((psessionEntry = peFindSessionByBssid(pMac, pDelStaReq->bssid, &sessionId)) 
            == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                "PE Session does not exist for given sme sessionId %d",
                pDelStaReq->sessionId);
        limSendSmeTdlsDelStaRsp(pMac, pDelStaReq->sessionId, pDelStaReq->peerMac,
             NULL, eSIR_FAILURE) ;
        return eSIR_FAILURE;
    }

    /* check if we are in proper state to work as TDLS client */ 
    if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
                "Del sta received in wrong system Role %d",
                psessionEntry->limSystemRole);
        goto lim_tdls_del_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 ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
            (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
    {

        limLog(pMac, LOGE, "Del Sta received in invalid LIMsme state (%d)",
               psessionEntry->limSmeState);
        goto lim_tdls_del_sta_error;
    }

    pStaDs = limTdlsDelSta(pMac, pDelStaReq->peerMac, psessionEntry) ;

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

    if(pStaDs)
    {
        limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
                pStaDs, eSIR_SUCCESS) ;
        limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ;

        /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
        CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, pStaDs->assocId);
        limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ;

        return eSIR_SUCCESS;

    }

lim_tdls_del_sta_error:
     limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
             NULL, eSIR_FAILURE) ;

    return eSIR_SUCCESS;
}

/* Intersects the two input arrays and outputs an array */
/* For now the array length of tANI_U8 suffices */
static void limTdlsGetIntersection(tANI_U8 *input_array1,tANI_U8 input1_length,
                            tANI_U8 *input_array2,tANI_U8 input2_length,
                            tANI_U8 *output_array,tANI_U8 *output_length)
{
    tANI_U8 i,j,k=0,flag=0;
    for(i=0;i<input1_length;i++)
    {
        flag=0;
        for(j=0;j<input2_length;j++)
        {
            if(input_array1[i]==input_array2[j])
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
        {
            output_array[k]=input_array1[i];
            k++;
        }
    }
    *output_length = k;
}
/*
 * Process Link Establishment Request from SME .
 */
tSirRetStatus limProcesSmeTdlsLinkEstablishReq(tpAniSirGlobal pMac,
                                                           tANI_U32 *pMsgBuf)
{
    /* get all discovery request parameters */
    tSirTdlsLinkEstablishReq *pTdlsLinkEstablishReq = (tSirTdlsLinkEstablishReq*) pMsgBuf ;
    tpPESession psessionEntry;
    tANI_U8      sessionId;
    tpTdlsLinkEstablishParams pMsgTdlsLinkEstablishReq;
    tSirMsgQ msg;
    tANI_U16 peerIdx = 0 ;
    tpDphHashNode pStaDs = NULL ;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
            ("Send Mgmt Recieved")) ;

    if((psessionEntry = peFindSessionByBssid(pMac, pTdlsLinkEstablishReq->bssid, &sessionId))
            == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                "PE Session does not exist for given sme sessionId %d",
                pTdlsLinkEstablishReq->sessionId);
        limSendSmeTdlsLinkEstablishReqRsp(pMac, pTdlsLinkEstablishReq->sessionId, pTdlsLinkEstablishReq->peerMac,
             NULL, eSIR_FAILURE) ;
        return eSIR_FAILURE;
    }

    /* check if we are in proper state to work as TDLS client */
    if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                "TDLS Link Establish Request received in wrong system Role %d",
                psessionEntry->limSystemRole);
        goto lim_tdls_link_establish_error;
    }

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

        limLog(pMac, LOGE, "TDLS Link Establish Request received in "
               "invalid LIMsme state (%d)", psessionEntry->limSmeState);
        goto lim_tdls_link_establish_error;
    }
    /*TODO Sunil , TDLSPeer Entry has the STA ID , Use it */
    pStaDs = dphLookupHashEntry(pMac, pTdlsLinkEstablishReq->peerMac, &peerIdx,
                                &psessionEntry->dph.dphHashTable) ;
    if ( NULL == pStaDs )
    {
        limLog( pMac, LOGE, FL( "pStaDs is NULL" ));
        goto lim_tdls_link_establish_error;

    }
    pMsgTdlsLinkEstablishReq = vos_mem_malloc(sizeof( tTdlsLinkEstablishParams ));
    if ( NULL == pMsgTdlsLinkEstablishReq )
    {
        limLog( pMac, LOGE,
                     FL( "Unable to allocate memory TDLS Link Establish Request" ));
        return eSIR_MEM_ALLOC_FAILED;
    }

    vos_mem_set( (tANI_U8 *)pMsgTdlsLinkEstablishReq, sizeof(tpTdlsLinkEstablishParams), 0);

    pMsgTdlsLinkEstablishReq->staIdx = pStaDs->staIndex;
    pMsgTdlsLinkEstablishReq->isResponder = pTdlsLinkEstablishReq->isResponder;
    pMsgTdlsLinkEstablishReq->uapsdQueues = pTdlsLinkEstablishReq->uapsdQueues;
    pMsgTdlsLinkEstablishReq->maxSp = pTdlsLinkEstablishReq->maxSp;
    pMsgTdlsLinkEstablishReq->isBufsta = pTdlsLinkEstablishReq->isBufSta;
    pMsgTdlsLinkEstablishReq->isOffChannelSupported =
                                pTdlsLinkEstablishReq->isOffChannelSupported;
    pMsgTdlsLinkEstablishReq->isOffChannelSupported = 1;

    if ( 0 != pTdlsLinkEstablishReq->supportedChannelsLen)
    {
        tANI_U32   selfNumChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
        tANI_U8    selfSupportedChannels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
        if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST,
                          selfSupportedChannels, &selfNumChans) != eSIR_SUCCESS)
        {
            /**
             * Could not get Valid channel list from CFG.
             * Log error.
             */
             limLog(pMac, LOGP,
                    FL("could not retrieve Valid channel list"));
        }
        limTdlsGetIntersection(selfSupportedChannels, selfNumChans,
                               pTdlsLinkEstablishReq->supportedChannels,
                               pTdlsLinkEstablishReq->supportedChannelsLen,
                               pMsgTdlsLinkEstablishReq->validChannels,
                               &pMsgTdlsLinkEstablishReq->validChannelsLen);
    }
    vos_mem_copy(pMsgTdlsLinkEstablishReq->validOperClasses,
                        pTdlsLinkEstablishReq->supportedOperClasses, pTdlsLinkEstablishReq->supportedOperClassesLen);
    pMsgTdlsLinkEstablishReq->validOperClassesLen =
                                pTdlsLinkEstablishReq->supportedOperClassesLen;

    msg.type = WDA_SET_TDLS_LINK_ESTABLISH_REQ;
    msg.reserved = 0;
    msg.bodyptr = pMsgTdlsLinkEstablishReq;
    msg.bodyval = 0;
    if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
    {
        limLog(pMac, LOGE, FL("halPostMsgApi failed"));
        goto lim_tdls_link_establish_error;
    }
    return eSIR_SUCCESS;
lim_tdls_link_establish_error:
     limSendSmeTdlsLinkEstablishReqRsp(pMac, psessionEntry->smeSessionId, pTdlsLinkEstablishReq->peerMac,
                                       NULL, eSIR_FAILURE) ;

    return eSIR_SUCCESS;
}


/* Delete all the TDLS peer connected before leaving the BSS */
tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
    tpDphHashNode pStaDs = NULL ;
    int i, aid;

    if (NULL == psessionEntry)
    {
        PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));)
        return eSIR_FAILURE;
    }

    /* 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 */
    for (i = 0; i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); i++)
    {
        for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++)
        {
            if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid))
            {
                pStaDs = dphGetHashEntry(pMac, (aid + i*(sizeof(tANI_U32) << 3)), &psessionEntry->dph.dphHashTable);

                if (NULL != pStaDs)
                {
                    PELOGE(limLog(pMac, LOGE, FL("Deleting "MAC_ADDRESS_STR),
                           MAC_ADDR_ARRAY(pStaDs->staAddr)););

                    limSendDeauthMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                                           pStaDs->staAddr, psessionEntry, FALSE);
                    dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable);
                }
                limReleasePeerIdx(pMac, (aid + i*(sizeof(tANI_U32) << 3)), psessionEntry) ;
                CLEAR_BIT(psessionEntry->peerAIDBitmap[i], aid);
            }
        }
    }
    limSendSmeTDLSDeleteAllPeerInd(pMac, psessionEntry);

    return eSIR_SUCCESS;
}
#endif
