blob: 4094fd468ced3a94c71056c3bf7116e1817758d4 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * */
24/** ------------------------------------------------------------------------- *
25 ------------------------------------------------------------------------- *
26
27
28 \file csrNeighborRoam.c
29
30 Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform.
31
32 Copyright (C) 2010 Qualcomm, Incorporated
33
34
35 ========================================================================== */
36
37/*===========================================================================
38
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45
46
47 when who what, where, why
48---------- --- --------------------------------------------------------
4908/01/10 Murali Created
50
51===========================================================================*/
52#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
53#include "wlan_qct_wda.h"
54#include "palApi.h"
55#include "csrInsideApi.h"
56#include "smsDebug.h"
57#include "logDump.h"
58#include "smeQosInternal.h"
59#include "wlan_qct_tl.h"
60#include "smeInside.h"
61#include "vos_diag_core_event.h"
62#include "vos_diag_core_log.h"
63#include "csrApi.h"
64#include "wlan_qct_tl.h"
65#include "sme_Api.h"
66#include "csrNeighborRoam.h"
67#ifdef FEATURE_WLAN_CCX
68#include "csrCcx.h"
69#endif
70
71#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
72#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
73#define NEIGHBOR_ROAM_DEBUG smsLog
74#else
75#define NEIGHBOR_ROAM_DEBUG(x...)
76#endif
77
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -070078static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo);
79static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac);
80static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac);
81static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac);
82
Jeff Johnson295189b2012-06-20 16:38:30 -070083VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
84 v_PVOID_t pUserCtxt);
85VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
86 v_PVOID_t pUserCtxt);
87void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus);
88eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile );
89
90#ifdef WLAN_FEATURE_VOWIFI_11R
91static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac);
92VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac);
93#endif
94
95/* State Transition macro */
96#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
97{\
98 pMac->roam.neighborRoamInfo.prevNeighborRoamState = pMac->roam.neighborRoamInfo.neighborRoamState;\
99 pMac->roam.neighborRoamInfo.neighborRoamState = newState;\
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700100 smsLog(pMac, LOG1, FL("Neighbor Roam Transition from state %d ==> %d"), pMac->roam.neighborRoamInfo.prevNeighborRoamState, newState);\
Jeff Johnson295189b2012-06-20 16:38:30 -0700101}
102
103/* ---------------------------------------------------------------------------
104
105 \fn csrNeighborRoamFreeNeighborRoamBSSNode
106
107 \brief This function frees all the internal pointers CSR NeighborRoam BSS Info
108 and also frees the node itself
109
110 \param pMac - The handle returned by macOpen.
111 neighborRoamBSSNode - Neighbor Roam BSS Node to be freed
112
113 \return VOID
114
115---------------------------------------------------------------------------*/
116void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode)
117{
118 if (neighborRoamBSSNode)
119 {
120 if (neighborRoamBSSNode->pBssDescription)
121 {
122 vos_mem_free(neighborRoamBSSNode->pBssDescription);
123 neighborRoamBSSNode->pBssDescription = NULL;
124 }
125 vos_mem_free(neighborRoamBSSNode);
126 neighborRoamBSSNode = NULL;
127 }
128
129 return;
130}
131
132/* ---------------------------------------------------------------------------
133
134 \fn csrNeighborRoamRemoveRoamableAPListEntry
135
136 \brief This function removes a given entry from the given list
137
138 \param pMac - The handle returned by macOpen.
139 pList - The list from which the entry should be removed
140 pNeighborEntry - Neighbor Roam BSS Node to be removed
141
142 \return TRUE if successfully removed, else FALSE
143
144---------------------------------------------------------------------------*/
145tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
146 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
147{
148 if(pList)
149 {
150 return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
151 }
152
153 smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d\n"), csrLLCount(pList));
154
155 return eANI_BOOLEAN_FALSE;
156}
157
158/* ---------------------------------------------------------------------------
159
160 \fn csrNeighborRoamGetRoamableAPListNextEntry
161
162 \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list
163
164 \param pMac - The handle returned by macOpen.
165 pList - The list from which the entry should be returned
166 pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned
167
168 \return Neighbor Roam BSS Node to be returned
169
170---------------------------------------------------------------------------*/
171tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
172 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
173{
174 tListElem *pEntry = NULL;
175 tpCsrNeighborRoamBSSInfo pResult = NULL;
176
177 if(pList)
178 {
179 if(NULL == pNeighborEntry)
180 {
181 pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK);
182 }
183 else
184 {
185 pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
186 }
187 if(pEntry)
188 {
189 pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
190 }
191 }
192
193 return pResult;
194}
195
196/* ---------------------------------------------------------------------------
197
198 \fn csrNeighborRoamFreeRoamableBSSList
199
200 \brief Empties and frees all the nodes in the roamable AP list
201
202 \param pMac - The handle returned by macOpen.
203 pList - Neighbor Roam BSS List to be emptied
204
205 \return VOID
206
207---------------------------------------------------------------------------*/
208void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList)
209{
210 tpCsrNeighborRoamBSSInfo pResult = NULL;
211
Mohit Khanna23863762012-09-11 17:40:09 -0700212 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Emptying the BSS list. Current count = %d\n"), csrLLCount(pList));
Jeff Johnson295189b2012-06-20 16:38:30 -0700213
214 /* Pick up the head, remove and free the node till the list becomes empty */
215 while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL)
216 {
217 csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult);
218 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult);
219 }
220 return;
221}
222
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -0800223static void csrNeighborRoamTriggerHandoff(tpAniSirGlobal pMac,
224 tpCsrNeighborRoamControlInfo pNeighborRoamInfo)
225{
226#ifdef WLAN_FEATURE_VOWIFI_11R
227 if (pNeighborRoamInfo->is11rAssoc)
228 {
229 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
230 {
231 csrNeighborRoamIssuePreauthReq(pMac);
232 }
233 else
234 {
235 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
236 VOS_ASSERT(0);
237 }
238 }
239 else
240#endif
241
242#ifdef FEATURE_WLAN_CCX
243 if (pNeighborRoamInfo->isCCXAssoc)
244 {
245 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
246 {
247 csrNeighborRoamIssuePreauthReq(pMac);
248 }
249 else
250 {
251 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
252 VOS_ASSERT(0);
253 }
254 }
255 else
256#endif
257#ifdef FEATURE_WLAN_LFR
258 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
259 {
260 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
261 {
262 csrNeighborRoamIssuePreauthReq(pMac);
263 }
264 else
265 {
266 smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
267 VOS_ASSERT(0);
268 }
269 }
270 else
271#endif
272 {
273 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
274 {
275 csrNeighborRoamRequestHandoff(pMac);
276 }
277 else
278 {
279 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
280 VOS_ASSERT(0);
281 }
282 }
283}
284
Jeff Johnson295189b2012-06-20 16:38:30 -0700285/* ---------------------------------------------------------------------------
286
287 \fn csrNeighborRoamReassocIndCallback
288
289 \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold.
290 Directly triggere HO in case of non-11r association
291 In case of 11R association, triggers a pre-auth eventually followed by actual HO
292
293 \param pAdapter - VOS Context
294 trafficStatus - UP/DOWN indication from TL
295 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
296
297 \return VOID
298
299---------------------------------------------------------------------------*/
300VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter,
301 v_U8_t trafficStatus,
302 v_PVOID_t pUserCtxt)
303{
304 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
305 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
306 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
307
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
309
310
311 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
312 WLANTL_HO_THRESHOLD_DOWN,
313 csrNeighborRoamReassocIndCallback,
314 VOS_MODULE_ID_SME);
315
316 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
317 {
318 //err msg
319 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
320 }
321
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -0800322 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Rcvd reassoc notification-deregister UP indication. RSSI = %d"),
323 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
324 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
325 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
326 WLANTL_HO_THRESHOLD_UP,
327 csrNeighborRoamNeighborLookupUPCallback,
328 VOS_MODULE_ID_SME);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329
330 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
331 {
332 //err msg
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530333 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupUPCallback with TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 }
335
336 /* We dont need to run this timer any more. */
337 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
338
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -0800339 csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700340
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 return VOS_STATUS_SUCCESS;
342}
343
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700344/*CleanUP Routines*/
345static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo)
346{
347 if ((rChInfo->IAPPNeighborListReceived == FALSE) &&
348 (rChInfo->currentChannelListInfo.numOfChannels))
349 {
350 rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
351 rChInfo->currentChannelListInfo.numOfChannels = 0;
352
353 if (rChInfo->currentChannelListInfo.ChannelList)
354 vos_mem_free(rChInfo->currentChannelListInfo.ChannelList);
355
356 rChInfo->currentChannelListInfo.ChannelList = NULL;
357 rChInfo->chanListScanInProgress = eANI_BOOLEAN_FALSE;
358 }
359 else
360 {
361 rChInfo->currentChanIndex = 0;
362 rChInfo->chanListScanInProgress = eANI_BOOLEAN_TRUE;
363 }
364}
365
366static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac)
367{
368 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
369
370 /* Stop neighbor scan timer */
371 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
372
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -0700373 /* Stop neighbor scan results refresh timer */
374 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
375
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700376 /* Abort any ongoing scan */
377 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
378 {
379 csrScanAbortMacScan(pMac);
380 }
381 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
382
383 /* Reset roam channel list information */
384 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
385}
386
387static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac)
388{
389 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
390
391#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
392 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
393 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
394 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId =
395 CSR_SESSION_ID_INVALID;
396 /* Purge pre-auth fail list */
397 csrNeighborRoamPurgePreauthFailedList(pMac);
398#endif
399
400 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
401 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
402#ifdef WLAN_FEATURE_VOWIFI_11R
403 /* Do not free up the preauth done list here */
404 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
405 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
406 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
407 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
408 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
409#endif
410}
411
412static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac)
413{
414 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
415 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
416
417 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
418 FL("Deregister neighbor lookup UP callback with TL. RSSI = %d"),
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800419 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700420
421 /* Deregister reassoc callback. Ignore return status */
422 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800423 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700424 WLANTL_HO_THRESHOLD_UP,
425 csrNeighborRoamNeighborLookupUPCallback,
426 VOS_MODULE_ID_SME);
427
428 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
429 {
430 smsLog(pMac, LOGW,
431 FL("Couldn't deregister csrNeighborRoamNeighborLookupUPCallback "
432 "with TL: Status = %d\n"), vosStatus);
433 }
434
435 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
436 FL("Deregistering reassoc DOWN callback with TL. RSSI = %d"),
437 pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
438
439 /* Deregister reassoc callback. Ignore return status */
440 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
441 (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
442 WLANTL_HO_THRESHOLD_DOWN,
443 csrNeighborRoamReassocIndCallback,
444 VOS_MODULE_ID_SME);
445
446 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
447 {
448 smsLog(pMac, LOGW,
449 FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with "
450 "TL: Status = %d\n"), vosStatus);
451 }
452
453 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
454 FL("Deregistering neighborLookup DOWN callback with TL. RSSI = %d"),
455 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
456
457 /* Deregister neighbor lookup callback. Ignore return status */
458 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
459 (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
460 WLANTL_HO_THRESHOLD_DOWN,
461 csrNeighborRoamNeighborLookupDOWNCallback,
462 VOS_MODULE_ID_SME);
463
464 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
465 {
466 smsLog(pMac, LOGW,
467 FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback "
468 "with TL: Status = %d\n"), vosStatus);
469 }
470
471 /* Reset thresholds only after deregistering DOWN event from TL */
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700472 pNeighborRoamInfo->currentNeighborLookupThreshold =
473 pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -0800474#ifdef FEATURE_WLAN_LFR
475 pNeighborRoamInfo->uEmptyScanCount = 0;
476#endif
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700477}
478
Jeff Johnson295189b2012-06-20 16:38:30 -0700479/* ---------------------------------------------------------------------------
480
481 \fn csrNeighborRoamResetConnectedStateControlInfo
482
483 \brief This function will reset the neighbor roam control info data structures.
484 This function should be invoked whenever we move to CONNECTED state from
485 any state other than INIT state
486
487 \param pMac - The handle returned by macOpen.
488
489 \return VOID
490
491---------------------------------------------------------------------------*/
492void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
493{
494 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
495
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700496 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700497 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700498
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700499 /* We dont need to run this timer any more. */
500 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -0700501
502#ifdef WLAN_FEATURE_VOWIFI_11R
503 /* Do not free up the preauth done list here */
504 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
505 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
506 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
507 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
508 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
509 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
510 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
511#endif
512
513}
514
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700515void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac)
Jeff Johnson295189b2012-06-20 16:38:30 -0700516{
517 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700518 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
519 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
520 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
521 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -0700522#ifdef FEATURE_WLAN_CCX
523 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
524 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
525 pNeighborRoamInfo->MinQBssLoadRequired = 0;
526#endif
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -0700527
528 /* Stop scan refresh timer */
529 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700530 /* Purge roamable AP list */
531 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700532 return;
533}
534
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700535/* ---------------------------------------------------------------------------
536
537 \fn csrNeighborRoamResetInitStateControlInfo
538
539 \brief This function will reset the neighbor roam control info data structures.
540 This function should be invoked whenever we move to CONNECTED state from
541 INIT state
542
543 \param pMac - The handle returned by macOpen.
544
545 \return VOID
546
547---------------------------------------------------------------------------*/
548void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
549{
550 csrNeighborRoamResetConnectedStateControlInfo(pMac);
551
552 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
553 csrNeighborRoamResetReportScanStateControlInfo(pMac);
554}
555
556
557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558#ifdef WLAN_FEATURE_VOWIFI_11R
559/* ---------------------------------------------------------------------------
560
561 \fn csrNeighborRoamBssIdScanFilter
562
563 \brief This API is used to prepare a filter to obtain scan results when
564 we complete the scan in the REPORT_SCAN state after receiving a
565 valid neighbor report from AP. This filter includes BSSIDs received from
566 the neighbor report from the AP in addition to the other filter parameters
567 created from connected profile
568
569 \param pMac - The handle returned by macOpen.
570 pScanFilter - Scan filter to be filled and returned
571
572 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
573 code otherwise
574
575---------------------------------------------------------------------------*/
576static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
577{
578 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
579 tANI_U8 i = 0;
580
581 VOS_ASSERT(pScanFilter != NULL);
582 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
583
584 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
585 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
586 if (NULL == pScanFilter->BSSIDs.bssid)
587 {
588 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
589 return eHAL_STATUS_FAILED_ALLOC;
590 }
591
592 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
593
594 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
595 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
596 {
597 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
598 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
599 }
600
601 /* Fill other general scan filter params */
602 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
603}
604
605/* ---------------------------------------------------------------------------
606
607 \fn csrNeighborRoamPurgePreauthFailList
608
609 \brief This function empties the preauth fail list
610
611 \param pMac - The handle returned by macOpen.
612
613 \return VOID
614
615---------------------------------------------------------------------------*/
616void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
617{
618 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
619
620 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
621 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
622 {
623 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
624 sizeof(tSirMacAddr));
625 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
626 }
627 return;
628}
629
630/* ---------------------------------------------------------------------------
631
632 \fn csrNeighborRoamAddBssIdToPreauthFailList
633
634 \brief This function adds the given BSSID to the Preauth fail list
635
636 \param pMac - The handle returned by macOpen.
637 bssId - BSSID to be added to the preauth fail list
638
639 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
640
641---------------------------------------------------------------------------*/
642eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
643{
644 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
645
646 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
647 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
648
649
650 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
651 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
652 {
653 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
654 return eHAL_STATUS_FAILURE;
655 }
656 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
657 bssId, sizeof(tSirMacAddr));
658 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
659
660 return eHAL_STATUS_SUCCESS;
661}
662
663/* ---------------------------------------------------------------------------
664
665 \fn csrNeighborRoamIsPreauthCandidate
666
667 \brief This function checks whether the given MAC address is already
668 present in the preauth fail list and returns TRUE/FALSE accordingly
669
670 \param pMac - The handle returned by macOpen.
671
672 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
673
674---------------------------------------------------------------------------*/
675tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
676{
677 tANI_U8 i = 0;
678 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
679
680 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
681 return eANI_BOOLEAN_TRUE;
682
683 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
684 {
685 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
686 bssId, sizeof(tSirMacAddr)))
687 {
688 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
689 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
690 return eANI_BOOLEAN_FALSE;
691 }
692 }
693
694 return eANI_BOOLEAN_TRUE;
695}
696
697/* ---------------------------------------------------------------------------
698
699 \fn csrNeighborRoamIssuePreauthReq
700
701 \brief This function issues preauth request to PE with the 1st AP entry in the
702 roamable AP list
703
704 \param pMac - The handle returned by macOpen.
705
706 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
707
708---------------------------------------------------------------------------*/
709static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
710{
711 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
712 eHalStatus status = eHAL_STATUS_SUCCESS;
713 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
714
715 /* This must not be true here */
716 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
717
718 /* Issue Preauth request to PE here */
719 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
720 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
721 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
722 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
723
724 if (NULL == pNeighborBssNode)
725 {
726 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
727 return eHAL_STATUS_FAILURE;
728 }
729 else
730 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700731 status = csrRoamEnqueuePreauth(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription,
732 eCsrPerformPreauth, eANI_BOOLEAN_TRUE);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530733
734 smsLog(pMac, LOGE, FL("Before Pre-Auth: BSSID %02x:%02x:%02x:%02x:%02x:%02x %d"),
735 pNeighborBssNode->pBssDescription->bssId[0],
736 pNeighborBssNode->pBssDescription->bssId[1],
737 pNeighborBssNode->pBssDescription->bssId[2],
738 pNeighborBssNode->pBssDescription->bssId[3],
739 pNeighborBssNode->pBssDescription->bssId[4],
740 pNeighborBssNode->pBssDescription->bssId[5]);
741 smsLog(pMac, LOGE, FL("Before Pre-Auth: Channel %d\n"), (int)pNeighborBssNode->pBssDescription->channelId);
742
Jeff Johnson295189b2012-06-20 16:38:30 -0700743 if (eHAL_STATUS_SUCCESS != status)
744 {
745 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
746 return status;
747 }
748 }
749
750 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
751
752 /* Increment the preauth retry count */
753 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
754
755 /* Transition the state to preauthenticating */
756 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700757#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 /* Start the preauth rsp timer */
759 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
760 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
761 eANI_BOOLEAN_FALSE);
762 if (eHAL_STATUS_SUCCESS != status)
763 {
764 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
765 return status;
766 }
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700767#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700768
769 return status;
770}
771
772/* ---------------------------------------------------------------------------
773
774 \fn csrNeighborRoamPreauthRspHandler
775
776 \brief This function handle the Preauth response from PE
777 Every preauth is allowed max 3 tries if it fails. If a bssid failed
778 for more than MAX_TRIES, we will remove it from the list and try
779 with the next node in the roamable AP list and add the BSSID to pre-auth failed
780 list. If no more entries present in
781 roamable AP list, transition to REPORT_SCAN state
782
783 \param pMac - The handle returned by macOpen.
784 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
785
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700786 \return eHAL_STATUS_SUCCESS on success (i.e. pre-auth processed),
787 eHAL_STATUS_FAILURE otherwise
Jeff Johnson295189b2012-06-20 16:38:30 -0700788
789---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700790eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -0700791{
792 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
793 eHalStatus status = eHAL_STATUS_SUCCESS;
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700794 eHalStatus preauthProcessed = eHAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700796
797 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->FTRoamInfo.preauthRspPending)
798 {
799
800 /* This can happen when we disconnect immediately
801 * after sending a pre-auth request. During processing
802 * of the disconnect command, we would have reset
803 * preauthRspPending and transitioned to INIT state.
804 */
805 NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
806 FL("Unexpected pre-auth response in state %d\n"),
807 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700808 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700809 goto DEQ_PREAUTH;
810 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700811
812 // We can receive it in these 2 states.
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
814 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
815 {
Madan Mohan Koyyalamudi8186a9e2012-10-11 14:23:43 -0700816 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %d\n"),
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700817 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700818 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700819 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700820 }
821
822 if (VOS_STATUS_E_TIMEOUT != vosStatus)
823 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700824#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 /* This means we got the response from PE. Hence stop the timer */
826 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700828 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
829 }
830
831 if (VOS_STATUS_SUCCESS == vosStatus)
832 {
833 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
834 }
835 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
836 {
837 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
838
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +0530839 smsLog(pMac, LOGE, FL("After Pre-Auth: BSSID %02x:%02x:%02x:%02x:%02x:%02x\n"),
840 pPreauthRspNode->pBssDescription->bssId[0],
841 pPreauthRspNode->pBssDescription->bssId[1],
842 pPreauthRspNode->pBssDescription->bssId[2],
843 pPreauthRspNode->pBssDescription->bssId[3],
844 pPreauthRspNode->pBssDescription->bssId[4],
845 pPreauthRspNode->pBssDescription->bssId[5]);
846 smsLog(pMac, LOGE, FL("After Pre-Auth: Channel %d\n"), (int)pPreauthRspNode->pBssDescription->channelId);
847
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
849 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
850 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
851
852 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
853 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
854 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
855
856 /* The caller of this function would start a timer and by the time it expires, supplicant should
857 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
858 }
859 else
860 {
861 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
862 tListElem *pEntry;
863
864 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
865
866 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
867 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
868 {
869 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
870 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
871
872 /* The one in the head of the list should be one with which we issued pre-auth and failed */
873 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
874 if(pEntry)
875 {
876 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
877 /* Add the BSSID to pre-auth fail list */
878 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
879 /* Now we can free this node */
880 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
881 }
882 }
883
884 /* Issue preauth request for the same/next entry */
885 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700886 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700887
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -0800888 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN);
889
890 /* Register Neighbor Lookup threshold callback with TL for UP event now */
891 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No more pre-auth candidates-"
892 "register UP indication with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
893
894 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
895 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
896 WLANTL_HO_THRESHOLD_UP,
897 csrNeighborRoamNeighborLookupUPCallback,
898 VOS_MODULE_ID_SME, pMac);
899 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
900 {
901 //err msg
902 smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
903 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700904
905 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
906 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
907 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
908 eANI_BOOLEAN_FALSE);
909 if (eHAL_STATUS_SUCCESS != status)
910 {
911 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 }
913 }
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700914
915DEQ_PREAUTH:
916 csrRoamDequeuePreauth(pMac);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700917 return preauthProcessed;
Jeff Johnson295189b2012-06-20 16:38:30 -0700918}
919#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
920
921/* ---------------------------------------------------------------------------
922
923 \fn csrNeighborRoamPrepareScanProfileFilter
924
925 \brief This function creates a scan filter based on the currently connected profile.
926 Based on this filter, scan results are obtained
927
928 \param pMac - The handle returned by macOpen.
929 pScanFilter - Populated scan filter based on the connected profile
930
931 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
932
933---------------------------------------------------------------------------*/
934eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
935{
936 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
937 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
938 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
939 tANI_U8 i = 0;
940
941 VOS_ASSERT(pScanFilter != NULL);
942
943 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
944
945 /* We dont want to set BSSID based Filter */
946 pScanFilter->BSSIDs.numOfBSSIDs = 0;
947
948 /* Populate all the information from the connected profile */
949 pScanFilter->SSIDs.numOfSSIDs = 1;
950 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
951 if (NULL == pScanFilter->SSIDs.SSIDList)
952 {
953 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
954 return eHAL_STATUS_FAILED_ALLOC;
955 }
956 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
957 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
958 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
959 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
960
961 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
962 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
963 pScanFilter->authType.numEntries = 1;
964 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
965
966 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
967 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
968
969 pScanFilter->mcEncryptionType.numEntries = 1;
970 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
971
972 pScanFilter->BSSType = pCurProfile->BSSType;
973
974 /* We are intrested only in the scan results on channels that we scanned */
975 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
976 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
977 if (NULL == pScanFilter->ChannelInfo.ChannelList)
978 {
979 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
980 vos_mem_free(pScanFilter->SSIDs.SSIDList);
981 pScanFilter->SSIDs.SSIDList = NULL;
982 return eHAL_STATUS_FAILED_ALLOC;
983 }
984 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
985 {
986 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
987 }
988
989#ifdef WLAN_FEATURE_VOWIFI_11R
990 if (pNeighborRoamInfo->is11rAssoc)
991 {
992 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
993 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
994 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
995 }
996#endif
997
998 return eHAL_STATUS_SUCCESS;
999}
1000
Jeff Johnson43971f52012-07-17 12:26:56 -07001001tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
1002{
1003 tCsrScanResultInfo *pScanResult;
1004 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1005 tANI_U32 CurrAPRssi = -125; /* We are setting this as default value to make sure we return this value,
1006 when we do not see this AP in the scan result for some reason.However,it is
1007 less likely that we are associated to an AP and do not see it in the scan list*/
1008
1009 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
1010 {
1011
1012 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
1013 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
1014 {
1015 /* We got a match with the currently associated AP.
1016 * Capture the RSSI value and complete the while loop.
1017 * The while loop is completed in order to make the current entry go back to NULL,
1018 * and in the next while loop, it properly starts searching from the head of the list.
1019 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
1020
1021 CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ;
1022
1023 } else {
1024 continue;
1025 }
1026 }
1027
1028 return CurrAPRssi;
1029
1030}
1031
Jeff Johnson295189b2012-06-20 16:38:30 -07001032/* ---------------------------------------------------------------------------
1033
1034 \fn csrNeighborRoamProcessScanResults
1035
1036 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
1037 Assumed that the results are already sorted by RSSI by csrScanGetResult
1038
1039 \param pMac - The handle returned by macOpen.
1040 pScanResultList - Scan result result obtained from csrScanGetResult()
1041
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001042 \return tANI_BOOLEAN - return TRUE if we have a candidate we can immediately
1043 roam to. Otherwise, return FALSE.
Jeff Johnson295189b2012-06-20 16:38:30 -07001044
1045---------------------------------------------------------------------------*/
1046
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001047static tANI_BOOLEAN csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac,
1048 tScanResultHandle *pScanResultList)
Jeff Johnson295189b2012-06-20 16:38:30 -07001049{
1050 tCsrScanResultInfo *pScanResult;
1051 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1052 tpCsrNeighborRoamBSSInfo pBssInfo;
Jeff Johnson43971f52012-07-17 12:26:56 -07001053 tANI_U32 CurrAPRssi;
1054 tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff;
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001055#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1056 tANI_U8 immediateRoamRssiDiff = pMac->roam.configParam.nImmediateRoamRssiDiff;
1057#endif
1058 tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE;
Jeff Johnson43971f52012-07-17 12:26:56 -07001059
1060 /***************************************************************
1061 * Find out the Current AP RSSI and keep it handy to check if
1062 * it is better than the RSSI of the AP which we are
1063 * going to roam.If so, we are going to continue with the
1064 * current AP.
1065 ***************************************************************/
1066 CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001067
1068 /* Expecting the scan result already to be in the sorted order based on the RSSI */
1069 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
1070 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
1071 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
1072 /* 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
1073 and rssi score are in the same order. This will be taken care later */
1074
1075 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
1076 {
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001077 NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
1078 FL("Scan result: BSSID %02x:%02x:%02x:%02x:%02x:%02x (Rssi %d)"),
1079 pScanResult->BssDescriptor.bssId[0],
1080 pScanResult->BssDescriptor.bssId[1],
1081 pScanResult->BssDescriptor.bssId[2],
1082 pScanResult->BssDescriptor.bssId[3],
1083 pScanResult->BssDescriptor.bssId[4],
1084 pScanResult->BssDescriptor.bssId[5],
1085 abs(pScanResult->BssDescriptor.rssi));
Jeff Johnson295189b2012-06-20 16:38:30 -07001086
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001087 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001088 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
1089 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001090 /* currently associated AP. Do not have this in the roamable AP list */
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08001091 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1092 "SKIP-currently associated AP\n");
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 continue;
1094 }
1095
Jeff Johnson43971f52012-07-17 12:26:56 -07001096 /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature
1097 * is disabled and we continue to roam without any check*/
1098 if(RoamRssiDiff > 0)
1099 {
Madan Mohan Koyyalamudif553b742012-12-03 16:37:39 -08001100 /*
1101 * If RSSI is lower than the lookup threshold, then continue.
1102 */
1103 if (abs(pScanResult->BssDescriptor.rssi) >
1104 pNeighborRoamInfo->currentNeighborLookupThreshold)
1105 {
1106 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1107 "%s: [INFOLOG] new ap rssi (%d) lower than lookup threshold (%d)\n",
1108 __func__, (int)pScanResult->BssDescriptor.rssi * (-1),
1109 (int)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1110 continue;
1111 }
1112
Jeff Johnson43971f52012-07-17 12:26:56 -07001113 if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi))
1114 {
1115 /*Do not roam to an AP with worse RSSI than the current*/
1116 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1117 "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d\n", __func__,
1118 CurrAPRssi,
1119 (int)pScanResult->BssDescriptor.rssi * (-1) );
1120 continue;
1121 } else {
1122 /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the
1123 * margin that is provided by user from the ini file (RoamRssiDiff)*/
1124 if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff)
1125 {
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08001126 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1127 "%s: [INFOLOG]Current AP rssi=%d new ap rssi=%d not good enough, roamRssiDiff=%d\n", __func__,
1128 CurrAPRssi,
1129 (int)pScanResult->BssDescriptor.rssi * (-1),
1130 RoamRssiDiff);
Jeff Johnson43971f52012-07-17 12:26:56 -07001131 continue;
1132 }
1133 else {
1134 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1135 "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d\n", __func__,
1136 CurrAPRssi,
1137 (int)pScanResult->BssDescriptor.rssi * (-1) );
1138 }
1139 }
1140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001141
1142#ifdef WLAN_FEATURE_VOWIFI_11R
1143 if (pNeighborRoamInfo->is11rAssoc)
1144 {
1145 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1146 {
1147 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1148 continue;
1149 }
1150 }
1151#endif /* WLAN_FEATURE_VOWIFI_11R */
1152
1153#ifdef FEATURE_WLAN_CCX
1154 if (pNeighborRoamInfo->isCCXAssoc)
1155 {
1156 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1157 {
1158 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1159 continue;
1160 }
1161 }
1162 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
1163 (pScanResult->BssDescriptor.QBSSLoad_avail))
1164 {
1165 if (pNeighborRoamInfo->isVOAdmitted)
1166 {
1167 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
1168 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
1169 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
1170 {
1171 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1172 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
1173 pScanResult->BssDescriptor.bssId[0],
1174 pScanResult->BssDescriptor.bssId[1],
1175 pScanResult->BssDescriptor.bssId[2],
1176 pScanResult->BssDescriptor.bssId[3],
1177 pScanResult->BssDescriptor.bssId[4],
1178 pScanResult->BssDescriptor.bssId[5]);
1179 continue;
1180 }
1181 }
1182 }
1183 else
1184 {
1185 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
1186 if (pNeighborRoamInfo->isVOAdmitted)
1187 {
1188 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1189 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
1190 pScanResult->BssDescriptor.bssId[0],
1191 pScanResult->BssDescriptor.bssId[1],
1192 pScanResult->BssDescriptor.bssId[2],
1193 pScanResult->BssDescriptor.bssId[3],
1194 pScanResult->BssDescriptor.bssId[4],
1195 pScanResult->BssDescriptor.bssId[5]);
1196 continue;
1197 }
1198 }
1199#endif /* FEATURE_WLAN_CCX */
1200
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001201#ifdef FEATURE_WLAN_LFR
1202 // If we are supporting legacy roaming, and
1203 // if the candidate is on the "pre-auth failed" list, ignore it.
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05301204 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001205 {
1206 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1207 {
1208 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1209 continue;
1210 }
1211 }
1212#endif /* FEATURE_WLAN_LFR */
1213
Jeff Johnson295189b2012-06-20 16:38:30 -07001214 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
1215 * this result */
1216 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
1217 {
1218 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
1219 continue;
1220 }
1221
1222 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
1223 if (NULL == pBssInfo)
1224 {
1225 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
1226 continue;
1227 }
1228
1229 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1230 if (pBssInfo->pBssDescription != NULL)
1231 {
1232 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
1233 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1234 }
1235 else
1236 {
1237 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
1238 vos_mem_free(pBssInfo);
1239 continue;
1240
1241 }
1242 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
1243
1244 /* Just add to the end of the list as it is already sorted by RSSI */
1245 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001246
1247#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1248 if (immediateRoamRssiDiff &&
1249 (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) >= immediateRoamRssiDiff))
1250 {
1251 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1252 "%s: [INFOLOG] potential candidate to roam immediately (diff=%d, expected=%d)",
1253 __func__, abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)),
1254 immediateRoamRssiDiff);
1255 roamNow = eANI_BOOLEAN_TRUE;
1256 }
1257#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001258 }
1259
1260 /* 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 */
1261 csrScanResultPurge(pMac, *pScanResultList);
1262
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001263 return roamNow;
Jeff Johnson295189b2012-06-20 16:38:30 -07001264}
1265
1266/* ---------------------------------------------------------------------------
1267
1268 \fn csrNeighborRoamHandleEmptyScanResult
1269
1270 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1271 there are no valid APs in the scan result for roaming. This means
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001272 our AP is the best and no other AP is around. No point in scanning
Jeff Johnson295189b2012-06-20 16:38:30 -07001273 again and again. Performing the following here.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001274 1. Stop the neighbor scan timer.
1275 2a. If this is the first time we encountered empty scan, then
1276 re-register with TL with modified lookup threshold.
1277 2b. Else if this is the second time we encountered empty scan,
1278 then start neighbor scan results refresh timer (20s).
1279 2c. Else, nothing more to do.
1280 NOTE: In LFR, channels selected for scanning is dervied from
1281 the occuped channel list. Scan cycle following one which
1282 yielded empty results is split into two halves: (i) scan on
1283 channels in the occupied list, and (ii) scan on channels not
1284 in the occupied list. This helps converging faster (while
1285 looking for candidates in the occupied list first), and also,
1286 adds channels to the occupied channel list upon finding candidates
1287 matching SSID profile of interest.
1288
1289 uEmptyScanCount Comments
1290 eFirstEmptyScan Previous scan was done on channels in the
1291 occupied list and yielded potential candidates.
1292 This scan cycle was likely triggered through
1293 receipt of lookup DOWN notification event.
1294 eSecondEmptyScan Previous scan was done on channels in the
1295 occupied list and yielded no candidates. This scan
1296 cycle was triggered through RSSI notification
1297 with modified lookup threshold.
1298 eThirdEmptyScan Previous scan was done on channels NOT in
1299 the occupied list and yielded no candidates. This
1300 scan cycle was triggered immediately after scanning
1301 channels in the occupied list and no candidates
1302 were found.
1303 eFourthEmptyScan Previous scan was done on channels in the
1304 occupied list and yielded no candidates. This scan
1305 cycle was triggered upon expiry of
1306 neighborScanResultsRefreshPeriod (=20s).
1307 eFifthEmptyScan Previous scan was done on channels NOT in
1308 the occupied list and yielded no candidates. This
1309 scan cycle was triggered immediately after scanning
1310 channels in the occupied list and no candidates
1311 were found.
1312
1313 [1], [2,3] and [4,5] together form one discrete set of scan cycle.
Jeff Johnson295189b2012-06-20 16:38:30 -07001314
1315 \param pMac - The handle returned by macOpen.
1316
1317 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1318
1319---------------------------------------------------------------------------*/
1320static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1321{
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001322 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001323 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1324 eHalStatus status = eHAL_STATUS_SUCCESS;
1325
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001326 /* Stop neighbor scan timer */
Jeff Johnson295189b2012-06-20 16:38:30 -07001327 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001328 if (eHAL_STATUS_SUCCESS != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001329 {
1330 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1331 }
1332
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001333 /*
1334 * Increase the neighbor lookup threshold by 3 dB
1335 * after every scan cycle. NOTE: uEmptyScanCount
1336 * would be either 1, 3 or 5 at the end of every
1337 * scan cycle.
1338 */
1339#ifdef FEATURE_WLAN_LFR
1340 if ((++pNeighborRoamInfo->uEmptyScanCount) > eFifthEmptyScan)
1341 {
1342 pNeighborRoamInfo->uEmptyScanCount = eFifthEmptyScan;
1343 }
1344#endif
1345 if (((pNeighborRoamInfo->currentNeighborLookupThreshold+3) <
1346 pNeighborRoamInfo->cfgParams.neighborReassocThreshold)
1347#ifdef FEATURE_WLAN_LFR
1348 && ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1)
1349#endif
1350 )
1351 {
1352 pNeighborRoamInfo->currentNeighborLookupThreshold += 3;
1353 }
1354
Jeff Johnson295189b2012-06-20 16:38:30 -07001355#ifdef WLAN_FEATURE_VOWIFI_11R
1356 /* Clear off the old neighbor report details */
1357 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1358#endif
1359
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001360#ifdef FEATURE_WLAN_LFR
1361 if (pNeighborRoamInfo->uEmptyScanCount == eFirstEmptyScan)
1362 {
1363#endif
1364 /* Empty scan results for the first time */
1365 /* Transition to CONNECTED state */
1366 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1367
1368 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1369 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1370
1371 /* Re-register neighbor lookup DOWN threshold callback with TL */
1372 NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
1373 FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"),
1374 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1375
1376 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
1377 (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1378 WLANTL_HO_THRESHOLD_DOWN,
1379 csrNeighborRoamNeighborLookupDOWNCallback,
1380 VOS_MODULE_ID_SME, pMac);
1381
1382 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1383 {
1384 smsLog(pMac, LOGW,
1385 FL("Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback"
1386 " with TL: Status = %d\n"), status);
1387 }
1388#ifdef FEATURE_WLAN_LFR
1389 }
1390 else if ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) ||
1391 (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan))
1392 {
1393 /* Empty scan results for the second or fourth time */
1394 /* Transition to CONNECTED state */
1395 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1396
1397 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1398 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1399
1400 /* Immediately scan on channels in non-occupied list */
1401 csrNeighborRoamTransitToCFGChanScan(pMac);
1402 }
1403 else if (pNeighborRoamInfo->uEmptyScanCount == eThirdEmptyScan)
1404 {
1405 /* Empty scan results for the third time */
1406 /* Remain in eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN */
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001407 /* Start neighbor scan results refresh timer */
1408 if (eHAL_STATUS_SUCCESS !=
1409 palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001410 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001411 eANI_BOOLEAN_FALSE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001412 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001413 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start (%d)"),
1414 status);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001415 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1416 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001417 vosStatus = VOS_STATUS_E_FAILURE;
1418 }
1419 else
1420 {
1421 smsLog(pMac, LOG2, FL("Neighbor results refresh timer started (%ld ms)"),
1422 (pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT));
1423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001424 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001425 else
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001426 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001427 /* Do nothing */
1428 /* Transition to CONNECTED state */
1429 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
1430
1431 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1432 csrNeighborRoamResetConnectedStateControlInfo(pMac);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001433 }
1434
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001435 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Neighbor roam empty scan count=%d",
1436 pNeighborRoamInfo->uEmptyScanCount);
1437#endif
1438 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001439}
1440
1441/* ---------------------------------------------------------------------------
1442
1443 \fn csrNeighborRoamScanRequestCallback
1444
1445 \brief This function is the callback function registered in csrScanRequest() to
1446 indicate the completion of scan. If scan is completed for all the channels in
1447 the channel list, this function gets the scan result and starts the refresh results
1448 timer to avoid having stale results. If scan is not completed on all the channels,
1449 it restarts the neighbor scan timer which on expiry issues scan on the next
1450 channel
1451
1452 \param halHandle - The handle returned by macOpen.
1453 pContext - not used
1454 scanId - not used
1455 status - not used
1456
1457 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1458
1459---------------------------------------------------------------------------*/
1460static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1461 tANI_U32 scanId, eCsrScanStatus status)
1462{
1463 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1464 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1465 tANI_U8 currentChanIndex;
1466 tCsrScanResultFilter scanFilter;
1467 tScanResultHandle scanResult;
1468 tANI_U32 tempVal = 0;
Jeff Johnson43971f52012-07-17 12:26:56 -07001469 eHalStatus hstatus;
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001470 tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001471
1472 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1473
1474 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1475 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1476 {
1477 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1478 return eHAL_STATUS_SUCCESS;
1479 }
1480
1481 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1482 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1483
1484 /* Validate inputs */
1485 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1486 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1487 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1488 }
1489 else
1490 {
1491 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1492 return eHAL_STATUS_SUCCESS;
1493 }
1494
1495 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1496 {
1497 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1498 just to get the results and perform PREAUTH */
1499 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1500 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1501 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1502 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1503
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001504#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001505 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1506 should use the BSSID filter made out of neighbor reports */
1507 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1508 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001509 hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1510 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 -07001511 tempVal = 1;
1512 }
1513 else
1514#endif
1515 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001516 hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1517 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 -07001518 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001519 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 {
1521 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1522 return eHAL_STATUS_FAILURE;
1523 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001524 hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301525 if (hstatus != eHAL_STATUS_SUCCESS)
1526 {
1527 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus);
1528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 /* Process the scan results and update roamable AP list */
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001530 roamNow = csrNeighborRoamProcessScanResults(pMac, &scanResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07001531
1532 /* Free the scan filter */
1533 csrFreeScanFilter(pMac, &scanFilter);
1534
1535 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1536
1537 switch(pNeighborRoamInfo->neighborRoamState)
1538 {
1539 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1540 if (tempVal)
1541 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001542#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001543 /*
1544 * Since there are non-zero candidates found
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001545 * after the scan, reset empty scan count.
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001546 */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001547 pNeighborRoamInfo->uEmptyScanCount = 0;
1548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001549#ifdef WLAN_FEATURE_VOWIFI_11R
1550 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1551 APs in the roamable AP list */
1552 if (pNeighborRoamInfo->is11rAssoc)
1553 {
1554 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1555 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1556 }
1557 else
1558#endif
1559#ifdef FEATURE_WLAN_CCX
1560 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1561 APs in the roamable AP list */
1562 if (pNeighborRoamInfo->isCCXAssoc)
1563 {
1564 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1565 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1566 }
1567 else
1568#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001569#ifdef FEATURE_WLAN_LFR
1570 /* If LFR is enabled, then we can register the reassoc callback here as we have some
1571 APs in the roamable AP list */
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05301572 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001573 {
1574 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1575 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1576 }
1577 else
1578#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001579 {
1580
1581 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1582 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1583 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1584 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1585 within certain duration */
1586
1587// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1588 }
1589 }
1590 else
1591 {
Madan Mohan Koyyalamudib40e5582012-10-11 16:48:42 -07001592 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1593 /* Handle it appropriately */
1594 csrNeighborRoamHandleEmptyScanResult(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001595 }
1596 break;
1597#ifdef WLAN_FEATURE_VOWIFI_11R
1598 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1599 if (!tempVal)
1600 {
1601 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1602 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1603 csrNeighborRoamTransitToCFGChanScan(pMac);
1604 }
1605 break;
1606#endif /* WLAN_FEATURE_VOWIFI_11R */
1607 default:
1608 // Can come only in INIT state. Where in we are associated, we sent scan and user
1609 // in the meantime decides to disassoc, we will be in init state and still received call
1610 // back issued. Should not come here in any other state, printing just in case
1611 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1612 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1613
1614 // Lets just exit out silently.
1615 return eHAL_STATUS_SUCCESS;
1616 }
1617
1618 if (tempVal)
1619 {
1620 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1621
Madan Mohan Koyyalamudi62b55b02012-12-03 16:45:39 -08001622 if (roamNow)
1623 {
1624 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
1625 FL("Immediate roam-deregister UP indication. RSSI = %d"),
1626 NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1));
1627
1628 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
1629 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
1630 WLANTL_HO_THRESHOLD_UP,
1631 csrNeighborRoamNeighborLookupUPCallback,
1632 VOS_MODULE_ID_SME);
1633
1634 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1635 {
1636 smsLog(pMac, LOGW,
1637 FL("Couldn't deregister lookup UP callback with TL: Status = %d\n"), vosStatus);
1638 }
1639
1640 csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo);
1641 return eHAL_STATUS_SUCCESS;
1642 }
1643
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1645 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1646 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1647 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1648 eANI_BOOLEAN_FALSE))
1649 {
1650 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1651 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1652 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001653 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001654 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001655
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1657 /* Register a reassoc Indication callback */
1658 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1659 WLANTL_HO_THRESHOLD_DOWN,
1660 csrNeighborRoamReassocIndCallback,
1661 VOS_MODULE_ID_SME, pMac);
1662
1663 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1664 {
1665 //err msg
1666 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1667 }
1668
1669 }
1670 }
1671 else
1672 {
1673
1674 /* Restart the timer for the next scan sequence as scanning is not over */
Jeff Johnson43971f52012-07-17 12:26:56 -07001675 hstatus = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1677 eANI_BOOLEAN_FALSE);
1678
Jeff Johnson43971f52012-07-17 12:26:56 -07001679 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001680 {
1681 /* Timer start failed.. Should we ASSERT here??? */
1682 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1683 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1684 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001685 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001686 }
1687 }
1688 return eHAL_STATUS_SUCCESS;
1689}
1690
1691/* ---------------------------------------------------------------------------
1692
1693 \fn csrNeighborRoamIssueBgScanRequest
1694
1695 \brief This function issues CSR scan request after populating all the BG scan params
1696 passed
1697
1698 \param pMac - The handle returned by macOpen.
1699 pBgScanParams - Params that need to be populated into csr Scan request
1700
1701 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1702
1703---------------------------------------------------------------------------*/
1704eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1705{
1706 eHalStatus status = eHAL_STATUS_SUCCESS;
1707 tANI_U32 scanId;
1708 tCsrScanRequest scanReq;
1709 tANI_U8 channel;
1710
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301711 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001712 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1713
1714
1715 //send down the scan req for 1 channel on the associated SSID
1716 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1717 /* Fill in the SSID Info */
1718 scanReq.SSIDs.numOfSSIDs = 1;
1719 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1720 if(NULL == scanReq.SSIDs.SSIDList)
1721 {
1722 //err msg
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301723 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 -07001724 return eHAL_STATUS_FAILURE;
1725 }
1726 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1727
1728 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1729 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1730 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1731
1732 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1733
1734 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1735 scanReq.ChannelInfo.ChannelList = &channel;
1736
1737 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1738 scanReq.scanType = eSIR_ACTIVE_SCAN;
1739 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1740 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1741 scanReq.minChnTime = pBgScanParams->minChnTime;
1742 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1743 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1744 if (eHAL_STATUS_SUCCESS != status)
1745 {
1746 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1747 vos_mem_free(scanReq.SSIDs.SSIDList);
1748 return status;
1749 }
1750 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1751
1752 vos_mem_free(scanReq.SSIDs.SSIDList);
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301753 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %08x, Actual index = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001754 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1755 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1756 return status;
1757}
1758
1759/* ---------------------------------------------------------------------------
1760
1761 \fn csrNeighborRoamPerformBgScan
1762
1763 \brief This function is invoked on every expiry of neighborScanTimer till all
1764 the channels in the channel list are scanned. It populates necessary
1765 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1766 request
1767
1768 \param pMac - The handle returned by macOpen.
1769
1770 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1771
1772---------------------------------------------------------------------------*/
1773eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1774{
1775 eHalStatus status = eHAL_STATUS_SUCCESS;
1776 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1777 tCsrBGScanRequest bgScanParams;
1778 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1779 tANI_U8 channel = 0;
1780
1781 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1782 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301783 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
Jeff Johnson295189b2012-06-20 16:38:30 -07001784 }
1785 else
1786 {
1787 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
Jeff Johnson902c9832012-12-10 14:28:09 -08001788 // Go back and restart. Mostly timer start failure has occurred.
Jeff Johnson295189b2012-06-20 16:38:30 -07001789 // When timer start is declared a failure, then we delete the list.
1790 // Should not happen now as we stop and then only start the scan timer.
1791 // still handle the unlikely case.
1792 csrNeighborRoamHandleEmptyScanResult(pMac);
1793 return status;
1794 }
1795 /* Need to perform scan here before getting the list */
1796 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1797 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1798 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1799 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1800
1801 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1802 bgScanParams.ChannelInfo.numOfChannels = 1;
1803 bgScanParams.ChannelInfo.ChannelList = &channel;
1804
1805 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1806 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1807
1808 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1809 if (eHAL_STATUS_SUCCESS != status)
1810 {
1811 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1812 return status;
1813 }
1814
1815 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1816 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1817 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1818 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05301819 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001820 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1821 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1822 /* We have completed scanning all the channels */
1823 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1824 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1825 and select the best AP in the list */
1826 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1827 {
1828 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1829 }
1830 }
1831
1832 return status;
1833}
1834
1835/* ---------------------------------------------------------------------------
1836
1837 \fn csrNeighborRoamNeighborScanTimerCallback
1838
1839 \brief This function is the neighbor scan timer callback function. It invokes
1840 the BG scan request based on the current and previous states
1841
1842 \param pv - CSR timer context info which includes pMac and session ID
1843
1844 \return VOID
1845
1846---------------------------------------------------------------------------*/
1847void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1848{
1849 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1850 tpAniSirGlobal pMac = pInfo->pMac;
1851 tANI_U32 sessionId = pInfo->sessionId;
1852 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1853
1854 // check if bg scan is on going, no need to send down the new params if true
1855 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1856 {
1857 //msg
1858 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1859 return;
1860 }
1861
1862 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1863
1864 switch (pNeighborRoamInfo->neighborRoamState)
1865 {
1866#ifdef WLAN_FEATURE_VOWIFI_11R
1867 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1868 switch(pNeighborRoamInfo->prevNeighborRoamState)
1869 {
1870 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1871 csrNeighborRoamPerformBgScan(pMac);
1872 break;
1873 default:
1874 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1875 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1876 break;
1877 }
1878 break;
1879#endif /* WLAN_FEATURE_VOWIFI_11R */
1880 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1881 csrNeighborRoamPerformBgScan(pMac);
1882 break;
1883 default:
1884 break;
1885 }
1886 return;
1887}
1888
1889/* ---------------------------------------------------------------------------
1890
1891 \fn csrNeighborRoamResultsRefreshTimerCallback
1892
1893 \brief This function is the timer callback function for results refresh timer.
1894 When this is invoked, it is as good as down event received from TL. So,
1895 clear off the roamable AP list and start the scan procedure based on 11R
1896 or non-11R association
1897
1898 \param context - CSR timer context info which includes pMac and session ID
1899
1900 \return VOID
1901
1902---------------------------------------------------------------------------*/
1903void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1904{
1905 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1906 tpAniSirGlobal pMac = pInfo->pMac;
1907 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1908 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1909
1910 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1911
1912 /* Deregister reassoc callback. Ignore return status */
1913 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1914 WLANTL_HO_THRESHOLD_DOWN,
1915 csrNeighborRoamReassocIndCallback,
1916 VOS_MODULE_ID_SME);
1917
1918 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1919 {
1920 //err msg
1921 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1922 }
1923
1924 /* Reset all the variables just as no scan had happened before */
1925 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1926
1927#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1928 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1929 {
1930 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1931 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1932 if (VOS_STATUS_SUCCESS != vosStatus)
1933 {
1934 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1935 return;
1936 }
1937 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1938 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1939 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1940 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1941 }
1942 else
1943#endif
1944 {
1945 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1946 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1947 if (VOS_STATUS_SUCCESS != vosStatus)
1948 {
1949 return;
1950 }
1951 }
1952 return;
1953}
1954
1955#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1956/* ---------------------------------------------------------------------------
1957
1958 \fn csrNeighborRoamIssueNeighborRptRequest
1959
1960 \brief This function is invoked when TL issues a down event and the current assoc
1961 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1962 the currently associated AP with the current SSID
1963
1964 \param pMac - The handle returned by macOpen.
1965
1966 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1967
1968---------------------------------------------------------------------------*/
1969VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1970{
1971 tRrmNeighborRspCallbackInfo callbackInfo;
1972 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1973 tRrmNeighborReq neighborReq;
1974
1975
1976 neighborReq.no_ssid = 0;
1977
1978 /* Fill in the SSID */
1979 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1980 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1981 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1982
1983 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
1984 callbackInfo.neighborRspCallbackContext = pMac;
1985 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
1986
1987 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
1988}
1989
1990/* ---------------------------------------------------------------------------
1991
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001992 \fn csrNeighborRoamMergeChannelLists
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001993
1994 \brief This function is used to merge two channel list.
1995 NB: If called with outputNumOfChannels == 0, this routines
1996 simply copies the input channel list to the output channel list.
1997
1998 \param pMac - The handle returned by macOpen.
1999 \param pInputChannelList - The addtional channels to merge in to the "merged" channels list.
2000 \param inputNumOfChannels - The number of additional channels.
2001 \param pOutputChannelList - The place to put the "merged" channel list.
2002 \param outputNumOfChannels - The original number of channels in the "merged" channels list.
2003 \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list.
2004
2005 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2006
2007---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002008VOS_STATUS csrNeighborRoamMergeChannelLists(
2009 tpAniSirGlobal pMac,
2010 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002011 int inputNumOfChannels,
2012 tANI_U8 *pOutputChannelList,
2013 int outputNumOfChannels,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002014 int *pMergedOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002015 )
2016{
2017 int i = 0;
2018 int j = 0;
2019 int numChannels = outputNumOfChannels;
2020
2021 // Check for NULL pointer
2022 if (!pInputChannelList) return eHAL_STATUS_E_NULL_VALUE;
2023
2024 // Check for NULL pointer
2025 if (!pOutputChannelList) return eHAL_STATUS_E_NULL_VALUE;
2026
2027 // Add the "new" channels in the input list to the end of the output list.
2028 for (i = 0; i < inputNumOfChannels; i++)
2029 {
2030 for (j = 0; j < outputNumOfChannels; j++)
2031 {
2032 if (pInputChannelList[i] == pOutputChannelList[j])
2033 break;
2034 }
2035 if (j == outputNumOfChannels)
2036 {
2037 if (pInputChannelList[i])
2038 {
Madan Mohan Koyyalamudif5c368b2012-12-06 13:10:13 -08002039 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002040 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
2041 pInputChannelList[i]);
2042 pOutputChannelList[numChannels] = pInputChannelList[i];
2043 numChannels++;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002044 }
2045 }
2046 }
2047
2048 // Return final number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002049 *pMergedOutputNumOfChannels = numChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002050
2051 return eHAL_STATUS_SUCCESS;
2052}
2053
2054/* ---------------------------------------------------------------------------
2055
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 \fn csrNeighborRoamCreateChanListFromNeighborReport
2057
2058 \brief This function is invoked when neighbor report is received for the
2059 neighbor request. Based on the channels present in the neighbor report,
2060 it generates channel list which will be used in REPORT_SCAN state to
2061 scan for these neighbor APs
2062
2063 \param pMac - The handle returned by macOpen.
2064
2065 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2066
2067---------------------------------------------------------------------------*/
2068VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
2069{
2070 tpRrmNeighborReportDesc pNeighborBssDesc;
2071 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002072 tANI_U8 numChannels = 0, i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002073 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002074#if 0
2075 eHalStatus status = eHAL_STATUS_SUCCESS;
2076#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002077
2078 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
2079 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
2080
2081 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
2082
2083 while (pNeighborBssDesc)
2084 {
2085 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
2086
2087 /* Update the neighbor BSS Info in the 11r FT Roam Info */
2088 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
2089 pNeighborBssDesc->pNeighborBssDescription->channel;
2090 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
2091 (tANI_U8)pNeighborBssDesc->roamScore;
2092 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
2093 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
2094 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
2095
2096 /* Saving the channel list non-redundantly */
2097 if (numChannels > 0)
2098 {
2099 for (i = 0; i < numChannels; i++)
2100 {
2101 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
2102 break;
2103 }
2104
2105 }
2106 if (i == numChannels)
2107 {
2108 if (pNeighborBssDesc->pNeighborBssDescription->channel)
2109 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002110 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
2111 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
2112 pNeighborBssDesc->pNeighborBssDescription->channel);
2113 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
2114 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 }
2116 }
2117
2118 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
2119 }
2120
2121 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2122 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002123#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 // Before we free the existing channel list for a safety net make sure
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002125 // we have a union of the IAPP and the already existing list.
2126 status = csrNeighborRoamMergeChannelLists(
2127 pMac,
2128 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2129 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels,
2130 channelList,
2131 numChannels,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002132 &numChannels );
2133#endif
2134
Jeff Johnson295189b2012-06-20 16:38:30 -07002135 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2136 }
2137
2138 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2139 /* Store the obtained channel list to the Neighbor Control data structure */
2140 if (numChannels)
2141 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
2142 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2143 {
2144 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
2145 return VOS_STATUS_E_RESOURCES;
2146 }
2147
2148 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2149 channelList, (numChannels) * sizeof(tANI_U8));
2150 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
2151 if (numChannels)
2152 {
2153 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
2154 pNeighborRoamInfo->neighborRoamState);
2155 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
2156 }
2157 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2158 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
2159
2160 return VOS_STATUS_SUCCESS;
2161}
2162
2163/* ---------------------------------------------------------------------------
2164
2165 \fn csrNeighborRoamRRMNeighborReportResult
2166
2167 \brief This function is the neighbor report callback that will be invoked by
2168 SME RRM on receiving a neighbor report or of neighbor report is not
2169 received after timeout. On receiving a valid report, it generates a
2170 channel list from the neighbor report and starts the
2171 neighbor scan timer
2172
2173 \param context - The handle returned by macOpen.
2174 vosStatus - Status of the callback(SUCCESS/FAILURE)
2175
2176 \return VOID
2177
2178---------------------------------------------------------------------------*/
2179void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
2180{
2181 tpAniSirGlobal pMac = PMAC_STRUCT(context);
2182 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2183 eHalStatus status = eHAL_STATUS_SUCCESS;
2184
2185 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
2186 switch (pNeighborRoamInfo->neighborRoamState)
2187 {
2188 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
2189 /* Reset the report pending variable */
2190 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
2191 if (VOS_STATUS_SUCCESS == vosStatus)
2192 {
2193 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
2194 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
2195 if (VOS_STATUS_SUCCESS == vosStatus)
2196 {
2197 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
2198 }
2199
2200 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2201 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2202
2203 /* Now ready for neighbor scan based on the channel list created */
2204 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2205 what palTimerStart expects */
2206 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2207 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2208 eANI_BOOLEAN_FALSE);
2209 if (eHAL_STATUS_SUCCESS != status)
2210 {
2211 /* Timer start failed.. Should we ASSERT here??? */
2212 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
2213 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2214 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2215 return;
2216 }
2217 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2218 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
2219 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
2220 }
2221 else
2222 {
2223 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
2224 reach the maxNeighborRetries or receiving a successful neighbor response */
2225 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
2226 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
2227 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
2228 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
2229 {
2230 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
2231 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2232 if (VOS_STATUS_SUCCESS != vosStatus)
2233 {
2234 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
2235 return;
2236 }
2237 /* We transitioned to different state now. Reset the Neighbor report retry count */
2238 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2239 }
2240 else
2241 {
2242 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2243 if (VOS_STATUS_SUCCESS != vosStatus)
2244 {
2245 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2246 return;
2247 }
2248 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2249 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2250 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2251 }
2252 }
2253 break;
2254 default:
2255 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
2256 break;
2257 }
2258 return;
2259}
2260#endif /* WLAN_FEATURE_VOWIFI_11R */
2261
2262
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002263#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002264tANI_BOOLEAN csrNeighborRoamIsSsidAndSecurityMatch(
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002265 tpAniSirGlobal pMac,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002266 tCsrRoamConnectedProfile *pCurProfile,
2267 tSirBssDescription *pBssDesc,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002268 tDot11fBeaconIEs *pIes)
2269{
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002270 tCsrAuthList authType;
2271 tCsrEncryptionList uCEncryptionType;
2272 tCsrEncryptionList mCEncryptionType;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002273 tANI_BOOLEAN fMatch = FALSE;
2274
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002275 authType.numEntries = 1;
2276 authType.authType[0] = pCurProfile->AuthType;
2277 uCEncryptionType.numEntries = 1;
2278 uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
2279 mCEncryptionType.numEntries = 1;
2280 mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002281
2282 if( pIes )
2283 {
2284 if(pIes->SSID.present)
2285 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002286 fMatch = csrIsSsidMatch( pMac,
2287 (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length,
2288 pIes->SSID.ssid, pIes->SSID.num_ssid,
2289 eANI_BOOLEAN_TRUE );
2290 if(TRUE == fMatch)
2291 {
2292 fMatch = csrIsSecurityMatch( pMac, &authType, &uCEncryptionType,
2293 &mCEncryptionType, pBssDesc, pIes, NULL, NULL, NULL );
2294 return (fMatch);
2295 }
2296 else
2297 {
2298 return (fMatch);
2299 }
2300
2301 }
2302 else
2303 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002304 return FALSE; // Treat a missing SSID as a non-match.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002305 }
2306 }
2307 else
2308 {
2309 return FALSE; // Again, treat missing pIes as a non-match.
2310 }
2311}
2312
2313tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile(
2314 tpAniSirGlobal pMac)
2315{
2316 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2317 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
2318 tCsrRoamConnectedProfile *pCurrProfile = NULL;
2319 tCsrRoamConnectedProfile *pPrevProfile = NULL;
2320 tDot11fBeaconIEs *pIes = NULL;
2321 tSirBssDescription *pBssDesc = NULL;
2322 tANI_BOOLEAN fNew = TRUE;
2323
2324 if(!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId)))
2325 {
2326 return (fNew);
2327 }
2328
2329 pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
2330 if( !pCurrProfile )
2331 {
2332 return (fNew);
2333}
2334
2335 pPrevProfile = &pNeighborRoamInfo->prevConnProfile;
2336 if( !pPrevProfile )
2337 {
2338 return (fNew);
2339 }
2340
2341 pBssDesc = pPrevProfile->pBssDesc;
2342 if (pBssDesc)
2343 {
2344 if (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
2345 pBssDesc, &pIes)) &&
2346 csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurrProfile, pBssDesc, pIes))
2347 {
2348 fNew = FALSE;
2349 }
2350 if (pIes) {
2351 palFreeMemory(pMac->hHdd, pIes);
2352 }
2353 }
2354
2355 if (fNew)
2356 {
2357 smsLog(pMac, LOG1, FL("Prev roam profile did not match current"));
2358 csrRoamFreeConnectProfile(pMac, pPrevProfile);
2359 csrRoamGetConnectProfile(pMac, sessionId, pPrevProfile);
2360 }
2361 else
2362 {
2363 smsLog(pMac, LOG1, FL("Prev roam profile matches current"));
2364 }
2365
2366 return (fNew);
2367}
2368
2369tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch(
2370 tpAniSirGlobal pMac,
2371 tCsrScanResult *pResult,
2372 tDot11fBeaconIEs *pIes)
2373{
2374 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2375 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
2376 tCsrRoamConnectedProfile *pCurProfile = NULL;
2377 tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor;
2378
2379 if( !(pMac->roam.roamSession
2380 && CSR_IS_SESSION_VALID(pMac, sessionId)))
2381 {
2382 return FALSE;
2383 }
2384
2385 pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
2386
2387 if( !pCurProfile)
2388 {
2389 return FALSE;
2390 }
2391
2392 return csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurProfile, pBssDesc, pIes);
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002393}
2394
2395/* ---------------------------------------------------------------------------
2396
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002397 \fn csrNeighborRoamPrepareNonOccupiedChannelList
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002398
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002399 \brief This function is used to prepare a channel list that is derived from
2400 the list of valid channels and does not include those in the occupied
2401 list.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002402
2403 \param pMac - The handle returned by macOpen.
2404 \param pInputChannelList - The default channels list.
2405 \param numOfChannels - The number of channels in the default channels list.
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002406 \param pOutputChannelList - The place to put the non-occupied channel list.
2407 \param pOutputNumOfChannels - The number of channels in the non-occupied channel list.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002408
2409 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2410
2411---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002412VOS_STATUS csrNeighborRoamPrepareNonOccupiedChannelList(
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002413 tpAniSirGlobal pMac,
2414 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002415 int numOfChannels,
2416 tANI_U8 *pOutputChannelList,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002417 int *pOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002418 )
2419{
2420 int i = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002421 int outputNumOfChannels = 0; // Clear the output number of channels
2422 tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels;
2423 tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList;
2424
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002425 for (i = 0; i < numOfChannels; i++)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002426 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002427 if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels,
2428 pInputChannelList[i]))
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002429 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002430 pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002431 }
2432 }
2433
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002434 smsLog(pMac, LOG2, FL("Number of channels in the valid channel list=%d; "
2435 "Number of channels in the non-occupied list list=%d"),
2436 numOfChannels, outputNumOfChannels);
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002437
2438 // Return the number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002439 *pOutputNumOfChannels = outputNumOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002440
2441 return eHAL_STATUS_SUCCESS;
2442}
2443#endif /* FEATURE_WLAN_LFR */
2444
Jeff Johnson295189b2012-06-20 16:38:30 -07002445/* ---------------------------------------------------------------------------
2446
2447 \fn csrNeighborRoamTransitToCFGChanScan
2448
2449 \brief This function is called whenever there is a transition to CFG chan scan
2450 state from any state. It frees up the current channel list and allocates
2451 a new memory for the channels received from CFG item. It then starts the
2452 neighbor scan timer to perform the scan on each channel one by one
2453
2454 \param pMac - The handle returned by macOpen.
2455
2456 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2457
2458---------------------------------------------------------------------------*/
2459VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
2460{
2461 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2462 eHalStatus status = eHAL_STATUS_SUCCESS;
2463 int i = 0;
2464 int numOfChannels = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002465 tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002466 tpCsrChannelInfo currChannelListInfo;
2467
2468 currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07002469
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002470 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07002471#ifdef FEATURE_WLAN_CCX
2472 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002473 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07002474 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
2475#endif // CCX
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002476 currChannelListInfo->numOfChannels == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002477 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002478 smsLog(pMac, LOGW, FL("Building channel list to scan"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002479
2480
2481 /* Free up the channel list and allocate a new memory. This is because we dont know how much
2482 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
2483 result in memory corruption */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002484 if (NULL != currChannelListInfo->ChannelList)
Jeff Johnson295189b2012-06-20 16:38:30 -07002485 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002486 vos_mem_free(currChannelListInfo->ChannelList);
2487 currChannelListInfo->ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002488 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002489
2490 // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER
2491 // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR.
2492 if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
Jeff Johnson295189b2012-06-20 16:38:30 -07002493 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002494 // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini".
2495 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini");
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002496 status = csrNeighborRoamMergeChannelLists(
2497 pMac,
2498 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2499 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels,
2500 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002501 0, //NB: If 0, simply copy the input channel list to the output list.
2502 &numOfChannels );
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002503
2504 currChannelListInfo->ChannelList =
2505 vos_mem_malloc(numOfChannels*sizeof(tANI_U8));
2506 if (NULL == currChannelListInfo->ChannelList)
2507 {
2508 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2509 return VOS_STATUS_E_RESOURCES;
2510 }
2511
2512 vos_mem_copy(currChannelListInfo->ChannelList,
2513 channelList, numOfChannels * sizeof(tANI_U8));
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002514 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002515 else
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002516 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002517 /* Get current list of valid channels. */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002518 numOfChannels = pMac->scan.occupiedChannels.numChannels;
2519 if (numOfChannels
2520#ifdef FEATURE_WLAN_LFR
2521 && ((pNeighborRoamInfo->uEmptyScanCount == 0) ||
2522 ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1))
2523#endif
2524 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002525 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002526 /*
2527 * Always scan channels in the occupied channel list
2528 * before scanning on the non-occupied list.
2529 */
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302530 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to occupied channel list");
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002531 VOS_ASSERT(currChannelListInfo->ChannelList == NULL);
2532 currChannelListInfo->ChannelList = vos_mem_malloc(numOfChannels);
2533
2534 if (NULL == currChannelListInfo->ChannelList)
2535 {
2536 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2537 return VOS_STATUS_E_RESOURCES;
2538 }
2539 vos_mem_copy(currChannelListInfo->ChannelList,
2540 pMac->scan.occupiedChannels.channelList,
2541 numOfChannels * sizeof(tANI_U8));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002542 }
2543 else
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002544 {
2545 /* Scan all channels from non-occupied list */
2546 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Get valid channel list");
2547 numOfChannels = sizeof(pMac->roam.validChannelList);
2548
2549 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac,
2550 (tANI_U8 *)pMac->roam.validChannelList,
2551 (tANI_U32 *) &numOfChannels)))
2552 {
2553#ifdef FEATURE_WLAN_LFR
2554 /*
2555 * Prepare non-occupied channel list (channelList)
2556 * from the actual "valid channel list" information
2557 * formed by CSR.
2558 */
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302559 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to non-occupied channel list");
2560 status = csrNeighborRoamPrepareNonOccupiedChannelList(pMac,
2561 (tANI_U8 *)pMac->roam.validChannelList,
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002562 numOfChannels,
2563 channelList,
2564 &numOfChannels);
2565#else
2566 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Merging channel list");
2567 status = csrNeighborRoamMergeChannelLists(
2568 pMac,
2569 (tANI_U8 *)pMac->roam.validChannelList,
2570 numOfChannels, // The number of channels in the validChannelList
2571 channelList,
2572 0, //NB: If 0, simply copy the input channel list to the output list.
2573 &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels
2574#endif
2575 }
2576 else
2577 {
2578 smsLog(pMac, LOGE, FL("Could not get valid channel list"));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002579 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002580 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002581 currChannelListInfo->ChannelList =
2582 vos_mem_malloc(numOfChannels*sizeof(tANI_U8));
2583
2584 if (NULL == currChannelListInfo->ChannelList)
2585 {
2586 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed"));
2587 return VOS_STATUS_E_RESOURCES;
2588 }
2589#ifdef FEATURE_WLAN_LFR
2590 vos_mem_copy(currChannelListInfo->ChannelList,
2591 channelList, numOfChannels * sizeof(tANI_U8));
2592#else
2593 vos_mem_copy(currChannelListInfo->ChannelList,
2594 (tANI_U8 *)pMac->roam.validChannelList,
2595 numOfChannels * sizeof(tANI_U8));
2596#endif
2597 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 }
2599
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002600 /* Adjust for the actual number that are used */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002601 currChannelListInfo->numOfChannels = numOfChannels;
2602 for (i = 0; i < currChannelListInfo->numOfChannels; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 {
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302604 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Channel List from CFG (or) (non-)occupied list"
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002605 "= %d\n", currChannelListInfo->ChannelList[i]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 }
2607 }
2608
2609 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2610 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2611
2612 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2613 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2614 what palTimerStart expects */
2615 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2616 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2617 eANI_BOOLEAN_FALSE);
2618
2619 if (eHAL_STATUS_SUCCESS != status)
2620 {
2621 /* Timer start failed.. */
2622 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002623 vos_mem_free(currChannelListInfo->ChannelList);
2624 currChannelListInfo->ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 return VOS_STATUS_E_FAILURE;
2626 }
2627
2628 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2629 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302630 /* We are about to start a fresh scan cycle,
2631 * purge non-P2P results from the past */
2632 csrScanFlushSelectiveResult(pMac, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002633
2634 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2635 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2636
2637 return VOS_STATUS_SUCCESS;
2638}
2639
2640/* ---------------------------------------------------------------------------
2641
2642 \fn csrNeighborRoamNeighborLookupUpEvent
2643
2644 \brief This function is called as soon as TL indicates that the current AP's
2645 RSSI is better than the neighbor lookup threshold. Here, we transition to
2646 CONNECTED state and reset all the scan parameters
2647
2648 \param pMac - The handle returned by macOpen.
2649
2650 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2651
2652---------------------------------------------------------------------------*/
2653VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2654{
2655 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2656 VOS_STATUS vosStatus;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002657 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002658
Jeff Johnson295189b2012-06-20 16:38:30 -07002659 /* Recheck whether the below check is needed. */
2660 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2661 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
Jeff Johnsone7245742012-09-05 17:12:55 -07002662
2663 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2664 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2665
Jeff Johnson295189b2012-06-20 16:38:30 -07002666
2667 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2668 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2669 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2670 WLANTL_HO_THRESHOLD_DOWN,
2671 csrNeighborRoamNeighborLookupDOWNCallback,
2672 VOS_MODULE_ID_SME, pMac);
2673 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2674 {
2675 //err msg
2676 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2677 }
2678
2679
2680 return vosStatus;
2681}
2682
2683/* ---------------------------------------------------------------------------
2684
2685 \fn csrNeighborRoamNeighborLookupDownEvent
2686
2687 \brief This function is called as soon as TL indicates that the current AP's
2688 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2689 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2690 a non-11R association.
2691
2692 \param pMac - The handle returned by macOpen.
2693
2694 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2695
2696---------------------------------------------------------------------------*/
2697VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2698{
2699 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2700 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2701 eHalStatus status = eHAL_STATUS_SUCCESS;
2702
2703 switch (pNeighborRoamInfo->neighborRoamState)
2704 {
2705 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2706
2707 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2708 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2709 /* De-register Neighbor Lookup threshold callback with TL */
2710 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2711 WLANTL_HO_THRESHOLD_DOWN,
2712 csrNeighborRoamNeighborLookupDOWNCallback,
2713 VOS_MODULE_ID_SME);
2714
2715 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2716 {
2717 //err msg
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002718 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002719 }
2720
2721
2722#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2723 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2724 {
2725
2726 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2727 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2728 if (VOS_STATUS_SUCCESS != vosStatus)
2729 {
2730 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2731 return vosStatus;
2732 }
2733 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2734 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2735 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2736 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2737 }
2738 else
2739#endif
2740 {
2741 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2742
2743 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2744 if (VOS_STATUS_SUCCESS != vosStatus)
2745 {
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08002746 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamTransitToCFGChanScan failed"
2747 " with status=%d"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002748 return vosStatus;
2749 }
2750 }
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002751 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 -07002752 /* Register Neighbor Lookup threshold callback with TL for UP event now */
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002753 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext,
2754 (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002755 WLANTL_HO_THRESHOLD_UP,
2756 csrNeighborRoamNeighborLookupUPCallback,
2757 VOS_MODULE_ID_SME, pMac);
2758 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2759 {
2760 //err msg
Madan Mohan Koyyalamudi4450acc2012-11-15 17:24:31 -08002761 smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 }
2763 break;
2764 default:
2765 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2766 break;
2767
2768 }
2769 return vosStatus;
2770}
2771
2772/* ---------------------------------------------------------------------------
2773
2774 \fn csrNeighborRoamNeighborLookupUPCallback
2775
2776 \brief This function is registered with TL to indicate whenever the RSSI
2777 gets better than the neighborLookup RSSI Threshold
2778
2779 \param pAdapter - VOS Context
2780 trafficStatus - UP/DOWN indication from TL
2781 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2782
2783 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2784
2785---------------------------------------------------------------------------*/
2786VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2787 v_PVOID_t pUserCtxt)
2788{
2789 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2790 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2791 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2792
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302793 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
Jeff Johnson295189b2012-06-20 16:38:30 -07002794
2795 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2796 {
2797 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2798 return VOS_STATUS_SUCCESS;
2799 }
2800
2801 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2802 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2803 return vosStatus;
2804}
2805
2806/* ---------------------------------------------------------------------------
2807
2808 \fn csrNeighborRoamNeighborLookupDOWNCallback
2809
2810 \brief This function is registered with TL to indicate whenever the RSSI
2811 falls below the current neighborLookup RSSI Threshold
2812
2813 \param pAdapter - VOS Context
2814 trafficStatus - UP/DOWN indication from TL
2815 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2816
2817 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2818
2819---------------------------------------------------------------------------*/
2820VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2821 v_PVOID_t pUserCtxt)
2822{
2823 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2824 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2825 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2826
Madan Mohan Koyyalamudi22f27082012-11-27 19:11:12 +05302827 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
Jeff Johnson295189b2012-06-20 16:38:30 -07002828
2829 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2830 {
2831 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2832 return VOS_STATUS_SUCCESS;
2833 }
2834
2835 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2836 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2837
2838 return vosStatus;
2839}
2840
2841#ifdef RSSI_HACK
2842extern int dumpCmdRSSI;
2843#endif
2844
2845/* ---------------------------------------------------------------------------
2846
2847 \fn csrNeighborRoamIndicateDisconnect
2848
2849 \brief This function is called by CSR as soon as the station disconnects from
2850 the AP. This function does the necessary cleanup of neighbor roam data
2851 structures. Neighbor roam state transitions to INIT state whenever this
2852 function is called except if the current state is REASSOCIATING
2853
2854 \param pMac - The handle returned by macOpen.
2855 sessionId - CSR session id that got disconnected
2856
2857 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2858
2859---------------------------------------------------------------------------*/
2860eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2861{
2862 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2863
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002864 smsLog(pMac, LOGE, FL("Disconnect indication on session %d in state %d (sub-state %d)"),
2865 sessionId, pNeighborRoamInfo->neighborRoamState,
2866 pMac->roam.curSubState[sessionId]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002867
2868#ifdef FEATURE_WLAN_CCX
2869 {
2870 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2871 if (pSession->connectedProfile.isCCXAssoc)
2872 {
2873 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2874 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2875 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2876 pSession->isPrevApInfoValid = TRUE;
2877 pSession->roamTS1 = vos_timer_get_system_time();
2878
2879 }
2880 }
2881#endif
2882
2883#ifdef RSSI_HACK
2884 dumpCmdRSSI = -40;
2885#endif
2886 switch (pNeighborRoamInfo->neighborRoamState)
2887 {
2888 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2889 // Stop scan and neighbor refresh timers.
2890 // These are indeed not required when we are in reassociating
2891 // state.
2892 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2893 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002894 if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId )) {
2895 /*
2896 * Disconnect indication during Disassoc Handoff sub-state
2897 * is received when we are trying to disconnect with the old
2898 * AP during roam. BUT, if receive a disconnect indication
2899 * outside of Disassoc Handoff sub-state, then it means that
2900 * this is a genuine disconnect and we need to clean up.
2901 * Otherwise, we will be stuck in reassoc state which will
2902 * in-turn block scans (see csrIsScanAllowed).
2903 */
2904 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002906 break;
2907
2908 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 csrNeighborRoamResetInitStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002910 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 break;
2912
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002913 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
2914 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2915 csrNeighborRoamResetCfgListChanScanControlInfo(pMac);
2916 csrNeighborRoamDeregAllRssiIndication(pMac);
2917 break;
2918
2919 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
2920 /* Stop pre-auth to reassoc interval timer */
2921 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002922 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2923 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2924 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002925 csrNeighborRoamResetPreauthControlInfo(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002926 csrNeighborRoamResetReportScanStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002927 csrNeighborRoamDeregAllRssiIndication(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002928 break;
2929
Jeff Johnson295189b2012-06-20 16:38:30 -07002930 default:
Madan Mohan Koyyalamudi5695b502012-09-24 14:21:12 -07002931 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2932 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002934 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002935 }
2936 return eHAL_STATUS_SUCCESS;
2937}
2938
2939/* ---------------------------------------------------------------------------
2940
2941 \fn csrNeighborRoamIndicateConnect
2942
2943 \brief This function is called by CSR as soon as the station connects to an AP.
2944 This initializes all the necessary data structures related to the
2945 associated AP and transitions the state to CONNECTED state
2946
2947 \param pMac - The handle returned by macOpen.
2948 sessionId - CSR session id that got connected
2949 vosStatus - connect status SUCCESS/FAILURE
2950
2951 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2952
2953---------------------------------------------------------------------------*/
2954eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2955{
2956 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2957 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002958 VOS_STATUS vstatus;
2959
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002960#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 int init_ft_flag = FALSE;
2962#endif
2963
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002964 smsLog(pMac, LOG2, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002965
2966 switch (pNeighborRoamInfo->neighborRoamState)
2967 {
2968 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2969 if (VOS_STATUS_SUCCESS != vosStatus)
2970 {
2971 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2972 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2973 break;
2974 }
2975 /* Fall through if the status is SUCCESS */
2976 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2977 /* Reset all the data structures here */
2978 csrNeighborRoamResetInitStateControlInfo(pMac);
2979
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 pNeighborRoamInfo->csrSessionId = sessionId;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002981
2982#ifdef FEATURE_WLAN_LFR
2983 /*
2984 * Initialize the occupied list ONLY if we are
2985 * transitioning from INIT state to CONNECTED state.
2986 */
2987 if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState)
2988 csrInitOccupiedChannelsList(pMac);
2989#endif
2990 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
2991
Jeff Johnson295189b2012-06-20 16:38:30 -07002992 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2993 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2994 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2995 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2996 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08002997 pNeighborRoamInfo->currentNeighborLookupThreshold =
2998 pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
2999#ifdef FEATURE_WLAN_LFR
3000 pNeighborRoamInfo->uEmptyScanCount = 0;
3001#endif
3002
Jeff Johnson295189b2012-06-20 16:38:30 -07003003
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003004#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07003005 /* Now we can clear the preauthDone that was saved as we are connected afresh */
3006 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3007#endif
3008
3009#ifdef WLAN_FEATURE_VOWIFI_11R
3010 // Based on the auth scheme tell if we are 11r
Madan Mohan Koyyalamudi5e32b962012-11-28 16:07:55 -08003011 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType,
3012 pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent))
Jeff Johnson295189b2012-06-20 16:38:30 -07003013 {
3014 if (pMac->roam.configParam.isFastTransitionEnabled)
3015 init_ft_flag = TRUE;
3016 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
3017 }
3018 else
3019 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003020 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
Jeff Johnson295189b2012-06-20 16:38:30 -07003021#endif
3022
3023#ifdef FEATURE_WLAN_CCX
3024 // Based on the auth scheme tell if we are 11r
3025 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
3026 {
3027 if (pMac->roam.configParam.isFastTransitionEnabled)
3028 init_ft_flag = TRUE;
3029 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
3030 }
3031 else
3032 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003033 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isCCXAssoc is = %d ft = %d"),
3034 pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
Jeff Johnson295189b2012-06-20 16:38:30 -07003035
3036#endif
3037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003038#ifdef FEATURE_WLAN_LFR
3039 // If "Legacy Fast Roaming" is enabled
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05303040 if (csrRoamIsFastRoamEnabled(pMac, sessionId))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003041 {
3042 init_ft_flag = TRUE;
3043 }
3044#endif
3045
3046#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07003047 if ( init_ft_flag == TRUE )
3048 {
3049 /* Initialize all the data structures needed for the 11r FT Preauth */
3050 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
3051 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
3052 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
3053 csrNeighborRoamPurgePreauthFailedList(pMac);
3054
3055 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
3056 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07003057 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07003058 WLANTL_HO_THRESHOLD_DOWN,
3059 csrNeighborRoamNeighborLookupDOWNCallback,
3060 VOS_MODULE_ID_SME, pMac);
3061
Jeff Johnson43971f52012-07-17 12:26:56 -07003062 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07003063 {
3064 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07003065 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
3066 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003067 }
3068 }
3069#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003070 break;
3071 default:
3072 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
3073 break;
3074 }
3075 return status;
3076}
3077
3078
3079#ifdef WLAN_FEATURE_VOWIFI_11R
3080/* ---------------------------------------------------------------------------
3081
3082 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
3083
3084 \brief If this function is invoked, that means the preauthentication response
3085 is timed out from the PE. Preauth rsp handler is called with status as
3086 TIMEOUT
3087
3088 \param context - CSR Timer info which holds pMac and session ID
3089
3090 \return VOID
3091
3092---------------------------------------------------------------------------*/
3093void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
3094{
3095 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
3096 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
3097 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3098
3099 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
3100
3101 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
3102}
3103
3104/* ---------------------------------------------------------------------------
3105
3106 \fn csrNeighborRoamPurgePreauthFailedList
3107
3108 \brief This function purges all the MAC addresses in the pre-auth fail list
3109
3110 \param pMac - The handle returned by macOpen.
3111
3112 \return VOID
3113
3114---------------------------------------------------------------------------*/
3115void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
3116{
3117 tANI_U8 i;
3118
3119 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
3120 {
3121 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
3122 }
3123 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
3124
3125 return;
3126}
3127
3128/* ---------------------------------------------------------------------------
3129
3130 \fn csrNeighborRoamInit11rAssocInfo
3131
3132 \brief This function initializes 11r related neighbor roam data structures
3133
3134 \param pMac - The handle returned by macOpen.
3135
3136 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
3137
3138---------------------------------------------------------------------------*/
3139eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
3140{
3141 eHalStatus status;
3142 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
3143
3144 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
3145 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
3146 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
3147 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
3148 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
3149 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
3150
3151 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
3152 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3153 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
3154 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
3155
3156 if (eHAL_STATUS_SUCCESS != status)
3157 {
3158 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3159 return eHAL_STATUS_RESOURCES;
3160 }
3161
3162 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
3163 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
3164 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
3165 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
3166
3167
3168 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
3169 if (eHAL_STATUS_SUCCESS != status)
3170 {
3171 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
3172 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
3173 return eHAL_STATUS_RESOURCES;
3174 }
3175 return status;
3176}
3177#endif /* WLAN_FEATURE_VOWIFI_11R */
3178
3179/* ---------------------------------------------------------------------------
3180
3181 \fn csrNeighborRoamInit
3182
3183 \brief This function initializes neighbor roam data structures
3184
3185 \param pMac - The handle returned by macOpen.
3186
3187 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
3188
3189---------------------------------------------------------------------------*/
3190eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
3191{
3192 eHalStatus status;
3193 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3194
3195 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
3196 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
3197 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
3198 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
3199 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
3200 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
3201 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
3202 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
3203 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
3204 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
3205
3206 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
3207 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
3208
3209 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
3210 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
3211
3212 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
3213 {
3214 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
3215 return eHAL_STATUS_RESOURCES;
3216 }
3217
3218 /* Update the roam global structure from CFG */
3219 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
3220 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
3221 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
3222
3223 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
3224 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08003225#ifdef FEATURE_WLAN_LFR
3226 pNeighborRoamInfo->uEmptyScanCount = 0;
3227 palZeroMemory(pMac->hHdd, &pNeighborRoamInfo->prevConnProfile,
3228 sizeof(tCsrRoamConnectedProfile));
3229#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003230 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
3231
3232 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
3233 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3234 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
3235 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
3236
3237 if (eHAL_STATUS_SUCCESS != status)
3238 {
3239 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3240 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3241 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3242 return eHAL_STATUS_RESOURCES;
3243 }
3244
3245 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
3246 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
3247
3248 if (eHAL_STATUS_SUCCESS != status)
3249 {
3250 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
3251 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3252 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3253 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3254 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3255 return eHAL_STATUS_RESOURCES;
3256 }
3257
3258 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
3259 if (eHAL_STATUS_SUCCESS != status)
3260 {
3261 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3262 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3263 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3264 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3265 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3266 return eHAL_STATUS_RESOURCES;
3267 }
3268
3269 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
3270 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
3271 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3272 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
3273 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
3274
3275#ifdef WLAN_FEATURE_VOWIFI_11R
3276 status = csrNeighborRoamInit11rAssocInfo(pMac);
3277 if (eHAL_STATUS_SUCCESS != status)
3278 {
3279 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
3280 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3281 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3282 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3283 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3284 csrLLClose(&pNeighborRoamInfo->roamableAPList);
3285 return eHAL_STATUS_RESOURCES;
3286 }
3287#endif
3288 /* Initialize this with the current tick count */
3289 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
3290
3291 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3292
3293 return eHAL_STATUS_SUCCESS;
3294}
3295
3296/* ---------------------------------------------------------------------------
3297
3298 \fn csrNeighborRoamClose
3299
3300 \brief This function closes/frees all the neighbor roam data structures
3301
3302 \param pMac - The handle returned by macOpen.
3303
3304 \return VOID
3305
3306---------------------------------------------------------------------------*/
3307void csrNeighborRoamClose(tpAniSirGlobal pMac)
3308{
3309 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3310
3311 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
3312 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07003313 smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003314 return;
3315 }
3316
3317 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
3318 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
3319
3320 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
3321
3322 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
3323 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3324 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
3325 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
3326
3327 /* Should free up the nodes in the list before closing the double Linked list */
3328 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
3329 csrLLClose(&pNeighborRoamInfo->roamableAPList);
3330
3331 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
3332 {
3333 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
3334 }
3335
3336 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3337 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
3338 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
3339 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
3340 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
3341 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
3342
3343 /* Free the profile.. */
3344 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
3345
3346#ifdef WLAN_FEATURE_VOWIFI_11R
3347 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
3348 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
3349 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
3350 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3351 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
3352 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
3353 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
3354 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3355 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3356#endif /* WLAN_FEATURE_VOWIFI_11R */
3357
3358 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
3359
3360 return;
3361}
3362
3363/* ---------------------------------------------------------------------------
3364
3365 \fn csrNeighborRoamRequestHandoff
3366
3367 \brief This function triggers actual switching from one AP to the new AP.
3368 It issues disassociate with reason code as Handoff and CSR as a part of
3369 handling disassoc rsp, issues reassociate to the new AP
3370
3371 \param pMac - The handle returned by macOpen.
3372
3373 \return VOID
3374
3375---------------------------------------------------------------------------*/
3376void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
3377{
3378
3379 tCsrRoamInfo roamInfo;
3380 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3381 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
3382 tCsrNeighborRoamBSSInfo handoffNode;
3383 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
3384 tANI_U32 roamId = 0;
3385
3386 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
3387 {
3388 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
3389 pMac->roam.neighborRoamInfo.neighborRoamState);
3390 return;
3391 }
3392
3393 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3394 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
3395 eSIR_SME_SUCCESS);
3396
3397 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3398 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
3399
3400 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
3401 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
3402 handoffNode.pBssDescription->bssId[0],
3403 handoffNode.pBssDescription->bssId[1],
3404 handoffNode.pBssDescription->bssId[2],
3405 handoffNode.pBssDescription->bssId[3],
3406 handoffNode.pBssDescription->bssId[4],
3407 handoffNode.pBssDescription->bssId[5]);
3408
3409 /* Free the profile.. Just to make sure we dont leak memory here */
3410 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
3411 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
3412 This should happen before issuing disconnect */
3413 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
3414 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
3415 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
3416
3417 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
3418
3419 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
3420 {
3421 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
3422 return;
3423 }
3424
3425 //notify HDD for handoff, providing the BSSID too
3426 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
3427
3428 vos_mem_copy(roamInfo.bssid,
3429 handoffNode.pBssDescription->bssId,
3430 sizeof( tCsrBssid ));
3431
3432 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
3433
3434
3435 return;
3436}
3437
3438/* ---------------------------------------------------------------------------
3439
3440 \fn csrNeighborRoamIsHandoffInProgress
3441
3442 \brief This function returns whether handoff is in progress or not based on
3443 the current neighbor roam state
3444
3445 \param pMac - The handle returned by macOpen.
3446 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
3447
3448 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
3449
3450---------------------------------------------------------------------------*/
3451tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
3452{
3453 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
3454 return eANI_BOOLEAN_TRUE;
3455
3456 return eANI_BOOLEAN_FALSE;
3457}
3458
Madan Mohan Koyyalamudi5e32b962012-11-28 16:07:55 -08003459#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(WLAN_FEATURE_NEIGHBOR_ROAMING)
Jeff Johnson295189b2012-06-20 16:38:30 -07003460/* ---------------------------------------------------------------------------
3461
3462 \fn csrNeighborRoamIs11rAssoc
3463
3464 \brief This function returns whether the current association is a 11r assoc or not
3465
3466 \param pMac - The handle returned by macOpen.
3467
3468 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
3469
3470---------------------------------------------------------------------------*/
3471tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
3472{
3473 return pMac->roam.neighborRoamInfo.is11rAssoc;
3474}
3475#endif /* WLAN_FEATURE_VOWIFI_11R */
3476
3477
3478/* ---------------------------------------------------------------------------
3479
3480 \fn csrNeighborRoamGetHandoffAPInfo
3481
3482 \brief This function returns the best possible AP for handoff. For 11R case, it
3483 returns the 1st entry from pre-auth done list. For non-11r case, it returns
3484 the 1st entry from roamable AP list
3485
3486 \param pMac - The handle returned by macOpen.
3487 pHandoffNode - AP node that is the handoff candidate returned
3488
3489 \return VOID
3490
3491---------------------------------------------------------------------------*/
3492void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
3493{
3494 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3495 tpCsrNeighborRoamBSSInfo pBssNode;
3496
3497 VOS_ASSERT(NULL != pHandoffNode);
3498
3499#ifdef WLAN_FEATURE_VOWIFI_11R
3500 if (pNeighborRoamInfo->is11rAssoc)
3501 {
3502 /* Always the BSS info in the head is the handoff candidate */
3503 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3504 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3505 }
3506 else
3507#endif
3508#ifdef FEATURE_WLAN_CCX
3509 if (pNeighborRoamInfo->isCCXAssoc)
3510 {
3511 /* Always the BSS info in the head is the handoff candidate */
3512 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3513 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3514 }
3515 else
3516#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003517#ifdef FEATURE_WLAN_LFR
Madan Mohan Koyyalamudi03aae5f2012-11-28 01:51:22 +05303518 if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003519 {
3520 /* Always the BSS info in the head is the handoff candidate */
3521 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3522 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3523 }
3524 else
3525#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 {
3527 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
3528 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
3529 }
3530 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
3531
3532 return;
3533}
3534
3535/* ---------------------------------------------------------------------------
3536 \brief This function returns TRUE if preauth is completed
3537
3538 \param pMac - The handle returned by macOpen.
3539
3540 \return boolean
3541
3542---------------------------------------------------------------------------*/
3543tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
3544{
3545 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
3546 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
3547}
3548
3549/* ---------------------------------------------------------------------------
3550 \brief In the event that we are associated with AP1 and we have
3551 completed pre auth with AP2. Then we receive a deauth/disassoc from
3552 AP1.
3553 At this point neighbor roam is in pre auth done state, pre auth timer
3554 is running. We now handle this case by stopping timer and clearing
3555 the pre-auth state. We basically clear up and just go to disconnected
3556 state.
3557
3558 \param pMac - The handle returned by macOpen.
3559
3560 \return boolean
3561---------------------------------------------------------------------------*/
3562void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
3563{
3564 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
3565 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
3566
3567 // Stop timer
3568 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
3569
3570 // Transition to init state
3571 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3572}
3573
3574#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */