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