blob: 36093c6a77d8fca900b64866ffb3a01074d7c4df [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;\
95 smsLog(pMac, LOGE, FL("Neighbor Roam Transition from state %d ==> %d"), pMac->roam.neighborRoamInfo.prevNeighborRoamState, newState);\
96}
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
1692 \fn csrNeighborRoamCreateChanListFromNeighborReport
1693
1694 \brief This function is invoked when neighbor report is received for the
1695 neighbor request. Based on the channels present in the neighbor report,
1696 it generates channel list which will be used in REPORT_SCAN state to
1697 scan for these neighbor APs
1698
1699 \param pMac - The handle returned by macOpen.
1700
1701 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1702
1703---------------------------------------------------------------------------*/
1704VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
1705{
1706 tpRrmNeighborReportDesc pNeighborBssDesc;
1707 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1708 tANI_U8 numChannels = 0, i = 0, j=0;
1709 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1710
1711 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
1712 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
1713
1714 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
1715
1716 while (pNeighborBssDesc)
1717 {
1718 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
1719
1720 /* Update the neighbor BSS Info in the 11r FT Roam Info */
1721 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
1722 pNeighborBssDesc->pNeighborBssDescription->channel;
1723 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
1724 (tANI_U8)pNeighborBssDesc->roamScore;
1725 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
1726 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
1727 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
1728
1729 /* Saving the channel list non-redundantly */
1730 if (numChannels > 0)
1731 {
1732 for (i = 0; i < numChannels; i++)
1733 {
1734 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
1735 break;
1736 }
1737
1738 }
1739 if (i == numChannels)
1740 {
1741 if (pNeighborBssDesc->pNeighborBssDescription->channel)
1742 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001743 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1744 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1745 pNeighborBssDesc->pNeighborBssDescription->channel);
1746 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1747 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 }
1749 }
1750
1751 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
1752 }
1753
1754 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1755 {
1756 // Before we free the existing channel list for a safety net make sure
1757 // we have a union of the IAPP and the already existing list.
1758 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
1759 {
1760 for (j = 0; j < numChannels; j++)
1761 {
1762 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] == channelList[j])
1763 break;
1764 }
1765 if (j == numChannels)
1766 {
1767 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i])
1768 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1770 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1771 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1772 channelList[numChannels] =
1773 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1774 numChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 }
1776 }
1777 }
1778 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1779 }
1780
1781 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1782 /* Store the obtained channel list to the Neighbor Control data structure */
1783 if (numChannels)
1784 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
1785 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1786 {
1787 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1788 return VOS_STATUS_E_RESOURCES;
1789 }
1790
1791 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1792 channelList, (numChannels) * sizeof(tANI_U8));
1793 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
1794 if (numChannels)
1795 {
1796 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
1797 pNeighborRoamInfo->neighborRoamState);
1798 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
1799 }
1800 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1801 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1802
1803 return VOS_STATUS_SUCCESS;
1804}
1805
1806/* ---------------------------------------------------------------------------
1807
1808 \fn csrNeighborRoamRRMNeighborReportResult
1809
1810 \brief This function is the neighbor report callback that will be invoked by
1811 SME RRM on receiving a neighbor report or of neighbor report is not
1812 received after timeout. On receiving a valid report, it generates a
1813 channel list from the neighbor report and starts the
1814 neighbor scan timer
1815
1816 \param context - The handle returned by macOpen.
1817 vosStatus - Status of the callback(SUCCESS/FAILURE)
1818
1819 \return VOID
1820
1821---------------------------------------------------------------------------*/
1822void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
1823{
1824 tpAniSirGlobal pMac = PMAC_STRUCT(context);
1825 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1826 eHalStatus status = eHAL_STATUS_SUCCESS;
1827
1828 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
1829 switch (pNeighborRoamInfo->neighborRoamState)
1830 {
1831 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1832 /* Reset the report pending variable */
1833 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
1834 if (VOS_STATUS_SUCCESS == vosStatus)
1835 {
1836 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
1837 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
1838 if (VOS_STATUS_SUCCESS == vosStatus)
1839 {
1840 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
1841 }
1842
1843 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1844 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1845
1846 /* Now ready for neighbor scan based on the channel list created */
1847 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1848 what palTimerStart expects */
1849 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1850 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1851 eANI_BOOLEAN_FALSE);
1852 if (eHAL_STATUS_SUCCESS != status)
1853 {
1854 /* Timer start failed.. Should we ASSERT here??? */
1855 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
1856 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1857 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1858 return;
1859 }
1860 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1861 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
1862 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1863 }
1864 else
1865 {
1866 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
1867 reach the maxNeighborRetries or receiving a successful neighbor response */
1868 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
1869 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
1870 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
1871 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
1872 {
1873 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
1874 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1875 if (VOS_STATUS_SUCCESS != vosStatus)
1876 {
1877 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
1878 return;
1879 }
1880 /* We transitioned to different state now. Reset the Neighbor report retry count */
1881 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1882 }
1883 else
1884 {
1885 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1886 if (VOS_STATUS_SUCCESS != vosStatus)
1887 {
1888 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1889 return;
1890 }
1891 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1892 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1893 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1894 }
1895 }
1896 break;
1897 default:
1898 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
1899 break;
1900 }
1901 return;
1902}
1903#endif /* WLAN_FEATURE_VOWIFI_11R */
1904
1905
1906/* ---------------------------------------------------------------------------
1907
1908 \fn csrNeighborRoamTransitToCFGChanScan
1909
1910 \brief This function is called whenever there is a transition to CFG chan scan
1911 state from any state. It frees up the current channel list and allocates
1912 a new memory for the channels received from CFG item. It then starts the
1913 neighbor scan timer to perform the scan on each channel one by one
1914
1915 \param pMac - The handle returned by macOpen.
1916
1917 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1918
1919---------------------------------------------------------------------------*/
1920VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
1921{
1922 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1923 eHalStatus status = eHAL_STATUS_SUCCESS;
1924 int i = 0;
1925 int numOfChannels = 0;
1926 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1927
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001928 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07001929#ifdef FEATURE_WLAN_CCX
1930 ((pNeighborRoamInfo->isCCXAssoc) &&
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001931 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
Jeff Johnson295189b2012-06-20 16:38:30 -07001932 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
1933#endif // CCX
1934 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels == 0)
1935
1936 {
1937 smsLog(pMac, LOGW, FL("Falling back to CFG channel list"));
1938
1939
1940 /* Free up the channel list and allocate a new memory. This is because we dont know how much
1941 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
1942 result in memory corruption */
1943 if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1944 {
1945 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1946 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1947 }
1948 // Find the right subset of the cfg list based on the current band we are on.
1949 for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
1950 {
1951 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i])
1952 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1954 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1955 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
1956 channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
1957 numOfChannels++;
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 }
1959 }
1960
1961 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
1962 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1963 if (numOfChannels)
1964 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc(numOfChannels);
1965
1966 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1967 {
1968 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1969 return VOS_STATUS_E_RESOURCES;
1970 }
1971
1972 /* Since this is a legacy case, copy the channel list from CFG here */
1973 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1974 channelList, numOfChannels * sizeof(tANI_U8));
1975
1976 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
1977 {
1978 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG = %d\n",
1979 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1980 }
1981 }
1982
1983 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1984 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1985
1986 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1987 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1988 what palTimerStart expects */
1989 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1990 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1991 eANI_BOOLEAN_FALSE);
1992
1993 if (eHAL_STATUS_SUCCESS != status)
1994 {
1995 /* Timer start failed.. */
1996 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1997 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1998 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1999 return VOS_STATUS_E_FAILURE;
2000 }
2001
2002 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
2003 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
2004
2005 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
2006 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
2007
2008 return VOS_STATUS_SUCCESS;
2009}
2010
2011/* ---------------------------------------------------------------------------
2012
2013 \fn csrNeighborRoamNeighborLookupUpEvent
2014
2015 \brief This function is called as soon as TL indicates that the current AP's
2016 RSSI is better than the neighbor lookup threshold. Here, we transition to
2017 CONNECTED state and reset all the scan parameters
2018
2019 \param pMac - The handle returned by macOpen.
2020
2021 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2022
2023---------------------------------------------------------------------------*/
2024VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
2025{
2026 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2027 VOS_STATUS vosStatus;
2028
2029 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2030 /* Deregister the UP event now */
2031 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2032 WLANTL_HO_THRESHOLD_UP,
2033 csrNeighborRoamNeighborLookupUPCallback,
2034 VOS_MODULE_ID_SME);
2035
2036 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2037 {
2038 //err msg
2039 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
2040 }
2041
2042 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2043 /* Deregister the UP event now */
2044 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2045 WLANTL_HO_THRESHOLD_DOWN,
2046 csrNeighborRoamNeighborLookupDOWNCallback,
2047 VOS_MODULE_ID_SME);
2048
2049 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2050 {
2051 //err msg
2052 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
2053 }
2054
2055 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
2056 /* Deregister reassoc callback. */
2057 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
2058 WLANTL_HO_THRESHOLD_DOWN,
2059 csrNeighborRoamReassocIndCallback,
2060 VOS_MODULE_ID_SME);
2061
2062 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2063 {
2064 //err msg
2065 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
2066 }
2067
2068
2069 /* RSSI got better than the CFG neighbor lookup threshold. Reset the threshold to older value and set the increment multiplier to 0 */
2070 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2071
2072 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
2073
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 /* Recheck whether the below check is needed. */
2075 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2076 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
Jeff Johnsone7245742012-09-05 17:12:55 -07002077
2078 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2079 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2080
Jeff Johnson295189b2012-06-20 16:38:30 -07002081
2082 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2083 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2084 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2085 WLANTL_HO_THRESHOLD_DOWN,
2086 csrNeighborRoamNeighborLookupDOWNCallback,
2087 VOS_MODULE_ID_SME, pMac);
2088 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2089 {
2090 //err msg
2091 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2092 }
2093
2094
2095 return vosStatus;
2096}
2097
2098/* ---------------------------------------------------------------------------
2099
2100 \fn csrNeighborRoamNeighborLookupDownEvent
2101
2102 \brief This function is called as soon as TL indicates that the current AP's
2103 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2104 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2105 a non-11R association.
2106
2107 \param pMac - The handle returned by macOpen.
2108
2109 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2110
2111---------------------------------------------------------------------------*/
2112VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2113{
2114 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2115 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2116 eHalStatus status = eHAL_STATUS_SUCCESS;
2117
2118 switch (pNeighborRoamInfo->neighborRoamState)
2119 {
2120 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2121
2122 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2123 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2124 /* De-register Neighbor Lookup threshold callback with TL */
2125 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2126 WLANTL_HO_THRESHOLD_DOWN,
2127 csrNeighborRoamNeighborLookupDOWNCallback,
2128 VOS_MODULE_ID_SME);
2129
2130 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2131 {
2132 //err msg
2133 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), status);
2134 }
2135
2136
2137#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2138 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2139 {
2140
2141 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2142 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2143 if (VOS_STATUS_SUCCESS != vosStatus)
2144 {
2145 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2146 return vosStatus;
2147 }
2148 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2149 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2150 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2151 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2152 }
2153 else
2154#endif
2155 {
2156 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2157
2158 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2159 if (VOS_STATUS_SUCCESS != vosStatus)
2160 {
2161 return vosStatus;
2162 }
2163 }
2164 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2165 /* Register Neighbor Lookup threshold callback with TL for UP event now */
2166 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2167 WLANTL_HO_THRESHOLD_UP,
2168 csrNeighborRoamNeighborLookupUPCallback,
2169 VOS_MODULE_ID_SME, pMac);
2170 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2171 {
2172 //err msg
2173 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
2174 }
2175 break;
2176 default:
2177 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2178 break;
2179
2180 }
2181 return vosStatus;
2182}
2183
2184/* ---------------------------------------------------------------------------
2185
2186 \fn csrNeighborRoamNeighborLookupUPCallback
2187
2188 \brief This function is registered with TL to indicate whenever the RSSI
2189 gets better than the neighborLookup RSSI Threshold
2190
2191 \param pAdapter - VOS Context
2192 trafficStatus - UP/DOWN indication from TL
2193 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2194
2195 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2196
2197---------------------------------------------------------------------------*/
2198VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2199 v_PVOID_t pUserCtxt)
2200{
2201 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2202 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2203 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2204
2205 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
2206
2207 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2208 {
2209 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2210 return VOS_STATUS_SUCCESS;
2211 }
2212
2213 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2214 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2215 return vosStatus;
2216}
2217
2218/* ---------------------------------------------------------------------------
2219
2220 \fn csrNeighborRoamNeighborLookupDOWNCallback
2221
2222 \brief This function is registered with TL to indicate whenever the RSSI
2223 falls below the current neighborLookup RSSI Threshold
2224
2225 \param pAdapter - VOS Context
2226 trafficStatus - UP/DOWN indication from TL
2227 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2228
2229 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2230
2231---------------------------------------------------------------------------*/
2232VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2233 v_PVOID_t pUserCtxt)
2234{
2235 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2236 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2237 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2238
2239 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
2240
2241 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2242 {
2243 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2244 return VOS_STATUS_SUCCESS;
2245 }
2246
2247 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2248 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2249
2250 return vosStatus;
2251}
2252
2253#ifdef RSSI_HACK
2254extern int dumpCmdRSSI;
2255#endif
2256
2257/* ---------------------------------------------------------------------------
2258
2259 \fn csrNeighborRoamIndicateDisconnect
2260
2261 \brief This function is called by CSR as soon as the station disconnects from
2262 the AP. This function does the necessary cleanup of neighbor roam data
2263 structures. Neighbor roam state transitions to INIT state whenever this
2264 function is called except if the current state is REASSOCIATING
2265
2266 \param pMac - The handle returned by macOpen.
2267 sessionId - CSR session id that got disconnected
2268
2269 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2270
2271---------------------------------------------------------------------------*/
2272eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2273{
2274 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2275
2276 smsLog(pMac, LOGE, FL("Disconnect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2277
2278#ifdef FEATURE_WLAN_CCX
2279 {
2280 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2281 if (pSession->connectedProfile.isCCXAssoc)
2282 {
2283 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2284 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2285 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2286 pSession->isPrevApInfoValid = TRUE;
2287 pSession->roamTS1 = vos_timer_get_system_time();
2288
2289 }
2290 }
2291#endif
2292
2293#ifdef RSSI_HACK
2294 dumpCmdRSSI = -40;
2295#endif
2296 switch (pNeighborRoamInfo->neighborRoamState)
2297 {
2298 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2299 // Stop scan and neighbor refresh timers.
2300 // These are indeed not required when we are in reassociating
2301 // state.
2302 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2303 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2304 break;
2305
2306 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2307 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Ignoring disconnect event in INIT state"));
2308 csrNeighborRoamResetInitStateControlInfo(pMac);
2309 break;
2310
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002311 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2312 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2313 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2314 csrNeighborRoamResetReportScanStateControlInfo(pMac);
2315 break;
2316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 default:
2318 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2319 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Transitioning to INIT state"));
2320 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
Madan Mohan Koyyalamudi4f292df2012-09-18 17:27:40 -07002321 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 }
2323 return eHAL_STATUS_SUCCESS;
2324}
2325
2326/* ---------------------------------------------------------------------------
2327
2328 \fn csrNeighborRoamIndicateConnect
2329
2330 \brief This function is called by CSR as soon as the station connects to an AP.
2331 This initializes all the necessary data structures related to the
2332 associated AP and transitions the state to CONNECTED state
2333
2334 \param pMac - The handle returned by macOpen.
2335 sessionId - CSR session id that got connected
2336 vosStatus - connect status SUCCESS/FAILURE
2337
2338 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2339
2340---------------------------------------------------------------------------*/
2341eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2342{
2343 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2344 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -07002345 VOS_STATUS vstatus;
2346
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002347#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002348 int init_ft_flag = FALSE;
2349#endif
2350
2351 smsLog(pMac, LOGE, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2352
2353 switch (pNeighborRoamInfo->neighborRoamState)
2354 {
2355 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2356 if (VOS_STATUS_SUCCESS != vosStatus)
2357 {
2358 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2359 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2360 break;
2361 }
2362 /* Fall through if the status is SUCCESS */
2363 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2364 /* Reset all the data structures here */
2365 csrNeighborRoamResetInitStateControlInfo(pMac);
2366
2367 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2368
2369 pNeighborRoamInfo->csrSessionId = sessionId;
2370 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2371 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2372 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2373 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2374 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
2375
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002376#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002377 /* Now we can clear the preauthDone that was saved as we are connected afresh */
2378 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2379#endif
2380
2381#ifdef WLAN_FEATURE_VOWIFI_11R
2382 // Based on the auth scheme tell if we are 11r
2383 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType ) )
2384 {
2385 if (pMac->roam.configParam.isFastTransitionEnabled)
2386 init_ft_flag = TRUE;
2387 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
2388 }
2389 else
2390 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
2391 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
2392#endif
2393
2394#ifdef FEATURE_WLAN_CCX
2395 // Based on the auth scheme tell if we are 11r
2396 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
2397 {
2398 if (pMac->roam.configParam.isFastTransitionEnabled)
2399 init_ft_flag = TRUE;
2400 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
2401 }
2402 else
2403 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
2404 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("isCCXAssoc is = %d"), pNeighborRoamInfo->isCCXAssoc);
2405 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
2406 "ccx=%d ft=%d\n", pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
2407
2408#endif
2409
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002410#ifdef FEATURE_WLAN_LFR
2411 // If "Legacy Fast Roaming" is enabled
2412 if (csrRoamIsFastRoamEnabled(pMac))
2413 {
2414 init_ft_flag = TRUE;
2415 }
2416#endif
2417
2418#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07002419 if ( init_ft_flag == TRUE )
2420 {
2421 /* Initialize all the data structures needed for the 11r FT Preauth */
2422 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
2423 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
2424 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2425 csrNeighborRoamPurgePreauthFailedList(pMac);
2426
2427 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
2428 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
Jeff Johnson43971f52012-07-17 12:26:56 -07002429 vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
Jeff Johnson295189b2012-06-20 16:38:30 -07002430 WLANTL_HO_THRESHOLD_DOWN,
2431 csrNeighborRoamNeighborLookupDOWNCallback,
2432 VOS_MODULE_ID_SME, pMac);
2433
Jeff Johnson43971f52012-07-17 12:26:56 -07002434 if(!VOS_IS_STATUS_SUCCESS(vstatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 {
2436 //err msg
Jeff Johnson43971f52012-07-17 12:26:56 -07002437 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vstatus);
2438 status = eHAL_STATUS_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002439 }
2440 }
2441#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 break;
2443 default:
2444 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2445 break;
2446 }
2447 return status;
2448}
2449
2450
2451#ifdef WLAN_FEATURE_VOWIFI_11R
2452/* ---------------------------------------------------------------------------
2453
2454 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
2455
2456 \brief If this function is invoked, that means the preauthentication response
2457 is timed out from the PE. Preauth rsp handler is called with status as
2458 TIMEOUT
2459
2460 \param context - CSR Timer info which holds pMac and session ID
2461
2462 \return VOID
2463
2464---------------------------------------------------------------------------*/
2465void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
2466{
2467 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
2468 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
2469 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2470
2471 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
2472
2473 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
2474}
2475
2476/* ---------------------------------------------------------------------------
2477
2478 \fn csrNeighborRoamPurgePreauthFailedList
2479
2480 \brief This function purges all the MAC addresses in the pre-auth fail list
2481
2482 \param pMac - The handle returned by macOpen.
2483
2484 \return VOID
2485
2486---------------------------------------------------------------------------*/
2487void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
2488{
2489 tANI_U8 i;
2490
2491 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
2492 {
2493 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
2494 }
2495 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
2496
2497 return;
2498}
2499
2500/* ---------------------------------------------------------------------------
2501
2502 \fn csrNeighborRoamInit11rAssocInfo
2503
2504 \brief This function initializes 11r related neighbor roam data structures
2505
2506 \param pMac - The handle returned by macOpen.
2507
2508 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2509
2510---------------------------------------------------------------------------*/
2511eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
2512{
2513 eHalStatus status;
2514 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
2515
2516 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
2517 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
2518 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
2519 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
2520 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
2521 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
2522
2523 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
2524 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2525 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
2526 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
2527
2528 if (eHAL_STATUS_SUCCESS != status)
2529 {
2530 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2531 return eHAL_STATUS_RESOURCES;
2532 }
2533
2534 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2535 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2536 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2537 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2538
2539
2540 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
2541 if (eHAL_STATUS_SUCCESS != status)
2542 {
2543 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
2544 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
2545 return eHAL_STATUS_RESOURCES;
2546 }
2547 return status;
2548}
2549#endif /* WLAN_FEATURE_VOWIFI_11R */
2550
2551/* ---------------------------------------------------------------------------
2552
2553 \fn csrNeighborRoamInit
2554
2555 \brief This function initializes neighbor roam data structures
2556
2557 \param pMac - The handle returned by macOpen.
2558
2559 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2560
2561---------------------------------------------------------------------------*/
2562eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
2563{
2564 eHalStatus status;
2565 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2566
2567 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2568 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2569 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
2570 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
2571 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
2572 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
2573 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
2574 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
2575 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
2576 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
2577
2578 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
2579 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
2580
2581 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
2582 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2583
2584 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2585 {
2586 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
2587 return eHAL_STATUS_RESOURCES;
2588 }
2589
2590 /* Update the roam global structure from CFG */
2591 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2592 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
2593 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2594
2595 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
2596 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
2597 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2598 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
2599
2600 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2601 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2602 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
2603 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2604
2605 if (eHAL_STATUS_SUCCESS != status)
2606 {
2607 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2608 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2609 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2610 return eHAL_STATUS_RESOURCES;
2611 }
2612
2613 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
2614 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2615
2616 if (eHAL_STATUS_SUCCESS != status)
2617 {
2618 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2619 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2620 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2621 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2622 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2623 return eHAL_STATUS_RESOURCES;
2624 }
2625
2626 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
2627 if (eHAL_STATUS_SUCCESS != status)
2628 {
2629 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2630 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2631 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2632 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2633 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2634 return eHAL_STATUS_RESOURCES;
2635 }
2636
2637 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2638 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2639 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2640 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2641 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2642
2643#ifdef WLAN_FEATURE_VOWIFI_11R
2644 status = csrNeighborRoamInit11rAssocInfo(pMac);
2645 if (eHAL_STATUS_SUCCESS != status)
2646 {
2647 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2648 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2649 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2650 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2651 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2652 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2653 return eHAL_STATUS_RESOURCES;
2654 }
2655#endif
2656 /* Initialize this with the current tick count */
2657 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2658
2659 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2660
2661 return eHAL_STATUS_SUCCESS;
2662}
2663
2664/* ---------------------------------------------------------------------------
2665
2666 \fn csrNeighborRoamClose
2667
2668 \brief This function closes/frees all the neighbor roam data structures
2669
2670 \param pMac - The handle returned by macOpen.
2671
2672 \return VOID
2673
2674---------------------------------------------------------------------------*/
2675void csrNeighborRoamClose(tpAniSirGlobal pMac)
2676{
2677 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2678
2679 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
2680 {
2681 smsLog(pMac, LOGE, FL("Neighbor Roam Algorithm Already Closed\n"));
2682 return;
2683 }
2684
2685 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2686 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2687
2688 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2689
2690 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
2691 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2692 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2693 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2694
2695 /* Should free up the nodes in the list before closing the double Linked list */
2696 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
2697 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2698
2699 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2700 {
2701 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2702 }
2703
2704 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2705 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2706 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2707 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2708 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2709 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2710
2711 /* Free the profile.. */
2712 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2713
2714#ifdef WLAN_FEATURE_VOWIFI_11R
2715 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2716 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
2717 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
2718 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2719 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2720 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2721 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2722 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2723 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2724#endif /* WLAN_FEATURE_VOWIFI_11R */
2725
2726 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
2727
2728 return;
2729}
2730
2731/* ---------------------------------------------------------------------------
2732
2733 \fn csrNeighborRoamRequestHandoff
2734
2735 \brief This function triggers actual switching from one AP to the new AP.
2736 It issues disassociate with reason code as Handoff and CSR as a part of
2737 handling disassoc rsp, issues reassociate to the new AP
2738
2739 \param pMac - The handle returned by macOpen.
2740
2741 \return VOID
2742
2743---------------------------------------------------------------------------*/
2744void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
2745{
2746
2747 tCsrRoamInfo roamInfo;
2748 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2749 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
2750 tCsrNeighborRoamBSSInfo handoffNode;
2751 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
2752 tANI_U32 roamId = 0;
2753
2754 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
2755 {
2756 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
2757 pMac->roam.neighborRoamInfo.neighborRoamState);
2758 return;
2759 }
2760
2761 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2762 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
2763 eSIR_SME_SUCCESS);
2764
2765 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2766 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
2767
2768 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
2769 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
2770 handoffNode.pBssDescription->bssId[0],
2771 handoffNode.pBssDescription->bssId[1],
2772 handoffNode.pBssDescription->bssId[2],
2773 handoffNode.pBssDescription->bssId[3],
2774 handoffNode.pBssDescription->bssId[4],
2775 handoffNode.pBssDescription->bssId[5]);
2776
2777 /* Free the profile.. Just to make sure we dont leak memory here */
2778 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2779 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
2780 This should happen before issuing disconnect */
2781 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
2782 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
2783 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
2784
2785 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
2786
2787 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
2788 {
2789 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
2790 return;
2791 }
2792
2793 //notify HDD for handoff, providing the BSSID too
2794 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
2795
2796 vos_mem_copy(roamInfo.bssid,
2797 handoffNode.pBssDescription->bssId,
2798 sizeof( tCsrBssid ));
2799
2800 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
2801
2802
2803 return;
2804}
2805
2806/* ---------------------------------------------------------------------------
2807
2808 \fn csrNeighborRoamIsHandoffInProgress
2809
2810 \brief This function returns whether handoff is in progress or not based on
2811 the current neighbor roam state
2812
2813 \param pMac - The handle returned by macOpen.
2814 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
2815
2816 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
2817
2818---------------------------------------------------------------------------*/
2819tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
2820{
2821 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
2822 return eANI_BOOLEAN_TRUE;
2823
2824 return eANI_BOOLEAN_FALSE;
2825}
2826
2827#ifdef WLAN_FEATURE_VOWIFI_11R
2828/* ---------------------------------------------------------------------------
2829
2830 \fn csrNeighborRoamIs11rAssoc
2831
2832 \brief This function returns whether the current association is a 11r assoc or not
2833
2834 \param pMac - The handle returned by macOpen.
2835
2836 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
2837
2838---------------------------------------------------------------------------*/
2839tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
2840{
2841 return pMac->roam.neighborRoamInfo.is11rAssoc;
2842}
2843#endif /* WLAN_FEATURE_VOWIFI_11R */
2844
2845
2846/* ---------------------------------------------------------------------------
2847
2848 \fn csrNeighborRoamGetHandoffAPInfo
2849
2850 \brief This function returns the best possible AP for handoff. For 11R case, it
2851 returns the 1st entry from pre-auth done list. For non-11r case, it returns
2852 the 1st entry from roamable AP list
2853
2854 \param pMac - The handle returned by macOpen.
2855 pHandoffNode - AP node that is the handoff candidate returned
2856
2857 \return VOID
2858
2859---------------------------------------------------------------------------*/
2860void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
2861{
2862 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2863 tpCsrNeighborRoamBSSInfo pBssNode;
2864
2865 VOS_ASSERT(NULL != pHandoffNode);
2866
2867#ifdef WLAN_FEATURE_VOWIFI_11R
2868 if (pNeighborRoamInfo->is11rAssoc)
2869 {
2870 /* Always the BSS info in the head is the handoff candidate */
2871 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2872 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2873 }
2874 else
2875#endif
2876#ifdef FEATURE_WLAN_CCX
2877 if (pNeighborRoamInfo->isCCXAssoc)
2878 {
2879 /* Always the BSS info in the head is the handoff candidate */
2880 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2881 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2882 }
2883 else
2884#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002885#ifdef FEATURE_WLAN_LFR
2886 if (csrRoamIsFastRoamEnabled(pMac))
2887 {
2888 /* Always the BSS info in the head is the handoff candidate */
2889 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2890 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2891 }
2892 else
2893#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 {
2895 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
2896 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
2897 }
2898 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
2899
2900 return;
2901}
2902
2903/* ---------------------------------------------------------------------------
2904 \brief This function returns TRUE if preauth is completed
2905
2906 \param pMac - The handle returned by macOpen.
2907
2908 \return boolean
2909
2910---------------------------------------------------------------------------*/
2911tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
2912{
2913 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
2914 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
2915}
2916
2917/* ---------------------------------------------------------------------------
2918 \brief In the event that we are associated with AP1 and we have
2919 completed pre auth with AP2. Then we receive a deauth/disassoc from
2920 AP1.
2921 At this point neighbor roam is in pre auth done state, pre auth timer
2922 is running. We now handle this case by stopping timer and clearing
2923 the pre-auth state. We basically clear up and just go to disconnected
2924 state.
2925
2926 \param pMac - The handle returned by macOpen.
2927
2928 \return boolean
2929---------------------------------------------------------------------------*/
2930void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
2931{
2932 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
2933 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
2934
2935 // Stop timer
2936 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
2937
2938 // Transition to init state
2939 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2940}
2941
2942#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */