blob: c1d710e545ec94c38d5bed351e4b3084665db6e7 [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/*
23 * */
24/** ------------------------------------------------------------------------- *
25 ------------------------------------------------------------------------- *
26
27
28 \file csrNeighborRoam.c
29
30 Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform.
31
32 Copyright (C) 2010 Qualcomm, Incorporated
33
34
35 ========================================================================== */
36
37/*===========================================================================
38
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45
46
47 when who what, where, why
48---------- --- --------------------------------------------------------
4908/01/10 Murali Created
50
51===========================================================================*/
52#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
53#include "wlan_qct_wda.h"
54#include "palApi.h"
55#include "csrInsideApi.h"
56#include "smsDebug.h"
57#include "logDump.h"
58#include "smeQosInternal.h"
59#include "wlan_qct_tl.h"
60#include "smeInside.h"
61#include "vos_diag_core_event.h"
62#include "vos_diag_core_log.h"
63#include "csrApi.h"
64#include "wlan_qct_tl.h"
65#include "sme_Api.h"
66#include "csrNeighborRoam.h"
67#ifdef FEATURE_WLAN_CCX
68#include "csrCcx.h"
69#endif
70
71#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
72#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
73#define NEIGHBOR_ROAM_DEBUG smsLog
74#else
75#define NEIGHBOR_ROAM_DEBUG(x...)
76#endif
77
78VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
79 v_PVOID_t pUserCtxt);
80VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
81 v_PVOID_t pUserCtxt);
82void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus);
83eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile );
84
85#ifdef WLAN_FEATURE_VOWIFI_11R
86static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac);
87VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac);
88#endif
89
90/* State Transition macro */
91#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
92{\
93 pMac->roam.neighborRoamInfo.prevNeighborRoamState = pMac->roam.neighborRoamInfo.neighborRoamState;\
94 pMac->roam.neighborRoamInfo.neighborRoamState = newState;\
95 smsLog(pMac, LOGE, FL("Neighbor Roam Transition from state %d ==> %d"), pMac->roam.neighborRoamInfo.prevNeighborRoamState, newState);\
96}
97
98/* ---------------------------------------------------------------------------
99
100 \fn csrNeighborRoamFreeNeighborRoamBSSNode
101
102 \brief This function frees all the internal pointers CSR NeighborRoam BSS Info
103 and also frees the node itself
104
105 \param pMac - The handle returned by macOpen.
106 neighborRoamBSSNode - Neighbor Roam BSS Node to be freed
107
108 \return VOID
109
110---------------------------------------------------------------------------*/
111void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode)
112{
113 if (neighborRoamBSSNode)
114 {
115 if (neighborRoamBSSNode->pBssDescription)
116 {
117 vos_mem_free(neighborRoamBSSNode->pBssDescription);
118 neighborRoamBSSNode->pBssDescription = NULL;
119 }
120 vos_mem_free(neighborRoamBSSNode);
121 neighborRoamBSSNode = NULL;
122 }
123
124 return;
125}
126
127/* ---------------------------------------------------------------------------
128
129 \fn csrNeighborRoamRemoveRoamableAPListEntry
130
131 \brief This function removes a given entry from the given list
132
133 \param pMac - The handle returned by macOpen.
134 pList - The list from which the entry should be removed
135 pNeighborEntry - Neighbor Roam BSS Node to be removed
136
137 \return TRUE if successfully removed, else FALSE
138
139---------------------------------------------------------------------------*/
140tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
141 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
142{
143 if(pList)
144 {
145 return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
146 }
147
148 smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d\n"), csrLLCount(pList));
149
150 return eANI_BOOLEAN_FALSE;
151}
152
153/* ---------------------------------------------------------------------------
154
155 \fn csrNeighborRoamGetRoamableAPListNextEntry
156
157 \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list
158
159 \param pMac - The handle returned by macOpen.
160 pList - The list from which the entry should be returned
161 pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned
162
163 \return Neighbor Roam BSS Node to be returned
164
165---------------------------------------------------------------------------*/
166tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
167 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
168{
169 tListElem *pEntry = NULL;
170 tpCsrNeighborRoamBSSInfo pResult = NULL;
171
172 if(pList)
173 {
174 if(NULL == pNeighborEntry)
175 {
176 pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK);
177 }
178 else
179 {
180 pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
181 }
182 if(pEntry)
183 {
184 pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
185 }
186 }
187
188 return pResult;
189}
190
191/* ---------------------------------------------------------------------------
192
193 \fn csrNeighborRoamFreeRoamableBSSList
194
195 \brief Empties and frees all the nodes in the roamable AP list
196
197 \param pMac - The handle returned by macOpen.
198 pList - Neighbor Roam BSS List to be emptied
199
200 \return VOID
201
202---------------------------------------------------------------------------*/
203void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList)
204{
205 tpCsrNeighborRoamBSSInfo pResult = NULL;
206
207 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Emptying the BSS list. Current count = %d\n"), csrLLCount(pList));
208
209 /* Pick up the head, remove and free the node till the list becomes empty */
210 while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL)
211 {
212 csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult);
213 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult);
214 }
215 return;
216}
217
218/* ---------------------------------------------------------------------------
219
220 \fn csrNeighborRoamReassocIndCallback
221
222 \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold.
223 Directly triggere HO in case of non-11r association
224 In case of 11R association, triggers a pre-auth eventually followed by actual HO
225
226 \param pAdapter - VOS Context
227 trafficStatus - UP/DOWN indication from TL
228 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
229
230 \return VOID
231
232---------------------------------------------------------------------------*/
233VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter,
234 v_U8_t trafficStatus,
235 v_PVOID_t pUserCtxt)
236{
237 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
238 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
239 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
240
241 smsLog(pMac, LOG1, FL("Reassoc indication callback called"));
242
243
244 //smsLog(pMac, LOGE, FL("Reassoc indication callback called at state %d"), pNeighborRoamInfo->neighborRoamState);
245
246 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
247
248
249 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
250 WLANTL_HO_THRESHOLD_DOWN,
251 csrNeighborRoamReassocIndCallback,
252 VOS_MODULE_ID_SME);
253
254 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
255 {
256 //err msg
257 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
258 }
259
260 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
261 /* Deregister reassoc callback. Ignore return status */
262 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
263 WLANTL_HO_THRESHOLD_DOWN,
264 csrNeighborRoamNeighborLookupUPCallback,
265 VOS_MODULE_ID_SME);
266
267 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
268 {
269 //err msg
270 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
271 }
272
273 /* We dont need to run this timer any more. */
274 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
275
276#ifdef WLAN_FEATURE_VOWIFI_11R
277 if (pNeighborRoamInfo->is11rAssoc)
278 {
279 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
280 {
281 csrNeighborRoamIssuePreauthReq(pMac);
282 }
283 else
284 {
285 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
286 VOS_ASSERT(0);
287 }
288 }
289 else
290#endif
291
292#ifdef FEATURE_WLAN_CCX
293 if (pNeighborRoamInfo->isCCXAssoc)
294 {
295 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
296 {
297 csrNeighborRoamIssuePreauthReq(pMac);
298 }
299 else
300 {
301 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
302 VOS_ASSERT(0);
303 }
304 }
305 else
306#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700307#ifdef FEATURE_WLAN_LFR
308 if (csrRoamIsFastRoamEnabled(pMac))
309 {
310 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
311 {
312 csrNeighborRoamIssuePreauthReq(pMac);
313 }
314 else
315 {
316 smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
317 VOS_ASSERT(0);
318 }
319 }
320 else
321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 {
323 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
324 {
325 csrNeighborRoamRequestHandoff(pMac);
326 }
327 else
328 {
329 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
330 VOS_ASSERT(0);
331 }
332 }
333 return VOS_STATUS_SUCCESS;
334}
335
336/* ---------------------------------------------------------------------------
337
338 \fn csrNeighborRoamResetConnectedStateControlInfo
339
340 \brief This function will reset the neighbor roam control info data structures.
341 This function should be invoked whenever we move to CONNECTED state from
342 any state other than INIT state
343
344 \param pMac - The handle returned by macOpen.
345
346 \return VOID
347
348---------------------------------------------------------------------------*/
349void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
350{
351 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
352
353 /* Do not reset the currentNeighborLookup Threshold here. The threshold and multiplier will be set before calling this API */
354 if ((pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == FALSE) &&
355 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels))
356 {
357 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
358 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
359
360 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
361 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
362
363 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
364 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
365 }
366 else
367 {
368 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
369 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
370 }
371
372 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
373
374 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
375
376 /* Abort any ongoing BG scans */
377 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
378 csrScanAbortMacScan(pMac);
379
380 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
381
382 /* We dont need to run this timer any more. */
383 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
384
385#ifdef WLAN_FEATURE_VOWIFI_11R
386 /* Do not free up the preauth done list here */
387 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
388 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
389 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
390 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
391 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
392 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
393 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
394#endif
395
396}
397
398/* ---------------------------------------------------------------------------
399
400 \fn csrNeighborRoamResetInitStateControlInfo
401
402 \brief This function will reset the neighbor roam control info data structures.
403 This function should be invoked whenever we move to CONNECTED state from
404 INIT state
405
406 \param pMac - The handle returned by macOpen.
407
408 \return VOID
409
410---------------------------------------------------------------------------*/
411void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
412{
413 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
414 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
415
416 csrNeighborRoamResetConnectedStateControlInfo(pMac);
417
418 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
419 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
420 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
421 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
422 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700423#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700424 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
425 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
426 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
427 csrNeighborRoamPurgePreauthFailedList(pMac);
428#endif
429#ifdef FEATURE_WLAN_CCX
430 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
431 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
432 pNeighborRoamInfo->MinQBssLoadRequired = 0;
433#endif
434
435 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
436 /* Deregister reassoc callback. Ignore return status */
437 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
438 WLANTL_HO_THRESHOLD_DOWN,
439 csrNeighborRoamReassocIndCallback,
440 VOS_MODULE_ID_SME);
441
442 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
443 {
444 //err msg
445 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
446 }
447
448 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighborLookup callback with TL. RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
449 /* Deregister neighbor lookup callback. Ignore return status */
450 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
451 WLANTL_HO_THRESHOLD_DOWN,
452 csrNeighborRoamNeighborLookupDOWNCallback,
453 VOS_MODULE_ID_SME);
454
455 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
456 {
457 //err msg
458 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vosStatus);
459 }
460
461 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
462 /* Deregister reassoc callback. Ignore return status */
463 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
464 WLANTL_HO_THRESHOLD_UP,
465 csrNeighborRoamNeighborLookupUPCallback,
466 VOS_MODULE_ID_SME);
467
468 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
469 {
470 //err msg
471 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
472 }
473
474 /* Reset currentNeighborLookupThreshold only after deregistering DOWN event from TL */
475 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
476 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
477
478 return;
479}
480
481#ifdef WLAN_FEATURE_VOWIFI_11R
482/* ---------------------------------------------------------------------------
483
484 \fn csrNeighborRoamBssIdScanFilter
485
486 \brief This API is used to prepare a filter to obtain scan results when
487 we complete the scan in the REPORT_SCAN state after receiving a
488 valid neighbor report from AP. This filter includes BSSIDs received from
489 the neighbor report from the AP in addition to the other filter parameters
490 created from connected profile
491
492 \param pMac - The handle returned by macOpen.
493 pScanFilter - Scan filter to be filled and returned
494
495 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
496 code otherwise
497
498---------------------------------------------------------------------------*/
499static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
500{
501 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
502 tANI_U8 i = 0;
503
504 VOS_ASSERT(pScanFilter != NULL);
505 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
506
507 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
508 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
509 if (NULL == pScanFilter->BSSIDs.bssid)
510 {
511 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
512 return eHAL_STATUS_FAILED_ALLOC;
513 }
514
515 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
516
517 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
518 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
519 {
520 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
521 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
522 }
523
524 /* Fill other general scan filter params */
525 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
526}
527
528/* ---------------------------------------------------------------------------
529
530 \fn csrNeighborRoamPurgePreauthFailList
531
532 \brief This function empties the preauth fail list
533
534 \param pMac - The handle returned by macOpen.
535
536 \return VOID
537
538---------------------------------------------------------------------------*/
539void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
540{
541 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
542
543 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
544 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
545 {
546 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
547 sizeof(tSirMacAddr));
548 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
549 }
550 return;
551}
552
553/* ---------------------------------------------------------------------------
554
555 \fn csrNeighborRoamAddBssIdToPreauthFailList
556
557 \brief This function adds the given BSSID to the Preauth fail list
558
559 \param pMac - The handle returned by macOpen.
560 bssId - BSSID to be added to the preauth fail list
561
562 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
563
564---------------------------------------------------------------------------*/
565eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
566{
567 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
568
569 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
570 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
571
572
573 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
574 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
575 {
576 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
577 return eHAL_STATUS_FAILURE;
578 }
579 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
580 bssId, sizeof(tSirMacAddr));
581 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
582
583 return eHAL_STATUS_SUCCESS;
584}
585
586/* ---------------------------------------------------------------------------
587
588 \fn csrNeighborRoamIsPreauthCandidate
589
590 \brief This function checks whether the given MAC address is already
591 present in the preauth fail list and returns TRUE/FALSE accordingly
592
593 \param pMac - The handle returned by macOpen.
594
595 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
596
597---------------------------------------------------------------------------*/
598tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
599{
600 tANI_U8 i = 0;
601 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
602
603 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
604 return eANI_BOOLEAN_TRUE;
605
606 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
607 {
608 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
609 bssId, sizeof(tSirMacAddr)))
610 {
611 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
612 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
613 return eANI_BOOLEAN_FALSE;
614 }
615 }
616
617 return eANI_BOOLEAN_TRUE;
618}
619
620/* ---------------------------------------------------------------------------
621
622 \fn csrNeighborRoamIssuePreauthReq
623
624 \brief This function issues preauth request to PE with the 1st AP entry in the
625 roamable AP list
626
627 \param pMac - The handle returned by macOpen.
628
629 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
630
631---------------------------------------------------------------------------*/
632static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
633{
634 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
635 eHalStatus status = eHAL_STATUS_SUCCESS;
636 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
637
638 /* This must not be true here */
639 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
640
641 /* Issue Preauth request to PE here */
642 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
643 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
644 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
645 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
646
647 if (NULL == pNeighborBssNode)
648 {
649 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
650 return eHAL_STATUS_FAILURE;
651 }
652 else
653 {
654 status = csrRoamIssueFTPreauthReq(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription);
655 if (eHAL_STATUS_SUCCESS != status)
656 {
657 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
658 return status;
659 }
660 }
661
662 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
663
664 /* Increment the preauth retry count */
665 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
666
667 /* Transition the state to preauthenticating */
668 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
669
670 /* Start the preauth rsp timer */
671 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
672 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
673 eANI_BOOLEAN_FALSE);
674 if (eHAL_STATUS_SUCCESS != status)
675 {
676 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
677 return status;
678 }
679
680
681 return status;
682}
683
684/* ---------------------------------------------------------------------------
685
686 \fn csrNeighborRoamPreauthRspHandler
687
688 \brief This function handle the Preauth response from PE
689 Every preauth is allowed max 3 tries if it fails. If a bssid failed
690 for more than MAX_TRIES, we will remove it from the list and try
691 with the next node in the roamable AP list and add the BSSID to pre-auth failed
692 list. If no more entries present in
693 roamable AP list, transition to REPORT_SCAN state
694
695 \param pMac - The handle returned by macOpen.
696 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
697
698 \return VOID
699
700---------------------------------------------------------------------------*/
701void csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
702{
703 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
704 eHalStatus status = eHAL_STATUS_SUCCESS;
705 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
706
707 // We can receive it in these 2 states.
708 VOS_ASSERT((pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) ||
709 (pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN));
710
711 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
712 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
713 {
714 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %\n"),
715 pNeighborRoamInfo->neighborRoamState);
716 }
717
718 if (VOS_STATUS_E_TIMEOUT != vosStatus)
719 {
720 /* This means we got the response from PE. Hence stop the timer */
721 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
722 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
723 }
724
725 if (VOS_STATUS_SUCCESS == vosStatus)
726 {
727 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
728 }
729 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
730 {
731 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
732
733 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
734 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
735 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
736
737 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
738 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
739 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
740
741 /* The caller of this function would start a timer and by the time it expires, supplicant should
742 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
743 }
744 else
745 {
746 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
747 tListElem *pEntry;
748
749 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
750
751 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
752 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
753 {
754 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
755 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
756
757 /* The one in the head of the list should be one with which we issued pre-auth and failed */
758 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
759 if(pEntry)
760 {
761 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
762 /* Add the BSSID to pre-auth fail list */
763 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
764 /* Now we can free this node */
765 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
766 }
767 }
768
769 /* Issue preauth request for the same/next entry */
770 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
771 return;
772
773 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
774
775 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
776 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
777 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
778 eANI_BOOLEAN_FALSE);
779 if (eHAL_STATUS_SUCCESS != status)
780 {
781 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
782 return;
783 }
784 }
785}
786#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
787
788/* ---------------------------------------------------------------------------
789
790 \fn csrNeighborRoamPrepareScanProfileFilter
791
792 \brief This function creates a scan filter based on the currently connected profile.
793 Based on this filter, scan results are obtained
794
795 \param pMac - The handle returned by macOpen.
796 pScanFilter - Populated scan filter based on the connected profile
797
798 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
799
800---------------------------------------------------------------------------*/
801eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
802{
803 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
804 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
805 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
806 tANI_U8 i = 0;
807
808 VOS_ASSERT(pScanFilter != NULL);
809
810 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
811
812 /* We dont want to set BSSID based Filter */
813 pScanFilter->BSSIDs.numOfBSSIDs = 0;
814
815 /* Populate all the information from the connected profile */
816 pScanFilter->SSIDs.numOfSSIDs = 1;
817 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
818 if (NULL == pScanFilter->SSIDs.SSIDList)
819 {
820 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
821 return eHAL_STATUS_FAILED_ALLOC;
822 }
823 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
824 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
825 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
826 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
827
828 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
829 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
830 pScanFilter->authType.numEntries = 1;
831 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
832
833 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
834 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
835
836 pScanFilter->mcEncryptionType.numEntries = 1;
837 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
838
839 pScanFilter->BSSType = pCurProfile->BSSType;
840
841 /* We are intrested only in the scan results on channels that we scanned */
842 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
843 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
844 if (NULL == pScanFilter->ChannelInfo.ChannelList)
845 {
846 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
847 vos_mem_free(pScanFilter->SSIDs.SSIDList);
848 pScanFilter->SSIDs.SSIDList = NULL;
849 return eHAL_STATUS_FAILED_ALLOC;
850 }
851 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
852 {
853 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
854 }
855
856#ifdef WLAN_FEATURE_VOWIFI_11R
857 if (pNeighborRoamInfo->is11rAssoc)
858 {
859 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
860 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
861 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
862 }
863#endif
864
865 return eHAL_STATUS_SUCCESS;
866}
867
Jeff Johnson43971f52012-07-17 12:26:56 -0700868tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
869{
870 tCsrScanResultInfo *pScanResult;
871 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
872 tANI_U32 CurrAPRssi = -125; /* We are setting this as default value to make sure we return this value,
873 when we do not see this AP in the scan result for some reason.However,it is
874 less likely that we are associated to an AP and do not see it in the scan list*/
875
876 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
877 {
878
879 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
880 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
881 {
882 /* We got a match with the currently associated AP.
883 * Capture the RSSI value and complete the while loop.
884 * The while loop is completed in order to make the current entry go back to NULL,
885 * and in the next while loop, it properly starts searching from the head of the list.
886 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
887
888 CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ;
889
890 } else {
891 continue;
892 }
893 }
894
895 return CurrAPRssi;
896
897}
898
Jeff Johnson295189b2012-06-20 16:38:30 -0700899/* ---------------------------------------------------------------------------
900
901 \fn csrNeighborRoamProcessScanResults
902
903 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
904 Assumed that the results are already sorted by RSSI by csrScanGetResult
905
906 \param pMac - The handle returned by macOpen.
907 pScanResultList - Scan result result obtained from csrScanGetResult()
908
909 \return VOID
910
911---------------------------------------------------------------------------*/
912
913static void csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
914{
915 tCsrScanResultInfo *pScanResult;
916 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
917 tpCsrNeighborRoamBSSInfo pBssInfo;
Jeff Johnson43971f52012-07-17 12:26:56 -0700918 tANI_U32 CurrAPRssi;
919 tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff;
920
921 /***************************************************************
922 * Find out the Current AP RSSI and keep it handy to check if
923 * it is better than the RSSI of the AP which we are
924 * going to roam.If so, we are going to continue with the
925 * current AP.
926 ***************************************************************/
927 CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700928
929 /* Expecting the scan result already to be in the sorted order based on the RSSI */
930 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
931 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
932 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
933 /* For now, let us take the top of the list provided as it is by the CSR Scan result API. This means it is assumed that neighbor score
934 and rssi score are in the same order. This will be taken care later */
935
936 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
937 {
938 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Scan result: BSSID : %02x:%02x:%02x:%02x:%02x:%02x"),
939 pScanResult->BssDescriptor.bssId[0],
940 pScanResult->BssDescriptor.bssId[1],
941 pScanResult->BssDescriptor.bssId[2],
942 pScanResult->BssDescriptor.bssId[3],
943 pScanResult->BssDescriptor.bssId[4],
944 pScanResult->BssDescriptor.bssId[5]);
945
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700946 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700947 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
948 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700949 /* currently associated AP. Do not have this in the roamable AP list */
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 continue;
951 }
952
Jeff Johnson43971f52012-07-17 12:26:56 -0700953 /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature
954 * is disabled and we continue to roam without any check*/
955 if(RoamRssiDiff > 0)
956 {
957 if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi))
958 {
959 /*Do not roam to an AP with worse RSSI than the current*/
960 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
961 "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d\n", __func__,
962 CurrAPRssi,
963 (int)pScanResult->BssDescriptor.rssi * (-1) );
964 continue;
965 } else {
966 /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the
967 * margin that is provided by user from the ini file (RoamRssiDiff)*/
968 if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff)
969 {
970 continue;
971 }
972 else {
973 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
974 "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d\n", __func__,
975 CurrAPRssi,
976 (int)pScanResult->BssDescriptor.rssi * (-1) );
977 }
978 }
979 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700980
981#ifdef WLAN_FEATURE_VOWIFI_11R
982 if (pNeighborRoamInfo->is11rAssoc)
983 {
984 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
985 {
986 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
987 continue;
988 }
989 }
990#endif /* WLAN_FEATURE_VOWIFI_11R */
991
992#ifdef FEATURE_WLAN_CCX
993 if (pNeighborRoamInfo->isCCXAssoc)
994 {
995 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
996 {
997 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
998 continue;
999 }
1000 }
1001 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
1002 (pScanResult->BssDescriptor.QBSSLoad_avail))
1003 {
1004 if (pNeighborRoamInfo->isVOAdmitted)
1005 {
1006 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
1007 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
1008 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
1009 {
1010 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1011 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
1012 pScanResult->BssDescriptor.bssId[0],
1013 pScanResult->BssDescriptor.bssId[1],
1014 pScanResult->BssDescriptor.bssId[2],
1015 pScanResult->BssDescriptor.bssId[3],
1016 pScanResult->BssDescriptor.bssId[4],
1017 pScanResult->BssDescriptor.bssId[5]);
1018 continue;
1019 }
1020 }
1021 }
1022 else
1023 {
1024 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
1025 if (pNeighborRoamInfo->isVOAdmitted)
1026 {
1027 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1028 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
1029 pScanResult->BssDescriptor.bssId[0],
1030 pScanResult->BssDescriptor.bssId[1],
1031 pScanResult->BssDescriptor.bssId[2],
1032 pScanResult->BssDescriptor.bssId[3],
1033 pScanResult->BssDescriptor.bssId[4],
1034 pScanResult->BssDescriptor.bssId[5]);
1035 continue;
1036 }
1037 }
1038#endif /* FEATURE_WLAN_CCX */
1039
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001040#ifdef FEATURE_WLAN_LFR
1041 // If we are supporting legacy roaming, and
1042 // if the candidate is on the "pre-auth failed" list, ignore it.
1043 if (csrRoamIsFastRoamEnabled(pMac))
1044 {
1045 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1046 {
1047 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1048 continue;
1049 }
1050 }
1051#endif /* FEATURE_WLAN_LFR */
1052
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
1054 * this result */
1055 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
1056 {
1057 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
1058 continue;
1059 }
1060
1061 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
1062 if (NULL == pBssInfo)
1063 {
1064 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
1065 continue;
1066 }
1067
1068 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1069 if (pBssInfo->pBssDescription != NULL)
1070 {
1071 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
1072 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1073 }
1074 else
1075 {
1076 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
1077 vos_mem_free(pBssInfo);
1078 continue;
1079
1080 }
1081 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
1082
1083 /* Just add to the end of the list as it is already sorted by RSSI */
1084 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
1085 }
1086
1087 /* Now we have all the scan results in our local list. Good time to free up the the list we got as a part of csrGetScanResult */
1088 csrScanResultPurge(pMac, *pScanResultList);
1089
1090 return;
1091}
1092
1093/* ---------------------------------------------------------------------------
1094
1095 \fn csrNeighborRoamHandleEmptyScanResult
1096
1097 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1098 there are no valid APs in the scan result for roaming. This means
1099 out AP is the best and no other AP is around. No point in scanning
1100 again and again. Performing the following here.
1101 1. Deregister the pre-auth callback from TL
1102 2. Stop the neighbor scan timer
1103 3. Re-register the neighbor lookup callback with increased pre-auth threshold
1104 4. Transition the state to CONNECTED state
1105
1106 \param pMac - The handle returned by macOpen.
1107
1108 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1109
1110---------------------------------------------------------------------------*/
1111static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1112{
1113 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1114 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1115 eHalStatus status = eHAL_STATUS_SUCCESS;
1116
1117 /* Stop the neighbor scan timer now */
1118 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1119 if (eHAL_STATUS_SUCCESS != status)
1120 {
1121 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1122 }
1123
1124 /* Increase the neighbor lookup threshold by a constant factor or 1 */
1125 if ((pNeighborRoamInfo->currentNeighborLookupThreshold+3) < pNeighborRoamInfo->cfgParams.neighborReassocThreshold)
1126 {
1127 pNeighborRoamInfo->currentNeighborLookupThreshold += 3;
1128 }
1129
1130
1131#ifdef WLAN_FEATURE_VOWIFI_11R
1132 /* Clear off the old neighbor report details */
1133 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1134#endif
1135
1136 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1137 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1138
1139 /* Transition to CONNECTED state */
1140 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
1141 /* Re-register Neighbor Lookup threshold callback with TL */
1142 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1143 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1144 WLANTL_HO_THRESHOLD_DOWN,
1145 csrNeighborRoamNeighborLookupDOWNCallback,
1146 VOS_MODULE_ID_SME, pMac);
1147
1148 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1149 {
1150 //err msg
1151 smsLog(pMac, LOGW, FL(" Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), status);
1152 }
1153 return vosStatus;
1154}
1155
1156/* ---------------------------------------------------------------------------
1157
1158 \fn csrNeighborRoamScanRequestCallback
1159
1160 \brief This function is the callback function registered in csrScanRequest() to
1161 indicate the completion of scan. If scan is completed for all the channels in
1162 the channel list, this function gets the scan result and starts the refresh results
1163 timer to avoid having stale results. If scan is not completed on all the channels,
1164 it restarts the neighbor scan timer which on expiry issues scan on the next
1165 channel
1166
1167 \param halHandle - The handle returned by macOpen.
1168 pContext - not used
1169 scanId - not used
1170 status - not used
1171
1172 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1173
1174---------------------------------------------------------------------------*/
1175static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1176 tANI_U32 scanId, eCsrScanStatus status)
1177{
1178 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1179 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1180 tANI_U8 currentChanIndex;
1181 tCsrScanResultFilter scanFilter;
1182 tScanResultHandle scanResult;
1183 tANI_U32 tempVal = 0;
Jeff Johnson43971f52012-07-17 12:26:56 -07001184 eHalStatus hstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001185
1186 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1187
1188 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1189 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1190 {
1191 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1192 return eHAL_STATUS_SUCCESS;
1193 }
1194
1195 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1196 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1197
1198 /* Validate inputs */
1199 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1200 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1201 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1202 }
1203 else
1204 {
1205 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1206 return eHAL_STATUS_SUCCESS;
1207 }
1208
1209 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1210 {
1211 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1212 just to get the results and perform PREAUTH */
1213 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1214 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1215 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1216 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1217
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1220 should use the BSSID filter made out of neighbor reports */
1221 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1222 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001223 hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1224 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R or CCX Association: Prepare scan filter status with neighbor AP = %d"), hstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 tempVal = 1;
1226 }
1227 else
1228#endif
1229 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001230 hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1231 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R/CCX/Other Association: Prepare scan to find neighbor AP filter status = %d"), hstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001233 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001234 {
1235 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1236 return eHAL_STATUS_FAILURE;
1237 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001238 hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult);
1239 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 /* Process the scan results and update roamable AP list */
1241 csrNeighborRoamProcessScanResults(pMac, &scanResult);
1242
1243 /* Free the scan filter */
1244 csrFreeScanFilter(pMac, &scanFilter);
1245
1246 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1247
1248 switch(pNeighborRoamInfo->neighborRoamState)
1249 {
1250 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1251 if (tempVal)
1252 {
1253#ifdef WLAN_FEATURE_VOWIFI_11R
1254 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1255 APs in the roamable AP list */
1256 if (pNeighborRoamInfo->is11rAssoc)
1257 {
1258 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1259 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1260 }
1261 else
1262#endif
1263#ifdef FEATURE_WLAN_CCX
1264 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1265 APs in the roamable AP list */
1266 if (pNeighborRoamInfo->isCCXAssoc)
1267 {
1268 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1269 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1270 }
1271 else
1272#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001273#ifdef FEATURE_WLAN_LFR
1274 /* If LFR is enabled, then we can register the reassoc callback here as we have some
1275 APs in the roamable AP list */
1276 if (csrRoamIsFastRoamEnabled(pMac))
1277 {
1278 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1279 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1280 }
1281 else
1282#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001283 {
1284
1285 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1286 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1287 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1288 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1289 within certain duration */
1290
1291// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1292 }
1293 }
1294 else
1295 {
1296 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1297 /* Handle it appropriately */
1298 csrNeighborRoamHandleEmptyScanResult(pMac);
1299 }
1300 break;
1301#ifdef WLAN_FEATURE_VOWIFI_11R
1302 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1303 if (!tempVal)
1304 {
1305 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1306 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1307 csrNeighborRoamTransitToCFGChanScan(pMac);
1308 }
1309 break;
1310#endif /* WLAN_FEATURE_VOWIFI_11R */
1311 default:
1312 // Can come only in INIT state. Where in we are associated, we sent scan and user
1313 // in the meantime decides to disassoc, we will be in init state and still received call
1314 // back issued. Should not come here in any other state, printing just in case
1315 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1316 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1317
1318 // Lets just exit out silently.
1319 return eHAL_STATUS_SUCCESS;
1320 }
1321
1322 if (tempVal)
1323 {
1324 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1325
1326 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1327 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1328 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1329 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1330 eANI_BOOLEAN_FALSE))
1331 {
1332 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1333 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1334 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001335 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001336 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001337
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1339 /* Register a reassoc Indication callback */
1340 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1341 WLANTL_HO_THRESHOLD_DOWN,
1342 csrNeighborRoamReassocIndCallback,
1343 VOS_MODULE_ID_SME, pMac);
1344
1345 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1346 {
1347 //err msg
1348 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1349 }
1350
1351 }
1352 }
1353 else
1354 {
1355
1356 /* Restart the timer for the next scan sequence as scanning is not over */
Jeff Johnson43971f52012-07-17 12:26:56 -07001357 hstatus = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
Jeff Johnson295189b2012-06-20 16:38:30 -07001358 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1359 eANI_BOOLEAN_FALSE);
1360
Jeff Johnson43971f52012-07-17 12:26:56 -07001361 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001362 {
1363 /* Timer start failed.. Should we ASSERT here??? */
1364 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1365 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1366 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001367 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001368 }
1369 }
1370 return eHAL_STATUS_SUCCESS;
1371}
1372
1373/* ---------------------------------------------------------------------------
1374
1375 \fn csrNeighborRoamIssueBgScanRequest
1376
1377 \brief This function issues CSR scan request after populating all the BG scan params
1378 passed
1379
1380 \param pMac - The handle returned by macOpen.
1381 pBgScanParams - Params that need to be populated into csr Scan request
1382
1383 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1384
1385---------------------------------------------------------------------------*/
1386eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1387{
1388 eHalStatus status = eHAL_STATUS_SUCCESS;
1389 tANI_U32 scanId;
1390 tCsrScanRequest scanReq;
1391 tANI_U8 channel;
1392
1393 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
1394 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1395
1396
1397 //send down the scan req for 1 channel on the associated SSID
1398 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1399 /* Fill in the SSID Info */
1400 scanReq.SSIDs.numOfSSIDs = 1;
1401 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1402 if(NULL == scanReq.SSIDs.SSIDList)
1403 {
1404 //err msg
1405 smsLog(pMac, LOGW, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List\n"));
1406 return eHAL_STATUS_FAILURE;
1407 }
1408 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1409
1410 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1411 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1412 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1413
1414 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1415
1416 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1417 scanReq.ChannelInfo.ChannelList = &channel;
1418
1419 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1420 scanReq.scanType = eSIR_ACTIVE_SCAN;
1421 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1422 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1423 scanReq.minChnTime = pBgScanParams->minChnTime;
1424 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1425 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1426 if (eHAL_STATUS_SUCCESS != status)
1427 {
1428 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1429 vos_mem_free(scanReq.SSIDs.SSIDList);
1430 return status;
1431 }
1432 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1433
1434 vos_mem_free(scanReq.SSIDs.SSIDList);
1435 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x, Actual index = %d"),
1436 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1437 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1438 return status;
1439}
1440
1441/* ---------------------------------------------------------------------------
1442
1443 \fn csrNeighborRoamPerformBgScan
1444
1445 \brief This function is invoked on every expiry of neighborScanTimer till all
1446 the channels in the channel list are scanned. It populates necessary
1447 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1448 request
1449
1450 \param pMac - The handle returned by macOpen.
1451
1452 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1453
1454---------------------------------------------------------------------------*/
1455eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1456{
1457 eHalStatus status = eHAL_STATUS_SUCCESS;
1458 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1459 tCsrBGScanRequest bgScanParams;
1460 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1461 tANI_U8 channel = 0;
1462
1463 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1464 {
1465 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
1466 }
1467 else
1468 {
1469 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
1470 // Go back and restart. Mostly timer start failure has occured.
1471 // When timer start is declared a failure, then we delete the list.
1472 // Should not happen now as we stop and then only start the scan timer.
1473 // still handle the unlikely case.
1474 csrNeighborRoamHandleEmptyScanResult(pMac);
1475 return status;
1476 }
1477 /* Need to perform scan here before getting the list */
1478 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1479 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1480 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1481 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1482
1483 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1484 bgScanParams.ChannelInfo.numOfChannels = 1;
1485 bgScanParams.ChannelInfo.ChannelList = &channel;
1486
1487 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1488 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1489
1490 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1491 if (eHAL_STATUS_SUCCESS != status)
1492 {
1493 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1494 return status;
1495 }
1496
1497 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1498 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1499 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1500 {
1501 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
1502 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1503 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1504 /* We have completed scanning all the channels */
1505 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1506 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1507 and select the best AP in the list */
1508 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1509 {
1510 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1511 }
1512 }
1513
1514 return status;
1515}
1516
1517/* ---------------------------------------------------------------------------
1518
1519 \fn csrNeighborRoamNeighborScanTimerCallback
1520
1521 \brief This function is the neighbor scan timer callback function. It invokes
1522 the BG scan request based on the current and previous states
1523
1524 \param pv - CSR timer context info which includes pMac and session ID
1525
1526 \return VOID
1527
1528---------------------------------------------------------------------------*/
1529void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1530{
1531 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1532 tpAniSirGlobal pMac = pInfo->pMac;
1533 tANI_U32 sessionId = pInfo->sessionId;
1534 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1535
1536 // check if bg scan is on going, no need to send down the new params if true
1537 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1538 {
1539 //msg
1540 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1541 return;
1542 }
1543
1544 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1545
1546 switch (pNeighborRoamInfo->neighborRoamState)
1547 {
1548#ifdef WLAN_FEATURE_VOWIFI_11R
1549 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1550 switch(pNeighborRoamInfo->prevNeighborRoamState)
1551 {
1552 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1553 csrNeighborRoamPerformBgScan(pMac);
1554 break;
1555 default:
1556 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1557 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1558 break;
1559 }
1560 break;
1561#endif /* WLAN_FEATURE_VOWIFI_11R */
1562 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1563 csrNeighborRoamPerformBgScan(pMac);
1564 break;
1565 default:
1566 break;
1567 }
1568 return;
1569}
1570
1571/* ---------------------------------------------------------------------------
1572
1573 \fn csrNeighborRoamResultsRefreshTimerCallback
1574
1575 \brief This function is the timer callback function for results refresh timer.
1576 When this is invoked, it is as good as down event received from TL. So,
1577 clear off the roamable AP list and start the scan procedure based on 11R
1578 or non-11R association
1579
1580 \param context - CSR timer context info which includes pMac and session ID
1581
1582 \return VOID
1583
1584---------------------------------------------------------------------------*/
1585void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1586{
1587 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1588 tpAniSirGlobal pMac = pInfo->pMac;
1589 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1590 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1591
1592 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1593
1594 /* Deregister reassoc callback. Ignore return status */
1595 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1596 WLANTL_HO_THRESHOLD_DOWN,
1597 csrNeighborRoamReassocIndCallback,
1598 VOS_MODULE_ID_SME);
1599
1600 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1601 {
1602 //err msg
1603 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1604 }
1605
1606 /* Reset all the variables just as no scan had happened before */
1607 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1608
1609#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1610 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1611 {
1612 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1613 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1614 if (VOS_STATUS_SUCCESS != vosStatus)
1615 {
1616 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1617 return;
1618 }
1619 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1620 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1621 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1622 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1623 }
1624 else
1625#endif
1626 {
1627 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1628 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1629 if (VOS_STATUS_SUCCESS != vosStatus)
1630 {
1631 return;
1632 }
1633 }
1634 return;
1635}
1636
1637#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1638/* ---------------------------------------------------------------------------
1639
1640 \fn csrNeighborRoamIssueNeighborRptRequest
1641
1642 \brief This function is invoked when TL issues a down event and the current assoc
1643 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1644 the currently associated AP with the current SSID
1645
1646 \param pMac - The handle returned by macOpen.
1647
1648 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1649
1650---------------------------------------------------------------------------*/
1651VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1652{
1653 tRrmNeighborRspCallbackInfo callbackInfo;
1654 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1655 tRrmNeighborReq neighborReq;
1656
1657
1658 neighborReq.no_ssid = 0;
1659
1660 /* Fill in the SSID */
1661 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1662 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1663 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1664
1665 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
1666 callbackInfo.neighborRspCallbackContext = pMac;
1667 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
1668
1669 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
1670}
1671
1672/* ---------------------------------------------------------------------------
1673
1674 \fn csrNeighborRoamCreateChanListFromNeighborReport
1675
1676 \brief This function is invoked when neighbor report is received for the
1677 neighbor request. Based on the channels present in the neighbor report,
1678 it generates channel list which will be used in REPORT_SCAN state to
1679 scan for these neighbor APs
1680
1681 \param pMac - The handle returned by macOpen.
1682
1683 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1684
1685---------------------------------------------------------------------------*/
1686VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
1687{
1688 tpRrmNeighborReportDesc pNeighborBssDesc;
1689 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1690 tANI_U8 numChannels = 0, i = 0, j=0;
1691 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1692
1693 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
1694 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
1695
1696 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
1697
1698 while (pNeighborBssDesc)
1699 {
1700 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
1701
1702 /* Update the neighbor BSS Info in the 11r FT Roam Info */
1703 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
1704 pNeighborBssDesc->pNeighborBssDescription->channel;
1705 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
1706 (tANI_U8)pNeighborBssDesc->roamScore;
1707 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
1708 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
1709 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
1710
1711 /* Saving the channel list non-redundantly */
1712 if (numChannels > 0)
1713 {
1714 for (i = 0; i < numChannels; i++)
1715 {
1716 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
1717 break;
1718 }
1719
1720 }
1721 if (i == numChannels)
1722 {
1723 if (pNeighborBssDesc->pNeighborBssDescription->channel)
1724 {
1725 // Make sure to add only if its the same band
1726 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1727 (pNeighborBssDesc->pNeighborBssDescription->channel <= (RF_CHAN_14+1)))
1728 {
1729 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1730 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1731 pNeighborBssDesc->pNeighborBssDescription->channel);
1732 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1733 numChannels++;
1734 }
1735 else if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1736 (pNeighborBssDesc->pNeighborBssDescription->channel >= RF_CHAN_128))
1737 {
1738 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1739 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1740 pNeighborBssDesc->pNeighborBssDescription->channel);
1741 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1742 numChannels++;
1743 }
1744 }
1745 }
1746
1747 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
1748 }
1749
1750 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1751 {
1752 // Before we free the existing channel list for a safety net make sure
1753 // we have a union of the IAPP and the already existing list.
1754 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
1755 {
1756 for (j = 0; j < numChannels; j++)
1757 {
1758 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] == channelList[j])
1759 break;
1760 }
1761 if (j == numChannels)
1762 {
1763 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i])
1764 {
1765 // Make sure to add only if its the same band
1766 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1767 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] <= (RF_CHAN_14+1)))
1768 {
1769 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1770 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1771 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1772 channelList[numChannels] =
1773 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1774 numChannels++;
1775 }
1776 if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1777 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] >= RF_CHAN_128))
1778 {
1779 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1780 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1781 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1782 channelList[numChannels] =
1783 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1784 numChannels++;
1785 }
1786 }
1787 }
1788 }
1789 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1790 }
1791
1792 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1793 /* Store the obtained channel list to the Neighbor Control data structure */
1794 if (numChannels)
1795 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
1796 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1797 {
1798 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1799 return VOS_STATUS_E_RESOURCES;
1800 }
1801
1802 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1803 channelList, (numChannels) * sizeof(tANI_U8));
1804 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
1805 if (numChannels)
1806 {
1807 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
1808 pNeighborRoamInfo->neighborRoamState);
1809 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
1810 }
1811 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1812 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1813
1814 return VOS_STATUS_SUCCESS;
1815}
1816
1817/* ---------------------------------------------------------------------------
1818
1819 \fn csrNeighborRoamRRMNeighborReportResult
1820
1821 \brief This function is the neighbor report callback that will be invoked by
1822 SME RRM on receiving a neighbor report or of neighbor report is not
1823 received after timeout. On receiving a valid report, it generates a
1824 channel list from the neighbor report and starts the
1825 neighbor scan timer
1826
1827 \param context - The handle returned by macOpen.
1828 vosStatus - Status of the callback(SUCCESS/FAILURE)
1829
1830 \return VOID
1831
1832---------------------------------------------------------------------------*/
1833void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
1834{
1835 tpAniSirGlobal pMac = PMAC_STRUCT(context);
1836 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1837 eHalStatus status = eHAL_STATUS_SUCCESS;
1838
1839 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
1840 switch (pNeighborRoamInfo->neighborRoamState)
1841 {
1842 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1843 /* Reset the report pending variable */
1844 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
1845 if (VOS_STATUS_SUCCESS == vosStatus)
1846 {
1847 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
1848 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
1849 if (VOS_STATUS_SUCCESS == vosStatus)
1850 {
1851 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
1852 }
1853
1854 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1855 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1856
1857 /* Now ready for neighbor scan based on the channel list created */
1858 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1859 what palTimerStart expects */
1860 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1861 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1862 eANI_BOOLEAN_FALSE);
1863 if (eHAL_STATUS_SUCCESS != status)
1864 {
1865 /* Timer start failed.. Should we ASSERT here??? */
1866 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
1867 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1868 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1869 return;
1870 }
1871 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1872 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
1873 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1874 }
1875 else
1876 {
1877 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
1878 reach the maxNeighborRetries or receiving a successful neighbor response */
1879 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
1880 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
1881 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
1882 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
1883 {
1884 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
1885 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1886 if (VOS_STATUS_SUCCESS != vosStatus)
1887 {
1888 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
1889 return;
1890 }
1891 /* We transitioned to different state now. Reset the Neighbor report retry count */
1892 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1893 }
1894 else
1895 {
1896 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1897 if (VOS_STATUS_SUCCESS != vosStatus)
1898 {
1899 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1900 return;
1901 }
1902 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1903 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1904 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1905 }
1906 }
1907 break;
1908 default:
1909 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
1910 break;
1911 }
1912 return;
1913}
1914#endif /* WLAN_FEATURE_VOWIFI_11R */
1915
1916
1917/* ---------------------------------------------------------------------------
1918
1919 \fn csrNeighborRoamTransitToCFGChanScan
1920
1921 \brief This function is called whenever there is a transition to CFG chan scan
1922 state from any state. It frees up the current channel list and allocates
1923 a new memory for the channels received from CFG item. It then starts the
1924 neighbor scan timer to perform the scan on each channel one by one
1925
1926 \param pMac - The handle returned by macOpen.
1927
1928 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1929
1930---------------------------------------------------------------------------*/
1931VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
1932{
1933 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1934 eHalStatus status = eHAL_STATUS_SUCCESS;
1935 int i = 0;
1936 int numOfChannels = 0;
1937 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1938
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001939 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07001940#ifdef FEATURE_WLAN_CCX
1941 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001942 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
1944#endif // CCX
1945 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels == 0)
1946
1947 {
1948 smsLog(pMac, LOGW, FL("Falling back to CFG channel list"));
1949
1950
1951 /* Free up the channel list and allocate a new memory. This is because we dont know how much
1952 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
1953 result in memory corruption */
1954 if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1955 {
1956 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1957 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1958 }
1959 // Find the right subset of the cfg list based on the current band we are on.
1960 for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
1961 {
1962 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i])
1963 {
1964 // Make sure to add only if its the same band
1965 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1966 (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i] <= (RF_CHAN_14+1)))
1967 {
1968 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1969 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1970 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
1971 channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
1972 numOfChannels++;
1973 }
1974 if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1975 (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i] >= RF_CHAN_128))
1976 {
1977 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1978 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1979 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
1980 channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
1981 numOfChannels++;
1982 }
1983 }
1984 }
1985
1986 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
1987 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1988 if (numOfChannels)
1989 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc(numOfChannels);
1990
1991 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1992 {
1993 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1994 return VOS_STATUS_E_RESOURCES;
1995 }
1996
1997 /* Since this is a legacy case, copy the channel list from CFG here */
1998 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1999 channelList, numOfChannels * sizeof(tANI_U8));
2000
2001 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
2002 {
2003 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG = %d\n",
2004 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
2005 }
2006 }
2007
2008 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2009 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2010
2011 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2012 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2013 what palTimerStart expects */
2014 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2015 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2016 eANI_BOOLEAN_FALSE);
2017
2018 if (eHAL_STATUS_SUCCESS != status)
2019 {
2020 /* Timer start failed.. */
2021 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
2022 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2023 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2024 return VOS_STATUS_E_FAILURE;
2025 }
2026
2027 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2028 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
2029
2030 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2031 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2032
2033 return VOS_STATUS_SUCCESS;
2034}
2035
2036/* ---------------------------------------------------------------------------
2037
2038 \fn csrNeighborRoamNeighborLookupUpEvent
2039
2040 \brief This function is called as soon as TL indicates that the current AP's
2041 RSSI is better than the neighbor lookup threshold. Here, we transition to
2042 CONNECTED state and reset all the scan parameters
2043
2044 \param pMac - The handle returned by macOpen.
2045
2046 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2047
2048---------------------------------------------------------------------------*/
2049VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2050{
2051 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2052 VOS_STATUS vosStatus;
2053
2054 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2055 /* Deregister the UP event now */
2056 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2057 WLANTL_HO_THRESHOLD_UP,
2058 csrNeighborRoamNeighborLookupUPCallback,
2059 VOS_MODULE_ID_SME);
2060
2061 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2062 {
2063 //err msg
2064 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
2065 }
2066
2067 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2068 /* Deregister the UP event now */
2069 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2070 WLANTL_HO_THRESHOLD_DOWN,
2071 csrNeighborRoamNeighborLookupDOWNCallback,
2072 VOS_MODULE_ID_SME);
2073
2074 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2075 {
2076 //err msg
2077 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
2078 }
2079
2080 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
2081 /* Deregister reassoc callback. */
2082 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
2083 WLANTL_HO_THRESHOLD_DOWN,
2084 csrNeighborRoamReassocIndCallback,
2085 VOS_MODULE_ID_SME);
2086
2087 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2088 {
2089 //err msg
2090 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
2091 }
2092
2093
2094 /* RSSI got better than the CFG neighbor lookup threshold. Reset the threshold to older value and set the increment multiplier to 0 */
2095 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2096
2097 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
2098
2099 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2100 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2101
2102 /* Recheck whether the below check is needed. */
2103 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2104 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2105
2106 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2107 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2108 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2109 WLANTL_HO_THRESHOLD_DOWN,
2110 csrNeighborRoamNeighborLookupDOWNCallback,
2111 VOS_MODULE_ID_SME, pMac);
2112 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2113 {
2114 //err msg
2115 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2116 }
2117
2118
2119 return vosStatus;
2120}
2121
2122/* ---------------------------------------------------------------------------
2123
2124 \fn csrNeighborRoamNeighborLookupDownEvent
2125
2126 \brief This function is called as soon as TL indicates that the current AP's
2127 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2128 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2129 a non-11R association.
2130
2131 \param pMac - The handle returned by macOpen.
2132
2133 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2134
2135---------------------------------------------------------------------------*/
2136VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2137{
2138 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2139 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2140 eHalStatus status = eHAL_STATUS_SUCCESS;
2141
2142 switch (pNeighborRoamInfo->neighborRoamState)
2143 {
2144 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2145
2146 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2147 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2148 /* De-register Neighbor Lookup threshold callback with TL */
2149 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2150 WLANTL_HO_THRESHOLD_DOWN,
2151 csrNeighborRoamNeighborLookupDOWNCallback,
2152 VOS_MODULE_ID_SME);
2153
2154 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2155 {
2156 //err msg
2157 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), status);
2158 }
2159
2160
2161#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2162 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2163 {
2164
2165 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2166 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2167 if (VOS_STATUS_SUCCESS != vosStatus)
2168 {
2169 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2170 return vosStatus;
2171 }
2172 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2173 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2174 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2175 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2176 }
2177 else
2178#endif
2179 {
2180 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2181
2182 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2183 if (VOS_STATUS_SUCCESS != vosStatus)
2184 {
2185 return vosStatus;
2186 }
2187 }
2188 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2189 /* Register Neighbor Lookup threshold callback with TL for UP event now */
2190 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2191 WLANTL_HO_THRESHOLD_UP,
2192 csrNeighborRoamNeighborLookupUPCallback,
2193 VOS_MODULE_ID_SME, pMac);
2194 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2195 {
2196 //err msg
2197 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
2198 }
2199 break;
2200 default:
2201 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2202 break;
2203
2204 }
2205 return vosStatus;
2206}
2207
2208/* ---------------------------------------------------------------------------
2209
2210 \fn csrNeighborRoamNeighborLookupUPCallback
2211
2212 \brief This function is registered with TL to indicate whenever the RSSI
2213 gets better than the neighborLookup RSSI Threshold
2214
2215 \param pAdapter - VOS Context
2216 trafficStatus - UP/DOWN indication from TL
2217 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2218
2219 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2220
2221---------------------------------------------------------------------------*/
2222VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2223 v_PVOID_t pUserCtxt)
2224{
2225 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2226 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2227 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2228
2229 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
2230
2231 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2232 {
2233 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2234 return VOS_STATUS_SUCCESS;
2235 }
2236
2237 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2238 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2239 return vosStatus;
2240}
2241
2242/* ---------------------------------------------------------------------------
2243
2244 \fn csrNeighborRoamNeighborLookupDOWNCallback
2245
2246 \brief This function is registered with TL to indicate whenever the RSSI
2247 falls below the current neighborLookup RSSI Threshold
2248
2249 \param pAdapter - VOS Context
2250 trafficStatus - UP/DOWN indication from TL
2251 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2252
2253 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2254
2255---------------------------------------------------------------------------*/
2256VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2257 v_PVOID_t pUserCtxt)
2258{
2259 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2260 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2261 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2262
2263 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
2264
2265 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2266 {
2267 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2268 return VOS_STATUS_SUCCESS;
2269 }
2270
2271 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2272 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2273
2274 return vosStatus;
2275}
2276
2277#ifdef RSSI_HACK
2278extern int dumpCmdRSSI;
2279#endif
2280
2281/* ---------------------------------------------------------------------------
2282
2283 \fn csrNeighborRoamIndicateDisconnect
2284
2285 \brief This function is called by CSR as soon as the station disconnects from
2286 the AP. This function does the necessary cleanup of neighbor roam data
2287 structures. Neighbor roam state transitions to INIT state whenever this
2288 function is called except if the current state is REASSOCIATING
2289
2290 \param pMac - The handle returned by macOpen.
2291 sessionId - CSR session id that got disconnected
2292
2293 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2294
2295---------------------------------------------------------------------------*/
2296eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2297{
2298 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2299
2300 smsLog(pMac, LOGE, FL("Disconnect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2301
2302#ifdef FEATURE_WLAN_CCX
2303 {
2304 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2305 if (pSession->connectedProfile.isCCXAssoc)
2306 {
2307 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2308 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2309 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2310 pSession->isPrevApInfoValid = TRUE;
2311 pSession->roamTS1 = vos_timer_get_system_time();
2312
2313 }
2314 }
2315#endif
2316
2317#ifdef RSSI_HACK
2318 dumpCmdRSSI = -40;
2319#endif
2320 switch (pNeighborRoamInfo->neighborRoamState)
2321 {
2322 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2323 // Stop scan and neighbor refresh timers.
2324 // These are indeed not required when we are in reassociating
2325 // state.
2326 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2327 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2328 break;
2329
2330 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2331 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Ignoring disconnect event in INIT state"));
2332 csrNeighborRoamResetInitStateControlInfo(pMac);
2333 break;
2334
2335 default:
2336 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2337 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Transitioning to INIT state"));
2338 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2339 }
2340 return eHAL_STATUS_SUCCESS;
2341}
2342
2343/* ---------------------------------------------------------------------------
2344
2345 \fn csrNeighborRoamIndicateConnect
2346
2347 \brief This function is called by CSR as soon as the station connects to an AP.
2348 This initializes all the necessary data structures related to the
2349 associated AP and transitions the state to CONNECTED state
2350
2351 \param pMac - The handle returned by macOpen.
2352 sessionId - CSR session id that got connected
2353 vosStatus - connect status SUCCESS/FAILURE
2354
2355 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2356
2357---------------------------------------------------------------------------*/
2358eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2359{
2360 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2361 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002362 VOS_STATUS vstatus;
2363
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002365 int init_ft_flag = FALSE;
2366#endif
2367
2368 smsLog(pMac, LOGE, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2369
2370 switch (pNeighborRoamInfo->neighborRoamState)
2371 {
2372 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2373 if (VOS_STATUS_SUCCESS != vosStatus)
2374 {
2375 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2376 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2377 break;
2378 }
2379 /* Fall through if the status is SUCCESS */
2380 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2381 /* Reset all the data structures here */
2382 csrNeighborRoamResetInitStateControlInfo(pMac);
2383
2384 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2385
2386 pNeighborRoamInfo->csrSessionId = sessionId;
2387 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2388 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2389 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2390 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2391 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
2392
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002393#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002394 /* Now we can clear the preauthDone that was saved as we are connected afresh */
2395 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2396#endif
2397
2398#ifdef WLAN_FEATURE_VOWIFI_11R
2399 // Based on the auth scheme tell if we are 11r
2400 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType ) )
2401 {
2402 if (pMac->roam.configParam.isFastTransitionEnabled)
2403 init_ft_flag = TRUE;
2404 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
2405 }
2406 else
2407 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
2408 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
2409#endif
2410
2411#ifdef FEATURE_WLAN_CCX
2412 // Based on the auth scheme tell if we are 11r
2413 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
2414 {
2415 if (pMac->roam.configParam.isFastTransitionEnabled)
2416 init_ft_flag = TRUE;
2417 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
2418 }
2419 else
2420 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
2421 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("isCCXAssoc is = %d"), pNeighborRoamInfo->isCCXAssoc);
2422 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
2423 "ccx=%d ft=%d\n", pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
2424
2425#endif
2426
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002427#ifdef FEATURE_WLAN_LFR
2428 // If "Legacy Fast Roaming" is enabled
2429 if (csrRoamIsFastRoamEnabled(pMac))
2430 {
2431 init_ft_flag = TRUE;
2432 }
2433#endif
2434
2435#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 if ( init_ft_flag == TRUE )
2437 {
2438 /* Initialize all the data structures needed for the 11r FT Preauth */
2439 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
2440 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
2441 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2442 csrNeighborRoamPurgePreauthFailedList(pMac);
2443
2444 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
2445 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07002446 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 WLANTL_HO_THRESHOLD_DOWN,
2448 csrNeighborRoamNeighborLookupDOWNCallback,
2449 VOS_MODULE_ID_SME, pMac);
2450
Jeff Johnson43971f52012-07-17 12:26:56 -07002451 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002452 {
2453 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07002454 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
2455 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 }
2457 }
2458#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002459 break;
2460 default:
2461 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2462 break;
2463 }
2464 return status;
2465}
2466
2467
2468#ifdef WLAN_FEATURE_VOWIFI_11R
2469/* ---------------------------------------------------------------------------
2470
2471 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
2472
2473 \brief If this function is invoked, that means the preauthentication response
2474 is timed out from the PE. Preauth rsp handler is called with status as
2475 TIMEOUT
2476
2477 \param context - CSR Timer info which holds pMac and session ID
2478
2479 \return VOID
2480
2481---------------------------------------------------------------------------*/
2482void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
2483{
2484 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
2485 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
2486 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2487
2488 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
2489
2490 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
2491}
2492
2493/* ---------------------------------------------------------------------------
2494
2495 \fn csrNeighborRoamPurgePreauthFailedList
2496
2497 \brief This function purges all the MAC addresses in the pre-auth fail list
2498
2499 \param pMac - The handle returned by macOpen.
2500
2501 \return VOID
2502
2503---------------------------------------------------------------------------*/
2504void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
2505{
2506 tANI_U8 i;
2507
2508 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
2509 {
2510 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
2511 }
2512 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
2513
2514 return;
2515}
2516
2517/* ---------------------------------------------------------------------------
2518
2519 \fn csrNeighborRoamInit11rAssocInfo
2520
2521 \brief This function initializes 11r related neighbor roam data structures
2522
2523 \param pMac - The handle returned by macOpen.
2524
2525 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2526
2527---------------------------------------------------------------------------*/
2528eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
2529{
2530 eHalStatus status;
2531 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
2532
2533 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
2534 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
2535 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
2536 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
2537 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
2538 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
2539
2540 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
2541 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2542 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
2543 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
2544
2545 if (eHAL_STATUS_SUCCESS != status)
2546 {
2547 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2548 return eHAL_STATUS_RESOURCES;
2549 }
2550
2551 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2552 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2553 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2554 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2555
2556
2557 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
2558 if (eHAL_STATUS_SUCCESS != status)
2559 {
2560 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
2561 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
2562 return eHAL_STATUS_RESOURCES;
2563 }
2564 return status;
2565}
2566#endif /* WLAN_FEATURE_VOWIFI_11R */
2567
2568/* ---------------------------------------------------------------------------
2569
2570 \fn csrNeighborRoamInit
2571
2572 \brief This function initializes neighbor roam data structures
2573
2574 \param pMac - The handle returned by macOpen.
2575
2576 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2577
2578---------------------------------------------------------------------------*/
2579eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
2580{
2581 eHalStatus status;
2582 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2583
2584 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2585 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2586 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
2587 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
2588 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
2589 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
2590 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
2591 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
2592 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
2593 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
2594
2595 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
2596 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
2597
2598 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
2599 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2600
2601 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2602 {
2603 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
2604 return eHAL_STATUS_RESOURCES;
2605 }
2606
2607 /* Update the roam global structure from CFG */
2608 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2609 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
2610 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2611
2612 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
2613 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
2614 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2615 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
2616
2617 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2618 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2619 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
2620 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2621
2622 if (eHAL_STATUS_SUCCESS != status)
2623 {
2624 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2625 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2626 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2627 return eHAL_STATUS_RESOURCES;
2628 }
2629
2630 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
2631 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2632
2633 if (eHAL_STATUS_SUCCESS != status)
2634 {
2635 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2636 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2637 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2638 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2639 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2640 return eHAL_STATUS_RESOURCES;
2641 }
2642
2643 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
2644 if (eHAL_STATUS_SUCCESS != status)
2645 {
2646 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2647 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2648 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2649 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2650 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2651 return eHAL_STATUS_RESOURCES;
2652 }
2653
2654 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2655 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2656 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2657 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2658 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2659
2660#ifdef WLAN_FEATURE_VOWIFI_11R
2661 status = csrNeighborRoamInit11rAssocInfo(pMac);
2662 if (eHAL_STATUS_SUCCESS != status)
2663 {
2664 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2665 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2666 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2667 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2668 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2669 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2670 return eHAL_STATUS_RESOURCES;
2671 }
2672#endif
2673 /* Initialize this with the current tick count */
2674 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2675
2676 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2677
2678 return eHAL_STATUS_SUCCESS;
2679}
2680
2681/* ---------------------------------------------------------------------------
2682
2683 \fn csrNeighborRoamClose
2684
2685 \brief This function closes/frees all the neighbor roam data structures
2686
2687 \param pMac - The handle returned by macOpen.
2688
2689 \return VOID
2690
2691---------------------------------------------------------------------------*/
2692void csrNeighborRoamClose(tpAniSirGlobal pMac)
2693{
2694 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2695
2696 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
2697 {
2698 smsLog(pMac, LOGE, FL("Neighbor Roam Algorithm Already Closed\n"));
2699 return;
2700 }
2701
2702 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2703 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2704
2705 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2706
2707 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
2708 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2709 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2710 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2711
2712 /* Should free up the nodes in the list before closing the double Linked list */
2713 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
2714 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2715
2716 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2717 {
2718 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2719 }
2720
2721 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2722 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2723 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2724 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2725 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2726 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2727
2728 /* Free the profile.. */
2729 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2730
2731#ifdef WLAN_FEATURE_VOWIFI_11R
2732 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2733 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
2734 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
2735 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2736 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2737 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2738 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2739 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2740 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2741#endif /* WLAN_FEATURE_VOWIFI_11R */
2742
2743 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
2744
2745 return;
2746}
2747
2748/* ---------------------------------------------------------------------------
2749
2750 \fn csrNeighborRoamRequestHandoff
2751
2752 \brief This function triggers actual switching from one AP to the new AP.
2753 It issues disassociate with reason code as Handoff and CSR as a part of
2754 handling disassoc rsp, issues reassociate to the new AP
2755
2756 \param pMac - The handle returned by macOpen.
2757
2758 \return VOID
2759
2760---------------------------------------------------------------------------*/
2761void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
2762{
2763
2764 tCsrRoamInfo roamInfo;
2765 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2766 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
2767 tCsrNeighborRoamBSSInfo handoffNode;
2768 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
2769 tANI_U32 roamId = 0;
2770
2771 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
2772 {
2773 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
2774 pMac->roam.neighborRoamInfo.neighborRoamState);
2775 return;
2776 }
2777
2778 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2779 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
2780 eSIR_SME_SUCCESS);
2781
2782 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2783 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
2784
2785 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
2786 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
2787 handoffNode.pBssDescription->bssId[0],
2788 handoffNode.pBssDescription->bssId[1],
2789 handoffNode.pBssDescription->bssId[2],
2790 handoffNode.pBssDescription->bssId[3],
2791 handoffNode.pBssDescription->bssId[4],
2792 handoffNode.pBssDescription->bssId[5]);
2793
2794 /* Free the profile.. Just to make sure we dont leak memory here */
2795 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2796 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
2797 This should happen before issuing disconnect */
2798 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
2799 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
2800 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
2801
2802 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
2803
2804 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
2805 {
2806 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
2807 return;
2808 }
2809
2810 //notify HDD for handoff, providing the BSSID too
2811 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
2812
2813 vos_mem_copy(roamInfo.bssid,
2814 handoffNode.pBssDescription->bssId,
2815 sizeof( tCsrBssid ));
2816
2817 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
2818
2819
2820 return;
2821}
2822
2823/* ---------------------------------------------------------------------------
2824
2825 \fn csrNeighborRoamIsHandoffInProgress
2826
2827 \brief This function returns whether handoff is in progress or not based on
2828 the current neighbor roam state
2829
2830 \param pMac - The handle returned by macOpen.
2831 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
2832
2833 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
2834
2835---------------------------------------------------------------------------*/
2836tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
2837{
2838 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
2839 return eANI_BOOLEAN_TRUE;
2840
2841 return eANI_BOOLEAN_FALSE;
2842}
2843
2844#ifdef WLAN_FEATURE_VOWIFI_11R
2845/* ---------------------------------------------------------------------------
2846
2847 \fn csrNeighborRoamIs11rAssoc
2848
2849 \brief This function returns whether the current association is a 11r assoc or not
2850
2851 \param pMac - The handle returned by macOpen.
2852
2853 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
2854
2855---------------------------------------------------------------------------*/
2856tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
2857{
2858 return pMac->roam.neighborRoamInfo.is11rAssoc;
2859}
2860#endif /* WLAN_FEATURE_VOWIFI_11R */
2861
2862
2863/* ---------------------------------------------------------------------------
2864
2865 \fn csrNeighborRoamGetHandoffAPInfo
2866
2867 \brief This function returns the best possible AP for handoff. For 11R case, it
2868 returns the 1st entry from pre-auth done list. For non-11r case, it returns
2869 the 1st entry from roamable AP list
2870
2871 \param pMac - The handle returned by macOpen.
2872 pHandoffNode - AP node that is the handoff candidate returned
2873
2874 \return VOID
2875
2876---------------------------------------------------------------------------*/
2877void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
2878{
2879 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2880 tpCsrNeighborRoamBSSInfo pBssNode;
2881
2882 VOS_ASSERT(NULL != pHandoffNode);
2883
2884#ifdef WLAN_FEATURE_VOWIFI_11R
2885 if (pNeighborRoamInfo->is11rAssoc)
2886 {
2887 /* Always the BSS info in the head is the handoff candidate */
2888 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2889 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2890 }
2891 else
2892#endif
2893#ifdef FEATURE_WLAN_CCX
2894 if (pNeighborRoamInfo->isCCXAssoc)
2895 {
2896 /* Always the BSS info in the head is the handoff candidate */
2897 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2898 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2899 }
2900 else
2901#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002902#ifdef FEATURE_WLAN_LFR
2903 if (csrRoamIsFastRoamEnabled(pMac))
2904 {
2905 /* Always the BSS info in the head is the handoff candidate */
2906 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2907 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2908 }
2909 else
2910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 {
2912 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
2913 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
2914 }
2915 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
2916
2917 return;
2918}
2919
2920/* ---------------------------------------------------------------------------
2921 \brief This function returns TRUE if preauth is completed
2922
2923 \param pMac - The handle returned by macOpen.
2924
2925 \return boolean
2926
2927---------------------------------------------------------------------------*/
2928tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
2929{
2930 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
2931 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
2932}
2933
2934/* ---------------------------------------------------------------------------
2935 \brief In the event that we are associated with AP1 and we have
2936 completed pre auth with AP2. Then we receive a deauth/disassoc from
2937 AP1.
2938 At this point neighbor roam is in pre auth done state, pre auth timer
2939 is running. We now handle this case by stopping timer and clearing
2940 the pre-auth state. We basically clear up and just go to disconnected
2941 state.
2942
2943 \param pMac - The handle returned by macOpen.
2944
2945 \return boolean
2946---------------------------------------------------------------------------*/
2947void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
2948{
2949 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
2950 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
2951
2952 // Stop timer
2953 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
2954
2955 // Transition to init state
2956 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2957}
2958
2959#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */