blob: aa674e2495b54e7a9c14cea6d07b277d05f75cf2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*
43 * */
44/** ------------------------------------------------------------------------- *
45 ------------------------------------------------------------------------- *
46
47
48 \file csrNeighborRoam.c
49
50 Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform.
51
52 Copyright (C) 2010 Qualcomm, Incorporated
53
54
55 ========================================================================== */
56
57/*===========================================================================
58
59 EDIT HISTORY FOR FILE
60
61
62 This section contains comments describing changes made to the module.
63 Notice that changes are listed in reverse chronological order.
64
65
66
67 when who what, where, why
68---------- --- --------------------------------------------------------
6908/01/10 Murali Created
70
71===========================================================================*/
72#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
73#include "wlan_qct_wda.h"
74#include "palApi.h"
75#include "csrInsideApi.h"
76#include "smsDebug.h"
77#include "logDump.h"
78#include "smeQosInternal.h"
79#include "wlan_qct_tl.h"
80#include "smeInside.h"
81#include "vos_diag_core_event.h"
82#include "vos_diag_core_log.h"
83#include "csrApi.h"
84#include "wlan_qct_tl.h"
85#include "sme_Api.h"
86#include "csrNeighborRoam.h"
87#ifdef FEATURE_WLAN_CCX
88#include "csrCcx.h"
89#endif
90
91#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
92#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
93#define NEIGHBOR_ROAM_DEBUG smsLog
94#else
95#define NEIGHBOR_ROAM_DEBUG(x...)
96#endif
97
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -070098static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo);
99static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac);
100static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac);
101static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac);
102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
Srinivasdaaec712012-12-12 15:59:44 -0800104 v_PVOID_t pUserCtxt,
105 v_S7_t avgRssi);
Jeff Johnson295189b2012-06-20 16:38:30 -0700106VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
Srinivasdaaec712012-12-12 15:59:44 -0800107 v_PVOID_t pUserCtxt,
108 v_S7_t avgRssi);
Jeff Johnson295189b2012-06-20 16:38:30 -0700109void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus);
110eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile );
111
112#ifdef WLAN_FEATURE_VOWIFI_11R
113static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac);
114VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac);
115#endif
116
117/* State Transition macro */
118#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
119{\
120 pMac->roam.neighborRoamInfo.prevNeighborRoamState = pMac->roam.neighborRoamInfo.neighborRoamState;\
121 pMac->roam.neighborRoamInfo.neighborRoamState = newState;\
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700122 smsLog(pMac, LOG1, FL("Neighbor Roam Transition from state %d ==> %d"), pMac->roam.neighborRoamInfo.prevNeighborRoamState, newState);\
Jeff Johnson295189b2012-06-20 16:38:30 -0700123}
124
125/* ---------------------------------------------------------------------------
126
127 \fn csrNeighborRoamFreeNeighborRoamBSSNode
128
129 \brief This function frees all the internal pointers CSR NeighborRoam BSS Info
130 and also frees the node itself
131
132 \param pMac - The handle returned by macOpen.
133 neighborRoamBSSNode - Neighbor Roam BSS Node to be freed
134
135 \return VOID
136
137---------------------------------------------------------------------------*/
138void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode)
139{
140 if (neighborRoamBSSNode)
141 {
142 if (neighborRoamBSSNode->pBssDescription)
143 {
144 vos_mem_free(neighborRoamBSSNode->pBssDescription);
145 neighborRoamBSSNode->pBssDescription = NULL;
146 }
147 vos_mem_free(neighborRoamBSSNode);
148 neighborRoamBSSNode = NULL;
149 }
150
151 return;
152}
153
154/* ---------------------------------------------------------------------------
155
156 \fn csrNeighborRoamRemoveRoamableAPListEntry
157
158 \brief This function removes a given entry from the given list
159
160 \param pMac - The handle returned by macOpen.
161 pList - The list from which the entry should be removed
162 pNeighborEntry - Neighbor Roam BSS Node to be removed
163
164 \return TRUE if successfully removed, else FALSE
165
166---------------------------------------------------------------------------*/
167tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
168 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
169{
170 if(pList)
171 {
172 return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
173 }
174
175 smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d\n"), csrLLCount(pList));
176
177 return eANI_BOOLEAN_FALSE;
178}
179
180/* ---------------------------------------------------------------------------
181
182 \fn csrNeighborRoamGetRoamableAPListNextEntry
183
184 \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list
185
186 \param pMac - The handle returned by macOpen.
187 pList - The list from which the entry should be returned
188 pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned
189
190 \return Neighbor Roam BSS Node to be returned
191
192---------------------------------------------------------------------------*/
193tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
194 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
195{
196 tListElem *pEntry = NULL;
197 tpCsrNeighborRoamBSSInfo pResult = NULL;
198
199 if(pList)
200 {
201 if(NULL == pNeighborEntry)
202 {
203 pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK);
204 }
205 else
206 {
207 pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
208 }
209 if(pEntry)
210 {
211 pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
212 }
213 }
214
215 return pResult;
216}
217
218/* ---------------------------------------------------------------------------
219
220 \fn csrNeighborRoamFreeRoamableBSSList
221
222 \brief Empties and frees all the nodes in the roamable AP list
223
224 \param pMac - The handle returned by macOpen.
225 pList - Neighbor Roam BSS List to be emptied
226
227 \return VOID
228
229---------------------------------------------------------------------------*/
230void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList)
231{
232 tpCsrNeighborRoamBSSInfo pResult = NULL;
233
Mohit Khanna23863762012-09-11 17:40:09 -0700234 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Emptying the BSS list. Current count = %d\n"), csrLLCount(pList));
Jeff Johnson295189b2012-06-20 16:38:30 -0700235
236 /* Pick up the head, remove and free the node till the list becomes empty */
237 while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL)
238 {
239 csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult);
240 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult);
241 }
242 return;
243}
244
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -0800245static void csrNeighborRoamTriggerHandoff(tpAniSirGlobal pMac,
246 tpCsrNeighborRoamControlInfo pNeighborRoamInfo)
247{
248#ifdef WLAN_FEATURE_VOWIFI_11R
249 if (pNeighborRoamInfo->is11rAssoc)
250 {
251 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
252 {
253 csrNeighborRoamIssuePreauthReq(pMac);
254 }
255 else
256 {
257 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
258 VOS_ASSERT(0);
259 }
260 }
261 else
262#endif
263
264#ifdef FEATURE_WLAN_CCX
265 if (pNeighborRoamInfo->isCCXAssoc)
266 {
267 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
268 {
269 csrNeighborRoamIssuePreauthReq(pMac);
270 }
271 else
272 {
273 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
274 VOS_ASSERT(0);
275 }
276 }
277 else
278#endif
279#ifdef FEATURE_WLAN_LFR
280 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
281 {
282 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
283 {
284 csrNeighborRoamIssuePreauthReq(pMac);
285 }
286 else
287 {
288 smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
289 VOS_ASSERT(0);
290 }
291 }
292 else
293#endif
294 {
295 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
296 {
297 csrNeighborRoamRequestHandoff(pMac);
298 }
299 else
300 {
301 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
302 VOS_ASSERT(0);
303 }
304 }
305}
306
Jeff Johnson295189b2012-06-20 16:38:30 -0700307/* ---------------------------------------------------------------------------
308
309 \fn csrNeighborRoamReassocIndCallback
310
311 \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold.
312 Directly triggere HO in case of non-11r association
313 In case of 11R association, triggers a pre-auth eventually followed by actual HO
314
315 \param pAdapter - VOS Context
316 trafficStatus - UP/DOWN indication from TL
317 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
318
319 \return VOID
320
321---------------------------------------------------------------------------*/
322VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter,
323 v_U8_t trafficStatus,
Srinivasdaaec712012-12-12 15:59:44 -0800324 v_PVOID_t pUserCtxt,
325 v_S7_t avgRssi)
Jeff Johnson295189b2012-06-20 16:38:30 -0700326{
327 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
328 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
329 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
330
Srinivasdaaec712012-12-12 15:59:44 -0800331 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. Threshold RSSI = %d Reported RSSI = %d"),
332 pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
333 avgRssi);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334
335 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
336 WLANTL_HO_THRESHOLD_DOWN,
337 csrNeighborRoamReassocIndCallback,
338 VOS_MODULE_ID_SME);
339
340 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
341 {
342 //err msg
343 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
344 }
345
Srinivasdaaec712012-12-12 15:59:44 -0800346 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Rcvd reassoc notification-deregister UP indication. Threshold RSSI = %d Reported RSSI = %d"),
347 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), avgRssi);
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -0800348 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
349 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
350 WLANTL_HO_THRESHOLD_UP,
351 csrNeighborRoamNeighborLookupUPCallback,
352 VOS_MODULE_ID_SME);
Jeff Johnson295189b2012-06-20 16:38:30 -0700353
354 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
355 {
356 //err msg
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530357 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupUPCallback with TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 }
359
360 /* We dont need to run this timer any more. */
361 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
362
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -0800363 csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700364
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 return VOS_STATUS_SUCCESS;
366}
367
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700368/*CleanUP Routines*/
369static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo)
370{
371 if ((rChInfo->IAPPNeighborListReceived == FALSE) &&
372 (rChInfo->currentChannelListInfo.numOfChannels))
373 {
374 rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
375 rChInfo->currentChannelListInfo.numOfChannels = 0;
376
377 if (rChInfo->currentChannelListInfo.ChannelList)
378 vos_mem_free(rChInfo->currentChannelListInfo.ChannelList);
379
380 rChInfo->currentChannelListInfo.ChannelList = NULL;
381 rChInfo->chanListScanInProgress = eANI_BOOLEAN_FALSE;
382 }
383 else
384 {
385 rChInfo->currentChanIndex = 0;
386 rChInfo->chanListScanInProgress = eANI_BOOLEAN_TRUE;
387 }
388}
389
390static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac)
391{
392 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
393
394 /* Stop neighbor scan timer */
395 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
396
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -0700397 /* Stop neighbor scan results refresh timer */
398 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
399
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700400 /* Abort any ongoing scan */
401 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
402 {
403 csrScanAbortMacScan(pMac);
404 }
405 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
406
407 /* Reset roam channel list information */
408 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
409}
410
411static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac)
412{
413 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
414
415#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
416 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
417 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
418 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId =
419 CSR_SESSION_ID_INVALID;
420 /* Purge pre-auth fail list */
421 csrNeighborRoamPurgePreauthFailedList(pMac);
422#endif
423
424 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
425 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
426#ifdef WLAN_FEATURE_VOWIFI_11R
427 /* Do not free up the preauth done list here */
428 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
429 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
430 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
431 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
432 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
433#endif
434}
435
436static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac)
437{
438 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
439 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
440
441 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
442 FL("Deregister neighbor lookup UP callback with TL. RSSI = %d"),
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800443 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700444
445 /* Deregister reassoc callback. Ignore return status */
446 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800447 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700448 WLANTL_HO_THRESHOLD_UP,
449 csrNeighborRoamNeighborLookupUPCallback,
450 VOS_MODULE_ID_SME);
451
452 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
453 {
454 smsLog(pMac, LOGW,
455 FL("Couldn't deregister csrNeighborRoamNeighborLookupUPCallback "
456 "with TL: Status = %d\n"), vosStatus);
457 }
458
459 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
460 FL("Deregistering reassoc DOWN callback with TL. RSSI = %d"),
461 pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
462
463 /* Deregister reassoc callback. Ignore return status */
464 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
465 (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
466 WLANTL_HO_THRESHOLD_DOWN,
467 csrNeighborRoamReassocIndCallback,
468 VOS_MODULE_ID_SME);
469
470 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
471 {
472 smsLog(pMac, LOGW,
473 FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with "
474 "TL: Status = %d\n"), vosStatus);
475 }
476
477 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
478 FL("Deregistering neighborLookup DOWN callback with TL. RSSI = %d"),
479 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
480
481 /* Deregister neighbor lookup callback. Ignore return status */
482 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
483 (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
484 WLANTL_HO_THRESHOLD_DOWN,
485 csrNeighborRoamNeighborLookupDOWNCallback,
486 VOS_MODULE_ID_SME);
487
488 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
489 {
490 smsLog(pMac, LOGW,
491 FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback "
492 "with TL: Status = %d\n"), vosStatus);
493 }
494
495 /* Reset thresholds only after deregistering DOWN event from TL */
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700496 pNeighborRoamInfo->currentNeighborLookupThreshold =
497 pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800498#ifdef FEATURE_WLAN_LFR
499 pNeighborRoamInfo->uEmptyScanCount = 0;
500#endif
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700501}
502
Jeff Johnson295189b2012-06-20 16:38:30 -0700503/* ---------------------------------------------------------------------------
504
505 \fn csrNeighborRoamResetConnectedStateControlInfo
506
507 \brief This function will reset the neighbor roam control info data structures.
508 This function should be invoked whenever we move to CONNECTED state from
509 any state other than INIT state
510
511 \param pMac - The handle returned by macOpen.
512
513 \return VOID
514
515---------------------------------------------------------------------------*/
516void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
517{
518 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
519
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700520 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700522
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700523 /* We dont need to run this timer any more. */
524 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -0700525
526#ifdef WLAN_FEATURE_VOWIFI_11R
527 /* Do not free up the preauth done list here */
528 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
529 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
530 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
531 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
532 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
533 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
534 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
535#endif
536
537}
538
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700539void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac)
Jeff Johnson295189b2012-06-20 16:38:30 -0700540{
541 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700542 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
543 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
544 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
545 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -0700546#ifdef FEATURE_WLAN_CCX
547 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
548 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
549 pNeighborRoamInfo->MinQBssLoadRequired = 0;
550#endif
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -0700551
552 /* Stop scan refresh timer */
553 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700554 /* Purge roamable AP list */
555 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700556 return;
557}
558
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700559/* ---------------------------------------------------------------------------
560
561 \fn csrNeighborRoamResetInitStateControlInfo
562
563 \brief This function will reset the neighbor roam control info data structures.
564 This function should be invoked whenever we move to CONNECTED state from
565 INIT state
566
567 \param pMac - The handle returned by macOpen.
568
569 \return VOID
570
571---------------------------------------------------------------------------*/
572void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
573{
574 csrNeighborRoamResetConnectedStateControlInfo(pMac);
575
576 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
577 csrNeighborRoamResetReportScanStateControlInfo(pMac);
578}
579
580
581
Jeff Johnson295189b2012-06-20 16:38:30 -0700582#ifdef WLAN_FEATURE_VOWIFI_11R
583/* ---------------------------------------------------------------------------
584
585 \fn csrNeighborRoamBssIdScanFilter
586
587 \brief This API is used to prepare a filter to obtain scan results when
588 we complete the scan in the REPORT_SCAN state after receiving a
589 valid neighbor report from AP. This filter includes BSSIDs received from
590 the neighbor report from the AP in addition to the other filter parameters
591 created from connected profile
592
593 \param pMac - The handle returned by macOpen.
594 pScanFilter - Scan filter to be filled and returned
595
596 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
597 code otherwise
598
599---------------------------------------------------------------------------*/
600static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
601{
602 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
603 tANI_U8 i = 0;
604
605 VOS_ASSERT(pScanFilter != NULL);
606 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
607
608 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
609 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
610 if (NULL == pScanFilter->BSSIDs.bssid)
611 {
612 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
613 return eHAL_STATUS_FAILED_ALLOC;
614 }
615
616 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
617
618 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
619 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
620 {
621 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
622 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
623 }
624
625 /* Fill other general scan filter params */
626 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
627}
628
629/* ---------------------------------------------------------------------------
630
631 \fn csrNeighborRoamPurgePreauthFailList
632
633 \brief This function empties the preauth fail list
634
635 \param pMac - The handle returned by macOpen.
636
637 \return VOID
638
639---------------------------------------------------------------------------*/
640void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
641{
642 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
643
644 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
645 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
646 {
647 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
648 sizeof(tSirMacAddr));
649 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
650 }
651 return;
652}
653
654/* ---------------------------------------------------------------------------
655
656 \fn csrNeighborRoamAddBssIdToPreauthFailList
657
658 \brief This function adds the given BSSID to the Preauth fail list
659
660 \param pMac - The handle returned by macOpen.
661 bssId - BSSID to be added to the preauth fail list
662
663 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
664
665---------------------------------------------------------------------------*/
666eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
667{
668 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
669
670 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
671 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
672
673
674 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
675 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
676 {
677 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
678 return eHAL_STATUS_FAILURE;
679 }
680 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
681 bssId, sizeof(tSirMacAddr));
682 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
683
684 return eHAL_STATUS_SUCCESS;
685}
686
687/* ---------------------------------------------------------------------------
688
689 \fn csrNeighborRoamIsPreauthCandidate
690
691 \brief This function checks whether the given MAC address is already
692 present in the preauth fail list and returns TRUE/FALSE accordingly
693
694 \param pMac - The handle returned by macOpen.
695
696 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
697
698---------------------------------------------------------------------------*/
699tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
700{
701 tANI_U8 i = 0;
702 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
703
704 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
705 return eANI_BOOLEAN_TRUE;
706
707 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
708 {
709 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
710 bssId, sizeof(tSirMacAddr)))
711 {
712 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
713 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
714 return eANI_BOOLEAN_FALSE;
715 }
716 }
717
718 return eANI_BOOLEAN_TRUE;
719}
720
721/* ---------------------------------------------------------------------------
722
723 \fn csrNeighborRoamIssuePreauthReq
724
725 \brief This function issues preauth request to PE with the 1st AP entry in the
726 roamable AP list
727
728 \param pMac - The handle returned by macOpen.
729
730 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
731
732---------------------------------------------------------------------------*/
733static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
734{
735 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
736 eHalStatus status = eHAL_STATUS_SUCCESS;
737 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
738
739 /* This must not be true here */
740 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
741
742 /* Issue Preauth request to PE here */
743 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
744 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
745 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
746 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
747
748 if (NULL == pNeighborBssNode)
749 {
750 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
751 return eHAL_STATUS_FAILURE;
752 }
753 else
754 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700755 status = csrRoamEnqueuePreauth(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription,
756 eCsrPerformPreauth, eANI_BOOLEAN_TRUE);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530757
758 smsLog(pMac, LOGE, FL("Before Pre-Auth: BSSID %02x:%02x:%02x:%02x:%02x:%02x %d"),
759 pNeighborBssNode->pBssDescription->bssId[0],
760 pNeighborBssNode->pBssDescription->bssId[1],
761 pNeighborBssNode->pBssDescription->bssId[2],
762 pNeighborBssNode->pBssDescription->bssId[3],
763 pNeighborBssNode->pBssDescription->bssId[4],
764 pNeighborBssNode->pBssDescription->bssId[5]);
765 smsLog(pMac, LOGE, FL("Before Pre-Auth: Channel %d\n"), (int)pNeighborBssNode->pBssDescription->channelId);
766
Jeff Johnson295189b2012-06-20 16:38:30 -0700767 if (eHAL_STATUS_SUCCESS != status)
768 {
769 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
770 return status;
771 }
772 }
773
774 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
775
776 /* Increment the preauth retry count */
777 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
778
779 /* Transition the state to preauthenticating */
780 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700781#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 /* Start the preauth rsp timer */
783 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
784 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
785 eANI_BOOLEAN_FALSE);
786 if (eHAL_STATUS_SUCCESS != status)
787 {
788 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
789 return status;
790 }
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700792
793 return status;
794}
795
796/* ---------------------------------------------------------------------------
797
798 \fn csrNeighborRoamPreauthRspHandler
799
800 \brief This function handle the Preauth response from PE
801 Every preauth is allowed max 3 tries if it fails. If a bssid failed
802 for more than MAX_TRIES, we will remove it from the list and try
803 with the next node in the roamable AP list and add the BSSID to pre-auth failed
804 list. If no more entries present in
805 roamable AP list, transition to REPORT_SCAN state
806
807 \param pMac - The handle returned by macOpen.
808 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
809
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700810 \return eHAL_STATUS_SUCCESS on success (i.e. pre-auth processed),
811 eHAL_STATUS_FAILURE otherwise
Jeff Johnson295189b2012-06-20 16:38:30 -0700812
813---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700814eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -0700815{
816 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
817 eHalStatus status = eHAL_STATUS_SUCCESS;
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700818 eHalStatus preauthProcessed = eHAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700819 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700820
821 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->FTRoamInfo.preauthRspPending)
822 {
823
824 /* This can happen when we disconnect immediately
825 * after sending a pre-auth request. During processing
826 * of the disconnect command, we would have reset
827 * preauthRspPending and transitioned to INIT state.
828 */
829 NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
830 FL("Unexpected pre-auth response in state %d\n"),
831 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700832 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700833 goto DEQ_PREAUTH;
834 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700835
836 // We can receive it in these 2 states.
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
838 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
839 {
Madan Mohan Koyyalamudi8186a9e2012-10-11 14:23:43 -0700840 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %d\n"),
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700841 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700842 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700843 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 }
845
846 if (VOS_STATUS_E_TIMEOUT != vosStatus)
847 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700848#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700849 /* This means we got the response from PE. Hence stop the timer */
850 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
853 }
854
855 if (VOS_STATUS_SUCCESS == vosStatus)
856 {
857 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
858 }
859 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
860 {
861 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
862
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530863 smsLog(pMac, LOGE, FL("After Pre-Auth: BSSID %02x:%02x:%02x:%02x:%02x:%02x\n"),
864 pPreauthRspNode->pBssDescription->bssId[0],
865 pPreauthRspNode->pBssDescription->bssId[1],
866 pPreauthRspNode->pBssDescription->bssId[2],
867 pPreauthRspNode->pBssDescription->bssId[3],
868 pPreauthRspNode->pBssDescription->bssId[4],
869 pPreauthRspNode->pBssDescription->bssId[5]);
870 smsLog(pMac, LOGE, FL("After Pre-Auth: Channel %d\n"), (int)pPreauthRspNode->pBssDescription->channelId);
871
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
873 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
874 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
875
876 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
877 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
878 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
879
880 /* The caller of this function would start a timer and by the time it expires, supplicant should
881 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
882 }
883 else
884 {
885 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
886 tListElem *pEntry;
887
888 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
889
890 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
891 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
892 {
893 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
894 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
895
896 /* The one in the head of the list should be one with which we issued pre-auth and failed */
897 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
898 if(pEntry)
899 {
900 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
901 /* Add the BSSID to pre-auth fail list */
902 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
903 /* Now we can free this node */
904 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
905 }
906 }
907
908 /* Issue preauth request for the same/next entry */
909 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700910 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700911
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -0800912 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN);
913
914 /* Register Neighbor Lookup threshold callback with TL for UP event now */
915 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No more pre-auth candidates-"
916 "register UP indication with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
917
918 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
919 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
920 WLANTL_HO_THRESHOLD_UP,
921 csrNeighborRoamNeighborLookupUPCallback,
922 VOS_MODULE_ID_SME, pMac);
923 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
924 {
925 //err msg
926 smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
927 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700928
929 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
930 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
931 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
932 eANI_BOOLEAN_FALSE);
933 if (eHAL_STATUS_SUCCESS != status)
934 {
935 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 }
937 }
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700938
939DEQ_PREAUTH:
940 csrRoamDequeuePreauth(pMac);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700941 return preauthProcessed;
Jeff Johnson295189b2012-06-20 16:38:30 -0700942}
943#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
944
945/* ---------------------------------------------------------------------------
946
947 \fn csrNeighborRoamPrepareScanProfileFilter
948
949 \brief This function creates a scan filter based on the currently connected profile.
950 Based on this filter, scan results are obtained
951
952 \param pMac - The handle returned by macOpen.
953 pScanFilter - Populated scan filter based on the connected profile
954
955 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
956
957---------------------------------------------------------------------------*/
958eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
959{
960 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
961 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
962 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
963 tANI_U8 i = 0;
964
965 VOS_ASSERT(pScanFilter != NULL);
966
967 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
968
969 /* We dont want to set BSSID based Filter */
970 pScanFilter->BSSIDs.numOfBSSIDs = 0;
971
972 /* Populate all the information from the connected profile */
973 pScanFilter->SSIDs.numOfSSIDs = 1;
974 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
975 if (NULL == pScanFilter->SSIDs.SSIDList)
976 {
977 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
978 return eHAL_STATUS_FAILED_ALLOC;
979 }
980 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
981 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
982 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
983 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
984
985 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
986 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
987 pScanFilter->authType.numEntries = 1;
988 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
989
990 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
991 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
992
993 pScanFilter->mcEncryptionType.numEntries = 1;
994 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
995
996 pScanFilter->BSSType = pCurProfile->BSSType;
997
998 /* We are intrested only in the scan results on channels that we scanned */
999 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
1000 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
1001 if (NULL == pScanFilter->ChannelInfo.ChannelList)
1002 {
1003 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
1004 vos_mem_free(pScanFilter->SSIDs.SSIDList);
1005 pScanFilter->SSIDs.SSIDList = NULL;
1006 return eHAL_STATUS_FAILED_ALLOC;
1007 }
1008 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
1009 {
1010 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1011 }
1012
1013#ifdef WLAN_FEATURE_VOWIFI_11R
1014 if (pNeighborRoamInfo->is11rAssoc)
1015 {
1016 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
1017 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
1018 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
1019 }
1020#endif
1021
1022 return eHAL_STATUS_SUCCESS;
1023}
1024
Jeff Johnson43971f52012-07-17 12:26:56 -07001025tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
1026{
1027 tCsrScanResultInfo *pScanResult;
1028 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1029 tANI_U32 CurrAPRssi = -125; /* We are setting this as default value to make sure we return this value,
1030 when we do not see this AP in the scan result for some reason.However,it is
1031 less likely that we are associated to an AP and do not see it in the scan list*/
1032
1033 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
1034 {
1035
1036 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
1037 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
1038 {
1039 /* We got a match with the currently associated AP.
1040 * Capture the RSSI value and complete the while loop.
1041 * The while loop is completed in order to make the current entry go back to NULL,
1042 * and in the next while loop, it properly starts searching from the head of the list.
1043 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
1044
1045 CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ;
1046
1047 } else {
1048 continue;
1049 }
1050 }
1051
1052 return CurrAPRssi;
1053
1054}
1055
Jeff Johnson295189b2012-06-20 16:38:30 -07001056/* ---------------------------------------------------------------------------
1057
1058 \fn csrNeighborRoamProcessScanResults
1059
1060 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
1061 Assumed that the results are already sorted by RSSI by csrScanGetResult
1062
1063 \param pMac - The handle returned by macOpen.
1064 pScanResultList - Scan result result obtained from csrScanGetResult()
1065
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001066 \return tANI_BOOLEAN - return TRUE if we have a candidate we can immediately
1067 roam to. Otherwise, return FALSE.
Jeff Johnson295189b2012-06-20 16:38:30 -07001068
1069---------------------------------------------------------------------------*/
1070
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001071static tANI_BOOLEAN csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac,
1072 tScanResultHandle *pScanResultList)
Jeff Johnson295189b2012-06-20 16:38:30 -07001073{
1074 tCsrScanResultInfo *pScanResult;
1075 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1076 tpCsrNeighborRoamBSSInfo pBssInfo;
Jeff Johnson43971f52012-07-17 12:26:56 -07001077 tANI_U32 CurrAPRssi;
1078 tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff;
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001079#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1080 tANI_U8 immediateRoamRssiDiff = pMac->roam.configParam.nImmediateRoamRssiDiff;
1081#endif
1082 tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE;
Jeff Johnson43971f52012-07-17 12:26:56 -07001083
1084 /***************************************************************
1085 * Find out the Current AP RSSI and keep it handy to check if
1086 * it is better than the RSSI of the AP which we are
1087 * going to roam.If so, we are going to continue with the
1088 * current AP.
1089 ***************************************************************/
1090 CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001091
1092 /* Expecting the scan result already to be in the sorted order based on the RSSI */
1093 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
1094 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
1095 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
1096 /* 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
1097 and rssi score are in the same order. This will be taken care later */
1098
1099 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
1100 {
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001101 NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
1102 FL("Scan result: BSSID %02x:%02x:%02x:%02x:%02x:%02x (Rssi %d)"),
1103 pScanResult->BssDescriptor.bssId[0],
1104 pScanResult->BssDescriptor.bssId[1],
1105 pScanResult->BssDescriptor.bssId[2],
1106 pScanResult->BssDescriptor.bssId[3],
1107 pScanResult->BssDescriptor.bssId[4],
1108 pScanResult->BssDescriptor.bssId[5],
1109 abs(pScanResult->BssDescriptor.rssi));
Jeff Johnson295189b2012-06-20 16:38:30 -07001110
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001111 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
1113 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001114 /* currently associated AP. Do not have this in the roamable AP list */
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08001115 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1116 "SKIP-currently associated AP\n");
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 continue;
1118 }
1119
Jeff Johnson43971f52012-07-17 12:26:56 -07001120 /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature
1121 * is disabled and we continue to roam without any check*/
1122 if(RoamRssiDiff > 0)
1123 {
Madan Mohan Koyyalamudif553b742012-12-03 16:37:39 -08001124 /*
1125 * If RSSI is lower than the lookup threshold, then continue.
1126 */
1127 if (abs(pScanResult->BssDescriptor.rssi) >
1128 pNeighborRoamInfo->currentNeighborLookupThreshold)
1129 {
1130 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1131 "%s: [INFOLOG] new ap rssi (%d) lower than lookup threshold (%d)\n",
1132 __func__, (int)pScanResult->BssDescriptor.rssi * (-1),
1133 (int)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1134 continue;
1135 }
1136
Jeff Johnson43971f52012-07-17 12:26:56 -07001137 if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi))
1138 {
1139 /*Do not roam to an AP with worse RSSI than the current*/
1140 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1141 "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d\n", __func__,
1142 CurrAPRssi,
1143 (int)pScanResult->BssDescriptor.rssi * (-1) );
1144 continue;
1145 } else {
1146 /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the
1147 * margin that is provided by user from the ini file (RoamRssiDiff)*/
1148 if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff)
1149 {
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08001150 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1151 "%s: [INFOLOG]Current AP rssi=%d new ap rssi=%d not good enough, roamRssiDiff=%d\n", __func__,
1152 CurrAPRssi,
1153 (int)pScanResult->BssDescriptor.rssi * (-1),
1154 RoamRssiDiff);
Jeff Johnson43971f52012-07-17 12:26:56 -07001155 continue;
1156 }
1157 else {
1158 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1159 "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d\n", __func__,
1160 CurrAPRssi,
1161 (int)pScanResult->BssDescriptor.rssi * (-1) );
1162 }
1163 }
1164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001165
1166#ifdef WLAN_FEATURE_VOWIFI_11R
1167 if (pNeighborRoamInfo->is11rAssoc)
1168 {
1169 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1170 {
1171 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1172 continue;
1173 }
1174 }
1175#endif /* WLAN_FEATURE_VOWIFI_11R */
1176
1177#ifdef FEATURE_WLAN_CCX
1178 if (pNeighborRoamInfo->isCCXAssoc)
1179 {
1180 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1181 {
1182 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1183 continue;
1184 }
1185 }
1186 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
1187 (pScanResult->BssDescriptor.QBSSLoad_avail))
1188 {
1189 if (pNeighborRoamInfo->isVOAdmitted)
1190 {
1191 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
1192 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
1193 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
1194 {
1195 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1196 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
1197 pScanResult->BssDescriptor.bssId[0],
1198 pScanResult->BssDescriptor.bssId[1],
1199 pScanResult->BssDescriptor.bssId[2],
1200 pScanResult->BssDescriptor.bssId[3],
1201 pScanResult->BssDescriptor.bssId[4],
1202 pScanResult->BssDescriptor.bssId[5]);
1203 continue;
1204 }
1205 }
1206 }
1207 else
1208 {
1209 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
1210 if (pNeighborRoamInfo->isVOAdmitted)
1211 {
1212 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1213 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
1214 pScanResult->BssDescriptor.bssId[0],
1215 pScanResult->BssDescriptor.bssId[1],
1216 pScanResult->BssDescriptor.bssId[2],
1217 pScanResult->BssDescriptor.bssId[3],
1218 pScanResult->BssDescriptor.bssId[4],
1219 pScanResult->BssDescriptor.bssId[5]);
1220 continue;
1221 }
1222 }
1223#endif /* FEATURE_WLAN_CCX */
1224
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001225#ifdef FEATURE_WLAN_LFR
1226 // If we are supporting legacy roaming, and
1227 // if the candidate is on the "pre-auth failed" list, ignore it.
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05301228 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001229 {
1230 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1231 {
1232 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1233 continue;
1234 }
1235 }
1236#endif /* FEATURE_WLAN_LFR */
1237
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
1239 * this result */
1240 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
1241 {
1242 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
1243 continue;
1244 }
1245
1246 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
1247 if (NULL == pBssInfo)
1248 {
1249 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
1250 continue;
1251 }
1252
1253 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1254 if (pBssInfo->pBssDescription != NULL)
1255 {
1256 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
1257 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1258 }
1259 else
1260 {
1261 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
1262 vos_mem_free(pBssInfo);
1263 continue;
1264
1265 }
1266 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
1267
1268 /* Just add to the end of the list as it is already sorted by RSSI */
1269 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001270
1271#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1272 if (immediateRoamRssiDiff &&
1273 (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) >= immediateRoamRssiDiff))
1274 {
1275 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1276 "%s: [INFOLOG] potential candidate to roam immediately (diff=%d, expected=%d)",
1277 __func__, abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)),
1278 immediateRoamRssiDiff);
1279 roamNow = eANI_BOOLEAN_TRUE;
1280 }
1281#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 }
1283
1284 /* 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 */
1285 csrScanResultPurge(pMac, *pScanResultList);
1286
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001287 return roamNow;
Jeff Johnson295189b2012-06-20 16:38:30 -07001288}
1289
1290/* ---------------------------------------------------------------------------
1291
1292 \fn csrNeighborRoamHandleEmptyScanResult
1293
1294 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1295 there are no valid APs in the scan result for roaming. This means
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001296 our AP is the best and no other AP is around. No point in scanning
Jeff Johnson295189b2012-06-20 16:38:30 -07001297 again and again. Performing the following here.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001298 1. Stop the neighbor scan timer.
1299 2a. If this is the first time we encountered empty scan, then
1300 re-register with TL with modified lookup threshold.
1301 2b. Else if this is the second time we encountered empty scan,
1302 then start neighbor scan results refresh timer (20s).
1303 2c. Else, nothing more to do.
1304 NOTE: In LFR, channels selected for scanning is dervied from
1305 the occuped channel list. Scan cycle following one which
1306 yielded empty results is split into two halves: (i) scan on
1307 channels in the occupied list, and (ii) scan on channels not
1308 in the occupied list. This helps converging faster (while
1309 looking for candidates in the occupied list first), and also,
1310 adds channels to the occupied channel list upon finding candidates
1311 matching SSID profile of interest.
1312
1313 uEmptyScanCount Comments
1314 eFirstEmptyScan Previous scan was done on channels in the
1315 occupied list and yielded potential candidates.
1316 This scan cycle was likely triggered through
1317 receipt of lookup DOWN notification event.
1318 eSecondEmptyScan Previous scan was done on channels in the
1319 occupied list and yielded no candidates. This scan
1320 cycle was triggered through RSSI notification
1321 with modified lookup threshold.
1322 eThirdEmptyScan Previous scan was done on channels NOT in
1323 the occupied list and yielded no candidates. This
1324 scan cycle was triggered immediately after scanning
1325 channels in the occupied list and no candidates
1326 were found.
1327 eFourthEmptyScan Previous scan was done on channels in the
1328 occupied list and yielded no candidates. This scan
1329 cycle was triggered upon expiry of
1330 neighborScanResultsRefreshPeriod (=20s).
1331 eFifthEmptyScan Previous scan was done on channels NOT in
1332 the occupied list and yielded no candidates. This
1333 scan cycle was triggered immediately after scanning
1334 channels in the occupied list and no candidates
1335 were found.
1336
1337 [1], [2,3] and [4,5] together form one discrete set of scan cycle.
Jeff Johnson295189b2012-06-20 16:38:30 -07001338
1339 \param pMac - The handle returned by macOpen.
1340
1341 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1342
1343---------------------------------------------------------------------------*/
1344static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1345{
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001346 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1348 eHalStatus status = eHAL_STATUS_SUCCESS;
1349
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001350 /* Stop neighbor scan timer */
Jeff Johnson295189b2012-06-20 16:38:30 -07001351 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001352 if (eHAL_STATUS_SUCCESS != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001353 {
1354 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1355 }
1356
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001357 /*
1358 * Increase the neighbor lookup threshold by 3 dB
1359 * after every scan cycle. NOTE: uEmptyScanCount
1360 * would be either 1, 3 or 5 at the end of every
1361 * scan cycle.
1362 */
1363#ifdef FEATURE_WLAN_LFR
1364 if ((++pNeighborRoamInfo->uEmptyScanCount) > eFifthEmptyScan)
1365 {
1366 pNeighborRoamInfo->uEmptyScanCount = eFifthEmptyScan;
1367 }
1368#endif
1369 if (((pNeighborRoamInfo->currentNeighborLookupThreshold+3) <
1370 pNeighborRoamInfo->cfgParams.neighborReassocThreshold)
1371#ifdef FEATURE_WLAN_LFR
1372 && ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1)
1373#endif
1374 )
1375 {
1376 pNeighborRoamInfo->currentNeighborLookupThreshold += 3;
1377 }
1378
Jeff Johnson295189b2012-06-20 16:38:30 -07001379#ifdef WLAN_FEATURE_VOWIFI_11R
1380 /* Clear off the old neighbor report details */
1381 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1382#endif
1383
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001384#ifdef FEATURE_WLAN_LFR
1385 if (pNeighborRoamInfo->uEmptyScanCount == eFirstEmptyScan)
1386 {
1387#endif
1388 /* Empty scan results for the first time */
1389 /* Transition to CONNECTED state */
1390 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1391
1392 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1393 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1394
1395 /* Re-register neighbor lookup DOWN threshold callback with TL */
1396 NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
1397 FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"),
1398 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1399
1400 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
1401 (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1402 WLANTL_HO_THRESHOLD_DOWN,
1403 csrNeighborRoamNeighborLookupDOWNCallback,
1404 VOS_MODULE_ID_SME, pMac);
1405
1406 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1407 {
1408 smsLog(pMac, LOGW,
1409 FL("Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback"
1410 " with TL: Status = %d\n"), status);
1411 }
1412#ifdef FEATURE_WLAN_LFR
1413 }
1414 else if ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) ||
1415 (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan))
1416 {
1417 /* Empty scan results for the second or fourth time */
1418 /* Transition to CONNECTED state */
1419 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1420
1421 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1422 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1423
1424 /* Immediately scan on channels in non-occupied list */
1425 csrNeighborRoamTransitToCFGChanScan(pMac);
1426 }
1427 else if (pNeighborRoamInfo->uEmptyScanCount == eThirdEmptyScan)
1428 {
1429 /* Empty scan results for the third time */
1430 /* Remain in eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN */
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001431 /* Start neighbor scan results refresh timer */
1432 if (eHAL_STATUS_SUCCESS !=
1433 palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001434 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001435 eANI_BOOLEAN_FALSE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001436 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001437 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start (%d)"),
1438 status);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001439 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1440 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001441 vosStatus = VOS_STATUS_E_FAILURE;
1442 }
1443 else
1444 {
1445 smsLog(pMac, LOG2, FL("Neighbor results refresh timer started (%ld ms)"),
1446 (pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT));
1447 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001449 else
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001450 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001451 /* Do nothing */
1452 /* Transition to CONNECTED state */
1453 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1454
1455 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1456 csrNeighborRoamResetConnectedStateControlInfo(pMac);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001457 }
1458
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001459 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Neighbor roam empty scan count=%d",
1460 pNeighborRoamInfo->uEmptyScanCount);
1461#endif
1462 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001463}
1464
1465/* ---------------------------------------------------------------------------
1466
1467 \fn csrNeighborRoamScanRequestCallback
1468
1469 \brief This function is the callback function registered in csrScanRequest() to
1470 indicate the completion of scan. If scan is completed for all the channels in
1471 the channel list, this function gets the scan result and starts the refresh results
1472 timer to avoid having stale results. If scan is not completed on all the channels,
1473 it restarts the neighbor scan timer which on expiry issues scan on the next
1474 channel
1475
1476 \param halHandle - The handle returned by macOpen.
1477 pContext - not used
1478 scanId - not used
1479 status - not used
1480
1481 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1482
1483---------------------------------------------------------------------------*/
1484static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1485 tANI_U32 scanId, eCsrScanStatus status)
1486{
1487 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1488 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1489 tANI_U8 currentChanIndex;
1490 tCsrScanResultFilter scanFilter;
1491 tScanResultHandle scanResult;
1492 tANI_U32 tempVal = 0;
Jeff Johnson43971f52012-07-17 12:26:56 -07001493 eHalStatus hstatus;
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001494 tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001495
1496 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1497
1498 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1499 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1500 {
1501 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1502 return eHAL_STATUS_SUCCESS;
1503 }
1504
1505 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1506 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1507
1508 /* Validate inputs */
1509 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1510 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1511 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1512 }
1513 else
1514 {
1515 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1516 return eHAL_STATUS_SUCCESS;
1517 }
1518
1519 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1520 {
1521 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1522 just to get the results and perform PREAUTH */
1523 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1524 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1525 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1526 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1527
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001528#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1530 should use the BSSID filter made out of neighbor reports */
1531 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1532 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001533 hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1534 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 -07001535 tempVal = 1;
1536 }
1537 else
1538#endif
1539 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001540 hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1541 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 -07001542 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001543 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001544 {
1545 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1546 return eHAL_STATUS_FAILURE;
1547 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001548 hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301549 if (hstatus != eHAL_STATUS_SUCCESS)
1550 {
1551 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus);
1552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001553 /* Process the scan results and update roamable AP list */
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001554 roamNow = csrNeighborRoamProcessScanResults(pMac, &scanResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07001555
1556 /* Free the scan filter */
1557 csrFreeScanFilter(pMac, &scanFilter);
1558
1559 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1560
1561 switch(pNeighborRoamInfo->neighborRoamState)
1562 {
1563 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1564 if (tempVal)
1565 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001566#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001567 /*
1568 * Since there are non-zero candidates found
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001569 * after the scan, reset empty scan count.
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001570 */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001571 pNeighborRoamInfo->uEmptyScanCount = 0;
1572#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001573#ifdef WLAN_FEATURE_VOWIFI_11R
1574 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1575 APs in the roamable AP list */
1576 if (pNeighborRoamInfo->is11rAssoc)
1577 {
1578 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1579 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1580 }
1581 else
1582#endif
1583#ifdef FEATURE_WLAN_CCX
1584 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1585 APs in the roamable AP list */
1586 if (pNeighborRoamInfo->isCCXAssoc)
1587 {
1588 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1589 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1590 }
1591 else
1592#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001593#ifdef FEATURE_WLAN_LFR
1594 /* If LFR is enabled, then we can register the reassoc callback here as we have some
1595 APs in the roamable AP list */
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05301596 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001597 {
1598 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1599 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1600 }
1601 else
1602#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 {
1604
1605 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1606 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1607 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1608 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1609 within certain duration */
1610
1611// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1612 }
1613 }
1614 else
1615 {
Madan Mohan Koyyalamudib40e5582012-10-11 16:48:42 -07001616 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1617 /* Handle it appropriately */
1618 csrNeighborRoamHandleEmptyScanResult(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001619 }
1620 break;
1621#ifdef WLAN_FEATURE_VOWIFI_11R
1622 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1623 if (!tempVal)
1624 {
1625 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1626 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1627 csrNeighborRoamTransitToCFGChanScan(pMac);
1628 }
1629 break;
1630#endif /* WLAN_FEATURE_VOWIFI_11R */
1631 default:
1632 // Can come only in INIT state. Where in we are associated, we sent scan and user
1633 // in the meantime decides to disassoc, we will be in init state and still received call
1634 // back issued. Should not come here in any other state, printing just in case
1635 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1636 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1637
1638 // Lets just exit out silently.
1639 return eHAL_STATUS_SUCCESS;
1640 }
1641
1642 if (tempVal)
1643 {
1644 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1645
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001646 if (roamNow)
1647 {
1648 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
1649 FL("Immediate roam-deregister UP indication. RSSI = %d"),
1650 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
1651
1652 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
1653 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
1654 WLANTL_HO_THRESHOLD_UP,
1655 csrNeighborRoamNeighborLookupUPCallback,
1656 VOS_MODULE_ID_SME);
1657
1658 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1659 {
1660 smsLog(pMac, LOGW,
1661 FL("Couldn't deregister lookup UP callback with TL: Status = %d\n"), vosStatus);
1662 }
1663
1664 csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo);
1665 return eHAL_STATUS_SUCCESS;
1666 }
1667
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1669 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1670 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1671 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1672 eANI_BOOLEAN_FALSE))
1673 {
1674 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1675 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1676 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001677 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001679
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1681 /* Register a reassoc Indication callback */
1682 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1683 WLANTL_HO_THRESHOLD_DOWN,
1684 csrNeighborRoamReassocIndCallback,
1685 VOS_MODULE_ID_SME, pMac);
1686
1687 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1688 {
1689 //err msg
1690 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1691 }
1692
1693 }
1694 }
1695 else
1696 {
1697
1698 /* Restart the timer for the next scan sequence as scanning is not over */
Jeff Johnson43971f52012-07-17 12:26:56 -07001699 hstatus = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
Jeff Johnson295189b2012-06-20 16:38:30 -07001700 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1701 eANI_BOOLEAN_FALSE);
1702
Jeff Johnson43971f52012-07-17 12:26:56 -07001703 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001704 {
1705 /* Timer start failed.. Should we ASSERT here??? */
1706 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1707 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1708 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001709 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001710 }
1711 }
1712 return eHAL_STATUS_SUCCESS;
1713}
1714
1715/* ---------------------------------------------------------------------------
1716
1717 \fn csrNeighborRoamIssueBgScanRequest
1718
1719 \brief This function issues CSR scan request after populating all the BG scan params
1720 passed
1721
1722 \param pMac - The handle returned by macOpen.
1723 pBgScanParams - Params that need to be populated into csr Scan request
1724
1725 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1726
1727---------------------------------------------------------------------------*/
1728eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1729{
1730 eHalStatus status = eHAL_STATUS_SUCCESS;
1731 tANI_U32 scanId;
1732 tCsrScanRequest scanReq;
1733 tANI_U8 channel;
1734
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301735 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1737
1738
1739 //send down the scan req for 1 channel on the associated SSID
1740 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1741 /* Fill in the SSID Info */
1742 scanReq.SSIDs.numOfSSIDs = 1;
1743 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1744 if(NULL == scanReq.SSIDs.SSIDList)
1745 {
1746 //err msg
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301747 smsLog(pMac, LOGE, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 return eHAL_STATUS_FAILURE;
1749 }
1750 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1751
1752 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1753 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1754 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1755
1756 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1757
1758 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1759 scanReq.ChannelInfo.ChannelList = &channel;
1760
1761 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1762 scanReq.scanType = eSIR_ACTIVE_SCAN;
1763 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1764 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1765 scanReq.minChnTime = pBgScanParams->minChnTime;
1766 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1767 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1768 if (eHAL_STATUS_SUCCESS != status)
1769 {
1770 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1771 vos_mem_free(scanReq.SSIDs.SSIDList);
1772 return status;
1773 }
1774 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1775
1776 vos_mem_free(scanReq.SSIDs.SSIDList);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301777 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %08x, Actual index = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001778 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1779 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1780 return status;
1781}
1782
1783/* ---------------------------------------------------------------------------
1784
1785 \fn csrNeighborRoamPerformBgScan
1786
1787 \brief This function is invoked on every expiry of neighborScanTimer till all
1788 the channels in the channel list are scanned. It populates necessary
1789 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1790 request
1791
1792 \param pMac - The handle returned by macOpen.
1793
1794 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1795
1796---------------------------------------------------------------------------*/
1797eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1798{
1799 eHalStatus status = eHAL_STATUS_SUCCESS;
1800 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1801 tCsrBGScanRequest bgScanParams;
1802 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1803 tANI_U8 channel = 0;
1804
1805 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1806 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301807 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 }
1809 else
1810 {
1811 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
Jeff Johnson902c9832012-12-10 14:28:09 -08001812 // Go back and restart. Mostly timer start failure has occurred.
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 // When timer start is declared a failure, then we delete the list.
1814 // Should not happen now as we stop and then only start the scan timer.
1815 // still handle the unlikely case.
1816 csrNeighborRoamHandleEmptyScanResult(pMac);
1817 return status;
1818 }
1819 /* Need to perform scan here before getting the list */
1820 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1821 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1822 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1823 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1824
1825 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1826 bgScanParams.ChannelInfo.numOfChannels = 1;
1827 bgScanParams.ChannelInfo.ChannelList = &channel;
1828
1829 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1830 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1831
1832 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1833 if (eHAL_STATUS_SUCCESS != status)
1834 {
1835 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1836 return status;
1837 }
1838
1839 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1840 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1841 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1842 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301843 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001844 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1845 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1846 /* We have completed scanning all the channels */
1847 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1848 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1849 and select the best AP in the list */
1850 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1851 {
1852 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1853 }
1854 }
1855
1856 return status;
1857}
1858
1859/* ---------------------------------------------------------------------------
1860
1861 \fn csrNeighborRoamNeighborScanTimerCallback
1862
1863 \brief This function is the neighbor scan timer callback function. It invokes
1864 the BG scan request based on the current and previous states
1865
1866 \param pv - CSR timer context info which includes pMac and session ID
1867
1868 \return VOID
1869
1870---------------------------------------------------------------------------*/
1871void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1872{
1873 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1874 tpAniSirGlobal pMac = pInfo->pMac;
1875 tANI_U32 sessionId = pInfo->sessionId;
1876 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1877
1878 // check if bg scan is on going, no need to send down the new params if true
1879 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1880 {
1881 //msg
1882 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1883 return;
1884 }
1885
1886 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1887
1888 switch (pNeighborRoamInfo->neighborRoamState)
1889 {
1890#ifdef WLAN_FEATURE_VOWIFI_11R
1891 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1892 switch(pNeighborRoamInfo->prevNeighborRoamState)
1893 {
1894 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1895 csrNeighborRoamPerformBgScan(pMac);
1896 break;
1897 default:
1898 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1899 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1900 break;
1901 }
1902 break;
1903#endif /* WLAN_FEATURE_VOWIFI_11R */
1904 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1905 csrNeighborRoamPerformBgScan(pMac);
1906 break;
1907 default:
1908 break;
1909 }
1910 return;
1911}
1912
1913/* ---------------------------------------------------------------------------
1914
1915 \fn csrNeighborRoamResultsRefreshTimerCallback
1916
1917 \brief This function is the timer callback function for results refresh timer.
1918 When this is invoked, it is as good as down event received from TL. So,
1919 clear off the roamable AP list and start the scan procedure based on 11R
1920 or non-11R association
1921
1922 \param context - CSR timer context info which includes pMac and session ID
1923
1924 \return VOID
1925
1926---------------------------------------------------------------------------*/
1927void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1928{
1929 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1930 tpAniSirGlobal pMac = pInfo->pMac;
1931 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1932 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1933
1934 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1935
1936 /* Deregister reassoc callback. Ignore return status */
1937 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1938 WLANTL_HO_THRESHOLD_DOWN,
1939 csrNeighborRoamReassocIndCallback,
1940 VOS_MODULE_ID_SME);
1941
1942 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1943 {
1944 //err msg
1945 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1946 }
1947
1948 /* Reset all the variables just as no scan had happened before */
1949 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1950
1951#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1952 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1953 {
1954 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1955 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1956 if (VOS_STATUS_SUCCESS != vosStatus)
1957 {
1958 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1959 return;
1960 }
1961 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1962 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1963 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1964 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1965 }
1966 else
1967#endif
1968 {
1969 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1970 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1971 if (VOS_STATUS_SUCCESS != vosStatus)
1972 {
1973 return;
1974 }
1975 }
1976 return;
1977}
1978
1979#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1980/* ---------------------------------------------------------------------------
1981
1982 \fn csrNeighborRoamIssueNeighborRptRequest
1983
1984 \brief This function is invoked when TL issues a down event and the current assoc
1985 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1986 the currently associated AP with the current SSID
1987
1988 \param pMac - The handle returned by macOpen.
1989
1990 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1991
1992---------------------------------------------------------------------------*/
1993VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1994{
1995 tRrmNeighborRspCallbackInfo callbackInfo;
1996 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1997 tRrmNeighborReq neighborReq;
1998
1999
2000 neighborReq.no_ssid = 0;
2001
2002 /* Fill in the SSID */
2003 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
2004 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
2005 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
2006
2007 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
2008 callbackInfo.neighborRspCallbackContext = pMac;
2009 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
2010
2011 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
2012}
2013
2014/* ---------------------------------------------------------------------------
2015
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002016 \fn csrNeighborRoamMergeChannelLists
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002017
2018 \brief This function is used to merge two channel list.
2019 NB: If called with outputNumOfChannels == 0, this routines
2020 simply copies the input channel list to the output channel list.
2021
2022 \param pMac - The handle returned by macOpen.
2023 \param pInputChannelList - The addtional channels to merge in to the "merged" channels list.
2024 \param inputNumOfChannels - The number of additional channels.
2025 \param pOutputChannelList - The place to put the "merged" channel list.
2026 \param outputNumOfChannels - The original number of channels in the "merged" channels list.
2027 \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list.
2028
2029 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2030
2031---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002032VOS_STATUS csrNeighborRoamMergeChannelLists(
2033 tpAniSirGlobal pMac,
2034 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002035 int inputNumOfChannels,
2036 tANI_U8 *pOutputChannelList,
2037 int outputNumOfChannels,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002038 int *pMergedOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002039 )
2040{
2041 int i = 0;
2042 int j = 0;
2043 int numChannels = outputNumOfChannels;
2044
2045 // Check for NULL pointer
2046 if (!pInputChannelList) return eHAL_STATUS_E_NULL_VALUE;
2047
2048 // Check for NULL pointer
2049 if (!pOutputChannelList) return eHAL_STATUS_E_NULL_VALUE;
2050
2051 // Add the "new" channels in the input list to the end of the output list.
2052 for (i = 0; i < inputNumOfChannels; i++)
2053 {
2054 for (j = 0; j < outputNumOfChannels; j++)
2055 {
2056 if (pInputChannelList[i] == pOutputChannelList[j])
2057 break;
2058 }
2059 if (j == outputNumOfChannels)
2060 {
2061 if (pInputChannelList[i])
2062 {
Madan Mohan Koyyalamudif5c368b2012-12-06 13:10:13 -08002063 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002064 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
2065 pInputChannelList[i]);
2066 pOutputChannelList[numChannels] = pInputChannelList[i];
2067 numChannels++;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002068 }
2069 }
2070 }
2071
2072 // Return final number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002073 *pMergedOutputNumOfChannels = numChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002074
2075 return eHAL_STATUS_SUCCESS;
2076}
2077
2078/* ---------------------------------------------------------------------------
2079
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 \fn csrNeighborRoamCreateChanListFromNeighborReport
2081
2082 \brief This function is invoked when neighbor report is received for the
2083 neighbor request. Based on the channels present in the neighbor report,
2084 it generates channel list which will be used in REPORT_SCAN state to
2085 scan for these neighbor APs
2086
2087 \param pMac - The handle returned by macOpen.
2088
2089 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2090
2091---------------------------------------------------------------------------*/
2092VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
2093{
2094 tpRrmNeighborReportDesc pNeighborBssDesc;
2095 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002096 tANI_U8 numChannels = 0, i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002098#if 0
2099 eHalStatus status = eHAL_STATUS_SUCCESS;
2100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002101
2102 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
2103 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
2104
2105 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
2106
2107 while (pNeighborBssDesc)
2108 {
2109 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
2110
2111 /* Update the neighbor BSS Info in the 11r FT Roam Info */
2112 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
2113 pNeighborBssDesc->pNeighborBssDescription->channel;
2114 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
2115 (tANI_U8)pNeighborBssDesc->roamScore;
2116 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
2117 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
2118 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
2119
2120 /* Saving the channel list non-redundantly */
2121 if (numChannels > 0)
2122 {
2123 for (i = 0; i < numChannels; i++)
2124 {
2125 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
2126 break;
2127 }
2128
2129 }
2130 if (i == numChannels)
2131 {
2132 if (pNeighborBssDesc->pNeighborBssDescription->channel)
2133 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
2135 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
2136 pNeighborBssDesc->pNeighborBssDescription->channel);
2137 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
2138 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 }
2140 }
2141
2142 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
2143 }
2144
2145 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2146 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002147#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -07002148 // Before we free the existing channel list for a safety net make sure
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002149 // we have a union of the IAPP and the already existing list.
2150 status = csrNeighborRoamMergeChannelLists(
2151 pMac,
2152 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2153 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels,
2154 channelList,
2155 numChannels,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002156 &numChannels );
2157#endif
2158
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2160 }
2161
2162 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2163 /* Store the obtained channel list to the Neighbor Control data structure */
2164 if (numChannels)
2165 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
2166 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2167 {
2168 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
2169 return VOS_STATUS_E_RESOURCES;
2170 }
2171
2172 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2173 channelList, (numChannels) * sizeof(tANI_U8));
2174 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
2175 if (numChannels)
2176 {
2177 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
2178 pNeighborRoamInfo->neighborRoamState);
2179 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
2180 }
2181 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2182 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
2183
2184 return VOS_STATUS_SUCCESS;
2185}
2186
2187/* ---------------------------------------------------------------------------
2188
2189 \fn csrNeighborRoamRRMNeighborReportResult
2190
2191 \brief This function is the neighbor report callback that will be invoked by
2192 SME RRM on receiving a neighbor report or of neighbor report is not
2193 received after timeout. On receiving a valid report, it generates a
2194 channel list from the neighbor report and starts the
2195 neighbor scan timer
2196
2197 \param context - The handle returned by macOpen.
2198 vosStatus - Status of the callback(SUCCESS/FAILURE)
2199
2200 \return VOID
2201
2202---------------------------------------------------------------------------*/
2203void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
2204{
2205 tpAniSirGlobal pMac = PMAC_STRUCT(context);
2206 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2207 eHalStatus status = eHAL_STATUS_SUCCESS;
2208
2209 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
2210 switch (pNeighborRoamInfo->neighborRoamState)
2211 {
2212 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
2213 /* Reset the report pending variable */
2214 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
2215 if (VOS_STATUS_SUCCESS == vosStatus)
2216 {
2217 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
2218 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
2219 if (VOS_STATUS_SUCCESS == vosStatus)
2220 {
2221 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
2222 }
2223
2224 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2225 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2226
2227 /* Now ready for neighbor scan based on the channel list created */
2228 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2229 what palTimerStart expects */
2230 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2231 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2232 eANI_BOOLEAN_FALSE);
2233 if (eHAL_STATUS_SUCCESS != status)
2234 {
2235 /* Timer start failed.. Should we ASSERT here??? */
2236 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
2237 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2238 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2239 return;
2240 }
2241 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2242 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
2243 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
2244 }
2245 else
2246 {
2247 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
2248 reach the maxNeighborRetries or receiving a successful neighbor response */
2249 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
2250 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
2251 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
2252 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
2253 {
2254 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
2255 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2256 if (VOS_STATUS_SUCCESS != vosStatus)
2257 {
2258 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
2259 return;
2260 }
2261 /* We transitioned to different state now. Reset the Neighbor report retry count */
2262 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2263 }
2264 else
2265 {
2266 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2267 if (VOS_STATUS_SUCCESS != vosStatus)
2268 {
2269 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2270 return;
2271 }
2272 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2273 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2274 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2275 }
2276 }
2277 break;
2278 default:
2279 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
2280 break;
2281 }
2282 return;
2283}
2284#endif /* WLAN_FEATURE_VOWIFI_11R */
2285
2286
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002287#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002288tANI_BOOLEAN csrNeighborRoamIsSsidAndSecurityMatch(
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002289 tpAniSirGlobal pMac,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002290 tCsrRoamConnectedProfile *pCurProfile,
2291 tSirBssDescription *pBssDesc,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002292 tDot11fBeaconIEs *pIes)
2293{
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002294 tCsrAuthList authType;
2295 tCsrEncryptionList uCEncryptionType;
2296 tCsrEncryptionList mCEncryptionType;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002297 tANI_BOOLEAN fMatch = FALSE;
2298
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002299 authType.numEntries = 1;
2300 authType.authType[0] = pCurProfile->AuthType;
2301 uCEncryptionType.numEntries = 1;
2302 uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
2303 mCEncryptionType.numEntries = 1;
2304 mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002305
2306 if( pIes )
2307 {
2308 if(pIes->SSID.present)
2309 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002310 fMatch = csrIsSsidMatch( pMac,
2311 (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length,
2312 pIes->SSID.ssid, pIes->SSID.num_ssid,
2313 eANI_BOOLEAN_TRUE );
2314 if(TRUE == fMatch)
2315 {
2316 fMatch = csrIsSecurityMatch( pMac, &authType, &uCEncryptionType,
2317 &mCEncryptionType, pBssDesc, pIes, NULL, NULL, NULL );
2318 return (fMatch);
2319 }
2320 else
2321 {
2322 return (fMatch);
2323 }
2324
2325 }
2326 else
2327 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002328 return FALSE; // Treat a missing SSID as a non-match.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002329 }
2330 }
2331 else
2332 {
2333 return FALSE; // Again, treat missing pIes as a non-match.
2334 }
2335}
2336
2337tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile(
2338 tpAniSirGlobal pMac)
2339{
2340 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2341 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
2342 tCsrRoamConnectedProfile *pCurrProfile = NULL;
2343 tCsrRoamConnectedProfile *pPrevProfile = NULL;
2344 tDot11fBeaconIEs *pIes = NULL;
2345 tSirBssDescription *pBssDesc = NULL;
2346 tANI_BOOLEAN fNew = TRUE;
2347
2348 if(!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId)))
2349 {
2350 return (fNew);
2351 }
2352
2353 pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
2354 if( !pCurrProfile )
2355 {
2356 return (fNew);
2357}
2358
2359 pPrevProfile = &pNeighborRoamInfo->prevConnProfile;
2360 if( !pPrevProfile )
2361 {
2362 return (fNew);
2363 }
2364
2365 pBssDesc = pPrevProfile->pBssDesc;
2366 if (pBssDesc)
2367 {
2368 if (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
2369 pBssDesc, &pIes)) &&
2370 csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurrProfile, pBssDesc, pIes))
2371 {
2372 fNew = FALSE;
2373 }
2374 if (pIes) {
2375 palFreeMemory(pMac->hHdd, pIes);
2376 }
2377 }
2378
2379 if (fNew)
2380 {
2381 smsLog(pMac, LOG1, FL("Prev roam profile did not match current"));
2382 csrRoamFreeConnectProfile(pMac, pPrevProfile);
2383 csrRoamGetConnectProfile(pMac, sessionId, pPrevProfile);
2384 }
2385 else
2386 {
2387 smsLog(pMac, LOG1, FL("Prev roam profile matches current"));
2388 }
2389
2390 return (fNew);
2391}
2392
2393tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch(
2394 tpAniSirGlobal pMac,
2395 tCsrScanResult *pResult,
2396 tDot11fBeaconIEs *pIes)
2397{
2398 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2399 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
2400 tCsrRoamConnectedProfile *pCurProfile = NULL;
2401 tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor;
2402
2403 if( !(pMac->roam.roamSession
2404 && CSR_IS_SESSION_VALID(pMac, sessionId)))
2405 {
2406 return FALSE;
2407 }
2408
2409 pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
2410
2411 if( !pCurProfile)
2412 {
2413 return FALSE;
2414 }
2415
2416 return csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurProfile, pBssDesc, pIes);
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002417}
2418
2419/* ---------------------------------------------------------------------------
2420
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002421 \fn csrNeighborRoamPrepareNonOccupiedChannelList
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002422
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002423 \brief This function is used to prepare a channel list that is derived from
2424 the list of valid channels and does not include those in the occupied
2425 list.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002426
2427 \param pMac - The handle returned by macOpen.
2428 \param pInputChannelList - The default channels list.
2429 \param numOfChannels - The number of channels in the default channels list.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002430 \param pOutputChannelList - The place to put the non-occupied channel list.
2431 \param pOutputNumOfChannels - The number of channels in the non-occupied channel list.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002432
2433 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2434
2435---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002436VOS_STATUS csrNeighborRoamPrepareNonOccupiedChannelList(
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002437 tpAniSirGlobal pMac,
2438 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002439 int numOfChannels,
2440 tANI_U8 *pOutputChannelList,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002441 int *pOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002442 )
2443{
2444 int i = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002445 int outputNumOfChannels = 0; // Clear the output number of channels
2446 tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels;
2447 tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList;
2448
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002449 for (i = 0; i < numOfChannels; i++)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002450 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002451 if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels,
2452 pInputChannelList[i]))
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002453 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002454 pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002455 }
2456 }
2457
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002458 smsLog(pMac, LOG2, FL("Number of channels in the valid channel list=%d; "
2459 "Number of channels in the non-occupied list list=%d"),
2460 numOfChannels, outputNumOfChannels);
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002461
2462 // Return the number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002463 *pOutputNumOfChannels = outputNumOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002464
2465 return eHAL_STATUS_SUCCESS;
2466}
2467#endif /* FEATURE_WLAN_LFR */
2468
Jeff Johnson295189b2012-06-20 16:38:30 -07002469/* ---------------------------------------------------------------------------
2470
2471 \fn csrNeighborRoamTransitToCFGChanScan
2472
2473 \brief This function is called whenever there is a transition to CFG chan scan
2474 state from any state. It frees up the current channel list and allocates
2475 a new memory for the channels received from CFG item. It then starts the
2476 neighbor scan timer to perform the scan on each channel one by one
2477
2478 \param pMac - The handle returned by macOpen.
2479
2480 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2481
2482---------------------------------------------------------------------------*/
2483VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
2484{
2485 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2486 eHalStatus status = eHAL_STATUS_SUCCESS;
2487 int i = 0;
2488 int numOfChannels = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002489 tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002490 tpCsrChannelInfo currChannelListInfo;
2491
2492 currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07002493
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002494 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07002495#ifdef FEATURE_WLAN_CCX
2496 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002497 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07002498 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
2499#endif // CCX
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002500 currChannelListInfo->numOfChannels == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002501 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002502 smsLog(pMac, LOGW, FL("Building channel list to scan"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002503
2504
2505 /* Free up the channel list and allocate a new memory. This is because we dont know how much
2506 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
2507 result in memory corruption */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002508 if (NULL != currChannelListInfo->ChannelList)
Jeff Johnson295189b2012-06-20 16:38:30 -07002509 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002510 vos_mem_free(currChannelListInfo->ChannelList);
2511 currChannelListInfo->ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002513
2514 // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER
2515 // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR.
2516 if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002518 // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini".
2519 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini");
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002520 status = csrNeighborRoamMergeChannelLists(
2521 pMac,
2522 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2523 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels,
2524 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002525 0, //NB: If 0, simply copy the input channel list to the output list.
2526 &numOfChannels );
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002527
2528 currChannelListInfo->ChannelList =
2529 vos_mem_malloc(numOfChannels*sizeof(tANI_U8));
2530 if (NULL == currChannelListInfo->ChannelList)
2531 {
2532 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2533 return VOS_STATUS_E_RESOURCES;
2534 }
2535
2536 vos_mem_copy(currChannelListInfo->ChannelList,
2537 channelList, numOfChannels * sizeof(tANI_U8));
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002538 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002539 else
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002540 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002541 /* Get current list of valid channels. */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002542 numOfChannels = pMac->scan.occupiedChannels.numChannels;
2543 if (numOfChannels
2544#ifdef FEATURE_WLAN_LFR
2545 && ((pNeighborRoamInfo->uEmptyScanCount == 0) ||
2546 ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1))
2547#endif
2548 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002550 /*
2551 * Always scan channels in the occupied channel list
2552 * before scanning on the non-occupied list.
2553 */
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302554 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to occupied channel list");
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002555 VOS_ASSERT(currChannelListInfo->ChannelList == NULL);
2556 currChannelListInfo->ChannelList = vos_mem_malloc(numOfChannels);
2557
2558 if (NULL == currChannelListInfo->ChannelList)
2559 {
2560 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2561 return VOS_STATUS_E_RESOURCES;
2562 }
2563 vos_mem_copy(currChannelListInfo->ChannelList,
2564 pMac->scan.occupiedChannels.channelList,
2565 numOfChannels * sizeof(tANI_U8));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002566 }
2567 else
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002568 {
2569 /* Scan all channels from non-occupied list */
2570 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Get valid channel list");
2571 numOfChannels = sizeof(pMac->roam.validChannelList);
2572
2573 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac,
2574 (tANI_U8 *)pMac->roam.validChannelList,
2575 (tANI_U32 *) &numOfChannels)))
2576 {
2577#ifdef FEATURE_WLAN_LFR
2578 /*
2579 * Prepare non-occupied channel list (channelList)
2580 * from the actual "valid channel list" information
2581 * formed by CSR.
2582 */
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302583 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to non-occupied channel list");
2584 status = csrNeighborRoamPrepareNonOccupiedChannelList(pMac,
2585 (tANI_U8 *)pMac->roam.validChannelList,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002586 numOfChannels,
2587 channelList,
2588 &numOfChannels);
2589#else
2590 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Merging channel list");
2591 status = csrNeighborRoamMergeChannelLists(
2592 pMac,
2593 (tANI_U8 *)pMac->roam.validChannelList,
2594 numOfChannels, // The number of channels in the validChannelList
2595 channelList,
2596 0, //NB: If 0, simply copy the input channel list to the output list.
2597 &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels
2598#endif
2599 }
2600 else
2601 {
2602 smsLog(pMac, LOGE, FL("Could not get valid channel list"));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002603 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002605 currChannelListInfo->ChannelList =
2606 vos_mem_malloc(numOfChannels*sizeof(tANI_U8));
2607
2608 if (NULL == currChannelListInfo->ChannelList)
2609 {
2610 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2611 return VOS_STATUS_E_RESOURCES;
2612 }
2613#ifdef FEATURE_WLAN_LFR
2614 vos_mem_copy(currChannelListInfo->ChannelList,
2615 channelList, numOfChannels * sizeof(tANI_U8));
2616#else
2617 vos_mem_copy(currChannelListInfo->ChannelList,
2618 (tANI_U8 *)pMac->roam.validChannelList,
2619 numOfChannels * sizeof(tANI_U8));
2620#endif
2621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 }
2623
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002624 /* Adjust for the actual number that are used */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002625 currChannelListInfo->numOfChannels = numOfChannels;
2626 for (i = 0; i < currChannelListInfo->numOfChannels; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07002627 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302628 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Channel List from CFG (or) (non-)occupied list"
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002629 "= %d\n", currChannelListInfo->ChannelList[i]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 }
2631 }
2632
2633 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2634 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2635
2636 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2637 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2638 what palTimerStart expects */
2639 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2640 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2641 eANI_BOOLEAN_FALSE);
2642
2643 if (eHAL_STATUS_SUCCESS != status)
2644 {
2645 /* Timer start failed.. */
2646 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002647 vos_mem_free(currChannelListInfo->ChannelList);
2648 currChannelListInfo->ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002649 return VOS_STATUS_E_FAILURE;
2650 }
2651
2652 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2653 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302654 /* We are about to start a fresh scan cycle,
2655 * purge non-P2P results from the past */
2656 csrScanFlushSelectiveResult(pMac, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002657
2658 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2659 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2660
2661 return VOS_STATUS_SUCCESS;
2662}
2663
2664/* ---------------------------------------------------------------------------
2665
2666 \fn csrNeighborRoamNeighborLookupUpEvent
2667
2668 \brief This function is called as soon as TL indicates that the current AP's
2669 RSSI is better than the neighbor lookup threshold. Here, we transition to
2670 CONNECTED state and reset all the scan parameters
2671
2672 \param pMac - The handle returned by macOpen.
2673
2674 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2675
2676---------------------------------------------------------------------------*/
2677VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2678{
2679 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2680 VOS_STATUS vosStatus;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002681 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002682
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 /* Recheck whether the below check is needed. */
2684 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2685 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
Jeff Johnsone7245742012-09-05 17:12:55 -07002686
2687 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2688 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2689
Jeff Johnson295189b2012-06-20 16:38:30 -07002690
2691 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2692 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2693 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2694 WLANTL_HO_THRESHOLD_DOWN,
2695 csrNeighborRoamNeighborLookupDOWNCallback,
2696 VOS_MODULE_ID_SME, pMac);
2697 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2698 {
2699 //err msg
2700 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2701 }
2702
2703
2704 return vosStatus;
2705}
2706
2707/* ---------------------------------------------------------------------------
2708
2709 \fn csrNeighborRoamNeighborLookupDownEvent
2710
2711 \brief This function is called as soon as TL indicates that the current AP's
2712 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2713 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2714 a non-11R association.
2715
2716 \param pMac - The handle returned by macOpen.
2717
2718 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2719
2720---------------------------------------------------------------------------*/
2721VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2722{
2723 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2724 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2725 eHalStatus status = eHAL_STATUS_SUCCESS;
2726
2727 switch (pNeighborRoamInfo->neighborRoamState)
2728 {
2729 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2730
2731 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2732 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2733 /* De-register Neighbor Lookup threshold callback with TL */
2734 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2735 WLANTL_HO_THRESHOLD_DOWN,
2736 csrNeighborRoamNeighborLookupDOWNCallback,
2737 VOS_MODULE_ID_SME);
2738
2739 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2740 {
2741 //err msg
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002742 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002743 }
2744
2745
2746#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2747 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2748 {
2749
2750 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2751 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2752 if (VOS_STATUS_SUCCESS != vosStatus)
2753 {
2754 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2755 return vosStatus;
2756 }
2757 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2758 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2759 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2760 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2761 }
2762 else
2763#endif
2764 {
2765 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2766
2767 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2768 if (VOS_STATUS_SUCCESS != vosStatus)
2769 {
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08002770 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamTransitToCFGChanScan failed"
2771 " with status=%d"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002772 return vosStatus;
2773 }
2774 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002775 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
Jeff Johnson295189b2012-06-20 16:38:30 -07002776 /* Register Neighbor Lookup threshold callback with TL for UP event now */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002777 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
2778 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002779 WLANTL_HO_THRESHOLD_UP,
2780 csrNeighborRoamNeighborLookupUPCallback,
2781 VOS_MODULE_ID_SME, pMac);
2782 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2783 {
2784 //err msg
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08002785 smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002786 }
2787 break;
2788 default:
2789 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2790 break;
2791
2792 }
2793 return vosStatus;
2794}
2795
2796/* ---------------------------------------------------------------------------
2797
2798 \fn csrNeighborRoamNeighborLookupUPCallback
2799
2800 \brief This function is registered with TL to indicate whenever the RSSI
2801 gets better than the neighborLookup RSSI Threshold
2802
2803 \param pAdapter - VOS Context
2804 trafficStatus - UP/DOWN indication from TL
2805 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2806
2807 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2808
2809---------------------------------------------------------------------------*/
2810VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
Srinivasdaaec712012-12-12 15:59:44 -08002811 v_PVOID_t pUserCtxt,
2812 v_S7_t avgRssi)
Jeff Johnson295189b2012-06-20 16:38:30 -07002813{
2814 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2815 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2816 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2817
Srinivasdaaec712012-12-12 15:59:44 -08002818 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup UP indication callback called with notification %d Reported RSSI = %d"),
2819 rssiNotification,
2820 avgRssi);
Jeff Johnson295189b2012-06-20 16:38:30 -07002821
2822 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2823 {
2824 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2825 return VOS_STATUS_SUCCESS;
2826 }
2827
2828 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2829 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2830 return vosStatus;
2831}
2832
2833/* ---------------------------------------------------------------------------
2834
2835 \fn csrNeighborRoamNeighborLookupDOWNCallback
2836
2837 \brief This function is registered with TL to indicate whenever the RSSI
2838 falls below the current neighborLookup RSSI Threshold
2839
2840 \param pAdapter - VOS Context
2841 trafficStatus - UP/DOWN indication from TL
2842 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2843
2844 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2845
2846---------------------------------------------------------------------------*/
2847VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
Srinivasdaaec712012-12-12 15:59:44 -08002848 v_PVOID_t pUserCtxt,
2849 v_S7_t avgRssi)
Jeff Johnson295189b2012-06-20 16:38:30 -07002850{
2851 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2852 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2853 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2854
Srinivasdaaec712012-12-12 15:59:44 -08002855 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup DOWN indication callback called with notification %d Reported RSSI = %d"),
2856 rssiNotification,
2857 avgRssi);
Jeff Johnson295189b2012-06-20 16:38:30 -07002858
2859 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2860 {
2861 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2862 return VOS_STATUS_SUCCESS;
2863 }
2864
2865 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2866 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2867
2868 return vosStatus;
2869}
2870
2871#ifdef RSSI_HACK
2872extern int dumpCmdRSSI;
2873#endif
2874
2875/* ---------------------------------------------------------------------------
2876
2877 \fn csrNeighborRoamIndicateDisconnect
2878
2879 \brief This function is called by CSR as soon as the station disconnects from
2880 the AP. This function does the necessary cleanup of neighbor roam data
2881 structures. Neighbor roam state transitions to INIT state whenever this
2882 function is called except if the current state is REASSOCIATING
2883
2884 \param pMac - The handle returned by macOpen.
2885 sessionId - CSR session id that got disconnected
2886
2887 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2888
2889---------------------------------------------------------------------------*/
2890eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2891{
2892 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2893
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002894 smsLog(pMac, LOGE, FL("Disconnect indication on session %d in state %d (sub-state %d)"),
2895 sessionId, pNeighborRoamInfo->neighborRoamState,
2896 pMac->roam.curSubState[sessionId]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002897
2898#ifdef FEATURE_WLAN_CCX
2899 {
2900 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2901 if (pSession->connectedProfile.isCCXAssoc)
2902 {
2903 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2904 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2905 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2906 pSession->isPrevApInfoValid = TRUE;
2907 pSession->roamTS1 = vos_timer_get_system_time();
2908
2909 }
2910 }
2911#endif
2912
2913#ifdef RSSI_HACK
2914 dumpCmdRSSI = -40;
2915#endif
2916 switch (pNeighborRoamInfo->neighborRoamState)
2917 {
2918 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2919 // Stop scan and neighbor refresh timers.
2920 // These are indeed not required when we are in reassociating
2921 // state.
2922 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2923 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002924 if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId )) {
2925 /*
2926 * Disconnect indication during Disassoc Handoff sub-state
2927 * is received when we are trying to disconnect with the old
2928 * AP during roam. BUT, if receive a disconnect indication
2929 * outside of Disassoc Handoff sub-state, then it means that
2930 * this is a genuine disconnect and we need to clean up.
2931 * Otherwise, we will be stuck in reassoc state which will
2932 * in-turn block scans (see csrIsScanAllowed).
2933 */
2934 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2935 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 break;
2937
2938 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 csrNeighborRoamResetInitStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002940 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002941 break;
2942
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002943 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
2944 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2945 csrNeighborRoamResetCfgListChanScanControlInfo(pMac);
2946 csrNeighborRoamDeregAllRssiIndication(pMac);
2947 break;
2948
2949 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
2950 /* Stop pre-auth to reassoc interval timer */
2951 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002952 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2953 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2954 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002955 csrNeighborRoamResetPreauthControlInfo(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002956 csrNeighborRoamResetReportScanStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002957 csrNeighborRoamDeregAllRssiIndication(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002958 break;
2959
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 default:
Madan Mohan Koyyalamudi5695b502012-09-24 14:21:12 -07002961 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2962 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002963 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002964 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002965 }
2966 return eHAL_STATUS_SUCCESS;
2967}
2968
2969/* ---------------------------------------------------------------------------
2970
2971 \fn csrNeighborRoamIndicateConnect
2972
2973 \brief This function is called by CSR as soon as the station connects to an AP.
2974 This initializes all the necessary data structures related to the
2975 associated AP and transitions the state to CONNECTED state
2976
2977 \param pMac - The handle returned by macOpen.
2978 sessionId - CSR session id that got connected
2979 vosStatus - connect status SUCCESS/FAILURE
2980
2981 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2982
2983---------------------------------------------------------------------------*/
2984eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2985{
2986 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2987 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002988 VOS_STATUS vstatus;
2989
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002990#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 int init_ft_flag = FALSE;
2992#endif
2993
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002994 smsLog(pMac, LOG2, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002995
2996 switch (pNeighborRoamInfo->neighborRoamState)
2997 {
2998 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2999 if (VOS_STATUS_SUCCESS != vosStatus)
3000 {
3001 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
3002 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3003 break;
3004 }
3005 /* Fall through if the status is SUCCESS */
3006 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
3007 /* Reset all the data structures here */
3008 csrNeighborRoamResetInitStateControlInfo(pMac);
3009
Jeff Johnson295189b2012-06-20 16:38:30 -07003010 pNeighborRoamInfo->csrSessionId = sessionId;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08003011
3012#ifdef FEATURE_WLAN_LFR
3013 /*
3014 * Initialize the occupied list ONLY if we are
3015 * transitioning from INIT state to CONNECTED state.
3016 */
3017 if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState)
3018 csrInitOccupiedChannelsList(pMac);
3019#endif
3020 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
3021
Jeff Johnson295189b2012-06-20 16:38:30 -07003022 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
3023 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
3024 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
3025 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
3026 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08003027 pNeighborRoamInfo->currentNeighborLookupThreshold =
3028 pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
3029#ifdef FEATURE_WLAN_LFR
3030 pNeighborRoamInfo->uEmptyScanCount = 0;
3031#endif
3032
Jeff Johnson295189b2012-06-20 16:38:30 -07003033
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003034#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07003035 /* Now we can clear the preauthDone that was saved as we are connected afresh */
3036 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3037#endif
3038
3039#ifdef WLAN_FEATURE_VOWIFI_11R
3040 // Based on the auth scheme tell if we are 11r
Madan Mohan Koyyalamudi5e32b962012-11-28 16:07:55 -08003041 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType,
3042 pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent))
Jeff Johnson295189b2012-06-20 16:38:30 -07003043 {
3044 if (pMac->roam.configParam.isFastTransitionEnabled)
3045 init_ft_flag = TRUE;
3046 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
3047 }
3048 else
3049 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003050 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
Jeff Johnson295189b2012-06-20 16:38:30 -07003051#endif
3052
3053#ifdef FEATURE_WLAN_CCX
3054 // Based on the auth scheme tell if we are 11r
3055 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
3056 {
3057 if (pMac->roam.configParam.isFastTransitionEnabled)
3058 init_ft_flag = TRUE;
3059 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
3060 }
3061 else
3062 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003063 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isCCXAssoc is = %d ft = %d"),
3064 pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
Jeff Johnson295189b2012-06-20 16:38:30 -07003065
3066#endif
3067
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003068#ifdef FEATURE_WLAN_LFR
3069 // If "Legacy Fast Roaming" is enabled
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05303070 if (csrRoamIsFastRoamEnabled(pMac, sessionId))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003071 {
3072 init_ft_flag = TRUE;
3073 }
3074#endif
3075
3076#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07003077 if ( init_ft_flag == TRUE )
3078 {
3079 /* Initialize all the data structures needed for the 11r FT Preauth */
3080 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
3081 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
3082 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
3083 csrNeighborRoamPurgePreauthFailedList(pMac);
3084
3085 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
3086 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07003087 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 WLANTL_HO_THRESHOLD_DOWN,
3089 csrNeighborRoamNeighborLookupDOWNCallback,
3090 VOS_MODULE_ID_SME, pMac);
3091
Jeff Johnson43971f52012-07-17 12:26:56 -07003092 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07003093 {
3094 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07003095 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
3096 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003097 }
3098 }
3099#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 break;
3101 default:
3102 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
3103 break;
3104 }
3105 return status;
3106}
3107
3108
3109#ifdef WLAN_FEATURE_VOWIFI_11R
3110/* ---------------------------------------------------------------------------
3111
3112 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
3113
3114 \brief If this function is invoked, that means the preauthentication response
3115 is timed out from the PE. Preauth rsp handler is called with status as
3116 TIMEOUT
3117
3118 \param context - CSR Timer info which holds pMac and session ID
3119
3120 \return VOID
3121
3122---------------------------------------------------------------------------*/
3123void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
3124{
3125 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
3126 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
3127 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3128
3129 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
3130
3131 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
3132}
3133
3134/* ---------------------------------------------------------------------------
3135
3136 \fn csrNeighborRoamPurgePreauthFailedList
3137
3138 \brief This function purges all the MAC addresses in the pre-auth fail list
3139
3140 \param pMac - The handle returned by macOpen.
3141
3142 \return VOID
3143
3144---------------------------------------------------------------------------*/
3145void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
3146{
3147 tANI_U8 i;
3148
3149 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
3150 {
3151 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
3152 }
3153 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
3154
3155 return;
3156}
3157
3158/* ---------------------------------------------------------------------------
3159
3160 \fn csrNeighborRoamInit11rAssocInfo
3161
3162 \brief This function initializes 11r related neighbor roam data structures
3163
3164 \param pMac - The handle returned by macOpen.
3165
3166 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
3167
3168---------------------------------------------------------------------------*/
3169eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
3170{
3171 eHalStatus status;
3172 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
3173
3174 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
3175 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
3176 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
3177 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
3178 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
3179 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
3180
3181 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
3182 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3183 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
3184 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
3185
3186 if (eHAL_STATUS_SUCCESS != status)
3187 {
3188 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3189 return eHAL_STATUS_RESOURCES;
3190 }
3191
3192 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
3193 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
3194 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
3195 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
3196
3197
3198 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
3199 if (eHAL_STATUS_SUCCESS != status)
3200 {
3201 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
3202 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
3203 return eHAL_STATUS_RESOURCES;
3204 }
3205 return status;
3206}
3207#endif /* WLAN_FEATURE_VOWIFI_11R */
3208
3209/* ---------------------------------------------------------------------------
3210
3211 \fn csrNeighborRoamInit
3212
3213 \brief This function initializes neighbor roam data structures
3214
3215 \param pMac - The handle returned by macOpen.
3216
3217 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
3218
3219---------------------------------------------------------------------------*/
3220eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
3221{
3222 eHalStatus status;
3223 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3224
3225 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
3226 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
3227 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
3228 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
3229 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
3230 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
3231 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
3232 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
3233 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
3234 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
3235
3236 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
3237 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
3238
3239 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
3240 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
3241
3242 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
3243 {
3244 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
3245 return eHAL_STATUS_RESOURCES;
3246 }
3247
3248 /* Update the roam global structure from CFG */
3249 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
3250 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
3251 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
3252
3253 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
3254 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08003255#ifdef FEATURE_WLAN_LFR
3256 pNeighborRoamInfo->uEmptyScanCount = 0;
3257 palZeroMemory(pMac->hHdd, &pNeighborRoamInfo->prevConnProfile,
3258 sizeof(tCsrRoamConnectedProfile));
3259#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003260 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
3261
3262 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
3263 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3264 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
3265 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
3266
3267 if (eHAL_STATUS_SUCCESS != status)
3268 {
3269 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3270 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3271 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3272 return eHAL_STATUS_RESOURCES;
3273 }
3274
3275 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
3276 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
3277
3278 if (eHAL_STATUS_SUCCESS != status)
3279 {
3280 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3281 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3282 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3283 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3284 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3285 return eHAL_STATUS_RESOURCES;
3286 }
3287
3288 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
3289 if (eHAL_STATUS_SUCCESS != status)
3290 {
3291 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3292 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3293 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3294 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3295 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3296 return eHAL_STATUS_RESOURCES;
3297 }
3298
3299 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
3300 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
3301 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3302 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
3303 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
3304
3305#ifdef WLAN_FEATURE_VOWIFI_11R
3306 status = csrNeighborRoamInit11rAssocInfo(pMac);
3307 if (eHAL_STATUS_SUCCESS != status)
3308 {
3309 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3310 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3311 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3312 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3313 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3314 csrLLClose(&pNeighborRoamInfo->roamableAPList);
3315 return eHAL_STATUS_RESOURCES;
3316 }
3317#endif
3318 /* Initialize this with the current tick count */
3319 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
3320
3321 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3322
3323 return eHAL_STATUS_SUCCESS;
3324}
3325
3326/* ---------------------------------------------------------------------------
3327
3328 \fn csrNeighborRoamClose
3329
3330 \brief This function closes/frees all the neighbor roam data structures
3331
3332 \param pMac - The handle returned by macOpen.
3333
3334 \return VOID
3335
3336---------------------------------------------------------------------------*/
3337void csrNeighborRoamClose(tpAniSirGlobal pMac)
3338{
3339 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3340
3341 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
3342 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07003343 smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003344 return;
3345 }
3346
3347 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
3348 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3349
3350 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3351
3352 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
3353 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3354 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3355 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3356
3357 /* Should free up the nodes in the list before closing the double Linked list */
3358 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
3359 csrLLClose(&pNeighborRoamInfo->roamableAPList);
3360
3361 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
3362 {
3363 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
3364 }
3365
3366 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3367 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
3368 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
3369 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3370 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
3371 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
3372
3373 /* Free the profile.. */
3374 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
Sandeep Pc4818ef2012-12-13 14:19:25 -08003375#ifdef FEATURE_WLAN_LFR
Sandeep Pc2b00f62012-12-12 16:44:44 -08003376 csrRoamFreeConnectProfile(pMac, &pNeighborRoamInfo->prevConnProfile);
Sandeep Pc4818ef2012-12-13 14:19:25 -08003377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003378#ifdef WLAN_FEATURE_VOWIFI_11R
3379 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
3380 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
3381 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
3382 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3383 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
3384 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
3385 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
3386 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3387 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3388#endif /* WLAN_FEATURE_VOWIFI_11R */
3389
3390 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
3391
3392 return;
3393}
3394
3395/* ---------------------------------------------------------------------------
3396
3397 \fn csrNeighborRoamRequestHandoff
3398
3399 \brief This function triggers actual switching from one AP to the new AP.
3400 It issues disassociate with reason code as Handoff and CSR as a part of
3401 handling disassoc rsp, issues reassociate to the new AP
3402
3403 \param pMac - The handle returned by macOpen.
3404
3405 \return VOID
3406
3407---------------------------------------------------------------------------*/
3408void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
3409{
3410
3411 tCsrRoamInfo roamInfo;
3412 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3413 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
3414 tCsrNeighborRoamBSSInfo handoffNode;
3415 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
3416 tANI_U32 roamId = 0;
3417
3418 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
3419 {
3420 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
3421 pMac->roam.neighborRoamInfo.neighborRoamState);
3422 return;
3423 }
3424
3425 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3426 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
3427 eSIR_SME_SUCCESS);
3428
3429 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3430 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
3431
3432 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
3433 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
3434 handoffNode.pBssDescription->bssId[0],
3435 handoffNode.pBssDescription->bssId[1],
3436 handoffNode.pBssDescription->bssId[2],
3437 handoffNode.pBssDescription->bssId[3],
3438 handoffNode.pBssDescription->bssId[4],
3439 handoffNode.pBssDescription->bssId[5]);
3440
3441 /* Free the profile.. Just to make sure we dont leak memory here */
3442 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
3443 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
3444 This should happen before issuing disconnect */
3445 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
3446 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
3447 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
3448
3449 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
3450
3451 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
3452 {
3453 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
3454 return;
3455 }
3456
3457 //notify HDD for handoff, providing the BSSID too
3458 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
3459
3460 vos_mem_copy(roamInfo.bssid,
3461 handoffNode.pBssDescription->bssId,
3462 sizeof( tCsrBssid ));
3463
3464 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
3465
3466
3467 return;
3468}
3469
3470/* ---------------------------------------------------------------------------
3471
3472 \fn csrNeighborRoamIsHandoffInProgress
3473
3474 \brief This function returns whether handoff is in progress or not based on
3475 the current neighbor roam state
3476
3477 \param pMac - The handle returned by macOpen.
3478 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
3479
3480 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
3481
3482---------------------------------------------------------------------------*/
3483tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
3484{
3485 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
3486 return eANI_BOOLEAN_TRUE;
3487
3488 return eANI_BOOLEAN_FALSE;
3489}
3490
Madan Mohan Koyyalamudi5e32b962012-11-28 16:07:55 -08003491#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(WLAN_FEATURE_NEIGHBOR_ROAMING)
Jeff Johnson295189b2012-06-20 16:38:30 -07003492/* ---------------------------------------------------------------------------
3493
3494 \fn csrNeighborRoamIs11rAssoc
3495
3496 \brief This function returns whether the current association is a 11r assoc or not
3497
3498 \param pMac - The handle returned by macOpen.
3499
3500 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
3501
3502---------------------------------------------------------------------------*/
3503tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
3504{
3505 return pMac->roam.neighborRoamInfo.is11rAssoc;
3506}
3507#endif /* WLAN_FEATURE_VOWIFI_11R */
3508
3509
3510/* ---------------------------------------------------------------------------
3511
3512 \fn csrNeighborRoamGetHandoffAPInfo
3513
3514 \brief This function returns the best possible AP for handoff. For 11R case, it
3515 returns the 1st entry from pre-auth done list. For non-11r case, it returns
3516 the 1st entry from roamable AP list
3517
3518 \param pMac - The handle returned by macOpen.
3519 pHandoffNode - AP node that is the handoff candidate returned
3520
3521 \return VOID
3522
3523---------------------------------------------------------------------------*/
3524void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
3525{
3526 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3527 tpCsrNeighborRoamBSSInfo pBssNode;
3528
3529 VOS_ASSERT(NULL != pHandoffNode);
3530
3531#ifdef WLAN_FEATURE_VOWIFI_11R
3532 if (pNeighborRoamInfo->is11rAssoc)
3533 {
3534 /* Always the BSS info in the head is the handoff candidate */
3535 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3536 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3537 }
3538 else
3539#endif
3540#ifdef FEATURE_WLAN_CCX
3541 if (pNeighborRoamInfo->isCCXAssoc)
3542 {
3543 /* Always the BSS info in the head is the handoff candidate */
3544 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3545 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3546 }
3547 else
3548#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003549#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05303550 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003551 {
3552 /* Always the BSS info in the head is the handoff candidate */
3553 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3554 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3555 }
3556 else
3557#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003558 {
3559 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
3560 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
3561 }
3562 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
3563
3564 return;
3565}
3566
3567/* ---------------------------------------------------------------------------
3568 \brief This function returns TRUE if preauth is completed
3569
3570 \param pMac - The handle returned by macOpen.
3571
3572 \return boolean
3573
3574---------------------------------------------------------------------------*/
3575tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
3576{
3577 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
3578 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
3579}
3580
3581/* ---------------------------------------------------------------------------
3582 \brief In the event that we are associated with AP1 and we have
3583 completed pre auth with AP2. Then we receive a deauth/disassoc from
3584 AP1.
3585 At this point neighbor roam is in pre auth done state, pre auth timer
3586 is running. We now handle this case by stopping timer and clearing
3587 the pre-auth state. We basically clear up and just go to disconnected
3588 state.
3589
3590 \param pMac - The handle returned by macOpen.
3591
3592 \return boolean
3593---------------------------------------------------------------------------*/
3594void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
3595{
3596 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
3597 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
3598
3599 // Stop timer
3600 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
3601
3602 // Transition to init state
3603 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3604}
3605
3606#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */