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