blob: 4936b289bb2e0ba22f8494d2d0086a26d2b5106a [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
Gopichand Nakkala681989c2013-03-06 22:27:48 -0800139static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac,
140 tSirTdlsAddStaReq *pAddStaReq,
141 tpPESession psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -0800142void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
143 tDot11fIELinkIdentifier *linkIden,
144 tSirMacAddr peerMac , tANI_U8 reqType) ;
145void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac,
146 tDot11fIEExtCap *extCapability) ;
Gopichand Nakkala681989c2013-03-06 22:27:48 -0800147
148void limLogVHTCap(tpAniSirGlobal pMac,
149 tDot11fIEVHTCaps *pDot11f);
150tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac,
151 tpSirSupportedRates pRates,
152 tDot11fIEVHTCaps *pPeerVHTCaps,
153 tpPESession psessionEntry);
154ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode);
Kiran V1ccee932012-12-12 14:49:46 -0800155/*
156 * TDLS data frames will go out/come in as non-qos data.
157 * so, eth_890d_header will be aligned access..
158 */
159static const tANI_U8 eth_890d_header[] =
160{
161 0xaa, 0xaa, 0x03, 0x00,
162 0x00, 0x00, 0x89, 0x0d,
163} ;
164
165/*
166 * type of links used in TDLS
167 */
168enum tdlsLinks
169{
170 TDLS_LINK_AP,
171 TDLS_LINK_DIRECT
172} eTdlsLink ;
173
174/*
175 * node status in node searching
176 */
177enum tdlsLinkNodeStatus
178{
179 TDLS_NODE_NOT_FOUND,
180 TDLS_NODE_FOUND
181} eTdlsLinkNodeStatus ;
182
183
184enum tdlsReqType
185{
186 TDLS_INITIATOR,
187 TDLS_RESPONDER
188} eTdlsReqType ;
189
190typedef enum tdlsLinkSetupStatus
191{
192 TDLS_SETUP_STATUS_SUCCESS = 0,
193 TDLS_SETUP_STATUS_FAILURE = 37
194}etdlsLinkSetupStatus ;
195
196/* some local defines */
197#define LINK_IDEN_BSSID_OFFSET (0)
198#define PEER_MAC_OFFSET (12)
199#define STA_MAC_OFFSET (6)
200#define LINK_IDEN_ELE_ID (101)
201//#define LINK_IDEN_LENGTH (18)
202#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
203#define PTI_LINK_IDEN_OFFSET (5)
204#define PTI_BUF_STATUS_OFFSET (25)
205
206/* TODO, Move this parameters to configuration */
207#define PEER_PSM_SUPPORT (0)
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700208#define PEER_BUFFER_STA_SUPPORT (0)
Kiran V1ccee932012-12-12 14:49:46 -0800209#define CH_SWITCH_SUPPORT (0)
210#define TDLS_SUPPORT (1)
211#define TDLS_PROHIBITED (0)
212#define TDLS_CH_SWITCH_PROHIBITED (1)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800213/** @brief Set bit manipulation macro */
214#define SET_BIT(value,mask) ((value) |= (1 << (mask)))
215/** @brief Clear bit manipulation macro */
216#define CLEAR_BIT(value,mask) ((value) &= ~(1 << (mask)))
217/** @brief Check bit manipulation macro */
218#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
219
220#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
221 if ((aid) < (sizeof(tANI_U32) << 3)) \
222 SET_BIT(peer_bitmap[0], (aid)); \
223 else if ((aid) < (sizeof(tANI_U32) << 4)) \
224 SET_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3)));
225
226#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
227 if ((aid) < (sizeof(tANI_U32) << 3)) \
228 CLEAR_BIT(peer_bitmap[0], (aid)); \
229 else if ((aid) < (sizeof(tANI_U32) << 4)) \
230 CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3)));
231
Kiran V1ccee932012-12-12 14:49:46 -0800232
233#ifdef LIM_DEBUG_TDLS
234#define TDLS_CASE_RETURN_STRING(x) case (x): return( ((const tANI_U8*)#x) + 8); /* 8 = remove redundant SIR_MAC_ */
235
236#ifdef FEATURE_WLAN_TDLS
237#define WNI_CFG_TDLS_DISCOVERY_RSP_WAIT (100)
238#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
239#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
240#endif
241
242const tANI_U8* limTraceTdlsActionString( tANI_U8 tdlsActionCode )
243{
244 switch( tdlsActionCode )
245 {
246 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
247 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
248 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
249 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
250 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
251 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
252 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
253 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
254 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
255 TDLS_CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
256 }
257 return (const tANI_U8*)"UNKNOWN";
258}
259#endif
260#if 0
261static void printMacAddr(tSirMacAddr macAddr)
262{
263 int i = 0 ;
264 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, (" Mac Addr: "));
265
266 for(i = 0 ; i < 6; i++)
267 {
268 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
269 (" %02x "), macAddr[i]);
270 }
271 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("\n"));
272 return ;
273}
274#endif
Kiran V1ccee932012-12-12 14:49:46 -0800275/*
276 * initialize TDLS setup list and related data structures.
277 */
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800278void limInitTdlsData(tpAniSirGlobal pMac, tpPESession pSessionEntry)
Kiran V1ccee932012-12-12 14:49:46 -0800279{
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800280#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -0800281 pMac->lim.gLimTdlsDisResultList = NULL ;
282 pMac->lim.gLimTdlsDisStaCount = 0 ;
283 palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsDisReq,
284 sizeof(tSirTdlsDisReq));
285 palZeroMemory(pMac->hHdd, &pMac->lim.gLimTdlsLinkSetupInfo,
286 sizeof(tLimTdlsLinkSetupInfo));
287 pMac->lim.gAddStaDisRspWait = 0 ;
288
289#ifdef FEATURE_WLAN_TDLS_NEGATIVE
290 /* when reassociated, negative behavior will not be kept */
291 /* you have to explicitly enable negative behavior per (re)association */
292 pMac->lim.gLimTdlsNegativeBehavior = 0;
293#endif
Gopichand Nakkala777e6032012-12-31 16:39:21 -0800294#endif
295 limInitPeerIdxpool(pMac, pSessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -0800296
297 return ;
298}
Kiran V1ccee932012-12-12 14:49:46 -0800299#ifdef FEATURE_WLAN_TDLS_NEGATIVE
300void limTdlsSetNegativeBehavior(tpAniSirGlobal pMac, tANI_U8 value, tANI_BOOLEAN on)
301{
302 if(on) {
303 if(value == 255)
304 pMac->lim.gLimTdlsNegativeBehavior = 0XFFFFFFFF;
305 else
306 pMac->lim.gLimTdlsNegativeBehavior |= (1 << (value-1));
307 }
308 else {
309 if(value == 255)
310 pMac->lim.gLimTdlsNegativeBehavior = 0;
311 else
312 pMac->lim.gLimTdlsNegativeBehavior &= ~(1 << (value-1));
313 }
314 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,("%d %d -> gLimTdlsNegativeBehavior= 0x%lx\n"), \
315 value, on, pMac->lim.gLimTdlsNegativeBehavior));
316}
317#endif
318#if 0
319/*
320 * This function is used for creating TDLS public Action frame to
321 * transmit on Direct link
322 */
323static void limPreparesActionFrameHdr(tpAniSirGlobal pMac, tANI_U8 *pFrame,
324 tANI_U8 type, tANI_U8 subType,
325 tANI_U8 *link_iden )
326{
327 tpSirMacMgmtHdr pMacHdr ;
328 tANI_U8 *bssid = link_iden ;
329#if 0
330 tANI_U8 *staMac = (tANI_U8 *)(bssid + sizeof(tSirMacAddr)) ;
331 tANI_U8 *peerMac = (tANI_U8 *) (staMac + sizeof(tSirMacAddr)) ;
332#else
333 tANI_U8 *peerMac = (tANI_U8 *) (bssid + sizeof(tSirMacAddr)) ;
334 tANI_U8 *staMac = (tANI_U8 *)(peerMac + sizeof(tSirMacAddr)) ;
335#endif
336 tANI_U8 toDs = ANI_TXDIR_IBSS ;
337
338 pMacHdr = (tpSirMacMgmtHdr) (pFrame);
339
340 /*
341 * prepare 802.11 header
342 */
343 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
344 pMacHdr->fc.type = type ;
345 pMacHdr->fc.subType = subType ;
346 /*
347 * TL is not setting up below fields, so we are doing it here
348 */
349 pMacHdr->fc.toDS = toDs ;
350 pMacHdr->fc.powerMgmt = 0 ;
351
352
353 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, peerMac,
354 sizeof( tSirMacAddr ));
355 palCopyMemory( pMac->hHdd,
356 (tANI_U8 *) pMacHdr->sa,
357 staMac, sizeof( tSirMacAddr ));
358
359 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->bssId,
360 bssid, sizeof( tSirMacAddr ));
361
362 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"), \
363 pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5], \
364 pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5], \
365 pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2], \
366 pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5]));
367
368 return ;
369}
370#endif
371/*
372 * prepare TDLS frame header, it includes
373 * | | | |
374 * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
375 * | | | |
376 */
377static tANI_U32 limPrepareTdlsFrameHeader(tpAniSirGlobal pMac, tANI_U8* pFrame,
378 tDot11fIELinkIdentifier *link_iden, tANI_U8 tdlsLinkType, tANI_U8 reqType, tpPESession psessionEntry )
379{
380 tpSirMacMgmtHdr pMacHdr ;
381 tANI_U32 header_offset = 0 ;
382 tANI_U8 *addr1 = NULL ;
383 tANI_U8 *addr3 = NULL ;
384 tANI_U8 toDs = (tdlsLinkType == TDLS_LINK_AP)
385 ? ANI_TXDIR_TODS :ANI_TXDIR_IBSS ;
386 tANI_U8 *peerMac = (reqType == TDLS_INITIATOR)
387 ? link_iden->RespStaAddr : link_iden->InitStaAddr;
388 tANI_U8 *staMac = (reqType == TDLS_INITIATOR)
389 ? link_iden->InitStaAddr : link_iden->RespStaAddr;
390
391 pMacHdr = (tpSirMacMgmtHdr) (pFrame);
392
393 /*
394 * if TDLS frame goes through the AP link, it follows normal address
395 * pattern, if TDLS frame goes thorugh the direct link, then
396 * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
397 */
398 (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
399 (addr3 = (peerMac)))
400 : ((addr1 = (peerMac)),
401 (addr3 = (link_iden->bssid))) ;
402 /*
403 * prepare 802.11 header
404 */
405 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
406 pMacHdr->fc.type = SIR_MAC_DATA_FRAME ;
407 pMacHdr->fc.subType = SIR_MAC_DATA_DATA ;
408 /*
409 * TL is not setting up below fields, so we are doing it here
410 */
411 pMacHdr->fc.toDS = toDs ;
412 pMacHdr->fc.powerMgmt = 0 ;
413 pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE)? 0 : 1;
414
415
416 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->da, (tANI_U8 *)addr1,
417 sizeof( tSirMacAddr ));
418 palCopyMemory( pMac->hHdd,
419 (tANI_U8 *) pMacHdr->sa,
420 (tANI_U8 *) staMac,
421 sizeof( tSirMacAddr ));
422
423 palCopyMemory( pMac->hHdd, (tANI_U8 *) pMacHdr->bssId,
424 (tANI_U8 *) (addr3), sizeof( tSirMacAddr ));
425
426 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"), \
427 (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "TD", \
428 pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5], \
429 pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5], \
430 pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2], \
431 pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5]));
432
433 //printMacAddr(pMacHdr->bssId) ;
434 //printMacAddr(pMacHdr->sa) ;
435 //printMacAddr(pMacHdr->da) ;
436
437 header_offset += sizeof(tSirMacMgmtHdr) ;
438 /*
439 * Now form RFC1042 header
440 */
441 palCopyMemory(pMac->hHdd, (tANI_U8 *)(pFrame + header_offset),
442 (tANI_U8 *)eth_890d_header , sizeof(eth_890d_header)) ;
443
444 header_offset += sizeof(eth_890d_header) ;
445
446 /* add payload type as TDLS */
447 *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS ;
448
449 return(header_offset += PAYLOAD_TYPE_TDLS_SIZE) ;
450}
451
452/*
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800453 * TX Complete for Management frames
454 */
455 eHalStatus limMgmtTXComplete(tpAniSirGlobal pMac,
456 tANI_U32 txCompleteSuccess)
457{
458 tpPESession psessionEntry = NULL ;
459
460 if (0xff != pMac->lim.mgmtFrameSessionId)
461 {
462 psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.mgmtFrameSessionId);
463 if (NULL == psessionEntry)
464 {
465 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
466 ("%s: sessionID %d is not found"), __func__, pMac->lim.mgmtFrameSessionId);
467 return eHAL_STATUS_FAILURE;
468 }
469 limSendSmeMgmtTXCompletion(pMac, psessionEntry, txCompleteSuccess);
470 pMac->lim.mgmtFrameSessionId = 0xff;
471 }
472 return eHAL_STATUS_SUCCESS;
473}
474
475/*
Kiran V1ccee932012-12-12 14:49:46 -0800476 * This function can be used for bacst or unicast discovery request
477 * We are not differentiating it here, it will all depnds on peer MAC address,
478 */
479tSirRetStatus limSendTdlsDisReqFrame(tpAniSirGlobal pMac, tSirMacAddr peer_mac,
480 tANI_U8 dialog, tpPESession psessionEntry)
481{
482 tDot11fTDLSDisReq tdlsDisReq ;
483 tANI_U32 status = 0 ;
484 tANI_U32 nPayload = 0 ;
485 tANI_U32 size = 0 ;
486 tANI_U32 nBytes = 0 ;
487 tANI_U32 header_offset = 0 ;
488 tANI_U8 *pFrame;
489 void *pPacket;
490 eHalStatus halstatus;
Hoonki Lee6c6822a2013-02-06 14:10:46 -0800491#ifndef NO_PAD_TDLS_MIN_8023_SIZE
492 tANI_U32 padLen = 0;
493#endif
Kiran V1ccee932012-12-12 14:49:46 -0800494
495 /*
496 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
497 * and then hand it off to 'dot11fPackProbeRequest' (for
498 * serialization). We start by zero-initializing the structure:
499 */
500 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisReq,
501 sizeof( tDot11fTDLSDisReq ) );
502
503 /*
504 * setup Fixed fields,
505 */
506 tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS ;
507 tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ ;
508 tdlsDisReq.DialogToken.token = dialog ;
509
510
511 size = sizeof(tSirMacAddr) ;
512
513 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
514 peer_mac, TDLS_INITIATOR) ;
515
516 /*
517 * now we pack it. First, how much space are we going to need?
518 */
519 status = dot11fGetPackedTDLSDisReqSize( pMac, &tdlsDisReq, &nPayload);
520 if ( DOT11F_FAILED( status ) )
521 {
522 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
523 "or a discovery Request (0x%08x).\n"), status );
524 /* We'll fall back on the worst case scenario: */
525 nPayload = sizeof( tDot11fTDLSDisReq );
526 }
527 else if ( DOT11F_WARNED( status ) )
528 {
529 limLog( pMac, LOGW, FL("There were warnings while calculating"
530 "the packed size for a discovery Request ("
531 "0x%08x).\n"), status );
532 }
533
534 /*
535 * This frame is going out from PE as data frames with special ethertype
536 * 89-0d.
537 * 8 bytes of RFC 1042 header
538 */
539
540
541 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
542 + sizeof( eth_890d_header )
543 + PAYLOAD_TYPE_TDLS_SIZE ;
544
Hoonki Lee6c6822a2013-02-06 14:10:46 -0800545#ifndef NO_PAD_TDLS_MIN_8023_SIZE
546 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
547 Hence AP itself padding some bytes, which caused teardown packet is dropped at
548 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
549 */
550 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE)
551 {
552 padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ;
553
554 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
555 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
556 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
557
558 nBytes += padLen;
559 }
560#endif
561
Kiran V1ccee932012-12-12 14:49:46 -0800562 /* Ok-- try to allocate memory from MGMT PKT pool */
563
564 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
565 ( tANI_U16 )nBytes, ( void** ) &pFrame,
566 ( void** ) &pPacket );
567 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
568 {
569 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
570 "Discovery Request.\n"), nBytes );
571 return eSIR_MEM_ALLOC_FAILED;
572 }
573
574 /* zero out the memory */
575 palZeroMemory( pMac->hHdd, pFrame, nBytes );
576
577 /*
578 * IE formation, memory allocation is completed, Now form TDLS discovery
579 * request frame
580 */
581
582 /* fill out the buffer descriptor */
583
584 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
585 LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP, TDLS_INITIATOR, psessionEntry) ;
586
587#ifdef FEATURE_WLAN_TDLS_NEGATIVE
588 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_REQ)
589 {
590 tdlsDisReq.LinkIdentifier.bssid[4] = 0xde;
591 tdlsDisReq.LinkIdentifier.bssid[5] = 0xad;
592 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
593 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Req\n"), \
594 tdlsDisReq.LinkIdentifier.bssid[0],
595 tdlsDisReq.LinkIdentifier.bssid[1],
596 tdlsDisReq.LinkIdentifier.bssid[2],
597 tdlsDisReq.LinkIdentifier.bssid[3],
598 tdlsDisReq.LinkIdentifier.bssid[4],
599 tdlsDisReq.LinkIdentifier.bssid[5]);
600 }
601#endif
602 status = dot11fPackTDLSDisReq( pMac, &tdlsDisReq, pFrame
603 + header_offset, nPayload, &nPayload );
604
605 if ( DOT11F_FAILED( status ) )
606 {
607 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
608 (0x%08x).\n"), status );
609 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
610 ( void* ) pFrame, ( void* ) pPacket );
611 return eSIR_FAILURE;
612 }
613 else if ( DOT11F_WARNED( status ) )
614 {
615 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
616 "Discovery Request (0x%08x).\n") );
617 }
618
Hoonki Lee6c6822a2013-02-06 14:10:46 -0800619#ifndef NO_PAD_TDLS_MIN_8023_SIZE
620 if (padLen != 0)
621 {
622 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
623 tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload;
624 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
625 padVendorSpecific[0] = 221;
626 padVendorSpecific[1] = padLen - 2;
627 padVendorSpecific[2] = 0x00;
628 padVendorSpecific[3] = 0xA0;
629 padVendorSpecific[4] = 0xC6;
630
631 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
632 padLen ));
633
634 /* padding zero if more than 5 bytes are required */
635 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
636 palZeroMemory( pMac->hHdd, pFrame + header_offset + nPayload + MIN_VENDOR_SPECIFIC_IE_SIZE, padLen - MIN_VENDOR_SPECIFIC_IE_SIZE);
637 }
638#endif
Kiran V1ccee932012-12-12 14:49:46 -0800639
Hoonki Lee1090c6a2013-01-16 17:40:54 -0800640 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 -0800641 SIR_MAC_TDLS_DIS_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ) ));
642
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800643 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
Kiran V1ccee932012-12-12 14:49:46 -0800644 HAL_TXRX_FRM_802_11_DATA,
645 ANI_TXDIR_TODS,
646 7,
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800647 limTxComplete, pFrame,
648 limMgmtTXComplete,
649 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME);
Kiran V1ccee932012-12-12 14:49:46 -0800650 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
651 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800652 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -0800653 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
654 return eSIR_FAILURE;
Kiran V1ccee932012-12-12 14:49:46 -0800655 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800656 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -0800657
658 return eSIR_SUCCESS;
659
660}
661
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800662#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -0800663/*
664 * Once Discovery response is sent successfully (or failure) on air, now send
665 * response to PE and send del STA to HAL.
666 */
667eHalStatus limTdlsDisRspTxComplete(tpAniSirGlobal pMac,
668 tANI_U32 txCompleteSuccess)
669{
670 eHalStatus status = eHAL_STATUS_SUCCESS ;
Kiran V1ccee932012-12-12 14:49:46 -0800671 tpDphHashNode pStaDs = NULL ;
672 tSirTdlsPeerInfo *peerInfo = 0 ;
673
674 /* find peer by looking into the list by expected state */
675 peerInfo = limTdlsFindDisPeerByState(pMac, TDLS_DIS_RSP_SENT_WAIT_STATE) ;
676
677 if(NULL == peerInfo)
678 {
679 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
680 ("DisRspTxComplete: No TDLS state machine waits for this event\n"));
681 VOS_ASSERT(0) ;
682 return eHAL_STATUS_FAILURE;
683 }
684
685 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_DONE_STATE ;
686
687 if(peerInfo->delStaNeeded)
688 {
689 tpPESession psessionEntry;
690
691 peerInfo->delStaNeeded = false ;
692 psessionEntry = peFindSessionBySessionId (pMac, peerInfo->sessionId);
693
694 if(NULL == psessionEntry)
695 {
696 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
697 ("DisRspTxComplete: sessionID %d is not found\n"), peerInfo->sessionId);
698 return eHAL_STATUS_FAILURE;
699 }
700 /* send del STA to remove context for this TDLS STA */
701 pStaDs = limTdlsDelSta(pMac, peerInfo->peerMac, psessionEntry) ;
702
703 /* now send indication to SME-->HDD->TL to remove STA from TL */
704 if(pStaDs)
705 {
706 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
707 pStaDs, eSIR_SUCCESS) ;
708 }
709 else
710 {
711 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
712 ("DisRspTxComplete: staDs not found for %02x:%02x:%02x:%02x:%02x:%02x\n"),
713 (peerInfo)->peerMac[0],
714 (peerInfo)->peerMac[1],
715 (peerInfo)->peerMac[2],
716 (peerInfo)->peerMac[3],
717 (peerInfo)->peerMac[4],
718 (peerInfo)->peerMac[5]) ;
719 VOS_ASSERT(0) ;
720 return eHAL_STATUS_FAILURE;
721 }
722 }
723
724 if(!txCompleteSuccess)
725 {
726 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
727 ("TX complete failure for Dis RSP"));
728 limSendSmeTdlsDisRsp(pMac, eSIR_FAILURE,
729 eWNI_SME_TDLS_DISCOVERY_START_IND) ;
730 status = eHAL_STATUS_FAILURE;
731 }
732 else
733 {
734 limSendSmeTdlsDisRsp(pMac, eSIR_SUCCESS,
735 eWNI_SME_TDLS_DISCOVERY_START_IND) ;
736 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
737 ("TX complete Success for Dis RSP"));
738 status = eHAL_STATUS_SUCCESS ;
739 }
740 //pMac->hal.pCBackFnTxComp = NULL ;
Kiran V1ccee932012-12-12 14:49:46 -0800741 return status ;
742
743}
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800744#endif
745
746#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -0800747/*
748 * Once setup CNF is sent successfully (or failure) on air, now send
749 * response to PE and send del STA to HAL.
750 */
751eHalStatus limTdlsSetupCnfTxComplete(tpAniSirGlobal pMac,
752 tANI_U32 txCompleteSuccess)
753{
754 eHalStatus status = eHAL_STATUS_SUCCESS ;
Kiran V1ccee932012-12-12 14:49:46 -0800755 tLimTdlsLinkSetupPeer *peerInfo = 0 ;
756 /* find peer by looking into the list by expected state */
757 limTdlsFindSetupPeerByState(pMac,
758 TDLS_LINK_SETUP_RSP_WAIT_STATE, &peerInfo) ;
759
760 if(NULL == peerInfo)
761 {
762 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
763 ("limTdlsSetupCnfTxComplete: No TDLS state machine waits for this event\n"));
764 VOS_ASSERT(0) ;
765 return eHAL_STATUS_FAILURE;
766 }
767
768 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
769 (peerInfo)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ;
770
771 if(!txCompleteSuccess)
772 {
773 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
774 ("TX complete Failure for setup CNF"));
775 limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE, (peerInfo)->peerMac,
776 eWNI_SME_TDLS_LINK_START_RSP) ;
777 status = eHAL_STATUS_FAILURE;
778 }
779 else
780 {
781 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
782 ("RSP-->SME peer MAC = %02x,%02x,%02x,%02x,%02x,%02x\n"),
783 (peerInfo)->peerMac[0],
784 (peerInfo)->peerMac[1],
785 (peerInfo)->peerMac[2],
786 (peerInfo)->peerMac[3],
787 (peerInfo)->peerMac[4],
788 (peerInfo)->peerMac[5]) ;
789
790 limSendSmeTdlsLinkStartRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
791 eWNI_SME_TDLS_LINK_START_RSP) ;
792
793 /* tdls_hklee: prepare PTI template and send it to HAL */
794 limTdlsLinkEstablish(pMac, (peerInfo)->peerMac);
795
796 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
797 ("TX complete Success for setup CNF"));
798 status = eHAL_STATUS_SUCCESS ;
799 }
800 //pMac->hal.pCBackFnTxComp = NULL ;
Kiran V1ccee932012-12-12 14:49:46 -0800801 return status ;
Kiran V1ccee932012-12-12 14:49:46 -0800802}
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800803#endif
Kiran V1ccee932012-12-12 14:49:46 -0800804
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800805#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -0800806/*
807 * Tx Complete for Teardown frame
808 */
809eHalStatus limTdlsTeardownTxComplete(tpAniSirGlobal pMac,
810 tANI_U32 txCompleteSuccess)
811{
812 eHalStatus status = eHAL_STATUS_SUCCESS ;
Kiran V1ccee932012-12-12 14:49:46 -0800813 tpDphHashNode pStaDs = NULL ;
814 tLimTdlsLinkSetupPeer *peerInfo = 0 ;
815 tpPESession psessionEntry = NULL ;
816 //tANI_U16 msgType = 0 ;
817
818 //tSirMacAddr peerMac = {0} ;
819 /* find peer by looking into the list by expected state */
820 limTdlsFindSetupPeerByState(pMac,
821 TDLS_LINK_TEARDOWN_START_STATE, &peerInfo) ;
822
823 if(NULL == peerInfo)
824 {
825 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
826 ("limTdlsTeardownTxComplete: No TDLS state machine waits for this event\n"));
827 VOS_ASSERT(0) ;
828 return eHAL_STATUS_FAILURE;
829 }
830
831 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
832 ("teardown peer Mac = %02x,%02x,%02x,%02x,%02x,%02x\n"),
833 (peerInfo)->peerMac[0] ,
834 (peerInfo)->peerMac[1] ,
835 (peerInfo)->peerMac[2] ,
836 (peerInfo)->peerMac[3] ,
837 (peerInfo)->peerMac[4] ,
838 (peerInfo)->peerMac[5] ) ;
839
840
841 //pMac->hal.pCBackFnTxComp = NULL ;
842
843 psessionEntry = peFindSessionBySessionId(pMac, (peerInfo)->tdls_sessionId);
844
845 if(NULL == psessionEntry)
846 {
847 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
848 ("limTdlsTeardownTxComplete: sessionID %d is not found\n"), (peerInfo)->tdls_sessionId);
849 VOS_ASSERT(0) ;
850 return eHAL_STATUS_FAILURE;
851 }
852
853 if(!txCompleteSuccess)
854 {
855 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
856 ("TX complete failure for Teardown \n")) ;
857
858 /*
859 * we should be sending Teradown to AP with status code
860 * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, we are not worried if
861 * that is delivered or not, any way we removing this peer STA from our
862 * list
863 */
864 if(NULL != psessionEntry)
865 {
866 limSendTdlsTeardownFrame(pMac, (peerInfo)->peerMac,
867 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE, psessionEntry, NULL, 0) ;
868 }
869 }
870
871 if(TDLS_LINK_SETUP_WAIT_STATE != (peerInfo)->tdls_prev_link_state)
872 {
873 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
874 (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ;
875 /* send del STA to remove context for this TDLS STA */
876 if(NULL != psessionEntry)
877 {
878 /* tdls_hklee: send message to HAL before it is deleted */
879 limTdlsLinkTeardown(pMac, (peerInfo)->peerMac) ;
880
881 pStaDs = limTdlsDelSta(pMac, (peerInfo)->peerMac, psessionEntry) ;
882 }
883
884 /* now send indication to SME-->HDD->TL to remove STA from TL */
885 if(!pStaDs)
886 {
887 VOS_ASSERT(0) ;
888 return eSIR_FAILURE ;
889 }
890 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
891 pStaDs, eSIR_SUCCESS) ;
892
893 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
894 ("TX complete SUCCESS for Teardown\n")) ;
895 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
896 ("Prev State = %d\n"), (peerInfo)->tdls_prev_link_state) ;
897 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
898 eWNI_SME_TDLS_TEARDOWN_RSP) ;
899 /* Delete Peer for Link Peer List */
900 limTdlsDelLinkPeer(pMac, (peerInfo)->peerMac) ;
901 }
902 else
903 {
904 (peerInfo)->tdls_prev_link_state = (peerInfo)->tdls_link_state ;
905 (peerInfo)->tdls_link_state = TDLS_LINK_TEARDOWN_DONE_STATE ;
906 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (peerInfo)->peerMac,
907 eWNI_SME_TDLS_TEARDOWN_IND) ;
908 }
909
910
911#if 0
912 /* if previous state is link restart, then restart link setup again */
913 if(TDLS_LINK_SETUP_RESTART_STATE == (peerInfo)->tdls_prev_link_state)
914 {
915 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
916 limTdlsPrepareSetupReqFrame(pMac, setupInfo, 37,
917 peerMac, psessionEntry) ;
918 }
919#endif
920 status = eHAL_STATUS_SUCCESS ;
Kiran V1ccee932012-12-12 14:49:46 -0800921 return status ;
922}
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800923#endif
Kiran V1ccee932012-12-12 14:49:46 -0800924
925/*
926 * Send TDLS discovery response frame on direct link.
927 */
928
929static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac,
930 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry)
931{
932 tDot11fTDLSDisRsp tdlsDisRsp ;
933 tANI_U16 caps = 0 ;
934 tANI_U32 status = 0 ;
935 tANI_U32 nPayload = 0 ;
936 tANI_U32 nBytes = 0 ;
937 tANI_U8 *pFrame;
938 void *pPacket;
939 eHalStatus halstatus;
940
941 /*
942 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
943 * and then hand it off to 'dot11fPackProbeRequest' (for
944 * serialization). We start by zero-initializing the structure:
945 */
946 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsDisRsp,
947 sizeof( tDot11fTDLSDisRsp ) );
948
949 /*
950 * setup Fixed fields,
951 */
952 tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
953 tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP ;
954 tdlsDisRsp.DialogToken.token = dialog ;
955
956 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisRsp.LinkIdentifier,
957 peerMac, TDLS_RESPONDER) ;
958
959 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
960 {
961 /*
962 * Could not get Capabilities value
963 * from CFG. Log error.
964 */
965 limLog(pMac, LOGP,
966 FL("could not retrieve Capabilities value\n"));
967 }
968 swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities );
969
970 /* populate supported rate IE */
971 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
972 &tdlsDisRsp.SuppRates, psessionEntry );
973
974 /* Populate extended supported rates */
975 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
976 &tdlsDisRsp.ExtSuppRates, psessionEntry );
977
978 /* Populate extended supported rates */
979 PopulateDot11fTdlsExtCapability( pMac, &tdlsDisRsp.ExtCap );
980
981 /* Include HT Capability IE */
982 //This does not depend on peer capabilities. If it is supported then it should be included
983 PopulateDot11fHTCaps( pMac, psessionEntry, &tdlsDisRsp.HTCaps );
984
985 /*
986 * now we pack it. First, how much space are we going to need?
987 */
988 status = dot11fGetPackedTDLSDisRspSize( pMac, &tdlsDisRsp, &nPayload);
989 if ( DOT11F_FAILED( status ) )
990 {
991 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
992 "or a discovery Request (0x%08x).\n"), status );
993 /* We'll fall back on the worst case scenario: */
994 nPayload = sizeof( tDot11fProbeRequest );
995 }
996 else if ( DOT11F_WARNED( status ) )
997 {
998 limLog( pMac, LOGW, FL("There were warnings while calculating"
999 "the packed size for a discovery Request ("
1000 "0x%08x).\n"), status );
1001 }
1002
1003 /*
1004 * This frame is going out from PE as data frames with special ethertype
1005 * 89-0d.
1006 * 8 bytes of RFC 1042 header
1007 */
1008
1009
1010 nBytes = nPayload + sizeof( tSirMacMgmtHdr ) ;
1011
1012 /* Ok-- try to allocate memory from MGMT PKT pool */
1013
1014 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1015 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1016 ( void** ) &pPacket );
1017 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1018 {
1019 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1020 "Discovery Request.\n"), nBytes );
1021 return eSIR_MEM_ALLOC_FAILED;
1022 }
1023
1024 /* zero out the memory */
1025 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1026
1027 /*
1028 * IE formation, memory allocation is completed, Now form TDLS discovery
1029 * response frame
1030 */
1031
1032 /* Make public Action Frame */
1033
1034#if 0
1035 limPreparesActionFrameHdr(pMac, pFrame, SIR_MAC_MGMT_FRAME,
1036 SIR_MAC_MGMT_ACTION,
1037 LINK_IDEN_ADDR_OFFSET(tdlsDisRsp)) ;
1038#endif
1039 limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
1040 SIR_MAC_MGMT_ACTION, peerMac, psessionEntry->selfMacAddr);
1041
1042 {
1043 tpSirMacMgmtHdr pMacHdr;
1044 pMacHdr = ( tpSirMacMgmtHdr ) pFrame;
1045 pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
1046 pMacHdr->fc.powerMgmt = 0 ;
1047 sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId);
1048 }
1049
1050#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1051 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_RSP)
1052 {
1053 tdlsDisRsp.LinkIdentifier.bssid[4] = 0xde;
1054 tdlsDisRsp.LinkIdentifier.bssid[5] = 0xad;
1055 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1056 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Discovery Rsp\n"), \
1057 tdlsDisRsp.LinkIdentifier.bssid[0],
1058 tdlsDisRsp.LinkIdentifier.bssid[1],
1059 tdlsDisRsp.LinkIdentifier.bssid[2],
1060 tdlsDisRsp.LinkIdentifier.bssid[3],
1061 tdlsDisRsp.LinkIdentifier.bssid[4],
1062 tdlsDisRsp.LinkIdentifier.bssid[5]);
1063 }
1064#endif
1065 status = dot11fPackTDLSDisRsp( pMac, &tdlsDisRsp, pFrame +
1066 sizeof( tSirMacMgmtHdr ),
1067 nPayload, &nPayload );
1068
1069 if ( DOT11F_FAILED( status ) )
1070 {
1071 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1072 (0x%08x).\n"), status );
1073 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1074 ( void* ) pFrame, ( void* ) pPacket );
1075 return eSIR_FAILURE;
1076 }
1077 else if ( DOT11F_WARNED( status ) )
1078 {
1079 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1080 "Discovery Request (0x%08x).\n") );
1081 }
1082
1083#if 0
1084 if(pMac->hal.pCBackFnTxComp == NULL)
1085 {
1086 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsDisRspTxComplete;
1087
1088 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
1089 {
1090 status = eHAL_STATUS_FAILURE;
1091 return status;
1092
1093 }
1094 }
1095#endif
1096 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
1097 ("transmitting Discovery response on direct link\n")) ;
1098
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001099 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 -08001100 SIR_MAC_TDLS_DIS_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_DIS_RSP) ));
1101
1102
1103 /*
1104 * Transmit Discovery response and watch if this is delivered to
1105 * peer STA.
1106 */
1107 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
1108 HAL_TXRX_FRM_802_11_DATA,
1109 ANI_TXDIR_IBSS,
1110 0,
1111 limTxComplete, pFrame,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001112 limMgmtTXComplete,
Kiran V1ccee932012-12-12 14:49:46 -08001113 HAL_USE_SELF_STA_REQUESTED_MASK );
1114 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1115 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001116 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -08001117 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1118 return eSIR_FAILURE;
Kiran V1ccee932012-12-12 14:49:46 -08001119 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001120 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -08001121
1122 return eSIR_SUCCESS;
1123
1124}
1125
1126/*
1127 * TDLS setup Request frame on AP link
1128 */
1129
1130tSirRetStatus limSendTdlsLinkSetupReqFrame(tpAniSirGlobal pMac,
1131 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry,
1132 tANI_U8 *addIe, tANI_U16 addIeLen)
1133{
1134 tDot11fTDLSSetupReq tdlsSetupReq ;
1135 tANI_U16 caps = 0 ;
1136 tANI_U32 status = 0 ;
1137 tANI_U32 nPayload = 0 ;
1138 tANI_U32 nBytes = 0 ;
1139 tANI_U32 header_offset = 0 ;
1140 tANI_U8 *pFrame;
1141 void *pPacket;
1142 eHalStatus halstatus;
1143
1144 /*
1145 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1146 * and then hand it off to 'dot11fPackProbeRequest' (for
1147 * serialization). We start by zero-initializing the structure:
1148 */
1149 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupReq,
1150 sizeof( tDot11fTDLSSetupReq ) );
1151 tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS ;
1152 tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ ;
1153 tdlsSetupReq.DialogToken.token = dialog ;
1154
1155
1156 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupReq.LinkIdentifier,
1157 peerMac, TDLS_INITIATOR) ;
1158
1159 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
1160 {
1161 /*
1162 * Could not get Capabilities value
1163 * from CFG. Log error.
1164 */
1165 limLog(pMac, LOGP,
1166 FL("could not retrieve Capabilities value\n"));
1167 }
1168 swapBitField16(caps, ( tANI_U16* )&tdlsSetupReq.Capabilities );
1169
1170 /* populate supported rate IE */
1171 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1172 &tdlsSetupReq.SuppRates, psessionEntry );
1173
1174 /* Populate extended supported rates */
1175 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1176 &tdlsSetupReq.ExtSuppRates, psessionEntry );
1177
1178 /* Populate extended supported rates */
1179 PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupReq.ExtCap );
1180
1181 /*
1182 * TODO: we need to see if we have to support conditions where we have
1183 * EDCA parameter info element is needed a) if we need different QOS
1184 * parameters for off channel operations or QOS is not supported on
1185 * AP link and we wanted to QOS on direct link.
1186 */
1187 /* Populate QOS info, needed for Peer U-APSD session */
1188 /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and
1189 TDLS doesn't want to depend on AP's capability */
1190 tdlsSetupReq.QOSCapsStation.present = 1;
1191 tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
1192 tdlsSetupReq.QOSCapsStation.qack = 0;
1193 tdlsSetupReq.QOSCapsStation.acbe_uapsd = 0;
1194 tdlsSetupReq.QOSCapsStation.acbk_uapsd = 0;
1195 tdlsSetupReq.QOSCapsStation.acvi_uapsd = 0;
1196 tdlsSetupReq.QOSCapsStation.acvo_uapsd = 0;
1197
1198
1199 /*
1200 * we will always try to init TDLS link with 11n capabilities
1201 * let TDLS setup response to come, and we will set our caps based
1202 * of peer caps
1203 */
1204
1205 /* Include HT Capability IE */
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001206 PopulateDot11fHTCaps( pMac, NULL, &tdlsSetupReq.HTCaps );
Hoonki Lee2dc39412013-03-12 16:35:22 -07001207 if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001208 {
Hoonki Lee2dc39412013-03-12 16:35:22 -07001209 tdlsSetupReq.HTCaps.present = 1;
1210 tdlsSetupReq.HTCaps.supportedChannelWidthSet = 0;
1211 }
1212 else
1213 {
1214 if (tdlsSetupReq.HTCaps.present)
1215 {
1216 tdlsSetupReq.HTCaps.supportedChannelWidthSet = 1; // pVhtCaps->supportedChannelWidthSet;
1217 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001218 }
1219 /* Include VHT Capability IE */
1220 PopulateDot11fVHTCaps( pMac, &tdlsSetupReq.VHTCaps );
Hoonki Lee2dc39412013-03-12 16:35:22 -07001221 if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001222 {
Hoonki Lee2dc39412013-03-12 16:35:22 -07001223 tdlsSetupReq.VHTCaps.present = 0;
1224 tdlsSetupReq.VHTCaps.supportedChannelWidthSet = 0;
1225 tdlsSetupReq.VHTCaps.ldpcCodingCap = 0;
1226 tdlsSetupReq.VHTCaps.suBeamFormerCap = 0;
1227 }
1228 else
1229 {
1230 if (tdlsSetupReq.VHTCaps.present)
1231 {
1232 tdlsSetupReq.VHTCaps.supportedChannelWidthSet = 1; // pVhtCaps->supportedChannelWidthSet;
1233 tdlsSetupReq.VHTCaps.ldpcCodingCap = 1; // pVhtCaps->ldpcCodingCap
1234 tdlsSetupReq.VHTCaps.suBeamFormerCap = 1; // pVhtCaps->suBeamFormerCap
1235 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001236 }
Kiran V1ccee932012-12-12 14:49:46 -08001237 /*
1238 * now we pack it. First, how much space are we going to need?
1239 */
1240 status = dot11fGetPackedTDLSSetupReqSize( pMac, &tdlsSetupReq,
1241 &nPayload);
1242 if ( DOT11F_FAILED( status ) )
1243 {
1244 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1245 "or a discovery Request (0x%08x).\n"), status );
1246 /* We'll fall back on the worst case scenario: */
1247 nPayload = sizeof( tDot11fProbeRequest );
1248 }
1249 else if ( DOT11F_WARNED( status ) )
1250 {
1251 limLog( pMac, LOGW, FL("There were warnings while calculating"
1252 "the packed size for a discovery Request ("
1253 "0x%08x).\n"), status );
1254 }
1255
1256
1257 /*
1258 * This frame is going out from PE as data frames with special ethertype
1259 * 89-0d.
1260 * 8 bytes of RFC 1042 header
1261 */
1262
1263
1264 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1265 + sizeof( eth_890d_header )
1266 + PAYLOAD_TYPE_TDLS_SIZE
1267 + addIeLen;
1268
1269 /* Ok-- try to allocate memory from MGMT PKT pool */
1270
1271 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1272 ( tANI_U16 )nBytes , ( void** ) &pFrame,
1273 ( void** ) &pPacket );
1274 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1275 {
1276 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1277 "Discovery Request.\n"), nBytes );
1278 return eSIR_MEM_ALLOC_FAILED;
1279 }
1280
1281 /* zero out the memory */
1282 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1283
1284 /*
1285 * IE formation, memory allocation is completed, Now form TDLS discovery
1286 * request frame
1287 */
1288
1289 /* fill out the buffer descriptor */
1290
1291 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1292 LINK_IDEN_ADDR_OFFSET(tdlsSetupReq), TDLS_LINK_AP, TDLS_INITIATOR, psessionEntry) ;
1293
1294#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1295 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_REQ)
1296 {
1297 tdlsSetupReq.LinkIdentifier.bssid[4] = 0xde;
1298 tdlsSetupReq.LinkIdentifier.bssid[5] = 0xad;
1299 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1300 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Req\n"), \
1301 tdlsSetupReq.LinkIdentifier.bssid[0],
1302 tdlsSetupReq.LinkIdentifier.bssid[1],
1303 tdlsSetupReq.LinkIdentifier.bssid[2],
1304 tdlsSetupReq.LinkIdentifier.bssid[3],
1305 tdlsSetupReq.LinkIdentifier.bssid[4],
1306 tdlsSetupReq.LinkIdentifier.bssid[5]);
1307 }
1308#endif
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001309 limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"),
1310 __func__, tdlsSetupReq.VHTCaps.supportedChannelWidthSet, tdlsSetupReq.VHTCaps.rxMCSMap,
1311 tdlsSetupReq.VHTCaps.txMCSMap, tdlsSetupReq.VHTCaps.txSupDataRate );
1312
Kiran V1ccee932012-12-12 14:49:46 -08001313 status = dot11fPackTDLSSetupReq( pMac, &tdlsSetupReq, pFrame
1314 + header_offset, nPayload, &nPayload );
1315
1316 if ( DOT11F_FAILED( status ) )
1317 {
1318 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1319 (0x%08x).\n"), status );
1320 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1321 ( void* ) pFrame, ( void* ) pPacket );
1322 return eSIR_FAILURE;
1323 }
1324 else if ( DOT11F_WARNED( status ) )
1325 {
1326 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1327 "Discovery Request (0x%08x).\n") );
1328 }
1329
1330 //Copy the additional IE.
1331 //TODO : addIe is added at the end of the frame. This means it doesnt
1332 //follow the order. This should be ok, but we should consider changing this
1333 //if there is any IOT issue.
1334 if( addIeLen != 0 )
1335 {
1336 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
1337 addIeLen ));
1338 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1339 }
1340
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001341 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 -08001342 SIR_MAC_TDLS_SETUP_REQ, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ) ));
1343
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001344 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
Kiran V1ccee932012-12-12 14:49:46 -08001345 HAL_TXRX_FRM_802_11_DATA,
1346 ANI_TXDIR_TODS,
1347 7,//SMAC_SWBD_TX_TID_MGMT_HIGH,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001348 limTxComplete, pFrame,
1349 limMgmtTXComplete,
1350 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
1351
Kiran V1ccee932012-12-12 14:49:46 -08001352 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1353 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001354 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -08001355 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1356 return eSIR_FAILURE;
Kiran V1ccee932012-12-12 14:49:46 -08001357 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001358 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -08001359
1360 return eSIR_SUCCESS;
1361
1362}
1363/*
1364 * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
1365 */
1366
1367tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac,
Hoonki Leea34dd892013-02-05 22:56:02 -08001368 tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry,
Kiran V1ccee932012-12-12 14:49:46 -08001369 tANI_U8 *addIe, tANI_U16 addIeLen)
1370{
1371 tDot11fTDLSTeardown teardown ;
1372 tANI_U32 status = 0 ;
1373 tANI_U32 nPayload = 0 ;
1374 tANI_U32 nBytes = 0 ;
1375 tANI_U32 header_offset = 0 ;
1376 tANI_U8 *pFrame;
1377 void *pPacket;
1378 eHalStatus halstatus;
Hoonki Lee6c6822a2013-02-06 14:10:46 -08001379#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1380 tANI_U32 padLen = 0;
1381#endif
Kiran V1ccee932012-12-12 14:49:46 -08001382 /*
1383 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1384 * and then hand it off to 'dot11fPackProbeRequest' (for
1385 * serialization). We start by zero-initializing the structure:
1386 */
1387 palZeroMemory( pMac->hHdd, ( tANI_U8* )&teardown,
1388 sizeof( tDot11fTDLSTeardown ) );
1389 teardown.Category.category = SIR_MAC_ACTION_TDLS ;
1390 teardown.Action.action = SIR_MAC_TDLS_TEARDOWN ;
1391 teardown.Reason.code = reason ;
1392
1393 PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier,
Hoonki Leea34dd892013-02-05 22:56:02 -08001394 peerMac, (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR) ;
Kiran V1ccee932012-12-12 14:49:46 -08001395
1396
1397 /*
1398 * now we pack it. First, how much space are we going to need?
1399 */
1400 status = dot11fGetPackedTDLSTeardownSize( pMac, &teardown, &nPayload);
1401 if ( DOT11F_FAILED( status ) )
1402 {
1403 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1404 "or a discovery Request (0x%08x).\n"), status );
1405 /* We'll fall back on the worst case scenario: */
1406 nPayload = sizeof( tDot11fProbeRequest );
1407 }
1408 else if ( DOT11F_WARNED( status ) )
1409 {
1410 limLog( pMac, LOGW, FL("There were warnings while calculating"
1411 "the packed size for a discovery Request ("
1412 "0x%08x).\n"), status );
1413 }
1414
1415
1416 /*
1417 * This frame is going out from PE as data frames with special ethertype
1418 * 89-0d.
1419 * 8 bytes of RFC 1042 header
1420 */
1421
1422
1423 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1424 + sizeof( eth_890d_header )
1425 + PAYLOAD_TYPE_TDLS_SIZE
1426 + addIeLen;
1427
Hoonki Lee6c6822a2013-02-06 14:10:46 -08001428#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1429 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1430 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1431 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1432 */
1433 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE)
1434 {
1435 padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ;
1436
1437 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1438 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1439 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1440
1441 nBytes += padLen;
1442 }
1443#endif
1444
Kiran V1ccee932012-12-12 14:49:46 -08001445 /* Ok-- try to allocate memory from MGMT PKT pool */
1446
1447 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1448 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1449 ( void** ) &pPacket );
1450 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1451 {
1452 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1453 "Discovery Request.\n"), nBytes );
1454 return eSIR_MEM_ALLOC_FAILED;
1455 }
1456
1457 /* zero out the memory */
1458 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1459
1460 /*
1461 * IE formation, memory allocation is completed, Now form TDLS discovery
1462 * request frame
1463 */
1464
1465 /* fill out the buffer descriptor */
1466
1467 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1468 LINK_IDEN_ADDR_OFFSET(teardown),
1469 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
Gopichand Nakkala269032c2013-02-07 17:18:15 -08001470 ? TDLS_LINK_AP : TDLS_LINK_DIRECT,
1471 (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR,
Kiran V1ccee932012-12-12 14:49:46 -08001472 psessionEntry) ;
1473
1474 status = dot11fPackTDLSTeardown( pMac, &teardown, pFrame
1475 + header_offset, nPayload, &nPayload );
1476
1477 if ( DOT11F_FAILED( status ) )
1478 {
1479 limLog( pMac, LOGE, FL("Failed to pack a TDLS Teardown req \
1480 (0x%08x).\n"), status );
1481 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1482 ( void* ) pFrame, ( void* ) pPacket );
1483 return eSIR_FAILURE;
1484 }
1485 else if ( DOT11F_WARNED( status ) )
1486 {
1487 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1488 "Teardown Request (0x%08x).\n") );
1489 }
1490#if 0
1491 if(pMac->hal.pCBackFnTxComp == NULL)
1492 {
1493 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsTeardownTxComplete;
1494 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
1495 {
1496 status = eHAL_STATUS_FAILURE;
1497 return status;
1498
1499 }
1500 }
1501 else
1502 {
1503 VOS_ASSERT(0) ;
1504 return status ;
1505 }
1506#endif
1507
1508 if( addIeLen != 0 )
1509 {
1510 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Copy Additional Ie Len = %d"),
1511 addIeLen ));
1512 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1513 }
1514
Hoonki Lee6c6822a2013-02-06 14:10:46 -08001515#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1516 if (padLen != 0)
1517 {
1518 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1519 tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen;
1520 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1521 padVendorSpecific[0] = 221;
1522 padVendorSpecific[1] = padLen - 2;
1523 padVendorSpecific[2] = 0x00;
1524 padVendorSpecific[3] = 0xA0;
1525 padVendorSpecific[4] = 0xC6;
1526
1527 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
1528 padLen ));
1529
1530 /* padding zero if more than 5 bytes are required */
1531 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
1532 palZeroMemory( pMac->hHdd, pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, padLen - MIN_VENDOR_SPECIFIC_IE_SIZE);
1533 }
1534#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001535 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL, ("[TDLS] action %d (%s) -%s-> OTA"),
1536 SIR_MAC_TDLS_TEARDOWN, limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN),
1537 (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP": "DIRECT" ));
Kiran V1ccee932012-12-12 14:49:46 -08001538
1539 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
1540 HAL_TXRX_FRM_802_11_DATA,
1541 ANI_TXDIR_TODS,
1542 7,
1543 limTxComplete, pFrame,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001544 limMgmtTXComplete,
Gopichand Nakkalad75b1532013-02-15 13:33:42 -08001545 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
Kiran V1ccee932012-12-12 14:49:46 -08001546 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1547 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001548 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -08001549 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1550 return eSIR_FAILURE;
1551
1552 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001553 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -08001554 return eSIR_SUCCESS;
1555
1556}
1557
1558/*
1559 * Send Setup RSP frame on AP link.
1560 */
1561static tSirRetStatus limSendTdlsSetupRspFrame(tpAniSirGlobal pMac,
1562 tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry,
1563 etdlsLinkSetupStatus setupStatus, tANI_U8 *addIe, tANI_U16 addIeLen )
1564{
1565 tDot11fTDLSSetupRsp tdlsSetupRsp ;
1566 tANI_U32 status = 0 ;
1567 tANI_U16 caps = 0 ;
1568 tANI_U32 nPayload = 0 ;
1569 tANI_U32 header_offset = 0 ;
1570 tANI_U32 nBytes = 0 ;
1571 tANI_U8 *pFrame;
1572 void *pPacket;
1573 eHalStatus halstatus;
1574
1575 /*
1576 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1577 * and then hand it off to 'dot11fPackProbeRequest' (for
1578 * serialization). We start by zero-initializing the structure:
1579 */
1580 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupRsp,
1581 sizeof( tDot11fTDLSSetupRsp ) );
1582
1583 /*
1584 * setup Fixed fields,
1585 */
1586 tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
1587 tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP ;
1588 tdlsSetupRsp.DialogToken.token = dialog;
1589
1590 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupRsp.LinkIdentifier,
1591 peerMac, TDLS_RESPONDER) ;
1592
1593 if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
1594 {
1595 /*
1596 * Could not get Capabilities value
1597 * from CFG. Log error.
1598 */
1599 limLog(pMac, LOGP,
1600 FL("could not retrieve Capabilities value\n"));
1601 }
1602 swapBitField16(caps, ( tANI_U16* )&tdlsSetupRsp.Capabilities );
1603
1604 /* ipopulate supported rate IE */
1605 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1606 &tdlsSetupRsp.SuppRates, psessionEntry );
1607
1608 /* Populate extended supported rates */
1609 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
1610 &tdlsSetupRsp.ExtSuppRates, psessionEntry );
1611
1612 /* Populate extended supported rates */
1613 PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupRsp.ExtCap );
1614
1615 /*
1616 * TODO: we need to see if we have to support conditions where we have
1617 * EDCA parameter info element is needed a) if we need different QOS
1618 * parameters for off channel operations or QOS is not supported on
1619 * AP link and we wanted to QOS on direct link.
1620 */
1621 /* Populate QOS info, needed for Peer U-APSD session */
1622 /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and
1623 TDLS doesn't want to depend on AP's capability */
1624 tdlsSetupRsp.QOSCapsStation.present = 1;
1625 tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
1626 tdlsSetupRsp.QOSCapsStation.qack = 0;
1627 tdlsSetupRsp.QOSCapsStation.acbe_uapsd = 1;
1628 tdlsSetupRsp.QOSCapsStation.acbk_uapsd = 1;
1629 tdlsSetupRsp.QOSCapsStation.acvi_uapsd = 1;
1630 tdlsSetupRsp.QOSCapsStation.acvo_uapsd = 1;
1631
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001632 PopulateDot11fHTCaps( pMac, NULL, &tdlsSetupRsp.HTCaps );
Hoonki Lee2dc39412013-03-12 16:35:22 -07001633 if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001634 {
Hoonki Lee2dc39412013-03-12 16:35:22 -07001635 tdlsSetupRsp.HTCaps.present = 1;
1636 tdlsSetupRsp.HTCaps.supportedChannelWidthSet = 0;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001637 }
Hoonki Lee2dc39412013-03-12 16:35:22 -07001638 else
1639 {
1640 if (tdlsSetupRsp.HTCaps.present)
1641 {
1642 tdlsSetupRsp.HTCaps.supportedChannelWidthSet = 1; // pVhtCaps->supportedChannelWidthSet;
1643 }
1644 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001645 /* Include VHT Capability IE */
1646 PopulateDot11fVHTCaps( pMac, &tdlsSetupRsp.VHTCaps );
Hoonki Lee2dc39412013-03-12 16:35:22 -07001647 if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001648 {
Hoonki Lee2dc39412013-03-12 16:35:22 -07001649 tdlsSetupRsp.VHTCaps.present = 0;
1650 tdlsSetupRsp.VHTCaps.supportedChannelWidthSet = 0;
1651 tdlsSetupRsp.VHTCaps.ldpcCodingCap = 0;
1652 tdlsSetupRsp.VHTCaps.suBeamFormerCap = 0;
1653 }
1654 else
1655 {
1656 if (tdlsSetupRsp.VHTCaps.present)
1657 {
1658 tdlsSetupRsp.VHTCaps.supportedChannelWidthSet = 1; // pVhtCaps->supportedChannelWidthSet;
1659 tdlsSetupRsp.VHTCaps.ldpcCodingCap = 1; // pVhtCaps->ldpcCodingCap
1660 tdlsSetupRsp.VHTCaps.suBeamFormerCap = 1; // pVhtCaps->suBeamFormerCap
1661 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001662 }
Kiran V1ccee932012-12-12 14:49:46 -08001663 tdlsSetupRsp.Status.status = setupStatus ;
1664
1665 /*
1666 * now we pack it. First, how much space are we going to need?
1667 */
1668 status = dot11fGetPackedTDLSSetupRspSize( pMac, &tdlsSetupRsp,
1669 &nPayload);
1670 if ( DOT11F_FAILED( status ) )
1671 {
1672 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1673 "or a discovery Request (0x%08x).\n"), status );
1674 /* We'll fall back on the worst case scenario: */
1675 nPayload = sizeof( tDot11fProbeRequest );
1676 }
1677 else if ( DOT11F_WARNED( status ) )
1678 {
1679 limLog( pMac, LOGW, FL("There were warnings while calculating"
1680 "the packed size for a discovery Request ("
1681 "0x%08x).\n"), status );
1682 }
1683
1684 /*
1685 * This frame is going out from PE as data frames with special ethertype
1686 * 89-0d.
1687 * 8 bytes of RFC 1042 header
1688 */
1689
1690
1691 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1692 + sizeof( eth_890d_header )
1693 + PAYLOAD_TYPE_TDLS_SIZE
1694 + addIeLen;
1695
1696 /* Ok-- try to allocate memory from MGMT PKT pool */
1697
1698 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1699 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1700 ( void** ) &pPacket );
1701 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1702 {
1703 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1704 "Discovery Request.\n"), nBytes );
1705 return eSIR_MEM_ALLOC_FAILED;
1706 }
1707
1708 /* zero out the memory */
1709 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1710
1711 /*
1712 * IE formation, memory allocation is completed, Now form TDLS discovery
1713 * request frame
1714 */
1715
1716 /* fill out the buffer descriptor */
1717
1718 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1719 LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp),
1720 TDLS_LINK_AP, TDLS_RESPONDER,
1721 psessionEntry) ;
1722
1723#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1724 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_RSP)
1725 {
1726 tdlsSetupRsp.LinkIdentifier.bssid[4] = 0xde;
1727 tdlsSetupRsp.LinkIdentifier.bssid[5] = 0xad;
1728 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1729 ("TDLS negative running: wrong BSSID %02x:%02x:%02x:%02x:%02x:%02x in TDLS Setup Rsp\n"), \
1730 tdlsSetupRsp.LinkIdentifier.bssid[0],
1731 tdlsSetupRsp.LinkIdentifier.bssid[1],
1732 tdlsSetupRsp.LinkIdentifier.bssid[2],
1733 tdlsSetupRsp.LinkIdentifier.bssid[3],
1734 tdlsSetupRsp.LinkIdentifier.bssid[4],
1735 tdlsSetupRsp.LinkIdentifier.bssid[5]);
1736 }
1737#endif
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001738 limLog( pMac, LOGW, FL("%s: SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"),
1739 __func__, tdlsSetupRsp.VHTCaps.supportedChannelWidthSet, tdlsSetupRsp.VHTCaps.rxMCSMap,
1740 tdlsSetupRsp.VHTCaps.txMCSMap, tdlsSetupRsp.VHTCaps.txSupDataRate );
Kiran V1ccee932012-12-12 14:49:46 -08001741 status = dot11fPackTDLSSetupRsp( pMac, &tdlsSetupRsp, pFrame
1742 + header_offset, nPayload, &nPayload );
1743
1744 if ( DOT11F_FAILED( status ) )
1745 {
1746 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1747 (0x%08x).\n"), status );
1748 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1749 ( void* ) pFrame, ( void* ) pPacket );
1750 return eSIR_FAILURE;
1751 }
1752 else if ( DOT11F_WARNED( status ) )
1753 {
1754 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1755 "Discovery Request (0x%08x).\n") );
1756 }
1757
1758 //Copy the additional IE.
1759 //TODO : addIe is added at the end of the frame. This means it doesnt
1760 //follow the order. This should be ok, but we should consider changing this
1761 //if there is any IOT issue.
1762 if( addIeLen != 0 )
1763 {
1764 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1765 }
1766
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001767 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 -08001768 SIR_MAC_TDLS_SETUP_RSP, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP) ));
1769
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001770 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
Kiran V1ccee932012-12-12 14:49:46 -08001771 HAL_TXRX_FRM_802_11_DATA,
1772 ANI_TXDIR_TODS,
1773 //ANI_TXDIR_IBSS,
1774 7,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001775 limTxComplete, pFrame,
1776 limMgmtTXComplete,
1777 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
Kiran V1ccee932012-12-12 14:49:46 -08001778 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1779 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001780 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -08001781 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
1782 return eSIR_FAILURE;
Kiran V1ccee932012-12-12 14:49:46 -08001783 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001784 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -08001785
1786 return eSIR_SUCCESS;
1787
1788}
1789
1790/*
1791 * Send TDLS setup CNF frame on AP link
1792 */
1793
1794tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, tSirMacAddr peerMac,
1795 tANI_U8 dialog, tpPESession psessionEntry, tANI_U8* addIe, tANI_U16 addIeLen)
1796{
1797 tDot11fTDLSSetupCnf tdlsSetupCnf ;
1798 tANI_U32 status = 0 ;
1799 tANI_U32 nPayload = 0 ;
1800 tANI_U32 nBytes = 0 ;
1801 tANI_U32 header_offset = 0 ;
1802 tANI_U8 *pFrame;
1803 void *pPacket;
1804 eHalStatus halstatus;
Hoonki Lee426f0302013-02-08 17:35:38 -08001805#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1806 tANI_U32 padLen = 0;
1807#endif
Kiran V1ccee932012-12-12 14:49:46 -08001808
1809 /*
1810 * The scheme here is to fill out a 'tDot11fProbeRequest' structure
1811 * and then hand it off to 'dot11fPackProbeRequest' (for
1812 * serialization). We start by zero-initializing the structure:
1813 */
1814 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsSetupCnf,
1815 sizeof( tDot11fTDLSSetupCnf ) );
1816
1817 /*
1818 * setup Fixed fields,
1819 */
1820 tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
1821 tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF ;
1822 tdlsSetupCnf.DialogToken.token = dialog ;
1823
1824#if 1
1825 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupCnf.LinkIdentifier,
1826 peerMac, TDLS_INITIATOR) ;
1827#else
1828 palCopyMemory( pMac->hHdd, (tANI_U8 *)&tdlsSetupCnf.LinkIdentifier,
1829 (tANI_U8 *)&setupRsp->LinkIdentifier, sizeof(tDot11fIELinkIdentifier)) ;
1830#endif
1831
1832 /*
1833 * TODO: we need to see if we have to support conditions where we have
1834 * EDCA parameter info element is needed a) if we need different QOS
1835 * parameters for off channel operations or QOS is not supported on
1836 * AP link and we wanted to QOS on direct link.
1837 */
1838
1839 /* Include HT Info IE */
Gopichand Nakkala681989c2013-03-06 22:27:48 -08001840 /* Need to also check the Self Capability ??? TODO Sunil */
1841 if ( true == psessionEntry->htCapability)
1842 {
1843 PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry );
1844 }
1845 if ( true == psessionEntry->vhtCapability)
1846 {
1847 PopulateDot11fVHTOperation( pMac, &tdlsSetupCnf.VHTOperation);
1848 }
Kiran V1ccee932012-12-12 14:49:46 -08001849
1850 /*
1851 * now we pack it. First, how much space are we going to need?
1852 */
1853 status = dot11fGetPackedTDLSSetupCnfSize( pMac, &tdlsSetupCnf,
1854 &nPayload);
1855 if ( DOT11F_FAILED( status ) )
1856 {
1857 limLog( pMac, LOGP, FL("Failed to calculate the packed size f"
1858 "or a discovery Request (0x%08x).\n"), status );
1859 /* We'll fall back on the worst case scenario: */
1860 nPayload = sizeof( tDot11fProbeRequest );
1861 }
1862 else if ( DOT11F_WARNED( status ) )
1863 {
1864 limLog( pMac, LOGW, FL("There were warnings while calculating"
1865 "the packed size for a discovery Request ("
1866 "0x%08x).\n"), status );
1867 }
1868
1869 /*
1870 * This frame is going out from PE as data frames with special ethertype
1871 * 89-0d.
1872 * 8 bytes of RFC 1042 header
1873 */
1874
1875
1876 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
1877 + sizeof( eth_890d_header )
1878 + PAYLOAD_TYPE_TDLS_SIZE
1879 + addIeLen;
1880
Hoonki Lee426f0302013-02-08 17:35:38 -08001881#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1882 /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
1883 Hence AP itself padding some bytes, which caused teardown packet is dropped at
1884 receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
1885 */
1886 if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE)
1887 {
1888 padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ;
1889
1890 /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
1891 if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
1892 padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
1893
1894 nBytes += padLen;
1895 }
1896#endif
1897
1898
Kiran V1ccee932012-12-12 14:49:46 -08001899 /* Ok-- try to allocate memory from MGMT PKT pool */
1900
1901 halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1902 ( tANI_U16 )nBytes, ( void** ) &pFrame,
1903 ( void** ) &pPacket );
1904 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
1905 {
1906 limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TDLS"
1907 "Discovery Request.\n"), nBytes );
1908 return eSIR_MEM_ALLOC_FAILED;
1909 }
1910
1911 /* zero out the memory */
1912 palZeroMemory( pMac->hHdd, pFrame, nBytes );
1913
1914 /*
1915 * IE formation, memory allocation is completed, Now form TDLS discovery
1916 * request frame
1917 */
1918
1919 /* fill out the buffer descriptor */
1920
1921 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
1922 LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf), TDLS_LINK_AP, TDLS_INITIATOR,
1923 psessionEntry) ;
1924
1925#ifdef FEATURE_WLAN_TDLS_NEGATIVE
1926 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_STATUS_37_IN_SETUP_CNF) {
1927 tdlsSetupCnf.StatusCode.statusCode = 37;
1928 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
1929 ("TDLS negative running: StatusCode = 37 in TDLS Setup Cnf\n"));
1930 }
1931#endif
1932 status = dot11fPackTDLSSetupCnf( pMac, &tdlsSetupCnf, pFrame
1933 + header_offset, nPayload, &nPayload );
1934
1935 if ( DOT11F_FAILED( status ) )
1936 {
1937 limLog( pMac, LOGE, FL("Failed to pack a TDLS discovery req \
1938 (0x%08x).\n"), status );
1939 palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT,
1940 ( void* ) pFrame, ( void* ) pPacket );
1941 return eSIR_FAILURE;
1942 }
1943 else if ( DOT11F_WARNED( status ) )
1944 {
1945 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
1946 "Discovery Request (0x%08x).\n") );
1947 }
1948#if 0
1949 if(pMac->hal.pCBackFnTxComp == NULL)
1950 {
1951 pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsSetupCnfTxComplete;
1952 if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer))
1953 {
1954 status = eHAL_STATUS_FAILURE;
1955 return status;
1956
1957 }
1958 }
1959 else
1960 {
1961 VOS_ASSERT(0) ;
1962 return status ;
1963 }
1964#endif
1965 //Copy the additional IE.
1966 //TODO : addIe is added at the end of the frame. This means it doesnt
1967 //follow the order. This should be ok, but we should consider changing this
1968 //if there is any IOT issue.
1969 if( addIeLen != 0 )
1970 {
1971 palCopyMemory( pMac->hHdd, pFrame + header_offset + nPayload, addIe, addIeLen );
1972 }
1973
Hoonki Lee426f0302013-02-08 17:35:38 -08001974#ifndef NO_PAD_TDLS_MIN_8023_SIZE
1975 if (padLen != 0)
1976 {
1977 /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
1978 tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen;
1979 /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
1980 padVendorSpecific[0] = 221;
1981 padVendorSpecific[1] = padLen - 2;
1982 padVendorSpecific[2] = 0x00;
1983 padVendorSpecific[3] = 0xA0;
1984 padVendorSpecific[4] = 0xC6;
1985
1986 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, ("Padding Vendor Specific Ie Len = %d"),
1987 padLen ));
1988
1989 /* padding zero if more than 5 bytes are required */
1990 if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
1991 palZeroMemory( pMac->hHdd, pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, padLen - MIN_VENDOR_SPECIFIC_IE_SIZE);
1992 }
1993#endif
1994
1995
Hoonki Lee1090c6a2013-01-16 17:40:54 -08001996 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 -08001997 SIR_MAC_TDLS_SETUP_CNF, limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_CNF) ));
1998
1999 halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes,
2000 HAL_TXRX_FRM_802_11_DATA,
2001 ANI_TXDIR_TODS,
2002 7,
2003 limTxComplete, pFrame,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002004 limMgmtTXComplete,
Gopichand Nakkalad75b1532013-02-15 13:33:42 -08002005 HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME );
Kiran V1ccee932012-12-12 14:49:46 -08002006
2007
2008 if ( ! HAL_STATUS_SUCCESS ( halstatus ) )
2009 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002010 pMac->lim.mgmtFrameSessionId = 0xff;
Kiran V1ccee932012-12-12 14:49:46 -08002011 limLog( pMac, LOGE, FL("could not send TDLS Dis Request frame!\n" ));
2012 return eSIR_FAILURE;
2013
2014 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002015 pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
Kiran V1ccee932012-12-12 14:49:46 -08002016
2017 return eSIR_SUCCESS;
2018}
2019
2020#ifdef FEATURE_WLAN_TDLS_INTERNAL
2021/*
2022 * Convert HT caps to lim based HT caps
2023 */
2024static void limTdlsCovertHTCaps(tpAniSirGlobal pMac ,
2025 tSirTdlsPeerInfo *peerInfo, tDot11fIEHTCaps *HTCaps)
2026{
2027
2028 /* HT Capability Info */
2029 peerInfo->tdlsPeerHtCaps.advCodingCap = HTCaps->advCodingCap ;
2030 peerInfo->tdlsPeerHtCaps.supportedChannelWidthSet =
2031 HTCaps->supportedChannelWidthSet ;
2032 peerInfo->tdlsPeerHtCaps.mimoPowerSave = HTCaps->mimoPowerSave ;
2033 peerInfo->tdlsPeerHtCaps.greenField = HTCaps->greenField ;
2034 peerInfo->tdlsPeerHtCaps.shortGI20MHz = HTCaps->shortGI20MHz ;
2035 peerInfo->tdlsPeerHtCaps.shortGI40MHz = HTCaps->shortGI40MHz ;
2036 peerInfo->tdlsPeerHtCaps.txSTBC = HTCaps->txSTBC ;
2037 peerInfo->tdlsPeerHtCaps.rxSTBC = HTCaps->rxSTBC ;
2038 peerInfo->tdlsPeerHtCaps.delayedBA = HTCaps->delayedBA;
2039 peerInfo->tdlsPeerHtCaps.maximalAMSDUsize = HTCaps->maximalAMSDUsize ;
2040 peerInfo->tdlsPeerHtCaps.dsssCckMode40MHz = HTCaps->dsssCckMode40MHz ;
2041 peerInfo->tdlsPeerHtCaps.psmp = HTCaps->stbcControlFrame ;
2042 peerInfo->tdlsPeerHtCaps.stbcControlFrame = HTCaps->stbcControlFrame ;
2043 peerInfo->tdlsPeerHtCaps.lsigTXOPProtection =
2044 HTCaps->lsigTXOPProtection ;
2045
2046 /* HT Capa parameters */
2047 peerInfo->tdlsPeerHtParams.maxRxAMPDUFactor = HTCaps->maxRxAMPDUFactor ;
2048 peerInfo->tdlsPeerHtParams.mpduDensity = HTCaps->mpduDensity ;
2049 peerInfo->tdlsPeerHtParams.reserved = HTCaps->reserved1 ;
2050
2051 /* Extended HT caps */
2052 peerInfo->tdlsPeerHtExtCaps.pco = HTCaps->pco ;
2053 peerInfo->tdlsPeerHtExtCaps.transitionTime = HTCaps->transitionTime ;
2054 peerInfo->tdlsPeerHtExtCaps.mcsFeedback = HTCaps->mcsFeedback ;
2055 palCopyMemory(pMac->hHdd, peerInfo->supportedMCSSet,
2056 HTCaps->supportedMCSSet, SIZE_OF_SUPPORTED_MCS_SET) ;
2057
2058 return ;
2059}
2060
2061/*
2062 * update capability info..
2063 */
2064void tdlsUpdateCapInfo(tSirMacCapabilityInfo *capabilityInfo,
2065 tDot11fFfCapabilities *Capabilities)
2066{
2067
2068 capabilityInfo->ess = Capabilities->ess;
2069 capabilityInfo->ibss = Capabilities->ibss;
2070 capabilityInfo->cfPollable = Capabilities->cfPollable;
2071 capabilityInfo->cfPollReq = Capabilities->cfPollReq;
2072 capabilityInfo->privacy = Capabilities->privacy;
2073 capabilityInfo->shortPreamble = Capabilities->shortPreamble;
2074 capabilityInfo->pbcc = Capabilities->pbcc;
2075 capabilityInfo->channelAgility = Capabilities->channelAgility;
2076 capabilityInfo->spectrumMgt = Capabilities->spectrumMgt;
2077 capabilityInfo->qos = Capabilities->qos;
2078 capabilityInfo->shortSlotTime = Capabilities->shortSlotTime;
2079 capabilityInfo->apsd = Capabilities->apsd;
2080 capabilityInfo->rrm = Capabilities->rrm;
2081 capabilityInfo->dsssOfdm = Capabilities->dsssOfdm;
2082 capabilityInfo->immediateBA = Capabilities->immediateBA;
2083
2084 return ;
2085}
2086
2087/*
2088 * update Peer info from the link request frame recieved from Peer..
2089 * in list of STA participating in TDLS link setup
2090 */
2091void limTdlsUpdateLinkReqPeerInfo(tpAniSirGlobal pMac,
2092 tLimTdlsLinkSetupPeer *setupPeer,
2093 tDot11fTDLSSetupReq *setupReq)
2094{
2095
2096 /* Populate peer info of tdls discovery result */
2097
2098 tdlsUpdateCapInfo(&setupPeer->capabilityInfo , &setupReq->Capabilities) ;
2099
2100 if(setupReq->SuppRates.present)
2101 {
2102 ConvertSuppRates( pMac, &setupPeer->supportedRates,
2103 &setupReq->SuppRates );
2104 }
2105
2106 /* update QOS info, needed for Peer U-APSD session */
2107 if(setupReq->QOSCapsStation.present)
2108 {
2109 ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps,
2110 &setupReq->QOSCapsStation) ;
2111 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"), \
2112 setupReq->QOSCapsStation.max_sp_length, setupReq->QOSCapsStation.acbe_uapsd, \
2113 setupReq->QOSCapsStation.acbk_uapsd, setupReq->QOSCapsStation.acvi_uapsd, \
2114 setupReq->QOSCapsStation.acvo_uapsd, setupReq->QOSCapsStation.more_data_ack, \
2115 setupReq->QOSCapsStation.qack));
2116 }
2117
2118 if(setupReq->ExtSuppRates.present)
2119 {
2120 setupPeer->ExtRatesPresent = 1;
2121 ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
2122 &setupReq->ExtSuppRates );
2123 }
2124 /* update HT caps */
2125 if(setupReq->HTCaps.present)
2126 {
2127 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps,
2128 &setupReq->HTCaps, sizeof(tDot11fIEHTCaps)) ;
2129 }
2130 /* Update EXT caps */
2131 if(setupReq->ExtCap.present)
2132 {
2133 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerExtCaps,
2134 &setupReq->ExtCap, sizeof(tDot11fIEExtCap)) ;
2135 }
2136
2137 return ;
2138}
2139
2140/*
2141 * update peer Info recieved with TDLS setup RSP
2142 */
2143void limTdlsUpdateLinkRspPeerInfo(tpAniSirGlobal pMac,
2144 tLimTdlsLinkSetupPeer *setupPeer,
2145 tDot11fTDLSSetupRsp *setupRsp)
2146{
2147
2148 /* Populate peer info of tdls discovery result */
2149 tdlsUpdateCapInfo(&setupPeer->capabilityInfo , &setupRsp->Capabilities) ;
2150
2151 if(setupRsp->SuppRates.present)
2152 {
2153 tDot11fIESuppRates *suppRates = &setupRsp->SuppRates ;
2154 ConvertSuppRates( pMac, &setupPeer->supportedRates, suppRates);
2155 }
2156
2157 /* update QOS info, needed for Peer U-APSD session */
2158 if(setupRsp->QOSCapsStation.present)
2159 {
2160 ConvertQOSCapsStation(pMac->hHdd, &setupPeer->qosCaps,
2161 &setupRsp->QOSCapsStation) ;
2162 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"), \
2163 setupRsp->QOSCapsStation.max_sp_length, setupRsp->QOSCapsStation.acbe_uapsd, \
2164 setupRsp->QOSCapsStation.acbk_uapsd, setupRsp->QOSCapsStation.acvi_uapsd, \
2165 setupRsp->QOSCapsStation.acvo_uapsd, setupRsp->QOSCapsStation.more_data_ack, \
2166 setupRsp->QOSCapsStation.qack));
2167 }
2168
2169 if(setupRsp->ExtSuppRates.present)
2170 {
2171 setupPeer->ExtRatesPresent = 1;
2172 ConvertExtSuppRates( pMac, &setupPeer->extendedRates,
2173 &setupRsp->ExtSuppRates );
2174 }
2175 /* update HT caps */
2176 if(setupRsp->HTCaps.present)
2177 {
2178 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerHTCaps,
2179 &setupRsp->HTCaps, sizeof(tDot11fIEHTCaps)) ;
2180 }
2181
2182 /* update EXT caps */
2183 if(setupRsp->ExtCap.present)
2184 {
2185 palCopyMemory(pMac->hHdd, &setupPeer->tdlsPeerExtCaps,
2186 &setupRsp->ExtCap, sizeof(tDot11fIEExtCap)) ;
2187 }
2188
2189 return ;
2190}
2191#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002192
2193/* This Function is similar to PopulateDot11fHTCaps , except that the HT Capabilities
2194 * are considered from the AddStaReq rather from the cfg.dat as in PopulateDot11fHTCaps
2195 */
2196static tSirRetStatus limTdlsPopulateDot11fHTCaps(tpAniSirGlobal pMac, tpPESession psessionEntry,
2197 tSirTdlsAddStaReq *pTdlsAddStaReq, tDot11fIEHTCaps *pDot11f)
2198{
2199 tANI_U32 nCfgValue;
2200 tANI_U8 nCfgValue8;
2201 tSirMacHTParametersInfo *pHTParametersInfo;
2202 union {
2203 tANI_U16 nCfgValue16;
2204 tSirMacHTCapabilityInfo htCapInfo;
2205 tSirMacExtendedHTCapabilityInfo extHtCapInfo;
2206 } uHTCapabilityInfo;
2207
2208 tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
2209 tSirMacASCapabilityInfo *pASCapabilityInfo;
2210
2211 nCfgValue = pTdlsAddStaReq->htCap.capInfo;
2212
2213 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2214
2215 pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap;
2216 pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
2217 pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
2218 pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
2219 pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
2220 pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
2221 pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
2222 pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
2223 pDot11f->maximalAMSDUsize = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
2224 pDot11f->dsssCckMode40MHz = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
2225 pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
2226 pDot11f->stbcControlFrame = uHTCapabilityInfo.htCapInfo.stbcControlFrame;
2227 pDot11f->lsigTXOPProtection = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
2228
2229 // All sessionized entries will need the check below
2230 if (psessionEntry == NULL) // Only in case of NO session
2231 {
2232 pDot11f->supportedChannelWidthSet = uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
2233 }
2234 else
2235 {
2236 pDot11f->supportedChannelWidthSet = psessionEntry->htSupportedChannelWidthSet;
2237 }
2238
2239 /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
2240 eHT_CHANNEL_WIDTH_20MHZ */
2241 if(pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ)
2242 {
2243 pDot11f->shortGI40MHz = 0;
2244 }
2245
2246 dot11fLog(pMac, LOG2, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"),
2247 pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave, pDot11f->greenField,
2248 pDot11f->shortGI20MHz, pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz);
2249
2250 nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
2251
2252 nCfgValue8 = ( tANI_U8 ) nCfgValue;
2253 pHTParametersInfo = ( tSirMacHTParametersInfo* ) &nCfgValue8;
2254
2255 pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
2256 pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
2257 pDot11f->reserved1 = pHTParametersInfo->reserved;
2258
2259 dot11fLog( pMac, LOG2, FL( "AMPDU Param: %x" ), nCfgValue);
2260
2261 palCopyMemory(pMac->hHdd, pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet, SIZE_OF_SUPPORTED_MCS_SET);
2262
2263 nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
2264
2265 uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
2266
2267 pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
2268 pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
2269 pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
2270
2271 nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
2272
2273 pTxBFCapabilityInfo = ( tSirMacTxBFCapabilityInfo* ) &nCfgValue;
2274 pDot11f->txBF = pTxBFCapabilityInfo->txBF;
2275 pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
2276 pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
2277 pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
2278 pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
2279 pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
2280 pDot11f->calibration = pTxBFCapabilityInfo->calibration;
2281 pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
2282 pDot11f->explicitUncompressedSteeringMatrix = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
2283 pDot11f->explicitBFCSIFeedback = pTxBFCapabilityInfo->explicitBFCSIFeedback;
2284 pDot11f->explicitUncompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
2285 pDot11f->explicitCompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
2286 pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
2287 pDot11f->uncompressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
2288 pDot11f->compressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
2289
2290 nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
2291
2292 nCfgValue8 = ( tANI_U8 ) nCfgValue;
2293
2294 pASCapabilityInfo = ( tSirMacASCapabilityInfo* ) &nCfgValue8;
2295 pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
2296 pDot11f->explicitCSIFeedbackTx = pASCapabilityInfo->explicitCSIFeedbackTx;
2297 pDot11f->antennaIndicesFeedbackTx = pASCapabilityInfo->antennaIndicesFeedbackTx;
2298 pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
2299 pDot11f->antennaIndicesFeedback = pASCapabilityInfo->antennaIndicesFeedback;
2300 pDot11f->rxAS = pASCapabilityInfo->rxAS;
2301 pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
2302
2303 pDot11f->present = 1;
2304
2305 return eSIR_SUCCESS;
2306
2307}
2308
2309tSirRetStatus
2310limTdlsPopulateDot11fVHTCaps(tpAniSirGlobal pMac,
2311 tSirTdlsAddStaReq *pTdlsAddStaReq,
2312 tDot11fIEVHTCaps *pDot11f)
2313{
2314 tANI_U32 nCfgValue=0;
2315 union {
2316 tANI_U32 nCfgValue32;
2317 tSirMacVHTCapabilityInfo vhtCapInfo;
2318 } uVHTCapabilityInfo;
2319 union {
2320 tANI_U16 nCfgValue16;
2321 tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
2322 tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
2323 } uVHTSupDataRateInfo;
2324
2325 pDot11f->present = 1;
2326
2327 nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
2328 uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
2329
2330 pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
2331 pDot11f->supportedChannelWidthSet = uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
2332 pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
2333 pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
2334 pDot11f->shortGI160and80plus80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
2335 pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
2336 pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
2337 pDot11f->suBeamFormerCap = uVHTCapabilityInfo.vhtCapInfo.suBeamFormerCap;
2338 pDot11f->suBeamformeeCap = uVHTCapabilityInfo.vhtCapInfo.suBeamformeeCap;
2339 pDot11f->csnofBeamformerAntSup = uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
2340 pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
2341 pDot11f->muBeamformerCap = uVHTCapabilityInfo.vhtCapInfo.muBeamformerCap;
2342 pDot11f->muBeamformeeCap = uVHTCapabilityInfo.vhtCapInfo.muBeamformeeCap;
2343 pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
2344 pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
2345 pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
2346 pDot11f->vhtLinkAdaptCap = uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
2347 pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
2348 pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
2349 pDot11f->reserved1= uVHTCapabilityInfo.vhtCapInfo.reserved1;
2350
2351 pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
2352
2353 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
2354 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2355 pDot11f->rxHighSupDataRate = uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
2356
2357 pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
2358
2359 nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
2360 uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
2361 pDot11f->txSupDataRate = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
2362
2363 pDot11f->reserved3= uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
2364
2365 limLogVHTCap(pMac, pDot11f);
2366
2367 return eSIR_SUCCESS;
2368
2369}
2370
2371static tSirRetStatus
2372limTdlsPopulateMatchingRateSet(tpAniSirGlobal pMac,
2373 tpDphHashNode pStaDs,
2374 tANI_U8 *pSupportedRateSet,
2375 tANI_U8 supporteRatesLength,
2376 tANI_U8* pSupportedMCSSet,
2377 tSirMacPropRateSet *pAniLegRateSet,
2378 tpPESession psessionEntry,
2379 tDot11fIEVHTCaps *pVHTCaps)
2380
2381{
2382 tSirMacRateSet tempRateSet;
2383 tANI_U32 i,j,val,min,isArate;
2384 tSirMacRateSet tempRateSet2;
2385 tANI_U32 phyMode;
2386 tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
2387 isArate=0;
2388
2389 // limGetPhyMode(pMac, &phyMode);
2390 limGetPhyMode(pMac, &phyMode, NULL);
2391
2392 // get own rate set
2393 val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
2394 if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
2395 (tANI_U8 *) &tempRateSet.rate,
2396 &val) != eSIR_SUCCESS)
2397 {
2398 /// Could not get rateset from CFG. Log error.
2399 limLog(pMac, LOGP, FL("could not retrieve rateset\n"));
2400 }
2401 tempRateSet.numRates = val;
2402
2403 if (phyMode == WNI_CFG_PHY_MODE_11G)
2404 {
2405
2406 // get own extended rate set
2407 val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
2408 if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
2409 (tANI_U8 *) &tempRateSet2.rate,
2410 &val) != eSIR_SUCCESS)
2411 tempRateSet2.numRates = val;
2412 }
2413 else
2414 tempRateSet2.numRates = 0;
2415
2416 if ((tempRateSet.numRates + tempRateSet2.numRates) > 12)
2417 {
2418 PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG\n"));)
2419 goto error;
2420 }
2421
2422 /**
2423 * Handling of the rate set IEs is the following:
2424 * - keep only rates that we support and that the station supports
2425 * - sort and the rates into the pSta->rate array
2426 */
2427
2428 // Copy all rates in tempRateSet, there are 12 rates max
2429 for (i = 0; i < tempRateSet2.numRates; i++)
2430 tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i];
2431
2432 tempRateSet.numRates += tempRateSet2.numRates;
2433
2434 /**
2435 * Sort rates in tempRateSet (they are likely to be already sorted)
2436 * put the result in tempRateSet2
2437 */
2438 tempRateSet2.numRates = 0;
2439
2440 for (i = 0;i < tempRateSet.numRates; i++)
2441 {
2442 min = 0;
2443 val = 0xff;
2444
2445 for(j = 0;j < tempRateSet.numRates; j++)
2446 if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val)
2447 {
2448 val = tempRateSet.rate[j] & 0x7f;
2449 min = j;
2450 }
2451
2452 tempRateSet2.rate[tempRateSet2.numRates++] = tempRateSet.rate[min];
2453 tempRateSet.rate[min] = 0xff;
2454 }
2455
2456 /**
2457 * Copy received rates in tempRateSet, the parser has ensured
2458 * unicity of the rates so there cannot be more than 12 . Need to Check this
2459 * TODO Sunil.
2460 */
2461 for (i = 0; i < supporteRatesLength; i++)
2462 {
2463 tempRateSet.rate[i] = pSupportedRateSet[i];
2464 }
2465
2466 tempRateSet.numRates = supporteRatesLength;
2467
2468 {
2469 tpSirSupportedRates rates = &pStaDs->supportedRates;
2470 tANI_U8 aRateIndex = 0;
2471 tANI_U8 bRateIndex = 0;
2472 palZeroMemory( pMac->hHdd, (tANI_U8 *) rates, sizeof(tSirSupportedRates));
2473
2474 for (i = 0;i < tempRateSet2.numRates; i++)
2475 {
2476 for (j = 0;j < tempRateSet.numRates; j++)
2477 {
2478 if ((tempRateSet2.rate[i] & 0x7F) ==
2479 (tempRateSet.rate[j] & 0x7F))
2480 {
2481#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
2482 if ((bRateIndex > HAL_NUM_11B_RATES) || (aRateIndex > HAL_NUM_11A_RATES))
2483 {
2484 limLog(pMac, LOGE, FL("Invalid number of rates (11b->%d, 11a->%d)\n"),
2485 bRateIndex, aRateIndex);
2486 return eSIR_FAILURE;
2487 }
2488#endif
2489 if (sirIsArate(tempRateSet2.rate[i] & 0x7f))
2490 {
2491 isArate=1;
2492 rates->llaRates[aRateIndex++] = tempRateSet2.rate[i];
2493 }
2494 else
2495 rates->llbRates[bRateIndex++] = tempRateSet2.rate[i];
2496 break;
2497 }
2498 }
2499 }
2500 }
2501
2502
2503 //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n
2504#ifdef FEATURE_WLAN_TDLS
2505 if (pStaDs->mlmStaContext.htCapability)
2506#else
2507 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
2508 (pStaDs->mlmStaContext.htCapability))
2509#endif
2510 {
2511 val = SIZE_OF_SUPPORTED_MCS_SET;
2512 if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET,
2513 mcsSet,
2514 &val) != eSIR_SUCCESS)
2515 {
2516 /// Could not get rateset from CFG. Log error.
2517 limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet\n"));
2518 goto error;
2519 }
2520
2521 for (i=0; i<val; i++)
2522 pStaDs->supportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i];
2523
2524 PELOG2(limLog(pMac, LOG2, FL("limPopulateMatchingRateSet: MCS Rate Set Bitmap from CFG and DPH :"));)
2525 for (i=0; i<SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
2526 {
2527 PELOG2(limLog(pMac, LOG2,FL("%x %x "), mcsSet[i], pStaDs->supportedRates.supportedMCSSet[i]);)
2528 }
2529 }
2530
2531#ifdef WLAN_FEATURE_11AC
2532 limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry);
2533#endif
2534 /**
2535 * Set the erpEnabled bit iff the phy is in G mode and at least
2536 * one A rate is supported
2537 */
2538 if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate)
2539 pStaDs->erpEnabled = eHAL_SET;
2540
2541
2542
2543 return eSIR_SUCCESS;
2544
2545 error:
2546
2547 return eSIR_FAILURE;
2548}
2549
2550static int limTdlsSelectCBMode(tDphHashNode *pStaDs, tpPESession psessionEntry)
2551{
2552 tANI_U8 channel = psessionEntry->currentOperChannel;
2553
2554 if ( pStaDs->mlmStaContext.vhtCapability )
2555 {
2556 if ( channel== 36 || channel == 52 || channel == 100 ||
2557 channel == 116 || channel == 149 )
2558 {
2559 return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
2560 }
2561 else if ( channel == 40 || channel == 56 || channel == 104 ||
2562 channel == 120 || channel == 153 )
2563 {
2564 return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
2565 }
2566 else if ( channel == 44 || channel == 60 || channel == 108 ||
2567 channel == 124 || channel == 157 )
2568 {
2569 return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
2570 }
2571 else if ( channel == 48 || channel == 64 || channel == 112 ||
2572 channel == 128 || channel == 161 )
2573 {
2574 return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
2575 }
2576 else if ( channel == 165 )
2577 {
2578 return 0;
2579 }
2580 }
2581 else if ( pStaDs->mlmStaContext.htCapability )
2582 {
2583 if ( channel== 40 || channel == 48 || channel == 56 ||
2584 channel == 64 || channel == 104 || channel == 112 ||
2585 channel == 120 || channel == 128 || channel == 136 ||
2586 channel == 144 || channel == 153 || channel == 161 )
2587 {
2588 return 1;
2589 }
2590 else if ( channel== 36 || channel == 44 || channel == 52 ||
2591 channel == 60 || channel == 100 || channel == 108 ||
2592 channel == 116 || channel == 124 || channel == 132 ||
2593 channel == 140 || channel == 149 || channel == 157 )
2594 {
2595 return 2;
2596 }
2597 else if ( channel == 165 )
2598 {
2599 return 0;
2600 }
2601 }
2602 return 0;
2603}
2604
Kiran V1ccee932012-12-12 14:49:46 -08002605/*
2606 * update HASH node entry info
2607 */
2608static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002609 tSirTdlsAddStaReq *pTdlsAddStaReq, tpPESession psessionEntry)
Kiran V1ccee932012-12-12 14:49:46 -08002610{
2611 //tDot11fIEHTCaps *htCaps = &setupPeerInfo->tdlsPeerHTCaps ;
2612 tDot11fIEHTCaps htCap, *htCaps;
Hoonki Lee99e53782013-02-12 18:07:03 -08002613#ifdef WLAN_FEATURE_11AC
2614 tDot11fIEVHTCaps vhtCap, *pVhtCaps;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002615 tANI_U8 cbMode;
Hoonki Lee99e53782013-02-12 18:07:03 -08002616#endif
Kiran V1ccee932012-12-12 14:49:46 -08002617 tpDphHashNode pSessStaDs = NULL;
2618 tANI_U16 aid;
2619
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002620 if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD)
2621 {
2622 PopulateDot11fHTCaps(pMac, psessionEntry, &htCap);
2623 }
2624 else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE)
2625 {
2626 limTdlsPopulateDot11fHTCaps(pMac, NULL, pTdlsAddStaReq, &htCap);
2627 }
Kiran V1ccee932012-12-12 14:49:46 -08002628 htCaps = &htCap;
Hoonki Lee99e53782013-02-12 18:07:03 -08002629 if (htCaps->present)
Kiran V1ccee932012-12-12 14:49:46 -08002630 {
2631 pStaDs->mlmStaContext.htCapability = 1 ;
2632 pStaDs->htGreenfield = htCaps->greenField ;
2633 pStaDs->htSupportedChannelWidthSet = htCaps->supportedChannelWidthSet ;
2634 pStaDs->htMIMOPSState = htCaps->mimoPowerSave ;
2635 pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
2636 pStaDs->htAMpduDensity = htCaps->mpduDensity;
2637 pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz ;
2638 pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
2639 pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
2640 pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
2641 limFillRxHighestSupportedRate(pMac,
2642 &pStaDs->supportedRates.rxHighestDataRate,
2643 htCaps->supportedMCSSet);
2644 pStaDs->baPolicyFlag = 0xFF;
Kiran V1ccee932012-12-12 14:49:46 -08002645 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N ;
2646 }
2647 else
2648 {
2649 pStaDs->mlmStaContext.htCapability = 0 ;
2650 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG ;
2651 }
Hoonki Lee99e53782013-02-12 18:07:03 -08002652#ifdef WLAN_FEATURE_11AC
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002653 limTdlsPopulateDot11fVHTCaps(pMac, pTdlsAddStaReq, &vhtCap);
Hoonki Lee99e53782013-02-12 18:07:03 -08002654 pVhtCaps = &vhtCap;
2655 if (pVhtCaps->present)
2656 {
2657 pStaDs->mlmStaContext.vhtCapability = 1 ;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002658 pStaDs->vhtSupportedChannelWidthSet= pVhtCaps->supportedChannelWidthSet;
2659 pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
2660 pStaDs->vhtBeamFormerCapable= pVhtCaps->suBeamFormerCap;
2661 // TODO , is it necessary , Sunil???
Hoonki Lee99e53782013-02-12 18:07:03 -08002662 pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
2663 }
2664 else
2665 {
2666 pStaDs->mlmStaContext.vhtCapability = 0 ;
2667 }
2668#endif
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002669 /*Calculate the Secondary Coannel Offset */
2670 cbMode = limTdlsSelectCBMode(pStaDs, psessionEntry);
2671
2672 pStaDs->htSecondaryChannelOffset = cbMode;
2673
2674#ifdef WLAN_FEATURE_11AC
2675 if ( pStaDs->mlmStaContext.vhtCapability )
2676 {
2677 pStaDs->htSecondaryChannelOffset = limGetHTCBState(cbMode);
2678 }
2679#endif
Kiran V1ccee932012-12-12 14:49:46 -08002680
2681 pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid,
2682 &psessionEntry->dph.dphHashTable) ;
2683
2684 /* Lets enable QOS parameter */
2685 pStaDs->qosMode = 1;
2686 pStaDs->wmeEnabled = 1;
2687 pStaDs->lleEnabled = 0;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002688 /* TDLS Dummy AddSTA does not have qosInfo , is it OK ??
2689 */
2690 pStaDs->qos.capability.qosInfo = (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
Kiran V1ccee932012-12-12 14:49:46 -08002691
2692 /* populate matching rate set */
Kiran V1ccee932012-12-12 14:49:46 -08002693
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002694 /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
2695 */
2696 limTdlsPopulateMatchingRateSet(pMac, pStaDs, pTdlsAddStaReq->supported_rates,
2697 pTdlsAddStaReq->supported_rates_length,
2698 (tANI_U8 *)pTdlsAddStaReq->htCap.suppMcsSet,
2699 &pStaDs->mlmStaContext.propRateSet,
2700 psessionEntry, (tDot11fIEVHTCaps *)&pTdlsAddStaReq->vhtCap);
2701
2702 /* TDLS Dummy AddSTA does not have right capability , is it OK ??
2703 */
2704 pStaDs->mlmStaContext.capabilityInfo = ( *(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
Kiran V1ccee932012-12-12 14:49:46 -08002705
2706 return ;
2707}
2708
2709#ifdef FEATURE_WLAN_TDLS_INTERNAL
2710/*
2711 * find Peer in setup link list.
2712 */
2713
2714tANI_U8 limTdlsFindLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac,
2715 tLimTdlsLinkSetupPeer **setupPeer)
2716{
2717 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2718 tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
2719 tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ;
2720
2721 while (linkSetupList != NULL)
2722 {
2723 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2724 (tANI_U8 *) linkSetupList->peerMac,
2725 sizeof(tSirMacAddr)) )
2726 {
2727 checkNode = TDLS_NODE_FOUND ;
2728 *setupPeer = linkSetupList ;
2729 break ;
2730 }
2731 linkSetupList = linkSetupList->next;
2732 }
2733
2734 return ((TDLS_NODE_FOUND == checkNode) ? eSIR_SUCCESS : eSIR_FAILURE ) ;
2735}
2736
2737/*
2738 * find peer in Discovery list.
2739 * Dicovery list get populated in two instances, a) Recieved responses in reply
2740 * to discovery request b) If discover request is received from TDLS peer STA
2741 */
2742tSirTdlsPeerInfo *limTdlsFindDisPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
2743{
2744 tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
2745 tSirTdlsPeerInfo *peerInfo = NULL ;
2746
2747 while (discoveryList != NULL)
2748 {
2749 peerInfo = &discoveryList->tdlsDisPeerInfo ;
2750 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2751 ("Peer in discovery list = %02x, %02x, %02x, %02x, %02x, %02x \n"),
2752 peerInfo->peerMac[0],
2753 peerInfo->peerMac[1],
2754 peerInfo->peerMac[2],
2755 peerInfo->peerMac[3],
2756 peerInfo->peerMac[4],
2757 peerInfo->peerMac[5]) ;
2758
2759 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2760 (tANI_U8 *) &peerInfo->peerMac, sizeof(tSirMacAddr)) )
2761 {
2762 break ;
2763 }
2764 discoveryList = discoveryList->next;
2765 }
2766
2767 return peerInfo ;
2768}
2769
2770/*
2771 * find peer in Discovery list by looking into peer state.
2772 * Dicovery list get populated in two instances, a) Recieved responses in reply
2773 * to discovery request b) If discover request is received from TDLS peer STA
2774 */
2775static tSirTdlsPeerInfo *limTdlsFindDisPeerByState(tpAniSirGlobal pMac,
2776 tANI_U8 state)
2777{
2778 tLimDisResultList *discoveryList = pMac->lim.gLimTdlsDisResultList ;
2779 tSirTdlsPeerInfo *peerInfo = NULL ;
2780
2781 while (discoveryList != NULL)
2782 {
2783 peerInfo = &discoveryList->tdlsDisPeerInfo ;
2784 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2785 ("peerInfo Mac = %02x, %02x, %02x, %02x, %02x, %02x "),
2786 peerInfo->peerMac[0],
2787 peerInfo->peerMac[1],
2788 peerInfo->peerMac[2],
2789 peerInfo->peerMac[3],
2790 peerInfo->peerMac[4],
2791 peerInfo->peerMac[5]) ;
2792
2793 if (peerInfo->tdlsPeerState == state)
2794 {
2795 break ;
2796 }
2797 discoveryList = discoveryList->next;
2798 }
2799
2800 return peerInfo ;
2801}
2802
2803/*
2804 * find peer in Setup list by looking into peer state.
2805 * setup list get populated in two instances, a) Recieved responses in reply
2806 * to setup request b) If discover request is received from TDLS peer STA
2807 */
2808static tANI_U8 limTdlsFindSetupPeerByState(tpAniSirGlobal pMac, tANI_U8 state,
2809 tLimTdlsLinkSetupPeer **setupPeer)
2810{
2811
2812 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2813 tLimTdlsLinkSetupPeer *linkSetupList = setupInfo->tdlsLinkSetupList ;
2814 tANI_U8 checkNode = TDLS_NODE_NOT_FOUND ;
2815
2816 while (linkSetupList != NULL)
2817 {
2818 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2819 ("peer state = %02x\n"), (linkSetupList)->tdls_link_state) ;
2820 if((linkSetupList)->tdls_link_state == state)
2821 {
2822 checkNode = TDLS_NODE_FOUND ;
2823 *setupPeer = linkSetupList ;
2824 break ;
2825 }
2826 linkSetupList = (linkSetupList)->next;
2827 }
2828
2829 return ((TDLS_NODE_FOUND == checkNode) ? eSIR_SUCCESS: eSIR_FAILURE) ;
2830}
2831
2832
2833/*
2834 * delete Peer from Setup Link
2835 */
2836void limTdlsDelLinkPeer(tpAniSirGlobal pMac, tSirMacAddr peerMac)
2837{
2838 tLimTdlsLinkSetupInfo *setupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
2839 tLimTdlsLinkSetupPeer **linkSetupList = &setupInfo->tdlsLinkSetupList ;
2840 tLimTdlsLinkSetupPeer *currentNode = NULL ;
2841 tLimTdlsLinkSetupPeer *prevNode = NULL ;
2842
2843 for(currentNode = *linkSetupList ; currentNode != NULL ;
2844 prevNode = currentNode, currentNode = currentNode->next)
2845 {
2846 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) peerMac,
2847 (tANI_U8 *) currentNode->peerMac,
2848 sizeof(tSirMacAddr)) )
2849 {
2850 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2851 ("Del Node for Peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
2852 currentNode->peerMac[0],
2853 currentNode->peerMac[1],
2854 currentNode->peerMac[2],
2855 currentNode->peerMac[3],
2856 currentNode->peerMac[4],
2857 currentNode->peerMac[5]) ;
2858 /* if it's first Node */
2859 if(NULL == prevNode)
2860 {
2861 *linkSetupList = currentNode->next ;
2862 }
2863 else
2864 {
2865 prevNode->next = currentNode->next ;
2866 }
2867 palFreeMemory(pMac, currentNode) ;
2868 return ;
2869 }
2870 }
2871
2872 return ;
2873}
2874
2875
2876
2877/*
2878 * TDLS discovery request frame received from TDLS peer STA..
2879 */
2880static tSirRetStatus limProcessTdlsDisReqFrame(tpAniSirGlobal pMac,
2881 tANI_U8 *pBody, tANI_U32 frmLen )
2882{
2883 tDot11fTDLSDisReq tdlsDisReq = {{0}} ;
2884 tANI_U32 status = 0 ;
2885 tLimDisResultList *tdlsDisResult = NULL ;
2886 tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
2887 tSirMacAddr peerMac = {0} ;
2888 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
2889 tSirTdlsPeerInfo *peerInfo = NULL ;
2890 tpPESession psessionEntry = NULL ;
2891 tANI_U8 sessionId = 0 ;
2892
2893 status = dot11fUnpackTDLSDisReq(pMac, pBody, frmLen, &tdlsDisReq) ;
2894
2895 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,
2896 ("TDLS dis request dialog = %d\n"), tdlsDisReq.DialogToken.token);
2897
2898 if ( DOT11F_FAILED( status ) )
2899 {
2900 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
2901 frame (0x%08x, %d bytes):\n"),status, frmLen);
2902 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2903 return eSIR_FAILURE;
2904 }
2905 else if ( DOT11F_WARNED( status ) )
2906 {
2907 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
2908 TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
2909 status, frmLen );
2910 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
2911 }
2912
2913 /*
2914 * find session entry using BSSID in link identifier, not using MAC
2915 * header beacuse, there is cases in TDLS, there may be BSSID will not
2916 * be present in header
2917 */
2918 psessionEntry = peFindSessionByBssid(pMac,
2919 &tdlsDisReq.LinkIdentifier.bssid[0], &sessionId) ;
2920 if(NULL == psessionEntry)
2921 {
2922 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
2923 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
2924 tdlsDisReq.LinkIdentifier.bssid[0],
2925 tdlsDisReq.LinkIdentifier.bssid[1],
2926 tdlsDisReq.LinkIdentifier.bssid[2],
2927 tdlsDisReq.LinkIdentifier.bssid[3],
2928 tdlsDisReq.LinkIdentifier.bssid[4],
2929 tdlsDisReq.LinkIdentifier.bssid[5]) ;
2930
2931 //VOS_ASSERT(0) ;
2932 return eSIR_FAILURE;
2933 }
2934
2935 /* varify BSSID */
2936 status = palEqualMemory(pMac->hHdd, &psessionEntry->bssId[0],
2937 &tdlsDisReq.LinkIdentifier.bssid[0], sizeof(tSirMacAddr)) ;
2938 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2939 ("lim BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"),
2940 psessionEntry->bssId[0],
2941 psessionEntry->bssId[1],
2942 psessionEntry->bssId[2],
2943 psessionEntry->bssId[3],
2944 psessionEntry->bssId[4],
2945 psessionEntry->bssId[5]) ;
2946
2947 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
2948 ("Dis req from BSSID %02x, %02x, %02x, %02x, %02x, %02x\n"),
2949 tdlsDisReq.LinkIdentifier.bssid[0],
2950 tdlsDisReq.LinkIdentifier.bssid[1],
2951 tdlsDisReq.LinkIdentifier.bssid[2],
2952 tdlsDisReq.LinkIdentifier.bssid[3],
2953 tdlsDisReq.LinkIdentifier.bssid[4],
2954 tdlsDisReq.LinkIdentifier.bssid[5]
2955 ) ;
2956 if(!status)
2957 {
2958 limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter\n")) ;
2959
2960 return eSIR_FAILURE ;
2961 }
2962
2963 /*
2964 * check if this is echo of our transmitted discovery request
2965 * drop it here, TODO: better to drop this in TL.
2966 */
2967 status = palEqualMemory(pMac->hHdd, psessionEntry->selfMacAddr,
2968 &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
2969 sizeof(tSirMacAddr)) ;
2970 if(status)
2971 {
2972 limLog( pMac, LOGE, FL("Echo of our TDLS discovery request frame\n")) ;
2973 return eSIR_FAILURE ;
2974 }
2975
2976 /*
2977 * while processing Discovery request from Peer,
2978 * STA_MAC--> MAC of TDLS discovery initiator
2979 * STA_PEER_MAC--> MAC of TDLS discovery responder.
2980 */
2981 palCopyMemory(pMac->hHdd, peerMac,
2982 &tdlsDisReq.LinkIdentifier.InitStaAddr[0],
2983 sizeof(tSirMacAddr)) ;
2984 /* TODO, do more validation */
2985
2986 /* see if discovery is already in progress */
2987 peerInfo = limTdlsFindDisPeer(pMac, peerMac) ;
2988
2989 if(NULL == peerInfo)
2990 {
2991 /*
2992 * we are allocating peer info for individual peers found in TDLS
2993 * discovery, we need to keep adding TDLS peers till we have timed
2994 * out. We are freeing this memory at the time we are sending this
2995 * collected peer info to SME.
2996 */
2997 status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult,
2998 sizeof(tLimDisResultList)) ;
2999
3000 if(status != eHAL_STATUS_SUCCESS)
3001 {
3002 limLog(pMac, LOGP, FL("alloc fail for TDLS discovery \
3003 reponse info\n")) ;
3004 return eSIR_FAILURE ;
3005 }
3006
3007
3008 peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;
3009 peerInfo->tdlsPeerState = TDLS_DIS_REQ_PROCESS_STATE ;
3010 peerInfo->dialog = tdlsDisReq.DialogToken.token ;
3011
3012 peerInfo->sessionId = psessionEntry->peSessionId;
3013
3014 /* Populate peer info of tdls discovery result */
3015 status = palCopyMemory(pMac->hHdd, peerInfo->peerMac, peerMac,
3016 sizeof(tSirMacAddr)) ;
3017
3018 /*
3019 * Now, as per D13, there will not be any Supp rates, ext Supp rates
3020 * info in Discovery request frames, so we are populating this info
3021 * locally to pass it to ADD STA.
3022 */
3023 do
3024 {
3025 tDot11fIESuppRates suppRates = {0} ;
3026 tDot11fIEExtSuppRates extSuppRates = {0} ;
3027 tANI_U16 caps = 0 ;
3028 tDot11fFfCapabilities capsInfo = {0} ;
3029 tDot11fIEHTCaps HTCaps = {0} ;
3030 /* populate supported rate IE */
3031 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
3032 &suppRates, psessionEntry );
3033 ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates,
3034 &suppRates);
3035 /* Populate extended supported rates */
3036 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
3037 &extSuppRates, psessionEntry );
3038
3039 peerInfo->ExtRatesPresent = 1;
3040 ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates,
3041 &extSuppRates);
3042
3043 if(cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS)
3044 {
3045 /*
3046 * Could not get Capabilities value
3047 * from CFG. Log error.
3048 */
3049 limLog(pMac, LOGP,
3050 FL("could not retrieve Capabilities value\n"));
3051 }
3052 swapBitField16(caps, ( tANI_U16* )&capsInfo );
3053 /* update Caps Info */
3054 tdlsUpdateCapInfo(&peerInfo->capabilityInfo , &capsInfo) ;
3055
3056 PopulateDot11fHTCaps( pMac, psessionEntry, &HTCaps );
3057 limTdlsCovertHTCaps(pMac, peerInfo, &HTCaps) ;
3058
3059 } while (0) ;
3060
3061 /* now add this new found discovery node into tdls discovery list */
3062 tdlsDisResult->next = *disResultList ;
3063 *disResultList = tdlsDisResult ;
3064 pMac->lim.gLimTdlsDisStaCount++ ;
3065
3066 /* See if for this peer already entry in setup Link */
3067 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
3068
3069 /*
3070 * if there is no entry for this peer in setup list, we need to
3071 * do add sta for this peer to transmit discovery rsp.
3072 */
3073 if(NULL == setupPeer)
3074 {
3075 /* To start with, send add STA request to HAL */
3076 pMac->lim.gLimAddStaTdls = true ;
3077 peerInfo->delStaNeeded = true ;
3078
3079 if(eSIR_FAILURE == limTdlsDisAddSta(pMac, peerMac,
3080 peerInfo, psessionEntry))
3081 {
3082 VOS_ASSERT(0) ;
3083 limLog(pMac, LOGE, "Add STA for dis response is failed \n") ;
3084 return eSIR_FAILURE ;
3085 }
3086 } /* use setup link sta ID for discovery rsp */
3087 else
3088 {
3089 peerInfo->delStaNeeded = false ;
3090 limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
3091 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
3092 }
3093
3094 }
3095 else
3096 {
3097 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3098 ("discovery procedure in progress for this peer\n")) ;
3099 }
3100
3101 return eSIR_SUCCESS ;
3102}
3103
3104/* Process TDLS setup Request Frame */
3105
3106static tSirRetStatus limProcessTdlsSetupReqFrame(tpAniSirGlobal pMac,
3107 tANI_U8 *pBody, tANI_U32 frmLen)
3108{
3109
3110 tDot11fTDLSSetupReq tdlsSetupReq = {{0}} ;
3111 tANI_U32 status = 0 ;
3112 tpPESession psessionEntry = NULL ;
3113 tANI_U8 sessionId = 0 ;
3114 tANI_U8 currentState = TDLS_LINK_SETUP_WAIT_STATE ;
3115 tANI_U8 previousState = TDLS_LINK_IDLE_STATE ;
3116 /* create node for Link setup */
3117 tLimTdlsLinkSetupInfo *linkSetupInfo = &pMac->lim.gLimTdlsLinkSetupInfo ;
3118 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3119 tLimTdlsLinkSetupPeer *tmpSetupPeer = NULL ;
3120
3121 status = dot11fUnpackTDLSSetupReq(pMac, pBody, frmLen, &tdlsSetupReq) ;
3122
3123 if ( DOT11F_FAILED( status ) )
3124 {
3125 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
3126 frame (0x%08x, %d bytes):\n"),status, frmLen);
3127 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3128 return eSIR_FAILURE;
3129 }
3130 else if ( DOT11F_WARNED( status ) )
3131 {
3132 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3133 TDLS setup Request frame (0x%08x," "%d bytes):\n"),
3134 status, pBody );
3135 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3136 }
3137 /*
3138 * find session entry using BSSID in link identifier, not using MAC
3139 * header beacuse, there is cases in TDLS, there may be BSSID will not
3140 * be present in header
3141 */
3142 psessionEntry = peFindSessionByBssid(pMac,
3143 &tdlsSetupReq.LinkIdentifier.bssid[0], &sessionId) ;
3144 if(NULL == psessionEntry)
3145 {
3146 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
3147 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
3148 tdlsSetupReq.LinkIdentifier.bssid[0],
3149 tdlsSetupReq.LinkIdentifier.bssid[1],
3150 tdlsSetupReq.LinkIdentifier.bssid[2],
3151 tdlsSetupReq.LinkIdentifier.bssid[3],
3152 tdlsSetupReq.LinkIdentifier.bssid[4],
3153 tdlsSetupReq.LinkIdentifier.bssid[5]) ;
3154
3155 //VOS_ASSERT(0) ;
3156 return eSIR_FAILURE ;
3157 }
3158 /* TODO: we don;t need this check now, varify BSSID */
3159 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3160 &tdlsSetupReq.LinkIdentifier.bssid[0],
3161 sizeof(tSirMacAddr)) ;
3162
3163 if(!status)
3164 {
3165 limLog( pMac, LOGE, FL("TDLS setup request frame from other BSS -> something wrong. Check RXP filter\n")) ;
3166
3167 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, tdlsSetupReq.DialogToken.token , psessionEntry,
3168 TDLS_SETUP_STATUS_FAILURE, NULL, 0 ) ;
3169 return eSIR_FAILURE ;
3170 }
3171
3172#ifdef FEATURE_WLAN_TDLS_NEGATIVE
3173 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_RSP_TIMEOUT_TO_SETUP_REQ)
3174 {
3175 /* simply ignore this setup request packet */
3176 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3177 ("TDLS negative running: ignore TDLS Setup Req packet\n"));
3178 return eSIR_SUCCESS ;
3179 }
3180 if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
3181 {
3182 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3183 ("TDLS negative running: send TDLS Setup Req to peer TDLS Setup Req\n"));
3184 /* format TDLS discovery request frame and transmit it */
3185 limSendTdlsLinkSetupReqFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr, tdlsSetupReq.DialogToken.token, psessionEntry,
3186 NULL, 0) ;
3187 }
3188#endif
3189 /* TODO, do more validation */
3190
3191 if(!limTdlsFindLinkPeer(pMac,
3192 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
3193 &tmpSetupPeer))
3194 {
3195 tANI_U32 tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;
3196
3197 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3198 ("Link is already setup with this peer\n" )) ;
3199 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3200 ("state = %d\n"), tmpSetupPeer->tdls_link_state) ;
3201 //return eSIR_FAILURE ;
3202
3203 if(tmpSetupPeer == NULL)
3204 {
3205 VOS_ASSERT(0) ;
3206 return eSIR_FAILURE ;
3207
3208 }
3209 switch(tmpSetupPeer->tdls_link_state)
3210 {
3211
3212 case TDLS_LINK_SETUP_START_STATE:
3213 {
3214 v_SINT_t macCompare = 0 ;
3215 macCompare= vos_mem_compare2(tmpSetupPeer->peerMac,
3216 psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
3217 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3218 ("MAC comparison Rslt = %d\n"), macCompare ) ;
3219 if(0 > macCompare)
3220 {
3221 /*
3222 * Delete our Setup Request/Peer info and honour Peer
3223 * Setup Request, go ahead and respond for this
3224 */
3225 /* Deactivate the timer */
3226 tx_timer_deactivate(&tmpSetupPeer->gLimTdlsLinkSetupRspTimeoutTimer) ;
3227#ifdef FEATURE_WLAN_TDLS_NEGATIVE
3228 if((pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
3229 != LIM_TDLS_NEGATIVE_SEND_REQ_TO_SETUP_REQ)
3230#endif
3231 limSendSmeTdlsLinkStartRsp(pMac, eSIR_FAILURE,
3232 tmpSetupPeer->peerMac, eWNI_SME_TDLS_LINK_START_RSP);
3233
3234 limTdlsDelLinkPeer(pMac, tmpSetupPeer->peerMac) ;
3235 tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
3236 }
3237 else if(0 < macCompare)
3238 {
3239 /*
3240 * Go ahead with current setup as peer is going to
3241 * respond for setup request
3242 */
3243 tdlsStateStatus = TDLS_LINK_SETUP_START_STATE ;
3244 }
3245 else
3246 {
3247 /* same MAC, not possible */
3248 VOS_ASSERT(0) ;
3249 }
3250
3251 break ;
3252 }
3253#if 1
3254 case TDLS_LINK_SETUP_DONE_STATE:
3255 {
3256 tpDphHashNode pStaDs = NULL ;
3257
3258 previousState = TDLS_LINK_SETUP_WAIT_STATE ;
3259 currentState = TDLS_LINK_TEARDOWN_START_STATE ;
3260 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3261 ("link Setup Done state " )) ;
3262 tmpSetupPeer->tdls_prev_link_state = previousState ;
3263 tmpSetupPeer->tdls_link_state = currentState ;
3264 setupPeer = tmpSetupPeer ;
3265#if 0
3266 /* Send Teardown to this Peer and Initiate new TDLS Setup */
3267 limSendTdlsTeardownFrame(pMac,
3268 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
3269 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON, psessionEntry) ;
3270#else
3271
3272 /* tdls_hklee: send message to HAL before it is deleted, cause */
3273 limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;
3274
3275 /* send del STA to remove context for this TDLS STA */
3276 pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;
3277
3278 /* now send indication to SME-->HDD->TL to remove STA from TL */
3279
3280 if(pStaDs)
3281 {
3282 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
3283 pStaDs, eSIR_SUCCESS) ;
3284
3285 /* send Teardown Ind to SME */
3286 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
3287 eWNI_SME_TDLS_TEARDOWN_IND) ;
3288 /* remove node from setup list */
3289 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
3290 }
3291#endif
3292 //setupPeer->tdls_prev_link_state = TDLS_LINK_SETUP_RESTART_STATE;
3293 tdlsStateStatus = TDLS_LINK_IDLE_STATE ;
3294 break ;
3295
3296 }
3297 default:
3298 {
3299 VOS_ASSERT(0) ;
3300 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3301 ("link Setup is Recieved in unknown state\n" )) ;
3302 break ;
3303 }
3304#endif
3305 }
3306 if(tdlsStateStatus == TDLS_LINK_SETUP_START_STATE)
3307 return eSIR_FAILURE ;
3308 }
3309
3310 if(currentState != TDLS_LINK_TEARDOWN_START_STATE)
3311 {
3312 /*
3313 * Now we are sure to send discovery response frame to TDLS discovery
3314 * initiator, we don't care, if this request is unicast ro broadcast,
3315 * we simply, send discovery response frame on direct link.
3316 */
3317 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
3318 (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
3319 {
3320 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3321 ( "Unable to allocate memory during ADD_STA\n" ));
3322 return eSIR_MEM_ALLOC_FAILED;
3323 }
3324
3325 setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
3326 //setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
3327 //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
3328 setupPeer->tdls_prev_link_state = previousState ;
3329 setupPeer->tdls_link_state = currentState ;
3330 /* TDLS_sessionize: remember sessionId for future */
3331 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
3332 setupPeer->tdls_bIsResponder = 0;
3333
3334 palCopyMemory(pMac->hHdd, setupPeer->peerMac,
3335 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
3336 sizeof(tSirMacAddr)) ;
3337
3338 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3339 ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
3340 setupPeer->peerMac[0],
3341 setupPeer->peerMac[1],
3342 setupPeer->peerMac[2],
3343 setupPeer->peerMac[3],
3344 setupPeer->peerMac[4],
3345 setupPeer->peerMac[5] ) ;
3346
3347 limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
3348 pMac->lim.gLimAddStaTdls = true ;
3349
3350 /* To start with, send add STA request to HAL */
3351 if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, setupPeer->peerMac,
3352 setupPeer, psessionEntry))
3353 {
3354 VOS_ASSERT(0) ;
3355 palFreeMemory(pMac->hHdd, (void **) &setupPeer) ;
3356 return eSIR_FAILURE ;
3357 }
3358
3359 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
3360 tdlsSetupReq.DialogToken.token , psessionEntry,
3361 TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;
3362
3363 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
3364 &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
3365 (tANI_U32)setupPeer->peerMac,
3366 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
3367 SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;
3368
3369 /* update setup peer list */
3370 setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
3371 linkSetupInfo->tdlsLinkSetupList = setupPeer ;
3372 }
3373 else
3374 {
3375 setupPeer->dialog = tdlsSetupReq.DialogToken.token ;
3376 //setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
3377 //setupPeer->tdls_link_state = TDLS_LINK_SETUP_WAIT_STATE ;
3378 setupPeer->tdls_prev_link_state = previousState ;
3379 setupPeer->tdls_link_state = currentState ;
3380 /* TDLS_sessionize: remember sessionId for future */
3381 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
3382 setupPeer->tdls_bIsResponder = 0;
3383
3384 palCopyMemory(pMac->hHdd, setupPeer->peerMac,
3385 &tdlsSetupReq.LinkIdentifier.InitStaAddr[0],
3386 sizeof(tSirMacAddr)) ;
3387
3388 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3389 ("Setup REQ MAC = %02x,%02x, %02x, %02x, %02x, %02x\n"),
3390 setupPeer->peerMac[0],
3391 setupPeer->peerMac[1],
3392 setupPeer->peerMac[2],
3393 setupPeer->peerMac[3],
3394 setupPeer->peerMac[4],
3395 setupPeer->peerMac[5] ) ;
3396
3397 limTdlsUpdateLinkReqPeerInfo(pMac, setupPeer, &tdlsSetupReq) ;
3398 limSendTdlsSetupRspFrame(pMac, tdlsSetupReq.LinkIdentifier.InitStaAddr,
3399 tdlsSetupReq.DialogToken.token , psessionEntry,
3400 TDLS_SETUP_STATUS_SUCCESS, NULL, 0) ;
3401
3402 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
3403 &setupPeer->gLimTdlsLinkSetupCnfTimeoutTimer,
3404 (tANI_U32)setupPeer->peerMac,
3405 WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT,
3406 SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT) ;
3407 }
3408
3409
3410 return eSIR_SUCCESS ;
3411
3412}
3413
3414/*
3415 * TDLS discovery request frame received from TDLS peer STA..
3416 */
3417static tSirRetStatus limProcessTdlsSetupRspFrame(tpAniSirGlobal pMac,
3418 tANI_U8 *pBody, tANI_U32 frmLen )
3419{
3420 tDot11fTDLSSetupRsp tdlsSetupRsp = {{0}} ;
3421 tANI_U32 status = 0 ;
3422 tSirMacAddr peerMac = {0} ;
3423 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3424 tpPESession psessionEntry = NULL ;
3425 tANI_U8 sessionId = 0 ;
3426
3427 status = dot11fUnpackTDLSSetupRsp(pMac, pBody, frmLen, &tdlsSetupRsp) ;
3428
3429 if ( DOT11F_FAILED( status ) )
3430 {
3431 limLog(pMac, LOGE, FL("Failed to parse TDLS discovery Request \
3432 frame (0x%08x, %d bytes):\n"),status, frmLen);
3433 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3434 return eSIR_FAILURE;
3435 }
3436 else if ( DOT11F_WARNED( status ) )
3437 {
3438 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3439 TDLS discovery Request frame (0x%08x," "%d bytes):\n"),
3440 status, frmLen );
3441 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3442 }
3443
3444 /*
3445 * find session entry using BSSID in link identifier, not using MAC
3446 * header beacuse, there is cases in TDLS, there may be BSSID will not
3447 * be present in header
3448 */
3449 psessionEntry = peFindSessionByBssid(pMac,
3450 &tdlsSetupRsp.LinkIdentifier.bssid[0], &sessionId) ;
3451 if(NULL == psessionEntry)
3452 {
3453 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
3454 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
3455 tdlsSetupRsp.LinkIdentifier.bssid[0],
3456 tdlsSetupRsp.LinkIdentifier.bssid[1],
3457 tdlsSetupRsp.LinkIdentifier.bssid[2],
3458 tdlsSetupRsp.LinkIdentifier.bssid[3],
3459 tdlsSetupRsp.LinkIdentifier.bssid[4],
3460 tdlsSetupRsp.LinkIdentifier.bssid[5]) ;
3461
3462 //VOS_ASSERT(0) ;
3463 return eSIR_FAILURE;
3464 }
3465
3466 /* varify BSSID */
3467 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3468 &tdlsSetupRsp.LinkIdentifier.bssid[0],
3469 sizeof(tSirMacAddr)) ;
3470
3471 if(!status)
3472 {
3473 limLog( pMac, LOGE, FL("TDLS discovery request frame from other BSS -> something wrong. Check RXP filter\n")) ;
3474
3475 VOS_ASSERT(0) ;
3476 return eSIR_FAILURE ;
3477 }
3478 palCopyMemory(pMac->hHdd, peerMac,
3479 &tdlsSetupRsp.LinkIdentifier.RespStaAddr[0],
3480 sizeof(tSirMacAddr)) ;
3481
3482 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3483 ("TDLS setup RSP peer = %02x,%02x,%02x,%02x,%02x,%02x\n"),
3484 peerMac[0],
3485 peerMac[1],
3486 peerMac[2],
3487 peerMac[3],
3488 peerMac[4],
3489 peerMac[5]) ;
3490 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
3491
3492 if(NULL == setupPeer)
3493 {
3494 limLog( pMac, LOGE, FL(" unknown setup Response frame \
3495 other BSS\n")) ;
3496 return eSIR_FAILURE ;
3497 }
3498
3499 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3500 ("deactivating Setup RSP timer\n")) ;
3501
3502 /* Deactivate the timer */
3503 tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupRspTimeoutTimer) ;
3504
3505 /*
3506 * TDLS Setup RSP is recieved with Failure, Delete this STA entry
3507 * don't respond with TDLS CNF frame.
3508 */
3509 if(TDLS_SETUP_STATUS_SUCCESS != tdlsSetupRsp.Status.status)
3510 {
3511 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
3512 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3513 ("setup RSP with Failure Code\n")) ;
3514 return eSIR_FAILURE ;
3515 }
3516
3517 /* update Link Info */
3518 limTdlsUpdateLinkRspPeerInfo(pMac, setupPeer, &tdlsSetupRsp) ;
3519
3520 /* TODO, do more validation */
3521
3522
3523 /*
3524 * Now we are sure to send link setup CNF frame to TDLS link setup
3525 * reponded, now we will create dph hash entry and send add STA to HAL
3526 */
3527
3528 pMac->lim.gLimAddStaTdls = true ;
3529 if(eSIR_FAILURE == limTdlsSetupAddSta(pMac, peerMac,
3530 setupPeer, psessionEntry))
3531 {
3532 /* through error */
3533 VOS_ASSERT(0) ;
3534 return eSIR_FAILURE ;
3535 }
3536 /* TDLS_HKLEE_FIXME: now we add some delay for AddSta_Rsp comes */
3537
3538
3539 /* send TDLS confim frame to TDLS Peer STA */
3540 limSendTdlsLinkSetupCnfFrame(pMac, peerMac, tdlsSetupRsp.DialogToken.token, psessionEntry, NULL, 0) ;
3541
3542 /*
3543 * set the tdls_link_state to TDLS_LINK_SETUP_RSP_WAIT_STATE, and
3544 * wait for Setup CNF transmission on air, once we receive tx complete
3545 * message, we will change the peer state and send message to SME
3546 * callback..
3547 */
3548 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
3549 (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_RSP_WAIT_STATE ;
3550
3551 return eSIR_SUCCESS ;
3552}
3553/*
3554 * TDLS setup CNF frame processing ..
3555 */
3556
3557static tSirRetStatus limProcessTdlsSetupCnfFrame(tpAniSirGlobal pMac,
3558 tANI_U8 *pBody, tANI_U32 frmLen)
3559{
3560 tDot11fTDLSSetupCnf tdlsSetupCnf = {{0}} ;
3561 tANI_U32 status = 0 ;
3562 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3563 tpPESession psessionEntry = NULL ;
3564 tANI_U8 sessionId = 0 ;
3565
3566 status = dot11fUnpackTDLSSetupCnf(pMac, pBody, frmLen, &tdlsSetupCnf) ;
3567
3568 if ( DOT11F_FAILED( status ) )
3569 {
3570 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
3571 frame (0x%08x, %d bytes):\n"),status, frmLen);
3572 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3573 return eSIR_FAILURE;
3574 }
3575 else if ( DOT11F_WARNED( status ) )
3576 {
3577 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3578 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
3579 status, frmLen );
3580 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3581 }
3582 /*
3583 * find session entry using BSSID in link identifier, not using MAC
3584 * header beacuse, there is cases in TDLS, there may be BSSID will not
3585 * be present in header
3586 */
3587 psessionEntry = peFindSessionByBssid(pMac,
3588 &tdlsSetupCnf.LinkIdentifier.bssid[0], &sessionId) ;
3589 if(NULL == psessionEntry)
3590 {
3591 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
3592 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
3593 tdlsSetupCnf.LinkIdentifier.bssid[0],
3594 tdlsSetupCnf.LinkIdentifier.bssid[1],
3595 tdlsSetupCnf.LinkIdentifier.bssid[2],
3596 tdlsSetupCnf.LinkIdentifier.bssid[3],
3597 tdlsSetupCnf.LinkIdentifier.bssid[4],
3598 tdlsSetupCnf.LinkIdentifier.bssid[5]) ;
3599
3600 //VOS_ASSERT(0) ;
3601 return eSIR_FAILURE;
3602 }
3603
3604 /* varify BSSID */
3605 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3606 &tdlsSetupCnf.LinkIdentifier.bssid[0],
3607 sizeof(tSirMacAddr)) ;
3608
3609 if(!status)
3610 {
3611 limLog( pMac, LOGE, FL("TDLS setup CNF frame other BSS -> something wrong. Check RXP filter\n")) ;
3612
3613 VOS_ASSERT(0) ;
3614 return eSIR_FAILURE ;
3615 }
3616 /* TODO, do more validation */
3617 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3618 ("setup Cnf peer MAc = %02x,%02x,%02x,%02x,%02x,%02x\n"),
3619 tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
3620 tdlsSetupCnf.LinkIdentifier.InitStaAddr[1],
3621 tdlsSetupCnf.LinkIdentifier.InitStaAddr[2],
3622 tdlsSetupCnf.LinkIdentifier.InitStaAddr[3],
3623 tdlsSetupCnf.LinkIdentifier.InitStaAddr[4],
3624 tdlsSetupCnf.LinkIdentifier.InitStaAddr[5]
3625 ) ;
3626
3627 limTdlsFindLinkPeer(pMac,
3628 &tdlsSetupCnf.LinkIdentifier.InitStaAddr[0],
3629 &setupPeer) ;
3630
3631 if(NULL == setupPeer)
3632 {
3633 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3634 (" unknown setup CNF frame\n")) ;
3635 VOS_ASSERT(0) ;
3636 return eSIR_FAILURE ;
3637 }
3638 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3639 ("setup CNF peer MAC = %02x,%02x,%02x,%02x,%02x,%02x\n"),
3640 (setupPeer)->peerMac[0],
3641 (setupPeer)->peerMac[1],
3642 (setupPeer)->peerMac[2],
3643 (setupPeer)->peerMac[3],
3644 (setupPeer)->peerMac[4],
3645 (setupPeer)->peerMac[5]) ;
3646 /*T match dialog token, before proceeding further */
3647 if((setupPeer)->dialog != tdlsSetupCnf.DialogToken.token)
3648 {
3649 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
3650 ("setup CNF frame not matching with setup RSP\n")) ;
3651 VOS_ASSERT(0) ;
3652 return eSIR_FAILURE ;
3653 }
3654
3655 /*
3656 * Now we are sure that, this set CNF is for us, now stop
3657 * the running timer..
3658 */
3659 tx_timer_deactivate(&(setupPeer)->gLimTdlsLinkSetupCnfTimeoutTimer) ;
3660
3661 /* change TDLS peer State */
3662 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
3663 (setupPeer)->tdls_link_state = TDLS_LINK_SETUP_DONE_STATE ;
3664
3665 /* send indication to SME that, new link is setup */
3666 limSendSmeTdlsLinkSetupInd(pMac, (setupPeer)->peerMac, eSIR_SUCCESS) ;
3667
3668 /* tdls_hklee: prepare PTI template and send it to HAL */
3669 limTdlsLinkEstablish(pMac, (setupPeer)->peerMac);
3670
3671 return eSIR_SUCCESS ;
3672
3673}
3674
3675/*
3676 * TDLS discovery response frame processing ..
3677 */
3678
3679static tSirRetStatus limProcessTdlsDisRspFrame(tpAniSirGlobal pMac,
3680 tANI_U8 *pBody, tANI_U32 frmLen,
3681 tANI_S8 rssi, tpPESession psessionEntry)
3682{
3683 tDot11fTDLSDisRsp tdlsDisRsp = {{0}} ;
3684 tANI_U32 status = 0 ;
3685 tLimDisResultList *tdlsDisResult = NULL ;
3686 tLimDisResultList **disResultList = &pMac->lim.gLimTdlsDisResultList ;
3687 tSirTdlsDisReq *prevDisReq = &pMac->lim.gLimTdlsDisReq ;
3688
3689 status = dot11fUnpackTDLSDisRsp(pMac, pBody, frmLen, &tdlsDisRsp) ;
3690
3691 if ( DOT11F_FAILED( status ) )
3692 {
3693 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
3694 frame (0x%08x, %d bytes):\n"),status, frmLen);
3695 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3696 return eSIR_FAILURE;
3697 }
3698 else if ( DOT11F_WARNED( status ) )
3699 {
3700 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3701 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
3702 status, frmLen );
3703 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);)
3704 }
3705 /*TODO: match dialog token, before proceeding further */
3706
3707 /* varify BSSID */
3708 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3709 &tdlsDisRsp.LinkIdentifier.bssid[0],
3710 sizeof(tSirMacAddr)) ;
3711
3712 if(!status)
3713 {
3714 limLog( pMac, LOGW, FL(" TDLS discovery Response frame other BSS\n")) ;
3715 return eSIR_FAILURE ;
3716 }
3717 /* TODO, do more validation */
3718
3719 if(tdlsDisRsp.DialogToken.token != prevDisReq->dialog)
3720 {
3721 limLog( pMac, LOGW, FL(" wrong TDLS discovery Response frame\n")) ;
3722 return eSIR_FAILURE ;
3723 }
3724
3725 pMac->lim.gLimTdlsDisStaCount++ ;
3726
3727 /*
3728 * we are allocating peer info for individual peers found in TDLS
3729 * discovery, we need to keep adding TDLS peers till we have timed
3730 * out. We are freeing this memory at the time we are sending this
3731 * collected peer info to SME.
3732 */
3733 status = palAllocateMemory(pMac->hHdd, (void **)&tdlsDisResult,
3734 sizeof(tLimDisResultList)) ;
3735
3736 if(status != eHAL_STATUS_SUCCESS)
3737 {
3738 limLog(pMac, LOGP, FL("alloc fail for TDLS discovery reponse info\n")) ;
3739 return eSIR_FAILURE ;
3740 }
3741
3742 do
3743 {
3744 tSirTdlsPeerInfo *peerInfo = &tdlsDisResult->tdlsDisPeerInfo ;
3745
3746 /* Populate peer info of tdls discovery result */
3747 peerInfo->sessionId = psessionEntry->peSessionId;
3748 /*
3749 * When we receive DIS RSP from peer MAC,
3750 * STA_MAC_OFFSET will carry peer MAC address and PEER MAC OFFSET
3751 * will carry our MAC.
3752 */
3753 status = palCopyMemory(pMac->hHdd, peerInfo->peerMac,
3754 &tdlsDisRsp.LinkIdentifier.RespStaAddr[0],
3755 sizeof(tSirMacAddr)) ;
3756
3757 /* update RSSI for this TDLS peer STA */
3758 peerInfo->tdlsPeerRssi = rssi ;
3759
3760 /* update Caps Info */
3761 tdlsUpdateCapInfo(&peerInfo->capabilityInfo ,
3762 &tdlsDisRsp.Capabilities) ;
3763
3764 /* update Supp rates */
3765 if(tdlsDisRsp.SuppRates.present)
3766 {
3767 ConvertSuppRates( pMac, &peerInfo->tdlsPeerSuppRates,
3768 &tdlsDisRsp.SuppRates );
3769 }
3770
3771 /* update EXT supp rates */
3772 if(tdlsDisRsp.ExtSuppRates.present)
3773 {
3774 peerInfo->ExtRatesPresent = 1;
3775 ConvertExtSuppRates( pMac, &peerInfo->tdlsPeerExtRates,
3776 &tdlsDisRsp.ExtSuppRates );
3777 }
3778 /* update HT caps */
3779 if (tdlsDisRsp.HTCaps.present)
3780 {
3781 palCopyMemory( pMac, &peerInfo->tdlsPeerHtCaps, &tdlsDisRsp.HTCaps,
3782 sizeof( tDot11fIEHTCaps ) );
3783 }
3784 /* update EXT caps */
3785 if (tdlsDisRsp.ExtCap.present)
3786 {
3787 //palCopyMemory( pMac, &peerInfo->tdlsPeerExtenCaps,
3788 // &tdlsDisRsp.ExtCap,
3789 // sizeof( tDot11fIEExtCap ) );
3790 }
3791 } while(0) ;
3792
3793 /* now add this new found discovery node into tdls discovery list */
3794 tdlsDisResult->next = *disResultList ;
3795 *disResultList = tdlsDisResult ;
3796
3797 return eSIR_SUCCESS ;
3798}
3799
3800/*
3801 * Process TDLS Teardown request frame from TDLS peer STA
3802 */
3803static tSirRetStatus limProcessTdlsTeardownFrame(tpAniSirGlobal pMac,
3804 tANI_U8 *pBody, tANI_U32 frmLen )
3805{
3806 tDot11fTDLSTeardown tdlsTeardown = {{0}} ;
3807 tANI_U32 status = 0 ;
3808 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
3809 tpPESession psessionEntry = NULL ;
3810 tANI_U8 sessionId = 0 ;
3811
3812 status = dot11fUnpackTDLSTeardown(pMac, pBody, frmLen, &tdlsTeardown) ;
3813
3814 if ( DOT11F_FAILED( status ) )
3815 {
3816 limLog(pMac, LOGE, FL("Failed to parse an TDLS discovery Response \
3817 frame (0x%08x, %d bytes):\n"),status, frmLen);
3818 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3819 return eSIR_FAILURE;
3820 }
3821 else if ( DOT11F_WARNED( status ) )
3822 {
3823 limLog( pMac, LOGW, FL("There were warnings while unpacking an\
3824 TDLS discovery Response frame (0x%08x," "%d bytes):\n"),
3825 status, frmLen );
3826 PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frmLen);)
3827 }
3828
3829 /*
3830 * find session entry using BSSID in link identifier, not using MAC
3831 * header beacuse, there is cases in TDLS, there may be BSSID will not
3832 * be present in header
3833 */
3834 psessionEntry = peFindSessionByBssid(pMac,
3835 &tdlsTeardown.LinkIdentifier.bssid[0], &sessionId) ;
3836 if(NULL == psessionEntry)
3837 {
3838 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \
3839 ("no Seesion entry for TDLS session (bssid %02x:%02x:%02x:%02x:%02x:%02x)\n"), \
3840 tdlsTeardown.LinkIdentifier.bssid[0],
3841 tdlsTeardown.LinkIdentifier.bssid[1],
3842 tdlsTeardown.LinkIdentifier.bssid[2],
3843 tdlsTeardown.LinkIdentifier.bssid[3],
3844 tdlsTeardown.LinkIdentifier.bssid[4],
3845 tdlsTeardown.LinkIdentifier.bssid[5]) ;
3846
3847 //VOS_ASSERT(0) ;
3848 return eSIR_FAILURE;
3849 }
3850
3851 /* varify BSSID */
3852 status = palEqualMemory(pMac->hHdd, psessionEntry->bssId,
3853 &tdlsTeardown.LinkIdentifier.bssid[0],
3854 sizeof(tSirMacAddr)) ;
3855
3856
3857 if(!status)
3858 {
3859 limLog( pMac, LOGE, FL("Teardown from other BSS -> something wrong. Check RXP filter\n")) ;
3860 VOS_ASSERT(0) ;
3861 return eSIR_FAILURE ;
3862 }
3863
3864 limTdlsFindLinkPeer(pMac,
3865 &tdlsTeardown.LinkIdentifier.InitStaAddr[0],
3866 &setupPeer) ;
3867
3868 if(NULL == setupPeer)
3869 {
3870 //ignore
3871 //VOS_ASSERT(0) ;
3872 limLog( pMac, LOGE, FL("Teardown from unknown peer. --> ignored\n") );
3873
3874 return eSIR_FAILURE ;
3875 }
3876 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3877 ("teardown for peer %02x,%02x,%02x,%02x,%02x,%02x\n"),
3878 (setupPeer)->peerMac[0],
3879 (setupPeer)->peerMac[1],
3880 (setupPeer)->peerMac[2],
3881 (setupPeer)->peerMac[3],
3882 (setupPeer)->peerMac[4],
3883 (setupPeer)->peerMac[5]) ;
3884
3885 switch(tdlsTeardown.Reason.code)
3886 {
3887 case eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON:
3888 {
3889 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3890 ("teardown with unspecified reason\n")) ;
3891 break ;
3892 }
3893 case eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE:
3894 {
3895 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3896 (" Teardown from AP, TDLS peer unreachable\n")) ;
3897 break ;
3898 }
3899 default:
3900 {
3901 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
3902 (" unknown teardown\n")) ;
3903 break ;
3904 }
3905 }
3906
3907 /* change TDLS peer State */
3908 (setupPeer)->tdls_prev_link_state = (setupPeer)->tdls_link_state ;
3909 (setupPeer)->tdls_link_state = TDLS_LINK_TEARDOWN_START_STATE ;
3910
3911 do
3912 {
3913 tpDphHashNode pStaDs = NULL ;
3914
3915 /* tdls_hklee: send message to HAL before it is deleted, cause */
3916 limTdlsLinkTeardown(pMac, (setupPeer)->peerMac) ;
3917
3918 /* send del STA to remove context for this TDLS STA */
3919 pStaDs = limTdlsDelSta(pMac, (setupPeer)->peerMac, psessionEntry) ;
3920
3921 /* now send indication to SME-->HDD->TL to remove STA from TL */
3922
3923 if(pStaDs)
3924 {
3925 limSendSmeTdlsDelPeerInd(pMac, psessionEntry->smeSessionId,
3926 pStaDs, eSIR_SUCCESS) ;
3927
3928 /* send Teardown Ind to SME */
3929 limSendSmeTdlsTeardownRsp(pMac, eSIR_SUCCESS, (setupPeer)->peerMac,
3930 eWNI_SME_TDLS_TEARDOWN_IND) ;
3931 /* remove node from setup list */
3932 limTdlsDelLinkPeer(pMac, (setupPeer)->peerMac) ;
3933 }
3934
3935 }while(0) ;
3936
3937 return status ;
3938}
3939
3940/*
3941 * Common processing of TDLS action frames recieved
3942 */
3943void limProcessTdlsFrame(tpAniSirGlobal pMac, tANI_U32 *pBd)
3944{
3945 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
3946 tANI_U8 pOffset = ((0 == WDA_GET_RX_FT_DONE(pBd))
3947 ? (( sizeof( eth_890d_header ))) :(0)) ;
3948
3949 tANI_U8 category = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[0] ;
3950 tANI_U8 action = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE)[1] ;
3951 tANI_U32 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
3952 tANI_U8 *tdlsFrameBody = (pBody + pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
3953 //tANI_S8 rssi = (tANI_S8)SIR_MAC_BD_TO_RSSI_DB(pBd);
3954
3955 if(category != SIR_MAC_ACTION_TDLS)
3956 {
3957 limLog( pMac, LOGE, FL("Invalid TDLS action frame=(%d). Ignored\n"), category );
3958 return ;
3959 }
3960
3961 frameLen -= (pOffset + PAYLOAD_TYPE_TDLS_SIZE) ;
3962 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("Received TDLS action %d (%s)"), \
3963 action, limTraceTdlsActionString(action) ));
3964
3965 switch(action)
3966 {
3967
3968 case SIR_MAC_TDLS_SETUP_REQ:
3969 {
3970 limProcessTdlsSetupReqFrame(pMac, tdlsFrameBody, frameLen) ;
3971 break ;
3972 }
3973 case SIR_MAC_TDLS_SETUP_RSP:
3974 {
3975 limProcessTdlsSetupRspFrame(pMac, tdlsFrameBody, frameLen) ;
3976 break ;
3977 }
3978 case SIR_MAC_TDLS_SETUP_CNF:
3979 {
3980 limProcessTdlsSetupCnfFrame(pMac, tdlsFrameBody, frameLen) ;
3981 break ;
3982 }
3983 case SIR_MAC_TDLS_TEARDOWN:
3984 {
3985 limProcessTdlsTeardownFrame(pMac, tdlsFrameBody, frameLen) ;
3986 break ;
3987 }
3988 case SIR_MAC_TDLS_DIS_REQ:
3989 {
3990 limProcessTdlsDisReqFrame(pMac, tdlsFrameBody, frameLen) ;
3991 break ;
3992 }
3993 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
3994 case SIR_MAC_TDLS_CH_SWITCH_REQ:
3995 case SIR_MAC_TDLS_CH_SWITCH_RSP:
3996 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
3997 default:
3998 {
3999 break ;
4000 }
4001 }
4002
4003 return ;
4004}
4005
4006/*
4007 * ADD sta for dis response fame sent on direct link
4008 */
4009static tSirRetStatus limTdlsDisAddSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
4010 tSirTdlsPeerInfo *peerInfo, tpPESession psessionEntry)
4011{
4012 tpDphHashNode pStaDs = NULL ;
4013 tSirRetStatus status = eSIR_SUCCESS ;
4014 tANI_U16 aid = 0 ;
4015
4016 if(NULL == peerInfo)
4017 {
4018 VOS_ASSERT(0) ;
4019 return status ;
4020
4021 }
4022 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4023 ("ADD STA peer MAC: %02x, %02x, %02x, %02x, %02x, %02x\n"),
4024 peerMac[0],
4025 peerMac[1],
4026 peerMac[2],
4027 peerMac[3],
4028 peerMac[4],
4029 peerMac[5]) ;
4030
4031
4032 if(NULL != dphLookupHashEntry(pMac, peerMac,
4033 &aid, &psessionEntry->dph.dphHashTable))
4034 {
4035 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4036 (" there is hash entry for this client\n")) ;
4037 status = eSIR_FAILURE ;
4038 VOS_ASSERT(0) ;
4039 return status ;
4040 }
4041
Gopichand Nakkala777e6032012-12-31 16:39:21 -08004042 aid = limAssignPeerIdx(pMac, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08004043
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08004044 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
4045 SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
4046
Kiran V1ccee932012-12-12 14:49:46 -08004047 pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
4048
4049 if (pStaDs)
4050 {
4051 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
4052 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
4053 }
4054 pStaDs = dphAddHashEntry(pMac, peerMac, aid,
4055 &psessionEntry->dph.dphHashTable) ;
4056
4057 if(NULL == pStaDs)
4058 {
4059 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4060 (" add hash entry failed\n")) ;
4061 status = eSIR_FAILURE ;
4062 VOS_ASSERT(0) ;
4063 return status;
4064 }
4065 if(eSIR_SUCCESS == status)
4066 {
4067#ifdef TDLS_RATE_DEBUG
4068 tSirMacRateSet *suppRates = &peerInfo->tdlsPeerSuppRates ;
4069 tSirMacRateSet *extRates = &peerInfo->tdlsPeerExtRates ;
4070 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4071 ("pSta DS [%p] \n"), pStaDs) ;
4072 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4073 ("peerInfo->tdlsPeerSuppRates = [%p]\n"),
4074 (tANI_U8 *)&peerInfo->tdlsPeerSuppRates) ;
4075 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4076 ("peerInfo->tdlsPeerExtRates = [%p]\n"),
4077 (tANI_U8 *)&peerInfo->tdlsPeerExtRates) ;
4078 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4079 ("peerInfo->tdlsPeerPropRates = [%p]\n"),
4080 (tANI_U8 *)&pStaDs->mlmStaContext.propRateSet) ;
4081 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4082 ("peerInfo->mcs = [%p]\n"),
4083 (tANI_U8 *)peerInfo->supportedMCSSet) ;
4084 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4085 ("num of supp rates = %02x\n"), suppRates->numRates) ;
4086 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4087 ("num of ext rates = %01x\n"), extRates->numRates) ;
4088#endif
4089
4090 /* Populate matching rate set */
4091#ifdef WLAN_FEATURE_11AC
4092 if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs,
4093 &peerInfo->tdlsPeerSuppRates,
4094 &peerInfo->tdlsPeerExtRates,
4095 peerInfo->supportedMCSSet,
4096 &pStaDs->mlmStaContext.propRateSet,
4097 psessionEntry, NULL))
4098#else
4099 if(eSIR_FAILURE == limPopulateMatchingRateSet(pMac, pStaDs,
4100 &peerInfo->tdlsPeerSuppRates,
4101 &peerInfo->tdlsPeerExtRates,
4102 peerInfo->supportedMCSSet,
4103 &pStaDs->mlmStaContext.propRateSet,
4104 psessionEntry))
4105#endif
4106 {
4107 VOS_ASSERT(0) ;
4108 }
4109
4110
4111 pStaDs->mlmStaContext.capabilityInfo = peerInfo->capabilityInfo;
4112 palCopyMemory(pMac->hHdd, pStaDs->staAddr, peerMac,
4113 sizeof(tSirMacAddr)) ;
4114 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4115 ("Add STA for Peer: %02x, %02x, %02x, %02x, %02x, %02x\n"),
4116 pStaDs->staAddr[0],
4117 pStaDs->staAddr[1],
4118 pStaDs->staAddr[2],
4119 pStaDs->staAddr[3],
4120 pStaDs->staAddr[4],
4121 pStaDs->staAddr[5]) ;
4122
4123
4124 pStaDs->staType = STA_ENTRY_TDLS_PEER ;
4125
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004126 status = limAddSta(pMac, pStaDs, false, psessionEntry);
Kiran V1ccee932012-12-12 14:49:46 -08004127
4128 if(eSIR_SUCCESS != status)
4129 {
4130 /* should not fail */
4131 VOS_ASSERT(0) ;
4132 }
4133 }
4134
4135 return status ;
4136}
4137#endif
4138/*
4139 * Add STA for TDLS setup procedure
4140 */
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004141static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac,
4142 tSirTdlsAddStaReq *pAddStaReq,
4143 tpPESession psessionEntry)
Kiran V1ccee932012-12-12 14:49:46 -08004144{
4145 tpDphHashNode pStaDs = NULL ;
4146 tSirRetStatus status = eSIR_SUCCESS ;
4147 tANI_U16 aid = 0 ;
4148
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004149 pStaDs = dphLookupHashEntry(pMac, pAddStaReq->peerMac, &aid,
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004150 &psessionEntry->dph.dphHashTable);
Kiran V1ccee932012-12-12 14:49:46 -08004151 if(NULL == pStaDs)
4152 {
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004153 aid = limAssignPeerIdx(pMac, psessionEntry) ;
4154
4155 if( !aid )
4156 {
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08004157 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004158 ("%s: No more free AID for peer " MAC_ADDRESS_STR),
4159 __func__, MAC_ADDR_ARRAY(pAddStaReq->peerMac)) ;
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004160 return eSIR_FAILURE;
4161 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08004162
4163 /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
4164 SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
4165
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004166 VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004167 ("limTdlsSetupAddSta: Aid = %d, for peer =" MAC_ADDRESS_STR),
4168 aid, MAC_ADDR_ARRAY(pAddStaReq->peerMac));
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004169 pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
4170
4171 if (pStaDs)
4172 {
4173 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry);
4174 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry);
4175 }
4176
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004177 pStaDs = dphAddHashEntry(pMac, pAddStaReq->peerMac, aid,
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004178 &psessionEntry->dph.dphHashTable) ;
4179
4180 if(NULL == pStaDs)
4181 {
4182 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4183 (" add hash entry failed\n")) ;
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004184 VOS_ASSERT(0) ;
Gopichand Nakkala114718f2013-03-25 19:19:46 -07004185 return eSIR_FAILURE;
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004186 }
Kiran V1ccee932012-12-12 14:49:46 -08004187 }
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004188
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004189 limTdlsUpdateHashNodeInfo(pMac, pStaDs, pAddStaReq, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08004190
4191 pStaDs->staType = STA_ENTRY_TDLS_PEER ;
4192
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004193 status = limAddSta(pMac, pStaDs, (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) ? true: false, psessionEntry);
Kiran V1ccee932012-12-12 14:49:46 -08004194
4195 if(eSIR_SUCCESS != status)
4196 {
4197 /* should not fail */
4198 VOS_ASSERT(0) ;
Lee Hoonkif987a0b2013-01-29 02:07:07 -08004199 }
Kiran V1ccee932012-12-12 14:49:46 -08004200 return status ;
4201}
4202
4203/*
4204 * Del STA, after Link is teardown or discovery response sent on direct link
4205 */
4206static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
4207 tpPESession psessionEntry)
4208{
4209 tSirRetStatus status = eSIR_SUCCESS ;
Gopichand Nakkala777e6032012-12-31 16:39:21 -08004210 tANI_U16 peerIdx = 0 ;
Kiran V1ccee932012-12-12 14:49:46 -08004211 tpDphHashNode pStaDs = NULL ;
4212
Gopichand Nakkala777e6032012-12-31 16:39:21 -08004213 pStaDs = dphLookupHashEntry(pMac, peerMac, &peerIdx,
Kiran V1ccee932012-12-12 14:49:46 -08004214 &psessionEntry->dph.dphHashTable) ;
4215
4216 if(pStaDs)
4217 {
4218
4219 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4220 ("DEL STA peer MAC: %02x, %02x, %02x, %02x, %02x, %02x \n"),
4221 pStaDs->staAddr[0],
4222 pStaDs->staAddr[1],
4223 pStaDs->staAddr[2],
4224 pStaDs->staAddr[3],
4225 pStaDs->staAddr[4],
4226 pStaDs->staAddr[5]
4227 ) ;
4228
Hoonki Lee1090c6a2013-01-16 17:40:54 -08004229 VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
4230 ("limTdlsDelSta: STA type = %x, sta idx = %x\n"),pStaDs->staType,
Kiran V1ccee932012-12-12 14:49:46 -08004231 pStaDs->staIndex) ;
4232
4233 status = limDelSta(pMac, pStaDs, false, psessionEntry) ;
Hoonki Leef63df0d2013-01-16 19:29:14 -08004234#ifdef FEATURE_WLAN_TDLS_INTERNAL
Kiran V1ccee932012-12-12 14:49:46 -08004235 if(eSIR_SUCCESS == status)
4236 {
Gopichand Nakkala777e6032012-12-31 16:39:21 -08004237 limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx, psessionEntry) ;
4238 limReleasePeerIdx(pMac, peerIdx, psessionEntry) ;
Kiran V1ccee932012-12-12 14:49:46 -08004239 }
4240 else
4241 {
4242 VOS_ASSERT(0) ;
4243 }
Hoonki Leef63df0d2013-01-16 19:29:14 -08004244#endif
Kiran V1ccee932012-12-12 14:49:46 -08004245 }
4246
4247 return pStaDs ;
4248}
4249
4250#ifdef FEATURE_WLAN_TDLS_INTERNAL
4251/*
4252* Prepare link establish message for HAL, construct PTI template.
4253*
4254*/
4255static tSirRetStatus limTdlsLinkEstablish(tpAniSirGlobal pMac, tSirMacAddr peerMac)
4256{
4257 tANI_U8 pFrame[64] ;
4258 tDot11fTDLSPeerTrafficInd tdlsPtiTemplate ;
4259 tANI_U32 status = 0 ;
4260 tANI_U32 nPayload = 0 ;
4261 tANI_U32 nBytes = 0 ;
4262 tANI_U32 header_offset = 0 ;
4263 tANI_U16 aid = 0 ;
4264 tDphHashNode *pStaDs = NULL ;
4265 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
4266 tpPESession psessionEntry = NULL ;
4267
4268
4269 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
4270 if(NULL == setupPeer) {
4271 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4272 ("limTdlsLinkEstablish: cannot find peer mac in tdls linksetup list: %02X %02X %02X %02X %02X %02X\n"), \
4273 peerMac[0], peerMac[1], peerMac[2], \
4274 peerMac[3], peerMac[4], peerMac[5]);
4275 return eSIR_FAILURE;
4276 }
4277
4278 psessionEntry = peFindSessionBySessionId(pMac,
4279 setupPeer->tdls_sessionId) ;
4280
4281 if(NULL == psessionEntry)
4282 {
4283 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4284 ("limTdlsLinkEstablish: sessionID %d is not found\n"), setupPeer->tdls_sessionId);
4285 VOS_ASSERT(0) ;
4286 return eHAL_STATUS_FAILURE;
4287 }
4288
4289 /* */
4290 pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable) ;
4291 if(pStaDs == NULL) {
4292 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4293 ("limTdlsLinkEstablish: cannot find peer mac in hash table: %02X %02X %02X %02X %02X %02X\n"), \
4294 peerMac[0], peerMac[1], peerMac[2], \
4295 peerMac[3], peerMac[4], peerMac[5]);
4296 return eSIR_FAILURE;
4297 }
4298
4299 palZeroMemory( pMac->hHdd, ( tANI_U8* )&tdlsPtiTemplate,
4300 sizeof( tDot11fTDLSPeerTrafficInd ) );
4301
4302 /*
4303 * setup Fixed fields,
4304 */
4305 tdlsPtiTemplate.Category.category = SIR_MAC_ACTION_TDLS;
4306 tdlsPtiTemplate.Action.action = SIR_MAC_TDLS_PEER_TRAFFIC_IND;
4307 tdlsPtiTemplate.DialogToken.token = 0 ; /* filled by firmware at the time of transmission */
4308#if 1
4309 /* CHECK_PTI_LINK_IDENTIFIER_INITIATOR_ADDRESS: initator address should be TDLS link setup's initiator address,
4310 then below code makes such an way */
4311 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
4312 peerMac, !setupPeer->tdls_bIsResponder) ;
4313#else
4314 /* below code will make PTI's linkIdentifier's initiator address be selfAddr */
4315 PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsPtiTemplate.LinkIdentifier,
4316 peerMac, TDLS_INITIATOR) ;
4317#endif
4318
4319 /* PUBufferStatus will be filled by firmware at the time of transmission */
4320 tdlsPtiTemplate.PUBufferStatus.present = 1;
4321
4322 /* TODO: get ExtendedCapabilities IE */
4323
4324 /*
4325 * now we pack it. First, how much space are we going to need?
4326 */
4327 status = dot11fGetPackedTDLSPeerTrafficIndSize ( pMac, &tdlsPtiTemplate, &nPayload);
4328 if ( DOT11F_FAILED( status ) )
4329 {
4330 limLog( pMac, LOGP, FL("Failed to calculate the packed size for a PTI template (0x%08x).\n"), status );
4331 /* We'll fall back on the worst case scenario: */
4332 nPayload = sizeof( tdlsPtiTemplate );
4333 }
4334 else if ( DOT11F_WARNED( status ) )
4335 {
4336 limLog( pMac, LOGW, FL("There were warnings while calculating the packed size for a PTI template (0x%08x).\n"), status );
4337 }
4338
4339 /*
4340 * This frame is going out from PE as data frames with special ethertype
4341 * 89-0d.
4342 * 8 bytes of RFC 1042 header
4343 */
4344
4345 nBytes = nPayload + sizeof( tSirMacMgmtHdr )
4346 + sizeof( eth_890d_header )
4347 + PAYLOAD_TYPE_TDLS_SIZE ;
4348
4349 if(nBytes > 64) {
4350 limLog( pMac, LOGE, FL("required memory for PTI frame is %ld, but reserved only 64.\n"), nBytes);
4351 nBytes = 64;
4352 }
4353 /* zero out the memory */
4354 palZeroMemory( pMac->hHdd, pFrame, sizeof(pFrame) );
4355
4356 /* fill out the buffer descriptor */
4357
4358 header_offset = limPrepareTdlsFrameHeader(pMac, pFrame,
4359 LINK_IDEN_ADDR_OFFSET(tdlsPtiTemplate), TDLS_LINK_AP, !setupPeer->tdls_bIsResponder, psessionEntry) ;
4360
4361 status = dot11fPackTDLSPeerTrafficInd ( pMac, &tdlsPtiTemplate, pFrame
4362 + header_offset, nPayload, &nPayload );
4363
4364 if ( DOT11F_FAILED( status ) )
4365 {
4366 limLog( pMac, LOGE, FL("Failed to pack a PTI template \
4367 (0x%08x).\n"), status );
4368 return eSIR_FAILURE;
4369 }
4370 else if ( DOT11F_WARNED( status ) )
4371 {
4372 limLog( pMac, LOGW, FL("There were warnings while packing TDLS"
4373 "Peer Traffic Indication (0x%08x).\n") );
4374 }
4375
4376 LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("bIsResponder=%d, header_offset=%ld, linkIdenOffset=%d, ptiBufStatusOffset=%d \n"), \
4377 setupPeer->tdls_bIsResponder, header_offset, PTI_LINK_IDEN_OFFSET, PTI_BUF_STATUS_OFFSET));
4378
4379 limSendTdlsLinkEstablish(pMac, setupPeer->tdls_bIsResponder,
4380 header_offset+PTI_LINK_IDEN_OFFSET, header_offset+PTI_BUF_STATUS_OFFSET,
4381 nBytes, pFrame, (tANI_U8 *)&setupPeer->tdlsPeerExtCaps);
4382
4383 return eSIR_SUCCESS;
4384}
4385
4386/*
4387* Prepare link teardown message for HAL from peer_mac
4388*
4389*/
4390static tSirRetStatus limTdlsLinkTeardown(tpAniSirGlobal pMac, tSirMacAddr peerMac)
4391{
4392 tDphHashNode *pStaDs = NULL ;
4393 tANI_U16 aid = 0 ;
4394 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
4395 tpPESession psessionEntry = NULL ;
4396
4397
4398 limTdlsFindLinkPeer(pMac, peerMac, &setupPeer) ;
4399 if(NULL == setupPeer) {
4400 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4401 ("limTdlsLinkTeardown: cannot find peer mac in tdls linksetup list: %02X %02X %02X %02X %02X %02X\n"), \
4402 peerMac[0], peerMac[1], peerMac[2], \
4403 peerMac[3], peerMac[4], peerMac[5]);
4404 return eSIR_FAILURE;
4405 }
4406
4407 psessionEntry = peFindSessionBySessionId(pMac,
4408 setupPeer->tdls_sessionId) ;
4409
4410 if(NULL == psessionEntry)
4411 {
4412 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4413 ("limTdlsLinkTeardown: sessionID %d is not found\n"), setupPeer->tdls_sessionId);
4414 VOS_ASSERT(0) ;
4415 return eHAL_STATUS_FAILURE;
4416 }
4417
4418
4419 /* */
4420 pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable);
4421
4422 if(pStaDs == NULL) {
4423 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4424 ("limTdlsLinkTeardown: cannot find peer mac in hash table: %02X %02X %02X %02X %02X %02X\n"), \
4425 peerMac[0], peerMac[1], peerMac[2], \
4426 peerMac[3], peerMac[4], peerMac[5]);
4427 return eSIR_FAILURE;
4428 }
4429
4430 limSendTdlsLinkTeardown(pMac, pStaDs->staIndex);
4431
4432 return eSIR_SUCCESS;
4433}
4434
4435/*
4436 * Prepare Discovery RSP message for SME, collect peerINfo for all the
4437 * peers discovered and delete/clean discovery lists in PE.
4438 */
4439
4440static tSirTdlsDisRsp *tdlsPrepareTdlsDisRsp(tpAniSirGlobal pMac,
4441 tSirTdlsDisRsp *disRsp, tANI_U8 disStaCount)
4442{
4443 tANI_U32 disMsgRspSize = sizeof(tSirTdlsDisRsp);
4444 tANI_U8 status = eHAL_STATUS_SUCCESS ;
4445
4446 /*
4447 * allocate memory for tdls discovery response, allocated memory should
4448 * be alloc_mem = tdlsStaCount * sizeof(peerinfo)
4449 * + siezeof tSirTdlsDisRsp.
4450 */
4451 disMsgRspSize += (disStaCount * sizeof(tSirTdlsPeerInfo));
4452
4453 /* now allocate memory */
4454 status = palAllocateMemory( pMac->hHdd, (void **)&disRsp, disMsgRspSize ) ;
4455
4456 if(eHAL_STATUS_FAILURE == status)
4457 {
4458 limLog(pMac, LOGP, FL("palAllocateMemory failed for DIS RSP"));
4459 return NULL ;
4460 }
4461
4462 if(disStaCount)
4463 {
4464 tLimDisResultList *tdlsDisRspList = pMac->lim.gLimTdlsDisResultList ;
4465 tSirTdlsPeerInfo *peerInfo = &disRsp->tdlsDisPeerInfo[0] ;
4466
4467 tLimDisResultList *currentNode = tdlsDisRspList ;
4468 while(tdlsDisRspList != NULL)
4469 {
4470
4471 palCopyMemory( pMac->hHdd, (tANI_U8 *)peerInfo,
4472 (tANI_U8 *) &tdlsDisRspList->tdlsDisPeerInfo,
4473 sizeof(tSirTdlsPeerInfo));
4474
4475 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
4476 ("Msg Sent to PE, peer MAC: %02x, %02x, %02x, %02x, %02x, %02x\n"),
4477 peerInfo->peerMac[0] ,
4478 peerInfo->peerMac[1] ,
4479 peerInfo->peerMac[2] ,
4480 peerInfo->peerMac[3] ,
4481 peerInfo->peerMac[4] ,
4482 peerInfo->peerMac[5]) ;
4483 disStaCount-- ;
4484 peerInfo++ ;
4485 currentNode = tdlsDisRspList ;
4486 tdlsDisRspList = tdlsDisRspList->next ;
4487 palFreeMemory(pMac->hHdd, currentNode) ;
4488 /* boundary condition check, may be fatal */
4489 if(((!disStaCount) && (tdlsDisRspList))
4490 || ((!tdlsDisRspList) && disStaCount))
4491 {
4492 limLog(pMac, LOG1, FL("mismatch in dis sta count and\
4493 and number of nodes in list\n")) ;
4494 VOS_ASSERT(0) ;
4495 return NULL ;
4496 }
4497 } /* end of while */
4498
4499 /* All discovery STA processed */
4500 pMac->lim.gLimTdlsDisResultList = NULL ;
4501
4502 } /* end of if dis STA count */
4503
4504 return (disRsp) ;
4505}
4506
4507/* Send Teardown response back to PE */
4508
4509void limSendSmeTdlsTeardownRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
4510 tSirMacAddr peerMac, tANI_U16 msgType)
4511{
4512 tSirMsgQ mmhMsg = {0} ;
4513 tSirTdlsTeardownRsp *teardownRspMsg = NULL ;
4514 tANI_U8 status = eHAL_STATUS_SUCCESS ;
4515
4516 mmhMsg.type = msgType ;
4517
4518 status = palAllocateMemory( pMac->hHdd, (void **)&teardownRspMsg,
4519 sizeof(tSirTdlsTeardownRsp)) ;
4520
4521 if(eHAL_STATUS_SUCCESS != status)
4522 {
4523 VOS_ASSERT(0) ;
4524 }
4525 palCopyMemory( pMac->hHdd, teardownRspMsg->peerMac, (tANI_U8 *)peerMac,
4526 sizeof(tSirMacAddr)) ;
4527 teardownRspMsg->statusCode = statusCode ;
4528 mmhMsg.bodyptr = teardownRspMsg ;
4529 mmhMsg.bodyval = 0;
4530 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4531
4532 return ;
4533
4534}
4535
4536/*
4537 * Send Link start RSP back to SME after link is setup or failed
4538 */
4539void limSendSmeTdlsLinkStartRsp(tpAniSirGlobal pMac,
4540 tSirResultCodes statusCode,
4541 tSirMacAddr peerMac,
4542 tANI_U16 msgType)
4543{
4544 tSirMsgQ mmhMsg = {0} ;
4545 tSirTdlsLinksetupRsp *setupRspMsg = NULL ;
4546 tANI_U8 status = eHAL_STATUS_SUCCESS ;
4547
4548 mmhMsg.type = msgType ;
4549
4550 status = palAllocateMemory( pMac->hHdd, (void **)&setupRspMsg,
4551 sizeof(tSirTdlsLinksetupRsp)) ;
4552
4553 if(eHAL_STATUS_SUCCESS != status)
4554 {
4555 VOS_ASSERT(0) ;
4556 }
4557
4558 palCopyMemory( pMac->hHdd, setupRspMsg->peerMac, (tANI_U8 *)peerMac,
4559 sizeof(tSirMacAddr)) ;
4560 setupRspMsg->statusCode = statusCode ;
4561 mmhMsg.bodyptr = setupRspMsg ;
4562 mmhMsg.bodyval = 0;
4563 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4564
4565 return ;
4566}
4567
4568/*
4569 * Send TDLS discovery RSP back to SME
4570 */
4571void limSendSmeTdlsDisRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode,
4572 tANI_U16 msgType)
4573{
4574 tSirMsgQ mmhMsg = {0} ;
4575 tSirTdlsDisRsp *tdlsDisRsp = NULL ;
4576
4577 mmhMsg.type = msgType ;
4578
4579 if(eSIR_SME_SUCCESS == statusCode)
4580 {
4581 tANI_U8 tdlsStaCount = pMac->lim.gLimTdlsDisStaCount ;
4582
4583 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4584 ("no of TDLS STA discovered: %d\n"), tdlsStaCount) ;
4585 tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, tdlsStaCount) ;
4586
4587 if(tdlsDisRsp)
4588 {
4589 tdlsDisRsp->numDisSta = tdlsStaCount ;
4590 }
4591 else
4592 {
4593 limLog(pMac, LOGP, FL("fatal failure for TDLS DIS RSP\n"));
4594 VOS_ASSERT(0) ;
4595 return ;
4596 }
4597 /* all Discovery STA is processed */
4598 pMac->lim.gLimTdlsDisStaCount = 0 ;
4599 }
4600 else
4601 {
4602 tdlsDisRsp = tdlsPrepareTdlsDisRsp(pMac, tdlsDisRsp, 0) ;
4603 }
4604
4605 tdlsDisRsp->statusCode = statusCode ;
4606 mmhMsg.bodyptr = tdlsDisRsp ;
4607 mmhMsg.bodyval = 0;
4608 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4609
4610 return ;
4611}
4612
4613/*
4614 * Once Link is setup with PEER, send Add STA ind to SME
4615 */
4616static eHalStatus limSendSmeTdlsAddPeerInd(tpAniSirGlobal pMac,
4617 tANI_U8 sessionId, tDphHashNode *pStaDs, tANI_U8 status)
4618{
4619 tSirMsgQ mmhMsg = {0} ;
4620 tSirTdlsPeerInd *peerInd = NULL ;
4621 mmhMsg.type = eWNI_SME_ADD_TDLS_PEER_IND ;
4622 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
4623 (sizeof(tSirTdlsPeerInd))))
4624 {
4625 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4626 return eSIR_FAILURE;
4627 }
4628
4629 palCopyMemory( pMac->hHdd, peerInd->peerMac,
4630 (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
4631 peerInd->sessionId = sessionId;
4632 peerInd->staId = pStaDs->staIndex ;
4633 peerInd->ucastSig = pStaDs->ucUcastSig ;
4634 peerInd->bcastSig = pStaDs->ucBcastSig ;
4635 peerInd->length = sizeof(tSmeIbssPeerInd) ;
4636
4637 mmhMsg.bodyptr = peerInd ;
4638 mmhMsg.bodyval = 0;
4639 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4640
4641 return eSIR_SUCCESS ;
4642
4643}
4644
4645/*
4646 * Once link is teardown, send Del Peer Ind to SME
4647 */
4648static eHalStatus limSendSmeTdlsDelPeerInd(tpAniSirGlobal pMac,
4649 tANI_U8 sessionId, tDphHashNode *pStaDs, tANI_U8 status)
4650{
4651 tSirMsgQ mmhMsg = {0} ;
4652 tSirTdlsPeerInd *peerInd = NULL ;
4653 mmhMsg.type = eWNI_SME_DELETE_TDLS_PEER_IND ;
4654 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &peerInd,
4655 (sizeof(tSirTdlsPeerInd))))
4656 {
4657 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4658 return eSIR_FAILURE;
4659 }
4660
4661 palCopyMemory( pMac->hHdd, peerInd->peerMac,
4662 (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr));
4663 peerInd->sessionId = sessionId;
4664 peerInd->staId = pStaDs->staIndex ;
4665 peerInd->ucastSig = pStaDs->ucUcastSig ;
4666 peerInd->bcastSig = pStaDs->ucBcastSig ;
4667 peerInd->length = sizeof(tSmeIbssPeerInd) ;
4668
4669 mmhMsg.bodyptr = peerInd ;
4670
4671 //peerInd->statusCode = status ;
4672 mmhMsg.bodyval = 0;
4673 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4674 return eSIR_SUCCESS ;
4675
4676}
4677
4678/*
4679 * Send Link setup Ind to SME, This is the case where, link setup is
4680 * initiated by peer STA
4681 */
4682static eHalStatus limSendSmeTdlsLinkSetupInd(tpAniSirGlobal pMac,
4683 tSirMacAddr peerMac, tANI_U8 status)
4684{
4685 tSirMsgQ mmhMsg = {0} ;
4686 tSirTdlsLinkSetupInd *setupInd = NULL ;
4687
4688 mmhMsg.type = eWNI_SME_TDLS_LINK_START_IND ;
4689 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &setupInd,
4690 (sizeof(tSirTdlsLinkSetupInd))))
4691 {
4692 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4693 return eSIR_FAILURE;
4694 }
4695
4696 palCopyMemory( pMac->hHdd, setupInd->peerMac,
4697 (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
4698 setupInd->length = sizeof(tSirTdlsLinkSetupInd);
4699 setupInd->statusCode = status ;
4700 mmhMsg.bodyptr = setupInd ;
4701 mmhMsg.bodyval = 0;
4702 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4703
4704 return eSIR_SUCCESS ;
4705
4706}
4707
4708/*
4709 * Setup RSP timer handler
4710 */
4711void limTdlsLinkSetupRspTimerHandler(void *pMacGlobal, tANI_U32 timerId)
4712{
4713
4714 tANI_U32 statusCode;
4715 tSirMsgQ msg;
4716 tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
4717
4718 /* Prepare and post message to LIM Message Queue */
4719
4720 msg.type = SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT;
4721 msg.bodyptr = NULL ;
4722 msg.bodyval = timerId ;
4723
4724 if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
4725 limLog(pMac, LOGE,
4726 FL("posting message %X to LIM failed, reason=%d\n"),
4727 msg.type, statusCode);
4728 return ;
4729}
4730
4731/*
4732 * Link setup CNF timer
4733 */
4734void limTdlsLinkSetupCnfTimerHandler(void *pMacGlobal, tANI_U32 timerId)
4735{
4736
4737 tANI_U32 statusCode;
4738 tSirMsgQ msg;
4739 tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
4740
4741 // Prepare and post message to LIM Message Queue
4742
4743 msg.type = SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT;
4744 msg.bodyptr = NULL ;
4745 msg.bodyval = timerId ;
4746
4747 if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS)
4748 limLog(pMac, LOGE,
4749 FL("posting message %X to LIM failed, reason=%d\n"),
4750 msg.type, statusCode);
4751 return ;
4752}
4753
4754/*
4755 * start TDLS timer
4756 */
4757void limStartTdlsTimer(tpAniSirGlobal pMac, tANI_U8 sessionId, TX_TIMER *timer,
4758 tANI_U32 timerId, tANI_U16 timerType, tANI_U32 timerMsg)
4759{
4760 tANI_U32 cfgValue = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
4761 ? WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT
4762 : WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT ;
4763
4764 void *timerFunc = (timerMsg == SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT)
4765 ? (limTdlsLinkSetupRspTimerHandler)
4766 : limTdlsLinkSetupCnfTimerHandler ;
4767
4768 /* TODO: Read timer vals from CFG */
4769
4770 cfgValue = SYS_MS_TO_TICKS(cfgValue);
4771 /*
4772 * create TDLS discovery response wait timer and activate it
4773 */
4774 if (tx_timer_create(timer, "TDLS link setup timers", timerFunc,
4775 timerId, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS)
4776 {
4777 limLog(pMac, LOGP,
4778 FL("could not create TDLS discovery response wait timer\n"));
4779 return;
4780 }
4781
4782 //assign appropriate sessionId to the timer object
4783 timer->sessionId = sessionId;
4784
4785 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0,
4786 eLIM_TDLS_DISCOVERY_RSP_WAIT));
4787 if (tx_timer_activate(timer) != TX_SUCCESS)
4788 {
4789 limLog(pMac, LOGP, FL("TDLS link setup timer activation failed!\n"));
4790 return ;
4791 }
4792
4793 return ;
4794
4795}
4796#endif
4797
4798/*
4799 * Once Link is setup with PEER, send Add STA ind to SME
4800 */
4801static eHalStatus limSendSmeTdlsAddStaRsp(tpAniSirGlobal pMac,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004802 tANI_U8 sessionId, tSirMacAddr peerMac, tANI_U8 updateSta,
4803 tDphHashNode *pStaDs, tANI_U8 status)
Kiran V1ccee932012-12-12 14:49:46 -08004804{
4805 tSirMsgQ mmhMsg = {0} ;
4806 tSirTdlsAddStaRsp *addStaRsp = NULL ;
4807 mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ;
4808 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &addStaRsp,
4809 (sizeof(tSirTdlsAddStaRsp))))
4810 {
4811 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
4812 return eSIR_FAILURE;
4813 }
4814
4815 addStaRsp->sessionId = sessionId;
4816 addStaRsp->statusCode = status;
4817 if( pStaDs )
4818 {
4819 addStaRsp->staId = pStaDs->staIndex ;
4820 addStaRsp->ucastSig = pStaDs->ucUcastSig ;
4821 addStaRsp->bcastSig = pStaDs->ucBcastSig ;
4822 }
4823 if( peerMac )
4824 {
4825 palCopyMemory( pMac->hHdd, addStaRsp->peerMac,
4826 (tANI_U8 *) peerMac, sizeof(tSirMacAddr));
4827 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004828 if (updateSta)
4829 addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
4830 else
4831 addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
4832
Kiran V1ccee932012-12-12 14:49:46 -08004833 addStaRsp->length = sizeof(tSirTdlsAddStaRsp) ;
4834 addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP ;
4835
4836 mmhMsg.bodyptr = addStaRsp;
4837 mmhMsg.bodyval = 0;
4838 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
4839
4840 return eSIR_SUCCESS ;
4841
4842}
4843/*
4844 * STA RSP received from HAL
4845 */
4846eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg,
4847 tpPESession psessionEntry)
4848{
4849 tAddStaParams *pAddStaParams = (tAddStaParams *) msg ;
4850 tANI_U8 status = eSIR_SUCCESS ;
4851 tDphHashNode *pStaDs = NULL ;
4852 tANI_U16 aid = 0 ;
4853
4854 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08004855 VOS_TRACE(VOS_MODULE_ID_PE, TDLS_DEBUG_LOG_LEVEL,
4856 ("limTdlsAddStaRsp: staIdx=%d, staMac=%02x:%02x:%02x:%02x:%02x:%02x"), pAddStaParams->staIdx, \
Kiran V1ccee932012-12-12 14:49:46 -08004857 pAddStaParams->staMac[0],
4858 pAddStaParams->staMac[1],
4859 pAddStaParams->staMac[2],
4860 pAddStaParams->staMac[3],
4861 pAddStaParams->staMac[4],
4862 pAddStaParams->staMac[5] ) ;
4863
4864 if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
4865 {
4866 VOS_ASSERT(0) ;
4867 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4868 ("Add sta failed \n")) ;
4869 status = eSIR_FAILURE;
4870 goto add_sta_error;
4871 }
4872
4873 pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid,
4874 &psessionEntry->dph.dphHashTable);
4875 if(NULL == pStaDs)
4876 {
4877 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4878 ("pStaDs is NULL \n")) ;
4879 status = eSIR_FAILURE;
4880 goto add_sta_error;
4881 }
4882
4883 pStaDs->bssId = pAddStaParams->bssIdx;
4884 pStaDs->staIndex = pAddStaParams->staIdx;
4885 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
4886 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
4887 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
4888 pStaDs->valid = 1 ;
4889#ifdef FEATURE_WLAN_TDLS_INTERNAL
4890 status = limSendSmeTdlsAddPeerInd(pMac, psessionEntry->smeSessionId,
4891 pStaDs, eSIR_SUCCESS ) ;
4892 if(eSIR_FAILURE == status)
4893 {
4894 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
4895 ("Peer IND msg to SME failed\n")) ;
4896 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
4897 return eSIR_FAILURE ;
4898 }
4899
4900 /*
4901 * Now, there is two things a) ADD STA RSP for ADD STA request sent
4902 * after recieving discovery request from Peer.
4903 * now we have to send discovery response, if there is any pending
4904 * discovery equest..
4905 */
4906 do
4907 {
4908 tSirTdlsPeerInfo *peerInfo = limTdlsFindDisPeer(pMac,
4909 pAddStaParams->staMac) ;
4910
4911
4912 if(peerInfo)
4913 {
4914 /*
4915 * send TDLS discovery response frame on direct link, state machine
4916 * is rolling.., once discovery response is get Acked, we will
4917 * send response to SME based on TxComplete callback results
4918 */
4919 limSendTdlsDisRspFrame(pMac, peerInfo->peerMac, peerInfo->dialog, psessionEntry) ;
4920 peerInfo->tdlsPeerState = TDLS_DIS_RSP_SENT_WAIT_STATE ;
4921 }
4922 } while(0) ;
Kiran V1ccee932012-12-12 14:49:46 -08004923#endif
4924add_sta_error:
4925 status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004926 pAddStaParams->staMac, pAddStaParams->updateSta, pStaDs, status) ;
Kiran V1ccee932012-12-12 14:49:46 -08004927 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
4928 return status ;
4929}
4930
4931/*
4932 * FUNCTION: Populate Link Identifier element IE
4933 *
4934 */
4935
4936
4937void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry,
4938 tDot11fIELinkIdentifier *linkIden,
4939 tSirMacAddr peerMac, tANI_U8 reqType)
4940{
4941 //tANI_U32 size = sizeof(tSirMacAddr) ;
4942 tANI_U8 *initStaAddr = NULL ;
4943 tANI_U8 *respStaAddr = NULL ;
4944
4945 (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
4946 (respStaAddr = linkIden->RespStaAddr))
4947 : ((respStaAddr = linkIden->InitStaAddr ),
4948 (initStaAddr = linkIden->RespStaAddr)) ;
4949 palCopyMemory( pMac->hHdd, (tANI_U8 *)linkIden->bssid,
4950 (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ;
4951
4952 palCopyMemory( pMac->hHdd, (tANI_U8 *)initStaAddr,
4953 psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ;
4954
4955 palCopyMemory( pMac->hHdd, (tANI_U8 *)respStaAddr, (tANI_U8 *) peerMac,
4956 sizeof( tSirMacAddr ));
4957
4958 linkIden->present = 1 ;
4959 return ;
4960
4961}
4962
4963void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac,
4964 tDot11fIEExtCap *extCapability)
4965{
4966 extCapability->TDLSPeerPSMSupp = PEER_PSM_SUPPORT ;
4967 extCapability->TDLSPeerUAPSDBufferSTA = PEER_BUFFER_STA_SUPPORT ;
4968 extCapability->TDLSChannelSwitching = CH_SWITCH_SUPPORT ;
4969 extCapability->TDLSSupport = TDLS_SUPPORT ;
4970 extCapability->TDLSProhibited = TDLS_PROHIBITED ;
4971 extCapability->TDLSChanSwitProhibited = TDLS_CH_SWITCH_PROHIBITED ;
4972 extCapability->present = 1 ;
4973 return ;
4974}
4975
4976#ifdef FEATURE_WLAN_TDLS_INTERNAL
4977/*
4978 * Public Action frame common processing
4979 * This Function will be moved/merged to appropriate place
4980 * once other public action frames (particularly 802.11k)
4981 * is in place
4982 */
4983void limProcessTdlsPublicActionFrame(tpAniSirGlobal pMac, tANI_U32 *pBd,
4984 tpPESession psessionEntry)
4985{
4986 tANI_U32 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd) ;
4987 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd) ;
4988 tANI_S8 rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pBd) ;
4989
4990 limProcessTdlsDisRspFrame(pMac, pBody, frameLen, rssi, psessionEntry) ;
4991 return ;
4992}
4993
4994eHalStatus limTdlsPrepareSetupReqFrame(tpAniSirGlobal pMac,
4995 tLimTdlsLinkSetupInfo *linkSetupInfo,
4996 tANI_U8 dialog, tSirMacAddr peerMac,
4997 tpPESession psessionEntry)
4998{
4999 tLimTdlsLinkSetupPeer *setupPeer = NULL ;
5000
5001 /*
5002 * we allocate the TDLS setup Peer Memory here, we will free'd this
5003 * memory after teardown, if the link is successfully setup or
5004 * free this memory if any timeout is happen in link setup procedure
5005 */
5006 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
5007 (void **) &setupPeer, sizeof( tLimTdlsLinkSetupPeer )))
5008 {
5009 limLog( pMac, LOGP,
5010 FL( "Unable to allocate memory during ADD_STA\n" ));
5011 VOS_ASSERT(0) ;
5012 return eSIR_MEM_ALLOC_FAILED;
5013 }
5014 setupPeer->dialog = dialog ;
5015 setupPeer->tdls_prev_link_state = setupPeer->tdls_link_state ;
5016 setupPeer->tdls_link_state = TDLS_LINK_SETUP_START_STATE ;
5017
5018 /* TDLS_sessionize: remember sessionId for future */
5019 setupPeer->tdls_sessionId = psessionEntry->peSessionId;
5020 setupPeer->tdls_bIsResponder = 1;
5021
5022 /*
5023 * we only populate peer MAC, so it can assit us to find the
5024 * TDLS peer after response/or after response timeout
5025 */
5026 palCopyMemory(pMac->hHdd, setupPeer->peerMac, peerMac,
5027 sizeof(tSirMacAddr)) ;
5028 /* format TDLS discovery request frame and transmit it */
5029 limSendTdlsLinkSetupReqFrame(pMac, peerMac, dialog, psessionEntry, NULL, 0) ;
5030
5031 limStartTdlsTimer(pMac, psessionEntry->peSessionId,
5032 &setupPeer->gLimTdlsLinkSetupRspTimeoutTimer,
5033 (tANI_U32)setupPeer->peerMac,
5034 WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT,
5035 SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT) ;
5036 /* update setup peer list */
5037 setupPeer->next = linkSetupInfo->tdlsLinkSetupList ;
5038 linkSetupInfo->tdlsLinkSetupList = setupPeer ;
5039
5040 /* in case of success, eWNI_SME_TDLS_LINK_START_RSP is sent back to
5041 * SME later when TDLS setup cnf TX complete is successful. --> see
5042 * limTdlsSetupCnfTxComplete()
5043 */
5044 return eSIR_SUCCESS ;
5045}
5046#endif
5047
5048/*
5049 * Process Send Mgmt Request from SME and transmit to AP.
5050 */
5051tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac,
5052 tANI_U32 *pMsgBuf)
5053{
5054 /* get all discovery request parameters */
5055 tSirTdlsSendMgmtReq *pSendMgmtReq = (tSirTdlsSendMgmtReq*) pMsgBuf ;
5056 tpPESession psessionEntry;
5057 tANI_U8 sessionId;
5058 tSirResultCodes resultCode = eSIR_SME_INVALID_PARAMETERS;
5059
5060 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
5061 ("Send Mgmt Recieved\n")) ;
5062
5063 if((psessionEntry = peFindSessionByBssid(pMac, pSendMgmtReq->bssid, &sessionId))
5064 == NULL)
5065 {
5066 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5067 "PE Session does not exist for given sme sessionId %d\n",
5068 pSendMgmtReq->sessionId);
5069 goto lim_tdls_send_mgmt_error;
5070 }
5071
5072 /* check if we are in proper state to work as TDLS client */
5073 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
5074 {
5075 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5076 "send mgmt received in wrong system Role %d\n",
5077 psessionEntry->limSystemRole);
5078 goto lim_tdls_send_mgmt_error;
5079 }
5080
5081 /*
5082 * if we are still good, go ahead and check if we are in proper state to
5083 * do TDLS discovery req/rsp/....frames.
5084 */
5085 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
5086 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
5087 {
5088
5089 limLog(pMac, LOGE, "send mgmt received in invalid LIMsme \
5090 state (%d)\n", psessionEntry->limSmeState);
5091 goto lim_tdls_send_mgmt_error;
5092 }
5093
5094 switch( pSendMgmtReq->reqType )
5095 {
5096 case SIR_MAC_TDLS_DIS_REQ:
5097 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
5098 "Transmit Discovery Request Frame\n") ;
5099 /* format TDLS discovery request frame and transmit it */
5100 limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog,
5101 psessionEntry) ;
5102 resultCode = eSIR_SME_SUCCESS;
5103 break;
5104 case SIR_MAC_TDLS_DIS_RSP:
5105 {
5106 //Send a response mgmt action frame
5107 limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac,
5108 pSendMgmtReq->dialog, psessionEntry) ;
5109 resultCode = eSIR_SME_SUCCESS;
5110 }
5111 break;
5112 case SIR_MAC_TDLS_SETUP_REQ:
5113 {
5114 limSendTdlsLinkSetupReqFrame(pMac,
5115 pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry,
5116 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
5117 resultCode = eSIR_SME_SUCCESS;
5118 }
5119 break;
5120 case SIR_MAC_TDLS_SETUP_RSP:
5121 {
5122 limSendTdlsSetupRspFrame(pMac,
5123 pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode,
5124 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
5125 resultCode = eSIR_SME_SUCCESS;
5126 }
5127 break;
5128 case SIR_MAC_TDLS_SETUP_CNF:
5129 {
5130 limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog,
5131 psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
5132 resultCode = eSIR_SME_SUCCESS;
5133 }
5134 break;
5135 case SIR_MAC_TDLS_TEARDOWN:
5136 {
5137 limSendTdlsTeardownFrame(pMac,
Hoonki Leea34dd892013-02-05 22:56:02 -08005138 pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, pSendMgmtReq->responder, psessionEntry,
Kiran V1ccee932012-12-12 14:49:46 -08005139 &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq)));
5140 resultCode = eSIR_SME_SUCCESS;
5141 }
5142 break;
5143 case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
5144 {
5145 }
5146 break;
5147 case SIR_MAC_TDLS_CH_SWITCH_REQ:
5148 {
5149 }
5150 break;
5151 case SIR_MAC_TDLS_CH_SWITCH_RSP:
5152 {
5153 }
5154 break;
5155 case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
5156 {
5157 }
5158 break;
5159 default:
5160 break;
5161 }
5162
5163lim_tdls_send_mgmt_error:
5164
5165 limSendSmeRsp( pMac, eWNI_SME_TDLS_SEND_MGMT_RSP,
5166 resultCode, pSendMgmtReq->sessionId, pSendMgmtReq->transactionId);
5167
5168 return eSIR_SUCCESS;
5169}
5170
5171/*
5172 * Once link is teardown, send Del Peer Ind to SME
5173 */
5174static eHalStatus limSendSmeTdlsDelStaRsp(tpAniSirGlobal pMac,
5175 tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs,
5176 tANI_U8 status)
5177{
5178 tSirMsgQ mmhMsg = {0} ;
5179 tSirTdlsDelStaRsp *pDelSta = NULL ;
5180 mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP ;
5181 if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,(void * *) &pDelSta,
5182 (sizeof(tSirTdlsDelStaRsp))))
5183 {
5184 PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));)
5185 return eSIR_FAILURE;
5186 }
5187
5188 pDelSta->sessionId = sessionId;
5189 pDelSta->statusCode = status ;
5190 if( pStaDs )
5191 {
5192 pDelSta->staId = pStaDs->staIndex ;
5193 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005194 else
5195 pDelSta->staId = HAL_STA_INVALID_IDX;
5196
Kiran V1ccee932012-12-12 14:49:46 -08005197 if( peerMac )
5198 {
5199 palCopyMemory(pMac->hHdd, pDelSta->peerMac, peerMac, sizeof(tSirMacAddr));
5200 }
5201
5202 pDelSta->length = sizeof(tSirTdlsDelStaRsp) ;
5203 pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP ;
5204
5205 mmhMsg.bodyptr = pDelSta;
5206
5207 mmhMsg.bodyval = 0;
5208 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
5209 return eSIR_SUCCESS ;
5210
5211}
5212
5213/*
5214 * Process Send Mgmt Request from SME and transmit to AP.
5215 */
5216tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac,
5217 tANI_U32 *pMsgBuf)
5218{
5219 /* get all discovery request parameters */
5220 tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq*) pMsgBuf ;
5221 tpPESession psessionEntry;
5222 tANI_U8 sessionId;
Kiran V1ccee932012-12-12 14:49:46 -08005223
5224 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
5225 ("Send Mgmt Recieved\n")) ;
5226
5227 if((psessionEntry = peFindSessionByBssid(pMac, pAddStaReq->bssid, &sessionId))
5228 == NULL)
5229 {
5230 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5231 "PE Session does not exist for given sme sessionId %d\n",
5232 pAddStaReq->sessionId);
5233 goto lim_tdls_add_sta_error;
5234 }
5235
5236 /* check if we are in proper state to work as TDLS client */
5237 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
5238 {
5239 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5240 "send mgmt received in wrong system Role %d\n",
5241 psessionEntry->limSystemRole);
5242 goto lim_tdls_add_sta_error;
5243 }
5244
5245 /*
5246 * if we are still good, go ahead and check if we are in proper state to
5247 * do TDLS discovery req/rsp/....frames.
5248 */
5249 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
5250 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
5251 {
5252
5253 limLog(pMac, LOGE, "send mgmt received in invalid LIMsme \
5254 state (%d)\n", psessionEntry->limSmeState);
5255 goto lim_tdls_add_sta_error;
5256 }
5257
5258 pMac->lim.gLimAddStaTdls = true ;
5259
5260 /* To start with, send add STA request to HAL */
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005261 if (eSIR_FAILURE == limTdlsSetupAddSta(pMac, pAddStaReq, psessionEntry))
Kiran V1ccee932012-12-12 14:49:46 -08005262 {
Lee Hoonkif987a0b2013-01-29 02:07:07 -08005263 limLog(pMac, LOGE, "%s: Add TDLS Station request failed \n", __func__);
Kiran V1ccee932012-12-12 14:49:46 -08005264 goto lim_tdls_add_sta_error;
5265 }
5266 return eSIR_SUCCESS;
5267lim_tdls_add_sta_error:
5268 limSendSmeTdlsAddStaRsp(pMac,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005269 pAddStaReq->sessionId, pAddStaReq->peerMac,
5270 (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE), NULL, eSIR_FAILURE );
Kiran V1ccee932012-12-12 14:49:46 -08005271
5272 return eSIR_SUCCESS;
5273}
5274/*
5275 * Process Del Sta Request from SME .
5276 */
5277tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac,
5278 tANI_U32 *pMsgBuf)
5279{
5280 /* get all discovery request parameters */
5281 tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq*) pMsgBuf ;
5282 tpPESession psessionEntry;
5283 tANI_U8 sessionId;
5284 tpDphHashNode pStaDs = NULL ;
5285
5286 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
5287 ("Send Mgmt Recieved\n")) ;
5288
5289 if((psessionEntry = peFindSessionByBssid(pMac, pDelStaReq->bssid, &sessionId))
5290 == NULL)
5291 {
5292 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5293 "PE Session does not exist for given sme sessionId %d\n",
5294 pDelStaReq->sessionId);
Hoonki Leef63df0d2013-01-16 19:29:14 -08005295 limSendSmeTdlsDelStaRsp(pMac, pDelStaReq->sessionId, pDelStaReq->peerMac,
Kiran V1ccee932012-12-12 14:49:46 -08005296 NULL, eSIR_FAILURE) ;
5297 return eSIR_FAILURE;
5298 }
5299
5300 /* check if we are in proper state to work as TDLS client */
5301 if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
5302 {
5303 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
5304 "Del sta received in wrong system Role %d\n",
5305 psessionEntry->limSystemRole);
5306 goto lim_tdls_del_sta_error;
5307 }
5308
5309 /*
5310 * if we are still good, go ahead and check if we are in proper state to
5311 * do TDLS discovery req/rsp/....frames.
5312 */
5313 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
5314 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
5315 {
5316
5317 limLog(pMac, LOGE, "Del Sta received in invalid LIMsme \
5318 state (%d)\n", psessionEntry->limSmeState);
5319 goto lim_tdls_del_sta_error;
5320 }
5321
5322 pStaDs = limTdlsDelSta(pMac, pDelStaReq->peerMac, psessionEntry) ;
5323
5324 /* now send indication to SME-->HDD->TL to remove STA from TL */
5325
5326 if(pStaDs)
5327 {
5328 limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
5329 pStaDs, eSIR_SUCCESS) ;
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005330 limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ;
Hoonki Leef63df0d2013-01-16 19:29:14 -08005331
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005332 /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
5333 CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, pStaDs->assocId);
Hoonki Leef63df0d2013-01-16 19:29:14 -08005334 limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ;
5335
Kiran V1ccee932012-12-12 14:49:46 -08005336 return eSIR_SUCCESS;
5337
5338 }
5339
5340lim_tdls_del_sta_error:
5341 limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac,
5342 NULL, eSIR_FAILURE) ;
5343
5344 return eSIR_SUCCESS;
5345}
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005346
5347/* Delete all the TDLS peer connected before leaving the BSS */
5348tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry)
5349{
5350 tpDphHashNode pStaDs = NULL ;
5351 int i, aid;
5352
5353 if (NULL == psessionEntry)
5354 {
5355 PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));)
5356 return eSIR_FAILURE;
5357 }
5358
5359 /* Check all the set bit in peerAIDBitmap and delete the peer (with that aid) entry
5360 from the hash table and add the aid in free pool */
5361 for (i = 0; i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); i++)
5362 {
5363 for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++)
5364 {
5365 if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid))
5366 {
5367 pStaDs = dphGetHashEntry(pMac, (aid + i*(sizeof(tANI_U32) << 3)), &psessionEntry->dph.dphHashTable);
5368
5369 if (NULL != pStaDs)
5370 {
5371 PELOGE(limLog(pMac, LOGE, FL("Deleting %02x:%02x:%02x:%02x:%02x:%02x"),
5372 pStaDs->staAddr[0], pStaDs->staAddr[1], pStaDs->staAddr[2],
5373 pStaDs->staAddr[3], pStaDs->staAddr[4], pStaDs->staAddr[5]);)
5374
5375 limSendDeauthMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
5376 pStaDs->staAddr, psessionEntry, FALSE);
5377 dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable);
5378 }
5379 limReleasePeerIdx(pMac, (aid + i*(sizeof(tANI_U32) << 3)), psessionEntry) ;
5380 CLEAR_BIT(psessionEntry->peerAIDBitmap[i], aid);
5381 }
5382 }
5383 }
5384 limSendSmeTDLSDeleteAllPeerInd(pMac, psessionEntry);
5385
5386 return eSIR_SUCCESS;
5387}
5388
Kiran V1ccee932012-12-12 14:49:46 -08005389#endif