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