/*
 * 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);
/*only 31 op classes are available, 1 entry for current op class*/
static tDot11fIESuppOperatingClasses op_classes = {0};

op_class_map_t global_op_class[] = {
    {81, 25,  BW20,      {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
    {82, 25,  BW20,      {14}},
    {83, 40,  BW40PLUS,  {1, 2, 3, 4, 5, 6, 7, 8, 9}},
    {84, 40,  BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
    {115, 20, BW20,      {36, 40, 44, 48}},
    {116, 40, BW40PLUS,  {36, 44}},
    {117, 40, BW40MINUS, {40, 48}},
    {118, 20, BW20,      {52, 56, 60, 64}},
    {119, 40, BW40PLUS,  {52, 60}},
    {120, 40, BW40MINUS, {56, 64}},
    {121, 20, BW20,   {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
    {122, 40, BW40PLUS,  {100, 108, 116, 124, 132}},
    {123, 40, BW40MINUS, {104, 112, 120, 128, 136}},
    {125, 20, BW20,      {149, 153, 157, 161, 165, 169}},
    {126, 40, BW40PLUS,  {149, 157}},
    {127, 40, BW40MINUS, {153, 161}},
    {0, 0, 0, {0}},

};/*end global_op_class*/

op_class_map_t us_op_class[] = {
    {1, 20,  BW20,       {36, 40, 44, 48}},
    {2, 20,  BW20,       {52, 56, 60, 64}},
    {4, 20,  BW20,   {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
    {5, 20,  BW20,       {149, 153, 157, 161, 165}},
    {22, 40, BW40PLUS,  {36, 44}},
    {23, 40, BW40PLUS,  {52, 60}},
    {24, 40, BW40PLUS,  {100, 108, 116, 124, 132}},
    {26, 40, BW40PLUS,  {149, 157}},
    {27, 40, BW40MINUS, {40, 48}},
    {28, 40, BW40MINUS, {56, 64}},
    {29, 40, BW40MINUS, {104, 112, 120, 128, 136}},
    {31, 40, BW40MINUS, {153, 161}},
    {32, 40, BW40PLUS,  {1, 2, 3, 4, 5, 6, 7}},
    {33, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11}},
    {0, 0, 0, {0}},
};/*end us_op_class*/

op_class_map_t euro_op_class[] = {
    {1, 20,  BW20,      {36, 40, 44, 48}},
    {2, 20,  BW20,      {52, 56, 60, 64}},
    {3, 20,  BW20,   {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
    {4, 25,  BW20,      {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
    {5, 40,  BW40PLUS,  {36, 44}},
    {6, 40,  BW40PLUS,  {52, 60}},
    {7, 40,  BW40PLUS,  {100, 108, 116, 124, 132}},
    {8, 40,  BW40MINUS, {40, 48}},
    {9, 40,  BW40MINUS, {56, 64}},
    {10, 40, BW40MINUS, {104, 112, 120, 128, 136}},
    {11, 40, BW40PLUS,  {1, 2, 3, 4, 5, 6, 7, 8, 9}},
    {12, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}},
    {17, 20, BW20,      {149, 153, 157, 161, 165, 169}},
    {0, 0, 0, {0}},
};/*end euro_op_class*/

op_class_map_t japan_op_class[] = {
    {1, 20,  BW20,      {36, 40, 44, 48}},
    {30, 25, BW20,      {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}},
    {31, 25, BW20,      {14}},
    {32, 20, BW20,      {52, 56, 60, 64}},
    {34, 20, BW20,   {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}},
    {36, 40, BW40PLUS,  {36, 44}},
    {37, 40, BW40PLUS,  {52, 60}},
    {39, 40, BW40PLUS,  {100, 108, 116, 124, 132}},
    {41, 40, BW40MINUS, {40, 48}},
    {42, 40, BW40MINUS, {56, 64}},
    {44, 40, BW40MINUS, {104, 112, 120, 128, 136}},
    {0, 0, 0, {0}},
};/*end japan_op_class*/

/*
 * 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, eSIR_FALSE );
        }
        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, tANI_U8 *addIe,
                     tANI_U16 addIeLen)
{
    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 RSN Information element */
    PopulateDot11fRsnIEs(pMac, &tdlsDisRsp.RSN, addIe, addIeLen);

    /* Populate Timeout interval IE */
    PopulateDot11fTimeoutIEs(pMac, &tdlsDisRsp.TimeoutInterval,
                             (&addIe[22]), (addIeLen - 22));

    /* 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, NULL, 0);
            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, NULL, 0);
            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;
    tANI_U8    op_class;
    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 ;
    /*Get present operating class based on current operating channel*/
    op_class = limGetOPClassFromChannel(
                                     pMac->scan.countryCodeCurrent,
                                     psessionEntry->currentOperChannel,
                                     psessionEntry->htSecondaryChannelOffset);
    if (op_class == 0)
    {
        PELOGE(limLog(pMac, LOGE, FL("Present Operating class is Wrong!!!"));)
    }
    else
    {
        PELOGE(limLog(pMac, LOG1, FL("Present Operating channel=%d offset=%d class=%d"),
                      psessionEntry->currentOperChannel,
                      psessionEntry->htSecondaryChannelOffset,
                      op_class);)
    }
    suppOperClasses->present = 1;
    suppOperClasses->classes[0] = op_class;
    /*Fill operating classes from static array*/
    suppOperClasses->num_classes = op_classes.num_classes;
    for ( i = 0U; i < suppOperClasses->num_classes; i++)
    {
        suppOperClasses->classes[i+1] = op_classes.classes[i];

    }
    /*increment for present operating class*/
    suppOperClasses->num_classes++;
    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,
                        &pSendMgmtReq->addIe[0],
                        (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
                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 ;


}

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

    tSirTdlsChanSwitchReqRsp *pTdlsChanSwitchReqRsp = NULL ;

    pTdlsChanSwitchReqRsp = vos_mem_malloc(sizeof(tSirTdlsChanSwitchReqRsp));
    if ( NULL == pTdlsChanSwitchReqRsp )
    {
        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
        return ;
    }
    pTdlsChanSwitchReqRsp->statusCode = status ;
    if ( peerMac )
    {
        vos_mem_copy(pTdlsChanSwitchReqRsp->peerMac, peerMac, sizeof(tSirMacAddr));
    }
    pTdlsChanSwitchReqRsp->sessionId = sessionId;
    mmhMsg.type = eWNI_SME_TDLS_CHANNEL_SWITCH_RSP ;
    mmhMsg.bodyptr = pTdlsChanSwitchReqRsp;
    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;

    if (input1_length > WNI_CFG_VALID_CHANNEL_LIST_LEN)
    {
       input1_length = WNI_CFG_VALID_CHANNEL_LIST_LEN;
    }

    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(tTdlsLinkEstablishParams), 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 ((pTdlsLinkEstablishReq->supportedChannelsLen > 0) &&
        (pTdlsLinkEstablishReq->supportedChannelsLen <= SIR_MAC_MAX_SUPP_CHANNELS))
    {
        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;
}


tANI_U8 limGetOPClassFromChannel(tANI_U8 *country,
                                         tANI_U8 channel,
                                         tANI_U8 offset)
{
    op_class_map_t *class = NULL;
    tANI_U16 i = 0;

    if (VOS_TRUE == vos_mem_compare(country,"US", 2))  {

        class = us_op_class;

    } else if (VOS_TRUE == vos_mem_compare(country,"EU", 2)) {

        class = euro_op_class;

    } else if (VOS_TRUE == vos_mem_compare(country,"JP", 2)) {

        class = japan_op_class;

    } else {

        class = global_op_class;

    }

    while (class->op_class)
    {
        if ((offset == class->offset) || (offset == BWALL))
        {
            for (i=0; (i < 15 && class->channels[i]); i++)
            {
                if (channel == class->channels[i])
                    return class->op_class;
            }
        }
        class++;
    }
    return 0;
}

tANI_BOOLEAN  CheckAndAddOP(tANI_U8 class)
{
    tANI_U8 i;

    for (i=0; i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); i++)
    {
        /*0 is an invalid class. If class is already present ignore*/
        if (class == op_classes.classes[i])
            return FALSE;
        if(op_classes.classes[i] == 0)
        {
            return TRUE;
        }
    }
    //limLog(pMac, LOGE, FL("No space left for class = %d"), class);
    return FALSE;
}

void limInitOperatingClasses( tHalHandle hHal )
{

    tANI_U8 Index = 0;
    tANI_U8 class = 0;
    tANI_U8 i = 0;
    tANI_U8 j = 0;
    tANI_U8 swap = 0;
    tANI_U8 numChannels = 0;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    limLog(pMac, LOG1, FL("Current Country = %c%c"),
                          pMac->scan.countryCodeCurrent[0],
                          pMac->scan.countryCodeCurrent[1]);

    vos_mem_set(op_classes.classes, sizeof(op_classes.classes), 0);
    numChannels = pMac->scan.baseChannels.numChannels;
    limLog(pMac, LOG1, "Num of base ch =%d", numChannels);
    for ( Index = 0;
          Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1);
          Index++)
    {
        class = limGetOPClassFromChannel(
                            pMac->scan.countryCodeCurrent,
                            pMac->scan.baseChannels.channelList[ Index ],
                            BWALL);
        limLog(pMac, LOG4, "ch=%d <=> %d=class",
               pMac->scan.baseChannels.channelList[ Index ],
               class);
        if (CheckAndAddOP(class))
        {
            op_classes.classes[i]= class;
            i++;
        }
    }

    numChannels = pMac->scan.base20MHzChannels.numChannels;
    limLog(pMac, LOG1, "Num of 20MHz ch =%d", numChannels);
    for ( Index = 0;
          Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1);
          Index++)
    {
        class = limGetOPClassFromChannel(
                            pMac->scan.countryCodeCurrent,
                            pMac->scan.base20MHzChannels.channelList[ Index ],
                            BWALL);
        limLog(pMac, LOG4, "ch=%d <=> %d=class",
               pMac->scan.base20MHzChannels.channelList[ Index ],
               class);
        if (CheckAndAddOP(class))
        {
            op_classes.classes[i]= class;
            i++;
        }
    }

    numChannels = pMac->scan.base40MHzChannels.numChannels;
    limLog(pMac, LOG1, "Num of 40MHz ch =%d", numChannels);
    for ( Index = 0;
          Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1);
          Index++)
    {
        class = limGetOPClassFromChannel(
                            pMac->scan.countryCodeCurrent,
                            pMac->scan.base40MHzChannels.channelList[ Index ],
                            BWALL);
        limLog(pMac, LOG4, "ch=%d <=> %d=class",
               pMac->scan.base40MHzChannels.channelList[ Index ],
               class);
        if (CheckAndAddOP(class))
        {
            op_classes.classes[i]= class;
            i++;
        }
    }

    op_classes.num_classes = i;
    limLog(pMac, LOG1, "Total number of Unique supported classes =%d",
           op_classes.num_classes);
    /*as per spec the operating classes should be in ascending order*/
    /*Bubble sort is fine as we don't have many classes*/
    for (i = 0 ; i < ( op_classes.num_classes - 1 ); i++)
    {
        for (j = 0 ; j < op_classes.num_classes - i - 1; j++)
        {
            /* For decreasing order use < */
            if (op_classes.classes[j] > op_classes.classes[j+1])
            {
                swap = op_classes.classes[j];
                op_classes.classes[j] = op_classes.classes[j+1];
                op_classes.classes[j+1] = swap;
            }
        }
    }
    for (i=0; i < op_classes.num_classes; i++)
    {

        limLog(pMac, LOG1, "supported op_class[%d]=%d", i,
               op_classes.classes[i]);

    }
}

#endif
// tdlsoffchan
/*
 * Process Channel Switch from SME.
 */
tSirRetStatus limProcesSmeTdlsChanSwitchReq(tpAniSirGlobal pMac,
                                            tANI_U32 *pMsgBuf)
{
    /* get all discovery request parameters */
    tSirTdlsChanSwitch *pTdlsChanSwitch = (tSirTdlsChanSwitch*) pMsgBuf ;
    tpPESession            psessionEntry;
    tANI_U8                sessionId;
    tpTdlsChanSwitchParams pMsgTdlsChanSwitch;
    tSirMsgQ               msg;
    tANI_U16               peerIdx = 0;
    tpDphHashNode          pStaDs = NULL;

    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
             ("TDLS Channel Switch Recieved on peer:" MAC_ADDRESS_STR),
              MAC_ADDR_ARRAY(pTdlsChanSwitch->peerMac));

    psessionEntry = peFindSessionByBssid(pMac,
                                         pTdlsChanSwitch->bssid,
                                         &sessionId);
    if (psessionEntry == NULL)
    {
        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                  "PE Session does not exist for given sme sessionId %d",
                  pTdlsChanSwitch->sessionId);
        limSendSmeTdlsChanSwitchReqRsp(pMac, pTdlsChanSwitch->sessionId,
                                       pTdlsChanSwitch->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 Channel Switch received in wrong system Role %d",
                  psessionEntry->limSystemRole);
        goto lim_tdls_chan_switch_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 Channel Switch received in invalid LIMsme state (%d)",
               psessionEntry->limSmeState);
        goto lim_tdls_chan_switch_error;
    }

    pStaDs = dphLookupHashEntry(pMac, pTdlsChanSwitch->peerMac, &peerIdx,
                                &psessionEntry->dph.dphHashTable) ;
    if ( NULL == pStaDs )
    {
        limLog( pMac, LOGE, FL( "pStaDs is NULL" ));
        goto lim_tdls_chan_switch_error;

    }
    pMsgTdlsChanSwitch = vos_mem_malloc(sizeof( tTdlsChanSwitchParams ));
    if ( NULL == pMsgTdlsChanSwitch )
    {
        limLog( pMac, LOGE,
                     FL( "Unable to allocate memory TDLS Channel Switch" ));
        return eSIR_MEM_ALLOC_FAILED;
    }

    vos_mem_set( (tANI_U8 *)pMsgTdlsChanSwitch, sizeof(tpTdlsChanSwitchParams), 0);

    pMsgTdlsChanSwitch->staIdx = pStaDs->staIndex;
    pMsgTdlsChanSwitch->tdlsOffCh = pTdlsChanSwitch->tdlsOffCh;
    pMsgTdlsChanSwitch->tdlsOffChBwOffset = pTdlsChanSwitch->tdlsOffChBwOffset;
    pMsgTdlsChanSwitch->tdlsSwMode = pTdlsChanSwitch->tdlsSwMode;
    pMsgTdlsChanSwitch->operClass = limGetOPClassFromChannel(
                                           pMac->scan.countryCodeCurrent,
                                           pTdlsChanSwitch->tdlsOffCh,
                                           pTdlsChanSwitch->tdlsOffChBwOffset);
    if(pMsgTdlsChanSwitch->operClass == 0)
    {

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
                                   "Invalid Operating class 0 !!!");
        goto lim_tdls_chan_switch_error;
    }
    else
    {

        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
              "%s: TDLS Channel Switch params: staIdx %d class %d ch %d bw %d mode %d",
               __func__,
               pMsgTdlsChanSwitch->staIdx,
               pMsgTdlsChanSwitch->operClass,
               pMsgTdlsChanSwitch->tdlsOffCh,
               pMsgTdlsChanSwitch->tdlsOffChBwOffset,
               pMsgTdlsChanSwitch->tdlsSwMode);
    }

    msg.type = WDA_SET_TDLS_CHAN_SWITCH_REQ;
    msg.reserved = 0;
    msg.bodyptr = pMsgTdlsChanSwitch;
    msg.bodyval = 0;
    if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
    {
        limLog(pMac, LOGE, FL("halPostMsgApi failed\n"));
        goto lim_tdls_chan_switch_error;
    }

    return eSIR_SUCCESS;

lim_tdls_chan_switch_error:
    limSendSmeTdlsChanSwitchReqRsp(pMac, pTdlsChanSwitch->sessionId,
                                   pTdlsChanSwitch->peerMac,
                                   NULL, eSIR_FAILURE);
    return eSIR_FAILURE;
}

