blob: aa0c239743f2c5d33f05d0693aaf19fdbb8b8f31 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. 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 */
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;
445 pAddBssParams->currentExtChannel = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
446 }
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
513
514 limPopulateOwnRateSet(pMac, &pAddBssParams->staContext.supportedRates,
515 beaconStruct.HTCaps.supportedMCSSet, false,pftSessionEntry);
516 limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,pftSessionEntry);
517
518 }
519
520
521 //Disable BA. It will be set as part of ADDBA negotiation.
522 for( i = 0; i < STACFG_MAX_TC; i++ )
523 {
524 pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE;
525 pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE;
526 pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE;
527 pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE;
528 }
529
530#if defined WLAN_FEATURE_VOWIFI
531 pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;
532#endif
533
534 pAddBssParams->status = eHAL_STATUS_SUCCESS;
535 pAddBssParams->respReqd = true;
536
537 pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId;
538 pAddBssParams->sessionId = pftSessionEntry->peSessionId;
539
540 // Set a new state for MLME
541
542 pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
543
544 pAddBssParams->halPersona=(tANI_U8)pftSessionEntry->pePersona; //pass on the session persona to hal
545
546 pMac->ft.ftPEContext.pAddBssReq = pAddBssParams;
547
548#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
549 limLog( pMac, LOGE, FL( "Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..." ));
550#endif
551
552 return 0;
553}
554
555/*------------------------------------------------------------------
556 *
557 * Setup the new session for the pre-auth AP.
558 * Return the newly created session entry.
559 *
560 *------------------------------------------------------------------*/
561tpPESession limFillFTSession(tpAniSirGlobal pMac,
562 tpSirBssDescription pbssDescription, tpPESession psessionEntry)
563{
564 tpPESession pftSessionEntry;
565 tANI_U8 currentBssUapsd;
566 tANI_U8 sessionId;
567 tPowerdBm localPowerConstraint;
568 tPowerdBm regMax;
569 tSchBeaconStruct beaconStruct;
570
571 if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId,
572 &sessionId, pMac->lim.maxStation)) == NULL)
573 {
574 limLog(pMac, LOGE, FL("Session Can not be created for pre-auth 11R AP\n"));
575 return NULL;
576 }
577
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700578#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700579 limPrintMacAddr(pMac, pbssDescription->bssId, LOGE);
580#endif
581
582 /* Store PE session Id in session Table */
583 pftSessionEntry->peSessionId = sessionId;
584
585 pftSessionEntry->dot11mode = psessionEntry->dot11mode;
586 pftSessionEntry->htCapabality = psessionEntry->htCapabality;
587
588 pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled;
589 pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled;
590 pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled;
591 pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable;
592
593 // Fields to be filled later
594 pftSessionEntry->pLimJoinReq = NULL;
595 pftSessionEntry->smeSessionId = 0;
596 pftSessionEntry->transactionId = 0;
597
598 limExtractApCapabilities( pMac,
599 (tANI_U8 *) pbssDescription->ieFields,
600 limGetIElenFromBssDescription( pbssDescription ),
601 &beaconStruct );
602
603 pftSessionEntry->rateSet.numRates = beaconStruct.supportedRates.numRates;
604 palCopyMemory( pMac->hHdd, pftSessionEntry->rateSet.rate,
605 beaconStruct.supportedRates.rate, beaconStruct.supportedRates.numRates );
606
607 pftSessionEntry->extRateSet.numRates = beaconStruct.extendedRates.numRates;
608 palCopyMemory(pMac->hHdd, pftSessionEntry->extRateSet.rate,
609 beaconStruct.extendedRates.rate, pftSessionEntry->extRateSet.numRates);
610
611
612 pftSessionEntry->ssId.length = beaconStruct.ssId.length;
613 palCopyMemory( pMac->hHdd, pftSessionEntry->ssId.ssId, beaconStruct.ssId.ssId,
614 pftSessionEntry->ssId.length);
615
616
617 // Self Mac
618 sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr);
619 sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700620#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_CCX || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700621 limPrintMacAddr(pMac, pftSessionEntry->limReAssocbssId, LOGE);
622#endif
623
624 /* Store beaconInterval */
625 pftSessionEntry->beaconParams.beaconInterval = pbssDescription->beaconInterval;
626 pftSessionEntry->bssType = psessionEntry->bssType;
627
628 pftSessionEntry->statypeForBss = STA_ENTRY_PEER;
629 pftSessionEntry->nwType = pbssDescription->nwType;
630
631 /* Copy The channel Id to the session Table */
632 pftSessionEntry->limReassocChannelId = pbssDescription->channelId;
633 pftSessionEntry->currentOperChannel = pbssDescription->channelId;
634
635
636 if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE)
637 {
638 pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
639 }
640 else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE)
641 {
642 pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
643 }
644 else
645 {
646 /* Throw an error and return and make sure to delete the session.*/
647 limLog(pMac, LOGE, FL("Invalid bss type\n"));
648 }
649
650 pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo;
651 pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo;
652
653 pftSessionEntry->limCurrentTitanHtCaps=
654 pbssDescription->titanHtCaps;
655 pftSessionEntry->limReassocTitanHtCaps=
656 pftSessionEntry->limCurrentTitanHtCaps;
657
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,
664 &currentBssUapsd , &localPowerConstraint);
665
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
715 limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry,
716 pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription );
717 pMac->ft.ftPEContext.pftSessionEntry = pftSessionEntry;
718 }
719}
720
721/*------------------------------------------------------------------
722 * Resume Link Call Back
723 *------------------------------------------------------------------*/
724void limFTProcessPreAuthResult(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data)
725{
726 tpPESession psessionEntry;
727
728 psessionEntry = (tpPESession)data;
729
730 if (pMac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS)
731 {
732 limFTSetupAuthSession(pMac, psessionEntry);
733 }
734
735 // Post the FT Pre Auth Response to SME
736 limPostFTPreAuthRsp(pMac, pMac->ft.ftPEContext.ftPreAuthStatus,
737 pMac->ft.ftPEContext.saved_auth_rsp,
738 pMac->ft.ftPEContext.saved_auth_rsp_length, psessionEntry);
739
740}
741
742/*------------------------------------------------------------------
743 * Resume Link Call Back
744 *------------------------------------------------------------------*/
745void limPerformPostFTPreAuthAndChannelChange(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data,
746 tpPESession psessionEntry)
747{
748 //Set the resume channel to Any valid channel (invalid).
749 //This will instruct HAL to set it to any previous valid channel.
750 peSetResumeChannel(pMac, 0, 0);
751 limResumeLink(pMac, limFTProcessPreAuthResult, (tANI_U32 *)psessionEntry);
752}
753
754tSirRetStatus limCreateRICBlockAckIE(tpAniSirGlobal pMac, tANI_U8 tid, tCfgTrafficClass *pTrafficClass,
755 tANI_U8 *ric_ies, tANI_U32 *ieLength)
756{
757 tDot11fIERICDataDesc ricIe;
758 tDot11fFfBAStartingSequenceControl baSsnControl;
759 tDot11fFfAddBAParameterSet baParamSet;
760 tDot11fFfBATimeout baTimeout;
761
762 vos_mem_zero(&ricIe, sizeof(tDot11fIERICDataDesc));
763 vos_mem_zero(&baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
764 vos_mem_zero(&baParamSet, sizeof(tDot11fFfAddBAParameterSet));
765 vos_mem_zero(&baTimeout, sizeof(tDot11fFfBATimeout));
766
767 ricIe.present = 1;
768 ricIe.RICData.present = 1;
769 ricIe.RICData.resourceDescCount = 1;
770 ricIe.RICData.Identifier = LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 + tid;
771 ricIe.RICDescriptor.present = 1;
772 ricIe.RICDescriptor.resourceType = LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA;
773 baParamSet.tid = tid;
774 baParamSet.policy = pTrafficClass->fTxBApolicy; // Immediate Block Ack
775 baParamSet.bufferSize = pTrafficClass->txBufSize;
776 vos_mem_copy((v_VOID_t *)&baTimeout, (v_VOID_t *)&pTrafficClass->tuTxBAWaitTimeout, sizeof(baTimeout));
777 baSsnControl.fragNumber = 0;
778 baSsnControl.ssn = LIM_FT_RIC_BA_SSN;
779
780 dot11fPackFfAddBAParameterSet(pMac, &baParamSet, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
781 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baParamSet, sizeof(tDot11fFfAddBAParameterSet));
782 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfAddBAParameterSet);
783
784 dot11fPackFfBATimeout(pMac, &baTimeout, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
785 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baTimeout, sizeof(tDot11fFfBATimeout));
786 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBATimeout);
787
788 dot11fPackFfBAStartingSequenceControl(pMac, &baSsnControl, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]);
789 //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl));
790 ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBAStartingSequenceControl);
791
792 return (tSirRetStatus) dot11fPackIeRICDataDesc(pMac, &ricIe, ric_ies, sizeof(tDot11fIERICDataDesc), ieLength);
793}
794
795tSirRetStatus limFTFillRICBlockAckInfo(tpAniSirGlobal pMac, tANI_U8 *ric_ies, tANI_U32 *ric_ies_length)
796{
797 tANI_U8 tid = 0;
798 tpDphHashNode pSta;
799 tANI_U16 numBA = 0, aid = 0;
800 tpPESession psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry;
801 tANI_U32 offset = 0, ieLength = 0;
802 tSirRetStatus status = eSIR_SUCCESS;
803
804 // First, extract the DPH entry
805 pSta = dphLookupHashEntry( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &aid, &psessionEntry->dph.dphHashTable);
806 if( NULL == pSta )
807 {
808 PELOGE(limLog( pMac, LOGE,
809 FL( "STA context not found for saved session's BSSID %02x:%02x:%02x:%02x:%02x:%02x\n" ),
810 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[0],
811 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[1],
812 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[2],
813 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[3],
814 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[4],
815 pMac->ft.ftPEContext.pFTPreAuthReq->currbssId[5] );)
816 return eSIR_FAILURE;
817 }
818
819 for (tid = 0; tid < STACFG_MAX_TC; tid++)
820 {
821 if (pSta->tcCfg[tid].fUseBATx)
822 {
823 status = limCreateRICBlockAckIE(pMac, tid, &pSta->tcCfg[tid], ric_ies + offset, &ieLength);
824 if (eSIR_SUCCESS == status)
825 {
826 offset += ieLength;
827 *ric_ies_length += ieLength;
828 numBA++;
829 }
830 else
831 {
832 PELOGE(limLog(pMac, LOGE, FL("BA RIC IE creation for TID %d failed with status %d"), tid, status);)
833 }
834 }
835 }
836
837 PELOGE(limLog(pMac, LOGE, FL("Number of BA RIC IEs created = %d: Total length = %d\n"), numBA, *ric_ies_length);)
838 return status;
839}
840
841/*------------------------------------------------------------------
842 *
843 * Will post pre auth response to SME.
844 *
845 *------------------------------------------------------------------*/
846void limPostFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
847 tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
848 tpPESession psessionEntry)
849{
850 tpSirFTPreAuthRsp pFTPreAuthRsp;
851 tSirMsgQ mmhMsg;
852 tANI_U16 rspLen = sizeof(tSirFTPreAuthRsp);
853 tSirRetStatus sirStatus = eSIR_SUCCESS;
854
855 pFTPreAuthRsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rspLen);
856 if(NULL == pFTPreAuthRsp)
857 {
858 PELOGE(limLog( pMac, LOGE, "Failed to allocate memory\n");)
859 VOS_ASSERT(pFTPreAuthRsp != NULL);
860 return;
861 }
862 vos_mem_zero( pFTPreAuthRsp, rspLen);
863#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
864 PELOGE(limLog( pMac, LOGE, "%s: Auth Rsp = %p\n", pFTPreAuthRsp);)
865#endif
866
867 palZeroMemory(pMac, (tANI_U8*)pFTPreAuthRsp, rspLen);
868 pFTPreAuthRsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
869 pFTPreAuthRsp->length = (tANI_U16) rspLen;
870 pFTPreAuthRsp->status = status;
871 if (psessionEntry)
872 pFTPreAuthRsp->smeSessionId = psessionEntry->smeSessionId;
873
874 // The bssid of the AP we are sending Auth1 to.
875 if (pMac->ft.ftPEContext.pFTPreAuthReq)
876 sirCopyMacAddr(pFTPreAuthRsp->preAuthbssId,
877 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId);
878
879 // Attach the auth response now back to SME
880 pFTPreAuthRsp->ft_ies_length = 0;
881 if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
882 {
883 // Only 11r assoc has FT IEs.
884 vos_mem_copy(pFTPreAuthRsp->ft_ies, auth_rsp, auth_rsp_length);
885 pFTPreAuthRsp->ft_ies_length = auth_rsp_length;
886 }
887
888#ifdef WLAN_FEATURE_VOWIFI_11R
889 if ((psessionEntry) && (psessionEntry->is11Rconnection))
890 {
891 /* Fill in the Block Ack RIC IEs in the preAuthRsp */
892 sirStatus = limFTFillRICBlockAckInfo(pMac, pFTPreAuthRsp->ric_ies,
893 (tANI_U32 *)&pFTPreAuthRsp->ric_ies_length);
894 if (eSIR_SUCCESS != sirStatus)
895 {
896 PELOGE(limLog(pMac, LOGE, FL("Fill RIC BA Info failed with status %d"), sirStatus);)
897 }
898 }
899#endif
900
901 mmhMsg.type = pFTPreAuthRsp->messageType;
902 mmhMsg.bodyptr = pFTPreAuthRsp;
903 mmhMsg.bodyval = 0;
904
905#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
906 PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME\n");)
907#endif
908 PELOGE(limLog( pMac, LOGE, "Posted Auth Rsp to SME with status of %d\n", status);)
909 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
910}
911
912/*------------------------------------------------------------------
913 *
914 * Send the FT Pre Auth Response to SME when ever we have a status
915 * ready to be sent to SME
916 *
917 * SME will be the one to send it up to the supplicant to receive
918 * FTIEs which will be required for Reassoc Req.
919 *
920 *------------------------------------------------------------------*/
921void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, eHalStatus status,
922 tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length,
923 tpPESession psessionEntry)
924{
925
926 // Save the status of pre-auth
927 pMac->ft.ftPEContext.ftPreAuthStatus = status;
928
929 // Save the auth rsp, so we can send it to
930 // SME once we resume link.
931 pMac->ft.ftPEContext.saved_auth_rsp_length = 0;
932 if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE))
933 {
934 vos_mem_copy(pMac->ft.ftPEContext.saved_auth_rsp,
935 auth_rsp, auth_rsp_length);
936 pMac->ft.ftPEContext.saved_auth_rsp_length = auth_rsp_length;
937 }
938
939 if (psessionEntry->currentOperChannel !=
940 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum)
941 {
942 // Need to move to the original AP channel
943 limChangeChannelWithCallback(pMac, psessionEntry->currentOperChannel,
944 limPerformPostFTPreAuthAndChannelChange, NULL, psessionEntry);
945 }
946 else
947 {
948#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
949 PELOGE(limLog( pMac, LOGE, "Pre auth on same channel as connected AP channel %d\n",
950 pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);)
951#endif
952 limFTProcessPreAuthResult(pMac, status, (tANI_U32 *)psessionEntry);
953 }
954}
955
956/*------------------------------------------------------------------
957 *
958 * This function handles the 11R Reassoc Req from SME
959 *
960 *------------------------------------------------------------------*/
961void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf,
962 tpPESession psessionEntry)
963{
964 tANI_U8 smeSessionId = 0;
965 tANI_U16 transactionId = 0;
966 tANI_U8 chanNum = 0;
967 tLimMlmReassocReq *pMlmReassocReq;
968 tANI_U16 caps;
969 tANI_U32 val;
970 tSirMsgQ msgQ;
971 tSirRetStatus retCode;
972 tANI_U32 teleBcnEn = 0;
973
974 chanNum = psessionEntry->currentOperChannel;
975 limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId);
976 psessionEntry->smeSessionId = smeSessionId;
977 psessionEntry->transactionId = transactionId;
978
979
980
981 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pMlmReassocReq,
982 sizeof(tLimMlmReassocReq)))
983 {
984 // Log error
985 limLog(pMac, LOGE, FL("call to palAllocateMemory failed for mlmReassocReq\n"));
986 return;
987 }
988
989 palCopyMemory( pMac->hHdd, pMlmReassocReq->peerMacAddr,
990 psessionEntry->bssId,
991 sizeof(tSirMacAddr));
992
993 if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
994 (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout)
995 != eSIR_SUCCESS)
996 {
997 /**
998 * Could not get ReassocFailureTimeout value
999 * from CFG. Log error.
1000 */
1001 limLog(pMac, LOGE, FL("could not retrieve ReassocFailureTimeout value\n"));
1002 return;
1003 }
1004
1005 if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS)
1006 {
1007 /**
1008 * Could not get Capabilities value
1009 * from CFG. Log error.
1010 */
1011 limLog(pMac, LOGE, FL("could not retrieve Capabilities value\n"));
1012 return;
1013 }
1014 pMlmReassocReq->capabilityInfo = caps;
1015
1016 /* Update PE sessionId*/
1017 pMlmReassocReq->sessionId = psessionEntry->peSessionId;
1018
1019 /* If telescopic beaconing is enabled, set listen interval to WNI_CFG_TELE_BCN_MAX_LI */
1020 if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
1021 eSIR_SUCCESS)
1022 limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN\n"));
1023
1024 if(teleBcnEn)
1025 {
1026 if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != eSIR_SUCCESS)
1027 /**
1028 * Could not get ListenInterval value
1029 * from CFG. Log error.
1030 */
1031 limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
1032 return;
1033 }
1034 else
1035 {
1036 if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS)
1037 {
1038 /**
1039 * Could not get ListenInterval value
1040 * from CFG. Log error.
1041 */
1042 limLog(pMac, LOGE, FL("could not retrieve ListenInterval\n"));
1043 return;
1044 }
1045 }
1046 if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
1047 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1048 {
1049 return;
1050 }
1051
1052 if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
1053 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1054 {
1055 return;
1056 }
1057
1058 if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, psessionEntry->bssId,
1059 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1060 {
1061 return;
1062 }
1063
1064 pMlmReassocReq->listenInterval = (tANI_U16) val;
1065
1066 psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
1067
1068
1069 //we need to defer the message until we get the response back from HAL.
1070 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
1071
1072 msgQ.type = SIR_HAL_ADD_BSS_REQ;
1073 msgQ.reserved = 0;
1074 msgQ.bodyptr = pMac->ft.ftPEContext.pAddBssReq;
1075 msgQ.bodyval = 0;
1076
1077
1078#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
1079 limLog( pMac, LOGE, FL( "Sending SIR_HAL_ADD_BSS_REQ..." ));
1080#endif
1081 MTRACE(macTraceMsgTx(pMac, 0, msgQ.type));
1082
1083 retCode = wdaPostCtrlMsg( pMac, &msgQ );
1084 if( eSIR_SUCCESS != retCode)
1085 {
1086 vos_mem_free(pMac->ft.ftPEContext.pAddBssReq);
1087 limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X\n"),
1088 retCode );
1089 }
1090 // Dont need this anymore
1091 pMac->ft.ftPEContext.pAddBssReq = NULL;
1092 return;
1093}
1094
1095/*------------------------------------------------------------------
1096 *
1097 * This function is called if preauth response is not received from the AP
1098 * within this timeout while FT in progress
1099 *
1100 *------------------------------------------------------------------*/
1101void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac)
1102{
1103 tpPESession psessionEntry;
1104
1105 // We have failed pre auth. We need to resume link and get back on
1106 // home channel.
1107
1108 if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId))== NULL)
1109 {
1110 limLog(pMac, LOGE, FL("Session Does not exist for given sessionID\n"));
1111 return;
1112 }
1113
1114 // Ok, so attempted at Pre-Auth and failed. If we are off channel. We need
1115 // to get back.
1116 limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
1117}
1118
1119
1120/*------------------------------------------------------------------
1121 *
1122 * This function is called to process the update key request from SME
1123 *
1124 *------------------------------------------------------------------*/
1125tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
1126{
1127 tAddBssParams * pAddBssParams;
1128 tSirFTUpdateKeyInfo * pKeyInfo;
1129 tANI_U32 val = 0;
1130
1131 /* Sanity Check */
1132 if( pMac == NULL || pMsgBuf == NULL )
1133 {
1134 return TRUE;
1135 }
1136
1137 pAddBssParams = pMac->ft.ftPEContext.pAddBssReq;
1138 pKeyInfo = (tSirFTUpdateKeyInfo *)pMsgBuf;
1139
1140 /* Store the key information in the ADD BSS parameters */
1141 pAddBssParams->extSetStaKeyParamValid = 1;
1142 pAddBssParams->extSetStaKeyParam.encType = pKeyInfo->keyMaterial.edType;
1143 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pAddBssParams->extSetStaKeyParam.key,
1144 (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof( tSirKeys ));
1145 if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val))
1146 {
1147 limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC\n" ));
1148 }
1149
1150 pAddBssParams->extSetStaKeyParam.singleTidRc = val;
1151
1152 return TRUE;
1153}
1154
1155tSirRetStatus
1156limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf )
1157{
1158 tSirMsgQ msg;
1159 tSirAggrQosReq * aggrQosReq = (tSirAggrQosReq *)pMsgBuf;
1160 tpAggrAddTsParams pAggrAddTsParam;
1161 tpPESession psessionEntry = NULL;
1162 tpLimTspecInfo tspecInfo;
1163 tANI_U8 ac;
1164 tpDphHashNode pSta;
1165 tANI_U16 aid;
1166 tANI_U8 sessionId;
1167 int i;
1168
1169 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
1170 (void **)&pAggrAddTsParam,
1171 sizeof(tAggrAddTsParams)))
1172 {
1173 PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory() failed\n"));)
1174 return eSIR_MEM_ALLOC_FAILED;
1175 }
1176
1177 psessionEntry = peFindSessionByBssid(pMac, aggrQosReq->bssId, &sessionId);
1178
1179 if (psessionEntry == NULL) {
1180 PELOGE(limLog(pMac, LOGE, FL("psession Entry Null for sessionId = %d\n"), aggrQosReq->sessionId);)
1181 return eSIR_FAILURE;
1182 }
1183
1184 pSta = dphLookupHashEntry(pMac, aggrQosReq->bssId, &aid, &psessionEntry->dph.dphHashTable);
1185 if (pSta == NULL)
1186 {
1187 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
1188 return eSIR_FAILURE;
1189 }
1190
1191 palZeroMemory( pMac->hHdd, (tANI_U8 *)pAggrAddTsParam,
1192 sizeof(tAggrAddTsParams));
1193 pAggrAddTsParam->staIdx = psessionEntry->staId;
1194 // Fill in the sessionId specific to PE
1195 pAggrAddTsParam->sessionId = sessionId;
1196 pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
1197
1198 for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
1199 {
1200 if (aggrQosReq->aggrInfo.tspecIdx & (1<<i))
1201 {
1202 tSirMacTspecIE *pTspec = &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1203 /* Since AddTS response was successful, check for the PSB flag
1204 * and directional flag inside the TS Info field.
1205 * An AC is trigger enabled AC if the PSB subfield is set to 1
1206 * in the uplink direction.
1207 * An AC is delivery enabled AC if the PSB subfield is set to 1
1208 * in the downlink direction.
1209 * An AC is trigger and delivery enabled AC if the PSB subfield
1210 * is set to 1 in the bi-direction field.
1211 */
1212 if (pTspec->tsinfo.traffic.psb == 1)
1213 {
1214 limSetTspecUapsdMask(pMac, &pTspec->tsinfo, SET_UAPSD_MASK);
1215 }
1216 else
1217 {
1218 limSetTspecUapsdMask(pMac, &pTspec->tsinfo, CLEAR_UAPSD_MASK);
1219 }
1220 /* ADDTS success, so AC is now admitted. We shall now use the default
1221 * EDCA parameters as advertised by AP and send the updated EDCA params
1222 * to HAL.
1223 */
1224 ac = upToAc(pTspec->tsinfo.traffic.userPrio);
1225 if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
1226 {
1227 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
1228 }
1229 else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
1230 {
1231 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
1232 }
1233 else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
1234 {
1235 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
1236 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
1237 }
1238
1239 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
1240
1241 if (pSta->aniPeer == eANI_BOOLEAN_TRUE)
1242 {
1243 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_TRUE);
1244 }
1245 else
1246 {
1247 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_FALSE);
1248 }
1249
1250 if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, pTspec, 0, &tspecInfo))
1251 {
1252 PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
1253 pMac->lim.gLimAddtsSent = false;
1254 return eSIR_FAILURE; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
1255 }
1256
1257 // Copy the TSPEC paramters
1258 pAggrAddTsParam->tspec[i] = aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
1259 }
1260 }
1261
1262 msg.type = WDA_AGGR_QOS_REQ;
1263 msg.bodyptr = pAggrAddTsParam;
1264 msg.bodyval = 0;
1265
1266 /* We need to defer any incoming messages until we get a
1267 * WDA_AGGR_QOS_RSP from HAL.
1268 */
1269 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
1270 MTRACE(macTraceMsgTx(pMac, 0, msg.type));
1271
1272 if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
1273 {
1274 PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed\n"));)
1275 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1276 palFreeMemory(pMac->hHdd, (tANI_U8*)pAggrAddTsParam);
1277 return eSIR_FAILURE;
1278 }
1279
1280 return eSIR_SUCCESS;
1281}
1282
1283void
1284limFTSendAggrQosRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd,
1285 tpAggrAddTsParams aggrQosRsp, tANI_U8 smesessionId)
1286{
1287 tpSirAggrQosRsp rsp;
1288 int i = 0;
1289
1290 if (! rspReqd)
1291 {
1292 return;
1293 }
1294
1295 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&rsp,
1296 sizeof(tSirAggrQosRsp)))
1297 {
1298 limLog(pMac, LOGP, FL("palAllocateMemory failed for tSirAggrQosRsp"));
1299 return;
1300 }
1301
1302 palZeroMemory( pMac->hHdd, (tANI_U8 *) rsp, sizeof(*rsp));
1303 rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
1304 rsp->sessionId = smesessionId;
1305 rsp->length = sizeof(*rsp);
1306 rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
1307
1308 for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ )
1309 {
1310 if( (1 << i) & aggrQosRsp->tspecIdx )
1311 {
1312 rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i];
1313 rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
1314 }
1315 }
1316
1317 limSendSmeAggrQosRsp(pMac, rsp, smesessionId);
1318 return;
1319}
1320
1321
1322void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
1323{
1324 tpAggrAddTsParams pAggrQosRspMsg = NULL;
1325 //tpAggrQosParams pAggrQosRspMsg = NULL;
1326 tAddTsParams addTsParam = {0};
1327 tpDphHashNode pSta = NULL;
1328 tANI_U16 assocId =0;
1329 tSirMacAddr peerMacAddr;
1330 tANI_U8 rspReqd = 1;
1331 tpPESession psessionEntry = NULL;
1332 int i = 0;
1333
1334 PELOG1(limLog(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL\n"));)
1335
1336 /* Need to process all the deferred messages enqueued since sending the
1337 SIR_HAL_AGGR_ADD_TS_REQ */
1338 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1339
1340 pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr);
1341 if (NULL == pAggrQosRspMsg)
1342 {
1343 PELOGE(limLog(pMac, LOGE, FL("NULL pAggrQosRspMsg"));)
1344 return;
1345 }
1346
1347 psessionEntry = peFindSessionBySessionId(pMac, pAggrQosRspMsg->sessionId);
1348 if (NULL == psessionEntry)
1349 {
1350 // Cant find session entry
1351 PELOGE(limLog(pMac, LOGE, FL("Cant find session entry for %s\n"), __FUNCTION__);)
1352 if( pAggrQosRspMsg != NULL )
1353 {
1354 palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
1355 }
1356 return;
1357 }
1358
1359 for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ )
1360 {
1361 if((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
1362 (pAggrQosRspMsg->status[i] != eHAL_STATUS_SUCCESS))
1363 {
1364 /* send DELTS to the station */
1365 sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
1366
1367 addTsParam.staIdx = pAggrQosRspMsg->staIdx;
1368 addTsParam.sessionId = pAggrQosRspMsg->sessionId;
1369 addTsParam.tspec = pAggrQosRspMsg->tspec[i];
1370 addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx;
1371
1372 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd,
1373 &addTsParam.tspec.tsinfo,
1374 &addTsParam.tspec, psessionEntry);
1375
1376 pSta = dphLookupAssocId(pMac, addTsParam.staIdx, &assocId,
1377 &psessionEntry->dph.dphHashTable);
1378 if (pSta != NULL)
1379 {
1380 limAdmitControlDeleteTS(pMac, assocId, &addTsParam.tspec.tsinfo,
1381 NULL, (tANI_U8 *)&addTsParam.tspecIdx);
1382 }
1383 }
1384 }
1385
1386 /* Send the Aggr QoS response to SME */
1387
1388 limFTSendAggrQosRsp(pMac, rspReqd, pAggrQosRspMsg,
1389 psessionEntry->smeSessionId);
1390 if( pAggrQosRspMsg != NULL )
1391 {
1392 palFreeMemory( pMac->hHdd, (void *)pAggrQosRspMsg );
1393 }
1394 return;
1395}
1396
1397
1398/*--------------------------------------------------------------------------
1399 Determines if a session with ccx or 11r assoc is present.
1400 If present it will return TRUE else FALSE
1401 ------------------------------------------------------------------------*/
1402int limisFastTransitionRequired(tpAniSirGlobal pMac, int sessionId)
1403{
1404 if(pMac->lim.gpSession[sessionId].valid == TRUE)
1405 {
1406 // If ccx or 11r connection is found we need to return TRUE
1407 if((pMac->lim.gpSession[sessionId].bssType == eSIR_INFRASTRUCTURE_MODE) &&
1408 (((pMac->lim.gpSession[sessionId].is11Rconnection)
1409#ifdef FEATURE_WLAN_CCX
1410 || (pMac->lim.gpSession[sessionId].isCCXconnection)
1411#endif
1412 )&&
1413 pMac->lim.gpSession[sessionId].isFastTransitionEnabled))
1414 {
1415 // Make sure we have 11r/CCX and FT enabled only then we need
1416 // the values to be altered from cfg for FW RSSI Period alteration.
1417 return TRUE;
1418 }
1419 }
1420
1421 return FALSE;
1422}
1423
1424#endif /* WLAN_FEATURE_VOWIFI_11R */