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