blob: 8b8a1eb672e3848e86040e6e54b4ae37bb7eb07b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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 */
21
22#ifdef WLAN_FEATURE_VOWIFI_11R
23/**=========================================================================
24
25 \brief implementation for PE 11r VoWiFi FT Protocol
26
27 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
28
29 Qualcomm Confidential and Proprietary.
30
31 ========================================================================*/
32
33/* $Header$ */
34
35
36/*--------------------------------------------------------------------------
37 Include Files
38 ------------------------------------------------------------------------*/
39#include <limSendMessages.h>
40#include <limTypes.h>
41#include <limFT.h>
42#include <limFTDefs.h>
43#include <limUtils.h>
44#include <limPropExtsUtils.h>
45#include <limAssocUtils.h>
46#include <limSession.h>
47#include <limAdmitControl.h>
48#include "wmmApsd.h"
49
50#define LIM_FT_RIC_BA_SSN 1
51#define LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 248
52#define LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA 1
53
54/*--------------------------------------------------------------------------
55 Initialize the FT variables.
56 ------------------------------------------------------------------------*/
57void limFTOpen(tpAniSirGlobal pMac)
58{
59 pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
60 pMac->ft.ftPEContext.psavedsessionEntry = NULL;
61}
62
63/*--------------------------------------------------------------------------
64 Cleanup FT variables.
65 ------------------------------------------------------------------------*/
66void limFTCleanup(tpAniSirGlobal pMac)
67{
68 if (pMac->ft.ftPEContext.pFTPreAuthReq)
69 {
70#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
71 PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p\n",
72 __FUNCTION__, pMac->ft.ftPEContext.pFTPreAuthReq);)
73#endif
74 vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq);
75 pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
76 }
77
78 // This is the old session, should be deleted else where.
79 // We should not be cleaning it here, just set it to NULL.
80 if (pMac->ft.ftPEContext.psavedsessionEntry)
81 {
82#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
83 PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
84 __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
85#endif
86 pMac->ft.ftPEContext.psavedsessionEntry = NULL;
87 }
88
89 // This is the extra session we added as part of Auth resp
90 // clean it up.
91 if (pMac->ft.ftPEContext.pftSessionEntry)
92 {
93 if ((((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->valid) &&
94 (((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->limSmeState == eLIM_SME_WT_REASSOC_STATE))
95 {
96 PELOGE(limLog( pMac, LOGE, "%s: Deleting Preauth Session %d\n", __func__, ((tpPESession)pMac->ft.ftPEContext.pftSessionEntry)->peSessionId);)
97 peDeleteSession(pMac, pMac->ft.ftPEContext.pftSessionEntry);
98 }
99 pMac->ft.ftPEContext.pftSessionEntry = NULL;
100#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
101 PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
102 __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
103#endif
104 }
105
106 if (pMac->ft.ftPEContext.pAddBssReq)
107 {
108 vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
109 pMac->ft.ftPEContext.pAddBssReq = NULL;
110 }
111
112 if (pMac->ft.ftPEContext.pAddStaReq)
113 {
114 vos_mem_free(pMac->ft.ftPEContext.pAddStaReq);
115 pMac->ft.ftPEContext.pAddStaReq = NULL;
116 }
117
118 pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_SUCCESS;
119
120}
121
122/*--------------------------------------------------------------------------
123 Init FT variables.
124 ------------------------------------------------------------------------*/
125void limFTInit(tpAniSirGlobal pMac)
126{
127 if (pMac->ft.ftPEContext.pFTPreAuthReq)
128 {
129#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
130 PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p\n",
131 __FUNCTION__, pMac->ft.ftPEContext.pFTPreAuthReq);)
132#endif
133 vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq);
134 pMac->ft.ftPEContext.pFTPreAuthReq = NULL;
135 }
136
137 // This is the old session, should be deleted else where.
138 // We should not be cleaning it here, just set it to NULL.
139 if (pMac->ft.ftPEContext.psavedsessionEntry)
140 {
141#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
142 PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL\n",
143 __FUNCTION__, pMac->ft.ftPEContext.psavedsessionEntry);)
144#endif
145 pMac->ft.ftPEContext.psavedsessionEntry = NULL;
146 }
147
148 // This is the extra session we added as part of Auth resp
149 // clean it up.
150 if (pMac->ft.ftPEContext.pftSessionEntry)
151 {
152 /* Cannot delete sessions across associations */
153#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
154 PELOGE(limLog( pMac, LOGE, "%s: Deleting session = %p \n",
155 __FUNCTION__, pMac->ft.ftPEContext.pftSessionEntry);)
156#endif
157 pMac->ft.ftPEContext.pftSessionEntry = NULL;
158 }
159
160 if (pMac->ft.ftPEContext.pAddBssReq)
161 {
162#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
163 PELOGE(limLog( pMac, LOGE, "%s: Freeing AddBssReq = %p \n",
164 __FUNCTION__, pMac->ft.ftPEContext.pAddBssReq);)
165#endif
166 vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
167 pMac->ft.ftPEContext.pAddBssReq = NULL;
168 }
169
170
171 if (pMac->ft.ftPEContext.pAddStaReq)
172 {
173#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
174 PELOGE(limLog( pMac, LOGE, "%s: Freeing AddStaReq = %p \n",
175 __FUNCTION__, pMac->ft.ftPEContext.pAddStaReq);)
176#endif
177 vos_mem_free(pMac->ft.ftPEContext.pAddStaReq);
178 pMac->ft.ftPEContext.pAddStaReq = NULL;
179 }
180
181 pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_SUCCESS;
182
183}
184
185/*------------------------------------------------------------------
186 *
187 * This is the handler after suspending the link.
188 * We suspend the link and then now proceed to switch channel.
189 *
190 *------------------------------------------------------------------*/
191void FTPreAuthSuspendLinkHandler(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
192{
193 tpPESession psessionEntry;
194
195 // The link is suspended of not ?
196 if (status != eHAL_STATUS_SUCCESS)
197 {
198 PELOGE(limLog( pMac, LOGE, "%s: Returning \n", __FUNCTION__);)
199 // Post the FT Pre Auth Response to SME
200 limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, (tpPESession)data);
201
202 return;
203 }
204
205 psessionEntry = (tpPESession)data;
206 // Suspended, now move to a different channel.
207 // Perform some sanity check before proceeding.
208 if ((pMac->ft.ftPEContext.pFTPreAuthReq) && psessionEntry)
209 {
210 limChangeChannelWithCallback(pMac,
211 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum,
212 limPerformFTPreAuth, NULL, psessionEntry);
213 return;
214 }
215
216 // Else return error.
217 limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
218}
219
220
221/*--------------------------------------------------------------------------
222 In this function, we process the FT Pre Auth Req.
223 We receive Pre-Auth
224 Suspend link
225 Register a call back
226 In the call back, we will need to accept frames from the new bssid
227 Send out the auth req to new AP.
228 Start timer and when the timer is done or if we receive the Auth response
229 We change channel
230 Resume link
231 ------------------------------------------------------------------------*/
232int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
233{
234 int bufConsumed = FALSE;
235 tpPESession psessionEntry;
236 tANI_U8 sessionId;
237
238 // Now we are starting fresh make sure all's cleanup.
239 limFTInit(pMac);
240 pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE; // Can set it only after sending auth
241
242 // We need information from the Pre-Auth Req. Lets save that
243 pMac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)pMsg->bodyptr;
244
245#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
246 PELOGE(limLog( pMac, LOGE, "%s: PE Auth ft_ies_length=%02x%02x%02x\n", __FUNCTION__,
247 pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[0],
248 pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[1],
249 pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[2]);)
250#endif
251
252 // Get the current session entry
253 psessionEntry = peFindSessionByBssid(pMac,
254 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &sessionId);
255 if (psessionEntry == NULL)
256 {
257 PELOGE(limLog( pMac, LOGE, "%s: Unable to find session for the following bssid\n",
258 __FUNCTION__);)
259 limPrintMacAddr( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE );
260 // Post the FT Pre Auth Response to SME
261 limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, NULL);
262 return TRUE;
263 }
264
265 // Dont need to suspend if APs are in same channel
266 if (psessionEntry->currentOperChannel != pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum)
267 {
268 // Need to suspend link only if the channels are different
269 limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, FTPreAuthSuspendLinkHandler,
270 (tANI_U32 *)psessionEntry);
271 }
272 else
273 {
274 PELOGE(limLog( pMac, LOGE, "%s: Performing pre-auth on same channel\n",
275 __FUNCTION__);)
276 // We are in the same channel. Perform pre-auth
277 limPerformFTPreAuth(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry);
278 }
279
280 return bufConsumed;
281}
282
283/*------------------------------------------------------------------
284 * Send the Auth1
285 * Receive back Auth2
286 *------------------------------------------------------------------*/
287void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
288 tpPESession psessionEntry)
289{
290 tSirMacAuthFrameBody authFrame;
291
292 if (psessionEntry->is11Rconnection)
293 {
294 // Only 11r assoc has FT IEs.
295 if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies == NULL)
296 {
297 PELOGE(limLog( pMac, LOGE, "%s: FTIEs for Auth Req Seq 1 is absent\n");)
298 return;
299 }
300 }
301 if (status != eHAL_STATUS_SUCCESS)
302 {
303 PELOGE(limLog( pMac, LOGE, "%s: Change channel not successful for FT pre-auth\n");)
304 return;
305 }
306 pMac->ft.ftPEContext.psavedsessionEntry = psessionEntry;
307
308#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
309 PELOGE(limLog( pMac, LOGE, "Entered wait auth2 state for FT\n");)
310#endif
311
312
313 if (psessionEntry->is11Rconnection)
314 {
315 // Now we are on the right channel and need to send out Auth1 and
316 // receive Auth2.
317 authFrame.authAlgoNumber = eSIR_FT_AUTH; // Set the auth type to FT
318 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700319#if defined FEATURE_WLAN_CCX || defined FEATURE_WLAN_LFR
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 else
321 {
322 // Will need to make isCCXconnection a enum may be for further
323 // improvements to this to match this algorithm number
324 authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; // For now if its CCX and 11r FT.
325 }
326#endif
327 authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
328 authFrame.authStatusCode = 0;
329
330 // Start timer here to come back to operating channel.
331 pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = psessionEntry->peSessionId;
332 if(TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer))
333 {
334#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
335 PELOGE(limLog( pMac, LOGE, "%s: FT Auth Rsp Timer Start Failed\n", __FUNCTION__);)
336#endif
337 }
338
339#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
340 PELOGE(limLog( pMac, LOGE, "%s: FT Auth Rsp Timer Started\n", __FUNCTION__);)
341#endif
342
343 limSendAuthMgmtFrame(pMac, &authFrame,
344 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId,
345 LIM_NO_WEP_IN_FC, psessionEntry);
346
347 return;
348}
349
350
351/*------------------------------------------------------------------
352 *
353 * Create the new Add Bss Req to the new AP.
354 * This will be used when we are ready to FT to the new AP.
355 * The newly created ft Session entry is passed to this function
356 *
357 *------------------------------------------------------------------*/
358tSirRetStatus limFTPrepareAddBssReq( tpAniSirGlobal pMac,
359 tANI_U8 updateEntry, tpPESession pftSessionEntry,
360 tpSirBssDescription bssDescription )
361{
362 tpAddBssParams pAddBssParams = NULL;
363 tANI_U8 i;
364 tANI_U8 chanWidthSupp = 0;
365 tSchBeaconStruct beaconStruct;
366
367
368 // Package SIR_HAL_ADD_BSS_REQ message parameters
369 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
370 (void **) &pAddBssParams, sizeof( tAddBssParams )))
371 {
372 limLog( pMac, LOGP,
373 FL( "Unable to PAL allocate memory for creating ADD_BSS\n" ));
374 return (eSIR_MEM_ALLOC_FAILED);
375 }
376
377 palZeroMemory( pMac->hHdd, (tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ));
378
379
380 limExtractApCapabilities( pMac,
381 (tANI_U8 *) bssDescription->ieFields,
382 limGetIElenFromBssDescription( bssDescription ), &beaconStruct );
383
384 if (pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
385 limDecideStaProtectionOnAssoc(pMac, &beaconStruct, pftSessionEntry);
386
387 palCopyMemory( pMac->hHdd, pAddBssParams->bssId, bssDescription->bssId,
388 sizeof( tSirMacAddr ));
389
390 // Fill in tAddBssParams selfMacAddr
391 palCopyMemory( pMac->hHdd, pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr,
392 sizeof( tSirMacAddr ));
393
394 pAddBssParams->bssType = pftSessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE;
395 pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
396
397 pAddBssParams->beaconInterval = bssDescription->beaconInterval;
398
399 pAddBssParams->dtimPeriod = beaconStruct.tim.dtimPeriod;
400 pAddBssParams->updateBss = updateEntry;
401
402
403 pAddBssParams->cfParamSet.cfpCount = beaconStruct.cfParamSet.cfpCount;
404 pAddBssParams->cfParamSet.cfpPeriod = beaconStruct.cfParamSet.cfpPeriod;
405 pAddBssParams->cfParamSet.cfpMaxDuration = beaconStruct.cfParamSet.cfpMaxDuration;
406 pAddBssParams->cfParamSet.cfpDurRemaining = beaconStruct.cfParamSet.cfpDurRemaining;
407
408
409 pAddBssParams->rateSet.numRates = beaconStruct.supportedRates.numRates;
410 palCopyMemory( pMac->hHdd, pAddBssParams->rateSet.rate,
411 beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
412
413 pAddBssParams->nwType = bssDescription->nwType;
414
415 pAddBssParams->shortSlotTimeSupported = (tANI_U8)beaconStruct.capabilityInfo.shortSlotTime;
416 pAddBssParams->llaCoexist = (tANI_U8) pftSessionEntry->beaconParams.llaCoexist;
417 pAddBssParams->llbCoexist = (tANI_U8) pftSessionEntry->beaconParams.llbCoexist;
418 pAddBssParams->llgCoexist = (tANI_U8) pftSessionEntry->beaconParams.llgCoexist;
419 pAddBssParams->ht20Coexist = (tANI_U8) pftSessionEntry->beaconParams.ht20Coexist;
420
421 // Use the advertised capabilities from the received beacon/PR
422 if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
423 {
424 pAddBssParams->htCapable = beaconStruct.HTCaps.present;
425
426 if ( beaconStruct.HTInfo.present )
427 {
428 pAddBssParams->htOperMode = (tSirMacHTOperatingMode)beaconStruct.HTInfo.opMode;
429 pAddBssParams->dualCTSProtection = ( tANI_U8 ) beaconStruct.HTInfo.dualCTSProtection;
430
431#ifdef WLAN_SOFTAP_FEATURE
432 chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, pftSessionEntry);
433#else
434 chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET);
435#endif
436 if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
437 (chanWidthSupp) )
438 {
439 pAddBssParams->txChannelWidthSet = ( tANI_U8 ) beaconStruct.HTInfo.recommendedTxWidthSet;
440 pAddBssParams->currentExtChannel = beaconStruct.HTInfo.secondaryChannelOffset;
441 }
442 else
443 {
444 pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
Jeff Johnsone7245742012-09-05 17:12:55 -0700445 pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700446 }
447 pAddBssParams->llnNonGFCoexist = (tANI_U8)beaconStruct.HTInfo.nonGFDevicesPresent;
448 pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)beaconStruct.HTInfo.lsigTXOPProtectionFullSupport;
449 pAddBssParams->fRIFSMode = beaconStruct.HTInfo.rifsMode;
450 }
451 }
452
453 pAddBssParams->currentOperChannel = bssDescription->channelId;
454
455#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
456 limLog( pMac, LOGE, FL( "SIR_HAL_ADD_BSS_REQ with channel = %d..." ),
457 pAddBssParams->currentOperChannel);
458#endif
459
460
461 // Populate the STA-related parameters here
462 // Note that the STA here refers to the AP
463 {
464 pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA
465
466 palCopyMemory( pMac->hHdd, pAddBssParams->staContext.bssId,
467 bssDescription->bssId,
468 sizeof( tSirMacAddr ));
469 pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval;
470
471 pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this?
472 pAddBssParams->staContext.uAPSD = 0;
473 pAddBssParams->staContext.maxSPLen = 0;
474 pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)beaconStruct.capabilityInfo.shortPreamble;
475 pAddBssParams->staContext.updateSta = updateEntry;
476 pAddBssParams->staContext.encryptType = pftSessionEntry->encryptType;
477
478 if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( beaconStruct.HTCaps.present ))
479 {
480 pAddBssParams->staContext.us32MaxAmpduDuration = 0;
481 pAddBssParams->staContext.htCapable = 1;
482 pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) beaconStruct.HTCaps.greenField;
483 pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) beaconStruct.HTCaps.lsigTXOPProtection;
484 if( (beaconStruct.HTCaps.supportedChannelWidthSet) &&
485 (chanWidthSupp) )
486 {
487 pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )beaconStruct.HTInfo.recommendedTxWidthSet;
488 }
489 else
490 {
491 pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
492 }
493 pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)beaconStruct.HTCaps.mimoPowerSave;
494 pAddBssParams->staContext.delBASupport = ( tANI_U8 ) beaconStruct.HTCaps.delayedBA;
495 pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) beaconStruct.HTCaps.maximalAMSDUsize;
496 pAddBssParams->staContext.maxAmpduDensity = beaconStruct.HTCaps.mpduDensity;
497 pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)beaconStruct.HTCaps.dsssCckMode40MHz;
498 pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI20MHz;
499 pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)beaconStruct.HTCaps.shortGI40MHz;
500 pAddBssParams->staContext.maxAmpduSize= beaconStruct.HTCaps.maxRxAMPDUFactor;
501
502 if( beaconStruct.HTInfo.present )
503 pAddBssParams->staContext.rifsMode = beaconStruct.HTInfo.rifsMode;
504 }
505
506 if ((pftSessionEntry->limWmeEnabled && beaconStruct.wmeEdcaPresent) ||
507 (pftSessionEntry->limQosEnabled && beaconStruct.edcaPresent))
508 pAddBssParams->staContext.wmmEnabled = 1;
509 else
510 pAddBssParams->staContext.wmmEnabled = 0;
511
512 //Update the rates
Jeff Johnsone7245742012-09-05 17:12:55 -0700513#ifdef WLAN_FEATURE_11AC
514 limPopulateOwnRateSet(pMac, &pAddBssParams->staContext.supportedRates,
515 beaconStruct.HTCaps.supportedMCSSet,
516 false,pftSessionEntry,&beaconStruct.VHTCaps);
517#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 limPopulateOwnRateSet(pMac, &pAddBssParams->staContext.supportedRates,
519 beaconStruct.HTCaps.supportedMCSSet, false,pftSessionEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -0700520#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,pftSessionEntry);
522
523 }
524
525
526 //Disable BA. It will be set as part of ADDBA negotiation.
527 for( i = 0; i < STACFG_MAX_TC; i++ )
528 {
529 pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
530 pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
531 pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
532 pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
533 }
534
535#if defined WLAN_FEATURE_VOWIFI
536 pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;
537#endif
538
539 pAddBssParams->status = eHAL_STATUS_SUCCESS;
540 pAddBssParams->respReqd = true;
541
542 pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId;
543 pAddBssParams->sessionId = pftSessionEntry->peSessionId;
544
545 // Set a new state for MLME
546
547 pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
548
549 pAddBssParams->halPersona=(tANI_U8)pftSessionEntry->pePersona; //pass on the session persona to hal
550
551 pMac->ft.ftPEContext.pAddBssReq = pAddBssParams;
552
553#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
554 limLog( pMac, LOGE, FL( "Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..." ));
555#endif
556
557 return 0;
558}
559
560/*------------------------------------------------------------------
561 *
562 * Setup the new session for the pre-auth AP.
563 * Return the newly created session entry.
564 *
565 *------------------------------------------------------------------*/
566tpPESession limFillFTSession(tpAniSirGlobal pMac,
567 tpSirBssDescription pbssDescription, tpPESession psessionEntry)
568{
569 tpPESession pftSessionEntry;
570 tANI_U8 currentBssUapsd;
571 tANI_U8 sessionId;
572 tPowerdBm localPowerConstraint;
573 tPowerdBm regMax;
574 tSchBeaconStruct beaconStruct;
575
576 if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId,
577 &sessionId, pMac->lim.maxStation)) == NULL)
578 {
579 limLog(pMac, LOGE, FL("Session Can not be created for pre-auth 11R AP\n"));
580 return NULL;
581 }
582
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700583#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700584 limPrintMacAddr(pMac, pbssDescription->bssId, LOGE);
585#endif
586
587 /* Store PE session Id in session Table */
588 pftSessionEntry->peSessionId = sessionId;
589
590 pftSessionEntry->dot11mode = psessionEntry->dot11mode;
Jeff Johnsone7245742012-09-05 17:12:55 -0700591 pftSessionEntry->htCapability = psessionEntry->htCapability;
Jeff Johnson295189b2012-06-20 16:38:30 -0700592
593 pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled;
594 pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled;
595 pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled;
596 pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable;
597
598 // Fields to be filled later
599 pftSessionEntry->pLimJoinReq = NULL;
600 pftSessionEntry->smeSessionId = 0;
601 pftSessionEntry->transactionId = 0;
602
603 limExtractApCapabilities( pMac,
604 (tANI_U8 *) pbssDescription->ieFields,
605 limGetIElenFromBssDescription( pbssDescription ),
606 &beaconStruct );
607
608 pftSessionEntry->rateSet.numRates = beaconStruct.supportedRates.numRates;
609 palCopyMemory( pMac->hHdd, pftSessionEntry->rateSet.rate,
610 beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
611
612 pftSessionEntry->extRateSet.numRates = beaconStruct.extendedRates.numRates;
613 palCopyMemory(pMac->hHdd, pftSessionEntry->extRateSet.rate,
614 beaconStruct.extendedRates.rate, pftSessionEntry->extRateSet.numRates);
615
616
617 pftSessionEntry->ssId.length = beaconStruct.ssId.length;
618 palCopyMemory( pMac->hHdd, pftSessionEntry->ssId.ssId, beaconStruct.ssId.ssId,
619 pftSessionEntry->ssId.length);
620
621
622 // Self Mac
623 sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr);
624 sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700625#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700626 limPrintMacAddr(pMac, pftSessionEntry->limReAssocbssId, LOGE);
627#endif
628
629 /* Store beaconInterval */
630 pftSessionEntry->beaconParams.beaconInterval = pbssDescription->beaconInterval;
631 pftSessionEntry->bssType = psessionEntry->bssType;
632
633 pftSessionEntry->statypeForBss = STA_ENTRY_PEER;
634 pftSessionEntry->nwType = pbssDescription->nwType;
635
636 /* Copy The channel Id to the session Table */
637 pftSessionEntry->limReassocChannelId = pbssDescription->channelId;
638 pftSessionEntry->currentOperChannel = pbssDescription->channelId;
639
640
641 if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
642 {
643 pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
644 }
645 else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE)
646 {
647 pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
648 }
649 else
650 {
651 /* Throw an error and return and make sure to delete the session.*/
652 limLog(pMac, LOGE, FL("Invalid bss type\n"));
653 }
654
655 pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo;
656 pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700657
658 regMax = cfgGetRegulatoryMaxTransmitPower( pMac, pftSessionEntry->currentOperChannel );
659 localPowerConstraint = regMax;
660 limExtractApCapability( pMac, (tANI_U8 *) pbssDescription->ieFields,
661 limGetIElenFromBssDescription(pbssDescription),
662 &pftSessionEntry->limCurrentBssQosCaps,
663 &pftSessionEntry->limCurrentBssPropCap,
Madan Mohan Koyyalamudic6226de2012-09-18 16:33:31 -0700664 &currentBssUapsd , &localPowerConstraint, psessionEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -0700665
666 pftSessionEntry->limReassocBssQosCaps =
667 pftSessionEntry->limCurrentBssQosCaps;
668 pftSessionEntry->limReassocBssPropCap =
669 pftSessionEntry->limCurrentBssPropCap;
670
671
672 pftSessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) );
673
674#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
675 limLog( pMac, LOGE, "%s: Regulatory max = %d, local power constraint = %d, max tx = %d",
676 __FUNCTION__, regMax, localPowerConstraint, pftSessionEntry->maxTxPower );
677#endif
678
679 pftSessionEntry->limRFBand = limGetRFBand(pftSessionEntry->currentOperChannel);
680
681 pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
682 pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
683
684 pftSessionEntry->encryptType = psessionEntry->encryptType;
685
686#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
687 PELOGE(limLog( pMac, LOGE, "%s: Created session with the id = %d\n",
688 __FUNCTION__, pftSessionEntry->peSessionId);)
689#endif
690
691 return pftSessionEntry;
692}
693
694/*------------------------------------------------------------------
695 *
696 * Setup the session and the add bss req for the pre-auth AP.
697 *
698 *------------------------------------------------------------------*/
699void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry)
700{
701 tpPESession pftSessionEntry;
702
703 // Prepare the session right now with as much as possible.
704 pftSessionEntry = limFillFTSession(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription, psessionEntry);
705
706 if (pftSessionEntry)
707 {
708 pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection;
709#ifdef FEATURE_WLAN_CCX
710 pftSessionEntry->isCCXconnection = psessionEntry->isCCXconnection;
711#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700712#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 pftSessionEntry->isFastTransitionEnabled = psessionEntry->isFastTransitionEnabled;
714#endif
Jeff Johnson43971f52012-07-17 12:26:56 -0700715
716#ifdef FEATURE_WLAN_LFR
717 pftSessionEntry->isFastRoamIniFeatureEnabled = psessionEntry->isFastRoamIniFeatureEnabled;
718#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry,
720 pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription );
721 pMac->ft.ftPEContext.pftSessionEntry = pftSessionEntry;
722 }
723}
724
725/*------------------------------------------------------------------
726 * Resume Link Call Back
727 *------------------------------------------------------------------*/
728void limFTProcessPreAuthResult(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
729{
730 tpPESession psessionEntry;
731
732 psessionEntry = (tpPESession)data;
733
734 if (pMac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS)
735 {
736 limFTSetupAuthSession(pMac, psessionEntry);
737 }
738
739 // Post the FT Pre Auth Response to SME
740 limPostFTPreAuthRsp(pMac, pMac->ft.ftPEContext.ftPreAuthStatus,
741 pMac->ft.ftPEContext.saved_auth_rsp,
742 pMac->ft.ftPEContext.saved_auth_rsp_length, psessionEntry);
743
744}
745
746/*------------------------------------------------------------------
747 * Resume Link Call Back
748 *------------------------------------------------------------------*/
749void limPerformPostFTPreAuthAndChannelChange(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
750 tpPESession psessionEntry)
751{
752 //Set the resume channel to Any valid channel (invalid).
753 //This will instruct HAL to set it to any previous valid channel.
754 peSetResumeChannel(pMac, 0, 0);
755 limResumeLink(pMac, limFTProcessPreAuthResult, (tANI_U32 *)psessionEntry);
756}
757
758tSirRetStatus limCreateRICBlockAckIE(tpAniSirGlobal pMac, tANI_U8 tid, tCfgTrafficClass *pTrafficClass,
759 tANI_U8 *ric_ies, tANI_U32 *ieLength)
760{
761 tDot11fIERICDataDesc ricIe;
762 tDot11fFfBAStartingSequenceControl baSsnControl;
763 tDot11fFfAddBAParameterSet baParamSet;
764 tDot11fFfBATimeout baTimeout;
765
766 vos_mem_zero(&ricIe, sizeof(tDot11fIERICDataDesc));
767 vos_mem_zero(&baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
768 vos_mem_zero(&baParamSet, sizeof(tDot11fFfAddBAParameterSet));
769 vos_mem_zero(&baTimeout, sizeof(tDot11fFfBATimeout));
770
771 ricIe.present = 1;
772 ricIe.RICData.present = 1;
773 ricIe.RICData.resourceDescCount = 1;
774 ricIe.RICData.Identifier = LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 + tid;
775 ricIe.RICDescriptor.present = 1;
776 ricIe.RICDescriptor.resourceType = LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA;
777 baParamSet.tid = tid;
778 baParamSet.policy = pTrafficClass->fTxBApolicy; // Immediate Block Ack
779 baParamSet.bufferSize = pTrafficClass->txBufSize;
780 vos_mem_copy((v_VOID_t *)&baTimeout, (v_VOID_t *)&pTrafficClass->tuTxBAWaitTimeout, sizeof(baTimeout));
781 baSsnControl.fragNumber = 0;
782 baSsnControl.ssn = LIM_FT_RIC_BA_SSN;
783
784 dot11fPackFfAddBAParameterSet(pMac, &baParamSet, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
785 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baParamSet, sizeof(tDot11fFfAddBAParameterSet));
786 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfAddBAParameterSet);
787
788 dot11fPackFfBATimeout(pMac, &baTimeout, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
789 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baTimeout, sizeof(tDot11fFfBATimeout));
790 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBATimeout);
791
792 dot11fPackFfBAStartingSequenceControl(pMac, &baSsnControl, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
793 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
794 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBAStartingSequenceControl);
795
796 return (tSirRetStatus) dot11fPackIeRICDataDesc(pMac, &ricIe, ric_ies, sizeof(tDot11fIERICDataDesc), ieLength);
797}
798
799tSirRetStatus limFTFillRICBlockAckInfo(tpAniSirGlobal pMac, tANI_U8 *ric_ies, tANI_U32 *ric_ies_length)
800{
801 tANI_U8 tid = 0;
802 tpDphHashNode pSta;
803 tANI_U16 numBA = 0, aid = 0;
804 tpPESession psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry;
805 tANI_U32 offset = 0, ieLength = 0;
806 tSirRetStatus status = eSIR_SUCCESS;
807
808 // First, extract the DPH entry
809 pSta = dphLookupHashEntry( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &aid, &psessionEntry->dph.dphHashTable);
810 if( NULL == pSta )
811 {
812 PELOGE(limLog( pMac, LOGE,
813 FL( "STA context not found for saved session's BSSID %02x:%02x:%02x:%02x:%02x:%02x\n" ),
814 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[0],
815 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[1],
816 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[2],
817 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[3],
818 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[4],
819 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[5] );)
820 return eSIR_FAILURE;
821 }
822
823 for (tid = 0; tid < STACFG_MAX_TC; tid++)
824 {
825 if (pSta->tcCfg[tid].fUseBATx)
826 {
827 status = limCreateRICBlockAckIE(pMac, tid, &pSta->tcCfg[tid], ric_ies + offset, &ieLength);
828 if (eSIR_SUCCESS == status)
829 {
830 offset += ieLength;
831 *ric_ies_length += ieLength;
832 numBA++;
833 }
834 else
835 {
836 PELOGE(limLog(pMac, LOGE, FL("BA RIC IE creation for TID %d failed with status %d"), tid, status);)
837 }
838 }
839 }
840
841 PELOGE(limLog(pMac, LOGE, FL("Number of BA RIC IEs created = %d: Total length = %d\n"), numBA, *ric_ies_length);)
842 return status;
843}
844
845/*------------------------------------------------------------------
846 *
847 * Will post pre auth response to SME.
848 *
849 *------------------------------------------------------------------*/
850void limPostFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
851 tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
852 tpPESession psessionEntry)
853{
854 tpSirFTPreAuthRsp pFTPreAuthRsp;
855 tSirMsgQ mmhMsg;
856 tANI_U16 rspLen = sizeof(tSirFTPreAuthRsp);
857 tSirRetStatus sirStatus = eSIR_SUCCESS;
858
859 pFTPreAuthRsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rspLen);
860 if(NULL == pFTPreAuthRsp)
861 {
862 PELOGE(limLog( pMac, LOGE, "Failed to allocate memory\n");)
863 VOS_ASSERT(pFTPreAuthRsp != NULL);
864 return;
865 }
866 vos_mem_zero( pFTPreAuthRsp, rspLen);
867#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
868 PELOGE(limLog( pMac, LOGE, "%s: Auth Rsp = %p\n", pFTPreAuthRsp);)
869#endif
870
871 palZeroMemory(pMac, (tANI_U8*)pFTPreAuthRsp, rspLen);
872 pFTPreAuthRsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
873 pFTPreAuthRsp->length = (tANI_U16) rspLen;
874 pFTPreAuthRsp->status = status;
875 if (psessionEntry)
876 pFTPreAuthRsp->smeSessionId = psessionEntry->smeSessionId;
877
878 // The bssid of the AP we are sending Auth1 to.
879 if (pMac->ft.ftPEContext.pFTPreAuthReq)
880 sirCopyMacAddr(pFTPreAuthRsp->preAuthbssId,
881 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
882
883 // Attach the auth response now back to SME
884 pFTPreAuthRsp->ft_ies_length = 0;
885 if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
886 {
887 // Only 11r assoc has FT IEs.
888 vos_mem_copy(pFTPreAuthRsp->ft_ies, auth_rsp, auth_rsp_length);
889 pFTPreAuthRsp->ft_ies_length = auth_rsp_length;
890 }
891
892#ifdef WLAN_FEATURE_VOWIFI_11R
893 if ((psessionEntry) && (psessionEntry->is11Rconnection))
894 {
895 /* Fill in the Block Ack RIC IEs in the preAuthRsp */
896 sirStatus = limFTFillRICBlockAckInfo(pMac, pFTPreAuthRsp->ric_ies,
897 (tANI_U32 *)&pFTPreAuthRsp->ric_ies_length);
898 if (eSIR_SUCCESS != sirStatus)
899 {
900 PELOGE(limLog(pMac, LOGE, FL("Fill RIC BA Info failed with status %d"), sirStatus);)
901 }
902 }
903#endif
904
905 mmhMsg.type = pFTPreAuthRsp->messageType;
906 mmhMsg.bodyptr = pFTPreAuthRsp;
907 mmhMsg.bodyval = 0;
908
909#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
910 PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME\n");)
911#endif
912 PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME with status of %d\n", status);)
913 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
914}
915
916/*------------------------------------------------------------------
917 *
918 * Send the FT Pre Auth Response to SME when ever we have a status
919 * ready to be sent to SME
920 *
921 * SME will be the one to send it up to the supplicant to receive
922 * FTIEs which will be required for Reassoc Req.
923 *
924 *------------------------------------------------------------------*/
925void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
926 tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
927 tpPESession psessionEntry)
928{
929
930 // Save the status of pre-auth
931 pMac->ft.ftPEContext.ftPreAuthStatus = status;
932
933 // Save the auth rsp, so we can send it to
934 // SME once we resume link.
935 pMac->ft.ftPEContext.saved_auth_rsp_length = 0;
936 if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
937 {
938 vos_mem_copy(pMac->ft.ftPEContext.saved_auth_rsp,
939 auth_rsp, auth_rsp_length);
940 pMac->ft.ftPEContext.saved_auth_rsp_length = auth_rsp_length;
941 }
942
943 if (psessionEntry->currentOperChannel !=
944 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum)
945 {
946 // Need to move to the original AP channel
947 limChangeChannelWithCallback(pMac, psessionEntry->currentOperChannel,
948 limPerformPostFTPreAuthAndChannelChange, NULL, psessionEntry);
949 }
950 else
951 {
952#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
953 PELOGE(limLog( pMac, LOGE, "Pre auth on same channel as connected AP channel %d\n",
954 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);)
955#endif
956 limFTProcessPreAuthResult(pMac, status, (tANI_U32 *)psessionEntry);
957 }
958}
959
960/*------------------------------------------------------------------
961 *
962 * This function handles the 11R Reassoc Req from SME
963 *
964 *------------------------------------------------------------------*/
965void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf,
966 tpPESession psessionEntry)
967{
968 tANI_U8 smeSessionId = 0;
969 tANI_U16 transactionId = 0;
970 tANI_U8 chanNum = 0;
971 tLimMlmReassocReq *pMlmReassocReq;
972 tANI_U16 caps;
973 tANI_U32 val;
974 tSirMsgQ msgQ;
975 tSirRetStatus retCode;
976 tANI_U32 teleBcnEn = 0;
977
978 chanNum = psessionEntry->currentOperChannel;
979 limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
980 psessionEntry->smeSessionId = smeSessionId;
981 psessionEntry->transactionId = transactionId;
982
983
984
985 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmReassocReq,
986 sizeof(tLimMlmReassocReq)))
987 {
988 // Log error
989 limLog(pMac, LOGE, FL("call to palAllocateMemory failed for mlmReassocReq\n"));
990 return;
991 }
992
993 palCopyMemory( pMac->hHdd, pMlmReassocReq->peerMacAddr,
994 psessionEntry->bssId,
995 sizeof(tSirMacAddr));
996
997 if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
998 (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout)
999 != eSIR_SUCCESS)
1000 {
1001 /**
1002 * Could not get ReassocFailureTimeout value
1003 * from CFG. Log error.
1004 */
1005 limLog(pMac, LOGE, FL("could not retrieve ReassocFailureTimeout value\n"));
1006 return;
1007 }
1008
1009 if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
1010 {
1011 /**
1012 * Could not get Capabilities value
1013 * from CFG. Log error.
1014 */
1015 limLog(pMac, LOGE, FL("could not retrieve Capabilities value\n"));
1016 return;
1017 }
1018 pMlmReassocReq->capabilityInfo = caps;
1019
1020 /* Update PE sessionId*/
1021 pMlmReassocReq->sessionId = psessionEntry->peSessionId;
1022
1023 /* If telescopic beaconing is enabled, set listen interval to WNI_CFG_TELE_BCN_MAX_LI */
1024 if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
1025 eSIR_SUCCESS)
1026 limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN\n"));
1027
1028 if(teleBcnEn)
1029 {
1030 if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != eSIR_SUCCESS)
1031 /**
1032 * Could not get ListenInterval value
1033 * from CFG. Log error.
1034 */
1035 limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
1036 return;
1037 }
1038 else
1039 {
1040 if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
1041 {
1042 /**
1043 * Could not get ListenInterval value
1044 * from CFG. Log error.
1045 */
1046 limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
1047 return;
1048 }
1049 }
1050 if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
1051 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1052 {
1053 return;
1054 }
1055
1056 if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
1057 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1058 {
1059 return;
1060 }
1061
1062 if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
1063 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1064 {
1065 return;
1066 }
1067
1068 pMlmReassocReq->listenInterval = (tANI_U16) val;
1069
1070 psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
1071
1072
1073 //we need to defer the message until we get the response back from HAL.
1074 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
1075
1076 msgQ.type = SIR_HAL_ADD_BSS_REQ;
1077 msgQ.reserved = 0;
1078 msgQ.bodyptr = pMac->ft.ftPEContext.pAddBssReq;
1079 msgQ.bodyval = 0;
1080
1081
1082#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
1083 limLog( pMac, LOGE, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
1084#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07001085 MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07001086
1087 retCode = wdaPostCtrlMsg( pMac, &msgQ );
1088 if( eSIR_SUCCESS != retCode)
1089 {
1090 vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
1091 limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
1092 retCode );
1093 }
1094 // Dont need this anymore
1095 pMac->ft.ftPEContext.pAddBssReq = NULL;
1096 return;
1097}
1098
1099/*------------------------------------------------------------------
1100 *
1101 * This function is called if preauth response is not received from the AP
1102 * within this timeout while FT in progress
1103 *
1104 *------------------------------------------------------------------*/
1105void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac)
1106{
1107 tpPESession psessionEntry;
1108
1109 // We have failed pre auth. We need to resume link and get back on
1110 // home channel.
1111
1112 if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId))== NULL)
1113 {
1114 limLog(pMac, LOGE, FL("Session Does not exist for given sessionID\n"));
1115 return;
1116 }
1117
1118 // Ok, so attempted at Pre-Auth and failed. If we are off channel. We need
1119 // to get back.
1120 limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
1121}
1122
1123
1124/*------------------------------------------------------------------
1125 *
1126 * This function is called to process the update key request from SME
1127 *
1128 *------------------------------------------------------------------*/
1129tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
1130{
1131 tAddBssParams * pAddBssParams;
1132 tSirFTUpdateKeyInfo * pKeyInfo;
1133 tANI_U32 val = 0;
1134
1135 /* Sanity Check */
1136 if( pMac == NULL || pMsgBuf == NULL )
1137 {
1138 return TRUE;
1139 }
1140
1141 pAddBssParams = pMac->ft.ftPEContext.pAddBssReq;
1142 pKeyInfo = (tSirFTUpdateKeyInfo *)pMsgBuf;
1143
1144 /* Store the key information in the ADD BSS parameters */
1145 pAddBssParams->extSetStaKeyParamValid = 1;
1146 pAddBssParams->extSetStaKeyParam.encType = pKeyInfo->keyMaterial.edType;
1147 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pAddBssParams->extSetStaKeyParam.key,
1148 (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof( tSirKeys ));
1149 if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val))
1150 {
1151 limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC\n" ));
1152 }
1153
1154 pAddBssParams->extSetStaKeyParam.singleTidRc = val;
1155
1156 return TRUE;
1157}
1158
1159tSirRetStatus
1160limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
1161{
1162 tSirMsgQ msg;
1163 tSirAggrQosReq * aggrQosReq = (tSirAggrQosReq *)pMsgBuf;
1164 tpAggrAddTsParams pAggrAddTsParam;
1165 tpPESession psessionEntry = NULL;
1166 tpLimTspecInfo tspecInfo;
1167 tANI_U8 ac;
1168 tpDphHashNode pSta;
1169 tANI_U16 aid;
1170 tANI_U8 sessionId;
1171 int i;
1172
1173 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
1174 (void **)&pAggrAddTsParam,
1175 sizeof(tAggrAddTsParams)))
1176 {
1177 PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory() failed\n"));)
1178 return eSIR_MEM_ALLOC_FAILED;
1179 }
1180
1181 psessionEntry = peFindSessionByBssid(pMac, aggrQosReq->bssId, &sessionId);
1182
1183 if (psessionEntry == NULL) {
1184 PELOGE(limLog(pMac, LOGE, FL("psession Entry Null for sessionId = %d\n"), aggrQosReq->sessionId);)
1185 return eSIR_FAILURE;
1186 }
1187
1188 pSta = dphLookupHashEntry(pMac, aggrQosReq->bssId, &aid, &psessionEntry->dph.dphHashTable);
1189 if (pSta == NULL)
1190 {
1191 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
1192 return eSIR_FAILURE;
1193 }
1194
1195 palZeroMemory( pMac->hHdd, (tANI_U8 *)pAggrAddTsParam,
1196 sizeof(tAggrAddTsParams));
1197 pAggrAddTsParam->staIdx = psessionEntry->staId;
1198 // Fill in the sessionId specific to PE
1199 pAggrAddTsParam->sessionId = sessionId;
1200 pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
1201
1202 for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
1203 {
1204 if (aggrQosReq->aggrInfo.tspecIdx & (1<<i))
1205 {
1206 tSirMacTspecIE *pTspec = &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1207 /* Since AddTS response was successful, check for the PSB flag
1208 * and directional flag inside the TS Info field.
1209 * An AC is trigger enabled AC if the PSB subfield is set to 1
1210 * in the uplink direction.
1211 * An AC is delivery enabled AC if the PSB subfield is set to 1
1212 * in the downlink direction.
1213 * An AC is trigger and delivery enabled AC if the PSB subfield
1214 * is set to 1 in the bi-direction field.
1215 */
1216 if (pTspec->tsinfo.traffic.psb == 1)
1217 {
1218 limSetTspecUapsdMask(pMac, &pTspec->tsinfo, SET_UAPSD_MASK);
1219 }
1220 else
1221 {
1222 limSetTspecUapsdMask(pMac, &pTspec->tsinfo, CLEAR_UAPSD_MASK);
1223 }
1224 /* ADDTS success, so AC is now admitted. We shall now use the default
1225 * EDCA parameters as advertised by AP and send the updated EDCA params
1226 * to HAL.
1227 */
1228 ac = upToAc(pTspec->tsinfo.traffic.userPrio);
1229 if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
1230 {
1231 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
1232 }
1233 else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
1234 {
1235 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
1236 }
1237 else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
1238 {
1239 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
1240 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
1241 }
1242
1243 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
1244
1245 if (pSta->aniPeer == eANI_BOOLEAN_TRUE)
1246 {
1247 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_TRUE);
1248 }
1249 else
1250 {
1251 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_FALSE);
1252 }
1253
1254 if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, pTspec, 0, &tspecInfo))
1255 {
1256 PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
1257 pMac->lim.gLimAddtsSent = false;
1258 return eSIR_FAILURE; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
1259 }
1260
1261 // Copy the TSPEC paramters
1262 pAggrAddTsParam->tspec[i] = aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1263 }
1264 }
1265
1266 msg.type = WDA_AGGR_QOS_REQ;
1267 msg.bodyptr = pAggrAddTsParam;
1268 msg.bodyval = 0;
1269
1270 /* We need to defer any incoming messages until we get a
1271 * WDA_AGGR_QOS_RSP from HAL.
1272 */
1273 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
Jeff Johnsone7245742012-09-05 17:12:55 -07001274 MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07001275
1276 if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
1277 {
1278 PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
1279 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1280 palFreeMemory(pMac->hHdd, (tANI_U8*)pAggrAddTsParam);
1281 return eSIR_FAILURE;
1282 }
1283
1284 return eSIR_SUCCESS;
1285}
1286
1287void
1288limFTSendAggrQosRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd,
1289 tpAggrAddTsParams aggrQosRsp, tANI_U8 smesessionId)
1290{
1291 tpSirAggrQosRsp rsp;
1292 int i = 0;
1293
1294 if (! rspReqd)
1295 {
1296 return;
1297 }
1298
1299 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp,
1300 sizeof(tSirAggrQosRsp)))
1301 {
1302 limLog(pMac, LOGP, FL("palAllocateMemory failed for tSirAggrQosRsp"));
1303 return;
1304 }
1305
1306 palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
1307 rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
1308 rsp->sessionId = smesessionId;
1309 rsp->length = sizeof(*rsp);
1310 rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
1311
1312 for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ )
1313 {
1314 if( (1 << i) & aggrQosRsp->tspecIdx )
1315 {
1316 rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i];
1317 rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
1318 }
1319 }
1320
1321 limSendSmeAggrQosRsp(pMac, rsp, smesessionId);
1322 return;
1323}
1324
1325
1326void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
1327{
1328 tpAggrAddTsParams pAggrQosRspMsg = NULL;
1329 //tpAggrQosParams pAggrQosRspMsg = NULL;
1330 tAddTsParams addTsParam = {0};
1331 tpDphHashNode pSta = NULL;
1332 tANI_U16 assocId =0;
1333 tSirMacAddr peerMacAddr;
1334 tANI_U8 rspReqd = 1;
1335 tpPESession psessionEntry = NULL;
1336 int i = 0;
1337
1338 PELOG1(limLog(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL\n"));)
1339
1340 /* Need to process all the deferred messages enqueued since sending the
1341 SIR_HAL_AGGR_ADD_TS_REQ */
1342 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1343
1344 pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr);
1345 if (NULL == pAggrQosRspMsg)
1346 {
1347 PELOGE(limLog(pMac, LOGE, FL("NULL pAggrQosRspMsg"));)
1348 return;
1349 }
1350
1351 psessionEntry = peFindSessionBySessionId(pMac, pAggrQosRspMsg->sessionId);
1352 if (NULL == psessionEntry)
1353 {
1354 // Cant find session entry
1355 PELOGE(limLog(pMac, LOGE, FL("Cant find session entry for %s\n"), __FUNCTION__);)
1356 if( pAggrQosRspMsg != NULL )
1357 {
1358 palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
1359 }
1360 return;
1361 }
1362
1363 for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
1364 {
1365 if((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
1366 (pAggrQosRspMsg->status[i] != eHAL_STATUS_SUCCESS))
1367 {
1368 /* send DELTS to the station */
1369 sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
1370
1371 addTsParam.staIdx = pAggrQosRspMsg->staIdx;
1372 addTsParam.sessionId = pAggrQosRspMsg->sessionId;
1373 addTsParam.tspec = pAggrQosRspMsg->tspec[i];
1374 addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx;
1375
1376 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd,
1377 &addTsParam.tspec.tsinfo,
1378 &addTsParam.tspec, psessionEntry);
1379
1380 pSta = dphLookupAssocId(pMac, addTsParam.staIdx, &assocId,
1381 &psessionEntry->dph.dphHashTable);
1382 if (pSta != NULL)
1383 {
1384 limAdmitControlDeleteTS(pMac, assocId, &addTsParam.tspec.tsinfo,
1385 NULL, (tANI_U8 *)&addTsParam.tspecIdx);
1386 }
1387 }
1388 }
1389
1390 /* Send the Aggr QoS response to SME */
1391
1392 limFTSendAggrQosRsp(pMac, rspReqd, pAggrQosRspMsg,
1393 psessionEntry->smeSessionId);
1394 if( pAggrQosRspMsg != NULL )
1395 {
1396 palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
1397 }
1398 return;
1399}
1400
1401
1402/*--------------------------------------------------------------------------
1403 Determines if a session with ccx or 11r assoc is present.
1404 If present it will return TRUE else FALSE
1405 ------------------------------------------------------------------------*/
1406int limisFastTransitionRequired(tpAniSirGlobal pMac, int sessionId)
1407{
1408 if(pMac->lim.gpSession[sessionId].valid == TRUE)
1409 {
1410 // If ccx or 11r connection is found we need to return TRUE
1411 if((pMac->lim.gpSession[sessionId].bssType == eSIR_INFRASTRUCTURE_MODE) &&
1412 (((pMac->lim.gpSession[sessionId].is11Rconnection)
1413#ifdef FEATURE_WLAN_CCX
1414 || (pMac->lim.gpSession[sessionId].isCCXconnection)
1415#endif
Jeff Johnson43971f52012-07-17 12:26:56 -07001416#ifdef FEATURE_WLAN_LFR
1417 || (pMac->lim.gpSession[sessionId].isFastRoamIniFeatureEnabled)
1418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 )&&
1420 pMac->lim.gpSession[sessionId].isFastTransitionEnabled))
1421 {
1422 // Make sure we have 11r/CCX and FT enabled only then we need
1423 // the values to be altered from cfg for FW RSSI Period alteration.
1424 return TRUE;
1425 }
1426 }
1427
1428 return FALSE;
1429}
1430
1431#endif /* WLAN_FEATURE_VOWIFI_11R */