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