blob: 4a795165838dc62ecf7faf849d728838e3907bf5 [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Gopichand Nakkala0c1331e2013-01-07 22:49:07 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080021/*
22 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
23 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
Kiran V1ccee932012-12-12 14:49:46 -080041
42/*===========================================================================
43
44 limProcessTdls.c
45
46 OVERVIEW:
47
48 DEPENDENCIES:
49
50 Are listed for each API below.
51
Gopichand Nakkalabd9fa2d2013-01-08 13:16:22 -080052
53 Copyright (c) 2010 QUALCOMM Incorporated.
54 All Rights Reserved.
55 Qualcomm Confidential and Proprietary
Kiran V1ccee932012-12-12 14:49:46 -080056===========================================================================*/
57
58/*===========================================================================
59
60 EDIT HISTORY FOR FILE
61
62
63 This section contains comments describing changes made to the module.
64 Notice that changes are listed in reverse chronological order.
65
66
67 $Header$$DateTime$$Author$
68
69
70 when who what, where, why
71---------- --- --------------------------------------------------------
7205/05/2010 Ashwani Initial Creation, added TDLS action frame functionality,
73 TDLS message exchange with SME..etc..
74
75===========================================================================*/
76
77
78/**
79 * \file limProcessTdls.c
80 *
81 * \brief Code for preparing,processing and sending 802.11z action frames
82 *
83 */
84
85#ifdef FEATURE_WLAN_TDLS
86
87#include "sirApi.h"
88#include "aniGlobal.h"
89#include "sirMacProtDef.h"
90#include "cfgApi.h"
91#include "utilsApi.h"
92#include "limTypes.h"
93#include "limUtils.h"
94#include "limSecurityUtils.h"
95#include "dot11f.h"
96#include "limStaHashApi.h"
97#include "schApi.h"
98#include "limSendMessages.h"
99#include "utilsParser.h"
100#include "limAssocUtils.h"
101#include "dphHashTable.h"
102#include "wlan_qct_wda.h"
103
104
105#ifdef FEATURE_WLAN_TDLS_INTERNAL
106/* forword declarations */
107static tSirRetStatus limTdlsDisAddSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
108 tSirTdlsPeerInfo *peerInfo, tpPESession psessionEntry) ;
109static eHalStatus limSendSmeTdlsLinkSetupInd(tpAniSirGlobal pMac,
110 tSirMacAddr peerMac, tANI_U8 status);
111static eHalStatus limSendSmeTdlsDelPeerInd(tpAniSirGlobal pMac,
112 tANI_U8 sessionId, tDphHashNode *pStaDs, tANI_U8 status) ;
113static tSirTdlsPeerInfo *limTdlsFindDisPeerByState(tpAniSirGlobal pMac,
114 tANI_U8 state);
115static tANI_U8 limTdlsFindSetupPeerByState(tpAniSirGlobal pMac, tANI_U8 state,
116 tLimTdlsLinkSetupPeer **setupPeer) ;
117static tSirRetStatus limTdlsLinkEstablish(tpAniSirGlobal pMac, tSirMacAddr peer_mac);
118
119static tSirRetStatus limTdlsLinkTeardown(tpAniSirGlobal pMac, tSirMacAddr peer_mac);
120static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
121 tpPESession psessionEntry) ;
122
123#endif
124static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac, tSirMacAddr,
125 tLimTdlsLinkSetupPeer *setupPeer, tpPESession psessionEntry) ;
126void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
127 tDot11fIELinkIdentifier *linkIden,
128 tSirMacAddr peerMac , tANI_U8 reqType) ;
129void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac,
130 tDot11fIEExtCap *extCapability) ;
131/*
132 * TDLS data frames will go out/come in as non-qos data.
133 * so, eth_890d_header will be aligned access..
134 */
135static const tANI_U8 eth_890d_header[] =
136{
137 0xaa, 0xaa, 0x03, 0x00,
138 0x00, 0x00, 0x89, 0x0d,
139} ;
140
141/*
142 * type of links used in TDLS
143 */
144enum tdlsLinks
145{
146 TDLS_LINK_AP,
147 TDLS_LINK_DIRECT
148} eTdlsLink ;
149
150/*
151 * node status in node searching
152 */
153enum tdlsLinkNodeStatus
154{
155 TDLS_NODE_NOT_FOUND,
156 TDLS_NODE_FOUND
157} eTdlsLinkNodeStatus ;
158
159
160enum tdlsReqType
161{
162 TDLS_INITIATOR,
163 TDLS_RESPONDER
164} eTdlsReqType ;
165
166typedef enum tdlsLinkSetupStatus
167{
168 TDLS_SETUP_STATUS_SUCCESS = 0,
169 TDLS_SETUP_STATUS_FAILURE = 37
170}etdlsLinkSetupStatus ;
171
172/* some local defines */
173#define LINK_IDEN_BSSID_OFFSET (0)
174#define PEER_MAC_OFFSET (12)
175#define STA_MAC_OFFSET (6)
176#define LINK_IDEN_ELE_ID (101)
177//#define LINK_IDEN_LENGTH (18)
178#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
179#define PTI_LINK_IDEN_OFFSET (5)
180#define PTI_BUF_STATUS_OFFSET (25)
181
182/* TODO, Move this parameters to configuration */
183#define PEER_PSM_SUPPORT (0)
184#define PEER_BUFFER_STA_SUPPORT (1)
185#define CH_SWITCH_SUPPORT (0)
186#define TDLS_SUPPORT (1)
187#define TDLS_PROHIBITED (0)
188#define TDLS_CH_SWITCH_PROHIBITED (1)
189
190#ifdef LIM_DEBUG_TDLS
191#define TDLS_CASE_RETURN_STRING(x) case (x): return( ((const tANI_U8*)#x) + 8); /* 8 = remove redundant SIR_MAC_ */
192
193#ifdef FEATURE_WLAN_TDLS
194#define WNI_CFG_TDLS_DISCOVERY_RSP_WAIT (100)
195#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
196#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
197#endif
198
199const tANI_U8* limTraceTdlsActionString( tANI_U8 tdlsActionCode )
200{
201 switch( tdlsActionCode )
202 {
203 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
204 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
205 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
206 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
207 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
208 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
209 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
210 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
211 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
212 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
213 }
214 return (const tANI_U8*)"UNKNOWN";
215}
216#endif
217#if 0
218static void printMacAddr(tSirMacAddr macAddr)
219{
220 int i = 0 ;
221 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, (" Mac Addr: "));
222
223 for(i = 0 ; i < 6; i++)
224 {
225 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
226 (" %02x "), macAddr[i]);
227 }
228 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("\n"));
229 return ;
230}
231#endif
Kiran V1ccee932012-12-12 14:49:46 -0800232/*
233 * initialize TDLS setup list and related data structures.
234 */
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800235void limInitTdlsData(tpAniSirGlobal pMac, tpPESession pSessionEntry)
Kiran V1ccee932012-12-12 14:49:46 -0800236{
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800237#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -0800238 pMac->lim.gLimTdlsDisResultList = NULL ;
239 pMac->lim.gLimTdlsDisStaCount = 0 ;
240 palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsDisReq,
241 sizeof(tSirTdlsDisReq));
242 palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsLinkSetupInfo,
243 sizeof(tLimTdlsLinkSetupInfo));
244 pMac->lim.gAddStaDisRspWait = 0 ;
245
246#ifdef FEATURE_WLAN_TDLS_NEGATIVE
247 /* when reassociated, negative behavior will not be kept */
248 /* you have to explicitly enable negative behavior per (re)association */
249 pMac->lim.gLimTdlsNegativeBehavior = 0;
250#endif
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800251#endif
252 limInitPeerIdxpool(pMac, pSessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -0800253
254 return ;
255}
Kiran V1ccee932012-12-12 14:49:46 -0800256#ifdef FEATURE_WLAN_TDLS_NEGATIVE
257void limTdlsSetNegativeBehavior(tpAniSirGlobal pMac, tANI_U8 value, tANI_BOOLEAN on)
258{
259 if(on) {
260 if(value == 255)
261 pMac->lim.gLimTdlsNegativeBehavior = 0XFFFFFFFF;
262 else
263 pMac->lim.gLimTdlsNegativeBehavior |= (1 << (value-1));
264 }
265 else {
266 if(value == 255)
267 pMac->lim.gLimTdlsNegativeBehavior = 0;
268 else
269 pMac->lim.gLimTdlsNegativeBehavior &= ~(1 << (value-1));
270 }
271 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,("%d %d -> gLimTdlsNegativeBehavior= 0x%lx\n"), \
272 value, on, pMac->lim.gLimTdlsNegativeBehavior));
273}
274#endif
275#if 0
276/*
277 * This function is used for creating TDLS public Action frame to
278 * transmit on Direct link
279 */
280static void limPreparesActionFrameHdr(tpAniSirGlobal pMac, tANI_U8 *pFrame,
281 tANI_U8 type, tANI_U8 subType,
282 tANI_U8 *link_iden )
283{
284 tpSirMacMgmtHdr pMacHdr ;
285 tANI_U8 *bssid = link_iden ;
286#if 0
287 tANI_U8 *staMac = (tANI_U8 *)(bssid + sizeof(tSirMacAddr)) ;
288 tANI_U8 *peerMac = (tANI_U8 *) (staMac + sizeof(tSirMacAddr)) ;
289#else
290 tANI_U8 *peerMac = (tANI_U8 *) (bssid + sizeof(tSirMacAddr)) ;
291 tANI_U8 *staMac = (tANI_U8 *)(peerMac + sizeof(tSirMacAddr)) ;
292#endif
293 tANI_U8 toDs = ANI_TXDIR_IBSS ;
294
295 pMacHdr = (tpSirMacMgmtHdr) (pFrame);
296
297 /*
298 * prepare 802.11 header
299 */
300 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
301 pMacHdr->fc.type = type ;
302 pMacHdr->fc.subType = subType ;
303 /*
304 * TL is not setting up below fields, so we are doing it here
305 */
306 pMacHdr->fc.toDS = toDs ;
307 pMacHdr->fc.powerMgmt = 0 ;
308
309
310 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, peerMac,
311 sizeof( tSirMacAddr ));
312 palCopyMemory( pMac->hHdd,
313 (tANI_U8 *) pMacHdr->sa,
314 staMac, sizeof( tSirMacAddr ));
315
316 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->bssId,
317 bssid, sizeof( tSirMacAddr ));
318
319 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"), \
320 pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5], \
321 pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5], \
322 pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2], \
323 pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5]));
324
325 return ;
326}
327#endif
328/*
329 * prepare TDLS frame header, it includes
330 * | | | |
331 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
332 * | | | |
333 */
334static tANI_U32 limPrepareTdlsFrameHeader(tpAniSirGlobal pMac, tANI_U8* pFrame,
335 tDot11fIELinkIdentifier *link_iden, tANI_U8 tdlsLinkType, tANI_U8 reqType, tpPESession psessionEntry )
336{
337 tpSirMacMgmtHdr pMacHdr ;
338 tANI_U32 header_offset = 0 ;
339 tANI_U8 *addr1 = NULL ;
340 tANI_U8 *addr3 = NULL ;
341 tANI_U8 toDs = (tdlsLinkType == TDLS_LINK_AP)
342 ? ANI_TXDIR_TODS :ANI_TXDIR_IBSS ;
343 tANI_U8 *peerMac = (reqType == TDLS_INITIATOR)
344 ? link_iden->RespStaAddr : link_iden->InitStaAddr;
345 tANI_U8 *staMac = (reqType == TDLS_INITIATOR)
346 ? link_iden->InitStaAddr : link_iden->RespStaAddr;
347
348 pMacHdr = (tpSirMacMgmtHdr) (pFrame);
349
350 /*
351 * if TDLS frame goes through the AP link, it follows normal address
352 * pattern, if TDLS frame goes thorugh the direct link, then
353 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
354 */
355 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
356 (addr3 = (peerMac)))
357 : ((addr1 = (peerMac)),
358 (addr3 = (link_iden->bssid))) ;
359 /*
360 * prepare 802.11 header
361 */
362 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
363 pMacHdr->fc.type = SIR_MAC_DATA_FRAME ;
364 pMacHdr->fc.subType = SIR_MAC_DATA_DATA ;
365 /*
366 * TL is not setting up below fields, so we are doing it here
367 */
368 pMacHdr->fc.toDS = toDs ;
369 pMacHdr->fc.powerMgmt = 0 ;
370 pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE)? 0 : 1;
371
372
373 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, (tANI_U8 *)addr1,
374 sizeof( tSirMacAddr ));
375 palCopyMemory( pMac->hHdd,
376 (tANI_U8 *) pMacHdr->sa,
377 (tANI_U8 *) staMac,
378 sizeof( tSirMacAddr ));
379
380 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->bssId,
381 (tANI_U8 *) (addr3), sizeof( tSirMacAddr ));
382
383 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"), \
384 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "TD", \
385 pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5], \
386 pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5], \
387 pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2], \
388 pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5]));
389
390 //printMacAddr(pMacHdr->bssId) ;
391 //printMacAddr(pMacHdr->sa) ;
392 //printMacAddr(pMacHdr->da) ;
393
394 header_offset += sizeof(tSirMacMgmtHdr) ;
395 /*
396 * Now form RFC1042 header
397 */
398 palCopyMemory(pMac->hHdd, (tANI_U8 *)(pFrame + header_offset),
399 (tANI_U8 *)eth_890d_header , sizeof(eth_890d_header)) ;
400
401 header_offset += sizeof(eth_890d_header) ;
402
403 /* add payload type as TDLS */
404 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS ;
405
406 return(header_offset += PAYLOAD_TYPE_TDLS_SIZE) ;
407}
408
409/*
410 * This function can be used for bacst or unicast discovery request
411 * We are not differentiating it here, it will all depnds on peer MAC address,
412 */
413tSirRetStatus limSendTdlsDisReqFrame(tpAniSirGlobal pMac, tSirMacAddr peer_mac,
414 tANI_U8 dialog, tpPESession psessionEntry)
415{
416 tDot11fTDLSDisReq tdlsDisReq ;
417 tANI_U32 status = 0 ;
418 tANI_U32 nPayload = 0 ;
419 tANI_U32 size = 0 ;
420 tANI_U32 nBytes = 0 ;
421 tANI_U32 header_offset = 0 ;
422 tANI_U8 *pFrame;
423 void *pPacket;
424 eHalStatus halstatus;
425
426 /*
427 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
428 * and then hand it off to 'dot11fPackProbeRequest' (for
429 * serialization). We start by zero-initializing the structure:
430 */
431 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisReq,
432 sizeof( tDot11fTDLSDisReq ) );
433
434 /*
435 * setup Fixed fields,
436 */
437 tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS ;
438 tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ ;
439 tdlsDisReq.DialogToken.token = dialog ;
440
441
442 size = sizeof(tSirMacAddr) ;
443
444 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
445 peer_mac, TDLS_INITIATOR) ;
446
447 /*
448 * now we pack it. First, how much space are we going to need?
449 */
450 status = dot11fGetPackedTDLSDisReqSize( pMac, &tdlsDisReq, &nPayload);
451 if ( DOT11F_FAILED( status ) )
452 {
453 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
454 "or a discovery Request (0x%08x).\n"), status );
455 /* We'll fall back on the worst case scenario: */
456 nPayload = sizeof( tDot11fTDLSDisReq );
457 }
458 else if ( DOT11F_WARNED( status ) )
459 {
460 limLog( pMac, LOGW, FL("There were warnings while calculating"
461 "the packed size for a discovery Request ("
462 "0x%08x).\n"), status );
463 }
464
465 /*
466 * This frame is going out from PE as data frames with special ethertype
467 * 89-0d.
468 * 8 bytes of RFC 1042 header
469 */
470
471
472 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
473 + sizeof( eth_890d_header )
474 + PAYLOAD_TYPE_TDLS_SIZE ;
475
476 /* Ok-- try to allocate memory from MGMT PKT pool */
477
478 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
479 ( tANI_U16 )nBytes, ( void** ) &pFrame,
480 ( void** ) &pPacket );
481 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
482 {
483 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
484 "Discovery Request.\n"), nBytes );
485 return eSIR_MEM_ALLOC_FAILED;
486 }
487
488 /* zero out the memory */
489 palZeroMemory( pMac->hHdd, pFrame, nBytes );
490
491 /*
492 * IE formation, memory allocation is completed, Now form TDLS discovery
493 * request frame
494 */
495
496 /* fill out the buffer descriptor */
497
498 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
499 LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP, TDLS_INITIATOR, psessionEntry) ;
500
501#ifdef FEATURE_WLAN_TDLS_NEGATIVE
502 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_REQ)
503 {
504 tdlsDisReq.LinkIdentifier.bssid[4] = 0xde;
505 tdlsDisReq.LinkIdentifier.bssid[5] = 0xad;
506 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
507 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Req\n"), \
508 tdlsDisReq.LinkIdentifier.bssid[0],
509 tdlsDisReq.LinkIdentifier.bssid[1],
510 tdlsDisReq.LinkIdentifier.bssid[2],
511 tdlsDisReq.LinkIdentifier.bssid[3],
512 tdlsDisReq.LinkIdentifier.bssid[4],
513 tdlsDisReq.LinkIdentifier.bssid[5]);
514 }
515#endif
516 status = dot11fPackTDLSDisReq( pMac, &tdlsDisReq, pFrame
517 + header_offset, nPayload, &nPayload );
518
519 if ( DOT11F_FAILED( status ) )
520 {
521 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
522 (0x%08x).\n"), status );
523 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
524 ( void* ) pFrame, ( void* ) pPacket );
525 return eSIR_FAILURE;
526 }
527 else if ( DOT11F_WARNED( status ) )
528 {
529 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
530 "Discovery Request (0x%08x).\n") );
531 }
532
533
534 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
535 SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) ));
536
537 halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
538 HAL_TXRX_FRM_802_11_DATA,
539 ANI_TXDIR_TODS,
540 7,
541 limTxComplete, pFrame, 0 );
542 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
543 {
544 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
545 return eSIR_FAILURE;
546
547 }
548
549 return eSIR_SUCCESS;
550
551}
552
553/*
554 * Once Discovery response is sent successfully (or failure) on air, now send
555 * response to PE and send del STA to HAL.
556 */
557eHalStatus limTdlsDisRspTxComplete(tpAniSirGlobal pMac,
558 tANI_U32 txCompleteSuccess)
559{
560 eHalStatus status = eHAL_STATUS_SUCCESS ;
561#ifdef FEATURE_WLAN_TDLS_INTERNAL
562 tpDphHashNode pStaDs = NULL ;
563 tSirTdlsPeerInfo *peerInfo = 0 ;
564
565 /* find peer by looking into the list by expected state */
566 peerInfo = limTdlsFindDisPeerByState(pMac, TDLS_DIS_RSP_SENT_WAIT_STATE) ;
567
568 if(NULL == peerInfo)
569 {
570 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
571 ("DisRspTxComplete: No TDLS state machine waits for this event\n"));
572 VOS_ASSERT(0) ;
573 return eHAL_STATUS_FAILURE;
574 }
575
576 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_DONE_STATE ;
577
578 if(peerInfo->delStaNeeded)
579 {
580 tpPESession psessionEntry;
581
582 peerInfo->delStaNeeded = false ;
583 psessionEntry = peFindSessionBySessionId (pMac, peerInfo->sessionId);
584
585 if(NULL == psessionEntry)
586 {
587 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
588 ("DisRspTxComplete: sessionID %d is not found\n"), peerInfo->sessionId);
589 return eHAL_STATUS_FAILURE;
590 }
591 /* send del STA to remove context for this TDLS STA */
592 pStaDs = limTdlsDelSta(pMac, peerInfo->peerMac, psessionEntry) ;
593
594 /* now send indication to SME-->HDD->TL to remove STA from TL */
595 if(pStaDs)
596 {
597 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
598 pStaDs, eSIR_SUCCESS) ;
599 }
600 else
601 {
602 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
603 ("DisRspTxComplete: staDs not found for %02x:%02x:%02x:%02x:%02x:%02x\n"),
604 (peerInfo)->peerMac[0],
605 (peerInfo)->peerMac[1],
606 (peerInfo)->peerMac[2],
607 (peerInfo)->peerMac[3],
608 (peerInfo)->peerMac[4],
609 (peerInfo)->peerMac[5]) ;
610 VOS_ASSERT(0) ;
611 return eHAL_STATUS_FAILURE;
612 }
613 }
614
615 if(!txCompleteSuccess)
616 {
617 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
618 ("TX complete failure for Dis RSP"));
619 limSendSmeTdlsDisRsp(pMac, eSIR_FAILURE,
620 eWNI_SME_TDLS_DISCOVERY_START_IND) ;
621 status = eHAL_STATUS_FAILURE;
622 }
623 else
624 {
625 limSendSmeTdlsDisRsp(pMac, eSIR_SUCCESS,
626 eWNI_SME_TDLS_DISCOVERY_START_IND) ;
627 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
628 ("TX complete Success for Dis RSP"));
629 status = eHAL_STATUS_SUCCESS ;
630 }
631 //pMac->hal.pCBackFnTxComp = NULL ;
632#endif
633 return status ;
634
635}
636/*
637 * Once setup CNF is sent successfully (or failure) on air, now send
638 * response to PE and send del STA to HAL.
639 */
640eHalStatus limTdlsSetupCnfTxComplete(tpAniSirGlobal pMac,
641 tANI_U32 txCompleteSuccess)
642{
643 eHalStatus status = eHAL_STATUS_SUCCESS ;
644#ifdef FEATURE_WLAN_TDLS_INTERNAL
645 tLimTdlsLinkSetupPeer *peerInfo = 0 ;
646 /* find peer by looking into the list by expected state */
647 limTdlsFindSetupPeerByState(pMac,
648 TDLS_LINK_SETUP_RSP_WAIT_STATE, &peerInfo) ;
649
650 if(NULL == peerInfo)
651 {
652 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
653 ("limTdlsSetupCnfTxComplete: No TDLS state machine waits for this event\n"));
654 VOS_ASSERT(0) ;
655 return eHAL_STATUS_FAILURE;
656 }
657
658 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
659 (peerInfo)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ;
660
661 if(!txCompleteSuccess)
662 {
663 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
664 ("TX complete Failure for setup CNF"));
665 limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE, (peerInfo)->peerMac,
666 eWNI_SME_TDLS_LINK_START_RSP) ;
667 status = eHAL_STATUS_FAILURE;
668 }
669 else
670 {
671 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
672 ("RSP-->SME peer MAC = %02x,%02x,%02x,%02x,%02x,%02x\n"),
673 (peerInfo)->peerMac[0],
674 (peerInfo)->peerMac[1],
675 (peerInfo)->peerMac[2],
676 (peerInfo)->peerMac[3],
677 (peerInfo)->peerMac[4],
678 (peerInfo)->peerMac[5]) ;
679
680 limSendSmeTdlsLinkStartRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
681 eWNI_SME_TDLS_LINK_START_RSP) ;
682
683 /* tdls_hklee: prepare PTI template and send it to HAL */
684 limTdlsLinkEstablish(pMac, (peerInfo)->peerMac);
685
686 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
687 ("TX complete Success for setup CNF"));
688 status = eHAL_STATUS_SUCCESS ;
689 }
690 //pMac->hal.pCBackFnTxComp = NULL ;
691#endif
692 return status ;
693
694}
695
696/*
697 * Tx Complete for Teardown frame
698 */
699eHalStatus limTdlsTeardownTxComplete(tpAniSirGlobal pMac,
700 tANI_U32 txCompleteSuccess)
701{
702 eHalStatus status = eHAL_STATUS_SUCCESS ;
703#ifdef FEATURE_WLAN_TDLS_INTERNAL
704 tpDphHashNode pStaDs = NULL ;
705 tLimTdlsLinkSetupPeer *peerInfo = 0 ;
706 tpPESession psessionEntry = NULL ;
707 //tANI_U16 msgType = 0 ;
708
709 //tSirMacAddr peerMac = {0} ;
710 /* find peer by looking into the list by expected state */
711 limTdlsFindSetupPeerByState(pMac,
712 TDLS_LINK_TEARDOWN_START_STATE, &peerInfo) ;
713
714 if(NULL == peerInfo)
715 {
716 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
717 ("limTdlsTeardownTxComplete: No TDLS state machine waits for this event\n"));
718 VOS_ASSERT(0) ;
719 return eHAL_STATUS_FAILURE;
720 }
721
722 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
723 ("teardown peer Mac = %02x,%02x,%02x,%02x,%02x,%02x\n"),
724 (peerInfo)->peerMac[0] ,
725 (peerInfo)->peerMac[1] ,
726 (peerInfo)->peerMac[2] ,
727 (peerInfo)->peerMac[3] ,
728 (peerInfo)->peerMac[4] ,
729 (peerInfo)->peerMac[5] ) ;
730
731
732 //pMac->hal.pCBackFnTxComp = NULL ;
733
734 psessionEntry = peFindSessionBySessionId(pMac, (peerInfo)->tdls_sessionId);
735
736 if(NULL == psessionEntry)
737 {
738 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
739 ("limTdlsTeardownTxComplete: sessionID %d is not found\n"), (peerInfo)->tdls_sessionId);
740 VOS_ASSERT(0) ;
741 return eHAL_STATUS_FAILURE;
742 }
743
744 if(!txCompleteSuccess)
745 {
746 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
747 ("TX complete failure for Teardown \n")) ;
748
749 /*
750 * we should be sending Teradown to AP with status code
751 * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, we are not worried if
752 * that is delivered or not, any way we removing this peer STA from our
753 * list
754 */
755 if(NULL != psessionEntry)
756 {
757 limSendTdlsTeardownFrame(pMac, (peerInfo)->peerMac,
758 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, psessionEntry, NULL, 0) ;
759 }
760 }
761
762 if(TDLS_LINK_SETUP_WAIT_STATE != (peerInfo)->tdls_prev_link_state)
763 {
764 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
765 (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ;
766 /* send del STA to remove context for this TDLS STA */
767 if(NULL != psessionEntry)
768 {
769 /* tdls_hklee: send message to HAL before it is deleted */
770 limTdlsLinkTeardown(pMac, (peerInfo)->peerMac) ;
771
772 pStaDs = limTdlsDelSta(pMac, (peerInfo)->peerMac, psessionEntry) ;
773 }
774
775 /* now send indication to SME-->HDD->TL to remove STA from TL */
776 if(!pStaDs)
777 {
778 VOS_ASSERT(0) ;
779 return eSIR_FAILURE ;
780 }
781 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
782 pStaDs, eSIR_SUCCESS) ;
783
784 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
785 ("TX complete SUCCESS for Teardown\n")) ;
786 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
787 ("Prev State = %d\n"), (peerInfo)->tdls_prev_link_state) ;
788 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
789 eWNI_SME_TDLS_TEARDOWN_RSP) ;
790 /* Delete Peer for Link Peer List */
791 limTdlsDelLinkPeer(pMac, (peerInfo)->peerMac) ;
792 }
793 else
794 {
795 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
796 (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ;
797 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
798 eWNI_SME_TDLS_TEARDOWN_IND) ;
799 }
800
801
802#if 0
803 /* if previous state is link restart, then restart link setup again */
804 if(TDLS_LINK_SETUP_RESTART_STATE == (peerInfo)->tdls_prev_link_state)
805 {
806 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
807 limTdlsPrepareSetupReqFrame(pMac, setupInfo, 37,
808 peerMac, psessionEntry) ;
809 }
810#endif
811 status = eHAL_STATUS_SUCCESS ;
812#endif
813 return status ;
814}
815
816/*
817 * Send TDLS discovery response frame on direct link.
818 */
819
820static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac,
821 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry)
822{
823 tDot11fTDLSDisRsp tdlsDisRsp ;
824 tANI_U16 caps = 0 ;
825 tANI_U32 status = 0 ;
826 tANI_U32 nPayload = 0 ;
827 tANI_U32 nBytes = 0 ;
828 tANI_U8 *pFrame;
829 void *pPacket;
830 eHalStatus halstatus;
831
832 /*
833 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
834 * and then hand it off to 'dot11fPackProbeRequest' (for
835 * serialization). We start by zero-initializing the structure:
836 */
837 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisRsp,
838 sizeof( tDot11fTDLSDisRsp ) );
839
840 /*
841 * setup Fixed fields,
842 */
843 tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
844 tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP ;
845 tdlsDisRsp.DialogToken.token = dialog ;
846
847 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisRsp.LinkIdentifier,
848 peerMac, TDLS_RESPONDER) ;
849
850 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
851 {
852 /*
853 * Could not get Capabilities value
854 * from CFG. Log error.
855 */
856 limLog(pMac, LOGP,
857 FL("could not retrieve Capabilities value\n"));
858 }
859 swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities );
860
861 /* populate supported rate IE */
862 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
863 &tdlsDisRsp.SuppRates, psessionEntry );
864
865 /* Populate extended supported rates */
866 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
867 &tdlsDisRsp.ExtSuppRates, psessionEntry );
868
869 /* Populate extended supported rates */
870 PopulateDot11fTdlsExtCapability( pMac, &tdlsDisRsp.ExtCap );
871
872 /* Include HT Capability IE */
873 //This does not depend on peer capabilities. If it is supported then it should be included
874 PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsDisRsp.HTCaps );
875
876 /*
877 * now we pack it. First, how much space are we going to need?
878 */
879 status = dot11fGetPackedTDLSDisRspSize( pMac, &tdlsDisRsp, &nPayload);
880 if ( DOT11F_FAILED( status ) )
881 {
882 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
883 "or a discovery Request (0x%08x).\n"), status );
884 /* We'll fall back on the worst case scenario: */
885 nPayload = sizeof( tDot11fProbeRequest );
886 }
887 else if ( DOT11F_WARNED( status ) )
888 {
889 limLog( pMac, LOGW, FL("There were warnings while calculating"
890 "the packed size for a discovery Request ("
891 "0x%08x).\n"), status );
892 }
893
894 /*
895 * This frame is going out from PE as data frames with special ethertype
896 * 89-0d.
897 * 8 bytes of RFC 1042 header
898 */
899
900
901 nBytes = nPayload + sizeof( tSirMacMgmtHdr ) ;
902
903 /* Ok-- try to allocate memory from MGMT PKT pool */
904
905 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
906 ( tANI_U16 )nBytes, ( void** ) &pFrame,
907 ( void** ) &pPacket );
908 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
909 {
910 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
911 "Discovery Request.\n"), nBytes );
912 return eSIR_MEM_ALLOC_FAILED;
913 }
914
915 /* zero out the memory */
916 palZeroMemory( pMac->hHdd, pFrame, nBytes );
917
918 /*
919 * IE formation, memory allocation is completed, Now form TDLS discovery
920 * response frame
921 */
922
923 /* Make public Action Frame */
924
925#if 0
926 limPreparesActionFrameHdr(pMac, pFrame, SIR_MAC_MGMT_FRAME,
927 SIR_MAC_MGMT_ACTION,
928 LINK_IDEN_ADDR_OFFSET(tdlsDisRsp)) ;
929#endif
930 limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
931 SIR_MAC_MGMT_ACTION, peerMac, psessionEntry->selfMacAddr);
932
933 {
934 tpSirMacMgmtHdr pMacHdr;
935 pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
936 pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
937 pMacHdr->fc.powerMgmt = 0 ;
938 sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
939 }
940
941#ifdef FEATURE_WLAN_TDLS_NEGATIVE
942 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_RSP)
943 {
944 tdlsDisRsp.LinkIdentifier.bssid[4] = 0xde;
945 tdlsDisRsp.LinkIdentifier.bssid[5] = 0xad;
946 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
947 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Rsp\n"), \
948 tdlsDisRsp.LinkIdentifier.bssid[0],
949 tdlsDisRsp.LinkIdentifier.bssid[1],
950 tdlsDisRsp.LinkIdentifier.bssid[2],
951 tdlsDisRsp.LinkIdentifier.bssid[3],
952 tdlsDisRsp.LinkIdentifier.bssid[4],
953 tdlsDisRsp.LinkIdentifier.bssid[5]);
954 }
955#endif
956 status = dot11fPackTDLSDisRsp( pMac, &tdlsDisRsp, pFrame +
957 sizeof( tSirMacMgmtHdr ),
958 nPayload, &nPayload );
959
960 if ( DOT11F_FAILED( status ) )
961 {
962 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
963 (0x%08x).\n"), status );
964 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
965 ( void* ) pFrame, ( void* ) pPacket );
966 return eSIR_FAILURE;
967 }
968 else if ( DOT11F_WARNED( status ) )
969 {
970 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
971 "Discovery Request (0x%08x).\n") );
972 }
973
974#if 0
975 if(pMac->hal.pCBackFnTxComp == NULL)
976 {
977 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsDisRspTxComplete;
978
979 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
980 {
981 status = eHAL_STATUS_FAILURE;
982 return status;
983
984 }
985 }
986#endif
987 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
988 ("transmitting Discovery response on direct link\n")) ;
989
990 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
991 SIR_MAC_TDLS_DIS_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_RSP) ));
992
993
994 /*
995 * Transmit Discovery response and watch if this is delivered to
996 * peer STA.
997 */
998 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
999 HAL_TXRX_FRM_802_11_DATA,
1000 ANI_TXDIR_IBSS,
1001 0,
1002 limTxComplete, pFrame,
1003 limTdlsDisRspTxComplete,
1004 HAL_USE_SELF_STA_REQUESTED_MASK );
1005 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1006 {
1007 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1008 return eSIR_FAILURE;
1009
1010 }
1011
1012 return eSIR_SUCCESS;
1013
1014}
1015
1016/*
1017 * TDLS setup Request frame on AP link
1018 */
1019
1020tSirRetStatus limSendTdlsLinkSetupReqFrame(tpAniSirGlobal pMac,
1021 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry,
1022 tANI_U8 *addIe, tANI_U16 addIeLen)
1023{
1024 tDot11fTDLSSetupReq tdlsSetupReq ;
1025 tANI_U16 caps = 0 ;
1026 tANI_U32 status = 0 ;
1027 tANI_U32 nPayload = 0 ;
1028 tANI_U32 nBytes = 0 ;
1029 tANI_U32 header_offset = 0 ;
1030 tANI_U8 *pFrame;
1031 void *pPacket;
1032 eHalStatus halstatus;
1033
1034 /*
1035 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1036 * and then hand it off to 'dot11fPackProbeRequest' (for
1037 * serialization). We start by zero-initializing the structure:
1038 */
1039 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupReq,
1040 sizeof( tDot11fTDLSSetupReq ) );
1041 tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS ;
1042 tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ ;
1043 tdlsSetupReq.DialogToken.token = dialog ;
1044
1045
1046 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupReq.LinkIdentifier,
1047 peerMac, TDLS_INITIATOR) ;
1048
1049 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
1050 {
1051 /*
1052 * Could not get Capabilities value
1053 * from CFG. Log error.
1054 */
1055 limLog(pMac, LOGP,
1056 FL("could not retrieve Capabilities value\n"));
1057 }
1058 swapBitField16(caps, ( tANI_U16* )&tdlsSetupReq.Capabilities );
1059
1060 /* populate supported rate IE */
1061 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1062 &tdlsSetupReq.SuppRates, psessionEntry );
1063
1064 /* Populate extended supported rates */
1065 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1066 &tdlsSetupReq.ExtSuppRates, psessionEntry );
1067
1068 /* Populate extended supported rates */
1069 PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupReq.ExtCap );
1070
1071 /*
1072 * TODO: we need to see if we have to support conditions where we have
1073 * EDCA parameter info element is needed a) if we need different QOS
1074 * parameters for off channel operations or QOS is not supported on
1075 * AP link and we wanted to QOS on direct link.
1076 */
1077 /* Populate QOS info, needed for Peer U-APSD session */
1078 /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and
1079 TDLS doesn't want to depend on AP's capability */
1080 tdlsSetupReq.QOSCapsStation.present = 1;
1081 tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
1082 tdlsSetupReq.QOSCapsStation.qack = 0;
1083 tdlsSetupReq.QOSCapsStation.acbe_uapsd = 0;
1084 tdlsSetupReq.QOSCapsStation.acbk_uapsd = 0;
1085 tdlsSetupReq.QOSCapsStation.acvi_uapsd = 0;
1086 tdlsSetupReq.QOSCapsStation.acvo_uapsd = 0;
1087
1088
1089 /*
1090 * we will always try to init TDLS link with 11n capabilities
1091 * let TDLS setup response to come, and we will set our caps based
1092 * of peer caps
1093 */
1094
1095 /* Include HT Capability IE */
1096 PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsSetupReq.HTCaps );
1097
1098 /*
1099 * now we pack it. First, how much space are we going to need?
1100 */
1101 status = dot11fGetPackedTDLSSetupReqSize( pMac, &tdlsSetupReq,
1102 &nPayload);
1103 if ( DOT11F_FAILED( status ) )
1104 {
1105 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1106 "or a discovery Request (0x%08x).\n"), status );
1107 /* We'll fall back on the worst case scenario: */
1108 nPayload = sizeof( tDot11fProbeRequest );
1109 }
1110 else if ( DOT11F_WARNED( status ) )
1111 {
1112 limLog( pMac, LOGW, FL("There were warnings while calculating"
1113 "the packed size for a discovery Request ("
1114 "0x%08x).\n"), status );
1115 }
1116
1117
1118 /*
1119 * This frame is going out from PE as data frames with special ethertype
1120 * 89-0d.
1121 * 8 bytes of RFC 1042 header
1122 */
1123
1124
1125 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1126 + sizeof( eth_890d_header )
1127 + PAYLOAD_TYPE_TDLS_SIZE
1128 + addIeLen;
1129
1130 /* Ok-- try to allocate memory from MGMT PKT pool */
1131
1132 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1133 ( tANI_U16 )nBytes , ( void** ) &pFrame,
1134 ( void** ) &pPacket );
1135 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1136 {
1137 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1138 "Discovery Request.\n"), nBytes );
1139 return eSIR_MEM_ALLOC_FAILED;
1140 }
1141
1142 /* zero out the memory */
1143 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1144
1145 /*
1146 * IE formation, memory allocation is completed, Now form TDLS discovery
1147 * request frame
1148 */
1149
1150 /* fill out the buffer descriptor */
1151
1152 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1153 LINK_IDEN_ADDR_OFFSET(tdlsSetupReq), TDLS_LINK_AP, TDLS_INITIATOR, psessionEntry) ;
1154
1155#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1156 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_REQ)
1157 {
1158 tdlsSetupReq.LinkIdentifier.bssid[4] = 0xde;
1159 tdlsSetupReq.LinkIdentifier.bssid[5] = 0xad;
1160 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1161 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Req\n"), \
1162 tdlsSetupReq.LinkIdentifier.bssid[0],
1163 tdlsSetupReq.LinkIdentifier.bssid[1],
1164 tdlsSetupReq.LinkIdentifier.bssid[2],
1165 tdlsSetupReq.LinkIdentifier.bssid[3],
1166 tdlsSetupReq.LinkIdentifier.bssid[4],
1167 tdlsSetupReq.LinkIdentifier.bssid[5]);
1168 }
1169#endif
1170 status = dot11fPackTDLSSetupReq( pMac, &tdlsSetupReq, pFrame
1171 + header_offset, nPayload, &nPayload );
1172
1173 if ( DOT11F_FAILED( status ) )
1174 {
1175 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1176 (0x%08x).\n"), status );
1177 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1178 ( void* ) pFrame, ( void* ) pPacket );
1179 return eSIR_FAILURE;
1180 }
1181 else if ( DOT11F_WARNED( status ) )
1182 {
1183 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1184 "Discovery Request (0x%08x).\n") );
1185 }
1186
1187 //Copy the additional IE.
1188 //TODO : addIe is added at the end of the frame. This means it doesnt
1189 //follow the order. This should be ok, but we should consider changing this
1190 //if there is any IOT issue.
1191 if( addIeLen != 0 )
1192 {
1193 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
1194 addIeLen ));
1195 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1196 }
1197
1198 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
1199 SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) ));
1200
1201 halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
1202 HAL_TXRX_FRM_802_11_DATA,
1203 ANI_TXDIR_TODS,
1204 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
1205 limTxComplete, pFrame, 0 );
1206 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1207 {
1208 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1209 return eSIR_FAILURE;
1210
1211 }
1212
1213 return eSIR_SUCCESS;
1214
1215}
1216/*
1217 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1218 */
1219
1220tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac,
1221 tSirMacAddr peerMac, tANI_U16 reason, tpPESession psessionEntry,
1222 tANI_U8 *addIe, tANI_U16 addIeLen)
1223{
1224 tDot11fTDLSTeardown teardown ;
1225 tANI_U32 status = 0 ;
1226 tANI_U32 nPayload = 0 ;
1227 tANI_U32 nBytes = 0 ;
1228 tANI_U32 header_offset = 0 ;
1229 tANI_U8 *pFrame;
1230 void *pPacket;
1231 eHalStatus halstatus;
1232
1233 /*
1234 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1235 * and then hand it off to 'dot11fPackProbeRequest' (for
1236 * serialization). We start by zero-initializing the structure:
1237 */
1238 palZeroMemory( pMac->hHdd, ( tANI_U8* )&teardown,
1239 sizeof( tDot11fTDLSTeardown ) );
1240 teardown.Category.category = SIR_MAC_ACTION_TDLS ;
1241 teardown.Action.action = SIR_MAC_TDLS_TEARDOWN ;
1242 teardown.Reason.code = reason ;
1243
1244 PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier,
1245 peerMac, TDLS_INITIATOR) ;
1246
1247
1248 /*
1249 * now we pack it. First, how much space are we going to need?
1250 */
1251 status = dot11fGetPackedTDLSTeardownSize( pMac, &teardown, &nPayload);
1252 if ( DOT11F_FAILED( status ) )
1253 {
1254 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1255 "or a discovery Request (0x%08x).\n"), status );
1256 /* We'll fall back on the worst case scenario: */
1257 nPayload = sizeof( tDot11fProbeRequest );
1258 }
1259 else if ( DOT11F_WARNED( status ) )
1260 {
1261 limLog( pMac, LOGW, FL("There were warnings while calculating"
1262 "the packed size for a discovery Request ("
1263 "0x%08x).\n"), status );
1264 }
1265
1266
1267 /*
1268 * This frame is going out from PE as data frames with special ethertype
1269 * 89-0d.
1270 * 8 bytes of RFC 1042 header
1271 */
1272
1273
1274 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1275 + sizeof( eth_890d_header )
1276 + PAYLOAD_TYPE_TDLS_SIZE
1277 + addIeLen;
1278
1279 /* Ok-- try to allocate memory from MGMT PKT pool */
1280
1281 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1282 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1283 ( void** ) &pPacket );
1284 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1285 {
1286 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1287 "Discovery Request.\n"), nBytes );
1288 return eSIR_MEM_ALLOC_FAILED;
1289 }
1290
1291 /* zero out the memory */
1292 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1293
1294 /*
1295 * IE formation, memory allocation is completed, Now form TDLS discovery
1296 * request frame
1297 */
1298
1299 /* fill out the buffer descriptor */
1300
1301 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1302 LINK_IDEN_ADDR_OFFSET(teardown),
1303 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
1304 ? TDLS_LINK_AP : TDLS_LINK_DIRECT, TDLS_INITIATOR,
1305 psessionEntry) ;
1306
1307 status = dot11fPackTDLSTeardown( pMac, &teardown, pFrame
1308 + header_offset, nPayload, &nPayload );
1309
1310 if ( DOT11F_FAILED( status ) )
1311 {
1312 limLog( pMac, LOGE, FL("Failed to pack a TDLS Teardown req \
1313 (0x%08x).\n"), status );
1314 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1315 ( void* ) pFrame, ( void* ) pPacket );
1316 return eSIR_FAILURE;
1317 }
1318 else if ( DOT11F_WARNED( status ) )
1319 {
1320 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1321 "Teardown Request (0x%08x).\n") );
1322 }
1323#if 0
1324 if(pMac->hal.pCBackFnTxComp == NULL)
1325 {
1326 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsTeardownTxComplete;
1327 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
1328 {
1329 status = eHAL_STATUS_FAILURE;
1330 return status;
1331
1332 }
1333 }
1334 else
1335 {
1336 VOS_ASSERT(0) ;
1337 return status ;
1338 }
1339#endif
1340
1341 if( addIeLen != 0 )
1342 {
1343 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
1344 addIeLen ));
1345 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1346 }
1347
1348 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
1349 SIR_MAC_TDLS_TEARDOWN, limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN) ));
1350
1351 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
1352 HAL_TXRX_FRM_802_11_DATA,
1353 ANI_TXDIR_TODS,
1354 7,
1355 limTxComplete, pFrame,
1356 limTdlsTeardownTxComplete,
1357 0 );
1358 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1359 {
1360 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1361 return eSIR_FAILURE;
1362
1363 }
1364 return eSIR_SUCCESS;
1365
1366}
1367
1368/*
1369 * Send Setup RSP frame on AP link.
1370 */
1371static tSirRetStatus limSendTdlsSetupRspFrame(tpAniSirGlobal pMac,
1372 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry,
1373 etdlsLinkSetupStatus setupStatus, tANI_U8 *addIe, tANI_U16 addIeLen )
1374{
1375 tDot11fTDLSSetupRsp tdlsSetupRsp ;
1376 tANI_U32 status = 0 ;
1377 tANI_U16 caps = 0 ;
1378 tANI_U32 nPayload = 0 ;
1379 tANI_U32 header_offset = 0 ;
1380 tANI_U32 nBytes = 0 ;
1381 tANI_U8 *pFrame;
1382 void *pPacket;
1383 eHalStatus halstatus;
1384
1385 /*
1386 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1387 * and then hand it off to 'dot11fPackProbeRequest' (for
1388 * serialization). We start by zero-initializing the structure:
1389 */
1390 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupRsp,
1391 sizeof( tDot11fTDLSSetupRsp ) );
1392
1393 /*
1394 * setup Fixed fields,
1395 */
1396 tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
1397 tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP ;
1398 tdlsSetupRsp.DialogToken.token = dialog;
1399
1400 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupRsp.LinkIdentifier,
1401 peerMac, TDLS_RESPONDER) ;
1402
1403 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
1404 {
1405 /*
1406 * Could not get Capabilities value
1407 * from CFG. Log error.
1408 */
1409 limLog(pMac, LOGP,
1410 FL("could not retrieve Capabilities value\n"));
1411 }
1412 swapBitField16(caps, ( tANI_U16* )&tdlsSetupRsp.Capabilities );
1413
1414 /* ipopulate supported rate IE */
1415 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1416 &tdlsSetupRsp.SuppRates, psessionEntry );
1417
1418 /* Populate extended supported rates */
1419 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1420 &tdlsSetupRsp.ExtSuppRates, psessionEntry );
1421
1422 /* Populate extended supported rates */
1423 PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupRsp.ExtCap );
1424
1425 /*
1426 * TODO: we need to see if we have to support conditions where we have
1427 * EDCA parameter info element is needed a) if we need different QOS
1428 * parameters for off channel operations or QOS is not supported on
1429 * AP link and we wanted to QOS on direct link.
1430 */
1431 /* Populate QOS info, needed for Peer U-APSD session */
1432 /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and
1433 TDLS doesn't want to depend on AP's capability */
1434 tdlsSetupRsp.QOSCapsStation.present = 1;
1435 tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
1436 tdlsSetupRsp.QOSCapsStation.qack = 0;
1437 tdlsSetupRsp.QOSCapsStation.acbe_uapsd = 1;
1438 tdlsSetupRsp.QOSCapsStation.acbk_uapsd = 1;
1439 tdlsSetupRsp.QOSCapsStation.acvi_uapsd = 1;
1440 tdlsSetupRsp.QOSCapsStation.acvo_uapsd = 1;
1441
1442 /* Include HT Info IE */
1443// if ( setupReq->HTCaps.present)
1444// {
1445 PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsSetupRsp.HTCaps );
1446// }
1447
1448 tdlsSetupRsp.Status.status = setupStatus ;
1449
1450 /*
1451 * now we pack it. First, how much space are we going to need?
1452 */
1453 status = dot11fGetPackedTDLSSetupRspSize( pMac, &tdlsSetupRsp,
1454 &nPayload);
1455 if ( DOT11F_FAILED( status ) )
1456 {
1457 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1458 "or a discovery Request (0x%08x).\n"), status );
1459 /* We'll fall back on the worst case scenario: */
1460 nPayload = sizeof( tDot11fProbeRequest );
1461 }
1462 else if ( DOT11F_WARNED( status ) )
1463 {
1464 limLog( pMac, LOGW, FL("There were warnings while calculating"
1465 "the packed size for a discovery Request ("
1466 "0x%08x).\n"), status );
1467 }
1468
1469 /*
1470 * This frame is going out from PE as data frames with special ethertype
1471 * 89-0d.
1472 * 8 bytes of RFC 1042 header
1473 */
1474
1475
1476 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1477 + sizeof( eth_890d_header )
1478 + PAYLOAD_TYPE_TDLS_SIZE
1479 + addIeLen;
1480
1481 /* Ok-- try to allocate memory from MGMT PKT pool */
1482
1483 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1484 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1485 ( void** ) &pPacket );
1486 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1487 {
1488 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1489 "Discovery Request.\n"), nBytes );
1490 return eSIR_MEM_ALLOC_FAILED;
1491 }
1492
1493 /* zero out the memory */
1494 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1495
1496 /*
1497 * IE formation, memory allocation is completed, Now form TDLS discovery
1498 * request frame
1499 */
1500
1501 /* fill out the buffer descriptor */
1502
1503 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1504 LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp),
1505 TDLS_LINK_AP, TDLS_RESPONDER,
1506 psessionEntry) ;
1507
1508#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1509 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_RSP)
1510 {
1511 tdlsSetupRsp.LinkIdentifier.bssid[4] = 0xde;
1512 tdlsSetupRsp.LinkIdentifier.bssid[5] = 0xad;
1513 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1514 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Rsp\n"), \
1515 tdlsSetupRsp.LinkIdentifier.bssid[0],
1516 tdlsSetupRsp.LinkIdentifier.bssid[1],
1517 tdlsSetupRsp.LinkIdentifier.bssid[2],
1518 tdlsSetupRsp.LinkIdentifier.bssid[3],
1519 tdlsSetupRsp.LinkIdentifier.bssid[4],
1520 tdlsSetupRsp.LinkIdentifier.bssid[5]);
1521 }
1522#endif
1523 status = dot11fPackTDLSSetupRsp( pMac, &tdlsSetupRsp, pFrame
1524 + header_offset, nPayload, &nPayload );
1525
1526 if ( DOT11F_FAILED( status ) )
1527 {
1528 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1529 (0x%08x).\n"), status );
1530 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1531 ( void* ) pFrame, ( void* ) pPacket );
1532 return eSIR_FAILURE;
1533 }
1534 else if ( DOT11F_WARNED( status ) )
1535 {
1536 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1537 "Discovery Request (0x%08x).\n") );
1538 }
1539
1540 //Copy the additional IE.
1541 //TODO : addIe is added at the end of the frame. This means it doesnt
1542 //follow the order. This should be ok, but we should consider changing this
1543 //if there is any IOT issue.
1544 if( addIeLen != 0 )
1545 {
1546 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1547 }
1548
1549 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
1550 SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) ));
1551
1552 halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes,
1553 HAL_TXRX_FRM_802_11_DATA,
1554 ANI_TXDIR_TODS,
1555 //ANI_TXDIR_IBSS,
1556 7,
1557 limTxComplete, pFrame, 0 );
1558 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1559 {
1560 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1561 return eSIR_FAILURE;
1562
1563 }
1564
1565 return eSIR_SUCCESS;
1566
1567}
1568
1569/*
1570 * Send TDLS setup CNF frame on AP link
1571 */
1572
1573tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, tSirMacAddr peerMac,
1574 tANI_U8 dialog, tpPESession psessionEntry, tANI_U8* addIe, tANI_U16 addIeLen)
1575{
1576 tDot11fTDLSSetupCnf tdlsSetupCnf ;
1577 tANI_U32 status = 0 ;
1578 tANI_U32 nPayload = 0 ;
1579 tANI_U32 nBytes = 0 ;
1580 tANI_U32 header_offset = 0 ;
1581 tANI_U8 *pFrame;
1582 void *pPacket;
1583 eHalStatus halstatus;
1584
1585 /*
1586 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1587 * and then hand it off to 'dot11fPackProbeRequest' (for
1588 * serialization). We start by zero-initializing the structure:
1589 */
1590 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupCnf,
1591 sizeof( tDot11fTDLSSetupCnf ) );
1592
1593 /*
1594 * setup Fixed fields,
1595 */
1596 tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
1597 tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF ;
1598 tdlsSetupCnf.DialogToken.token = dialog ;
1599
1600#if 1
1601 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupCnf.LinkIdentifier,
1602 peerMac, TDLS_INITIATOR) ;
1603#else
1604 palCopyMemory( pMac->hHdd, (tANI_U8 *)&tdlsSetupCnf.LinkIdentifier,
1605 (tANI_U8 *)&setupRsp->LinkIdentifier, sizeof(tDot11fIELinkIdentifier)) ;
1606#endif
1607
1608 /*
1609 * TODO: we need to see if we have to support conditions where we have
1610 * EDCA parameter info element is needed a) if we need different QOS
1611 * parameters for off channel operations or QOS is not supported on
1612 * AP link and we wanted to QOS on direct link.
1613 */
1614
1615 /* Include HT Info IE */
1616 //if ( tdlsSetupCnf.HTCaps.present)
1617 //{
1618 // PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry );
1619 // }
1620
1621 /*
1622 * now we pack it. First, how much space are we going to need?
1623 */
1624 status = dot11fGetPackedTDLSSetupCnfSize( pMac, &tdlsSetupCnf,
1625 &nPayload);
1626 if ( DOT11F_FAILED( status ) )
1627 {
1628 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1629 "or a discovery Request (0x%08x).\n"), status );
1630 /* We'll fall back on the worst case scenario: */
1631 nPayload = sizeof( tDot11fProbeRequest );
1632 }
1633 else if ( DOT11F_WARNED( status ) )
1634 {
1635 limLog( pMac, LOGW, FL("There were warnings while calculating"
1636 "the packed size for a discovery Request ("
1637 "0x%08x).\n"), status );
1638 }
1639
1640 /*
1641 * This frame is going out from PE as data frames with special ethertype
1642 * 89-0d.
1643 * 8 bytes of RFC 1042 header
1644 */
1645
1646
1647 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1648 + sizeof( eth_890d_header )
1649 + PAYLOAD_TYPE_TDLS_SIZE
1650 + addIeLen;
1651
1652 /* Ok-- try to allocate memory from MGMT PKT pool */
1653
1654 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1655 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1656 ( void** ) &pPacket );
1657 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1658 {
1659 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1660 "Discovery Request.\n"), nBytes );
1661 return eSIR_MEM_ALLOC_FAILED;
1662 }
1663
1664 /* zero out the memory */
1665 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1666
1667 /*
1668 * IE formation, memory allocation is completed, Now form TDLS discovery
1669 * request frame
1670 */
1671
1672 /* fill out the buffer descriptor */
1673
1674 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1675 LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf), TDLS_LINK_AP, TDLS_INITIATOR,
1676 psessionEntry) ;
1677
1678#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1679 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_STATUS_37_IN_SETUP_CNF) {
1680 tdlsSetupCnf.StatusCode.statusCode = 37;
1681 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1682 ("TDLS negative running: StatusCode = 37 in TDLS Setup Cnf\n"));
1683 }
1684#endif
1685 status = dot11fPackTDLSSetupCnf( pMac, &tdlsSetupCnf, pFrame
1686 + header_offset, nPayload, &nPayload );
1687
1688 if ( DOT11F_FAILED( status ) )
1689 {
1690 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1691 (0x%08x).\n"), status );
1692 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1693 ( void* ) pFrame, ( void* ) pPacket );
1694 return eSIR_FAILURE;
1695 }
1696 else if ( DOT11F_WARNED( status ) )
1697 {
1698 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1699 "Discovery Request (0x%08x).\n") );
1700 }
1701#if 0
1702 if(pMac->hal.pCBackFnTxComp == NULL)
1703 {
1704 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsSetupCnfTxComplete;
1705 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
1706 {
1707 status = eHAL_STATUS_FAILURE;
1708 return status;
1709
1710 }
1711 }
1712 else
1713 {
1714 VOS_ASSERT(0) ;
1715 return status ;
1716 }
1717#endif
1718 //Copy the additional IE.
1719 //TODO : addIe is added at the end of the frame. This means it doesnt
1720 //follow the order. This should be ok, but we should consider changing this
1721 //if there is any IOT issue.
1722 if( addIeLen != 0 )
1723 {
1724 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1725 }
1726
1727 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Send TDLS action %d (%s)"),
1728 SIR_MAC_TDLS_SETUP_CNF, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_CNF) ));
1729
1730 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
1731 HAL_TXRX_FRM_802_11_DATA,
1732 ANI_TXDIR_TODS,
1733 7,
1734 limTxComplete, pFrame,
1735 limTdlsSetupCnfTxComplete,
1736 0 );
1737
1738
1739 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1740 {
1741 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1742 return eSIR_FAILURE;
1743
1744 }
1745
1746 return eSIR_SUCCESS;
1747}
1748
1749#ifdef FEATURE_WLAN_TDLS_INTERNAL
1750/*
1751 * Convert HT caps to lim based HT caps
1752 */
1753static void limTdlsCovertHTCaps(tpAniSirGlobal pMac ,
1754 tSirTdlsPeerInfo *peerInfo, tDot11fIEHTCaps *HTCaps)
1755{
1756
1757 /* HT Capability Info */
1758 peerInfo->tdlsPeerHtCaps.advCodingCap = HTCaps->advCodingCap ;
1759 peerInfo->tdlsPeerHtCaps.supportedChannelWidthSet =
1760 HTCaps->supportedChannelWidthSet ;
1761 peerInfo->tdlsPeerHtCaps.mimoPowerSave = HTCaps->mimoPowerSave ;
1762 peerInfo->tdlsPeerHtCaps.greenField = HTCaps->greenField ;
1763 peerInfo->tdlsPeerHtCaps.shortGI20MHz = HTCaps->shortGI20MHz ;
1764 peerInfo->tdlsPeerHtCaps.shortGI40MHz = HTCaps->shortGI40MHz ;
1765 peerInfo->tdlsPeerHtCaps.txSTBC = HTCaps->txSTBC ;
1766 peerInfo->tdlsPeerHtCaps.rxSTBC = HTCaps->rxSTBC ;
1767 peerInfo->tdlsPeerHtCaps.delayedBA = HTCaps->delayedBA;
1768 peerInfo->tdlsPeerHtCaps.maximalAMSDUsize = HTCaps->maximalAMSDUsize ;
1769 peerInfo->tdlsPeerHtCaps.dsssCckMode40MHz = HTCaps->dsssCckMode40MHz ;
1770 peerInfo->tdlsPeerHtCaps.psmp = HTCaps->stbcControlFrame ;
1771 peerInfo->tdlsPeerHtCaps.stbcControlFrame = HTCaps->stbcControlFrame ;
1772 peerInfo->tdlsPeerHtCaps.lsigTXOPProtection =
1773 HTCaps->lsigTXOPProtection ;
1774
1775 /* HT Capa parameters */
1776 peerInfo->tdlsPeerHtParams.maxRxAMPDUFactor = HTCaps->maxRxAMPDUFactor ;
1777 peerInfo->tdlsPeerHtParams.mpduDensity = HTCaps->mpduDensity ;
1778 peerInfo->tdlsPeerHtParams.reserved = HTCaps->reserved1 ;
1779
1780 /* Extended HT caps */
1781 peerInfo->tdlsPeerHtExtCaps.pco = HTCaps->pco ;
1782 peerInfo->tdlsPeerHtExtCaps.transitionTime = HTCaps->transitionTime ;
1783 peerInfo->tdlsPeerHtExtCaps.mcsFeedback = HTCaps->mcsFeedback ;
1784 palCopyMemory(pMac->hHdd, peerInfo->supportedMCSSet,
1785 HTCaps->supportedMCSSet, SIZE_OF_SUPPORTED_MCS_SET) ;
1786
1787 return ;
1788}
1789
1790/*
1791 * update capability info..
1792 */
1793void tdlsUpdateCapInfo(tSirMacCapabilityInfo *capabilityInfo,
1794 tDot11fFfCapabilities *Capabilities)
1795{
1796
1797 capabilityInfo->ess = Capabilities->ess;
1798 capabilityInfo->ibss = Capabilities->ibss;
1799 capabilityInfo->cfPollable = Capabilities->cfPollable;
1800 capabilityInfo->cfPollReq = Capabilities->cfPollReq;
1801 capabilityInfo->privacy = Capabilities->privacy;
1802 capabilityInfo->shortPreamble = Capabilities->shortPreamble;
1803 capabilityInfo->pbcc = Capabilities->pbcc;
1804 capabilityInfo->channelAgility = Capabilities->channelAgility;
1805 capabilityInfo->spectrumMgt = Capabilities->spectrumMgt;
1806 capabilityInfo->qos = Capabilities->qos;
1807 capabilityInfo->shortSlotTime = Capabilities->shortSlotTime;
1808 capabilityInfo->apsd = Capabilities->apsd;
1809 capabilityInfo->rrm = Capabilities->rrm;
1810 capabilityInfo->dsssOfdm = Capabilities->dsssOfdm;
1811 capabilityInfo->immediateBA = Capabilities->immediateBA;
1812
1813 return ;
1814}
1815
1816/*
1817 * update Peer info from the link request frame recieved from Peer..
1818 * in list of STA participating in TDLS link setup
1819 */
1820void limTdlsUpdateLinkReqPeerInfo(tpAniSirGlobal pMac,
1821 tLimTdlsLinkSetupPeer *setupPeer,
1822 tDot11fTDLSSetupReq *setupReq)
1823{
1824
1825 /* Populate peer info of tdls discovery result */
1826
1827 tdlsUpdateCapInfo(&setupPeer->capabilityInfo , &setupReq->Capabilities) ;
1828
1829 if(setupReq->SuppRates.present)
1830 {
1831 ConvertSuppRates( pMac, &setupPeer->supportedRates,
1832 &setupReq->SuppRates );
1833 }
1834
1835 /* update QOS info, needed for Peer U-APSD session */
1836 if(setupReq->QOSCapsStation.present)
1837 {
1838 ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps,
1839 &setupReq->QOSCapsStation) ;
1840 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"), \
1841 setupReq->QOSCapsStation.max_sp_length, setupReq->QOSCapsStation.acbe_uapsd, \
1842 setupReq->QOSCapsStation.acbk_uapsd, setupReq->QOSCapsStation.acvi_uapsd, \
1843 setupReq->QOSCapsStation.acvo_uapsd, setupReq->QOSCapsStation.more_data_ack, \
1844 setupReq->QOSCapsStation.qack));
1845 }
1846
1847 if(setupReq->ExtSuppRates.present)
1848 {
1849 setupPeer->ExtRatesPresent = 1;
1850 ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
1851 &setupReq->ExtSuppRates );
1852 }
1853 /* update HT caps */
1854 if(setupReq->HTCaps.present)
1855 {
1856 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps,
1857 &setupReq->HTCaps, sizeof(tDot11fIEHTCaps)) ;
1858 }
1859 /* Update EXT caps */
1860 if(setupReq->ExtCap.present)
1861 {
1862 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerExtCaps,
1863 &setupReq->ExtCap, sizeof(tDot11fIEExtCap)) ;
1864 }
1865
1866 return ;
1867}
1868
1869/*
1870 * update peer Info recieved with TDLS setup RSP
1871 */
1872void limTdlsUpdateLinkRspPeerInfo(tpAniSirGlobal pMac,
1873 tLimTdlsLinkSetupPeer *setupPeer,
1874 tDot11fTDLSSetupRsp *setupRsp)
1875{
1876
1877 /* Populate peer info of tdls discovery result */
1878 tdlsUpdateCapInfo(&setupPeer->capabilityInfo , &setupRsp->Capabilities) ;
1879
1880 if(setupRsp->SuppRates.present)
1881 {
1882 tDot11fIESuppRates *suppRates = &setupRsp->SuppRates ;
1883 ConvertSuppRates( pMac, &setupPeer->supportedRates, suppRates);
1884 }
1885
1886 /* update QOS info, needed for Peer U-APSD session */
1887 if(setupRsp->QOSCapsStation.present)
1888 {
1889 ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps,
1890 &setupRsp->QOSCapsStation) ;
1891 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"), \
1892 setupRsp->QOSCapsStation.max_sp_length, setupRsp->QOSCapsStation.acbe_uapsd, \
1893 setupRsp->QOSCapsStation.acbk_uapsd, setupRsp->QOSCapsStation.acvi_uapsd, \
1894 setupRsp->QOSCapsStation.acvo_uapsd, setupRsp->QOSCapsStation.more_data_ack, \
1895 setupRsp->QOSCapsStation.qack));
1896 }
1897
1898 if(setupRsp->ExtSuppRates.present)
1899 {
1900 setupPeer->ExtRatesPresent = 1;
1901 ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
1902 &setupRsp->ExtSuppRates );
1903 }
1904 /* update HT caps */
1905 if(setupRsp->HTCaps.present)
1906 {
1907 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps,
1908 &setupRsp->HTCaps, sizeof(tDot11fIEHTCaps)) ;
1909 }
1910
1911 /* update EXT caps */
1912 if(setupRsp->ExtCap.present)
1913 {
1914 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerExtCaps,
1915 &setupRsp->ExtCap, sizeof(tDot11fIEExtCap)) ;
1916 }
1917
1918 return ;
1919}
1920#endif
1921/*
1922 * update HASH node entry info
1923 */
1924static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs,
1925 tLimTdlsLinkSetupPeer *setupPeerInfo, tpPESession psessionEntry)
1926{
1927 //tDot11fIEHTCaps *htCaps = &setupPeerInfo->tdlsPeerHTCaps ;
1928 tDot11fIEHTCaps htCap, *htCaps;
1929 tpDphHashNode pSessStaDs = NULL;
1930 tANI_U16 aid;
1931
1932 //HACK- to get the session's htcaps.
1933 PopulateDot11fHTCaps(pMac, psessionEntry, &htCap);
1934 htCaps = &htCap;
1935 if(htCaps->present)
1936 {
1937 pStaDs->mlmStaContext.htCapability = 1 ;
1938 pStaDs->htGreenfield = htCaps->greenField ;
1939 pStaDs->htSupportedChannelWidthSet = htCaps->supportedChannelWidthSet ;
1940 pStaDs->htMIMOPSState = htCaps->mimoPowerSave ;
1941 pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
1942 pStaDs->htAMpduDensity = htCaps->mpduDensity;
1943 pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz ;
1944 pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
1945 pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
1946 pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
1947 limFillRxHighestSupportedRate(pMac,
1948 &pStaDs->supportedRates.rxHighestDataRate,
1949 htCaps->supportedMCSSet);
1950 pStaDs->baPolicyFlag = 0xFF;
1951
1952 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N ;
1953 }
1954 else
1955 {
1956 pStaDs->mlmStaContext.htCapability = 0 ;
1957 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG ;
1958 }
1959
1960 pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid,
1961 &psessionEntry->dph.dphHashTable) ;
1962
1963 /* Lets enable QOS parameter */
1964 pStaDs->qosMode = 1;
1965 pStaDs->wmeEnabled = 1;
1966 pStaDs->lleEnabled = 0;
1967 pStaDs->qos.capability.qosInfo = pSessStaDs->qos.capability.qosInfo; //setupPeerInfo->qosCaps.qosInfo;
1968
1969 /* populate matching rate set */
1970#if 0
1971#ifdef WLAN_FEATURE_11AC
1972 limPopulateMatchingRateSet(pMac, pStaDs, &setupPeerInfo->supportedRates,
1973 &setupPeerInfo->extendedRates,
1974 (tANI_U8 *)setupPeerInfo->tdlsPeerHTCaps.supportedMCSSet,
1975 &pStaDs->mlmStaContext.propRateSet, psessionEntry, NULL);
1976#else
1977 limPopulateMatchingRateSet(pMac, pStaDs, &setupPeerInfo->supportedRates,
1978 &setupPeerInfo->extendedRates,
1979 (tANI_U8 *)setupPeerInfo->tdlsPeerHTCaps.supportedMCSSet,
1980 &pStaDs->mlmStaContext.propRateSet, psessionEntry);
1981#endif
1982#else
1983 palCopyMemory( pMac->hHdd, &pStaDs->supportedRates, &pSessStaDs->supportedRates, sizeof(pStaDs->supportedRates));
1984#endif
1985
1986 pStaDs->mlmStaContext.capabilityInfo = pSessStaDs->mlmStaContext.capabilityInfo;// setupPeerInfo->capabilityInfo;
1987
1988 return ;
1989}
1990
1991#ifdef FEATURE_WLAN_TDLS_INTERNAL
1992/*
1993 * find Peer in setup link list.
1994 */
1995
1996tANI_U8 limTdlsFindLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac,
1997 tLimTdlsLinkSetupPeer **setupPeer)
1998{
1999 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2000 tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
2001 tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ;
2002
2003 while (linkSetupList != NULL)
2004 {
2005 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2006 (tANI_U8 *) linkSetupList->peerMac,
2007 sizeof(tSirMacAddr)) )
2008 {
2009 checkNode = TDLS_NODE_FOUND ;
2010 *setupPeer = linkSetupList ;
2011 break ;
2012 }
2013 linkSetupList = linkSetupList->next;
2014 }
2015
2016 return ((TDLS_NODE_FOUND == checkNode) ? eSIR_SUCCESS : eSIR_FAILURE ) ;
2017}
2018
2019/*
2020 * find peer in Discovery list.
2021 * Dicovery list get populated in two instances, a) Recieved responses in reply
2022 * to discovery request b) If discover request is received from TDLS peer STA
2023 */
2024tSirTdlsPeerInfo *limTdlsFindDisPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
2025{
2026 tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
2027 tSirTdlsPeerInfo *peerInfo = NULL ;
2028
2029 while (discoveryList != NULL)
2030 {
2031 peerInfo = &discoveryList->tdlsDisPeerInfo ;
2032 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2033 ("Peer in discovery list = %02x, %02x, %02x, %02x, %02x, %02x \n"),
2034 peerInfo->peerMac[0],
2035 peerInfo->peerMac[1],
2036 peerInfo->peerMac[2],
2037 peerInfo->peerMac[3],
2038 peerInfo->peerMac[4],
2039 peerInfo->peerMac[5]) ;
2040
2041 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2042 (tANI_U8 *) &peerInfo->peerMac, sizeof(tSirMacAddr)) )
2043 {
2044 break ;
2045 }
2046 discoveryList = discoveryList->next;
2047 }
2048
2049 return peerInfo ;
2050}
2051
2052/*
2053 * find peer in Discovery list by looking into peer state.
2054 * Dicovery list get populated in two instances, a) Recieved responses in reply
2055 * to discovery request b) If discover request is received from TDLS peer STA
2056 */
2057static tSirTdlsPeerInfo *limTdlsFindDisPeerByState(tpAniSirGlobal pMac,
2058 tANI_U8 state)
2059{
2060 tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
2061 tSirTdlsPeerInfo *peerInfo = NULL ;
2062
2063 while (discoveryList != NULL)
2064 {
2065 peerInfo = &discoveryList->tdlsDisPeerInfo ;
2066 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2067 ("peerInfo Mac = %02x, %02x, %02x, %02x, %02x, %02x "),
2068 peerInfo->peerMac[0],
2069 peerInfo->peerMac[1],
2070 peerInfo->peerMac[2],
2071 peerInfo->peerMac[3],
2072 peerInfo->peerMac[4],
2073 peerInfo->peerMac[5]) ;
2074
2075 if (peerInfo->tdlsPeerState == state)
2076 {
2077 break ;
2078 }
2079 discoveryList = discoveryList->next;
2080 }
2081
2082 return peerInfo ;
2083}
2084
2085/*
2086 * find peer in Setup list by looking into peer state.
2087 * setup list get populated in two instances, a) Recieved responses in reply
2088 * to setup request b) If discover request is received from TDLS peer STA
2089 */
2090static tANI_U8 limTdlsFindSetupPeerByState(tpAniSirGlobal pMac, tANI_U8 state,
2091 tLimTdlsLinkSetupPeer **setupPeer)
2092{
2093
2094 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2095 tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
2096 tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ;
2097
2098 while (linkSetupList != NULL)
2099 {
2100 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2101 ("peer state = %02x\n"), (linkSetupList)->tdls_link_state) ;
2102 if((linkSetupList)->tdls_link_state == state)
2103 {
2104 checkNode = TDLS_NODE_FOUND ;
2105 *setupPeer = linkSetupList ;
2106 break ;
2107 }
2108 linkSetupList = (linkSetupList)->next;
2109 }
2110
2111 return ((TDLS_NODE_FOUND == checkNode) ? eSIR_SUCCESS: eSIR_FAILURE) ;
2112}
2113
2114
2115/*
2116 * delete Peer from Setup Link
2117 */
2118void limTdlsDelLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
2119{
2120 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2121 tLimTdlsLinkSetupPeer **linkSetupList = &setupInfo->tdlsLinkSetupList ;
2122 tLimTdlsLinkSetupPeer *currentNode = NULL ;
2123 tLimTdlsLinkSetupPeer *prevNode = NULL ;
2124
2125 for(currentNode = *linkSetupList ; currentNode != NULL ;
2126 prevNode = currentNode, currentNode = currentNode->next)
2127 {
2128 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2129 (tANI_U8 *) currentNode->peerMac,
2130 sizeof(tSirMacAddr)) )
2131 {
2132 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2133 ("Del Node for Peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
2134 currentNode->peerMac[0],
2135 currentNode->peerMac[1],
2136 currentNode->peerMac[2],
2137 currentNode->peerMac[3],
2138 currentNode->peerMac[4],
2139 currentNode->peerMac[5]) ;
2140 /* if it's first Node */
2141 if(NULL == prevNode)
2142 {
2143 *linkSetupList = currentNode->next ;
2144 }
2145 else
2146 {
2147 prevNode->next = currentNode->next ;
2148 }
2149 palFreeMemory(pMac, currentNode) ;
2150 return ;
2151 }
2152 }
2153
2154 return ;
2155}
2156
2157
2158
2159/*
2160 * TDLS discovery request frame received from TDLS peer STA..
2161 */
2162static tSirRetStatus limProcessTdlsDisReqFrame(tpAniSirGlobal pMac,
2163 tANI_U8 *pBody, tANI_U32 frmLen )
2164{
2165 tDot11fTDLSDisReq tdlsDisReq = {{0}} ;
2166 tANI_U32 status = 0 ;
2167 tLimDisResultList *tdlsDisResult = NULL ;
2168 tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
2169 tSirMacAddr peerMac = {0} ;
2170 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
2171 tSirTdlsPeerInfo *peerInfo = NULL ;
2172 tpPESession psessionEntry = NULL ;
2173 tANI_U8 sessionId = 0 ;
2174
2175 status = dot11fUnpackTDLSDisReq(pMac, pBody, frmLen, &tdlsDisReq) ;
2176
2177 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,
2178 ("TDLS dis request dialog = %d\n"), tdlsDisReq.DialogToken.token);
2179
2180 if ( DOT11F_FAILED( status ) )
2181 {
2182 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
2183 frame (0x%08x, %d bytes):\n"),status, frmLen);
2184 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2185 return eSIR_FAILURE;
2186 }
2187 else if ( DOT11F_WARNED( status ) )
2188 {
2189 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2190 TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
2191 status, frmLen );
2192 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2193 }
2194
2195 /*
2196 * find session entry using BSSID in link identifier, not using MAC
2197 * header beacuse, there is cases in TDLS, there may be BSSID will not
2198 * be present in header
2199 */
2200 psessionEntry = peFindSessionByBssid(pMac,
2201 &tdlsDisReq.LinkIdentifier.bssid[0], &sessionId) ;
2202 if(NULL == psessionEntry)
2203 {
2204 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
2205 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
2206 tdlsDisReq.LinkIdentifier.bssid[0],
2207 tdlsDisReq.LinkIdentifier.bssid[1],
2208 tdlsDisReq.LinkIdentifier.bssid[2],
2209 tdlsDisReq.LinkIdentifier.bssid[3],
2210 tdlsDisReq.LinkIdentifier.bssid[4],
2211 tdlsDisReq.LinkIdentifier.bssid[5]) ;
2212
2213 //VOS_ASSERT(0) ;
2214 return eSIR_FAILURE;
2215 }
2216
2217 /* varify BSSID */
2218 status = palEqualMemory(pMac->hHdd, &psessionEntry->bssId[0],
2219 &tdlsDisReq.LinkIdentifier.bssid[0], sizeof(tSirMacAddr)) ;
2220 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2221 ("lim BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"),
2222 psessionEntry->bssId[0],
2223 psessionEntry->bssId[1],
2224 psessionEntry->bssId[2],
2225 psessionEntry->bssId[3],
2226 psessionEntry->bssId[4],
2227 psessionEntry->bssId[5]) ;
2228
2229 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2230 ("Dis req from BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"),
2231 tdlsDisReq.LinkIdentifier.bssid[0],
2232 tdlsDisReq.LinkIdentifier.bssid[1],
2233 tdlsDisReq.LinkIdentifier.bssid[2],
2234 tdlsDisReq.LinkIdentifier.bssid[3],
2235 tdlsDisReq.LinkIdentifier.bssid[4],
2236 tdlsDisReq.LinkIdentifier.bssid[5]
2237 ) ;
2238 if(!status)
2239 {
2240 limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter\n")) ;
2241
2242 return eSIR_FAILURE ;
2243 }
2244
2245 /*
2246 * check if this is echo of our transmitted discovery request
2247 * drop it here, TODO: better to drop this in TL.
2248 */
2249 status = palEqualMemory(pMac->hHdd, psessionEntry->selfMacAddr,
2250 &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
2251 sizeof(tSirMacAddr)) ;
2252 if(status)
2253 {
2254 limLog( pMac, LOGE, FL("Echo of our TDLS discovery request frame\n")) ;
2255 return eSIR_FAILURE ;
2256 }
2257
2258 /*
2259 * while processing Discovery request from Peer,
2260 * STA_MAC--> MAC of TDLS discovery initiator
2261 * STA_PEER_MAC--> MAC of TDLS discovery responder.
2262 */
2263 palCopyMemory(pMac->hHdd, peerMac,
2264 &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
2265 sizeof(tSirMacAddr)) ;
2266 /* TODO, do more validation */
2267
2268 /* see if discovery is already in progress */
2269 peerInfo = limTdlsFindDisPeer(pMac, peerMac) ;
2270
2271 if(NULL == peerInfo)
2272 {
2273 /*
2274 * we are allocating peer info for individual peers found in TDLS
2275 * discovery, we need to keep adding TDLS peers till we have timed
2276 * out. We are freeing this memory at the time we are sending this
2277 * collected peer info to SME.
2278 */
2279 status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult,
2280 sizeof(tLimDisResultList)) ;
2281
2282 if(status != eHAL_STATUS_SUCCESS)
2283 {
2284 limLog(pMac, LOGP, FL("alloc fail for TDLS discovery \
2285 reponse info\n")) ;
2286 return eSIR_FAILURE ;
2287 }
2288
2289
2290 peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;
2291 peerInfo->tdlsPeerState = TDLS_DIS_REQ_PROCESS_STATE ;
2292 peerInfo->dialog = tdlsDisReq.DialogToken.token ;
2293
2294 peerInfo->sessionId = psessionEntry->peSessionId;
2295
2296 /* Populate peer info of tdls discovery result */
2297 status = palCopyMemory(pMac->hHdd, peerInfo->peerMac, peerMac,
2298 sizeof(tSirMacAddr)) ;
2299
2300 /*
2301 * Now, as per D13, there will not be any Supp rates, ext Supp rates
2302 * info in Discovery request frames, so we are populating this info
2303 * locally to pass it to ADD STA.
2304 */
2305 do
2306 {
2307 tDot11fIESuppRates suppRates = {0} ;
2308 tDot11fIEExtSuppRates extSuppRates = {0} ;
2309 tANI_U16 caps = 0 ;
2310 tDot11fFfCapabilities capsInfo = {0} ;
2311 tDot11fIEHTCaps HTCaps = {0} ;
2312 /* populate supported rate IE */
2313 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2314 &suppRates, psessionEntry );
2315 ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates,
2316 &suppRates);
2317 /* Populate extended supported rates */
2318 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
2319 &extSuppRates, psessionEntry );
2320
2321 peerInfo->ExtRatesPresent = 1;
2322 ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates,
2323 &extSuppRates);
2324
2325 if(cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
2326 {
2327 /*
2328 * Could not get Capabilities value
2329 * from CFG. Log error.
2330 */
2331 limLog(pMac, LOGP,
2332 FL("could not retrieve Capabilities value\n"));
2333 }
2334 swapBitField16(caps, ( tANI_U16* )&capsInfo );
2335 /* update Caps Info */
2336 tdlsUpdateCapInfo(&peerInfo->capabilityInfo , &capsInfo) ;
2337
2338 PopulateDot11fHTCaps( pMac, psessionEntry, &HTCaps );
2339 limTdlsCovertHTCaps(pMac, peerInfo, &HTCaps) ;
2340
2341 } while (0) ;
2342
2343 /* now add this new found discovery node into tdls discovery list */
2344 tdlsDisResult->next = *disResultList ;
2345 *disResultList = tdlsDisResult ;
2346 pMac->lim.gLimTdlsDisStaCount++ ;
2347
2348 /* See if for this peer already entry in setup Link */
2349 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
2350
2351 /*
2352 * if there is no entry for this peer in setup list, we need to
2353 * do add sta for this peer to transmit discovery rsp.
2354 */
2355 if(NULL == setupPeer)
2356 {
2357 /* To start with, send add STA request to HAL */
2358 pMac->lim.gLimAddStaTdls = true ;
2359 peerInfo->delStaNeeded = true ;
2360
2361 if(eSIR_FAILURE == limTdlsDisAddSta(pMac, peerMac,
2362 peerInfo, psessionEntry))
2363 {
2364 VOS_ASSERT(0) ;
2365 limLog(pMac, LOGE, "Add STA for dis response is failed \n") ;
2366 return eSIR_FAILURE ;
2367 }
2368 } /* use setup link sta ID for discovery rsp */
2369 else
2370 {
2371 peerInfo->delStaNeeded = false ;
2372 limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
2373 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
2374 }
2375
2376 }
2377 else
2378 {
2379 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2380 ("discovery procedure in progress for this peer\n")) ;
2381 }
2382
2383 return eSIR_SUCCESS ;
2384}
2385
2386/* Process TDLS setup Request Frame */
2387
2388static tSirRetStatus limProcessTdlsSetupReqFrame(tpAniSirGlobal pMac,
2389 tANI_U8 *pBody, tANI_U32 frmLen)
2390{
2391
2392 tDot11fTDLSSetupReq tdlsSetupReq = {{0}} ;
2393 tANI_U32 status = 0 ;
2394 tpPESession psessionEntry = NULL ;
2395 tANI_U8 sessionId = 0 ;
2396 tANI_U8 currentState = TDLS_LINK_SETUP_WAIT_STATE ;
2397 tANI_U8 previousState = TDLS_LINK_IDLE_STATE ;
2398 /* create node for Link setup */
2399 tLimTdlsLinkSetupInfo *linkSetupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2400 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
2401 tLimTdlsLinkSetupPeer *tmpSetupPeer = NULL ;
2402
2403 status = dot11fUnpackTDLSSetupReq(pMac, pBody, frmLen, &tdlsSetupReq) ;
2404
2405 if ( DOT11F_FAILED( status ) )
2406 {
2407 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
2408 frame (0x%08x, %d bytes):\n"),status, frmLen);
2409 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2410 return eSIR_FAILURE;
2411 }
2412 else if ( DOT11F_WARNED( status ) )
2413 {
2414 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2415 TDLS setup Request frame (0x%08x," "%d bytes):\n"),
2416 status, pBody );
2417 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2418 }
2419 /*
2420 * find session entry using BSSID in link identifier, not using MAC
2421 * header beacuse, there is cases in TDLS, there may be BSSID will not
2422 * be present in header
2423 */
2424 psessionEntry = peFindSessionByBssid(pMac,
2425 &tdlsSetupReq.LinkIdentifier.bssid[0], &sessionId) ;
2426 if(NULL == psessionEntry)
2427 {
2428 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
2429 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
2430 tdlsSetupReq.LinkIdentifier.bssid[0],
2431 tdlsSetupReq.LinkIdentifier.bssid[1],
2432 tdlsSetupReq.LinkIdentifier.bssid[2],
2433 tdlsSetupReq.LinkIdentifier.bssid[3],
2434 tdlsSetupReq.LinkIdentifier.bssid[4],
2435 tdlsSetupReq.LinkIdentifier.bssid[5]) ;
2436
2437 //VOS_ASSERT(0) ;
2438 return eSIR_FAILURE ;
2439 }
2440 /* TODO: we don;t need this check now, varify BSSID */
2441 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
2442 &tdlsSetupReq.LinkIdentifier.bssid[0],
2443 sizeof(tSirMacAddr)) ;
2444
2445 if(!status)
2446 {
2447 limLog( pMac, LOGE, FL("TDLS setup request frame from other BSS -> something wrong. Check RXP filter\n")) ;
2448
2449 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, tdlsSetupReq.DialogToken.token , psessionEntry,
2450 TDLS_SETUP_STATUS_FAILURE, NULL, 0 ) ;
2451 return eSIR_FAILURE ;
2452 }
2453
2454#ifdef FEATURE_WLAN_TDLS_NEGATIVE
2455 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_RSP_TIMEOUT_TO_SETUP_REQ)
2456 {
2457 /* simply ignore this setup request packet */
2458 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2459 ("TDLS negative running: ignore TDLS Setup Req packet\n"));
2460 return eSIR_SUCCESS ;
2461 }
2462 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
2463 {
2464 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2465 ("TDLS negative running: send TDLS Setup Req to peer TDLS Setup Req\n"));
2466 /* format TDLS discovery request frame and transmit it */
2467 limSendTdlsLinkSetupReqFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, tdlsSetupReq.DialogToken.token, psessionEntry,
2468 NULL, 0) ;
2469 }
2470#endif
2471 /* TODO, do more validation */
2472
2473 if(!limTdlsFindLinkPeer(pMac,
2474 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
2475 &tmpSetupPeer))
2476 {
2477 tANI_U32 tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;
2478
2479 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2480 ("Link is already setup with this peer\n" )) ;
2481 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2482 ("state = %d\n"), tmpSetupPeer->tdls_link_state) ;
2483 //return eSIR_FAILURE ;
2484
2485 if(tmpSetupPeer == NULL)
2486 {
2487 VOS_ASSERT(0) ;
2488 return eSIR_FAILURE ;
2489
2490 }
2491 switch(tmpSetupPeer->tdls_link_state)
2492 {
2493
2494 case TDLS_LINK_SETUP_START_STATE:
2495 {
2496 v_SINT_t macCompare = 0 ;
2497 macCompare= vos_mem_compare2(tmpSetupPeer->peerMac,
2498 psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
2499 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2500 ("MAC comparison Rslt = %d\n"), macCompare ) ;
2501 if(0 > macCompare)
2502 {
2503 /*
2504 * Delete our Setup Request/Peer info and honour Peer
2505 * Setup Request, go ahead and respond for this
2506 */
2507 /* Deactivate the timer */
2508 tx_timer_deactivate(&tmpSetupPeer->gLimTdlsLinkSetupRspTimeoutTimer) ;
2509#ifdef FEATURE_WLAN_TDLS_NEGATIVE
2510 if((pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
2511 != LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
2512#endif
2513 limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE,
2514 tmpSetupPeer->peerMac, eWNI_SME_TDLS_LINK_START_RSP);
2515
2516 limTdlsDelLinkPeer(pMac, tmpSetupPeer->peerMac) ;
2517 tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
2518 }
2519 else if(0 < macCompare)
2520 {
2521 /*
2522 * Go ahead with current setup as peer is going to
2523 * respond for setup request
2524 */
2525 tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;
2526 }
2527 else
2528 {
2529 /* same MAC, not possible */
2530 VOS_ASSERT(0) ;
2531 }
2532
2533 break ;
2534 }
2535#if 1
2536 case TDLS_LINK_SETUP_DONE_STATE:
2537 {
2538 tpDphHashNode pStaDs = NULL ;
2539
2540 previousState = TDLS_LINK_SETUP_WAIT_STATE ;
2541 currentState = TDLS_LINK_TEARDOWN_START_STATE ;
2542 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2543 ("link Setup Done state " )) ;
2544 tmpSetupPeer->tdls_prev_link_state = previousState ;
2545 tmpSetupPeer->tdls_link_state = currentState ;
2546 setupPeer = tmpSetupPeer ;
2547#if 0
2548 /* Send Teardown to this Peer and Initiate new TDLS Setup */
2549 limSendTdlsTeardownFrame(pMac,
2550 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
2551 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON, psessionEntry) ;
2552#else
2553
2554 /* tdls_hklee: send message to HAL before it is deleted, cause */
2555 limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;
2556
2557 /* send del STA to remove context for this TDLS STA */
2558 pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;
2559
2560 /* now send indication to SME-->HDD->TL to remove STA from TL */
2561
2562 if(pStaDs)
2563 {
2564 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
2565 pStaDs, eSIR_SUCCESS) ;
2566
2567 /* send Teardown Ind to SME */
2568 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
2569 eWNI_SME_TDLS_TEARDOWN_IND) ;
2570 /* remove node from setup list */
2571 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
2572 }
2573#endif
2574 //setupPeer->tdls_prev_link_state = TDLS_LINK_SETUP_RESTART_STATE;
2575 tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
2576 break ;
2577
2578 }
2579 default:
2580 {
2581 VOS_ASSERT(0) ;
2582 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2583 ("link Setup is Recieved in unknown state\n" )) ;
2584 break ;
2585 }
2586#endif
2587 }
2588 if(tdlsStateStatus == TDLS_LINK_SETUP_START_STATE)
2589 return eSIR_FAILURE ;
2590 }
2591
2592 if(currentState != TDLS_LINK_TEARDOWN_START_STATE)
2593 {
2594 /*
2595 * Now we are sure to send discovery response frame to TDLS discovery
2596 * initiator, we don't care, if this request is unicast ro broadcast,
2597 * we simply, send discovery response frame on direct link.
2598 */
2599 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
2600 (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
2601 {
2602 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2603 ( "Unable to allocate memory during ADD_STA\n" ));
2604 return eSIR_MEM_ALLOC_FAILED;
2605 }
2606
2607 setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
2608 //setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
2609 //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
2610 setupPeer->tdls_prev_link_state = previousState ;
2611 setupPeer->tdls_link_state = currentState ;
2612 /* TDLS_sessionize: remember sessionId for future */
2613 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
2614 setupPeer->tdls_bIsResponder = 0;
2615
2616 palCopyMemory(pMac->hHdd, setupPeer->peerMac,
2617 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
2618 sizeof(tSirMacAddr)) ;
2619
2620 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2621 ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
2622 setupPeer->peerMac[0],
2623 setupPeer->peerMac[1],
2624 setupPeer->peerMac[2],
2625 setupPeer->peerMac[3],
2626 setupPeer->peerMac[4],
2627 setupPeer->peerMac[5] ) ;
2628
2629 limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
2630 pMac->lim.gLimAddStaTdls = true ;
2631
2632 /* To start with, send add STA request to HAL */
2633 if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, setupPeer->peerMac,
2634 setupPeer, psessionEntry))
2635 {
2636 VOS_ASSERT(0) ;
2637 palFreeMemory(pMac->hHdd, (void **) &setupPeer) ;
2638 return eSIR_FAILURE ;
2639 }
2640
2641 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
2642 tdlsSetupReq.DialogToken.token , psessionEntry,
2643 TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;
2644
2645 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
2646 &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
2647 (tANI_U32)setupPeer->peerMac,
2648 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
2649 SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;
2650
2651 /* update setup peer list */
2652 setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
2653 linkSetupInfo->tdlsLinkSetupList = setupPeer ;
2654 }
2655 else
2656 {
2657 setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
2658 //setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
2659 //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
2660 setupPeer->tdls_prev_link_state = previousState ;
2661 setupPeer->tdls_link_state = currentState ;
2662 /* TDLS_sessionize: remember sessionId for future */
2663 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
2664 setupPeer->tdls_bIsResponder = 0;
2665
2666 palCopyMemory(pMac->hHdd, setupPeer->peerMac,
2667 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
2668 sizeof(tSirMacAddr)) ;
2669
2670 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2671 ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
2672 setupPeer->peerMac[0],
2673 setupPeer->peerMac[1],
2674 setupPeer->peerMac[2],
2675 setupPeer->peerMac[3],
2676 setupPeer->peerMac[4],
2677 setupPeer->peerMac[5] ) ;
2678
2679 limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
2680 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
2681 tdlsSetupReq.DialogToken.token , psessionEntry,
2682 TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;
2683
2684 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
2685 &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
2686 (tANI_U32)setupPeer->peerMac,
2687 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
2688 SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;
2689 }
2690
2691
2692 return eSIR_SUCCESS ;
2693
2694}
2695
2696/*
2697 * TDLS discovery request frame received from TDLS peer STA..
2698 */
2699static tSirRetStatus limProcessTdlsSetupRspFrame(tpAniSirGlobal pMac,
2700 tANI_U8 *pBody, tANI_U32 frmLen )
2701{
2702 tDot11fTDLSSetupRsp tdlsSetupRsp = {{0}} ;
2703 tANI_U32 status = 0 ;
2704 tSirMacAddr peerMac = {0} ;
2705 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
2706 tpPESession psessionEntry = NULL ;
2707 tANI_U8 sessionId = 0 ;
2708
2709 status = dot11fUnpackTDLSSetupRsp(pMac, pBody, frmLen, &tdlsSetupRsp) ;
2710
2711 if ( DOT11F_FAILED( status ) )
2712 {
2713 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
2714 frame (0x%08x, %d bytes):\n"),status, frmLen);
2715 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2716 return eSIR_FAILURE;
2717 }
2718 else if ( DOT11F_WARNED( status ) )
2719 {
2720 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2721 TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
2722 status, frmLen );
2723 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2724 }
2725
2726 /*
2727 * find session entry using BSSID in link identifier, not using MAC
2728 * header beacuse, there is cases in TDLS, there may be BSSID will not
2729 * be present in header
2730 */
2731 psessionEntry = peFindSessionByBssid(pMac,
2732 &tdlsSetupRsp.LinkIdentifier.bssid[0], &sessionId) ;
2733 if(NULL == psessionEntry)
2734 {
2735 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
2736 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
2737 tdlsSetupRsp.LinkIdentifier.bssid[0],
2738 tdlsSetupRsp.LinkIdentifier.bssid[1],
2739 tdlsSetupRsp.LinkIdentifier.bssid[2],
2740 tdlsSetupRsp.LinkIdentifier.bssid[3],
2741 tdlsSetupRsp.LinkIdentifier.bssid[4],
2742 tdlsSetupRsp.LinkIdentifier.bssid[5]) ;
2743
2744 //VOS_ASSERT(0) ;
2745 return eSIR_FAILURE;
2746 }
2747
2748 /* varify BSSID */
2749 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
2750 &tdlsSetupRsp.LinkIdentifier.bssid[0],
2751 sizeof(tSirMacAddr)) ;
2752
2753 if(!status)
2754 {
2755 limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter\n")) ;
2756
2757 VOS_ASSERT(0) ;
2758 return eSIR_FAILURE ;
2759 }
2760 palCopyMemory(pMac->hHdd, peerMac,
2761 &tdlsSetupRsp.LinkIdentifier.RespStaAddr[0],
2762 sizeof(tSirMacAddr)) ;
2763
2764 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2765 ("TDLS setup RSP peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
2766 peerMac[0],
2767 peerMac[1],
2768 peerMac[2],
2769 peerMac[3],
2770 peerMac[4],
2771 peerMac[5]) ;
2772 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
2773
2774 if(NULL == setupPeer)
2775 {
2776 limLog( pMac, LOGE, FL(" unknown setup Response frame \
2777 other BSS\n")) ;
2778 return eSIR_FAILURE ;
2779 }
2780
2781 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2782 ("deactivating Setup RSP timer\n")) ;
2783
2784 /* Deactivate the timer */
2785 tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupRspTimeoutTimer) ;
2786
2787 /*
2788 * TDLS Setup RSP is recieved with Failure, Delete this STA entry
2789 * don't respond with TDLS CNF frame.
2790 */
2791 if(TDLS_SETUP_STATUS_SUCCESS != tdlsSetupRsp.Status.status)
2792 {
2793 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
2794 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2795 ("setup RSP with Failure Code\n")) ;
2796 return eSIR_FAILURE ;
2797 }
2798
2799 /* update Link Info */
2800 limTdlsUpdateLinkRspPeerInfo(pMac, setupPeer, &tdlsSetupRsp) ;
2801
2802 /* TODO, do more validation */
2803
2804
2805 /*
2806 * Now we are sure to send link setup CNF frame to TDLS link setup
2807 * reponded, now we will create dph hash entry and send add STA to HAL
2808 */
2809
2810 pMac->lim.gLimAddStaTdls = true ;
2811 if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, peerMac,
2812 setupPeer, psessionEntry))
2813 {
2814 /* through error */
2815 VOS_ASSERT(0) ;
2816 return eSIR_FAILURE ;
2817 }
2818 /* TDLS_HKLEE_FIXME: now we add some delay for AddSta_Rsp comes */
2819
2820
2821 /* send TDLS confim frame to TDLS Peer STA */
2822 limSendTdlsLinkSetupCnfFrame(pMac, peerMac, tdlsSetupRsp.DialogToken.token, psessionEntry, NULL, 0) ;
2823
2824 /*
2825 * set the tdls_link_state to TDLS_LINK_SETUP_RSP_WAIT_STATE, and
2826 * wait for Setup CNF transmission on air, once we receive tx complete
2827 * message, we will change the peer state and send message to SME
2828 * callback..
2829 */
2830 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
2831 (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_RSP_WAIT_STATE ;
2832
2833 return eSIR_SUCCESS ;
2834}
2835/*
2836 * TDLS setup CNF frame processing ..
2837 */
2838
2839static tSirRetStatus limProcessTdlsSetupCnfFrame(tpAniSirGlobal pMac,
2840 tANI_U8 *pBody, tANI_U32 frmLen)
2841{
2842 tDot11fTDLSSetupCnf tdlsSetupCnf = {{0}} ;
2843 tANI_U32 status = 0 ;
2844 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
2845 tpPESession psessionEntry = NULL ;
2846 tANI_U8 sessionId = 0 ;
2847
2848 status = dot11fUnpackTDLSSetupCnf(pMac, pBody, frmLen, &tdlsSetupCnf) ;
2849
2850 if ( DOT11F_FAILED( status ) )
2851 {
2852 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
2853 frame (0x%08x, %d bytes):\n"),status, frmLen);
2854 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2855 return eSIR_FAILURE;
2856 }
2857 else if ( DOT11F_WARNED( status ) )
2858 {
2859 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2860 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
2861 status, frmLen );
2862 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2863 }
2864 /*
2865 * find session entry using BSSID in link identifier, not using MAC
2866 * header beacuse, there is cases in TDLS, there may be BSSID will not
2867 * be present in header
2868 */
2869 psessionEntry = peFindSessionByBssid(pMac,
2870 &tdlsSetupCnf.LinkIdentifier.bssid[0], &sessionId) ;
2871 if(NULL == psessionEntry)
2872 {
2873 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
2874 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
2875 tdlsSetupCnf.LinkIdentifier.bssid[0],
2876 tdlsSetupCnf.LinkIdentifier.bssid[1],
2877 tdlsSetupCnf.LinkIdentifier.bssid[2],
2878 tdlsSetupCnf.LinkIdentifier.bssid[3],
2879 tdlsSetupCnf.LinkIdentifier.bssid[4],
2880 tdlsSetupCnf.LinkIdentifier.bssid[5]) ;
2881
2882 //VOS_ASSERT(0) ;
2883 return eSIR_FAILURE;
2884 }
2885
2886 /* varify BSSID */
2887 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
2888 &tdlsSetupCnf.LinkIdentifier.bssid[0],
2889 sizeof(tSirMacAddr)) ;
2890
2891 if(!status)
2892 {
2893 limLog( pMac, LOGE, FL("TDLS setup CNF frame other BSS -> something wrong. Check RXP filter\n")) ;
2894
2895 VOS_ASSERT(0) ;
2896 return eSIR_FAILURE ;
2897 }
2898 /* TODO, do more validation */
2899 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2900 ("setup Cnf peer MAc = %02x,%02x,%02x,%02x,%02x,%02x\n"),
2901 tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
2902 tdlsSetupCnf.LinkIdentifier.InitStaAddr[1],
2903 tdlsSetupCnf.LinkIdentifier.InitStaAddr[2],
2904 tdlsSetupCnf.LinkIdentifier.InitStaAddr[3],
2905 tdlsSetupCnf.LinkIdentifier.InitStaAddr[4],
2906 tdlsSetupCnf.LinkIdentifier.InitStaAddr[5]
2907 ) ;
2908
2909 limTdlsFindLinkPeer(pMac,
2910 &tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
2911 &setupPeer) ;
2912
2913 if(NULL == setupPeer)
2914 {
2915 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2916 (" unknown setup CNF frame\n")) ;
2917 VOS_ASSERT(0) ;
2918 return eSIR_FAILURE ;
2919 }
2920 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2921 ("setup CNF peer MAC = %02x,%02x,%02x,%02x,%02x,%02x\n"),
2922 (setupPeer)->peerMac[0],
2923 (setupPeer)->peerMac[1],
2924 (setupPeer)->peerMac[2],
2925 (setupPeer)->peerMac[3],
2926 (setupPeer)->peerMac[4],
2927 (setupPeer)->peerMac[5]) ;
2928 /*T match dialog token, before proceeding further */
2929 if((setupPeer)->dialog != tdlsSetupCnf.DialogToken.token)
2930 {
2931 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
2932 ("setup CNF frame not matching with setup RSP\n")) ;
2933 VOS_ASSERT(0) ;
2934 return eSIR_FAILURE ;
2935 }
2936
2937 /*
2938 * Now we are sure that, this set CNF is for us, now stop
2939 * the running timer..
2940 */
2941 tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupCnfTimeoutTimer) ;
2942
2943 /* change TDLS peer State */
2944 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
2945 (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ;
2946
2947 /* send indication to SME that, new link is setup */
2948 limSendSmeTdlsLinkSetupInd(pMac, (setupPeer)->peerMac, eSIR_SUCCESS) ;
2949
2950 /* tdls_hklee: prepare PTI template and send it to HAL */
2951 limTdlsLinkEstablish(pMac, (setupPeer)->peerMac);
2952
2953 return eSIR_SUCCESS ;
2954
2955}
2956
2957/*
2958 * TDLS discovery response frame processing ..
2959 */
2960
2961static tSirRetStatus limProcessTdlsDisRspFrame(tpAniSirGlobal pMac,
2962 tANI_U8 *pBody, tANI_U32 frmLen,
2963 tANI_S8 rssi, tpPESession psessionEntry)
2964{
2965 tDot11fTDLSDisRsp tdlsDisRsp = {{0}} ;
2966 tANI_U32 status = 0 ;
2967 tLimDisResultList *tdlsDisResult = NULL ;
2968 tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
2969 tSirTdlsDisReq *prevDisReq = &pMac->lim.gLimTdlsDisReq ;
2970
2971 status = dot11fUnpackTDLSDisRsp(pMac, pBody, frmLen, &tdlsDisRsp) ;
2972
2973 if ( DOT11F_FAILED( status ) )
2974 {
2975 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
2976 frame (0x%08x, %d bytes):\n"),status, frmLen);
2977 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2978 return eSIR_FAILURE;
2979 }
2980 else if ( DOT11F_WARNED( status ) )
2981 {
2982 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2983 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
2984 status, frmLen );
2985 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);)
2986 }
2987 /*TODO: match dialog token, before proceeding further */
2988
2989 /* varify BSSID */
2990 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
2991 &tdlsDisRsp.LinkIdentifier.bssid[0],
2992 sizeof(tSirMacAddr)) ;
2993
2994 if(!status)
2995 {
2996 limLog( pMac, LOGW, FL(" TDLS discovery Response frame other BSS\n")) ;
2997 return eSIR_FAILURE ;
2998 }
2999 /* TODO, do more validation */
3000
3001 if(tdlsDisRsp.DialogToken.token != prevDisReq->dialog)
3002 {
3003 limLog( pMac, LOGW, FL(" wrong TDLS discovery Response frame\n")) ;
3004 return eSIR_FAILURE ;
3005 }
3006
3007 pMac->lim.gLimTdlsDisStaCount++ ;
3008
3009 /*
3010 * we are allocating peer info for individual peers found in TDLS
3011 * discovery, we need to keep adding TDLS peers till we have timed
3012 * out. We are freeing this memory at the time we are sending this
3013 * collected peer info to SME.
3014 */
3015 status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult,
3016 sizeof(tLimDisResultList)) ;
3017
3018 if(status != eHAL_STATUS_SUCCESS)
3019 {
3020 limLog(pMac, LOGP, FL("alloc fail for TDLS discovery reponse info\n")) ;
3021 return eSIR_FAILURE ;
3022 }
3023
3024 do
3025 {
3026 tSirTdlsPeerInfo *peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;
3027
3028 /* Populate peer info of tdls discovery result */
3029 peerInfo->sessionId = psessionEntry->peSessionId;
3030 /*
3031 * When we receive DIS RSP from peer MAC,
3032 * STA_MAC_OFFSET will carry peer MAC address and PEER MAC OFFSET
3033 * will carry our MAC.
3034 */
3035 status = palCopyMemory(pMac->hHdd, peerInfo->peerMac,
3036 &tdlsDisRsp.LinkIdentifier.RespStaAddr[0],
3037 sizeof(tSirMacAddr)) ;
3038
3039 /* update RSSI for this TDLS peer STA */
3040 peerInfo->tdlsPeerRssi = rssi ;
3041
3042 /* update Caps Info */
3043 tdlsUpdateCapInfo(&peerInfo->capabilityInfo ,
3044 &tdlsDisRsp.Capabilities) ;
3045
3046 /* update Supp rates */
3047 if(tdlsDisRsp.SuppRates.present)
3048 {
3049 ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates,
3050 &tdlsDisRsp.SuppRates );
3051 }
3052
3053 /* update EXT supp rates */
3054 if(tdlsDisRsp.ExtSuppRates.present)
3055 {
3056 peerInfo->ExtRatesPresent = 1;
3057 ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates,
3058 &tdlsDisRsp.ExtSuppRates );
3059 }
3060 /* update HT caps */
3061 if (tdlsDisRsp.HTCaps.present)
3062 {
3063 palCopyMemory( pMac, &peerInfo->tdlsPeerHtCaps, &tdlsDisRsp.HTCaps,
3064 sizeof( tDot11fIEHTCaps ) );
3065 }
3066 /* update EXT caps */
3067 if (tdlsDisRsp.ExtCap.present)
3068 {
3069 //palCopyMemory( pMac, &peerInfo->tdlsPeerExtenCaps,
3070 // &tdlsDisRsp.ExtCap,
3071 // sizeof( tDot11fIEExtCap ) );
3072 }
3073 } while(0) ;
3074
3075 /* now add this new found discovery node into tdls discovery list */
3076 tdlsDisResult->next = *disResultList ;
3077 *disResultList = tdlsDisResult ;
3078
3079 return eSIR_SUCCESS ;
3080}
3081
3082/*
3083 * Process TDLS Teardown request frame from TDLS peer STA
3084 */
3085static tSirRetStatus limProcessTdlsTeardownFrame(tpAniSirGlobal pMac,
3086 tANI_U8 *pBody, tANI_U32 frmLen )
3087{
3088 tDot11fTDLSTeardown tdlsTeardown = {{0}} ;
3089 tANI_U32 status = 0 ;
3090 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3091 tpPESession psessionEntry = NULL ;
3092 tANI_U8 sessionId = 0 ;
3093
3094 status = dot11fUnpackTDLSTeardown(pMac, pBody, frmLen, &tdlsTeardown) ;
3095
3096 if ( DOT11F_FAILED( status ) )
3097 {
3098 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
3099 frame (0x%08x, %d bytes):\n"),status, frmLen);
3100 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3101 return eSIR_FAILURE;
3102 }
3103 else if ( DOT11F_WARNED( status ) )
3104 {
3105 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3106 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
3107 status, frmLen );
3108 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3109 }
3110
3111 /*
3112 * find session entry using BSSID in link identifier, not using MAC
3113 * header beacuse, there is cases in TDLS, there may be BSSID will not
3114 * be present in header
3115 */
3116 psessionEntry = peFindSessionByBssid(pMac,
3117 &tdlsTeardown.LinkIdentifier.bssid[0], &sessionId) ;
3118 if(NULL == psessionEntry)
3119 {
3120 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
3121 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
3122 tdlsTeardown.LinkIdentifier.bssid[0],
3123 tdlsTeardown.LinkIdentifier.bssid[1],
3124 tdlsTeardown.LinkIdentifier.bssid[2],
3125 tdlsTeardown.LinkIdentifier.bssid[3],
3126 tdlsTeardown.LinkIdentifier.bssid[4],
3127 tdlsTeardown.LinkIdentifier.bssid[5]) ;
3128
3129 //VOS_ASSERT(0) ;
3130 return eSIR_FAILURE;
3131 }
3132
3133 /* varify BSSID */
3134 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3135 &tdlsTeardown.LinkIdentifier.bssid[0],
3136 sizeof(tSirMacAddr)) ;
3137
3138
3139 if(!status)
3140 {
3141 limLog( pMac, LOGE, FL("Teardown from other BSS -> something wrong. Check RXP filter\n")) ;
3142 VOS_ASSERT(0) ;
3143 return eSIR_FAILURE ;
3144 }
3145
3146 limTdlsFindLinkPeer(pMac,
3147 &tdlsTeardown.LinkIdentifier.InitStaAddr[0],
3148 &setupPeer) ;
3149
3150 if(NULL == setupPeer)
3151 {
3152 //ignore
3153 //VOS_ASSERT(0) ;
3154 limLog( pMac, LOGE, FL("Teardown from unknown peer. --> ignored\n") );
3155
3156 return eSIR_FAILURE ;
3157 }
3158 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3159 ("teardown for peer %02x,%02x,%02x,%02x,%02x,%02x\n"),
3160 (setupPeer)->peerMac[0],
3161 (setupPeer)->peerMac[1],
3162 (setupPeer)->peerMac[2],
3163 (setupPeer)->peerMac[3],
3164 (setupPeer)->peerMac[4],
3165 (setupPeer)->peerMac[5]) ;
3166
3167 switch(tdlsTeardown.Reason.code)
3168 {
3169 case eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON:
3170 {
3171 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3172 ("teardown with unspecified reason\n")) ;
3173 break ;
3174 }
3175 case eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE:
3176 {
3177 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3178 (" Teardown from AP, TDLS peer unreachable\n")) ;
3179 break ;
3180 }
3181 default:
3182 {
3183 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3184 (" unknown teardown\n")) ;
3185 break ;
3186 }
3187 }
3188
3189 /* change TDLS peer State */
3190 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
3191 (setupPeer)->tdls_link_state = TDLS_LINK_TEARDOWN_START_STATE ;
3192
3193 do
3194 {
3195 tpDphHashNode pStaDs = NULL ;
3196
3197 /* tdls_hklee: send message to HAL before it is deleted, cause */
3198 limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;
3199
3200 /* send del STA to remove context for this TDLS STA */
3201 pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;
3202
3203 /* now send indication to SME-->HDD->TL to remove STA from TL */
3204
3205 if(pStaDs)
3206 {
3207 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
3208 pStaDs, eSIR_SUCCESS) ;
3209
3210 /* send Teardown Ind to SME */
3211 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
3212 eWNI_SME_TDLS_TEARDOWN_IND) ;
3213 /* remove node from setup list */
3214 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
3215 }
3216
3217 }while(0) ;
3218
3219 return status ;
3220}
3221
3222/*
3223 * Common processing of TDLS action frames recieved
3224 */
3225void limProcessTdlsFrame(tpAniSirGlobal pMac, tANI_U32 *pBd)
3226{
3227 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
3228 tANI_U8 pOffset = ((0 == WDA_GET_RX_FT_DONE(pBd))
3229 ? (( sizeof( eth_890d_header ))) :(0)) ;
3230
3231 tANI_U8 category = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[0] ;
3232 tANI_U8 action = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[1] ;
3233 tANI_U32 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
3234 tANI_U8 *tdlsFrameBody = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
3235 //tANI_S8 rssi = (tANI_S8)SIR_MAC_BD_TO_RSSI_DB(pBd);
3236
3237 if(category != SIR_MAC_ACTION_TDLS)
3238 {
3239 limLog( pMac, LOGE, FL("Invalid TDLS action frame=(%d). Ignored\n"), category );
3240 return ;
3241 }
3242
3243 frameLen -= (pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
3244 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Received TDLS action %d (%s)"), \
3245 action, limTraceTdlsActionString(action) ));
3246
3247 switch(action)
3248 {
3249
3250 case SIR_MAC_TDLS_SETUP_REQ:
3251 {
3252 limProcessTdlsSetupReqFrame(pMac, tdlsFrameBody, frameLen) ;
3253 break ;
3254 }
3255 case SIR_MAC_TDLS_SETUP_RSP:
3256 {
3257 limProcessTdlsSetupRspFrame(pMac, tdlsFrameBody, frameLen) ;
3258 break ;
3259 }
3260 case SIR_MAC_TDLS_SETUP_CNF:
3261 {
3262 limProcessTdlsSetupCnfFrame(pMac, tdlsFrameBody, frameLen) ;
3263 break ;
3264 }
3265 case SIR_MAC_TDLS_TEARDOWN:
3266 {
3267 limProcessTdlsTeardownFrame(pMac, tdlsFrameBody, frameLen) ;
3268 break ;
3269 }
3270 case SIR_MAC_TDLS_DIS_REQ:
3271 {
3272 limProcessTdlsDisReqFrame(pMac, tdlsFrameBody, frameLen) ;
3273 break ;
3274 }
3275 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
3276 case SIR_MAC_TDLS_CH_SWITCH_REQ:
3277 case SIR_MAC_TDLS_CH_SWITCH_RSP:
3278 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
3279 default:
3280 {
3281 break ;
3282 }
3283 }
3284
3285 return ;
3286}
3287
3288/*
3289 * ADD sta for dis response fame sent on direct link
3290 */
3291static tSirRetStatus limTdlsDisAddSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
3292 tSirTdlsPeerInfo *peerInfo, tpPESession psessionEntry)
3293{
3294 tpDphHashNode pStaDs = NULL ;
3295 tSirRetStatus status = eSIR_SUCCESS ;
3296 tANI_U16 aid = 0 ;
3297
3298 if(NULL == peerInfo)
3299 {
3300 VOS_ASSERT(0) ;
3301 return status ;
3302
3303 }
3304 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3305 ("ADD STA peer MAC: %02x, %02x, %02x, %02x, %02x, %02x\n"),
3306 peerMac[0],
3307 peerMac[1],
3308 peerMac[2],
3309 peerMac[3],
3310 peerMac[4],
3311 peerMac[5]) ;
3312
3313
3314 if(NULL != dphLookupHashEntry(pMac, peerMac,
3315 &aid, &psessionEntry->dph.dphHashTable))
3316 {
3317 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3318 (" there is hash entry for this client\n")) ;
3319 status = eSIR_FAILURE ;
3320 VOS_ASSERT(0) ;
3321 return status ;
3322 }
3323
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003324 aid = limAssignPeerIdx(pMac, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08003325
3326 pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
3327
3328 if (pStaDs)
3329 {
3330 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
3331 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
3332 }
3333 pStaDs = dphAddHashEntry(pMac, peerMac, aid,
3334 &psessionEntry->dph.dphHashTable) ;
3335
3336 if(NULL == pStaDs)
3337 {
3338 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3339 (" add hash entry failed\n")) ;
3340 status = eSIR_FAILURE ;
3341 VOS_ASSERT(0) ;
3342 return status;
3343 }
3344 if(eSIR_SUCCESS == status)
3345 {
3346#ifdef TDLS_RATE_DEBUG
3347 tSirMacRateSet *suppRates = &peerInfo->tdlsPeerSuppRates ;
3348 tSirMacRateSet *extRates = &peerInfo->tdlsPeerExtRates ;
3349 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3350 ("pSta DS [%p] \n"), pStaDs) ;
3351 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3352 ("peerInfo->tdlsPeerSuppRates = [%p]\n"),
3353 (tANI_U8 *)&peerInfo->tdlsPeerSuppRates) ;
3354 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3355 ("peerInfo->tdlsPeerExtRates = [%p]\n"),
3356 (tANI_U8 *)&peerInfo->tdlsPeerExtRates) ;
3357 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3358 ("peerInfo->tdlsPeerPropRates = [%p]\n"),
3359 (tANI_U8 *)&pStaDs->mlmStaContext.propRateSet) ;
3360 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3361 ("peerInfo->mcs = [%p]\n"),
3362 (tANI_U8 *)peerInfo->supportedMCSSet) ;
3363 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3364 ("num of supp rates = %02x\n"), suppRates->numRates) ;
3365 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3366 ("num of ext rates = %01x\n"), extRates->numRates) ;
3367#endif
3368
3369 /* Populate matching rate set */
3370#ifdef WLAN_FEATURE_11AC
3371 if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs,
3372 &peerInfo->tdlsPeerSuppRates,
3373 &peerInfo->tdlsPeerExtRates,
3374 peerInfo->supportedMCSSet,
3375 &pStaDs->mlmStaContext.propRateSet,
3376 psessionEntry, NULL))
3377#else
3378 if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs,
3379 &peerInfo->tdlsPeerSuppRates,
3380 &peerInfo->tdlsPeerExtRates,
3381 peerInfo->supportedMCSSet,
3382 &pStaDs->mlmStaContext.propRateSet,
3383 psessionEntry))
3384#endif
3385 {
3386 VOS_ASSERT(0) ;
3387 }
3388
3389
3390 pStaDs->mlmStaContext.capabilityInfo = peerInfo->capabilityInfo;
3391 palCopyMemory(pMac->hHdd, pStaDs->staAddr, peerMac,
3392 sizeof(tSirMacAddr)) ;
3393 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3394 ("Add STA for Peer: %02x, %02x, %02x, %02x, %02x, %02x\n"),
3395 pStaDs->staAddr[0],
3396 pStaDs->staAddr[1],
3397 pStaDs->staAddr[2],
3398 pStaDs->staAddr[3],
3399 pStaDs->staAddr[4],
3400 pStaDs->staAddr[5]) ;
3401
3402
3403 pStaDs->staType = STA_ENTRY_TDLS_PEER ;
3404
3405 status = limAddSta(pMac, pStaDs, psessionEntry);
3406
3407 if(eSIR_SUCCESS != status)
3408 {
3409 /* should not fail */
3410 VOS_ASSERT(0) ;
3411 }
3412 }
3413
3414 return status ;
3415}
3416#endif
3417/*
3418 * Add STA for TDLS setup procedure
3419 */
3420static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac,
3421 tSirMacAddr peerMac, tLimTdlsLinkSetupPeer *setupPeer,
3422 tpPESession psessionEntry)
3423{
3424 tpDphHashNode pStaDs = NULL ;
3425 tSirRetStatus status = eSIR_SUCCESS ;
3426 tANI_U16 aid = 0 ;
3427
3428 if(NULL != dphLookupHashEntry(pMac, peerMac, &aid,
3429 &psessionEntry->dph.dphHashTable))
3430 {
3431 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3432 (" there is hash entry for this client\n")) ;
3433 status = eSIR_FAILURE ;
3434 /* TDLS_TODO: I have seen this VOS ASSERT happened. must handle this (called from limProcessTdlsSetupReqFrame) */
3435 VOS_ASSERT(0) ;
3436 return status ;
3437 }
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003438 aid = limAssignPeerIdx(pMac, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08003439
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003440 if( !aid )
3441 {
3442 //Reject request.
3443 return eSIR_FAILURE;
3444 }
Kiran V1ccee932012-12-12 14:49:46 -08003445 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3446 ("Aid = %d, for peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
3447 aid, peerMac[0],peerMac[1],peerMac[2],
3448 peerMac[3],peerMac[4],peerMac[5]) ;
3449 pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
3450
3451 if (pStaDs)
3452 {
3453 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
3454 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
3455 }
3456
3457 pStaDs = dphAddHashEntry(pMac, peerMac, aid,
3458 &psessionEntry->dph.dphHashTable) ;
3459
3460 if(NULL == pStaDs)
3461 {
3462 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3463 (" add hash entry failed\n")) ;
3464 status = eSIR_FAILURE ;
3465 VOS_ASSERT(0) ;
3466 }
3467
3468 limTdlsUpdateHashNodeInfo(pMac, pStaDs, setupPeer, psessionEntry) ;
3469
3470 pStaDs->staType = STA_ENTRY_TDLS_PEER ;
3471
3472 status = limAddSta(pMac, pStaDs, psessionEntry);
3473
3474 if(eSIR_SUCCESS != status)
3475 {
3476 /* should not fail */
3477 VOS_ASSERT(0) ;
3478 }
3479 return status ;
3480}
3481
3482/*
3483 * Del STA, after Link is teardown or discovery response sent on direct link
3484 */
3485static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
3486 tpPESession psessionEntry)
3487{
3488 tSirRetStatus status = eSIR_SUCCESS ;
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003489 tANI_U16 peerIdx = 0 ;
Kiran V1ccee932012-12-12 14:49:46 -08003490 tpDphHashNode pStaDs = NULL ;
3491
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003492 pStaDs = dphLookupHashEntry(pMac, peerMac, &peerIdx,
Kiran V1ccee932012-12-12 14:49:46 -08003493 &psessionEntry->dph.dphHashTable) ;
3494
3495 if(pStaDs)
3496 {
3497
3498 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3499 ("DEL STA peer MAC: %02x, %02x, %02x, %02x, %02x, %02x \n"),
3500 pStaDs->staAddr[0],
3501 pStaDs->staAddr[1],
3502 pStaDs->staAddr[2],
3503 pStaDs->staAddr[3],
3504 pStaDs->staAddr[4],
3505 pStaDs->staAddr[5]
3506 ) ;
3507
3508 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3509 ("STA type = %x, sta idx = %x\n"),pStaDs->staType,
3510 pStaDs->staIndex) ;
3511
3512 status = limDelSta(pMac, pStaDs, false, psessionEntry) ;
3513 if(eSIR_SUCCESS == status)
3514 {
Gopichand Nakkala777e6032012-12-31 16:39:21 -08003515 limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx, psessionEntry) ;
3516 limReleasePeerIdx(pMac, peerIdx, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08003517 }
3518 else
3519 {
3520 VOS_ASSERT(0) ;
3521 }
3522 }
3523
3524 return pStaDs ;
3525}
3526
3527#ifdef FEATURE_WLAN_TDLS_INTERNAL
3528/*
3529* Prepare link establish message for HAL, construct PTI template.
3530*
3531*/
3532static tSirRetStatus limTdlsLinkEstablish(tpAniSirGlobal pMac, tSirMacAddr peerMac)
3533{
3534 tANI_U8 pFrame[64] ;
3535 tDot11fTDLSPeerTrafficInd tdlsPtiTemplate ;
3536 tANI_U32 status = 0 ;
3537 tANI_U32 nPayload = 0 ;
3538 tANI_U32 nBytes = 0 ;
3539 tANI_U32 header_offset = 0 ;
3540 tANI_U16 aid = 0 ;
3541 tDphHashNode *pStaDs = NULL ;
3542 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3543 tpPESession psessionEntry = NULL ;
3544
3545
3546 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
3547 if(NULL == setupPeer) {
3548 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3549 ("limTdlsLinkEstablish: cannot find peer mac in tdls linksetup list: %02X %02X %02X %02X %02X %02X\n"), \
3550 peerMac[0], peerMac[1], peerMac[2], \
3551 peerMac[3], peerMac[4], peerMac[5]);
3552 return eSIR_FAILURE;
3553 }
3554
3555 psessionEntry = peFindSessionBySessionId(pMac,
3556 setupPeer->tdls_sessionId) ;
3557
3558 if(NULL == psessionEntry)
3559 {
3560 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3561 ("limTdlsLinkEstablish: sessionID %d is not found\n"), setupPeer->tdls_sessionId);
3562 VOS_ASSERT(0) ;
3563 return eHAL_STATUS_FAILURE;
3564 }
3565
3566 /* */
3567 pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable) ;
3568 if(pStaDs == NULL) {
3569 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3570 ("limTdlsLinkEstablish: cannot find peer mac in hash table: %02X %02X %02X %02X %02X %02X\n"), \
3571 peerMac[0], peerMac[1], peerMac[2], \
3572 peerMac[3], peerMac[4], peerMac[5]);
3573 return eSIR_FAILURE;
3574 }
3575
3576 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsPtiTemplate,
3577 sizeof( tDot11fTDLSPeerTrafficInd ) );
3578
3579 /*
3580 * setup Fixed fields,
3581 */
3582 tdlsPtiTemplate.Category.category = SIR_MAC_ACTION_TDLS;
3583 tdlsPtiTemplate.Action.action = SIR_MAC_TDLS_PEER_TRAFFIC_IND;
3584 tdlsPtiTemplate.DialogToken.token = 0 ; /* filled by firmware at the time of transmission */
3585#if 1
3586 /* CHECK_PTI_LINK_IDENTIFIER_INITIATOR_ADDRESS: initator address should be TDLS link setup's initiator address,
3587 then below code makes such an way */
3588 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
3589 peerMac, !setupPeer->tdls_bIsResponder) ;
3590#else
3591 /* below code will make PTI's linkIdentifier's initiator address be selfAddr */
3592 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
3593 peerMac, TDLS_INITIATOR) ;
3594#endif
3595
3596 /* PUBufferStatus will be filled by firmware at the time of transmission */
3597 tdlsPtiTemplate.PUBufferStatus.present = 1;
3598
3599 /* TODO: get ExtendedCapabilities IE */
3600
3601 /*
3602 * now we pack it. First, how much space are we going to need?
3603 */
3604 status = dot11fGetPackedTDLSPeerTrafficIndSize ( pMac, &tdlsPtiTemplate, &nPayload);
3605 if ( DOT11F_FAILED( status ) )
3606 {
3607 limLog( pMac, LOGP, FL("Failed to calculate the packed size for a PTI template (0x%08x).\n"), status );
3608 /* We'll fall back on the worst case scenario: */
3609 nPayload = sizeof( tdlsPtiTemplate );
3610 }
3611 else if ( DOT11F_WARNED( status ) )
3612 {
3613 limLog( pMac, LOGW, FL("There were warnings while calculating the packed size for a PTI template (0x%08x).\n"), status );
3614 }
3615
3616 /*
3617 * This frame is going out from PE as data frames with special ethertype
3618 * 89-0d.
3619 * 8 bytes of RFC 1042 header
3620 */
3621
3622 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
3623 + sizeof( eth_890d_header )
3624 + PAYLOAD_TYPE_TDLS_SIZE ;
3625
3626 if(nBytes > 64) {
3627 limLog( pMac, LOGE, FL("required memory for PTI frame is %ld, but reserved only 64.\n"), nBytes);
3628 nBytes = 64;
3629 }
3630 /* zero out the memory */
3631 palZeroMemory( pMac->hHdd, pFrame, sizeof(pFrame) );
3632
3633 /* fill out the buffer descriptor */
3634
3635 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
3636 LINK_IDEN_ADDR_OFFSET(tdlsPtiTemplate), TDLS_LINK_AP, !setupPeer->tdls_bIsResponder, psessionEntry) ;
3637
3638 status = dot11fPackTDLSPeerTrafficInd ( pMac, &tdlsPtiTemplate, pFrame
3639 + header_offset, nPayload, &nPayload );
3640
3641 if ( DOT11F_FAILED( status ) )
3642 {
3643 limLog( pMac, LOGE, FL("Failed to pack a PTI template \
3644 (0x%08x).\n"), status );
3645 return eSIR_FAILURE;
3646 }
3647 else if ( DOT11F_WARNED( status ) )
3648 {
3649 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
3650 "Peer Traffic Indication (0x%08x).\n") );
3651 }
3652
3653 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("bIsResponder=%d, header_offset=%ld, linkIdenOffset=%d, ptiBufStatusOffset=%d \n"), \
3654 setupPeer->tdls_bIsResponder, header_offset, PTI_LINK_IDEN_OFFSET, PTI_BUF_STATUS_OFFSET));
3655
3656 limSendTdlsLinkEstablish(pMac, setupPeer->tdls_bIsResponder,
3657 header_offset+PTI_LINK_IDEN_OFFSET, header_offset+PTI_BUF_STATUS_OFFSET,
3658 nBytes, pFrame, (tANI_U8 *)&setupPeer->tdlsPeerExtCaps);
3659
3660 return eSIR_SUCCESS;
3661}
3662
3663/*
3664* Prepare link teardown message for HAL from peer_mac
3665*
3666*/
3667static tSirRetStatus limTdlsLinkTeardown(tpAniSirGlobal pMac, tSirMacAddr peerMac)
3668{
3669 tDphHashNode *pStaDs = NULL ;
3670 tANI_U16 aid = 0 ;
3671 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3672 tpPESession psessionEntry = NULL ;
3673
3674
3675 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
3676 if(NULL == setupPeer) {
3677 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3678 ("limTdlsLinkTeardown: cannot find peer mac in tdls linksetup list: %02X %02X %02X %02X %02X %02X\n"), \
3679 peerMac[0], peerMac[1], peerMac[2], \
3680 peerMac[3], peerMac[4], peerMac[5]);
3681 return eSIR_FAILURE;
3682 }
3683
3684 psessionEntry = peFindSessionBySessionId(pMac,
3685 setupPeer->tdls_sessionId) ;
3686
3687 if(NULL == psessionEntry)
3688 {
3689 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3690 ("limTdlsLinkTeardown: sessionID %d is not found\n"), setupPeer->tdls_sessionId);
3691 VOS_ASSERT(0) ;
3692 return eHAL_STATUS_FAILURE;
3693 }
3694
3695
3696 /* */
3697 pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable);
3698
3699 if(pStaDs == NULL) {
3700 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3701 ("limTdlsLinkTeardown: cannot find peer mac in hash table: %02X %02X %02X %02X %02X %02X\n"), \
3702 peerMac[0], peerMac[1], peerMac[2], \
3703 peerMac[3], peerMac[4], peerMac[5]);
3704 return eSIR_FAILURE;
3705 }
3706
3707 limSendTdlsLinkTeardown(pMac, pStaDs->staIndex);
3708
3709 return eSIR_SUCCESS;
3710}
3711
3712/*
3713 * Prepare Discovery RSP message for SME, collect peerINfo for all the
3714 * peers discovered and delete/clean discovery lists in PE.
3715 */
3716
3717static tSirTdlsDisRsp *tdlsPrepareTdlsDisRsp(tpAniSirGlobal pMac,
3718 tSirTdlsDisRsp *disRsp, tANI_U8 disStaCount)
3719{
3720 tANI_U32 disMsgRspSize = sizeof(tSirTdlsDisRsp);
3721 tANI_U8 status = eHAL_STATUS_SUCCESS ;
3722
3723 /*
3724 * allocate memory for tdls discovery response, allocated memory should
3725 * be alloc_mem = tdlsStaCount * sizeof(peerinfo)
3726 * + siezeof tSirTdlsDisRsp.
3727 */
3728 disMsgRspSize += (disStaCount * sizeof(tSirTdlsPeerInfo));
3729
3730 /* now allocate memory */
3731 status = palAllocateMemory( pMac->hHdd, (void **)&disRsp, disMsgRspSize ) ;
3732
3733 if(eHAL_STATUS_FAILURE == status)
3734 {
3735 limLog(pMac, LOGP, FL("palAllocateMemory failed for DIS RSP"));
3736 return NULL ;
3737 }
3738
3739 if(disStaCount)
3740 {
3741 tLimDisResultList *tdlsDisRspList = pMac->lim.gLimTdlsDisResultList ;
3742 tSirTdlsPeerInfo *peerInfo = &disRsp->tdlsDisPeerInfo[0] ;
3743
3744 tLimDisResultList *currentNode = tdlsDisRspList ;
3745 while(tdlsDisRspList != NULL)
3746 {
3747
3748 palCopyMemory( pMac->hHdd, (tANI_U8 *)peerInfo,
3749 (tANI_U8 *) &tdlsDisRspList->tdlsDisPeerInfo,
3750 sizeof(tSirTdlsPeerInfo));
3751
3752 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3753 ("Msg Sent to PE, peer MAC: %02x, %02x, %02x, %02x, %02x, %02x\n"),
3754 peerInfo->peerMac[0] ,
3755 peerInfo->peerMac[1] ,
3756 peerInfo->peerMac[2] ,
3757 peerInfo->peerMac[3] ,
3758 peerInfo->peerMac[4] ,
3759 peerInfo->peerMac[5]) ;
3760 disStaCount-- ;
3761 peerInfo++ ;
3762 currentNode = tdlsDisRspList ;
3763 tdlsDisRspList = tdlsDisRspList->next ;
3764 palFreeMemory(pMac->hHdd, currentNode) ;
3765 /* boundary condition check, may be fatal */
3766 if(((!disStaCount) && (tdlsDisRspList))
3767 || ((!tdlsDisRspList) && disStaCount))
3768 {
3769 limLog(pMac, LOG1, FL("mismatch in dis sta count and\
3770 and number of nodes in list\n")) ;
3771 VOS_ASSERT(0) ;
3772 return NULL ;
3773 }
3774 } /* end of while */
3775
3776 /* All discovery STA processed */
3777 pMac->lim.gLimTdlsDisResultList = NULL ;
3778
3779 } /* end of if dis STA count */
3780
3781 return (disRsp) ;
3782}
3783
3784/* Send Teardown response back to PE */
3785
3786void limSendSmeTdlsTeardownRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
3787 tSirMacAddr peerMac, tANI_U16 msgType)
3788{
3789 tSirMsgQ mmhMsg = {0} ;
3790 tSirTdlsTeardownRsp *teardownRspMsg = NULL ;
3791 tANI_U8 status = eHAL_STATUS_SUCCESS ;
3792
3793 mmhMsg.type = msgType ;
3794
3795 status = palAllocateMemory( pMac->hHdd, (void **)&teardownRspMsg,
3796 sizeof(tSirTdlsTeardownRsp)) ;
3797
3798 if(eHAL_STATUS_SUCCESS != status)
3799 {
3800 VOS_ASSERT(0) ;
3801 }
3802 palCopyMemory( pMac->hHdd, teardownRspMsg->peerMac, (tANI_U8 *)peerMac,
3803 sizeof(tSirMacAddr)) ;
3804 teardownRspMsg->statusCode = statusCode ;
3805 mmhMsg.bodyptr = teardownRspMsg ;
3806 mmhMsg.bodyval = 0;
3807 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3808
3809 return ;
3810
3811}
3812
3813/*
3814 * Send Link start RSP back to SME after link is setup or failed
3815 */
3816void limSendSmeTdlsLinkStartRsp(tpAniSirGlobal pMac,
3817 tSirResultCodes statusCode,
3818 tSirMacAddr peerMac,
3819 tANI_U16 msgType)
3820{
3821 tSirMsgQ mmhMsg = {0} ;
3822 tSirTdlsLinksetupRsp *setupRspMsg = NULL ;
3823 tANI_U8 status = eHAL_STATUS_SUCCESS ;
3824
3825 mmhMsg.type = msgType ;
3826
3827 status = palAllocateMemory( pMac->hHdd, (void **)&setupRspMsg,
3828 sizeof(tSirTdlsLinksetupRsp)) ;
3829
3830 if(eHAL_STATUS_SUCCESS != status)
3831 {
3832 VOS_ASSERT(0) ;
3833 }
3834
3835 palCopyMemory( pMac->hHdd, setupRspMsg->peerMac, (tANI_U8 *)peerMac,
3836 sizeof(tSirMacAddr)) ;
3837 setupRspMsg->statusCode = statusCode ;
3838 mmhMsg.bodyptr = setupRspMsg ;
3839 mmhMsg.bodyval = 0;
3840 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3841
3842 return ;
3843}
3844
3845/*
3846 * Send TDLS discovery RSP back to SME
3847 */
3848void limSendSmeTdlsDisRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
3849 tANI_U16 msgType)
3850{
3851 tSirMsgQ mmhMsg = {0} ;
3852 tSirTdlsDisRsp *tdlsDisRsp = NULL ;
3853
3854 mmhMsg.type = msgType ;
3855
3856 if(eSIR_SME_SUCCESS == statusCode)
3857 {
3858 tANI_U8 tdlsStaCount = pMac->lim.gLimTdlsDisStaCount ;
3859
3860 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3861 ("no of TDLS STA discovered: %d\n"), tdlsStaCount) ;
3862 tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, tdlsStaCount) ;
3863
3864 if(tdlsDisRsp)
3865 {
3866 tdlsDisRsp->numDisSta = tdlsStaCount ;
3867 }
3868 else
3869 {
3870 limLog(pMac, LOGP, FL("fatal failure for TDLS DIS RSP\n"));
3871 VOS_ASSERT(0) ;
3872 return ;
3873 }
3874 /* all Discovery STA is processed */
3875 pMac->lim.gLimTdlsDisStaCount = 0 ;
3876 }
3877 else
3878 {
3879 tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, 0) ;
3880 }
3881
3882 tdlsDisRsp->statusCode = statusCode ;
3883 mmhMsg.bodyptr = tdlsDisRsp ;
3884 mmhMsg.bodyval = 0;
3885 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3886
3887 return ;
3888}
3889
3890/*
3891 * Once Link is setup with PEER, send Add STA ind to SME
3892 */
3893static eHalStatus limSendSmeTdlsAddPeerInd(tpAniSirGlobal pMac,
3894 tANI_U8 sessionId, tDphHashNode *pStaDs, tANI_U8 status)
3895{
3896 tSirMsgQ mmhMsg = {0} ;
3897 tSirTdlsPeerInd *peerInd = NULL ;
3898 mmhMsg.type = eWNI_SME_ADD_TDLS_PEER_IND ;
3899 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
3900 (sizeof(tSirTdlsPeerInd))))
3901 {
3902 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
3903 return eSIR_FAILURE;
3904 }
3905
3906 palCopyMemory( pMac->hHdd, peerInd->peerMac,
3907 (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
3908 peerInd->sessionId = sessionId;
3909 peerInd->staId = pStaDs->staIndex ;
3910 peerInd->ucastSig = pStaDs->ucUcastSig ;
3911 peerInd->bcastSig = pStaDs->ucBcastSig ;
3912 peerInd->length = sizeof(tSmeIbssPeerInd) ;
3913
3914 mmhMsg.bodyptr = peerInd ;
3915 mmhMsg.bodyval = 0;
3916 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3917
3918 return eSIR_SUCCESS ;
3919
3920}
3921
3922/*
3923 * Once link is teardown, send Del Peer Ind to SME
3924 */
3925static eHalStatus limSendSmeTdlsDelPeerInd(tpAniSirGlobal pMac,
3926 tANI_U8 sessionId, tDphHashNode *pStaDs, tANI_U8 status)
3927{
3928 tSirMsgQ mmhMsg = {0} ;
3929 tSirTdlsPeerInd *peerInd = NULL ;
3930 mmhMsg.type = eWNI_SME_DELETE_TDLS_PEER_IND ;
3931 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
3932 (sizeof(tSirTdlsPeerInd))))
3933 {
3934 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
3935 return eSIR_FAILURE;
3936 }
3937
3938 palCopyMemory( pMac->hHdd, peerInd->peerMac,
3939 (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
3940 peerInd->sessionId = sessionId;
3941 peerInd->staId = pStaDs->staIndex ;
3942 peerInd->ucastSig = pStaDs->ucUcastSig ;
3943 peerInd->bcastSig = pStaDs->ucBcastSig ;
3944 peerInd->length = sizeof(tSmeIbssPeerInd) ;
3945
3946 mmhMsg.bodyptr = peerInd ;
3947
3948 //peerInd->statusCode = status ;
3949 mmhMsg.bodyval = 0;
3950 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3951 return eSIR_SUCCESS ;
3952
3953}
3954
3955/*
3956 * Send Link setup Ind to SME, This is the case where, link setup is
3957 * initiated by peer STA
3958 */
3959static eHalStatus limSendSmeTdlsLinkSetupInd(tpAniSirGlobal pMac,
3960 tSirMacAddr peerMac, tANI_U8 status)
3961{
3962 tSirMsgQ mmhMsg = {0} ;
3963 tSirTdlsLinkSetupInd *setupInd = NULL ;
3964
3965 mmhMsg.type = eWNI_SME_TDLS_LINK_START_IND ;
3966 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &setupInd,
3967 (sizeof(tSirTdlsLinkSetupInd))))
3968 {
3969 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
3970 return eSIR_FAILURE;
3971 }
3972
3973 palCopyMemory( pMac->hHdd, setupInd->peerMac,
3974 (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
3975 setupInd->length = sizeof(tSirTdlsLinkSetupInd);
3976 setupInd->statusCode = status ;
3977 mmhMsg.bodyptr = setupInd ;
3978 mmhMsg.bodyval = 0;
3979 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
3980
3981 return eSIR_SUCCESS ;
3982
3983}
3984
3985/*
3986 * Setup RSP timer handler
3987 */
3988void limTdlsLinkSetupRspTimerHandler(void *pMacGlobal, tANI_U32 timerId)
3989{
3990
3991 tANI_U32 statusCode;
3992 tSirMsgQ msg;
3993 tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
3994
3995 /* Prepare and post message to LIM Message Queue */
3996
3997 msg.type = SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT;
3998 msg.bodyptr = NULL ;
3999 msg.bodyval = timerId ;
4000
4001 if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
4002 limLog(pMac, LOGE,
4003 FL("posting message %X to LIM failed, reason=%d\n"),
4004 msg.type, statusCode);
4005 return ;
4006}
4007
4008/*
4009 * Link setup CNF timer
4010 */
4011void limTdlsLinkSetupCnfTimerHandler(void *pMacGlobal, tANI_U32 timerId)
4012{
4013
4014 tANI_U32 statusCode;
4015 tSirMsgQ msg;
4016 tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
4017
4018 // Prepare and post message to LIM Message Queue
4019
4020 msg.type = SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT;
4021 msg.bodyptr = NULL ;
4022 msg.bodyval = timerId ;
4023
4024 if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
4025 limLog(pMac, LOGE,
4026 FL("posting message %X to LIM failed, reason=%d\n"),
4027 msg.type, statusCode);
4028 return ;
4029}
4030
4031/*
4032 * start TDLS timer
4033 */
4034void limStartTdlsTimer(tpAniSirGlobal pMac, tANI_U8 sessionId, TX_TIMER *timer,
4035 tANI_U32 timerId, tANI_U16 timerType, tANI_U32 timerMsg)
4036{
4037 tANI_U32 cfgValue = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
4038 ? WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT
4039 : WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT ;
4040
4041 void *timerFunc = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
4042 ? (limTdlsLinkSetupRspTimerHandler)
4043 : limTdlsLinkSetupCnfTimerHandler ;
4044
4045 /* TODO: Read timer vals from CFG */
4046
4047 cfgValue = SYS_MS_TO_TICKS(cfgValue);
4048 /*
4049 * create TDLS discovery response wait timer and activate it
4050 */
4051 if (tx_timer_create(timer, "TDLS link setup timers", timerFunc,
4052 timerId, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS)
4053 {
4054 limLog(pMac, LOGP,
4055 FL("could not create TDLS discovery response wait timer\n"));
4056 return;
4057 }
4058
4059 //assign appropriate sessionId to the timer object
4060 timer->sessionId = sessionId;
4061
4062 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0,
4063 eLIM_TDLS_DISCOVERY_RSP_WAIT));
4064 if (tx_timer_activate(timer) != TX_SUCCESS)
4065 {
4066 limLog(pMac, LOGP, FL("TDLS link setup timer activation failed!\n"));
4067 return ;
4068 }
4069
4070 return ;
4071
4072}
4073#endif
4074
4075/*
4076 * Once Link is setup with PEER, send Add STA ind to SME
4077 */
4078static eHalStatus limSendSmeTdlsAddStaRsp(tpAniSirGlobal pMac,
4079 tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs,
4080 tANI_U8 status)
4081{
4082 tSirMsgQ mmhMsg = {0} ;
4083 tSirTdlsAddStaRsp *addStaRsp = NULL ;
4084 mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ;
4085 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &addStaRsp,
4086 (sizeof(tSirTdlsAddStaRsp))))
4087 {
4088 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4089 return eSIR_FAILURE;
4090 }
4091
4092 addStaRsp->sessionId = sessionId;
4093 addStaRsp->statusCode = status;
4094 if( pStaDs )
4095 {
4096 addStaRsp->staId = pStaDs->staIndex ;
4097 addStaRsp->ucastSig = pStaDs->ucUcastSig ;
4098 addStaRsp->bcastSig = pStaDs->ucBcastSig ;
4099 }
4100 if( peerMac )
4101 {
4102 palCopyMemory( pMac->hHdd, addStaRsp->peerMac,
4103 (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
4104 }
4105 addStaRsp->length = sizeof(tSirTdlsAddStaRsp) ;
4106 addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP ;
4107
4108 mmhMsg.bodyptr = addStaRsp;
4109 mmhMsg.bodyval = 0;
4110 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4111
4112 return eSIR_SUCCESS ;
4113
4114}
4115/*
4116 * STA RSP received from HAL
4117 */
4118eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg,
4119 tpPESession psessionEntry)
4120{
4121 tAddStaParams *pAddStaParams = (tAddStaParams *) msg ;
4122 tANI_U8 status = eSIR_SUCCESS ;
4123 tDphHashNode *pStaDs = NULL ;
4124 tANI_U16 aid = 0 ;
4125
4126 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
4127 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4128 ("ADD_STA_RSP received :staIdx=%d, staMac=%02x:%02x:%02x:%02x:%02x:%02x"), pAddStaParams->staIdx, \
4129 pAddStaParams->staMac[0],
4130 pAddStaParams->staMac[1],
4131 pAddStaParams->staMac[2],
4132 pAddStaParams->staMac[3],
4133 pAddStaParams->staMac[4],
4134 pAddStaParams->staMac[5] ) ;
4135
4136 if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
4137 {
4138 VOS_ASSERT(0) ;
4139 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4140 ("Add sta failed \n")) ;
4141 status = eSIR_FAILURE;
4142 goto add_sta_error;
4143 }
4144
4145 pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid,
4146 &psessionEntry->dph.dphHashTable);
4147 if(NULL == pStaDs)
4148 {
4149 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4150 ("pStaDs is NULL \n")) ;
4151 status = eSIR_FAILURE;
4152 goto add_sta_error;
4153 }
4154
4155 pStaDs->bssId = pAddStaParams->bssIdx;
4156 pStaDs->staIndex = pAddStaParams->staIdx;
4157 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
4158 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
4159 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
4160 pStaDs->valid = 1 ;
4161#ifdef FEATURE_WLAN_TDLS_INTERNAL
4162 status = limSendSmeTdlsAddPeerInd(pMac, psessionEntry->smeSessionId,
4163 pStaDs, eSIR_SUCCESS ) ;
4164 if(eSIR_FAILURE == status)
4165 {
4166 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4167 ("Peer IND msg to SME failed\n")) ;
4168 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
4169 return eSIR_FAILURE ;
4170 }
4171
4172 /*
4173 * Now, there is two things a) ADD STA RSP for ADD STA request sent
4174 * after recieving discovery request from Peer.
4175 * now we have to send discovery response, if there is any pending
4176 * discovery equest..
4177 */
4178 do
4179 {
4180 tSirTdlsPeerInfo *peerInfo = limTdlsFindDisPeer(pMac,
4181 pAddStaParams->staMac) ;
4182
4183
4184 if(peerInfo)
4185 {
4186 /*
4187 * send TDLS discovery response frame on direct link, state machine
4188 * is rolling.., once discovery response is get Acked, we will
4189 * send response to SME based on TxComplete callback results
4190 */
4191 limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
4192 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
4193 }
4194 } while(0) ;
4195#else
4196 status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId,
4197 pAddStaParams->staMac, pStaDs, status) ;
4198 if(eSIR_FAILURE == status)
4199 {
4200 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4201 ("Peer IND msg to SME failed\n")) ;
4202 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
4203 }
4204 return status;
4205
4206#endif
4207add_sta_error:
4208 status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId,
4209 pAddStaParams->staMac, NULL, status) ;
4210 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
4211 return status ;
4212}
4213
4214/*
4215 * FUNCTION: Populate Link Identifier element IE
4216 *
4217 */
4218
4219
4220void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
4221 tDot11fIELinkIdentifier *linkIden,
4222 tSirMacAddr peerMac, tANI_U8 reqType)
4223{
4224 //tANI_U32 size = sizeof(tSirMacAddr) ;
4225 tANI_U8 *initStaAddr = NULL ;
4226 tANI_U8 *respStaAddr = NULL ;
4227
4228 (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
4229 (respStaAddr = linkIden->RespStaAddr))
4230 : ((respStaAddr = linkIden->InitStaAddr ),
4231 (initStaAddr = linkIden->RespStaAddr)) ;
4232 palCopyMemory( pMac->hHdd, (tANI_U8 *)linkIden->bssid,
4233 (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ;
4234
4235 palCopyMemory( pMac->hHdd, (tANI_U8 *)initStaAddr,
4236 psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
4237
4238 palCopyMemory( pMac->hHdd, (tANI_U8 *)respStaAddr, (tANI_U8 *) peerMac,
4239 sizeof( tSirMacAddr ));
4240
4241 linkIden->present = 1 ;
4242 return ;
4243
4244}
4245
4246void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac,
4247 tDot11fIEExtCap *extCapability)
4248{
4249 extCapability->TDLSPeerPSMSupp = PEER_PSM_SUPPORT ;
4250 extCapability->TDLSPeerUAPSDBufferSTA = PEER_BUFFER_STA_SUPPORT ;
4251 extCapability->TDLSChannelSwitching = CH_SWITCH_SUPPORT ;
4252 extCapability->TDLSSupport = TDLS_SUPPORT ;
4253 extCapability->TDLSProhibited = TDLS_PROHIBITED ;
4254 extCapability->TDLSChanSwitProhibited = TDLS_CH_SWITCH_PROHIBITED ;
4255 extCapability->present = 1 ;
4256 return ;
4257}
4258
4259#ifdef FEATURE_WLAN_TDLS_INTERNAL
4260/*
4261 * Public Action frame common processing
4262 * This Function will be moved/merged to appropriate place
4263 * once other public action frames (particularly 802.11k)
4264 * is in place
4265 */
4266void limProcessTdlsPublicActionFrame(tpAniSirGlobal pMac, tANI_U32 *pBd,
4267 tpPESession psessionEntry)
4268{
4269 tANI_U32 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
4270 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd) ;
4271 tANI_S8 rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pBd) ;
4272
4273 limProcessTdlsDisRspFrame(pMac, pBody, frameLen, rssi, psessionEntry) ;
4274 return ;
4275}
4276
4277eHalStatus limTdlsPrepareSetupReqFrame(tpAniSirGlobal pMac,
4278 tLimTdlsLinkSetupInfo *linkSetupInfo,
4279 tANI_U8 dialog, tSirMacAddr peerMac,
4280 tpPESession psessionEntry)
4281{
4282 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
4283
4284 /*
4285 * we allocate the TDLS setup Peer Memory here, we will free'd this
4286 * memory after teardown, if the link is successfully setup or
4287 * free this memory if any timeout is happen in link setup procedure
4288 */
4289 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
4290 (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
4291 {
4292 limLog( pMac, LOGP,
4293 FL( "Unable to allocate memory during ADD_STA\n" ));
4294 VOS_ASSERT(0) ;
4295 return eSIR_MEM_ALLOC_FAILED;
4296 }
4297 setupPeer->dialog = dialog ;
4298 setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
4299 setupPeer->tdls_link_state = TDLS_LINK_SETUP_START_STATE ;
4300
4301 /* TDLS_sessionize: remember sessionId for future */
4302 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
4303 setupPeer->tdls_bIsResponder = 1;
4304
4305 /*
4306 * we only populate peer MAC, so it can assit us to find the
4307 * TDLS peer after response/or after response timeout
4308 */
4309 palCopyMemory(pMac->hHdd, setupPeer->peerMac, peerMac,
4310 sizeof(tSirMacAddr)) ;
4311 /* format TDLS discovery request frame and transmit it */
4312 limSendTdlsLinkSetupReqFrame(pMac, peerMac, dialog, psessionEntry, NULL, 0) ;
4313
4314 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
4315 &setupPeer->gLimTdlsLinkSetupRspTimeoutTimer,
4316 (tANI_U32)setupPeer->peerMac,
4317 WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT,
4318 SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT) ;
4319 /* update setup peer list */
4320 setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
4321 linkSetupInfo->tdlsLinkSetupList = setupPeer ;
4322
4323 /* in case of success, eWNI_SME_TDLS_LINK_START_RSP is sent back to
4324 * SME later when TDLS setup cnf TX complete is successful. --> see
4325 * limTdlsSetupCnfTxComplete()
4326 */
4327 return eSIR_SUCCESS ;
4328}
4329#endif
4330
4331/*
4332 * Process Send Mgmt Request from SME and transmit to AP.
4333 */
4334tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac,
4335 tANI_U32 *pMsgBuf)
4336{
4337 /* get all discovery request parameters */
4338 tSirTdlsSendMgmtReq *pSendMgmtReq = (tSirTdlsSendMgmtReq*) pMsgBuf ;
4339 tpPESession psessionEntry;
4340 tANI_U8 sessionId;
4341 tSirResultCodes resultCode = eSIR_SME_INVALID_PARAMETERS;
4342
4343 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4344 ("Send Mgmt Recieved\n")) ;
4345
4346 if((psessionEntry = peFindSessionByBssid(pMac, pSendMgmtReq->bssid, &sessionId))
4347 == NULL)
4348 {
4349 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4350 "PE Session does not exist for given sme sessionId %d\n",
4351 pSendMgmtReq->sessionId);
4352 goto lim_tdls_send_mgmt_error;
4353 }
4354
4355 /* check if we are in proper state to work as TDLS client */
4356 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
4357 {
4358 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4359 "send mgmt received in wrong system Role %d\n",
4360 psessionEntry->limSystemRole);
4361 goto lim_tdls_send_mgmt_error;
4362 }
4363
4364 /*
4365 * if we are still good, go ahead and check if we are in proper state to
4366 * do TDLS discovery req/rsp/....frames.
4367 */
4368 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
4369 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
4370 {
4371
4372 limLog(pMac, LOGE, "send mgmt received in invalid LIMsme \
4373 state (%d)\n", psessionEntry->limSmeState);
4374 goto lim_tdls_send_mgmt_error;
4375 }
4376
4377 switch( pSendMgmtReq->reqType )
4378 {
4379 case SIR_MAC_TDLS_DIS_REQ:
4380 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4381 "Transmit Discovery Request Frame\n") ;
4382 /* format TDLS discovery request frame and transmit it */
4383 limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog,
4384 psessionEntry) ;
4385 resultCode = eSIR_SME_SUCCESS;
4386 break;
4387 case SIR_MAC_TDLS_DIS_RSP:
4388 {
4389 //Send a response mgmt action frame
4390 limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac,
4391 pSendMgmtReq->dialog, psessionEntry) ;
4392 resultCode = eSIR_SME_SUCCESS;
4393 }
4394 break;
4395 case SIR_MAC_TDLS_SETUP_REQ:
4396 {
4397 limSendTdlsLinkSetupReqFrame(pMac,
4398 pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry,
4399 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
4400 resultCode = eSIR_SME_SUCCESS;
4401 }
4402 break;
4403 case SIR_MAC_TDLS_SETUP_RSP:
4404 {
4405 limSendTdlsSetupRspFrame(pMac,
4406 pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode,
4407 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
4408 resultCode = eSIR_SME_SUCCESS;
4409 }
4410 break;
4411 case SIR_MAC_TDLS_SETUP_CNF:
4412 {
4413 limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog,
4414 psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
4415 resultCode = eSIR_SME_SUCCESS;
4416 }
4417 break;
4418 case SIR_MAC_TDLS_TEARDOWN:
4419 {
4420 limSendTdlsTeardownFrame(pMac,
4421 pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, psessionEntry,
4422 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
4423 resultCode = eSIR_SME_SUCCESS;
4424 }
4425 break;
4426 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
4427 {
4428 }
4429 break;
4430 case SIR_MAC_TDLS_CH_SWITCH_REQ:
4431 {
4432 }
4433 break;
4434 case SIR_MAC_TDLS_CH_SWITCH_RSP:
4435 {
4436 }
4437 break;
4438 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
4439 {
4440 }
4441 break;
4442 default:
4443 break;
4444 }
4445
4446lim_tdls_send_mgmt_error:
4447
4448 limSendSmeRsp( pMac, eWNI_SME_TDLS_SEND_MGMT_RSP,
4449 resultCode, pSendMgmtReq->sessionId, pSendMgmtReq->transactionId);
4450
4451 return eSIR_SUCCESS;
4452}
4453
4454/*
4455 * Once link is teardown, send Del Peer Ind to SME
4456 */
4457static eHalStatus limSendSmeTdlsDelStaRsp(tpAniSirGlobal pMac,
4458 tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs,
4459 tANI_U8 status)
4460{
4461 tSirMsgQ mmhMsg = {0} ;
4462 tSirTdlsDelStaRsp *pDelSta = NULL ;
4463 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP ;
4464 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &pDelSta,
4465 (sizeof(tSirTdlsDelStaRsp))))
4466 {
4467 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4468 return eSIR_FAILURE;
4469 }
4470
4471 pDelSta->sessionId = sessionId;
4472 pDelSta->statusCode = status ;
4473 if( pStaDs )
4474 {
4475 pDelSta->staId = pStaDs->staIndex ;
4476 }
4477 if( peerMac )
4478 {
4479 palCopyMemory(pMac->hHdd, pDelSta->peerMac, peerMac, sizeof(tSirMacAddr));
4480 }
4481
4482 pDelSta->length = sizeof(tSirTdlsDelStaRsp) ;
4483 pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP ;
4484
4485 mmhMsg.bodyptr = pDelSta;
4486
4487 mmhMsg.bodyval = 0;
4488 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4489 return eSIR_SUCCESS ;
4490
4491}
4492
4493/*
4494 * Process Send Mgmt Request from SME and transmit to AP.
4495 */
4496tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac,
4497 tANI_U32 *pMsgBuf)
4498{
4499 /* get all discovery request parameters */
4500 tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq*) pMsgBuf ;
4501 tpPESession psessionEntry;
4502 tANI_U8 sessionId;
4503 tLimTdlsLinkSetupPeer setupPeer = {0};
4504
4505 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4506 ("Send Mgmt Recieved\n")) ;
4507
4508 if((psessionEntry = peFindSessionByBssid(pMac, pAddStaReq->bssid, &sessionId))
4509 == NULL)
4510 {
4511 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4512 "PE Session does not exist for given sme sessionId %d\n",
4513 pAddStaReq->sessionId);
4514 goto lim_tdls_add_sta_error;
4515 }
4516
4517 /* check if we are in proper state to work as TDLS client */
4518 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
4519 {
4520 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4521 "send mgmt received in wrong system Role %d\n",
4522 psessionEntry->limSystemRole);
4523 goto lim_tdls_add_sta_error;
4524 }
4525
4526 /*
4527 * if we are still good, go ahead and check if we are in proper state to
4528 * do TDLS discovery req/rsp/....frames.
4529 */
4530 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
4531 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
4532 {
4533
4534 limLog(pMac, LOGE, "send mgmt received in invalid LIMsme \
4535 state (%d)\n", psessionEntry->limSmeState);
4536 goto lim_tdls_add_sta_error;
4537 }
4538
4539 pMac->lim.gLimAddStaTdls = true ;
4540
4541 /* To start with, send add STA request to HAL */
4542 if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, pAddStaReq->peerMac,
4543 &setupPeer, psessionEntry))
4544 {
4545 VOS_ASSERT(0) ;
4546 goto lim_tdls_add_sta_error;
4547 }
4548 return eSIR_SUCCESS;
4549lim_tdls_add_sta_error:
4550 limSendSmeTdlsAddStaRsp(pMac,
4551 pAddStaReq->sessionId, pAddStaReq->peerMac, NULL, eSIR_FAILURE );
4552
4553 return eSIR_SUCCESS;
4554}
4555/*
4556 * Process Del Sta Request from SME .
4557 */
4558tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac,
4559 tANI_U32 *pMsgBuf)
4560{
4561 /* get all discovery request parameters */
4562 tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq*) pMsgBuf ;
4563 tpPESession psessionEntry;
4564 tANI_U8 sessionId;
4565 tpDphHashNode pStaDs = NULL ;
4566
4567 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4568 ("Send Mgmt Recieved\n")) ;
4569
4570 if((psessionEntry = peFindSessionByBssid(pMac, pDelStaReq->bssid, &sessionId))
4571 == NULL)
4572 {
4573 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4574 "PE Session does not exist for given sme sessionId %d\n",
4575 pDelStaReq->sessionId);
4576 limSendSmeTdlsDelStaRsp(pMac, 0, pDelStaReq->peerMac,
4577 NULL, eSIR_FAILURE) ;
4578 return eSIR_FAILURE;
4579 }
4580
4581 /* check if we are in proper state to work as TDLS client */
4582 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
4583 {
4584 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4585 "Del sta received in wrong system Role %d\n",
4586 psessionEntry->limSystemRole);
4587 goto lim_tdls_del_sta_error;
4588 }
4589
4590 /*
4591 * if we are still good, go ahead and check if we are in proper state to
4592 * do TDLS discovery req/rsp/....frames.
4593 */
4594 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
4595 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
4596 {
4597
4598 limLog(pMac, LOGE, "Del Sta received in invalid LIMsme \
4599 state (%d)\n", psessionEntry->limSmeState);
4600 goto lim_tdls_del_sta_error;
4601 }
4602
4603 pStaDs = limTdlsDelSta(pMac, pDelStaReq->peerMac, psessionEntry) ;
4604
4605 /* now send indication to SME-->HDD->TL to remove STA from TL */
4606
4607 if(pStaDs)
4608 {
4609 limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
4610 pStaDs, eSIR_SUCCESS) ;
4611 return eSIR_SUCCESS;
4612
4613 }
4614
4615lim_tdls_del_sta_error:
4616 limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
4617 NULL, eSIR_FAILURE) ;
4618
4619 return eSIR_SUCCESS;
4620}
4621#endif