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