wlan: Add QCA copyright information in Tdls files newly added.

Update TDLS files with QCA copyright information.

Change-Id: I6c3f5eb31af192f439a9141626c43e64d2af02da
CR-Fixed: 426223
diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c
new file mode 100644
index 0000000..cc2865f
--- /dev/null
+++ b/CORE/MAC/src/pe/lim/limProcessTdls.c
@@ -0,0 +1,4581 @@
+/*
+* Copyright (c) 2012 Qualcomm Atheros, Inc.
+* All Rights Reserved.
+* Qualcomm Atheros Confidential and Proprietary.
+*/
+
+/*===========================================================================
+
+                      limProcessTdls.c 
+
+  OVERVIEW:
+
+  DEPENDENCIES:
+
+  Are listed for each API below.
+
+
+  Copyright (c) 2010 QUALCOMM Incorporated.
+  All Rights Reserved.
+  Qualcomm Confidential and Proprietary
+===========================================================================*/
+
+/*===========================================================================
+
+                      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"
+
+
+#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, tSirMacAddr, 
+             tLimTdlsLinkSetupPeer *setupPeer, tpPESession psessionEntry) ;
+void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
+                          tDot11fIELinkIdentifier *linkIden, 
+                             tSirMacAddr peerMac , tANI_U8 reqType) ;
+void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, 
+                                    tDot11fIEExtCap *extCapability) ;
+/*
+ * 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 ;
+
+/* 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   (1)
+#define CH_SWITCH_SUPPORT         (0)
+#define TDLS_SUPPORT              (1)
+#define TDLS_PROHIBITED           (0)
+#define TDLS_CH_SWITCH_PROHIBITED (1)
+
+#ifdef LIM_DEBUG_TDLS
+#define TDLS_CASE_RETURN_STRING(x) case (x): return( ((const tANI_U8*)#x) + 8);  /* 8 = remove redundant SIR_MAC_ */
+
+#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
+
+const tANI_U8* limTraceTdlsActionString( tANI_U8 tdlsActionCode )
+{
+   switch( tdlsActionCode )
+   {
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
+       TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
+       TDLS_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, ("\n"));
+    return ;
+}
+#endif
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
+/*
+ * initialize TDLS setup list and related data structures.
+ */
+void limInitTdlsData(tpAniSirGlobal pMac, tpPESession sessionEntry)
+{
+    pMac->lim.gLimTdlsDisResultList = NULL ;
+    pMac->lim.gLimTdlsDisStaCount = 0 ;
+    palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsDisReq, 
+                                            sizeof(tSirTdlsDisReq));
+    palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsLinkSetupInfo, 
+                                            sizeof(tLimTdlsLinkSetupInfo));
+    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
+    limInitAIDpool(pMac, sessionEntry) ;
+
+    return ;
+}
+#endif
+#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\n"), \
+        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 ;
+
+     
+    palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, peerMac,
+                                                    sizeof( tSirMacAddr ));
+    palCopyMemory( pMac->hHdd,
+                   (tANI_U8 *) pMacHdr->sa,
+                   staMac, sizeof( tSirMacAddr ));
+
+    palCopyMemory( pMac->hHdd, (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\n"), \
+       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, tpPESession psessionEntry )
+{
+    tpSirMacMgmtHdr 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 = (tpSirMacMgmtHdr) (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 = 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;
+
+     
+    palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, (tANI_U8 *)addr1,
+                                                    sizeof( tSirMacAddr ));
+    palCopyMemory( pMac->hHdd,
+                   (tANI_U8 *) pMacHdr->sa,
+                   (tANI_U8 *) staMac,
+                   sizeof( tSirMacAddr ));
+
+    palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->bssId,
+                                (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\n"), \
+       (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "TD", \
+        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]));
+
+    //printMacAddr(pMacHdr->bssId) ;
+    //printMacAddr(pMacHdr->sa) ;
+    //printMacAddr(pMacHdr->da) ;
+ 
+    header_offset += sizeof(tSirMacMgmtHdr) ;
+    /* 
+     * Now form RFC1042 header
+     */
+    palCopyMemory(pMac->hHdd, (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) ; 
+}
+
+/*
+ * 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;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisReq, 
+                                      sizeof( tDot11fTDLSDisReq ) );
+
+    /*
+     * 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).\n"), 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).\n"), 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 ;
+
+    /* 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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, 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 %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Req\n"), \
+        tdlsDisReq.LinkIdentifier.bssid[0], 
+        tdlsDisReq.LinkIdentifier.bssid[1], 
+        tdlsDisReq.LinkIdentifier.bssid[2], 
+        tdlsDisReq.LinkIdentifier.bssid[3], 
+        tdlsDisReq.LinkIdentifier.bssid[4], 
+        tdlsDisReq.LinkIdentifier.bssid[5]);
+    }
+#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).\n"), 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).\n") );
+    }
+
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+            SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) ));
+
+    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+                            HAL_TXRX_FRM_802_11_DATA,
+                            ANI_TXDIR_TODS,
+                            7,
+                            limTxComplete, pFrame, 0 );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+
+    return eSIR_SUCCESS;
+
+}
+
+/*
+ * 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 ;
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
+    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\n"));
+        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\n"), 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 %02x:%02x:%02x:%02x:%02x:%02x\n"),
+                           (peerInfo)->peerMac[0],    
+                           (peerInfo)->peerMac[1],    
+                           (peerInfo)->peerMac[2],    
+                           (peerInfo)->peerMac[3],    
+                           (peerInfo)->peerMac[4],    
+                           (peerInfo)->peerMac[5]) ;
+            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 ;
+#endif 
+    return status ;
+
+}
+/*
+ * 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 ;
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
+    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\n"));
+        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 = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                           (peerInfo)->peerMac[0],    
+                           (peerInfo)->peerMac[1],    
+                           (peerInfo)->peerMac[2],    
+                           (peerInfo)->peerMac[3],    
+                           (peerInfo)->peerMac[4],    
+                           (peerInfo)->peerMac[5]) ;
+    
+        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 ;
+#endif 
+    return status ;
+
+}
+
+/*
+ * Tx Complete for Teardown frame
+ */
+eHalStatus limTdlsTeardownTxComplete(tpAniSirGlobal pMac,
+                                           tANI_U32 txCompleteSuccess)  
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS ;
+#ifdef FEATURE_WLAN_TDLS_INTERNAL
+    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\n"));
+        VOS_ASSERT(0) ;
+        return eHAL_STATUS_FAILURE;
+    }
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                  ("teardown peer Mac = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                             (peerInfo)->peerMac[0] ,             
+                             (peerInfo)->peerMac[1] ,             
+                             (peerInfo)->peerMac[2] ,             
+                             (peerInfo)->peerMac[3] ,             
+                             (peerInfo)->peerMac[4] ,             
+                             (peerInfo)->peerMac[5] ) ;           
+             
+
+    //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\n"), (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  \n")) ;
+
+        /* 
+         * 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\n")) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                      ("Prev State = %d\n"), (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 ;
+#endif
+    return status ;
+}
+
+/*
+ * Send TDLS discovery response frame on direct link.
+ */
+
+static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac, 
+                     tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry)
+{
+    tDot11fTDLSDisRsp   tdlsDisRsp ;
+    tANI_U16            caps = 0 ;            
+    tANI_U32            status = 0 ;
+    tANI_U32            nPayload = 0 ;
+    tANI_U32            nBytes = 0 ;
+    tANI_U8            *pFrame;
+    void               *pPacket;
+    eHalStatus          halstatus;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisRsp, 
+                                      sizeof( tDot11fTDLSDisRsp ) );
+
+    /*
+     * 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\n"));
+    }
+    swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities );
+
+    /* populate supported rate IE */
+    PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, 
+                                     &tdlsDisRsp.SuppRates, psessionEntry );
+   
+    /* Populate extended supported rates */
+    PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+                                &tdlsDisRsp.ExtSuppRates, psessionEntry );
+
+    /* Populate extended supported rates */
+    PopulateDot11fTdlsExtCapability( pMac, &tdlsDisRsp.ExtCap );
+
+    /* Include HT Capability IE */
+    //This does not depend on peer capabilities. If it is supported then it should be included
+    PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsDisRsp.HTCaps );
+
+    /* 
+     * 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).\n"), 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).\n"), 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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 %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Rsp\n"), \
+        tdlsDisRsp.LinkIdentifier.bssid[0], 
+        tdlsDisRsp.LinkIdentifier.bssid[1], 
+        tdlsDisRsp.LinkIdentifier.bssid[2], 
+        tdlsDisRsp.LinkIdentifier.bssid[3], 
+        tdlsDisRsp.LinkIdentifier.bssid[4], 
+        tdlsDisRsp.LinkIdentifier.bssid[5]);
+    }
+#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).\n"), 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).\n") );
+    }
+
+#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\n")) ;
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+            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, 
+                            limTdlsDisRspTxComplete,
+                            HAL_USE_SELF_STA_REQUESTED_MASK );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+
+    return eSIR_SUCCESS;
+
+}
+
+/*
+ * 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;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupReq, 
+                                      sizeof( tDot11fTDLSSetupReq ) );
+    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\n"));
+    }
+    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 );
+
+   /* 
+     * 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 = 0;
+    tdlsSetupReq.QOSCapsStation.acbk_uapsd = 0;
+    tdlsSetupReq.QOSCapsStation.acvi_uapsd = 0;
+    tdlsSetupReq.QOSCapsStation.acvo_uapsd = 0;
+    
+
+    /*
+     * 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
+     */
+
+    /* Include HT Capability IE */
+    PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsSetupReq.HTCaps );
+
+    /* 
+     * 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).\n"), 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).\n"), 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
+                        + 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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, 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 %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Req\n"), \
+        tdlsSetupReq.LinkIdentifier.bssid[0], 
+        tdlsSetupReq.LinkIdentifier.bssid[1], 
+        tdlsSetupReq.LinkIdentifier.bssid[2], 
+        tdlsSetupReq.LinkIdentifier.bssid[3], 
+        tdlsSetupReq.LinkIdentifier.bssid[4], 
+        tdlsSetupReq.LinkIdentifier.bssid[5]);
+    }
+#endif
+    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).\n"), 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).\n") );
+    }
+
+    //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 ));
+       palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen ); 
+    }
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+            SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) ));
+
+    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+                            HAL_TXRX_FRM_802_11_DATA,
+                            ANI_TXDIR_TODS,
+                            7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
+                            limTxComplete, pFrame, 0 );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+
+    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, 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;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&teardown, 
+                                      sizeof( tDot11fTDLSTeardown ) );
+    teardown.Category.category = SIR_MAC_ACTION_TDLS ;
+    teardown.Action.action     = SIR_MAC_TDLS_TEARDOWN ;
+    teardown.Reason.code       = reason ;
+
+    PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier, 
+                                                peerMac, 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).\n"), 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).\n"), 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
+                        + 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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, TDLS_INITIATOR,
+                              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).\n"), 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).\n") );
+    }
+#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 ));
+       palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen ); 
+    }
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+         SIR_MAC_TDLS_TEARDOWN, limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN) ));
+
+    halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
+                            HAL_TXRX_FRM_802_11_DATA,
+                            ANI_TXDIR_TODS,
+                            7,
+                            limTxComplete, pFrame, 
+                            limTdlsTeardownTxComplete,
+                            0 );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+    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;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupRsp, 
+                                      sizeof( tDot11fTDLSSetupRsp ) );
+
+    /*
+     * 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\n"));
+    }
+    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 );
+
+    /* 
+     * 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 = 1;
+    tdlsSetupRsp.QOSCapsStation.acbk_uapsd = 1;
+    tdlsSetupRsp.QOSCapsStation.acvi_uapsd = 1;
+    tdlsSetupRsp.QOSCapsStation.acvo_uapsd = 1;
+
+    /* Include HT Info IE */
+//    if ( setupReq->HTCaps.present)
+//    {
+        PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsSetupRsp.HTCaps );
+//    }
+
+    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).\n"), 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).\n"), 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
+                        + 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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,
+                                       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 %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Rsp\n"), \
+        tdlsSetupRsp.LinkIdentifier.bssid[0], 
+        tdlsSetupRsp.LinkIdentifier.bssid[1], 
+        tdlsSetupRsp.LinkIdentifier.bssid[2], 
+        tdlsSetupRsp.LinkIdentifier.bssid[3], 
+        tdlsSetupRsp.LinkIdentifier.bssid[4], 
+        tdlsSetupRsp.LinkIdentifier.bssid[5]);
+    }
+#endif
+    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).\n"), 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).\n") );
+    }
+
+    //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 )
+    {
+       palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen ); 
+    }
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+         SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) ));
+
+    halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
+                            HAL_TXRX_FRM_802_11_DATA,
+                            ANI_TXDIR_TODS,
+                            //ANI_TXDIR_IBSS,
+                            7,
+                            limTxComplete, pFrame, 0 );
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+
+    return eSIR_SUCCESS;
+
+}
+
+/*
+ * Send TDLS setup CNF frame on AP link
+ */
+
+tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, tSirMacAddr peerMac,
+                    tANI_U8 dialog, 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;
+
+    /* 
+     * 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:
+     */
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupCnf, 
+                                      sizeof( tDot11fTDLSSetupCnf ) );
+
+    /*
+     * 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
+    palCopyMemory( pMac->hHdd, (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.
+     */
+
+    /* Include HT Info IE */
+    //if ( tdlsSetupCnf.HTCaps.present)
+    //{
+    //    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).\n"), 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).\n"), 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
+                        + 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.\n"), nBytes );
+        return eSIR_MEM_ALLOC_FAILED;
+    }
+
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, nBytes );
+
+    /* 
+     * 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,
+                     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\n"));
+    }
+#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).\n"), 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).\n") );
+    }
+#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 )
+    {
+       palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen ); 
+    }
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),  
+         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,
+                            7,
+                            limTxComplete, pFrame, 
+                            limTdlsSetupCnfTxComplete,
+                            0 );
+
+
+    if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
+    {
+        limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
+        return eSIR_FAILURE;
+
+    }
+
+    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 ;
+    palCopyMemory(pMac->hHdd, 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.\n"), \
+         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)
+    {
+        palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps, 
+                    &setupReq->HTCaps, sizeof(tDot11fIEHTCaps)) ;
+    }
+    /* Update EXT caps */
+    if(setupReq->ExtCap.present)
+    {
+        palCopyMemory(pMac->hHdd, &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.\n"), \
+         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)
+    {
+        palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps, 
+                    &setupRsp->HTCaps, sizeof(tDot11fIEHTCaps)) ;
+    }
+
+    /* update EXT caps */
+    if(setupRsp->ExtCap.present)
+    {
+        palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerExtCaps, 
+                    &setupRsp->ExtCap, sizeof(tDot11fIEExtCap)) ;
+    }
+
+    return ;
+}
+#endif
+/*
+ * update HASH node entry info
+ */
+static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs,
+              tLimTdlsLinkSetupPeer *setupPeerInfo, tpPESession psessionEntry)
+{
+    //tDot11fIEHTCaps *htCaps = &setupPeerInfo->tdlsPeerHTCaps ;
+    tDot11fIEHTCaps htCap, *htCaps;
+    tpDphHashNode pSessStaDs = NULL;
+    tANI_U16 aid;
+
+    //HACK- to get the session's htcaps.
+    PopulateDot11fHTCaps(pMac, psessionEntry, &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 ;
+    }
+    
+    pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid, 
+                                          &psessionEntry->dph.dphHashTable) ;
+
+    /* Lets enable QOS parameter */
+    pStaDs->qosMode    = 1;
+    pStaDs->wmeEnabled = 1;
+    pStaDs->lleEnabled = 0;
+    pStaDs->qos.capability.qosInfo = pSessStaDs->qos.capability.qosInfo; //setupPeerInfo->qosCaps.qosInfo;
+
+    /* populate matching rate set */
+#if 0
+#ifdef WLAN_FEATURE_11AC
+    limPopulateMatchingRateSet(pMac, pStaDs, &setupPeerInfo->supportedRates,
+                          &setupPeerInfo->extendedRates, 
+                     (tANI_U8 *)setupPeerInfo->tdlsPeerHTCaps.supportedMCSSet,
+                            &pStaDs->mlmStaContext.propRateSet, psessionEntry, NULL);
+#else
+    limPopulateMatchingRateSet(pMac, pStaDs, &setupPeerInfo->supportedRates,
+                          &setupPeerInfo->extendedRates, 
+                     (tANI_U8 *)setupPeerInfo->tdlsPeerHTCaps.supportedMCSSet,
+                            &pStaDs->mlmStaContext.propRateSet, psessionEntry);
+#endif
+#else
+    palCopyMemory( pMac->hHdd, &pStaDs->supportedRates, &pSessStaDs->supportedRates, sizeof(pStaDs->supportedRates));
+#endif
+
+    pStaDs->mlmStaContext.capabilityInfo = pSessStaDs->mlmStaContext.capabilityInfo;// setupPeerInfo->capabilityInfo;
+
+    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 (palEqualMemory( pMac->hHdd,(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 = %02x, %02x, %02x, %02x, %02x, %02x \n"),
+                 peerInfo->peerMac[0], 
+                 peerInfo->peerMac[1], 
+                 peerInfo->peerMac[2], 
+                 peerInfo->peerMac[3], 
+                 peerInfo->peerMac[4], 
+                 peerInfo->peerMac[5]) ;
+
+        if (palEqualMemory( pMac->hHdd,(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 = %02x, %02x, %02x, %02x, %02x, %02x "),
+                                 peerInfo->peerMac[0], 
+                                 peerInfo->peerMac[1], 
+                                 peerInfo->peerMac[2], 
+                                 peerInfo->peerMac[3], 
+                                 peerInfo->peerMac[4], 
+                                 peerInfo->peerMac[5]) ;
+
+        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\n"), (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 (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac, 
+                        (tANI_U8 *) currentNode->peerMac, 
+                                                 sizeof(tSirMacAddr)) )
+        {
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                    ("Del Node for Peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                                    currentNode->peerMac[0], 
+                                    currentNode->peerMac[1], 
+                                    currentNode->peerMac[2], 
+                                    currentNode->peerMac[3], 
+                                    currentNode->peerMac[4], 
+                                    currentNode->peerMac[5]) ;
+            /* if it's first Node */
+            if(NULL == prevNode)
+            {
+                *linkSetupList = currentNode->next ;
+            }
+            else
+            {
+                prevNode->next = currentNode->next ;
+            }
+            palFreeMemory(pMac, 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\n"), tdlsDisReq.DialogToken.token);
+
+    if ( DOT11F_FAILED( status ) )
+    {
+        limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
+                              frame (0x%08x, %d bytes):\n"),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 an\
+                      TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
+                   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 Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
+        tdlsDisReq.LinkIdentifier.bssid[0],    
+        tdlsDisReq.LinkIdentifier.bssid[1],    
+        tdlsDisReq.LinkIdentifier.bssid[2],    
+        tdlsDisReq.LinkIdentifier.bssid[3],    
+        tdlsDisReq.LinkIdentifier.bssid[4],    
+        tdlsDisReq.LinkIdentifier.bssid[5]) ;
+
+        //VOS_ASSERT(0) ;
+        return eSIR_FAILURE;
+    }
+ 
+    /* varify BSSID */
+    status = palEqualMemory(pMac->hHdd, &psessionEntry->bssId[0],
+                    &tdlsDisReq.LinkIdentifier.bssid[0], sizeof(tSirMacAddr)) ;
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+            ("lim BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"), 
+                                             psessionEntry->bssId[0], 
+                                             psessionEntry->bssId[1], 
+                                             psessionEntry->bssId[2], 
+                                             psessionEntry->bssId[3], 
+                                             psessionEntry->bssId[4], 
+                                             psessionEntry->bssId[5]) ;
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+            ("Dis req from BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"), 
+                   tdlsDisReq.LinkIdentifier.bssid[0], 
+                   tdlsDisReq.LinkIdentifier.bssid[1], 
+                   tdlsDisReq.LinkIdentifier.bssid[2], 
+                   tdlsDisReq.LinkIdentifier.bssid[3], 
+                   tdlsDisReq.LinkIdentifier.bssid[4], 
+                   tdlsDisReq.LinkIdentifier.bssid[5]
+          ) ;
+    if(!status)
+    {
+        limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter\n")) ;
+
+        return eSIR_FAILURE ; 
+    }
+
+    /*
+     * check if this is echo of our transmitted discovery request
+     * drop it here, TODO: better to drop this in TL.
+     */    
+    status = palEqualMemory(pMac->hHdd, psessionEntry->selfMacAddr, 
+                    &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
+                                                     sizeof(tSirMacAddr)) ;
+    if(status)
+    {
+        limLog( pMac, LOGE, FL("Echo of our TDLS discovery request frame\n")) ;
+        return eSIR_FAILURE ; 
+    }
+
+    /*
+     * while processing Discovery request from Peer,
+     * STA_MAC--> MAC of TDLS discovery initiator
+     * STA_PEER_MAC--> MAC of TDLS discovery responder.
+     */
+    palCopyMemory(pMac->hHdd, 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.
+         */
+        status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult, 
+                                           sizeof(tLimDisResultList)) ; 
+    
+        if(status != eHAL_STATUS_SUCCESS)
+        {
+            limLog(pMac, LOGP, FL("alloc fail for TDLS discovery \
+                                                    reponse info\n")) ;
+            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 */
+        status = palCopyMemory(pMac->hHdd, 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\n"));
+            }
+            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 \n") ;
+                return eSIR_FAILURE ;
+            }
+        } /* use setup link sta ID for discovery rsp */
+        else
+        {
+            peerInfo->delStaNeeded = false ;
+            limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
+            peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
+        }
+
+    }
+    else
+    {
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                    ("discovery procedure in progress for this peer\n")) ;
+    } 
+
+    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):\n"),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 an\
+                      TDLS setup Request frame (0x%08x," "%d bytes):\n"),
+                   status, pBody );
+        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 Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
+        tdlsSetupReq.LinkIdentifier.bssid[0],    
+        tdlsSetupReq.LinkIdentifier.bssid[1],    
+        tdlsSetupReq.LinkIdentifier.bssid[2],    
+        tdlsSetupReq.LinkIdentifier.bssid[3],    
+        tdlsSetupReq.LinkIdentifier.bssid[4],    
+        tdlsSetupReq.LinkIdentifier.bssid[5]) ;
+
+        //VOS_ASSERT(0) ;
+        return eSIR_FAILURE ;
+    }
+    /* TODO: we don;t need this check now, varify BSSID */
+    status = palEqualMemory(pMac->hHdd, 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\n")) ;
+
+        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\n"));
+        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\n"));
+        /* 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\n" )) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
+                        ("state = %d\n"), 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\n"), 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\n" )) ;
+                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.
+         */
+        if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+                      (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
+        {
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, 
+                                 ( "Unable to allocate memory during ADD_STA\n" ));
+            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;
+
+        palCopyMemory(pMac->hHdd, setupPeer->peerMac,  
+                     &tdlsSetupReq.LinkIdentifier.InitStaAddr[0], 
+                                                     sizeof(tSirMacAddr)) ;
+
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                   ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
+                                    setupPeer->peerMac[0],  
+                                    setupPeer->peerMac[1],  
+                                    setupPeer->peerMac[2],  
+                                    setupPeer->peerMac[3],  
+                                    setupPeer->peerMac[4],  
+                                    setupPeer->peerMac[5] ) ;
+ 
+        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) ;
+            palFreeMemory(pMac->hHdd, (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;
+
+        palCopyMemory(pMac->hHdd, setupPeer->peerMac,  
+                     &tdlsSetupReq.LinkIdentifier.InitStaAddr[0], 
+                                                     sizeof(tSirMacAddr)) ;
+
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                   ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
+                                    setupPeer->peerMac[0],  
+                                    setupPeer->peerMac[1],  
+                                    setupPeer->peerMac[2],  
+                                    setupPeer->peerMac[3],  
+                                    setupPeer->peerMac[4],  
+                                    setupPeer->peerMac[5] ) ;
+ 
+        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):\n"),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 an\
+                      TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
+                   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 Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
+        tdlsSetupRsp.LinkIdentifier.bssid[0],    
+        tdlsSetupRsp.LinkIdentifier.bssid[1],    
+        tdlsSetupRsp.LinkIdentifier.bssid[2],    
+        tdlsSetupRsp.LinkIdentifier.bssid[3],    
+        tdlsSetupRsp.LinkIdentifier.bssid[4],    
+        tdlsSetupRsp.LinkIdentifier.bssid[5]) ;
+
+        //VOS_ASSERT(0) ;
+        return eSIR_FAILURE;
+    }
+  
+    /* varify BSSID */
+    status = palEqualMemory(pMac->hHdd, 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\n")) ;
+
+        VOS_ASSERT(0) ;
+        return eSIR_FAILURE ; 
+    }
+    palCopyMemory(pMac->hHdd, peerMac,  
+                      &tdlsSetupRsp.LinkIdentifier.RespStaAddr[0], 
+                                                     sizeof(tSirMacAddr)) ;
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+             ("TDLS setup RSP peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                                peerMac[0], 
+                                peerMac[1], 
+                                peerMac[2], 
+                                peerMac[3], 
+                                peerMac[4], 
+                                peerMac[5]) ; 
+    limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
+
+    if(NULL == setupPeer)
+    {
+        limLog( pMac, LOGE, FL(" unknown setup Response frame \
+                                                        other BSS\n")) ;
+        return eSIR_FAILURE ;
+    }
+                                                
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                                      ("deactivating Setup RSP timer\n")) ;
+
+    /* 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\n")) ;
+        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, 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):\n"),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 an\
+                      TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
+                   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 Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
+        tdlsSetupCnf.LinkIdentifier.bssid[0],    
+        tdlsSetupCnf.LinkIdentifier.bssid[1],    
+        tdlsSetupCnf.LinkIdentifier.bssid[2],    
+        tdlsSetupCnf.LinkIdentifier.bssid[3],    
+        tdlsSetupCnf.LinkIdentifier.bssid[4],    
+        tdlsSetupCnf.LinkIdentifier.bssid[5]) ;
+
+        //VOS_ASSERT(0) ;
+        return eSIR_FAILURE;
+    }
+ 
+    /* varify BSSID */
+    status = palEqualMemory(pMac->hHdd, 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\n")) ;
+
+        VOS_ASSERT(0) ;
+        return eSIR_FAILURE ; 
+    }
+    /* TODO, do more validation */
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+               ("setup Cnf peer MAc = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[1],
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[2], 
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[3],  
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[4],  
+                      tdlsSetupCnf.LinkIdentifier.InitStaAddr[5]
+                      ) ;
+    
+    limTdlsFindLinkPeer(pMac, 
+                   &tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
+                            &setupPeer) ;
+
+    if(NULL == setupPeer)
+    {
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                                          (" unknown setup CNF frame\n")) ;
+        VOS_ASSERT(0) ;
+        return eSIR_FAILURE ;
+    }
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                   ("setup CNF peer MAC = %02x,%02x,%02x,%02x,%02x,%02x\n"), 
+                            (setupPeer)->peerMac[0], 
+                            (setupPeer)->peerMac[1], 
+                            (setupPeer)->peerMac[2], 
+                            (setupPeer)->peerMac[3], 
+                            (setupPeer)->peerMac[4], 
+                            (setupPeer)->peerMac[5]) ; 
+    /*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\n")) ;
+        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):\n"),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 an\
+                      TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
+                   status, frmLen );
+        PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);)
+    }
+    /*TODO:  match dialog token, before proceeding further */
+
+    /* varify BSSID */
+    status = palEqualMemory(pMac->hHdd, psessionEntry->bssId, 
+                    &tdlsDisRsp.LinkIdentifier.bssid[0], 
+                                                     sizeof(tSirMacAddr)) ;
+
+    if(!status)
+    {
+        limLog( pMac, LOGW, FL(" TDLS discovery Response frame other BSS\n")) ;
+        return eSIR_FAILURE ; 
+    }
+    /* TODO, do more validation */
+  
+    if(tdlsDisRsp.DialogToken.token != prevDisReq->dialog)
+    {
+        limLog( pMac, LOGW, FL(" wrong TDLS discovery Response frame\n")) ;
+        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.
+     */
+    status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult, 
+                                               sizeof(tLimDisResultList)) ; 
+    
+    if(status != eHAL_STATUS_SUCCESS)
+    {
+        limLog(pMac, LOGP, FL("alloc fail for TDLS discovery reponse info\n")) ;
+        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.
+         */
+        status = palCopyMemory(pMac->hHdd, 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)
+        {
+            palCopyMemory( pMac, &peerInfo->tdlsPeerHtCaps, &tdlsDisRsp.HTCaps, 
+                                               sizeof( tDot11fIEHTCaps ) );
+        }
+        /* update EXT caps */
+        if (tdlsDisRsp.ExtCap.present)
+        {
+            //palCopyMemory( pMac, &peerInfo->tdlsPeerExtenCaps, 
+             //                &tdlsDisRsp.ExtCap, 
+              //                          sizeof( tDot11fIEExtCap ) );
+        }
+    } 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):\n"),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 an\
+                      TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
+                   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 Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
+        tdlsTeardown.LinkIdentifier.bssid[0],    
+        tdlsTeardown.LinkIdentifier.bssid[1],    
+        tdlsTeardown.LinkIdentifier.bssid[2],    
+        tdlsTeardown.LinkIdentifier.bssid[3],    
+        tdlsTeardown.LinkIdentifier.bssid[4],    
+        tdlsTeardown.LinkIdentifier.bssid[5]) ;
+
+        //VOS_ASSERT(0) ;
+        return eSIR_FAILURE;
+    }
+ 
+    /* varify BSSID */
+    status = palEqualMemory(pMac->hHdd, psessionEntry->bssId, 
+                                  &tdlsTeardown.LinkIdentifier.bssid[0], 
+                                                     sizeof(tSirMacAddr)) ;
+
+
+    if(!status)
+    {
+        limLog( pMac, LOGE, FL("Teardown from other BSS -> something wrong. Check RXP filter\n")) ;
+        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\n") );
+        
+        return eSIR_FAILURE ;
+    }
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                     ("teardown for peer %02x,%02x,%02x,%02x,%02x,%02x\n"), 
+                          (setupPeer)->peerMac[0],            
+                          (setupPeer)->peerMac[1],            
+                          (setupPeer)->peerMac[2],            
+                          (setupPeer)->peerMac[3],            
+                          (setupPeer)->peerMac[4],            
+                          (setupPeer)->peerMac[5]) ;            
+
+    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\n")) ;
+            break ;
+        }
+        case eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE:
+        {
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                       (" Teardown from AP, TDLS peer unreachable\n")) ;
+            break ;
+        }
+        default:
+        {
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                                            (" unknown teardown\n")) ;
+            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\n"), 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: %02x, %02x, %02x, %02x, %02x, %02x\n"), 
+                                             peerMac[0],
+                                             peerMac[1],
+                                             peerMac[2],
+                                             peerMac[3],
+                                             peerMac[4],
+                                             peerMac[5]) ;
+
+
+    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\n")) ;
+        status = eSIR_FAILURE ;
+        VOS_ASSERT(0) ;
+        return status ;
+    }
+
+    aid = limAssignAID(pMac) ;
+
+    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\n")) ;
+        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] \n"), pStaDs) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                   ("peerInfo->tdlsPeerSuppRates = [%p]\n"), 
+                        (tANI_U8 *)&peerInfo->tdlsPeerSuppRates) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+               ("peerInfo->tdlsPeerExtRates = [%p]\n"), 
+                        (tANI_U8 *)&peerInfo->tdlsPeerExtRates) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+              ("peerInfo->tdlsPeerPropRates = [%p]\n"), 
+                        (tANI_U8 *)&pStaDs->mlmStaContext.propRateSet) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+              ("peerInfo->mcs = [%p]\n"), 
+                        (tANI_U8 *)peerInfo->supportedMCSSet) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                  ("num of supp rates = %02x\n"), suppRates->numRates) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                      ("num of ext rates = %01x\n"), 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;
+        palCopyMemory(pMac->hHdd, pStaDs->staAddr, peerMac, 
+                                                   sizeof(tSirMacAddr)) ; 
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+                ("Add STA for Peer: %02x, %02x, %02x, %02x, %02x, %02x\n"), 
+                             pStaDs->staAddr[0],
+                             pStaDs->staAddr[1],
+                             pStaDs->staAddr[2],
+                             pStaDs->staAddr[3],
+                             pStaDs->staAddr[4],
+                             pStaDs->staAddr[5]) ;
+    
+
+        pStaDs->staType = STA_ENTRY_TDLS_PEER ;
+
+        status = limAddSta(pMac, pStaDs, 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, 
+                        tSirMacAddr peerMac, tLimTdlsLinkSetupPeer *setupPeer,
+                                            tpPESession psessionEntry)
+{
+    tpDphHashNode pStaDs = NULL ;
+    tSirRetStatus status = eSIR_SUCCESS ;
+    tANI_U16 aid = 0 ;
+
+    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\n")) ;
+        status = eSIR_FAILURE ;
+        /* TDLS_TODO: I have seen this VOS ASSERT happened. must handle this (called from limProcessTdlsSetupReqFrame) */
+        VOS_ASSERT(0) ;
+        return status ;
+    }
+    aid = limAssignAID(pMac) ;
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+          ("Aid = %d, for peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
+                     aid, peerMac[0],peerMac[1],peerMac[2],
+                              peerMac[3],peerMac[4],peerMac[5]) ;
+    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\n")) ;
+        status = eSIR_FAILURE ;
+        VOS_ASSERT(0) ;
+    }
+  
+    limTdlsUpdateHashNodeInfo(pMac, pStaDs, setupPeer, psessionEntry) ; 
+
+    pStaDs->staType = STA_ENTRY_TDLS_PEER ;
+
+    status = limAddSta(pMac, pStaDs, 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 aid = 0 ;
+    tpDphHashNode pStaDs = NULL ;
+ 
+    pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, 
+                                         &psessionEntry->dph.dphHashTable) ;
+
+    if(pStaDs)
+    {
+    
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+             ("DEL STA peer MAC: %02x, %02x, %02x, %02x, %02x, %02x \n"),
+                                   pStaDs->staAddr[0],
+                                   pStaDs->staAddr[1],
+                                   pStaDs->staAddr[2],
+                                   pStaDs->staAddr[3],
+                                   pStaDs->staAddr[4],
+                                   pStaDs->staAddr[5]
+                                    ) ;
+
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, 
+                   ("STA type = %x, sta idx = %x\n"),pStaDs->staType, 
+                                                           pStaDs->staIndex) ;
+ 
+        status = limDelSta(pMac, pStaDs, false, psessionEntry) ;
+        if(eSIR_SUCCESS == status)
+        {
+            limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry) ;
+            limReleaseAID(pMac, aid) ;
+        }
+        else
+        {
+            VOS_ASSERT(0) ;
+        }
+    }
+           
+    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: %02X %02X %02X %02X %02X %02X\n"), \
+        peerMac[0], peerMac[1], peerMac[2], \
+        peerMac[3], peerMac[4], peerMac[5]);
+        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\n"), 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 hash table: %02X %02X %02X %02X %02X %02X\n"), \
+            peerMac[0], peerMac[1], peerMac[2], \
+            peerMac[3], peerMac[4], peerMac[5]);
+        return eSIR_FAILURE;
+    }
+
+    palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsPtiTemplate, 
+               sizeof( tDot11fTDLSPeerTrafficInd ) );
+
+    /*
+    * 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).\n"), 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).\n"), 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.\n"), nBytes);
+        nBytes = 64;
+    }
+    /* zero out the memory */
+    palZeroMemory( pMac->hHdd, pFrame, sizeof(pFrame) );
+
+    /* 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).\n"), status );
+        return eSIR_FAILURE;
+    }
+    else if ( DOT11F_WARNED( status ) )
+    {
+        limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
+            "Peer Traffic Indication (0x%08x).\n") );
+    }
+
+    LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("bIsResponder=%d, header_offset=%ld, linkIdenOffset=%d, ptiBufStatusOffset=%d \n"), \
+        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: %02X %02X %02X %02X %02X %02X\n"), \
+        peerMac[0], peerMac[1], peerMac[2], \
+        peerMac[3], peerMac[4], peerMac[5]);
+        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\n"), 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: %02X %02X %02X %02X %02X %02X\n"), \
+            peerMac[0], peerMac[1], peerMac[2], \
+            peerMac[3], peerMac[4], peerMac[5]);
+        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 */
+    status = palAllocateMemory( pMac->hHdd, (void **)&disRsp, disMsgRspSize ) ;
+ 
+    if(eHAL_STATUS_FAILURE == status)
+    {
+        limLog(pMac, LOGP, FL("palAllocateMemory failed for DIS RSP"));
+        return NULL ;
+    }
+        
+    if(disStaCount)
+    { 
+        tLimDisResultList *tdlsDisRspList = pMac->lim.gLimTdlsDisResultList ;
+        tSirTdlsPeerInfo *peerInfo = &disRsp->tdlsDisPeerInfo[0] ;
+            
+        tLimDisResultList *currentNode = tdlsDisRspList ;
+        while(tdlsDisRspList != NULL)
+        {
+
+            palCopyMemory( pMac->hHdd, (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: %02x, %02x, %02x, %02x, %02x, %02x\n"), 
+                                  peerInfo->peerMac[0] ,
+                                  peerInfo->peerMac[1] ,
+                                  peerInfo->peerMac[2] ,
+                                  peerInfo->peerMac[3] ,
+                                  peerInfo->peerMac[4] ,
+                                  peerInfo->peerMac[5]) ;
+            disStaCount-- ;
+            peerInfo++ ;
+            currentNode = tdlsDisRspList ;
+            tdlsDisRspList = tdlsDisRspList->next ;
+            palFreeMemory(pMac->hHdd, currentNode) ;
+            /* boundary condition check, may be fatal */
+            if(((!disStaCount) && (tdlsDisRspList)) 
+                            || ((!tdlsDisRspList) && disStaCount))
+            {
+                limLog(pMac, LOG1, FL("mismatch in dis sta count and\
+                                        and number of nodes in list\n")) ;
+                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 ;
+
+    status = palAllocateMemory( pMac->hHdd, (void **)&teardownRspMsg, 
+                                        sizeof(tSirTdlsTeardownRsp)) ;
+
+    if(eHAL_STATUS_SUCCESS != status)
+    {
+        VOS_ASSERT(0) ;
+    } 
+    palCopyMemory( pMac->hHdd, 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 ;
+
+    status = palAllocateMemory( pMac->hHdd, (void **)&setupRspMsg, 
+                                        sizeof(tSirTdlsLinksetupRsp)) ;
+
+    if(eHAL_STATUS_SUCCESS != status)
+    {
+        VOS_ASSERT(0) ;
+    } 
+
+    palCopyMemory( pMac->hHdd, 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\n"), tdlsStaCount) ; 
+        tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, tdlsStaCount) ;
+
+        if(tdlsDisRsp)
+        {
+            tdlsDisRsp->numDisSta = tdlsStaCount ;
+        }
+        else
+        {
+            limLog(pMac, LOGP, FL("fatal failure for TDLS DIS RSP\n"));
+            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 ;
+    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
+                                                (sizeof(tSirTdlsPeerInd))))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+        return eSIR_FAILURE;
+    }
+
+    palCopyMemory( pMac->hHdd, 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 ;
+    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
+                                                (sizeof(tSirTdlsPeerInd))))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+        return eSIR_FAILURE;
+    }
+
+    palCopyMemory( pMac->hHdd, 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 ;
+    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &setupInd,
+                                            (sizeof(tSirTdlsLinkSetupInd))))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+        return eSIR_FAILURE;
+    }
+
+    palCopyMemory( pMac->hHdd, 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\n"),
+               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\n"),
+               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\n"));
+        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!\n"));
+        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, tDphHashNode   *pStaDs,
+                   tANI_U8 status)
+{
+    tSirMsgQ  mmhMsg = {0} ;
+    tSirTdlsAddStaRsp *addStaRsp = NULL ;
+    mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ;
+    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &addStaRsp,
+                                                (sizeof(tSirTdlsAddStaRsp))))
+    {
+        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 )
+    {
+        palCopyMemory( pMac->hHdd, addStaRsp->peerMac, 
+                (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
+    }
+    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, VOS_TRACE_LEVEL_ERROR, 
+            ("ADD_STA_RSP received :staIdx=%d, staMac=%02x:%02x:%02x:%02x:%02x:%02x"), pAddStaParams->staIdx, \
+                            pAddStaParams->staMac[0], 
+                            pAddStaParams->staMac[1], 
+                            pAddStaParams->staMac[2], 
+                            pAddStaParams->staMac[3], 
+                            pAddStaParams->staMac[4], 
+                            pAddStaParams->staMac[5] ) ;
+
+    if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
+    {
+        VOS_ASSERT(0) ;
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+                                                   ("Add sta failed \n")) ;
+        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 \n")) ;
+        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\n")) ;
+        palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+        return eSIR_FAILURE ;
+    }
+
+    /* 
+     * Now, there is two things a) ADD STA RSP for ADD STA request sent
+     * after recieving discovery request from Peer.
+     * now we have to send discovery response, if there is any pending
+     * discovery equest..
+     */
+    do
+    {
+        tSirTdlsPeerInfo *peerInfo = limTdlsFindDisPeer(pMac,
+                                            pAddStaParams->staMac) ;
+
+    
+        if(peerInfo)
+        {
+            /* 
+             * send TDLS discovery response frame on direct link, state machine
+             * is rolling.., once discovery response is get Acked, we will 
+             * send response to SME based on TxComplete callback results
+             */ 
+            limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
+            peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
+        }
+    } while(0) ;
+#else
+    status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId, 
+                                        pAddStaParams->staMac, pStaDs, status) ;
+    if(eSIR_FAILURE == status)
+    {
+        VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+                                         ("Peer IND msg to SME failed\n")) ;
+        palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+    }
+    return status;
+
+#endif
+add_sta_error:
+    status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId, 
+                                        pAddStaParams->staMac, NULL, status) ;
+    palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
+    return status ;
+}
+
+/*
+ * 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)) ;
+    palCopyMemory( pMac->hHdd, (tANI_U8 *)linkIden->bssid, 
+                     (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ; 
+
+    palCopyMemory( pMac->hHdd, (tANI_U8 *)initStaAddr,
+                          psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
+
+    palCopyMemory( pMac->hHdd, (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 = PEER_BUFFER_STA_SUPPORT ;
+    extCapability->TDLSChannelSwitching = CH_SWITCH_SUPPORT ;
+    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
+    */
+    if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+                  (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
+    {
+        limLog( pMac, LOGP, 
+                  FL( "Unable to allocate memory during ADD_STA\n" ));
+         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
+    */
+    palCopyMemory(pMac->hHdd, 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\n")) ;
+
+    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\n", 
+                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\n", 
+                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)\n", 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\n") ;
+            /* format TDLS discovery request frame and transmit it */
+            limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, 
+                    psessionEntry) ;
+            resultCode = eSIR_SME_SUCCESS;
+            break;
+        case SIR_MAC_TDLS_DIS_RSP:
+            {
+                //Send a response mgmt action frame
+                limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac,
+                        pSendMgmtReq->dialog, psessionEntry) ;
+                resultCode = eSIR_SME_SUCCESS;
+            }
+            break;
+        case SIR_MAC_TDLS_SETUP_REQ:
+            {
+                limSendTdlsLinkSetupReqFrame(pMac,
+                        pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry,
+                        &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); 
+                resultCode = eSIR_SME_SUCCESS;
+            }
+            break;
+        case SIR_MAC_TDLS_SETUP_RSP:
+            {
+                limSendTdlsSetupRspFrame(pMac, 
+                        pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode,
+                        &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
+                resultCode = eSIR_SME_SUCCESS;
+            }
+            break;
+        case SIR_MAC_TDLS_SETUP_CNF:
+            {
+                limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, 
+                        psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));  
+                resultCode = eSIR_SME_SUCCESS;
+            }
+            break;
+        case SIR_MAC_TDLS_TEARDOWN:
+            {
+                limSendTdlsTeardownFrame(pMac,
+                        pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, 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;
+}
+
+/*
+ * 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 ;
+    if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &pDelSta,
+                (sizeof(tSirTdlsDelStaRsp))))
+    {
+        PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
+            return eSIR_FAILURE;
+    }
+
+    pDelSta->sessionId = sessionId;
+    pDelSta->statusCode =  status ;
+    if( pStaDs )
+    {
+        pDelSta->staId = pStaDs->staIndex ;
+    }
+    if( peerMac )
+    {
+        palCopyMemory(pMac->hHdd, 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;
+    tLimTdlsLinkSetupPeer setupPeer = {0};
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+                                  ("Send Mgmt Recieved\n")) ;
+
+    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\n", 
+                                                            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\n", 
+                                             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)\n", 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->peerMac, 
+                                               &setupPeer, psessionEntry))
+     {
+         VOS_ASSERT(0) ;
+         goto lim_tdls_add_sta_error;
+     }
+     return eSIR_SUCCESS;
+lim_tdls_add_sta_error:
+     limSendSmeTdlsAddStaRsp(pMac, 
+                   pAddStaReq->sessionId, pAddStaReq->peerMac, 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\n")) ;
+
+    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\n", 
+                pDelStaReq->sessionId);
+        limSendSmeTdlsDelStaRsp(pMac, 0, 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\n", 
+                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)\n", 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) ;
+        return eSIR_SUCCESS;
+
+    }
+
+lim_tdls_del_sta_error:
+     limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
+             NULL, eSIR_FAILURE) ;
+
+    return eSIR_SUCCESS;
+}
+#endif