blob: 082883557793f21739fa552b7badc7733457db8b [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
223/* ---------------------------------------------------------------------------
224
225 \fn csrNeighborRoamReassocIndCallback
226
227 \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold.
228 Directly triggere HO in case of non-11r association
229 In case of 11R association, triggers a pre-auth eventually followed by actual HO
230
231 \param pAdapter - VOS Context
232 trafficStatus - UP/DOWN indication from TL
233 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
234
235 \return VOID
236
237---------------------------------------------------------------------------*/
238VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter,
239 v_U8_t trafficStatus,
240 v_PVOID_t pUserCtxt)
241{
242 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
243 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
244 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
245
246 smsLog(pMac, LOG1, FL("Reassoc indication callback called"));
247
248
249 //smsLog(pMac, LOGE, FL("Reassoc indication callback called at state %d"), pNeighborRoamInfo->neighborRoamState);
250
251 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
252
253
254 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
255 WLANTL_HO_THRESHOLD_DOWN,
256 csrNeighborRoamReassocIndCallback,
257 VOS_MODULE_ID_SME);
258
259 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
260 {
261 //err msg
262 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
263 }
264
265 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
266 /* Deregister reassoc callback. Ignore return status */
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700267 /*Varun TODO*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
269 WLANTL_HO_THRESHOLD_DOWN,
270 csrNeighborRoamNeighborLookupUPCallback,
271 VOS_MODULE_ID_SME);
272
273 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
274 {
275 //err msg
276 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
277 }
278
279 /* We dont need to run this timer any more. */
280 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
281
282#ifdef WLAN_FEATURE_VOWIFI_11R
283 if (pNeighborRoamInfo->is11rAssoc)
284 {
285 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
286 {
287 csrNeighborRoamIssuePreauthReq(pMac);
288 }
289 else
290 {
291 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
292 VOS_ASSERT(0);
293 }
294 }
295 else
296#endif
297
298#ifdef FEATURE_WLAN_CCX
299 if (pNeighborRoamInfo->isCCXAssoc)
300 {
301 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
302 {
303 csrNeighborRoamIssuePreauthReq(pMac);
304 }
305 else
306 {
307 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
308 VOS_ASSERT(0);
309 }
310 }
311 else
312#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700313#ifdef FEATURE_WLAN_LFR
314 if (csrRoamIsFastRoamEnabled(pMac))
315 {
316 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
317 {
318 csrNeighborRoamIssuePreauthReq(pMac);
319 }
320 else
321 {
322 smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
323 VOS_ASSERT(0);
324 }
325 }
326 else
327#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 {
329 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
330 {
331 csrNeighborRoamRequestHandoff(pMac);
332 }
333 else
334 {
335 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
336 VOS_ASSERT(0);
337 }
338 }
339 return VOS_STATUS_SUCCESS;
340}
341
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700342/*CleanUP Routines*/
343static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo)
344{
345 if ((rChInfo->IAPPNeighborListReceived == FALSE) &&
346 (rChInfo->currentChannelListInfo.numOfChannels))
347 {
348 rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
349 rChInfo->currentChannelListInfo.numOfChannels = 0;
350
351 if (rChInfo->currentChannelListInfo.ChannelList)
352 vos_mem_free(rChInfo->currentChannelListInfo.ChannelList);
353
354 rChInfo->currentChannelListInfo.ChannelList = NULL;
355 rChInfo->chanListScanInProgress = eANI_BOOLEAN_FALSE;
356 }
357 else
358 {
359 rChInfo->currentChanIndex = 0;
360 rChInfo->chanListScanInProgress = eANI_BOOLEAN_TRUE;
361 }
362}
363
364static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac)
365{
366 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
367
368 /* Stop neighbor scan timer */
369 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
370
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -0700371 /* Stop neighbor scan results refresh timer */
372 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
373
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700374 /* Abort any ongoing scan */
375 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
376 {
377 csrScanAbortMacScan(pMac);
378 }
379 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
380
381 /* Reset roam channel list information */
382 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
383}
384
385static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac)
386{
387 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
388
389#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
390 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
391 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
392 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId =
393 CSR_SESSION_ID_INVALID;
394 /* Purge pre-auth fail list */
395 csrNeighborRoamPurgePreauthFailedList(pMac);
396#endif
397
398 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
399 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
400#ifdef WLAN_FEATURE_VOWIFI_11R
401 /* Do not free up the preauth done list here */
402 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
403 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
404 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
405 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
406 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
407#endif
408}
409
410static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac)
411{
412 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
413 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
414
415 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
416 FL("Deregister neighbor lookup UP callback with TL. RSSI = %d"),
417 pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
418
419 /* Deregister reassoc callback. Ignore return status */
420 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
421 (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
422 WLANTL_HO_THRESHOLD_UP,
423 csrNeighborRoamNeighborLookupUPCallback,
424 VOS_MODULE_ID_SME);
425
426 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
427 {
428 smsLog(pMac, LOGW,
429 FL("Couldn't deregister csrNeighborRoamNeighborLookupUPCallback "
430 "with TL: Status = %d\n"), vosStatus);
431 }
432
433 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
434 FL("Deregistering reassoc DOWN callback with TL. RSSI = %d"),
435 pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
436
437 /* Deregister reassoc callback. Ignore return status */
438 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
439 (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
440 WLANTL_HO_THRESHOLD_DOWN,
441 csrNeighborRoamReassocIndCallback,
442 VOS_MODULE_ID_SME);
443
444 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
445 {
446 smsLog(pMac, LOGW,
447 FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with "
448 "TL: Status = %d\n"), vosStatus);
449 }
450
451 NEIGHBOR_ROAM_DEBUG(pMac, LOG2,
452 FL("Deregistering neighborLookup DOWN callback with TL. RSSI = %d"),
453 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
454
455 /* Deregister neighbor lookup callback. Ignore return status */
456 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext,
457 (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
458 WLANTL_HO_THRESHOLD_DOWN,
459 csrNeighborRoamNeighborLookupDOWNCallback,
460 VOS_MODULE_ID_SME);
461
462 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
463 {
464 smsLog(pMac, LOGW,
465 FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback "
466 "with TL: Status = %d\n"), vosStatus);
467 }
468
469 /* Reset thresholds only after deregistering DOWN event from TL */
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700470 pNeighborRoamInfo->currentNeighborLookupThreshold =
471 pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -0700472 pNeighborRoamInfo->currentScanResultsRefreshPeriod =
473 NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700474}
475
Jeff Johnson295189b2012-06-20 16:38:30 -0700476/* ---------------------------------------------------------------------------
477
478 \fn csrNeighborRoamResetConnectedStateControlInfo
479
480 \brief This function will reset the neighbor roam control info data structures.
481 This function should be invoked whenever we move to CONNECTED state from
482 any state other than INIT state
483
484 \param pMac - The handle returned by macOpen.
485
486 \return VOID
487
488---------------------------------------------------------------------------*/
489void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
490{
491 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
492
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700493 csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700494 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700495
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700496 /* We dont need to run this timer any more. */
497 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -0700498
499#ifdef WLAN_FEATURE_VOWIFI_11R
500 /* Do not free up the preauth done list here */
501 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
502 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
503 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
504 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
505 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
506 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
507 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
508#endif
509
510}
511
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700512void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac)
Jeff Johnson295189b2012-06-20 16:38:30 -0700513{
514 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -0700515 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
516 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
517 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
518 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
Jeff Johnson295189b2012-06-20 16:38:30 -0700519#ifdef FEATURE_WLAN_CCX
520 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
521 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
522 pNeighborRoamInfo->MinQBssLoadRequired = 0;
523#endif
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -0700524
525 /* Stop scan refresh timer */
526 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700527 /* Purge roamable AP list */
528 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 return;
530}
531
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700532/* ---------------------------------------------------------------------------
533
534 \fn csrNeighborRoamResetInitStateControlInfo
535
536 \brief This function will reset the neighbor roam control info data structures.
537 This function should be invoked whenever we move to CONNECTED state from
538 INIT state
539
540 \param pMac - The handle returned by macOpen.
541
542 \return VOID
543
544---------------------------------------------------------------------------*/
545void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
546{
547 csrNeighborRoamResetConnectedStateControlInfo(pMac);
548
549 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
550 csrNeighborRoamResetReportScanStateControlInfo(pMac);
551}
552
553
554
Jeff Johnson295189b2012-06-20 16:38:30 -0700555#ifdef WLAN_FEATURE_VOWIFI_11R
556/* ---------------------------------------------------------------------------
557
558 \fn csrNeighborRoamBssIdScanFilter
559
560 \brief This API is used to prepare a filter to obtain scan results when
561 we complete the scan in the REPORT_SCAN state after receiving a
562 valid neighbor report from AP. This filter includes BSSIDs received from
563 the neighbor report from the AP in addition to the other filter parameters
564 created from connected profile
565
566 \param pMac - The handle returned by macOpen.
567 pScanFilter - Scan filter to be filled and returned
568
569 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
570 code otherwise
571
572---------------------------------------------------------------------------*/
573static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
574{
575 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
576 tANI_U8 i = 0;
577
578 VOS_ASSERT(pScanFilter != NULL);
579 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
580
581 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
582 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
583 if (NULL == pScanFilter->BSSIDs.bssid)
584 {
585 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
586 return eHAL_STATUS_FAILED_ALLOC;
587 }
588
589 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
590
591 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
592 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
593 {
594 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
595 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
596 }
597
598 /* Fill other general scan filter params */
599 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
600}
601
602/* ---------------------------------------------------------------------------
603
604 \fn csrNeighborRoamPurgePreauthFailList
605
606 \brief This function empties the preauth fail list
607
608 \param pMac - The handle returned by macOpen.
609
610 \return VOID
611
612---------------------------------------------------------------------------*/
613void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
614{
615 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
616
617 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
618 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
619 {
620 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
621 sizeof(tSirMacAddr));
622 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
623 }
624 return;
625}
626
627/* ---------------------------------------------------------------------------
628
629 \fn csrNeighborRoamAddBssIdToPreauthFailList
630
631 \brief This function adds the given BSSID to the Preauth fail list
632
633 \param pMac - The handle returned by macOpen.
634 bssId - BSSID to be added to the preauth fail list
635
636 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
637
638---------------------------------------------------------------------------*/
639eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
640{
641 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
642
643 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
644 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
645
646
647 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
648 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
649 {
650 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
651 return eHAL_STATUS_FAILURE;
652 }
653 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
654 bssId, sizeof(tSirMacAddr));
655 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
656
657 return eHAL_STATUS_SUCCESS;
658}
659
660/* ---------------------------------------------------------------------------
661
662 \fn csrNeighborRoamIsPreauthCandidate
663
664 \brief This function checks whether the given MAC address is already
665 present in the preauth fail list and returns TRUE/FALSE accordingly
666
667 \param pMac - The handle returned by macOpen.
668
669 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
670
671---------------------------------------------------------------------------*/
672tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
673{
674 tANI_U8 i = 0;
675 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
676
677 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
678 return eANI_BOOLEAN_TRUE;
679
680 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
681 {
682 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
683 bssId, sizeof(tSirMacAddr)))
684 {
685 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
686 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
687 return eANI_BOOLEAN_FALSE;
688 }
689 }
690
691 return eANI_BOOLEAN_TRUE;
692}
693
694/* ---------------------------------------------------------------------------
695
696 \fn csrNeighborRoamIssuePreauthReq
697
698 \brief This function issues preauth request to PE with the 1st AP entry in the
699 roamable AP list
700
701 \param pMac - The handle returned by macOpen.
702
703 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
704
705---------------------------------------------------------------------------*/
706static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
707{
708 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
709 eHalStatus status = eHAL_STATUS_SUCCESS;
710 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
711
712 /* This must not be true here */
713 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
714
715 /* Issue Preauth request to PE here */
716 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
717 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
718 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
719 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
720
721 if (NULL == pNeighborBssNode)
722 {
723 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
724 return eHAL_STATUS_FAILURE;
725 }
726 else
727 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700728 status = csrRoamEnqueuePreauth(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription,
729 eCsrPerformPreauth, eANI_BOOLEAN_TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -0700730 if (eHAL_STATUS_SUCCESS != status)
731 {
732 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
733 return status;
734 }
735 }
736
737 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
738
739 /* Increment the preauth retry count */
740 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
741
742 /* Transition the state to preauthenticating */
743 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700744#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700745 /* Start the preauth rsp timer */
746 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
747 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
748 eANI_BOOLEAN_FALSE);
749 if (eHAL_STATUS_SUCCESS != status)
750 {
751 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
752 return status;
753 }
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700755
756 return status;
757}
758
759/* ---------------------------------------------------------------------------
760
761 \fn csrNeighborRoamPreauthRspHandler
762
763 \brief This function handle the Preauth response from PE
764 Every preauth is allowed max 3 tries if it fails. If a bssid failed
765 for more than MAX_TRIES, we will remove it from the list and try
766 with the next node in the roamable AP list and add the BSSID to pre-auth failed
767 list. If no more entries present in
768 roamable AP list, transition to REPORT_SCAN state
769
770 \param pMac - The handle returned by macOpen.
771 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
772
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700773 \return eHAL_STATUS_SUCCESS on success (i.e. pre-auth processed),
774 eHAL_STATUS_FAILURE otherwise
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
776---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700777eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -0700778{
779 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
780 eHalStatus status = eHAL_STATUS_SUCCESS;
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700781 eHalStatus preauthProcessed = eHAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700783
784 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->FTRoamInfo.preauthRspPending)
785 {
786
787 /* This can happen when we disconnect immediately
788 * after sending a pre-auth request. During processing
789 * of the disconnect command, we would have reset
790 * preauthRspPending and transitioned to INIT state.
791 */
792 NEIGHBOR_ROAM_DEBUG(pMac, LOGW,
793 FL("Unexpected pre-auth response in state %d\n"),
794 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700795 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700796 goto DEQ_PREAUTH;
797 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700798
799 // We can receive it in these 2 states.
Jeff Johnson295189b2012-06-20 16:38:30 -0700800 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
801 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
802 {
Madan Mohan Koyyalamudi8186a9e2012-10-11 14:23:43 -0700803 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %d\n"),
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700804 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700805 preauthProcessed = eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700806 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 }
808
809 if (VOS_STATUS_E_TIMEOUT != vosStatus)
810 {
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700811#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700812 /* This means we got the response from PE. Hence stop the timer */
813 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
Madan Mohan Koyyalamudi286b60e2012-10-11 12:59:07 -0700814#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700815 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
816 }
817
818 if (VOS_STATUS_SUCCESS == vosStatus)
819 {
820 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
821 }
822 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
823 {
824 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
825
826 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
827 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
828 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
829
830 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
831 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
832 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
833
834 /* The caller of this function would start a timer and by the time it expires, supplicant should
835 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
836 }
837 else
838 {
839 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
840 tListElem *pEntry;
841
842 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
843
844 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
845 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
846 {
847 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
848 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
849
850 /* The one in the head of the list should be one with which we issued pre-auth and failed */
851 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
852 if(pEntry)
853 {
854 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
855 /* Add the BSSID to pre-auth fail list */
856 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
857 /* Now we can free this node */
858 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
859 }
860 }
861
862 /* Issue preauth request for the same/next entry */
863 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700864 goto DEQ_PREAUTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700865
866 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
867
868 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
869 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
870 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
871 eANI_BOOLEAN_FALSE);
872 if (eHAL_STATUS_SUCCESS != status)
873 {
874 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
Jeff Johnson295189b2012-06-20 16:38:30 -0700875 }
876 }
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -0700877
878DEQ_PREAUTH:
879 csrRoamDequeuePreauth(pMac);
Madan Mohan Koyyalamudi7a579cc2012-10-21 11:25:39 -0700880 return preauthProcessed;
Jeff Johnson295189b2012-06-20 16:38:30 -0700881}
882#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
883
884/* ---------------------------------------------------------------------------
885
886 \fn csrNeighborRoamPrepareScanProfileFilter
887
888 \brief This function creates a scan filter based on the currently connected profile.
889 Based on this filter, scan results are obtained
890
891 \param pMac - The handle returned by macOpen.
892 pScanFilter - Populated scan filter based on the connected profile
893
894 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
895
896---------------------------------------------------------------------------*/
897eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
898{
899 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
900 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
901 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
902 tANI_U8 i = 0;
903
904 VOS_ASSERT(pScanFilter != NULL);
905
906 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
907
908 /* We dont want to set BSSID based Filter */
909 pScanFilter->BSSIDs.numOfBSSIDs = 0;
910
911 /* Populate all the information from the connected profile */
912 pScanFilter->SSIDs.numOfSSIDs = 1;
913 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
914 if (NULL == pScanFilter->SSIDs.SSIDList)
915 {
916 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
917 return eHAL_STATUS_FAILED_ALLOC;
918 }
919 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
920 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
921 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
922 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
923
924 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
925 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
926 pScanFilter->authType.numEntries = 1;
927 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
928
929 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
930 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
931
932 pScanFilter->mcEncryptionType.numEntries = 1;
933 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
934
935 pScanFilter->BSSType = pCurProfile->BSSType;
936
937 /* We are intrested only in the scan results on channels that we scanned */
938 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
939 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
940 if (NULL == pScanFilter->ChannelInfo.ChannelList)
941 {
942 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
943 vos_mem_free(pScanFilter->SSIDs.SSIDList);
944 pScanFilter->SSIDs.SSIDList = NULL;
945 return eHAL_STATUS_FAILED_ALLOC;
946 }
947 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
948 {
949 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
950 }
951
952#ifdef WLAN_FEATURE_VOWIFI_11R
953 if (pNeighborRoamInfo->is11rAssoc)
954 {
955 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
956 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
957 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
958 }
959#endif
960
961 return eHAL_STATUS_SUCCESS;
962}
963
Jeff Johnson43971f52012-07-17 12:26:56 -0700964tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
965{
966 tCsrScanResultInfo *pScanResult;
967 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
968 tANI_U32 CurrAPRssi = -125; /* We are setting this as default value to make sure we return this value,
969 when we do not see this AP in the scan result for some reason.However,it is
970 less likely that we are associated to an AP and do not see it in the scan list*/
971
972 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
973 {
974
975 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
976 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
977 {
978 /* We got a match with the currently associated AP.
979 * Capture the RSSI value and complete the while loop.
980 * The while loop is completed in order to make the current entry go back to NULL,
981 * and in the next while loop, it properly starts searching from the head of the list.
982 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
983
984 CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ;
985
986 } else {
987 continue;
988 }
989 }
990
991 return CurrAPRssi;
992
993}
994
Jeff Johnson295189b2012-06-20 16:38:30 -0700995/* ---------------------------------------------------------------------------
996
997 \fn csrNeighborRoamProcessScanResults
998
999 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
1000 Assumed that the results are already sorted by RSSI by csrScanGetResult
1001
1002 \param pMac - The handle returned by macOpen.
1003 pScanResultList - Scan result result obtained from csrScanGetResult()
1004
1005 \return VOID
1006
1007---------------------------------------------------------------------------*/
1008
1009static void csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
1010{
1011 tCsrScanResultInfo *pScanResult;
1012 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1013 tpCsrNeighborRoamBSSInfo pBssInfo;
Jeff Johnson43971f52012-07-17 12:26:56 -07001014 tANI_U32 CurrAPRssi;
1015 tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff;
1016
1017 /***************************************************************
1018 * Find out the Current AP RSSI and keep it handy to check if
1019 * it is better than the RSSI of the AP which we are
1020 * going to roam.If so, we are going to continue with the
1021 * current AP.
1022 ***************************************************************/
1023 CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList);
Jeff Johnson295189b2012-06-20 16:38:30 -07001024
1025 /* Expecting the scan result already to be in the sorted order based on the RSSI */
1026 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
1027 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
1028 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
1029 /* 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
1030 and rssi score are in the same order. This will be taken care later */
1031
1032 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
1033 {
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001034 NEIGHBOR_ROAM_DEBUG(pMac, LOGE,
1035 FL("Scan result: BSSID %02x:%02x:%02x:%02x:%02x:%02x (Rssi %d)"),
1036 pScanResult->BssDescriptor.bssId[0],
1037 pScanResult->BssDescriptor.bssId[1],
1038 pScanResult->BssDescriptor.bssId[2],
1039 pScanResult->BssDescriptor.bssId[3],
1040 pScanResult->BssDescriptor.bssId[4],
1041 pScanResult->BssDescriptor.bssId[5],
1042 abs(pScanResult->BssDescriptor.rssi));
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001044 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
1046 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001047 /* currently associated AP. Do not have this in the roamable AP list */
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 continue;
1049 }
1050
Jeff Johnson43971f52012-07-17 12:26:56 -07001051 /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature
1052 * is disabled and we continue to roam without any check*/
1053 if(RoamRssiDiff > 0)
1054 {
1055 if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi))
1056 {
1057 /*Do not roam to an AP with worse RSSI than the current*/
1058 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1059 "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d\n", __func__,
1060 CurrAPRssi,
1061 (int)pScanResult->BssDescriptor.rssi * (-1) );
1062 continue;
1063 } else {
1064 /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the
1065 * margin that is provided by user from the ini file (RoamRssiDiff)*/
1066 if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff)
1067 {
1068 continue;
1069 }
1070 else {
1071 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1072 "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d\n", __func__,
1073 CurrAPRssi,
1074 (int)pScanResult->BssDescriptor.rssi * (-1) );
1075 }
1076 }
1077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001078
1079#ifdef WLAN_FEATURE_VOWIFI_11R
1080 if (pNeighborRoamInfo->is11rAssoc)
1081 {
1082 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1083 {
1084 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1085 continue;
1086 }
1087 }
1088#endif /* WLAN_FEATURE_VOWIFI_11R */
1089
1090#ifdef FEATURE_WLAN_CCX
1091 if (pNeighborRoamInfo->isCCXAssoc)
1092 {
1093 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1094 {
1095 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1096 continue;
1097 }
1098 }
1099 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
1100 (pScanResult->BssDescriptor.QBSSLoad_avail))
1101 {
1102 if (pNeighborRoamInfo->isVOAdmitted)
1103 {
1104 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
1105 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
1106 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
1107 {
1108 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1109 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
1110 pScanResult->BssDescriptor.bssId[0],
1111 pScanResult->BssDescriptor.bssId[1],
1112 pScanResult->BssDescriptor.bssId[2],
1113 pScanResult->BssDescriptor.bssId[3],
1114 pScanResult->BssDescriptor.bssId[4],
1115 pScanResult->BssDescriptor.bssId[5]);
1116 continue;
1117 }
1118 }
1119 }
1120 else
1121 {
1122 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
1123 if (pNeighborRoamInfo->isVOAdmitted)
1124 {
1125 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1126 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
1127 pScanResult->BssDescriptor.bssId[0],
1128 pScanResult->BssDescriptor.bssId[1],
1129 pScanResult->BssDescriptor.bssId[2],
1130 pScanResult->BssDescriptor.bssId[3],
1131 pScanResult->BssDescriptor.bssId[4],
1132 pScanResult->BssDescriptor.bssId[5]);
1133 continue;
1134 }
1135 }
1136#endif /* FEATURE_WLAN_CCX */
1137
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001138#ifdef FEATURE_WLAN_LFR
1139 // If we are supporting legacy roaming, and
1140 // if the candidate is on the "pre-auth failed" list, ignore it.
1141 if (csrRoamIsFastRoamEnabled(pMac))
1142 {
1143 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1144 {
1145 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1146 continue;
1147 }
1148 }
1149#endif /* FEATURE_WLAN_LFR */
1150
Jeff Johnson295189b2012-06-20 16:38:30 -07001151 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
1152 * this result */
1153 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
1154 {
1155 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
1156 continue;
1157 }
1158
1159 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
1160 if (NULL == pBssInfo)
1161 {
1162 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
1163 continue;
1164 }
1165
1166 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1167 if (pBssInfo->pBssDescription != NULL)
1168 {
1169 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
1170 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1171 }
1172 else
1173 {
1174 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
1175 vos_mem_free(pBssInfo);
1176 continue;
1177
1178 }
1179 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
1180
1181 /* Just add to the end of the list as it is already sorted by RSSI */
1182 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
1183 }
1184
1185 /* 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 */
1186 csrScanResultPurge(pMac, *pScanResultList);
1187
1188 return;
1189}
1190
1191/* ---------------------------------------------------------------------------
1192
1193 \fn csrNeighborRoamHandleEmptyScanResult
1194
1195 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1196 there are no valid APs in the scan result for roaming. This means
1197 out AP is the best and no other AP is around. No point in scanning
1198 again and again. Performing the following here.
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001199 1. Remain in eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN.
1200 2. Stop the neighbor scan timer.
1201 3. Start neighbor scan results refresh timer.
1202 4. Update currentScanResultsRefreshPeriod for next iteration.
Jeff Johnson295189b2012-06-20 16:38:30 -07001203
1204 \param pMac - The handle returned by macOpen.
1205
1206 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1207
1208---------------------------------------------------------------------------*/
1209static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1210{
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1212 eHalStatus status = eHAL_STATUS_SUCCESS;
1213
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001214 /* Stop neighbor scan timer */
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001216 if (eHAL_STATUS_SUCCESS != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07001217 {
1218 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1219 }
1220
Jeff Johnson295189b2012-06-20 16:38:30 -07001221#ifdef WLAN_FEATURE_VOWIFI_11R
1222 /* Clear off the old neighbor report details */
1223 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1224#endif
1225
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001226 /* Start neighbor scan results refresh timer */
1227 if (eHAL_STATUS_SUCCESS !=
1228 palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1229 pNeighborRoamInfo->currentScanResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1230 eANI_BOOLEAN_FALSE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 {
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001232 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start (%d)"), status);
1233 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1234 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1235 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001236 }
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001237 smsLog(pMac, LOG1, FL("Neighbor results refresh timer started (%ld ms)"),
1238 (pNeighborRoamInfo->currentScanResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT));
1239
1240 /* Update currentScanResultsRefreshPeriod to be used for next iteration */
1241 if ( (2*pNeighborRoamInfo->currentScanResultsRefreshPeriod) >
1242 NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX )
1243 {
1244 pNeighborRoamInfo->currentScanResultsRefreshPeriod =
1245 NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX;
1246 } else {
1247 /* Double the refresh period every time we fail to find candidates */
1248 pNeighborRoamInfo->currentScanResultsRefreshPeriod *= 2;
1249 }
1250
1251 return VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07001252}
1253
1254/* ---------------------------------------------------------------------------
1255
1256 \fn csrNeighborRoamScanRequestCallback
1257
1258 \brief This function is the callback function registered in csrScanRequest() to
1259 indicate the completion of scan. If scan is completed for all the channels in
1260 the channel list, this function gets the scan result and starts the refresh results
1261 timer to avoid having stale results. If scan is not completed on all the channels,
1262 it restarts the neighbor scan timer which on expiry issues scan on the next
1263 channel
1264
1265 \param halHandle - The handle returned by macOpen.
1266 pContext - not used
1267 scanId - not used
1268 status - not used
1269
1270 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1271
1272---------------------------------------------------------------------------*/
1273static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1274 tANI_U32 scanId, eCsrScanStatus status)
1275{
1276 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1277 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1278 tANI_U8 currentChanIndex;
1279 tCsrScanResultFilter scanFilter;
1280 tScanResultHandle scanResult;
1281 tANI_U32 tempVal = 0;
Jeff Johnson43971f52012-07-17 12:26:56 -07001282 eHalStatus hstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001283
1284 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1285
1286 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1287 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1288 {
1289 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1290 return eHAL_STATUS_SUCCESS;
1291 }
1292
1293 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1294 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1295
1296 /* Validate inputs */
1297 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1298 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1299 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1300 }
1301 else
1302 {
1303 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1304 return eHAL_STATUS_SUCCESS;
1305 }
1306
1307 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1308 {
1309 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1310 just to get the results and perform PREAUTH */
1311 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1312 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1313 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1314 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1315
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001316#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1318 should use the BSSID filter made out of neighbor reports */
1319 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1320 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001321 hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1322 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 -07001323 tempVal = 1;
1324 }
1325 else
1326#endif
1327 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001328 hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1329 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 -07001330 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001331 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001332 {
1333 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1334 return eHAL_STATUS_FAILURE;
1335 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001336 hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult);
1337 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001338 /* Process the scan results and update roamable AP list */
1339 csrNeighborRoamProcessScanResults(pMac, &scanResult);
1340
1341 /* Free the scan filter */
1342 csrFreeScanFilter(pMac, &scanFilter);
1343
1344 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1345
1346 switch(pNeighborRoamInfo->neighborRoamState)
1347 {
1348 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1349 if (tempVal)
1350 {
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07001351 /*
1352 * Since there are non-zero candidates found
1353 * after the scan, reset the refresh period
1354 * to minimum.
1355 */
1356 pNeighborRoamInfo->currentScanResultsRefreshPeriod =
1357 NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07001358#ifdef WLAN_FEATURE_VOWIFI_11R
1359 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1360 APs in the roamable AP list */
1361 if (pNeighborRoamInfo->is11rAssoc)
1362 {
1363 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1364 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1365 }
1366 else
1367#endif
1368#ifdef FEATURE_WLAN_CCX
1369 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1370 APs in the roamable AP list */
1371 if (pNeighborRoamInfo->isCCXAssoc)
1372 {
1373 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1374 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1375 }
1376 else
1377#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001378#ifdef FEATURE_WLAN_LFR
1379 /* If LFR is enabled, then we can register the reassoc callback here as we have some
1380 APs in the roamable AP list */
1381 if (csrRoamIsFastRoamEnabled(pMac))
1382 {
1383 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1384 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1385 }
1386 else
1387#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 {
1389
1390 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1391 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1392 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1393 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1394 within certain duration */
1395
1396// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1397 }
1398 }
1399 else
1400 {
Madan Mohan Koyyalamudib40e5582012-10-11 16:48:42 -07001401 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1402 /* Handle it appropriately */
1403 csrNeighborRoamHandleEmptyScanResult(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 }
1405 break;
1406#ifdef WLAN_FEATURE_VOWIFI_11R
1407 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1408 if (!tempVal)
1409 {
1410 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1411 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1412 csrNeighborRoamTransitToCFGChanScan(pMac);
1413 }
1414 break;
1415#endif /* WLAN_FEATURE_VOWIFI_11R */
1416 default:
1417 // Can come only in INIT state. Where in we are associated, we sent scan and user
1418 // in the meantime decides to disassoc, we will be in init state and still received call
1419 // back issued. Should not come here in any other state, printing just in case
1420 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1421 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1422
1423 // Lets just exit out silently.
1424 return eHAL_STATUS_SUCCESS;
1425 }
1426
1427 if (tempVal)
1428 {
1429 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1430
1431 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1432 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1433 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1434 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1435 eANI_BOOLEAN_FALSE))
1436 {
1437 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1438 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1439 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001440 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001441 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001442
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1444 /* Register a reassoc Indication callback */
1445 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1446 WLANTL_HO_THRESHOLD_DOWN,
1447 csrNeighborRoamReassocIndCallback,
1448 VOS_MODULE_ID_SME, pMac);
1449
1450 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1451 {
1452 //err msg
1453 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1454 }
1455
1456 }
1457 }
1458 else
1459 {
1460
1461 /* Restart the timer for the next scan sequence as scanning is not over */
Jeff Johnson43971f52012-07-17 12:26:56 -07001462 hstatus = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1464 eANI_BOOLEAN_FALSE);
1465
Jeff Johnson43971f52012-07-17 12:26:56 -07001466 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001467 {
1468 /* Timer start failed.. Should we ASSERT here??? */
1469 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1470 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1471 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001472 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001473 }
1474 }
1475 return eHAL_STATUS_SUCCESS;
1476}
1477
1478/* ---------------------------------------------------------------------------
1479
1480 \fn csrNeighborRoamIssueBgScanRequest
1481
1482 \brief This function issues CSR scan request after populating all the BG scan params
1483 passed
1484
1485 \param pMac - The handle returned by macOpen.
1486 pBgScanParams - Params that need to be populated into csr Scan request
1487
1488 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1489
1490---------------------------------------------------------------------------*/
1491eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1492{
1493 eHalStatus status = eHAL_STATUS_SUCCESS;
1494 tANI_U32 scanId;
1495 tCsrScanRequest scanReq;
1496 tANI_U8 channel;
1497
1498 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
1499 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1500
1501
1502 //send down the scan req for 1 channel on the associated SSID
1503 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1504 /* Fill in the SSID Info */
1505 scanReq.SSIDs.numOfSSIDs = 1;
1506 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1507 if(NULL == scanReq.SSIDs.SSIDList)
1508 {
1509 //err msg
1510 smsLog(pMac, LOGW, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List\n"));
1511 return eHAL_STATUS_FAILURE;
1512 }
1513 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1514
1515 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1516 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1517 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1518
1519 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1520
1521 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1522 scanReq.ChannelInfo.ChannelList = &channel;
1523
1524 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1525 scanReq.scanType = eSIR_ACTIVE_SCAN;
1526 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1527 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1528 scanReq.minChnTime = pBgScanParams->minChnTime;
1529 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1530 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1531 if (eHAL_STATUS_SUCCESS != status)
1532 {
1533 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1534 vos_mem_free(scanReq.SSIDs.SSIDList);
1535 return status;
1536 }
1537 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1538
1539 vos_mem_free(scanReq.SSIDs.SSIDList);
1540 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x, Actual index = %d"),
1541 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1542 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1543 return status;
1544}
1545
1546/* ---------------------------------------------------------------------------
1547
1548 \fn csrNeighborRoamPerformBgScan
1549
1550 \brief This function is invoked on every expiry of neighborScanTimer till all
1551 the channels in the channel list are scanned. It populates necessary
1552 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1553 request
1554
1555 \param pMac - The handle returned by macOpen.
1556
1557 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1558
1559---------------------------------------------------------------------------*/
1560eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1561{
1562 eHalStatus status = eHAL_STATUS_SUCCESS;
1563 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1564 tCsrBGScanRequest bgScanParams;
1565 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1566 tANI_U8 channel = 0;
1567
1568 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1569 {
1570 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
1571 }
1572 else
1573 {
1574 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
1575 // Go back and restart. Mostly timer start failure has occured.
1576 // When timer start is declared a failure, then we delete the list.
1577 // Should not happen now as we stop and then only start the scan timer.
1578 // still handle the unlikely case.
1579 csrNeighborRoamHandleEmptyScanResult(pMac);
1580 return status;
1581 }
1582 /* Need to perform scan here before getting the list */
1583 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1584 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1585 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1586 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1587
1588 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1589 bgScanParams.ChannelInfo.numOfChannels = 1;
1590 bgScanParams.ChannelInfo.ChannelList = &channel;
1591
1592 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1593 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1594
1595 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1596 if (eHAL_STATUS_SUCCESS != status)
1597 {
1598 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1599 return status;
1600 }
1601
1602 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1603 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1604 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1605 {
1606 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
1607 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1608 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1609 /* We have completed scanning all the channels */
1610 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1611 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1612 and select the best AP in the list */
1613 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1614 {
1615 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1616 }
1617 }
1618
1619 return status;
1620}
1621
1622/* ---------------------------------------------------------------------------
1623
1624 \fn csrNeighborRoamNeighborScanTimerCallback
1625
1626 \brief This function is the neighbor scan timer callback function. It invokes
1627 the BG scan request based on the current and previous states
1628
1629 \param pv - CSR timer context info which includes pMac and session ID
1630
1631 \return VOID
1632
1633---------------------------------------------------------------------------*/
1634void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1635{
1636 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1637 tpAniSirGlobal pMac = pInfo->pMac;
1638 tANI_U32 sessionId = pInfo->sessionId;
1639 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1640
1641 // check if bg scan is on going, no need to send down the new params if true
1642 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1643 {
1644 //msg
1645 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1646 return;
1647 }
1648
1649 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1650
1651 switch (pNeighborRoamInfo->neighborRoamState)
1652 {
1653#ifdef WLAN_FEATURE_VOWIFI_11R
1654 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1655 switch(pNeighborRoamInfo->prevNeighborRoamState)
1656 {
1657 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1658 csrNeighborRoamPerformBgScan(pMac);
1659 break;
1660 default:
1661 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1662 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1663 break;
1664 }
1665 break;
1666#endif /* WLAN_FEATURE_VOWIFI_11R */
1667 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1668 csrNeighborRoamPerformBgScan(pMac);
1669 break;
1670 default:
1671 break;
1672 }
1673 return;
1674}
1675
1676/* ---------------------------------------------------------------------------
1677
1678 \fn csrNeighborRoamResultsRefreshTimerCallback
1679
1680 \brief This function is the timer callback function for results refresh timer.
1681 When this is invoked, it is as good as down event received from TL. So,
1682 clear off the roamable AP list and start the scan procedure based on 11R
1683 or non-11R association
1684
1685 \param context - CSR timer context info which includes pMac and session ID
1686
1687 \return VOID
1688
1689---------------------------------------------------------------------------*/
1690void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1691{
1692 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1693 tpAniSirGlobal pMac = pInfo->pMac;
1694 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1695 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1696
1697 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1698
1699 /* Deregister reassoc callback. Ignore return status */
1700 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1701 WLANTL_HO_THRESHOLD_DOWN,
1702 csrNeighborRoamReassocIndCallback,
1703 VOS_MODULE_ID_SME);
1704
1705 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1706 {
1707 //err msg
1708 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1709 }
1710
1711 /* Reset all the variables just as no scan had happened before */
1712 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1713
1714#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1715 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1716 {
1717 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1718 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1719 if (VOS_STATUS_SUCCESS != vosStatus)
1720 {
1721 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1722 return;
1723 }
1724 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1725 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1726 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1727 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1728 }
1729 else
1730#endif
1731 {
1732 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1733 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1734 if (VOS_STATUS_SUCCESS != vosStatus)
1735 {
1736 return;
1737 }
1738 }
1739 return;
1740}
1741
1742#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1743/* ---------------------------------------------------------------------------
1744
1745 \fn csrNeighborRoamIssueNeighborRptRequest
1746
1747 \brief This function is invoked when TL issues a down event and the current assoc
1748 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1749 the currently associated AP with the current SSID
1750
1751 \param pMac - The handle returned by macOpen.
1752
1753 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1754
1755---------------------------------------------------------------------------*/
1756VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1757{
1758 tRrmNeighborRspCallbackInfo callbackInfo;
1759 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1760 tRrmNeighborReq neighborReq;
1761
1762
1763 neighborReq.no_ssid = 0;
1764
1765 /* Fill in the SSID */
1766 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1767 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1768 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1769
1770 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
1771 callbackInfo.neighborRspCallbackContext = pMac;
1772 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
1773
1774 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
1775}
1776
1777/* ---------------------------------------------------------------------------
1778
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001779 \fn csrNeighborRoamMergeChannelLists
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001780
1781 \brief This function is used to merge two channel list.
1782 NB: If called with outputNumOfChannels == 0, this routines
1783 simply copies the input channel list to the output channel list.
1784
1785 \param pMac - The handle returned by macOpen.
1786 \param pInputChannelList - The addtional channels to merge in to the "merged" channels list.
1787 \param inputNumOfChannels - The number of additional channels.
1788 \param pOutputChannelList - The place to put the "merged" channel list.
1789 \param outputNumOfChannels - The original number of channels in the "merged" channels list.
1790 \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list.
1791
1792 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1793
1794---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001795VOS_STATUS csrNeighborRoamMergeChannelLists(
1796 tpAniSirGlobal pMac,
1797 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001798 int inputNumOfChannels,
1799 tANI_U8 *pOutputChannelList,
1800 int outputNumOfChannels,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001801 int *pMergedOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001802 )
1803{
1804 int i = 0;
1805 int j = 0;
1806 int numChannels = outputNumOfChannels;
1807
1808 // Check for NULL pointer
1809 if (!pInputChannelList) return eHAL_STATUS_E_NULL_VALUE;
1810
1811 // Check for NULL pointer
1812 if (!pOutputChannelList) return eHAL_STATUS_E_NULL_VALUE;
1813
1814 // Add the "new" channels in the input list to the end of the output list.
1815 for (i = 0; i < inputNumOfChannels; i++)
1816 {
1817 for (j = 0; j < outputNumOfChannels; j++)
1818 {
1819 if (pInputChannelList[i] == pOutputChannelList[j])
1820 break;
1821 }
1822 if (j == outputNumOfChannels)
1823 {
1824 if (pInputChannelList[i])
1825 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001826 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1827 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1828 pInputChannelList[i]);
1829 pOutputChannelList[numChannels] = pInputChannelList[i];
1830 numChannels++;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001831 }
1832 }
1833 }
1834
1835 // Return final number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001836 *pMergedOutputNumOfChannels = numChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001837
1838 return eHAL_STATUS_SUCCESS;
1839}
1840
1841/* ---------------------------------------------------------------------------
1842
Jeff Johnson295189b2012-06-20 16:38:30 -07001843 \fn csrNeighborRoamCreateChanListFromNeighborReport
1844
1845 \brief This function is invoked when neighbor report is received for the
1846 neighbor request. Based on the channels present in the neighbor report,
1847 it generates channel list which will be used in REPORT_SCAN state to
1848 scan for these neighbor APs
1849
1850 \param pMac - The handle returned by macOpen.
1851
1852 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1853
1854---------------------------------------------------------------------------*/
1855VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
1856{
1857 tpRrmNeighborReportDesc pNeighborBssDesc;
1858 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001859 tANI_U8 numChannels = 0, i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001860 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001861#if 0
1862 eHalStatus status = eHAL_STATUS_SUCCESS;
1863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001864
1865 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
1866 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
1867
1868 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
1869
1870 while (pNeighborBssDesc)
1871 {
1872 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
1873
1874 /* Update the neighbor BSS Info in the 11r FT Roam Info */
1875 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
1876 pNeighborBssDesc->pNeighborBssDescription->channel;
1877 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
1878 (tANI_U8)pNeighborBssDesc->roamScore;
1879 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
1880 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
1881 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
1882
1883 /* Saving the channel list non-redundantly */
1884 if (numChannels > 0)
1885 {
1886 for (i = 0; i < numChannels; i++)
1887 {
1888 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
1889 break;
1890 }
1891
1892 }
1893 if (i == numChannels)
1894 {
1895 if (pNeighborBssDesc->pNeighborBssDescription->channel)
1896 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1898 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1899 pNeighborBssDesc->pNeighborBssDescription->channel);
1900 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1901 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 }
1903 }
1904
1905 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
1906 }
1907
1908 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1909 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001910#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -07001911 // Before we free the existing channel list for a safety net make sure
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001912 // we have a union of the IAPP and the already existing list.
1913 status = csrNeighborRoamMergeChannelLists(
1914 pMac,
1915 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1916 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels,
1917 channelList,
1918 numChannels,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001919 &numChannels );
1920#endif
1921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1923 }
1924
1925 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1926 /* Store the obtained channel list to the Neighbor Control data structure */
1927 if (numChannels)
1928 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
1929 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1930 {
1931 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1932 return VOS_STATUS_E_RESOURCES;
1933 }
1934
1935 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1936 channelList, (numChannels) * sizeof(tANI_U8));
1937 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
1938 if (numChannels)
1939 {
1940 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
1941 pNeighborRoamInfo->neighborRoamState);
1942 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
1943 }
1944 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1945 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1946
1947 return VOS_STATUS_SUCCESS;
1948}
1949
1950/* ---------------------------------------------------------------------------
1951
1952 \fn csrNeighborRoamRRMNeighborReportResult
1953
1954 \brief This function is the neighbor report callback that will be invoked by
1955 SME RRM on receiving a neighbor report or of neighbor report is not
1956 received after timeout. On receiving a valid report, it generates a
1957 channel list from the neighbor report and starts the
1958 neighbor scan timer
1959
1960 \param context - The handle returned by macOpen.
1961 vosStatus - Status of the callback(SUCCESS/FAILURE)
1962
1963 \return VOID
1964
1965---------------------------------------------------------------------------*/
1966void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
1967{
1968 tpAniSirGlobal pMac = PMAC_STRUCT(context);
1969 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1970 eHalStatus status = eHAL_STATUS_SUCCESS;
1971
1972 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
1973 switch (pNeighborRoamInfo->neighborRoamState)
1974 {
1975 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1976 /* Reset the report pending variable */
1977 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
1978 if (VOS_STATUS_SUCCESS == vosStatus)
1979 {
1980 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
1981 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
1982 if (VOS_STATUS_SUCCESS == vosStatus)
1983 {
1984 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
1985 }
1986
1987 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1988 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1989
1990 /* Now ready for neighbor scan based on the channel list created */
1991 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1992 what palTimerStart expects */
1993 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1994 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1995 eANI_BOOLEAN_FALSE);
1996 if (eHAL_STATUS_SUCCESS != status)
1997 {
1998 /* Timer start failed.. Should we ASSERT here??? */
1999 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
2000 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2001 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2002 return;
2003 }
2004 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2005 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
2006 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
2007 }
2008 else
2009 {
2010 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
2011 reach the maxNeighborRetries or receiving a successful neighbor response */
2012 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
2013 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
2014 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
2015 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
2016 {
2017 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
2018 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2019 if (VOS_STATUS_SUCCESS != vosStatus)
2020 {
2021 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
2022 return;
2023 }
2024 /* We transitioned to different state now. Reset the Neighbor report retry count */
2025 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2026 }
2027 else
2028 {
2029 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2030 if (VOS_STATUS_SUCCESS != vosStatus)
2031 {
2032 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2033 return;
2034 }
2035 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2036 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2037 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2038 }
2039 }
2040 break;
2041 default:
2042 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
2043 break;
2044 }
2045 return;
2046}
2047#endif /* WLAN_FEATURE_VOWIFI_11R */
2048
2049
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002050#ifdef FEATURE_WLAN_LFR
2051tANI_BOOLEAN csrNeighborRoamIsSsidCandidateMatch(
2052 tpAniSirGlobal pMac,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002053 tDot11fBeaconIEs *pIes)
2054{
2055 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2056 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
2057 tCsrRoamConnectedProfile *pCurProfile;
2058 tANI_BOOLEAN fMatch = FALSE;
2059
2060 if( !(pMac->roam.roamSession
2061 && CSR_IS_SESSION_VALID(pMac, sessionId)))
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002062 return TRUE; // Treat missing information as a match for everything.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002063
2064 pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
2065
2066 if( !pCurProfile)
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002067 return TRUE; // Treat missing information as a match for everything.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002068
2069 if( pIes )
2070 {
2071 if(pIes->SSID.present)
2072 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002073 fMatch = csrIsSsidMatch( pMac, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length,
2074 pIes->SSID.ssid, pIes->SSID.num_ssid,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002075 eANI_BOOLEAN_TRUE ); // Treat a missing SSID as a non-match.
2076 // Return the result of the match operation
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002077 return fMatch;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002078 } else
2079 return FALSE; // Treat a missing SSID as a non-match.
2080 } else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002081 return FALSE; // Again, treat missing SSID information as a non-match.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002082}
2083
2084/* ---------------------------------------------------------------------------
2085
2086 \fn csrNeighborRoamReorderChannelList
2087
2088 \brief This function is used to reorder the channel list used for the background
2089 scan. It uses the information learned from previous scans to re-order the
2090 scan channel list to "favor" the "occupied channels". The actual algorithm
2091 is to scan the current set of "occupied channels" first, for every BG scan,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002092 followed by a "chunk" of the remaining list of "valid channels".
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002093
2094 \param pMac - The handle returned by macOpen.
2095 \param pInputChannelList - The default channels list.
2096 \param numOfChannels - The number of channels in the default channels list.
2097 \param pOutputChannelList - The place to put the "re-ordered" channel list.
2098 \param pOutputNumOfChannels - The number of channels in the "re-ordered" channel list.
2099
2100 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2101
2102---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002103VOS_STATUS csrNeighborRoamReorderChannelList(
2104 tpAniSirGlobal pMac,
2105 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002106 int numOfChannels,
2107 tANI_U8 *pOutputChannelList,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002108 int *pOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002109 )
2110{
2111 int i = 0;
2112 int j = 0;
2113 static int index = 0;
2114 int outputNumOfChannels = 0; // Clear the output number of channels
2115 tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels;
2116 tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList;
2117
2118
2119 // Copy over the "occupied channels" at the FRONT of pOutputChannelList.
2120 for (i = 0; i < numOccupiedChannels; i++)
2121 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002122 if (pOccupiedChannelList[i] != 0)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002123 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002124 pOutputChannelList[i] = pOccupiedChannelList[i];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002125 outputNumOfChannels++;
2126 }
2127 }
2128
2129 // Copy over one "chunk" of channels from the "rest of the channels"...append them to the END of pOutputChannelList.
2130 for (j = 0; j < CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE; j++)
2131 {
Madan Mohan Koyyalamudiaae6d472012-10-05 15:01:32 -07002132 if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, pInputChannelList[(j+index)%numOfChannels]))
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002133 {
Madan Mohan Koyyalamudiaae6d472012-10-05 15:01:32 -07002134 pOutputChannelList[i] = pInputChannelList[(j+index)%numOfChannels];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002135 i++;
2136 outputNumOfChannels++;
2137 }
2138 }
2139
2140 //Let's update the index...at which we start retrieving the next chunk
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002141 index = (index + CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE) % numOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002142
2143 //VOS_ASSERT(numOfChannels == i);
2144 smsLog(pMac, LOGE, FL("numOfChannels in the default channels list=%d. Number in the final list=%d."), numOfChannels, i);
2145
2146 // Return the number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002147 *pOutputNumOfChannels = outputNumOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002148
2149 return eHAL_STATUS_SUCCESS;
2150}
2151#endif /* FEATURE_WLAN_LFR */
2152
Jeff Johnson295189b2012-06-20 16:38:30 -07002153/* ---------------------------------------------------------------------------
2154
2155 \fn csrNeighborRoamTransitToCFGChanScan
2156
2157 \brief This function is called whenever there is a transition to CFG chan scan
2158 state from any state. It frees up the current channel list and allocates
2159 a new memory for the channels received from CFG item. It then starts the
2160 neighbor scan timer to perform the scan on each channel one by one
2161
2162 \param pMac - The handle returned by macOpen.
2163
2164 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2165
2166---------------------------------------------------------------------------*/
2167VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
2168{
2169 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2170 eHalStatus status = eHAL_STATUS_SUCCESS;
2171 int i = 0;
2172 int numOfChannels = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002173 tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
Jeff Johnson295189b2012-06-20 16:38:30 -07002174
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002175 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07002176#ifdef FEATURE_WLAN_CCX
2177 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002178 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
2180#endif // CCX
2181 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels == 0)
2182
2183 {
2184 smsLog(pMac, LOGW, FL("Falling back to CFG channel list"));
2185
2186
2187 /* Free up the channel list and allocate a new memory. This is because we dont know how much
2188 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
2189 result in memory corruption */
2190 if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2191 {
2192 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2193 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2194 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002195 VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
2196
2197 // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER
2198 // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR.
2199 if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002201 // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini".
2202 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini");
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002203 status = csrNeighborRoamMergeChannelLists(
2204 pMac,
2205 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2206 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels,
2207 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002208 0, //NB: If 0, simply copy the input channel list to the output list.
2209 &numOfChannels );
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002210 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002211 else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002212 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002213 /* Get current list of valid channels. */
2214 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Switching to master list of valid channels");
2215 numOfChannels = sizeof(pMac->roam.validChannelList);
2216 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, (tANI_U32 *) &numOfChannels)))
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002218 // Copy the "default valid channel list" (channelList) from the actual "valid channel list" information formed by CSR
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002219 status = csrNeighborRoamMergeChannelLists(
2220 pMac,
2221 (tANI_U8 *)pMac->roam.validChannelList,
2222 numOfChannels, // The number of channels in the validChannelList
2223 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002224 0, //NB: If 0, simply copy the input channel list to the output list.
2225 &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels
2226 }
2227 else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002228 {
2229 smsLog(pMac, LOGE, FL("Could not get valid channel list, TL event ignored"));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002230 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 }
2232 }
2233
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002234 /* At this point, channelList contains our best inputs on the "valid channel list" */
2235
2236 /* Allocate for the maximum number that might be used */
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002237 smsLog(pMac, LOGE, FL("%d channels in the default list. Add %d occupied channels. %d is the MAX scan channel list."),
2238 numOfChannels,
2239 CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002240 numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002242 VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 if (numOfChannels)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002244 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002245 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002246 vos_mem_malloc(numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
2247 }
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002248
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2250 {
2251 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
2252 return VOS_STATUS_E_RESOURCES;
2253 }
2254
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002255#ifdef FEATURE_WLAN_LFR
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 /* Since this is a legacy case, copy the channel list from CFG here */
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002257
2258 status = csrNeighborRoamReorderChannelList( pMac,
2259 channelList,
2260 numOfChannels,
2261 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002262 &numOfChannels );
2263 if (eHAL_STATUS_SUCCESS != status)
2264#endif
2265 {
2266 /* Re-ordering failed. */
2267 smsLog(pMac, LOGE, FL("Cannot re-order scan channel list. (status = %d) Going to use default scan channel list."), status);
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002268 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2269 channelList, numOfChannels * sizeof(tANI_U8));
2270 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002271
2272 /* Adjust for the actual number that are used */
2273 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
2275 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002276 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG (or scan caching) = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
2278 }
2279 }
2280
2281 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2282 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2283
2284 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2285 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2286 what palTimerStart expects */
2287 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2288 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2289 eANI_BOOLEAN_FALSE);
2290
2291 if (eHAL_STATUS_SUCCESS != status)
2292 {
2293 /* Timer start failed.. */
2294 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
2295 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2296 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2297 return VOS_STATUS_E_FAILURE;
2298 }
2299
2300 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2301 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -07002302 /* We are about to start a fresh scan cycle, purge results from the past */
2303 csrScanFlushResult(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002304
2305 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2306 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2307
2308 return VOS_STATUS_SUCCESS;
2309}
2310
2311/* ---------------------------------------------------------------------------
2312
2313 \fn csrNeighborRoamNeighborLookupUpEvent
2314
2315 \brief This function is called as soon as TL indicates that the current AP's
2316 RSSI is better than the neighbor lookup threshold. Here, we transition to
2317 CONNECTED state and reset all the scan parameters
2318
2319 \param pMac - The handle returned by macOpen.
2320
2321 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2322
2323---------------------------------------------------------------------------*/
2324VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2325{
2326 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2327 VOS_STATUS vosStatus;
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002328 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002329
Jeff Johnson295189b2012-06-20 16:38:30 -07002330 /* Recheck whether the below check is needed. */
2331 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2332 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
Jeff Johnsone7245742012-09-05 17:12:55 -07002333
2334 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2335 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2336
Jeff Johnson295189b2012-06-20 16:38:30 -07002337
2338 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2339 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2340 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2341 WLANTL_HO_THRESHOLD_DOWN,
2342 csrNeighborRoamNeighborLookupDOWNCallback,
2343 VOS_MODULE_ID_SME, pMac);
2344 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2345 {
2346 //err msg
2347 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2348 }
2349
2350
2351 return vosStatus;
2352}
2353
2354/* ---------------------------------------------------------------------------
2355
2356 \fn csrNeighborRoamNeighborLookupDownEvent
2357
2358 \brief This function is called as soon as TL indicates that the current AP's
2359 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2360 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2361 a non-11R association.
2362
2363 \param pMac - The handle returned by macOpen.
2364
2365 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2366
2367---------------------------------------------------------------------------*/
2368VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2369{
2370 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2371 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2372 eHalStatus status = eHAL_STATUS_SUCCESS;
2373
2374 switch (pNeighborRoamInfo->neighborRoamState)
2375 {
2376 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2377
2378 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2379 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2380 /* De-register Neighbor Lookup threshold callback with TL */
2381 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2382 WLANTL_HO_THRESHOLD_DOWN,
2383 csrNeighborRoamNeighborLookupDOWNCallback,
2384 VOS_MODULE_ID_SME);
2385
2386 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2387 {
2388 //err msg
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002389 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 }
2391
2392
2393#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2394 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2395 {
2396
2397 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2398 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2399 if (VOS_STATUS_SUCCESS != vosStatus)
2400 {
2401 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2402 return vosStatus;
2403 }
2404 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2405 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2406 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2407 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2408 }
2409 else
2410#endif
2411 {
2412 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2413
2414 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2415 if (VOS_STATUS_SUCCESS != vosStatus)
2416 {
2417 return vosStatus;
2418 }
2419 }
2420 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2421 /* Register Neighbor Lookup threshold callback with TL for UP event now */
2422 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2423 WLANTL_HO_THRESHOLD_UP,
2424 csrNeighborRoamNeighborLookupUPCallback,
2425 VOS_MODULE_ID_SME, pMac);
2426 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2427 {
2428 //err msg
2429 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
2430 }
2431 break;
2432 default:
2433 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2434 break;
2435
2436 }
2437 return vosStatus;
2438}
2439
2440/* ---------------------------------------------------------------------------
2441
2442 \fn csrNeighborRoamNeighborLookupUPCallback
2443
2444 \brief This function is registered with TL to indicate whenever the RSSI
2445 gets better than the neighborLookup RSSI Threshold
2446
2447 \param pAdapter - VOS Context
2448 trafficStatus - UP/DOWN indication from TL
2449 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2450
2451 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2452
2453---------------------------------------------------------------------------*/
2454VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2455 v_PVOID_t pUserCtxt)
2456{
2457 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2458 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2459 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2460
2461 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
2462
2463 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2464 {
2465 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2466 return VOS_STATUS_SUCCESS;
2467 }
2468
2469 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2470 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2471 return vosStatus;
2472}
2473
2474/* ---------------------------------------------------------------------------
2475
2476 \fn csrNeighborRoamNeighborLookupDOWNCallback
2477
2478 \brief This function is registered with TL to indicate whenever the RSSI
2479 falls below the current neighborLookup RSSI Threshold
2480
2481 \param pAdapter - VOS Context
2482 trafficStatus - UP/DOWN indication from TL
2483 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2484
2485 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2486
2487---------------------------------------------------------------------------*/
2488VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2489 v_PVOID_t pUserCtxt)
2490{
2491 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2492 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2493 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2494
2495 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
2496
2497 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2498 {
2499 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2500 return VOS_STATUS_SUCCESS;
2501 }
2502
2503 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2504 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2505
2506 return vosStatus;
2507}
2508
2509#ifdef RSSI_HACK
2510extern int dumpCmdRSSI;
2511#endif
2512
2513/* ---------------------------------------------------------------------------
2514
2515 \fn csrNeighborRoamIndicateDisconnect
2516
2517 \brief This function is called by CSR as soon as the station disconnects from
2518 the AP. This function does the necessary cleanup of neighbor roam data
2519 structures. Neighbor roam state transitions to INIT state whenever this
2520 function is called except if the current state is REASSOCIATING
2521
2522 \param pMac - The handle returned by macOpen.
2523 sessionId - CSR session id that got disconnected
2524
2525 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2526
2527---------------------------------------------------------------------------*/
2528eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2529{
2530 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2531
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002532 smsLog(pMac, LOGE, FL("Disconnect indication on session %d in state %d (sub-state %d)"),
2533 sessionId, pNeighborRoamInfo->neighborRoamState,
2534 pMac->roam.curSubState[sessionId]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002535
2536#ifdef FEATURE_WLAN_CCX
2537 {
2538 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2539 if (pSession->connectedProfile.isCCXAssoc)
2540 {
2541 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2542 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2543 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2544 pSession->isPrevApInfoValid = TRUE;
2545 pSession->roamTS1 = vos_timer_get_system_time();
2546
2547 }
2548 }
2549#endif
2550
2551#ifdef RSSI_HACK
2552 dumpCmdRSSI = -40;
2553#endif
2554 switch (pNeighborRoamInfo->neighborRoamState)
2555 {
2556 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2557 // Stop scan and neighbor refresh timers.
2558 // These are indeed not required when we are in reassociating
2559 // state.
2560 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2561 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Madan Mohan Koyyalamudi5ad3dff2012-10-21 11:32:02 -07002562 if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId )) {
2563 /*
2564 * Disconnect indication during Disassoc Handoff sub-state
2565 * is received when we are trying to disconnect with the old
2566 * AP during roam. BUT, if receive a disconnect indication
2567 * outside of Disassoc Handoff sub-state, then it means that
2568 * this is a genuine disconnect and we need to clean up.
2569 * Otherwise, we will be stuck in reassoc state which will
2570 * in-turn block scans (see csrIsScanAllowed).
2571 */
2572 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2573 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002574 break;
2575
2576 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 csrNeighborRoamResetInitStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002578 csrNeighborRoamDeregAllRssiIndication(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002579 break;
2580
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002581 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
2582 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT);
2583 csrNeighborRoamResetCfgListChanScanControlInfo(pMac);
2584 csrNeighborRoamDeregAllRssiIndication(pMac);
2585 break;
2586
2587 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
2588 /* Stop pre-auth to reassoc interval timer */
2589 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002590 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2591 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2592 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002593 csrNeighborRoamResetPreauthControlInfo(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002594 csrNeighborRoamResetReportScanStateControlInfo(pMac);
Madan Mohan Koyyalamudiedee8aa2012-10-15 15:36:40 -07002595 csrNeighborRoamDeregAllRssiIndication(pMac);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002596 break;
2597
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 default:
Madan Mohan Koyyalamudi5695b502012-09-24 14:21:12 -07002599 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2600 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002601 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002602 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 }
2604 return eHAL_STATUS_SUCCESS;
2605}
2606
2607/* ---------------------------------------------------------------------------
2608
2609 \fn csrNeighborRoamIndicateConnect
2610
2611 \brief This function is called by CSR as soon as the station connects to an AP.
2612 This initializes all the necessary data structures related to the
2613 associated AP and transitions the state to CONNECTED state
2614
2615 \param pMac - The handle returned by macOpen.
2616 sessionId - CSR session id that got connected
2617 vosStatus - connect status SUCCESS/FAILURE
2618
2619 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2620
2621---------------------------------------------------------------------------*/
2622eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2623{
2624 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2625 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002626 VOS_STATUS vstatus;
2627
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002628#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 int init_ft_flag = FALSE;
2630#endif
2631
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002632 smsLog(pMac, LOG2, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002633
2634 switch (pNeighborRoamInfo->neighborRoamState)
2635 {
2636 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2637 if (VOS_STATUS_SUCCESS != vosStatus)
2638 {
2639 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2640 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2641 break;
2642 }
2643 /* Fall through if the status is SUCCESS */
2644 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2645 /* Reset all the data structures here */
2646 csrNeighborRoamResetInitStateControlInfo(pMac);
2647
2648 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2649
2650 pNeighborRoamInfo->csrSessionId = sessionId;
2651 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2652 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2653 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2654 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2655 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
2656
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002657#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 /* Now we can clear the preauthDone that was saved as we are connected afresh */
2659 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2660#endif
2661
2662#ifdef WLAN_FEATURE_VOWIFI_11R
2663 // Based on the auth scheme tell if we are 11r
2664 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType ) )
2665 {
2666 if (pMac->roam.configParam.isFastTransitionEnabled)
2667 init_ft_flag = TRUE;
2668 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
2669 }
2670 else
2671 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002672 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
Jeff Johnson295189b2012-06-20 16:38:30 -07002673#endif
2674
2675#ifdef FEATURE_WLAN_CCX
2676 // Based on the auth scheme tell if we are 11r
2677 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
2678 {
2679 if (pMac->roam.configParam.isFastTransitionEnabled)
2680 init_ft_flag = TRUE;
2681 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
2682 }
2683 else
2684 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002685 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isCCXAssoc is = %d ft = %d"),
2686 pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002687
2688#endif
2689
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002690#ifdef FEATURE_WLAN_LFR
2691 // If "Legacy Fast Roaming" is enabled
2692 if (csrRoamIsFastRoamEnabled(pMac))
2693 {
2694 init_ft_flag = TRUE;
2695 }
2696#endif
2697
2698#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 if ( init_ft_flag == TRUE )
2700 {
2701 /* Initialize all the data structures needed for the 11r FT Preauth */
2702 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
2703 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
2704 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2705 csrNeighborRoamPurgePreauthFailedList(pMac);
2706
2707 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
2708 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07002709 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002710 WLANTL_HO_THRESHOLD_DOWN,
2711 csrNeighborRoamNeighborLookupDOWNCallback,
2712 VOS_MODULE_ID_SME, pMac);
2713
Jeff Johnson43971f52012-07-17 12:26:56 -07002714 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002715 {
2716 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07002717 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
2718 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002719 }
2720 }
2721#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002722 break;
2723 default:
2724 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2725 break;
2726 }
2727 return status;
2728}
2729
2730
2731#ifdef WLAN_FEATURE_VOWIFI_11R
2732/* ---------------------------------------------------------------------------
2733
2734 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
2735
2736 \brief If this function is invoked, that means the preauthentication response
2737 is timed out from the PE. Preauth rsp handler is called with status as
2738 TIMEOUT
2739
2740 \param context - CSR Timer info which holds pMac and session ID
2741
2742 \return VOID
2743
2744---------------------------------------------------------------------------*/
2745void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
2746{
2747 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
2748 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
2749 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2750
2751 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
2752
2753 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
2754}
2755
2756/* ---------------------------------------------------------------------------
2757
2758 \fn csrNeighborRoamPurgePreauthFailedList
2759
2760 \brief This function purges all the MAC addresses in the pre-auth fail list
2761
2762 \param pMac - The handle returned by macOpen.
2763
2764 \return VOID
2765
2766---------------------------------------------------------------------------*/
2767void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
2768{
2769 tANI_U8 i;
2770
2771 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
2772 {
2773 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
2774 }
2775 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
2776
2777 return;
2778}
2779
2780/* ---------------------------------------------------------------------------
2781
2782 \fn csrNeighborRoamInit11rAssocInfo
2783
2784 \brief This function initializes 11r related neighbor roam data structures
2785
2786 \param pMac - The handle returned by macOpen.
2787
2788 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2789
2790---------------------------------------------------------------------------*/
2791eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
2792{
2793 eHalStatus status;
2794 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
2795
2796 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
2797 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
2798 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
2799 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
2800 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
2801 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
2802
2803 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
2804 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2805 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
2806 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
2807
2808 if (eHAL_STATUS_SUCCESS != status)
2809 {
2810 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2811 return eHAL_STATUS_RESOURCES;
2812 }
2813
2814 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2815 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2816 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2817 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2818
2819
2820 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
2821 if (eHAL_STATUS_SUCCESS != status)
2822 {
2823 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
2824 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
2825 return eHAL_STATUS_RESOURCES;
2826 }
2827 return status;
2828}
2829#endif /* WLAN_FEATURE_VOWIFI_11R */
2830
2831/* ---------------------------------------------------------------------------
2832
2833 \fn csrNeighborRoamInit
2834
2835 \brief This function initializes neighbor roam data structures
2836
2837 \param pMac - The handle returned by macOpen.
2838
2839 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2840
2841---------------------------------------------------------------------------*/
2842eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
2843{
2844 eHalStatus status;
2845 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2846
2847 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2848 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2849 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
2850 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
2851 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
2852 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
2853 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
2854 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
2855 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
2856 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
2857
2858 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
2859 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
2860
2861 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
2862 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2863
2864 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2865 {
2866 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
2867 return eHAL_STATUS_RESOURCES;
2868 }
2869
2870 /* Update the roam global structure from CFG */
2871 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2872 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
2873 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2874
2875 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
2876 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
Madan Mohan Koyyalamudi04039a12012-10-21 12:24:56 -07002877 pNeighborRoamInfo->currentScanResultsRefreshPeriod =
2878 NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07002879 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
2880
2881 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2882 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2883 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
2884 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2885
2886 if (eHAL_STATUS_SUCCESS != status)
2887 {
2888 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2889 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2890 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2891 return eHAL_STATUS_RESOURCES;
2892 }
2893
2894 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
2895 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2896
2897 if (eHAL_STATUS_SUCCESS != status)
2898 {
2899 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2900 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2901 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2902 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2903 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2904 return eHAL_STATUS_RESOURCES;
2905 }
2906
2907 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
2908 if (eHAL_STATUS_SUCCESS != status)
2909 {
2910 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2911 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2912 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2913 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2914 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2915 return eHAL_STATUS_RESOURCES;
2916 }
2917
2918 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2919 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2920 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2921 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2922 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2923
2924#ifdef WLAN_FEATURE_VOWIFI_11R
2925 status = csrNeighborRoamInit11rAssocInfo(pMac);
2926 if (eHAL_STATUS_SUCCESS != status)
2927 {
2928 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2929 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2930 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2931 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2932 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2933 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2934 return eHAL_STATUS_RESOURCES;
2935 }
2936#endif
2937 /* Initialize this with the current tick count */
2938 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2939
2940 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2941
2942 return eHAL_STATUS_SUCCESS;
2943}
2944
2945/* ---------------------------------------------------------------------------
2946
2947 \fn csrNeighborRoamClose
2948
2949 \brief This function closes/frees all the neighbor roam data structures
2950
2951 \param pMac - The handle returned by macOpen.
2952
2953 \return VOID
2954
2955---------------------------------------------------------------------------*/
2956void csrNeighborRoamClose(tpAniSirGlobal pMac)
2957{
2958 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2959
2960 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
2961 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07002962 smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002963 return;
2964 }
2965
2966 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2967 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2968
2969 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2970
2971 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
2972 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2973 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2974 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2975
2976 /* Should free up the nodes in the list before closing the double Linked list */
2977 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
2978 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2979
2980 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2981 {
2982 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2983 }
2984
2985 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2986 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2987 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2988 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2989 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2990 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2991
2992 /* Free the profile.. */
2993 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2994
2995#ifdef WLAN_FEATURE_VOWIFI_11R
2996 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2997 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
2998 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
2999 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
3000 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
3001 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
3002 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
3003 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3004 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
3005#endif /* WLAN_FEATURE_VOWIFI_11R */
3006
3007 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
3008
3009 return;
3010}
3011
3012/* ---------------------------------------------------------------------------
3013
3014 \fn csrNeighborRoamRequestHandoff
3015
3016 \brief This function triggers actual switching from one AP to the new AP.
3017 It issues disassociate with reason code as Handoff and CSR as a part of
3018 handling disassoc rsp, issues reassociate to the new AP
3019
3020 \param pMac - The handle returned by macOpen.
3021
3022 \return VOID
3023
3024---------------------------------------------------------------------------*/
3025void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
3026{
3027
3028 tCsrRoamInfo roamInfo;
3029 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3030 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
3031 tCsrNeighborRoamBSSInfo handoffNode;
3032 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
3033 tANI_U32 roamId = 0;
3034
3035 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
3036 {
3037 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
3038 pMac->roam.neighborRoamInfo.neighborRoamState);
3039 return;
3040 }
3041
3042 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3043 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
3044 eSIR_SME_SUCCESS);
3045
3046 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
3047 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
3048
3049 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
3050 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
3051 handoffNode.pBssDescription->bssId[0],
3052 handoffNode.pBssDescription->bssId[1],
3053 handoffNode.pBssDescription->bssId[2],
3054 handoffNode.pBssDescription->bssId[3],
3055 handoffNode.pBssDescription->bssId[4],
3056 handoffNode.pBssDescription->bssId[5]);
3057
3058 /* Free the profile.. Just to make sure we dont leak memory here */
3059 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
3060 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
3061 This should happen before issuing disconnect */
3062 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
3063 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
3064 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
3065
3066 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
3067
3068 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
3069 {
3070 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
3071 return;
3072 }
3073
3074 //notify HDD for handoff, providing the BSSID too
3075 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
3076
3077 vos_mem_copy(roamInfo.bssid,
3078 handoffNode.pBssDescription->bssId,
3079 sizeof( tCsrBssid ));
3080
3081 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
3082
3083
3084 return;
3085}
3086
3087/* ---------------------------------------------------------------------------
3088
3089 \fn csrNeighborRoamIsHandoffInProgress
3090
3091 \brief This function returns whether handoff is in progress or not based on
3092 the current neighbor roam state
3093
3094 \param pMac - The handle returned by macOpen.
3095 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
3096
3097 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
3098
3099---------------------------------------------------------------------------*/
3100tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
3101{
3102 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
3103 return eANI_BOOLEAN_TRUE;
3104
3105 return eANI_BOOLEAN_FALSE;
3106}
3107
3108#ifdef WLAN_FEATURE_VOWIFI_11R
3109/* ---------------------------------------------------------------------------
3110
3111 \fn csrNeighborRoamIs11rAssoc
3112
3113 \brief This function returns whether the current association is a 11r assoc or not
3114
3115 \param pMac - The handle returned by macOpen.
3116
3117 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
3118
3119---------------------------------------------------------------------------*/
3120tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
3121{
3122 return pMac->roam.neighborRoamInfo.is11rAssoc;
3123}
3124#endif /* WLAN_FEATURE_VOWIFI_11R */
3125
3126
3127/* ---------------------------------------------------------------------------
3128
3129 \fn csrNeighborRoamGetHandoffAPInfo
3130
3131 \brief This function returns the best possible AP for handoff. For 11R case, it
3132 returns the 1st entry from pre-auth done list. For non-11r case, it returns
3133 the 1st entry from roamable AP list
3134
3135 \param pMac - The handle returned by macOpen.
3136 pHandoffNode - AP node that is the handoff candidate returned
3137
3138 \return VOID
3139
3140---------------------------------------------------------------------------*/
3141void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
3142{
3143 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3144 tpCsrNeighborRoamBSSInfo pBssNode;
3145
3146 VOS_ASSERT(NULL != pHandoffNode);
3147
3148#ifdef WLAN_FEATURE_VOWIFI_11R
3149 if (pNeighborRoamInfo->is11rAssoc)
3150 {
3151 /* Always the BSS info in the head is the handoff candidate */
3152 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3153 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3154 }
3155 else
3156#endif
3157#ifdef FEATURE_WLAN_CCX
3158 if (pNeighborRoamInfo->isCCXAssoc)
3159 {
3160 /* Always the BSS info in the head is the handoff candidate */
3161 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3162 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3163 }
3164 else
3165#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003166#ifdef FEATURE_WLAN_LFR
3167 if (csrRoamIsFastRoamEnabled(pMac))
3168 {
3169 /* Always the BSS info in the head is the handoff candidate */
3170 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3171 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3172 }
3173 else
3174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 {
3176 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
3177 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
3178 }
3179 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
3180
3181 return;
3182}
3183
3184/* ---------------------------------------------------------------------------
3185 \brief This function returns TRUE if preauth is completed
3186
3187 \param pMac - The handle returned by macOpen.
3188
3189 \return boolean
3190
3191---------------------------------------------------------------------------*/
3192tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
3193{
3194 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
3195 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
3196}
3197
3198/* ---------------------------------------------------------------------------
3199 \brief In the event that we are associated with AP1 and we have
3200 completed pre auth with AP2. Then we receive a deauth/disassoc from
3201 AP1.
3202 At this point neighbor roam is in pre auth done state, pre auth timer
3203 is running. We now handle this case by stopping timer and clearing
3204 the pre-auth state. We basically clear up and just go to disconnected
3205 state.
3206
3207 \param pMac - The handle returned by macOpen.
3208
3209 \return boolean
3210---------------------------------------------------------------------------*/
3211void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
3212{
3213 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
3214 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
3215
3216 // Stop timer
3217 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
3218
3219 // Transition to init state
3220 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3221}
3222
3223#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */