blob: f49bd29d4e81a95cb459185d4088e32830aa96ed [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 */
262 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
263 WLANTL_HO_THRESHOLD_DOWN,
264 csrNeighborRoamNeighborLookupUPCallback,
265 VOS_MODULE_ID_SME);
266
267 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
268 {
269 //err msg
270 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
271 }
272
273 /* We dont need to run this timer any more. */
274 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
275
276#ifdef WLAN_FEATURE_VOWIFI_11R
277 if (pNeighborRoamInfo->is11rAssoc)
278 {
279 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
280 {
281 csrNeighborRoamIssuePreauthReq(pMac);
282 }
283 else
284 {
285 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
286 VOS_ASSERT(0);
287 }
288 }
289 else
290#endif
291
292#ifdef FEATURE_WLAN_CCX
293 if (pNeighborRoamInfo->isCCXAssoc)
294 {
295 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
296 {
297 csrNeighborRoamIssuePreauthReq(pMac);
298 }
299 else
300 {
301 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
302 VOS_ASSERT(0);
303 }
304 }
305 else
306#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700307#ifdef FEATURE_WLAN_LFR
308 if (csrRoamIsFastRoamEnabled(pMac))
309 {
310 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
311 {
312 csrNeighborRoamIssuePreauthReq(pMac);
313 }
314 else
315 {
316 smsLog(pMac, LOGE, FL("LFR Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
317 VOS_ASSERT(0);
318 }
319 }
320 else
321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 {
323 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
324 {
325 csrNeighborRoamRequestHandoff(pMac);
326 }
327 else
328 {
329 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
330 VOS_ASSERT(0);
331 }
332 }
333 return VOS_STATUS_SUCCESS;
334}
335
336/* ---------------------------------------------------------------------------
337
338 \fn csrNeighborRoamResetConnectedStateControlInfo
339
340 \brief This function will reset the neighbor roam control info data structures.
341 This function should be invoked whenever we move to CONNECTED state from
342 any state other than INIT state
343
344 \param pMac - The handle returned by macOpen.
345
346 \return VOID
347
348---------------------------------------------------------------------------*/
349void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
350{
351 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
352
353 /* Do not reset the currentNeighborLookup Threshold here. The threshold and multiplier will be set before calling this API */
354 if ((pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == FALSE) &&
355 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels))
356 {
357 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
358 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
359
360 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
361 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
362
363 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
364 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
365 }
366 else
367 {
368 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
369 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
370 }
371
372 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
373
374 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
375
376 /* Abort any ongoing BG scans */
377 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
Jeff Johnsone7245742012-09-05 17:12:55 -0700378 {
379 if( pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
380 {
381 smsLog(pMac, LOGE, FL("Connected during scan state and we didn't"
382 "transition to state"));
383 VOS_ASSERT(0);
384 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 csrScanAbortMacScan(pMac);
Jeff Johnsone7245742012-09-05 17:12:55 -0700386 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700387
388 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
389
390 /* We dont need to run this timer any more. */
391 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
392
393#ifdef WLAN_FEATURE_VOWIFI_11R
394 /* Do not free up the preauth done list here */
395 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
396 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
397 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
398 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
399 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
400 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
401 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
402#endif
403
404}
405
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700406void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac)
Jeff Johnson295189b2012-06-20 16:38:30 -0700407{
408 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
409 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
410
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
412 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
413 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
414 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700415#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700416 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
417 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
418 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
419 csrNeighborRoamPurgePreauthFailedList(pMac);
420#endif
421#ifdef FEATURE_WLAN_CCX
422 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
423 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
424 pNeighborRoamInfo->MinQBssLoadRequired = 0;
425#endif
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -0700426
427 /* Stop scan refresh timer */
428 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -0700429
430 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
431 /* Deregister reassoc callback. Ignore return status */
432 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
433 WLANTL_HO_THRESHOLD_DOWN,
434 csrNeighborRoamReassocIndCallback,
435 VOS_MODULE_ID_SME);
436
437 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
438 {
439 //err msg
440 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
441 }
442
443 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighborLookup callback with TL. RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
444 /* Deregister neighbor lookup callback. Ignore return status */
445 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
446 WLANTL_HO_THRESHOLD_DOWN,
447 csrNeighborRoamNeighborLookupDOWNCallback,
448 VOS_MODULE_ID_SME);
449
450 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
451 {
452 //err msg
453 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vosStatus);
454 }
455
456 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
457 /* Deregister reassoc callback. Ignore return status */
458 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
459 WLANTL_HO_THRESHOLD_UP,
460 csrNeighborRoamNeighborLookupUPCallback,
461 VOS_MODULE_ID_SME);
462
463 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
464 {
465 //err msg
466 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
467 }
468
469 /* Reset currentNeighborLookupThreshold only after deregistering DOWN event from TL */
470 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
471 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
472
473 return;
474}
475
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700476/* ---------------------------------------------------------------------------
477
478 \fn csrNeighborRoamResetInitStateControlInfo
479
480 \brief This function will reset the neighbor roam control info data structures.
481 This function should be invoked whenever we move to CONNECTED state from
482 INIT state
483
484 \param pMac - The handle returned by macOpen.
485
486 \return VOID
487
488---------------------------------------------------------------------------*/
489void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
490{
491 csrNeighborRoamResetConnectedStateControlInfo(pMac);
492
493 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
494 csrNeighborRoamResetReportScanStateControlInfo(pMac);
495}
496
497
498
Jeff Johnson295189b2012-06-20 16:38:30 -0700499#ifdef WLAN_FEATURE_VOWIFI_11R
500/* ---------------------------------------------------------------------------
501
502 \fn csrNeighborRoamBssIdScanFilter
503
504 \brief This API is used to prepare a filter to obtain scan results when
505 we complete the scan in the REPORT_SCAN state after receiving a
506 valid neighbor report from AP. This filter includes BSSIDs received from
507 the neighbor report from the AP in addition to the other filter parameters
508 created from connected profile
509
510 \param pMac - The handle returned by macOpen.
511 pScanFilter - Scan filter to be filled and returned
512
513 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
514 code otherwise
515
516---------------------------------------------------------------------------*/
517static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
518{
519 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
520 tANI_U8 i = 0;
521
522 VOS_ASSERT(pScanFilter != NULL);
523 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
524
525 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
526 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
527 if (NULL == pScanFilter->BSSIDs.bssid)
528 {
529 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
530 return eHAL_STATUS_FAILED_ALLOC;
531 }
532
533 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
534
535 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
536 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
537 {
538 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
539 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
540 }
541
542 /* Fill other general scan filter params */
543 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
544}
545
546/* ---------------------------------------------------------------------------
547
548 \fn csrNeighborRoamPurgePreauthFailList
549
550 \brief This function empties the preauth fail list
551
552 \param pMac - The handle returned by macOpen.
553
554 \return VOID
555
556---------------------------------------------------------------------------*/
557void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
558{
559 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
560
561 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
562 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
563 {
564 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
565 sizeof(tSirMacAddr));
566 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
567 }
568 return;
569}
570
571/* ---------------------------------------------------------------------------
572
573 \fn csrNeighborRoamAddBssIdToPreauthFailList
574
575 \brief This function adds the given BSSID to the Preauth fail list
576
577 \param pMac - The handle returned by macOpen.
578 bssId - BSSID to be added to the preauth fail list
579
580 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
581
582---------------------------------------------------------------------------*/
583eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
584{
585 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
586
587 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
588 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
589
590
591 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
592 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
593 {
594 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
595 return eHAL_STATUS_FAILURE;
596 }
597 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
598 bssId, sizeof(tSirMacAddr));
599 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
600
601 return eHAL_STATUS_SUCCESS;
602}
603
604/* ---------------------------------------------------------------------------
605
606 \fn csrNeighborRoamIsPreauthCandidate
607
608 \brief This function checks whether the given MAC address is already
609 present in the preauth fail list and returns TRUE/FALSE accordingly
610
611 \param pMac - The handle returned by macOpen.
612
613 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
614
615---------------------------------------------------------------------------*/
616tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
617{
618 tANI_U8 i = 0;
619 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
620
621 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
622 return eANI_BOOLEAN_TRUE;
623
624 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
625 {
626 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
627 bssId, sizeof(tSirMacAddr)))
628 {
629 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
630 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
631 return eANI_BOOLEAN_FALSE;
632 }
633 }
634
635 return eANI_BOOLEAN_TRUE;
636}
637
638/* ---------------------------------------------------------------------------
639
640 \fn csrNeighborRoamIssuePreauthReq
641
642 \brief This function issues preauth request to PE with the 1st AP entry in the
643 roamable AP list
644
645 \param pMac - The handle returned by macOpen.
646
647 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
648
649---------------------------------------------------------------------------*/
650static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
651{
652 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
653 eHalStatus status = eHAL_STATUS_SUCCESS;
654 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
655
656 /* This must not be true here */
657 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
658
659 /* Issue Preauth request to PE here */
660 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
661 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
662 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
663 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
664
665 if (NULL == pNeighborBssNode)
666 {
667 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
668 return eHAL_STATUS_FAILURE;
669 }
670 else
671 {
672 status = csrRoamIssueFTPreauthReq(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription);
673 if (eHAL_STATUS_SUCCESS != status)
674 {
675 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
676 return status;
677 }
678 }
679
680 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
681
682 /* Increment the preauth retry count */
683 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
684
685 /* Transition the state to preauthenticating */
686 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
687
688 /* Start the preauth rsp timer */
689 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
690 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
691 eANI_BOOLEAN_FALSE);
692 if (eHAL_STATUS_SUCCESS != status)
693 {
694 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
695 return status;
696 }
697
698
699 return status;
700}
701
702/* ---------------------------------------------------------------------------
703
704 \fn csrNeighborRoamPreauthRspHandler
705
706 \brief This function handle the Preauth response from PE
707 Every preauth is allowed max 3 tries if it fails. If a bssid failed
708 for more than MAX_TRIES, we will remove it from the list and try
709 with the next node in the roamable AP list and add the BSSID to pre-auth failed
710 list. If no more entries present in
711 roamable AP list, transition to REPORT_SCAN state
712
713 \param pMac - The handle returned by macOpen.
714 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
715
716 \return VOID
717
718---------------------------------------------------------------------------*/
719void csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
720{
721 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
722 eHalStatus status = eHAL_STATUS_SUCCESS;
723 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
724
725 // We can receive it in these 2 states.
726 VOS_ASSERT((pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) ||
727 (pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN));
728
729 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
730 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
731 {
732 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %\n"),
733 pNeighborRoamInfo->neighborRoamState);
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -0700734 return;
Jeff Johnson295189b2012-06-20 16:38:30 -0700735 }
736
737 if (VOS_STATUS_E_TIMEOUT != vosStatus)
738 {
739 /* This means we got the response from PE. Hence stop the timer */
740 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
741 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
742 }
743
744 if (VOS_STATUS_SUCCESS == vosStatus)
745 {
746 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
747 }
748 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
749 {
750 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
751
752 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
753 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
754 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
755
756 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
757 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
758 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
759
760 /* The caller of this function would start a timer and by the time it expires, supplicant should
761 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
762 }
763 else
764 {
765 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
766 tListElem *pEntry;
767
768 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
769
770 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
771 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
772 {
773 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
774 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
775
776 /* The one in the head of the list should be one with which we issued pre-auth and failed */
777 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
778 if(pEntry)
779 {
780 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
781 /* Add the BSSID to pre-auth fail list */
782 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
783 /* Now we can free this node */
784 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
785 }
786 }
787
788 /* Issue preauth request for the same/next entry */
789 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
790 return;
791
792 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
793
794 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
795 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
796 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
797 eANI_BOOLEAN_FALSE);
798 if (eHAL_STATUS_SUCCESS != status)
799 {
800 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
801 return;
802 }
803 }
804}
805#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
806
807/* ---------------------------------------------------------------------------
808
809 \fn csrNeighborRoamPrepareScanProfileFilter
810
811 \brief This function creates a scan filter based on the currently connected profile.
812 Based on this filter, scan results are obtained
813
814 \param pMac - The handle returned by macOpen.
815 pScanFilter - Populated scan filter based on the connected profile
816
817 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
818
819---------------------------------------------------------------------------*/
820eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
821{
822 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
823 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
824 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
825 tANI_U8 i = 0;
826
827 VOS_ASSERT(pScanFilter != NULL);
828
829 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
830
831 /* We dont want to set BSSID based Filter */
832 pScanFilter->BSSIDs.numOfBSSIDs = 0;
833
834 /* Populate all the information from the connected profile */
835 pScanFilter->SSIDs.numOfSSIDs = 1;
836 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
837 if (NULL == pScanFilter->SSIDs.SSIDList)
838 {
839 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
840 return eHAL_STATUS_FAILED_ALLOC;
841 }
842 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
843 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
844 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
845 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
846
847 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
848 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
849 pScanFilter->authType.numEntries = 1;
850 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
851
852 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
853 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
854
855 pScanFilter->mcEncryptionType.numEntries = 1;
856 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
857
858 pScanFilter->BSSType = pCurProfile->BSSType;
859
860 /* We are intrested only in the scan results on channels that we scanned */
861 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
862 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
863 if (NULL == pScanFilter->ChannelInfo.ChannelList)
864 {
865 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
866 vos_mem_free(pScanFilter->SSIDs.SSIDList);
867 pScanFilter->SSIDs.SSIDList = NULL;
868 return eHAL_STATUS_FAILED_ALLOC;
869 }
870 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
871 {
872 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
873 }
874
875#ifdef WLAN_FEATURE_VOWIFI_11R
876 if (pNeighborRoamInfo->is11rAssoc)
877 {
878 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
879 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
880 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
881 }
882#endif
883
884 return eHAL_STATUS_SUCCESS;
885}
886
Jeff Johnson43971f52012-07-17 12:26:56 -0700887tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
888{
889 tCsrScanResultInfo *pScanResult;
890 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
891 tANI_U32 CurrAPRssi = -125; /* We are setting this as default value to make sure we return this value,
892 when we do not see this AP in the scan result for some reason.However,it is
893 less likely that we are associated to an AP and do not see it in the scan list*/
894
895 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
896 {
897
898 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
899 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
900 {
901 /* We got a match with the currently associated AP.
902 * Capture the RSSI value and complete the while loop.
903 * The while loop is completed in order to make the current entry go back to NULL,
904 * and in the next while loop, it properly starts searching from the head of the list.
905 * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/
906
907 CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ;
908
909 } else {
910 continue;
911 }
912 }
913
914 return CurrAPRssi;
915
916}
917
Jeff Johnson295189b2012-06-20 16:38:30 -0700918/* ---------------------------------------------------------------------------
919
920 \fn csrNeighborRoamProcessScanResults
921
922 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
923 Assumed that the results are already sorted by RSSI by csrScanGetResult
924
925 \param pMac - The handle returned by macOpen.
926 pScanResultList - Scan result result obtained from csrScanGetResult()
927
928 \return VOID
929
930---------------------------------------------------------------------------*/
931
932static void csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
933{
934 tCsrScanResultInfo *pScanResult;
935 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
936 tpCsrNeighborRoamBSSInfo pBssInfo;
Jeff Johnson43971f52012-07-17 12:26:56 -0700937 tANI_U32 CurrAPRssi;
938 tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff;
939
940 /***************************************************************
941 * Find out the Current AP RSSI and keep it handy to check if
942 * it is better than the RSSI of the AP which we are
943 * going to roam.If so, we are going to continue with the
944 * current AP.
945 ***************************************************************/
946 CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList);
Jeff Johnson295189b2012-06-20 16:38:30 -0700947
948 /* Expecting the scan result already to be in the sorted order based on the RSSI */
949 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
950 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
951 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
952 /* 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
953 and rssi score are in the same order. This will be taken care later */
954
955 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
956 {
957 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Scan result: BSSID : %02x:%02x:%02x:%02x:%02x:%02x"),
958 pScanResult->BssDescriptor.bssId[0],
959 pScanResult->BssDescriptor.bssId[1],
960 pScanResult->BssDescriptor.bssId[2],
961 pScanResult->BssDescriptor.bssId[3],
962 pScanResult->BssDescriptor.bssId[4],
963 pScanResult->BssDescriptor.bssId[5]);
964
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700965 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
967 {
Jeff Johnson43971f52012-07-17 12:26:56 -0700968 /* currently associated AP. Do not have this in the roamable AP list */
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 continue;
970 }
971
Jeff Johnson43971f52012-07-17 12:26:56 -0700972 /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature
973 * is disabled and we continue to roam without any check*/
974 if(RoamRssiDiff > 0)
975 {
976 if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi))
977 {
978 /*Do not roam to an AP with worse RSSI than the current*/
979 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
980 "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d\n", __func__,
981 CurrAPRssi,
982 (int)pScanResult->BssDescriptor.rssi * (-1) );
983 continue;
984 } else {
985 /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the
986 * margin that is provided by user from the ini file (RoamRssiDiff)*/
987 if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff)
988 {
989 continue;
990 }
991 else {
992 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
993 "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d\n", __func__,
994 CurrAPRssi,
995 (int)pScanResult->BssDescriptor.rssi * (-1) );
996 }
997 }
998 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700999
1000#ifdef WLAN_FEATURE_VOWIFI_11R
1001 if (pNeighborRoamInfo->is11rAssoc)
1002 {
1003 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1004 {
1005 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1006 continue;
1007 }
1008 }
1009#endif /* WLAN_FEATURE_VOWIFI_11R */
1010
1011#ifdef FEATURE_WLAN_CCX
1012 if (pNeighborRoamInfo->isCCXAssoc)
1013 {
1014 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1015 {
1016 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1017 continue;
1018 }
1019 }
1020 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
1021 (pScanResult->BssDescriptor.QBSSLoad_avail))
1022 {
1023 if (pNeighborRoamInfo->isVOAdmitted)
1024 {
1025 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
1026 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
1027 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
1028 {
1029 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1030 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
1031 pScanResult->BssDescriptor.bssId[0],
1032 pScanResult->BssDescriptor.bssId[1],
1033 pScanResult->BssDescriptor.bssId[2],
1034 pScanResult->BssDescriptor.bssId[3],
1035 pScanResult->BssDescriptor.bssId[4],
1036 pScanResult->BssDescriptor.bssId[5]);
1037 continue;
1038 }
1039 }
1040 }
1041 else
1042 {
1043 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
1044 if (pNeighborRoamInfo->isVOAdmitted)
1045 {
1046 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1047 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
1048 pScanResult->BssDescriptor.bssId[0],
1049 pScanResult->BssDescriptor.bssId[1],
1050 pScanResult->BssDescriptor.bssId[2],
1051 pScanResult->BssDescriptor.bssId[3],
1052 pScanResult->BssDescriptor.bssId[4],
1053 pScanResult->BssDescriptor.bssId[5]);
1054 continue;
1055 }
1056 }
1057#endif /* FEATURE_WLAN_CCX */
1058
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001059#ifdef FEATURE_WLAN_LFR
1060 // If we are supporting legacy roaming, and
1061 // if the candidate is on the "pre-auth failed" list, ignore it.
1062 if (csrRoamIsFastRoamEnabled(pMac))
1063 {
1064 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
1065 {
1066 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
1067 continue;
1068 }
1069 }
1070#endif /* FEATURE_WLAN_LFR */
1071
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
1073 * this result */
1074 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
1075 {
1076 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
1077 continue;
1078 }
1079
1080 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
1081 if (NULL == pBssInfo)
1082 {
1083 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
1084 continue;
1085 }
1086
1087 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1088 if (pBssInfo->pBssDescription != NULL)
1089 {
1090 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
1091 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
1092 }
1093 else
1094 {
1095 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
1096 vos_mem_free(pBssInfo);
1097 continue;
1098
1099 }
1100 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
1101
1102 /* Just add to the end of the list as it is already sorted by RSSI */
1103 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
1104 }
1105
1106 /* 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 */
1107 csrScanResultPurge(pMac, *pScanResultList);
1108
1109 return;
1110}
1111
1112/* ---------------------------------------------------------------------------
1113
1114 \fn csrNeighborRoamHandleEmptyScanResult
1115
1116 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1117 there are no valid APs in the scan result for roaming. This means
1118 out AP is the best and no other AP is around. No point in scanning
1119 again and again. Performing the following here.
1120 1. Deregister the pre-auth callback from TL
1121 2. Stop the neighbor scan timer
1122 3. Re-register the neighbor lookup callback with increased pre-auth threshold
1123 4. Transition the state to CONNECTED state
1124
1125 \param pMac - The handle returned by macOpen.
1126
1127 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1128
1129---------------------------------------------------------------------------*/
1130static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1131{
1132 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1133 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1134 eHalStatus status = eHAL_STATUS_SUCCESS;
1135
1136 /* Stop the neighbor scan timer now */
1137 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1138 if (eHAL_STATUS_SUCCESS != status)
1139 {
1140 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1141 }
1142
1143 /* Increase the neighbor lookup threshold by a constant factor or 1 */
1144 if ((pNeighborRoamInfo->currentNeighborLookupThreshold+3) < pNeighborRoamInfo->cfgParams.neighborReassocThreshold)
1145 {
1146 pNeighborRoamInfo->currentNeighborLookupThreshold += 3;
1147 }
1148
1149
1150#ifdef WLAN_FEATURE_VOWIFI_11R
1151 /* Clear off the old neighbor report details */
1152 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1153#endif
1154
Jeff Johnsone7245742012-09-05 17:12:55 -07001155 /* Transition to CONNECTED state */
1156 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
1157
Jeff Johnson295189b2012-06-20 16:38:30 -07001158 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1159 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1160
Jeff Johnsone7245742012-09-05 17:12:55 -07001161
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 /* Re-register Neighbor Lookup threshold callback with TL */
1163 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1164 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1165 WLANTL_HO_THRESHOLD_DOWN,
1166 csrNeighborRoamNeighborLookupDOWNCallback,
1167 VOS_MODULE_ID_SME, pMac);
1168
1169 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1170 {
1171 //err msg
1172 smsLog(pMac, LOGW, FL(" Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), status);
1173 }
1174 return vosStatus;
1175}
1176
1177/* ---------------------------------------------------------------------------
1178
1179 \fn csrNeighborRoamScanRequestCallback
1180
1181 \brief This function is the callback function registered in csrScanRequest() to
1182 indicate the completion of scan. If scan is completed for all the channels in
1183 the channel list, this function gets the scan result and starts the refresh results
1184 timer to avoid having stale results. If scan is not completed on all the channels,
1185 it restarts the neighbor scan timer which on expiry issues scan on the next
1186 channel
1187
1188 \param halHandle - The handle returned by macOpen.
1189 pContext - not used
1190 scanId - not used
1191 status - not used
1192
1193 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1194
1195---------------------------------------------------------------------------*/
1196static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1197 tANI_U32 scanId, eCsrScanStatus status)
1198{
1199 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1200 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1201 tANI_U8 currentChanIndex;
1202 tCsrScanResultFilter scanFilter;
1203 tScanResultHandle scanResult;
1204 tANI_U32 tempVal = 0;
Jeff Johnson43971f52012-07-17 12:26:56 -07001205 eHalStatus hstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07001206
1207 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1208
1209 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1210 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1211 {
1212 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1213 return eHAL_STATUS_SUCCESS;
1214 }
1215
1216 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1217 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1218
1219 /* Validate inputs */
1220 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1221 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1222 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1223 }
1224 else
1225 {
1226 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1227 return eHAL_STATUS_SUCCESS;
1228 }
1229
1230 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1231 {
1232 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1233 just to get the results and perform PREAUTH */
1234 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1235 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1236 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1237 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1238
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001239#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1241 should use the BSSID filter made out of neighbor reports */
1242 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1243 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001244 hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1245 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 -07001246 tempVal = 1;
1247 }
1248 else
1249#endif
1250 {
Jeff Johnson43971f52012-07-17 12:26:56 -07001251 hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1252 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 -07001253 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001254 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001255 {
1256 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1257 return eHAL_STATUS_FAILURE;
1258 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001259 hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult);
1260 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001261 /* Process the scan results and update roamable AP list */
1262 csrNeighborRoamProcessScanResults(pMac, &scanResult);
1263
1264 /* Free the scan filter */
1265 csrFreeScanFilter(pMac, &scanFilter);
1266
1267 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1268
1269 switch(pNeighborRoamInfo->neighborRoamState)
1270 {
1271 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1272 if (tempVal)
1273 {
1274#ifdef WLAN_FEATURE_VOWIFI_11R
1275 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1276 APs in the roamable AP list */
1277 if (pNeighborRoamInfo->is11rAssoc)
1278 {
1279 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1280 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1281 }
1282 else
1283#endif
1284#ifdef FEATURE_WLAN_CCX
1285 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1286 APs in the roamable AP list */
1287 if (pNeighborRoamInfo->isCCXAssoc)
1288 {
1289 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1290 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1291 }
1292 else
1293#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001294#ifdef FEATURE_WLAN_LFR
1295 /* If LFR is enabled, then we can register the reassoc callback here as we have some
1296 APs in the roamable AP list */
1297 if (csrRoamIsFastRoamEnabled(pMac))
1298 {
1299 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1300 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1301 }
1302 else
1303#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 {
1305
1306 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1307 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1308 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1309 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1310 within certain duration */
1311
1312// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1313 }
1314 }
1315 else
1316 {
1317 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1318 /* Handle it appropriately */
1319 csrNeighborRoamHandleEmptyScanResult(pMac);
1320 }
1321 break;
1322#ifdef WLAN_FEATURE_VOWIFI_11R
1323 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1324 if (!tempVal)
1325 {
1326 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1327 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1328 csrNeighborRoamTransitToCFGChanScan(pMac);
1329 }
1330 break;
1331#endif /* WLAN_FEATURE_VOWIFI_11R */
1332 default:
1333 // Can come only in INIT state. Where in we are associated, we sent scan and user
1334 // in the meantime decides to disassoc, we will be in init state and still received call
1335 // back issued. Should not come here in any other state, printing just in case
1336 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1337 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1338
1339 // Lets just exit out silently.
1340 return eHAL_STATUS_SUCCESS;
1341 }
1342
1343 if (tempVal)
1344 {
1345 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1346
1347 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1348 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1349 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1350 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1351 eANI_BOOLEAN_FALSE))
1352 {
1353 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1354 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1355 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001356 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 }
Jeff Johnson43971f52012-07-17 12:26:56 -07001358
Jeff Johnson295189b2012-06-20 16:38:30 -07001359 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1360 /* Register a reassoc Indication callback */
1361 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1362 WLANTL_HO_THRESHOLD_DOWN,
1363 csrNeighborRoamReassocIndCallback,
1364 VOS_MODULE_ID_SME, pMac);
1365
1366 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1367 {
1368 //err msg
1369 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1370 }
1371
1372 }
1373 }
1374 else
1375 {
1376
1377 /* Restart the timer for the next scan sequence as scanning is not over */
Jeff Johnson43971f52012-07-17 12:26:56 -07001378 hstatus = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
Jeff Johnson295189b2012-06-20 16:38:30 -07001379 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1380 eANI_BOOLEAN_FALSE);
1381
Jeff Johnson43971f52012-07-17 12:26:56 -07001382 if (eHAL_STATUS_SUCCESS != hstatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07001383 {
1384 /* Timer start failed.. Should we ASSERT here??? */
1385 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1386 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1387 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
Jeff Johnson43971f52012-07-17 12:26:56 -07001388 return eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001389 }
1390 }
1391 return eHAL_STATUS_SUCCESS;
1392}
1393
1394/* ---------------------------------------------------------------------------
1395
1396 \fn csrNeighborRoamIssueBgScanRequest
1397
1398 \brief This function issues CSR scan request after populating all the BG scan params
1399 passed
1400
1401 \param pMac - The handle returned by macOpen.
1402 pBgScanParams - Params that need to be populated into csr Scan request
1403
1404 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1405
1406---------------------------------------------------------------------------*/
1407eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1408{
1409 eHalStatus status = eHAL_STATUS_SUCCESS;
1410 tANI_U32 scanId;
1411 tCsrScanRequest scanReq;
1412 tANI_U8 channel;
1413
1414 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
1415 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1416
1417
1418 //send down the scan req for 1 channel on the associated SSID
1419 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1420 /* Fill in the SSID Info */
1421 scanReq.SSIDs.numOfSSIDs = 1;
1422 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1423 if(NULL == scanReq.SSIDs.SSIDList)
1424 {
1425 //err msg
1426 smsLog(pMac, LOGW, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List\n"));
1427 return eHAL_STATUS_FAILURE;
1428 }
1429 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1430
1431 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1432 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1433 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1434
1435 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1436
1437 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1438 scanReq.ChannelInfo.ChannelList = &channel;
1439
1440 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1441 scanReq.scanType = eSIR_ACTIVE_SCAN;
1442 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1443 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1444 scanReq.minChnTime = pBgScanParams->minChnTime;
1445 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1446 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1447 if (eHAL_STATUS_SUCCESS != status)
1448 {
1449 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1450 vos_mem_free(scanReq.SSIDs.SSIDList);
1451 return status;
1452 }
1453 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1454
1455 vos_mem_free(scanReq.SSIDs.SSIDList);
1456 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x, Actual index = %d"),
1457 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1458 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1459 return status;
1460}
1461
1462/* ---------------------------------------------------------------------------
1463
1464 \fn csrNeighborRoamPerformBgScan
1465
1466 \brief This function is invoked on every expiry of neighborScanTimer till all
1467 the channels in the channel list are scanned. It populates necessary
1468 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1469 request
1470
1471 \param pMac - The handle returned by macOpen.
1472
1473 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1474
1475---------------------------------------------------------------------------*/
1476eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1477{
1478 eHalStatus status = eHAL_STATUS_SUCCESS;
1479 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1480 tCsrBGScanRequest bgScanParams;
1481 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1482 tANI_U8 channel = 0;
1483
1484 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1485 {
1486 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
1487 }
1488 else
1489 {
1490 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
1491 // Go back and restart. Mostly timer start failure has occured.
1492 // When timer start is declared a failure, then we delete the list.
1493 // Should not happen now as we stop and then only start the scan timer.
1494 // still handle the unlikely case.
1495 csrNeighborRoamHandleEmptyScanResult(pMac);
1496 return status;
1497 }
1498 /* Need to perform scan here before getting the list */
1499 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1500 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1501 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1502 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1503
1504 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1505 bgScanParams.ChannelInfo.numOfChannels = 1;
1506 bgScanParams.ChannelInfo.ChannelList = &channel;
1507
1508 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1509 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1510
1511 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1512 if (eHAL_STATUS_SUCCESS != status)
1513 {
1514 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1515 return status;
1516 }
1517
1518 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1519 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1520 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1521 {
1522 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
1523 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1524 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1525 /* We have completed scanning all the channels */
1526 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1527 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1528 and select the best AP in the list */
1529 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1530 {
1531 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1532 }
1533 }
1534
1535 return status;
1536}
1537
1538/* ---------------------------------------------------------------------------
1539
1540 \fn csrNeighborRoamNeighborScanTimerCallback
1541
1542 \brief This function is the neighbor scan timer callback function. It invokes
1543 the BG scan request based on the current and previous states
1544
1545 \param pv - CSR timer context info which includes pMac and session ID
1546
1547 \return VOID
1548
1549---------------------------------------------------------------------------*/
1550void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1551{
1552 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1553 tpAniSirGlobal pMac = pInfo->pMac;
1554 tANI_U32 sessionId = pInfo->sessionId;
1555 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1556
1557 // check if bg scan is on going, no need to send down the new params if true
1558 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1559 {
1560 //msg
1561 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1562 return;
1563 }
1564
1565 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1566
1567 switch (pNeighborRoamInfo->neighborRoamState)
1568 {
1569#ifdef WLAN_FEATURE_VOWIFI_11R
1570 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1571 switch(pNeighborRoamInfo->prevNeighborRoamState)
1572 {
1573 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1574 csrNeighborRoamPerformBgScan(pMac);
1575 break;
1576 default:
1577 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1578 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1579 break;
1580 }
1581 break;
1582#endif /* WLAN_FEATURE_VOWIFI_11R */
1583 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1584 csrNeighborRoamPerformBgScan(pMac);
1585 break;
1586 default:
1587 break;
1588 }
1589 return;
1590}
1591
1592/* ---------------------------------------------------------------------------
1593
1594 \fn csrNeighborRoamResultsRefreshTimerCallback
1595
1596 \brief This function is the timer callback function for results refresh timer.
1597 When this is invoked, it is as good as down event received from TL. So,
1598 clear off the roamable AP list and start the scan procedure based on 11R
1599 or non-11R association
1600
1601 \param context - CSR timer context info which includes pMac and session ID
1602
1603 \return VOID
1604
1605---------------------------------------------------------------------------*/
1606void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1607{
1608 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1609 tpAniSirGlobal pMac = pInfo->pMac;
1610 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1611 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1612
1613 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1614
1615 /* Deregister reassoc callback. Ignore return status */
1616 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1617 WLANTL_HO_THRESHOLD_DOWN,
1618 csrNeighborRoamReassocIndCallback,
1619 VOS_MODULE_ID_SME);
1620
1621 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1622 {
1623 //err msg
1624 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1625 }
1626
1627 /* Reset all the variables just as no scan had happened before */
1628 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1629
1630#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1631 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1632 {
1633 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1634 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1635 if (VOS_STATUS_SUCCESS != vosStatus)
1636 {
1637 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1638 return;
1639 }
1640 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1641 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1642 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1643 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1644 }
1645 else
1646#endif
1647 {
1648 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1649 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1650 if (VOS_STATUS_SUCCESS != vosStatus)
1651 {
1652 return;
1653 }
1654 }
1655 return;
1656}
1657
1658#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1659/* ---------------------------------------------------------------------------
1660
1661 \fn csrNeighborRoamIssueNeighborRptRequest
1662
1663 \brief This function is invoked when TL issues a down event and the current assoc
1664 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1665 the currently associated AP with the current SSID
1666
1667 \param pMac - The handle returned by macOpen.
1668
1669 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1670
1671---------------------------------------------------------------------------*/
1672VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1673{
1674 tRrmNeighborRspCallbackInfo callbackInfo;
1675 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1676 tRrmNeighborReq neighborReq;
1677
1678
1679 neighborReq.no_ssid = 0;
1680
1681 /* Fill in the SSID */
1682 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1683 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1684 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1685
1686 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
1687 callbackInfo.neighborRspCallbackContext = pMac;
1688 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
1689
1690 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
1691}
1692
1693/* ---------------------------------------------------------------------------
1694
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001695 \fn csrNeighborRoamMergeChannelLists
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001696
1697 \brief This function is used to merge two channel list.
1698 NB: If called with outputNumOfChannels == 0, this routines
1699 simply copies the input channel list to the output channel list.
1700
1701 \param pMac - The handle returned by macOpen.
1702 \param pInputChannelList - The addtional channels to merge in to the "merged" channels list.
1703 \param inputNumOfChannels - The number of additional channels.
1704 \param pOutputChannelList - The place to put the "merged" channel list.
1705 \param outputNumOfChannels - The original number of channels in the "merged" channels list.
1706 \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list.
1707
1708 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1709
1710---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001711VOS_STATUS csrNeighborRoamMergeChannelLists(
1712 tpAniSirGlobal pMac,
1713 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001714 int inputNumOfChannels,
1715 tANI_U8 *pOutputChannelList,
1716 int outputNumOfChannels,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001717 int *pMergedOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001718 )
1719{
1720 int i = 0;
1721 int j = 0;
1722 int numChannels = outputNumOfChannels;
1723
1724 // Check for NULL pointer
1725 if (!pInputChannelList) return eHAL_STATUS_E_NULL_VALUE;
1726
1727 // Check for NULL pointer
1728 if (!pOutputChannelList) return eHAL_STATUS_E_NULL_VALUE;
1729
1730 // Add the "new" channels in the input list to the end of the output list.
1731 for (i = 0; i < inputNumOfChannels; i++)
1732 {
1733 for (j = 0; j < outputNumOfChannels; j++)
1734 {
1735 if (pInputChannelList[i] == pOutputChannelList[j])
1736 break;
1737 }
1738 if (j == outputNumOfChannels)
1739 {
1740 if (pInputChannelList[i])
1741 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001742 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1743 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1744 pInputChannelList[i]);
1745 pOutputChannelList[numChannels] = pInputChannelList[i];
1746 numChannels++;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001747 }
1748 }
1749 }
1750
1751 // Return final number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001752 *pMergedOutputNumOfChannels = numChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001753
1754 return eHAL_STATUS_SUCCESS;
1755}
1756
1757/* ---------------------------------------------------------------------------
1758
Jeff Johnson295189b2012-06-20 16:38:30 -07001759 \fn csrNeighborRoamCreateChanListFromNeighborReport
1760
1761 \brief This function is invoked when neighbor report is received for the
1762 neighbor request. Based on the channels present in the neighbor report,
1763 it generates channel list which will be used in REPORT_SCAN state to
1764 scan for these neighbor APs
1765
1766 \param pMac - The handle returned by macOpen.
1767
1768 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1769
1770---------------------------------------------------------------------------*/
1771VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
1772{
1773 tpRrmNeighborReportDesc pNeighborBssDesc;
1774 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001775 tANI_U8 numChannels = 0, i = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001776 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001777#if 0
1778 eHalStatus status = eHAL_STATUS_SUCCESS;
1779#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001780
1781 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
1782 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
1783
1784 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
1785
1786 while (pNeighborBssDesc)
1787 {
1788 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
1789
1790 /* Update the neighbor BSS Info in the 11r FT Roam Info */
1791 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
1792 pNeighborBssDesc->pNeighborBssDescription->channel;
1793 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
1794 (tANI_U8)pNeighborBssDesc->roamScore;
1795 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
1796 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
1797 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
1798
1799 /* Saving the channel list non-redundantly */
1800 if (numChannels > 0)
1801 {
1802 for (i = 0; i < numChannels; i++)
1803 {
1804 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
1805 break;
1806 }
1807
1808 }
1809 if (i == numChannels)
1810 {
1811 if (pNeighborBssDesc->pNeighborBssDescription->channel)
1812 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001813 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1814 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1815 pNeighborBssDesc->pNeighborBssDescription->channel);
1816 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1817 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001818 }
1819 }
1820
1821 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
1822 }
1823
1824 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1825 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001826#if 0
Jeff Johnson295189b2012-06-20 16:38:30 -07001827 // Before we free the existing channel list for a safety net make sure
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001828 // we have a union of the IAPP and the already existing list.
1829 status = csrNeighborRoamMergeChannelLists(
1830 pMac,
1831 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1832 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels,
1833 channelList,
1834 numChannels,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001835 &numChannels );
1836#endif
1837
Jeff Johnson295189b2012-06-20 16:38:30 -07001838 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1839 }
1840
1841 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1842 /* Store the obtained channel list to the Neighbor Control data structure */
1843 if (numChannels)
1844 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
1845 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1846 {
1847 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1848 return VOS_STATUS_E_RESOURCES;
1849 }
1850
1851 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1852 channelList, (numChannels) * sizeof(tANI_U8));
1853 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
1854 if (numChannels)
1855 {
1856 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
1857 pNeighborRoamInfo->neighborRoamState);
1858 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
1859 }
1860 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1861 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1862
1863 return VOS_STATUS_SUCCESS;
1864}
1865
1866/* ---------------------------------------------------------------------------
1867
1868 \fn csrNeighborRoamRRMNeighborReportResult
1869
1870 \brief This function is the neighbor report callback that will be invoked by
1871 SME RRM on receiving a neighbor report or of neighbor report is not
1872 received after timeout. On receiving a valid report, it generates a
1873 channel list from the neighbor report and starts the
1874 neighbor scan timer
1875
1876 \param context - The handle returned by macOpen.
1877 vosStatus - Status of the callback(SUCCESS/FAILURE)
1878
1879 \return VOID
1880
1881---------------------------------------------------------------------------*/
1882void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
1883{
1884 tpAniSirGlobal pMac = PMAC_STRUCT(context);
1885 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1886 eHalStatus status = eHAL_STATUS_SUCCESS;
1887
1888 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
1889 switch (pNeighborRoamInfo->neighborRoamState)
1890 {
1891 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1892 /* Reset the report pending variable */
1893 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
1894 if (VOS_STATUS_SUCCESS == vosStatus)
1895 {
1896 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
1897 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
1898 if (VOS_STATUS_SUCCESS == vosStatus)
1899 {
1900 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
1901 }
1902
1903 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1904 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1905
1906 /* Now ready for neighbor scan based on the channel list created */
1907 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1908 what palTimerStart expects */
1909 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1910 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1911 eANI_BOOLEAN_FALSE);
1912 if (eHAL_STATUS_SUCCESS != status)
1913 {
1914 /* Timer start failed.. Should we ASSERT here??? */
1915 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
1916 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1917 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1918 return;
1919 }
1920 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1921 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
1922 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1923 }
1924 else
1925 {
1926 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
1927 reach the maxNeighborRetries or receiving a successful neighbor response */
1928 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
1929 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
1930 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
1931 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
1932 {
1933 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
1934 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1935 if (VOS_STATUS_SUCCESS != vosStatus)
1936 {
1937 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
1938 return;
1939 }
1940 /* We transitioned to different state now. Reset the Neighbor report retry count */
1941 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1942 }
1943 else
1944 {
1945 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1946 if (VOS_STATUS_SUCCESS != vosStatus)
1947 {
1948 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1949 return;
1950 }
1951 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1952 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1953 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1954 }
1955 }
1956 break;
1957 default:
1958 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
1959 break;
1960 }
1961 return;
1962}
1963#endif /* WLAN_FEATURE_VOWIFI_11R */
1964
1965
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001966#ifdef FEATURE_WLAN_LFR
1967tANI_BOOLEAN csrNeighborRoamIsSsidCandidateMatch(
1968 tpAniSirGlobal pMac,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001969 tDot11fBeaconIEs *pIes)
1970{
1971 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1972 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
1973 tCsrRoamConnectedProfile *pCurProfile;
1974 tANI_BOOLEAN fMatch = FALSE;
1975
1976 if( !(pMac->roam.roamSession
1977 && CSR_IS_SESSION_VALID(pMac, sessionId)))
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001978 return TRUE; // Treat missing information as a match for everything.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001979
1980 pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
1981
1982 if( !pCurProfile)
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001983 return TRUE; // Treat missing information as a match for everything.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001984
1985 if( pIes )
1986 {
1987 if(pIes->SSID.present)
1988 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001989 fMatch = csrIsSsidMatch( pMac, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length,
1990 pIes->SSID.ssid, pIes->SSID.num_ssid,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001991 eANI_BOOLEAN_TRUE ); // Treat a missing SSID as a non-match.
1992 // Return the result of the match operation
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001993 return fMatch;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001994 } else
1995 return FALSE; // Treat a missing SSID as a non-match.
1996 } else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07001997 return FALSE; // Again, treat missing SSID information as a non-match.
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001998}
1999
2000/* ---------------------------------------------------------------------------
2001
2002 \fn csrNeighborRoamReorderChannelList
2003
2004 \brief This function is used to reorder the channel list used for the background
2005 scan. It uses the information learned from previous scans to re-order the
2006 scan channel list to "favor" the "occupied channels". The actual algorithm
2007 is to scan the current set of "occupied channels" first, for every BG scan,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002008 followed by a "chunk" of the remaining list of "valid channels".
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002009
2010 \param pMac - The handle returned by macOpen.
2011 \param pInputChannelList - The default channels list.
2012 \param numOfChannels - The number of channels in the default channels list.
2013 \param pOutputChannelList - The place to put the "re-ordered" channel list.
2014 \param pOutputNumOfChannels - The number of channels in the "re-ordered" channel list.
2015
2016 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2017
2018---------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002019VOS_STATUS csrNeighborRoamReorderChannelList(
2020 tpAniSirGlobal pMac,
2021 tANI_U8 *pInputChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002022 int numOfChannels,
2023 tANI_U8 *pOutputChannelList,
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002024 int *pOutputNumOfChannels
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002025 )
2026{
2027 int i = 0;
2028 int j = 0;
2029 static int index = 0;
2030 int outputNumOfChannels = 0; // Clear the output number of channels
2031 tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels;
2032 tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList;
2033
2034
2035 // Copy over the "occupied channels" at the FRONT of pOutputChannelList.
2036 for (i = 0; i < numOccupiedChannels; i++)
2037 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002038 if (pOccupiedChannelList[i] != 0)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002039 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002040 pOutputChannelList[i] = pOccupiedChannelList[i];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002041 outputNumOfChannels++;
2042 }
2043 }
2044
2045 // Copy over one "chunk" of channels from the "rest of the channels"...append them to the END of pOutputChannelList.
2046 for (j = 0; j < CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE; j++)
2047 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002048 if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, pInputChannelList[j+index % numOfChannels]))
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002049 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002050 pOutputChannelList[i] = pInputChannelList[j+index % numOfChannels];
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002051 i++;
2052 outputNumOfChannels++;
2053 }
2054 }
2055
2056 //Let's update the index...at which we start retrieving the next chunk
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002057 index = (index + CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE) % numOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002058
2059 //VOS_ASSERT(numOfChannels == i);
2060 smsLog(pMac, LOGE, FL("numOfChannels in the default channels list=%d. Number in the final list=%d."), numOfChannels, i);
2061
2062 // Return the number of channels
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002063 *pOutputNumOfChannels = outputNumOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002064
2065 return eHAL_STATUS_SUCCESS;
2066}
2067#endif /* FEATURE_WLAN_LFR */
2068
Jeff Johnson295189b2012-06-20 16:38:30 -07002069/* ---------------------------------------------------------------------------
2070
2071 \fn csrNeighborRoamTransitToCFGChanScan
2072
2073 \brief This function is called whenever there is a transition to CFG chan scan
2074 state from any state. It frees up the current channel list and allocates
2075 a new memory for the channels received from CFG item. It then starts the
2076 neighbor scan timer to perform the scan on each channel one by one
2077
2078 \param pMac - The handle returned by macOpen.
2079
2080 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2081
2082---------------------------------------------------------------------------*/
2083VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
2084{
2085 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2086 eHalStatus status = eHAL_STATUS_SUCCESS;
2087 int i = 0;
2088 int numOfChannels = 0;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002089 tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
Jeff Johnson295189b2012-06-20 16:38:30 -07002090
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002091 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07002092#ifdef FEATURE_WLAN_CCX
2093 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002094 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
2096#endif // CCX
2097 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels == 0)
2098
2099 {
2100 smsLog(pMac, LOGW, FL("Falling back to CFG channel list"));
2101
2102
2103 /* Free up the channel list and allocate a new memory. This is because we dont know how much
2104 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
2105 result in memory corruption */
2106 if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2107 {
2108 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2109 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2110 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002111 VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
2112
2113 // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER
2114 // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR.
2115 if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002117 // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini".
2118 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini");
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002119 status = csrNeighborRoamMergeChannelLists(
2120 pMac,
2121 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2122 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels,
2123 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002124 0, //NB: If 0, simply copy the input channel list to the output list.
2125 &numOfChannels );
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002126 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002127 else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002128 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002129 /* Get current list of valid channels. */
2130 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Switching to master list of valid channels");
2131 numOfChannels = sizeof(pMac->roam.validChannelList);
2132 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, (tANI_U32 *) &numOfChannels)))
Jeff Johnson295189b2012-06-20 16:38:30 -07002133 {
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002134 // 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 -07002135 status = csrNeighborRoamMergeChannelLists(
2136 pMac,
2137 (tANI_U8 *)pMac->roam.validChannelList,
2138 numOfChannels, // The number of channels in the validChannelList
2139 channelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002140 0, //NB: If 0, simply copy the input channel list to the output list.
2141 &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels
2142 }
2143 else
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002144 {
2145 smsLog(pMac, LOGE, FL("Could not get valid channel list, TL event ignored"));
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002146 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 }
2148 }
2149
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002150 /* At this point, channelList contains our best inputs on the "valid channel list" */
2151
2152 /* Allocate for the maximum number that might be used */
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002153 smsLog(pMac, LOGE, FL("%d channels in the default list. Add %d occupied channels. %d is the MAX scan channel list."),
2154 numOfChannels,
2155 CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002156 numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002158 VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 if (numOfChannels)
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002160 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002161 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList =
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002162 vos_mem_malloc(numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
2163 }
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002164
Jeff Johnson295189b2012-06-20 16:38:30 -07002165 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2166 {
2167 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
2168 return VOS_STATUS_E_RESOURCES;
2169 }
2170
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002171#ifdef FEATURE_WLAN_LFR
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 /* Since this is a legacy case, copy the channel list from CFG here */
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002173
2174 status = csrNeighborRoamReorderChannelList( pMac,
2175 channelList,
2176 numOfChannels,
2177 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002178 &numOfChannels );
2179 if (eHAL_STATUS_SUCCESS != status)
2180#endif
2181 {
2182 /* Re-ordering failed. */
2183 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 -07002184 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
2185 channelList, numOfChannels * sizeof(tANI_U8));
2186 }
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07002187
2188 /* Adjust for the actual number that are used */
2189 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
2191 {
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002192 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG (or scan caching) = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
2194 }
2195 }
2196
2197 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
2198 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2199
2200 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2201 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
2202 what palTimerStart expects */
2203 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
2204 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
2205 eANI_BOOLEAN_FALSE);
2206
2207 if (eHAL_STATUS_SUCCESS != status)
2208 {
2209 /* Timer start failed.. */
2210 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
2211 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2212 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2213 return VOS_STATUS_E_FAILURE;
2214 }
2215
2216 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2217 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
Madan Mohan Koyyalamudi595208a2012-10-05 12:48:38 -07002218 /* We are about to start a fresh scan cycle, purge results from the past */
2219 csrScanFlushResult(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220
2221 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2222 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2223
2224 return VOS_STATUS_SUCCESS;
2225}
2226
2227/* ---------------------------------------------------------------------------
2228
2229 \fn csrNeighborRoamNeighborLookupUpEvent
2230
2231 \brief This function is called as soon as TL indicates that the current AP's
2232 RSSI is better than the neighbor lookup threshold. Here, we transition to
2233 CONNECTED state and reset all the scan parameters
2234
2235 \param pMac - The handle returned by macOpen.
2236
2237 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2238
2239---------------------------------------------------------------------------*/
2240VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2241{
2242 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2243 VOS_STATUS vosStatus;
2244
2245 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2246 /* Deregister the UP event now */
2247 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2248 WLANTL_HO_THRESHOLD_UP,
2249 csrNeighborRoamNeighborLookupUPCallback,
2250 VOS_MODULE_ID_SME);
2251
2252 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2253 {
2254 //err msg
2255 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
2256 }
2257
2258 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2259 /* Deregister the UP event now */
2260 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2261 WLANTL_HO_THRESHOLD_DOWN,
2262 csrNeighborRoamNeighborLookupDOWNCallback,
2263 VOS_MODULE_ID_SME);
2264
2265 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2266 {
2267 //err msg
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002268 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002269 }
2270
2271 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
2272 /* Deregister reassoc callback. */
2273 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
2274 WLANTL_HO_THRESHOLD_DOWN,
2275 csrNeighborRoamReassocIndCallback,
2276 VOS_MODULE_ID_SME);
2277
2278 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2279 {
2280 //err msg
2281 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
2282 }
2283
2284
2285 /* RSSI got better than the CFG neighbor lookup threshold. Reset the threshold to older value and set the increment multiplier to 0 */
2286 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2287
2288 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
2289
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 /* Recheck whether the below check is needed. */
2291 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2292 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
Jeff Johnsone7245742012-09-05 17:12:55 -07002293
2294 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2295 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2296
Jeff Johnson295189b2012-06-20 16:38:30 -07002297
2298 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2299 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2300 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2301 WLANTL_HO_THRESHOLD_DOWN,
2302 csrNeighborRoamNeighborLookupDOWNCallback,
2303 VOS_MODULE_ID_SME, pMac);
2304 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2305 {
2306 //err msg
2307 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2308 }
2309
2310
2311 return vosStatus;
2312}
2313
2314/* ---------------------------------------------------------------------------
2315
2316 \fn csrNeighborRoamNeighborLookupDownEvent
2317
2318 \brief This function is called as soon as TL indicates that the current AP's
2319 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2320 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2321 a non-11R association.
2322
2323 \param pMac - The handle returned by macOpen.
2324
2325 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2326
2327---------------------------------------------------------------------------*/
2328VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2329{
2330 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2331 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2332 eHalStatus status = eHAL_STATUS_SUCCESS;
2333
2334 switch (pNeighborRoamInfo->neighborRoamState)
2335 {
2336 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2337
2338 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2339 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2340 /* De-register Neighbor Lookup threshold callback with TL */
2341 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2342 WLANTL_HO_THRESHOLD_DOWN,
2343 csrNeighborRoamNeighborLookupDOWNCallback,
2344 VOS_MODULE_ID_SME);
2345
2346 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2347 {
2348 //err msg
Madan Mohan Koyyalamudi596e4fb2012-10-05 11:39:52 -07002349 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), vosStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07002350 }
2351
2352
2353#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2354 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2355 {
2356
2357 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2358 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2359 if (VOS_STATUS_SUCCESS != vosStatus)
2360 {
2361 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2362 return vosStatus;
2363 }
2364 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2365 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2366 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2367 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2368 }
2369 else
2370#endif
2371 {
2372 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2373
2374 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2375 if (VOS_STATUS_SUCCESS != vosStatus)
2376 {
2377 return vosStatus;
2378 }
2379 }
2380 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2381 /* Register Neighbor Lookup threshold callback with TL for UP event now */
2382 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2383 WLANTL_HO_THRESHOLD_UP,
2384 csrNeighborRoamNeighborLookupUPCallback,
2385 VOS_MODULE_ID_SME, pMac);
2386 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2387 {
2388 //err msg
2389 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
2390 }
2391 break;
2392 default:
2393 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2394 break;
2395
2396 }
2397 return vosStatus;
2398}
2399
2400/* ---------------------------------------------------------------------------
2401
2402 \fn csrNeighborRoamNeighborLookupUPCallback
2403
2404 \brief This function is registered with TL to indicate whenever the RSSI
2405 gets better than the neighborLookup RSSI Threshold
2406
2407 \param pAdapter - VOS Context
2408 trafficStatus - UP/DOWN indication from TL
2409 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2410
2411 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2412
2413---------------------------------------------------------------------------*/
2414VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2415 v_PVOID_t pUserCtxt)
2416{
2417 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2418 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2419 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2420
2421 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
2422
2423 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2424 {
2425 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2426 return VOS_STATUS_SUCCESS;
2427 }
2428
2429 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2430 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2431 return vosStatus;
2432}
2433
2434/* ---------------------------------------------------------------------------
2435
2436 \fn csrNeighborRoamNeighborLookupDOWNCallback
2437
2438 \brief This function is registered with TL to indicate whenever the RSSI
2439 falls below the current neighborLookup RSSI Threshold
2440
2441 \param pAdapter - VOS Context
2442 trafficStatus - UP/DOWN indication from TL
2443 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2444
2445 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2446
2447---------------------------------------------------------------------------*/
2448VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2449 v_PVOID_t pUserCtxt)
2450{
2451 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2452 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2453 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2454
2455 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
2456
2457 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2458 {
2459 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2460 return VOS_STATUS_SUCCESS;
2461 }
2462
2463 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2464 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2465
2466 return vosStatus;
2467}
2468
2469#ifdef RSSI_HACK
2470extern int dumpCmdRSSI;
2471#endif
2472
2473/* ---------------------------------------------------------------------------
2474
2475 \fn csrNeighborRoamIndicateDisconnect
2476
2477 \brief This function is called by CSR as soon as the station disconnects from
2478 the AP. This function does the necessary cleanup of neighbor roam data
2479 structures. Neighbor roam state transitions to INIT state whenever this
2480 function is called except if the current state is REASSOCIATING
2481
2482 \param pMac - The handle returned by macOpen.
2483 sessionId - CSR session id that got disconnected
2484
2485 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2486
2487---------------------------------------------------------------------------*/
2488eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2489{
2490 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2491
Madan Mohan Koyyalamudi5695b502012-09-24 14:21:12 -07002492 smsLog(pMac, LOG1, FL("Disconnect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002493
2494#ifdef FEATURE_WLAN_CCX
2495 {
2496 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2497 if (pSession->connectedProfile.isCCXAssoc)
2498 {
2499 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2500 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2501 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2502 pSession->isPrevApInfoValid = TRUE;
2503 pSession->roamTS1 = vos_timer_get_system_time();
2504
2505 }
2506 }
2507#endif
2508
2509#ifdef RSSI_HACK
2510 dumpCmdRSSI = -40;
2511#endif
2512 switch (pNeighborRoamInfo->neighborRoamState)
2513 {
2514 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2515 // Stop scan and neighbor refresh timers.
2516 // These are indeed not required when we are in reassociating
2517 // state.
2518 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2519 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2520 break;
2521
2522 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2523 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Ignoring disconnect event in INIT state"));
2524 csrNeighborRoamResetInitStateControlInfo(pMac);
2525 break;
2526
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002527 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2528 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2529 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2530 csrNeighborRoamResetReportScanStateControlInfo(pMac);
2531 break;
2532
Jeff Johnson295189b2012-06-20 16:38:30 -07002533 default:
Madan Mohan Koyyalamudi5695b502012-09-24 14:21:12 -07002534 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2535 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002536 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002537 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 }
2539 return eHAL_STATUS_SUCCESS;
2540}
2541
2542/* ---------------------------------------------------------------------------
2543
2544 \fn csrNeighborRoamIndicateConnect
2545
2546 \brief This function is called by CSR as soon as the station connects to an AP.
2547 This initializes all the necessary data structures related to the
2548 associated AP and transitions the state to CONNECTED state
2549
2550 \param pMac - The handle returned by macOpen.
2551 sessionId - CSR session id that got connected
2552 vosStatus - connect status SUCCESS/FAILURE
2553
2554 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2555
2556---------------------------------------------------------------------------*/
2557eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2558{
2559 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2560 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002561 VOS_STATUS vstatus;
2562
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002563#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002564 int init_ft_flag = FALSE;
2565#endif
2566
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002567 smsLog(pMac, LOG2, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002568
2569 switch (pNeighborRoamInfo->neighborRoamState)
2570 {
2571 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2572 if (VOS_STATUS_SUCCESS != vosStatus)
2573 {
2574 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2575 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2576 break;
2577 }
2578 /* Fall through if the status is SUCCESS */
2579 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2580 /* Reset all the data structures here */
2581 csrNeighborRoamResetInitStateControlInfo(pMac);
2582
2583 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2584
2585 pNeighborRoamInfo->csrSessionId = sessionId;
2586 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2587 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2588 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2589 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2590 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
2591
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002592#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 /* Now we can clear the preauthDone that was saved as we are connected afresh */
2594 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2595#endif
2596
2597#ifdef WLAN_FEATURE_VOWIFI_11R
2598 // Based on the auth scheme tell if we are 11r
2599 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType ) )
2600 {
2601 if (pMac->roam.configParam.isFastTransitionEnabled)
2602 init_ft_flag = TRUE;
2603 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
2604 }
2605 else
2606 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002607 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
Jeff Johnson295189b2012-06-20 16:38:30 -07002608#endif
2609
2610#ifdef FEATURE_WLAN_CCX
2611 // Based on the auth scheme tell if we are 11r
2612 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
2613 {
2614 if (pMac->roam.configParam.isFastTransitionEnabled)
2615 init_ft_flag = TRUE;
2616 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
2617 }
2618 else
2619 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002620 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isCCXAssoc is = %d ft = %d"),
2621 pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
Jeff Johnson295189b2012-06-20 16:38:30 -07002622
2623#endif
2624
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002625#ifdef FEATURE_WLAN_LFR
2626 // If "Legacy Fast Roaming" is enabled
2627 if (csrRoamIsFastRoamEnabled(pMac))
2628 {
2629 init_ft_flag = TRUE;
2630 }
2631#endif
2632
2633#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002634 if ( init_ft_flag == TRUE )
2635 {
2636 /* Initialize all the data structures needed for the 11r FT Preauth */
2637 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
2638 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
2639 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2640 csrNeighborRoamPurgePreauthFailedList(pMac);
2641
2642 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
2643 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07002644 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002645 WLANTL_HO_THRESHOLD_DOWN,
2646 csrNeighborRoamNeighborLookupDOWNCallback,
2647 VOS_MODULE_ID_SME, pMac);
2648
Jeff Johnson43971f52012-07-17 12:26:56 -07002649 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002650 {
2651 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07002652 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
2653 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002654 }
2655 }
2656#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 break;
2658 default:
2659 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2660 break;
2661 }
2662 return status;
2663}
2664
2665
2666#ifdef WLAN_FEATURE_VOWIFI_11R
2667/* ---------------------------------------------------------------------------
2668
2669 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
2670
2671 \brief If this function is invoked, that means the preauthentication response
2672 is timed out from the PE. Preauth rsp handler is called with status as
2673 TIMEOUT
2674
2675 \param context - CSR Timer info which holds pMac and session ID
2676
2677 \return VOID
2678
2679---------------------------------------------------------------------------*/
2680void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
2681{
2682 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
2683 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
2684 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2685
2686 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
2687
2688 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
2689}
2690
2691/* ---------------------------------------------------------------------------
2692
2693 \fn csrNeighborRoamPurgePreauthFailedList
2694
2695 \brief This function purges all the MAC addresses in the pre-auth fail list
2696
2697 \param pMac - The handle returned by macOpen.
2698
2699 \return VOID
2700
2701---------------------------------------------------------------------------*/
2702void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
2703{
2704 tANI_U8 i;
2705
2706 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
2707 {
2708 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
2709 }
2710 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
2711
2712 return;
2713}
2714
2715/* ---------------------------------------------------------------------------
2716
2717 \fn csrNeighborRoamInit11rAssocInfo
2718
2719 \brief This function initializes 11r related neighbor roam data structures
2720
2721 \param pMac - The handle returned by macOpen.
2722
2723 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2724
2725---------------------------------------------------------------------------*/
2726eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
2727{
2728 eHalStatus status;
2729 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
2730
2731 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
2732 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
2733 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
2734 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
2735 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
2736 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
2737
2738 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
2739 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2740 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
2741 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
2742
2743 if (eHAL_STATUS_SUCCESS != status)
2744 {
2745 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2746 return eHAL_STATUS_RESOURCES;
2747 }
2748
2749 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2750 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2751 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2752 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2753
2754
2755 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
2756 if (eHAL_STATUS_SUCCESS != status)
2757 {
2758 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
2759 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
2760 return eHAL_STATUS_RESOURCES;
2761 }
2762 return status;
2763}
2764#endif /* WLAN_FEATURE_VOWIFI_11R */
2765
2766/* ---------------------------------------------------------------------------
2767
2768 \fn csrNeighborRoamInit
2769
2770 \brief This function initializes neighbor roam data structures
2771
2772 \param pMac - The handle returned by macOpen.
2773
2774 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2775
2776---------------------------------------------------------------------------*/
2777eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
2778{
2779 eHalStatus status;
2780 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2781
2782 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2783 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2784 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
2785 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
2786 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
2787 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
2788 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
2789 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
2790 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
2791 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
2792
2793 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
2794 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
2795
2796 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
2797 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2798
2799 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2800 {
2801 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
2802 return eHAL_STATUS_RESOURCES;
2803 }
2804
2805 /* Update the roam global structure from CFG */
2806 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2807 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
2808 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2809
2810 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
2811 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
2812 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2813 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
2814
2815 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2816 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2817 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
2818 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2819
2820 if (eHAL_STATUS_SUCCESS != status)
2821 {
2822 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2823 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2824 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2825 return eHAL_STATUS_RESOURCES;
2826 }
2827
2828 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
2829 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2830
2831 if (eHAL_STATUS_SUCCESS != status)
2832 {
2833 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2834 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2835 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2836 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2837 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2838 return eHAL_STATUS_RESOURCES;
2839 }
2840
2841 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
2842 if (eHAL_STATUS_SUCCESS != status)
2843 {
2844 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2845 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2846 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2847 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2848 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2849 return eHAL_STATUS_RESOURCES;
2850 }
2851
2852 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2853 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2854 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2855 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2856 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2857
2858#ifdef WLAN_FEATURE_VOWIFI_11R
2859 status = csrNeighborRoamInit11rAssocInfo(pMac);
2860 if (eHAL_STATUS_SUCCESS != status)
2861 {
2862 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2863 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2864 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2865 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2866 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2867 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2868 return eHAL_STATUS_RESOURCES;
2869 }
2870#endif
2871 /* Initialize this with the current tick count */
2872 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2873
2874 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2875
2876 return eHAL_STATUS_SUCCESS;
2877}
2878
2879/* ---------------------------------------------------------------------------
2880
2881 \fn csrNeighborRoamClose
2882
2883 \brief This function closes/frees all the neighbor roam data structures
2884
2885 \param pMac - The handle returned by macOpen.
2886
2887 \return VOID
2888
2889---------------------------------------------------------------------------*/
2890void csrNeighborRoamClose(tpAniSirGlobal pMac)
2891{
2892 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2893
2894 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
2895 {
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07002896 smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002897 return;
2898 }
2899
2900 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2901 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2902
2903 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2904
2905 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
2906 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2907 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2908 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2909
2910 /* Should free up the nodes in the list before closing the double Linked list */
2911 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
2912 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2913
2914 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2915 {
2916 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2917 }
2918
2919 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2920 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2921 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2922 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2923 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2924 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2925
2926 /* Free the profile.. */
2927 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2928
2929#ifdef WLAN_FEATURE_VOWIFI_11R
2930 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2931 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
2932 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
2933 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2934 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2935 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2936 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2937 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2938 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2939#endif /* WLAN_FEATURE_VOWIFI_11R */
2940
2941 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
2942
2943 return;
2944}
2945
2946/* ---------------------------------------------------------------------------
2947
2948 \fn csrNeighborRoamRequestHandoff
2949
2950 \brief This function triggers actual switching from one AP to the new AP.
2951 It issues disassociate with reason code as Handoff and CSR as a part of
2952 handling disassoc rsp, issues reassociate to the new AP
2953
2954 \param pMac - The handle returned by macOpen.
2955
2956 \return VOID
2957
2958---------------------------------------------------------------------------*/
2959void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
2960{
2961
2962 tCsrRoamInfo roamInfo;
2963 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2964 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
2965 tCsrNeighborRoamBSSInfo handoffNode;
2966 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
2967 tANI_U32 roamId = 0;
2968
2969 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
2970 {
2971 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
2972 pMac->roam.neighborRoamInfo.neighborRoamState);
2973 return;
2974 }
2975
2976 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2977 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
2978 eSIR_SME_SUCCESS);
2979
2980 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2981 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
2982
2983 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
2984 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
2985 handoffNode.pBssDescription->bssId[0],
2986 handoffNode.pBssDescription->bssId[1],
2987 handoffNode.pBssDescription->bssId[2],
2988 handoffNode.pBssDescription->bssId[3],
2989 handoffNode.pBssDescription->bssId[4],
2990 handoffNode.pBssDescription->bssId[5]);
2991
2992 /* Free the profile.. Just to make sure we dont leak memory here */
2993 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2994 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
2995 This should happen before issuing disconnect */
2996 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
2997 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
2998 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
2999
3000 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
3001
3002 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
3003 {
3004 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
3005 return;
3006 }
3007
3008 //notify HDD for handoff, providing the BSSID too
3009 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
3010
3011 vos_mem_copy(roamInfo.bssid,
3012 handoffNode.pBssDescription->bssId,
3013 sizeof( tCsrBssid ));
3014
3015 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
3016
3017
3018 return;
3019}
3020
3021/* ---------------------------------------------------------------------------
3022
3023 \fn csrNeighborRoamIsHandoffInProgress
3024
3025 \brief This function returns whether handoff is in progress or not based on
3026 the current neighbor roam state
3027
3028 \param pMac - The handle returned by macOpen.
3029 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
3030
3031 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
3032
3033---------------------------------------------------------------------------*/
3034tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
3035{
3036 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
3037 return eANI_BOOLEAN_TRUE;
3038
3039 return eANI_BOOLEAN_FALSE;
3040}
3041
3042#ifdef WLAN_FEATURE_VOWIFI_11R
3043/* ---------------------------------------------------------------------------
3044
3045 \fn csrNeighborRoamIs11rAssoc
3046
3047 \brief This function returns whether the current association is a 11r assoc or not
3048
3049 \param pMac - The handle returned by macOpen.
3050
3051 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
3052
3053---------------------------------------------------------------------------*/
3054tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
3055{
3056 return pMac->roam.neighborRoamInfo.is11rAssoc;
3057}
3058#endif /* WLAN_FEATURE_VOWIFI_11R */
3059
3060
3061/* ---------------------------------------------------------------------------
3062
3063 \fn csrNeighborRoamGetHandoffAPInfo
3064
3065 \brief This function returns the best possible AP for handoff. For 11R case, it
3066 returns the 1st entry from pre-auth done list. For non-11r case, it returns
3067 the 1st entry from roamable AP list
3068
3069 \param pMac - The handle returned by macOpen.
3070 pHandoffNode - AP node that is the handoff candidate returned
3071
3072 \return VOID
3073
3074---------------------------------------------------------------------------*/
3075void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
3076{
3077 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
3078 tpCsrNeighborRoamBSSInfo pBssNode;
3079
3080 VOS_ASSERT(NULL != pHandoffNode);
3081
3082#ifdef WLAN_FEATURE_VOWIFI_11R
3083 if (pNeighborRoamInfo->is11rAssoc)
3084 {
3085 /* Always the BSS info in the head is the handoff candidate */
3086 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3087 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3088 }
3089 else
3090#endif
3091#ifdef FEATURE_WLAN_CCX
3092 if (pNeighborRoamInfo->isCCXAssoc)
3093 {
3094 /* Always the BSS info in the head is the handoff candidate */
3095 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3096 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3097 }
3098 else
3099#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003100#ifdef FEATURE_WLAN_LFR
3101 if (csrRoamIsFastRoamEnabled(pMac))
3102 {
3103 /* Always the BSS info in the head is the handoff candidate */
3104 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
3105 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
3106 }
3107 else
3108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 {
3110 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
3111 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
3112 }
3113 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
3114
3115 return;
3116}
3117
3118/* ---------------------------------------------------------------------------
3119 \brief This function returns TRUE if preauth is completed
3120
3121 \param pMac - The handle returned by macOpen.
3122
3123 \return boolean
3124
3125---------------------------------------------------------------------------*/
3126tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
3127{
3128 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
3129 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
3130}
3131
3132/* ---------------------------------------------------------------------------
3133 \brief In the event that we are associated with AP1 and we have
3134 completed pre auth with AP2. Then we receive a deauth/disassoc from
3135 AP1.
3136 At this point neighbor roam is in pre auth done state, pre auth timer
3137 is running. We now handle this case by stopping timer and clearing
3138 the pre-auth state. We basically clear up and just go to disconnected
3139 state.
3140
3141 \param pMac - The handle returned by macOpen.
3142
3143 \return boolean
3144---------------------------------------------------------------------------*/
3145void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
3146{
3147 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
3148 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
3149
3150 // Stop timer
3151 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
3152
3153 // Transition to init state
3154 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
3155}
3156
3157#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */