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