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