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