blob: cd44ce54f769e8ff797a7a60a1d960ff5ee24784 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
Jeff Johnson295189b2012-06-20 16:38:30 -070042/**=========================================================================
43
44 \file sme_Rrm.c
45
46 \brief implementation for SME RRM APIs
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/* $Header$ */
55
56#if defined WLAN_FEATURE_VOWIFI
57/*--------------------------------------------------------------------------
58 Include Files
59 ------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -070060#include "aniGlobal.h"
61#include "smeInside.h"
62#include "sme_Api.h"
63#include "smsDebug.h"
64#include "cfgApi.h"
65
66#ifdef FEATURE_WLAN_DIAG_SUPPORT
67#include "vos_diag_core_event.h"
68#include "vos_diag_core_log.h"
69#endif /* FEATURE_WLAN_DIAG_SUPPORT */
70
71#include "csrInsideApi.h"
72
73#include "rrmGlobal.h"
74
75#ifdef FEATURE_WLAN_CCX
76#include "csrCcx.h"
77#endif
78
79/* Roam score for a neighbor AP will be calculated based on the below definitions.
80 The calculated roam score will be used to select the roamable candidate from neighbor AP list */
81#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY 0 /* When we support 11r over the DS, this should have a non-zero value */
82#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY 10
83#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE 20
84#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0 /* Not used */
85#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS 5
86#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD 3
87#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM 8
88#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA 0 /* We dont support delayed BA */
89#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA 3
90#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN 30
91
92#ifdef FEATURE_WLAN_CCX
93#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST 30
94#endif
95/**---------------------------------------------------------------------------
96
97 \brief rrmLLPurgeNeighborCache() -
98 This function purges all the entries in the neighbor cache and frees up all the internal nodes
99
100 \param - pMac - Pointer to the Hal Handle.
101 - pList - Pointer the List that should be purged.
102 \return - void
103
104 --------------------------------------------------------------------------*/
105static void rrmLLPurgeNeighborCache(tpAniSirGlobal pMac, tDblLinkList *pList)
106{
107 tListElem *pEntry;
108 tRrmNeighborReportDesc *pNeighborReportDesc;
109
110 csrLLLock(pList);
111
112 while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL)
113 {
114 pNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
115 vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
116 vos_mem_free(pNeighborReportDesc);
117 }
118
119 csrLLUnlock(pList);
120
121 return;
122}
123
124/**---------------------------------------------------------------------------
125
126 \brief rrmIndicateNeighborReportResult() -
127 This function calls the callback register by the caller while requesting for
128 neighbor report. This function gets invoked if a neighbor report is received from an AP
129 or neighbor response wait timer expires.
130
131 \param - pMac - Pointer to the Hal Handle.
132 - vosStatus - VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE based on whether a valid report is
133 received or neighbor timer expired
134 \return - void
135
136 --------------------------------------------------------------------------*/
137void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
138{
139 NeighborReportRspCallback callback;
140 void *callbackContext;
141
142 /* Reset the neighbor response pending status */
143 pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;
144
145 /* Stop the timer if it is already running. The timer should be running only in the SUCCESS case. */
146 if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer))
147 {
148 VOS_ASSERT(VOS_STATUS_SUCCESS == vosStatus);
149 vos_timer_stop(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer);
150 }
151 callback = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback;
152 callbackContext = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext;
153
154 /* Reset the callback and the callback context before calling the callback. It is very likely that there may be a registration in
155 callback itself. */
156 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = NULL;
157 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = NULL;
158
159 /* Call the callback with the status received from caller */
160 if (callback)
161 callback(callbackContext, vosStatus);
162#ifdef FEATURE_WLAN_CCX
163 // We came here with IAPP AP List
164 // Make sure we inform CSR of the neighbor list
165 // for CCX Associations. First clear the cache.
166 else
167 if (csrNeighborRoamIsCCXAssoc(pMac))
168 {
169 ProcessIAPPNeighborAPList(pMac);
170 }
171#endif
172
173 return;
174
175}
176
177/**---------------------------------------------------------------------------
178
179 \brief sme_RrmBeaconReportXmitInd() -
180
181 Create and send the beacon report Xmit ind message to PE.
182
183 \param - pMac - Pointer to the Hal Handle.
184 - pResult - scan result.
185 - measurementDone - flag to indicate that the measurement is done.
186 \return - 0 for success, non zero for failure
187
188 --------------------------------------------------------------------------*/
189static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, tCsrScanResultInfo **pResultArr, tANI_U8 measurementDone )
190{
191 tpSirBssDescription pBssDesc = NULL;
192 tpSirBeaconReportXmitInd pBeaconRep;
193 tANI_U16 length, ie_len;
194 tANI_U8 bssCounter=0, msgCounter=0;
195 tCsrScanResultInfo *pCurResult=NULL;
196 eHalStatus status = eHAL_STATUS_FAILURE;
197 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
198
199
200#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800201 smsLog( pMac, LOGE, "Beacon report xmit Ind to PE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700202#endif
203
204 if( NULL == pResultArr && !measurementDone )
205 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800206 smsLog( pMac, LOGE, "Beacon report xmit Ind to PE Failed");
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 return eHAL_STATUS_FAILURE;
208 }
209
210 if (pResultArr)
211 pCurResult=pResultArr[bssCounter];
212
213 do
214 {
215 length = sizeof(tSirBeaconReportXmitInd);
216 pBeaconRep = vos_mem_malloc ( length );
217 if ( NULL == pBeaconRep )
218 {
219 smsLog( pMac, LOGP, "Unable to allocate memory for beacon report");
220 return eHAL_STATUS_FAILED_ALLOC;
221 }
222 vos_mem_zero( pBeaconRep, length );
223#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800224 smsLog( pMac, LOGE, FL("Allocated memory for pBeaconRep"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700225#endif
226 pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
227 pBeaconRep->length = length;
228 pBeaconRep->uDialogToken = pSmeRrmContext->token;
229 pBeaconRep->duration = pSmeRrmContext->duration;
230 pBeaconRep->regClass = pSmeRrmContext->regClass;
231 vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) );
232
233 msgCounter=0;
234 while (pCurResult)
235 {
236 pBssDesc = &pCurResult->BssDescriptor;
237 ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length );
238 pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( ie_len+sizeof(tSirBssDescription) );
Jeff Johnson0282cf02013-04-03 17:30:03 -0700239 if (NULL == pBeaconRep->pBssDescription[msgCounter])
240 break;
Jeff Johnson295189b2012-06-20 16:38:30 -0700241 vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], pBssDesc, sizeof(tSirBssDescription) );
242 vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0], pBssDesc->ieFields, ie_len );
243
244 pBeaconRep->numBssDesc++;
245
246 if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
247 break;
248
249 if (csrRoamIs11rAssoc(pMac)) {
250 break;
251 }
252
253 pCurResult = pResultArr[msgCounter];
254 }
255
256 bssCounter+=msgCounter;
257 if (!pResultArr || !pCurResult || (bssCounter>=SIR_BCN_REPORT_MAX_BSS_DESC))
258 pCurResult = NULL;
259 else
260 pCurResult = pResultArr[bssCounter];
261
262 pBeaconRep->fMeasureDone = (pCurResult)?false:measurementDone;
263
Jeff Johnson0282cf02013-04-03 17:30:03 -0700264 smsLog(pMac, LOGW, "SME Sending BcnRepXmit to PE numBss %d",
265 pBeaconRep->numBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
Jeff Johnson0282cf02013-04-03 17:30:03 -0700267 status = palSendMBMessage(pMac->hHdd, pBeaconRep);
Jeff Johnson295189b2012-06-20 16:38:30 -0700268
269 } while (pCurResult);
270
271 return status;
272}
273
274/**---------------------------------------------------------------------------
275
276 \brief sme_RrmSendScanRequest() -
277
278 This function is called to get the scan result from CSR and send the beacon report
279 xmit ind message to PE.
280
281 \param - pMac - Pointer to the Hal Handle.
282 - num_chan - number of channels.
283 - channel list - list of channels to fetch the result from.
284 - measurementDone - flag to indicate that the measurement is done.
285 \return - 0 for success, non zero for failure
286
287 --------------------------------------------------------------------------*/
288static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan, tANI_U8* chanList, tANI_U8 measurementDone )
289{
290 tCsrScanResultFilter filter;
291 tScanResultHandle pResult;
292 tCsrScanResultInfo *pScanResult, *pNextResult;
293 tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC];
294 eHalStatus status;
295 tANI_U8 counter=0;
296 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
297 tANI_U32 sessionId;
298
299#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800300 smsLog( pMac, LOGE, "Send scan result to PE ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700301#endif
302
303 vos_mem_zero( &filter, sizeof(filter) );
304 vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC );
305
306 filter.BSSIDs.numOfBSSIDs = 1;
307 filter.BSSIDs.bssid = &pSmeRrmContext->bssId;
308
309 if( pSmeRrmContext->ssId.length )
310 {
311 filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
312 if( filter.SSIDs.SSIDList == NULL )
313 {
314 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
315 return eHAL_STATUS_FAILURE;
316 }
317#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800318 smsLog( pMac, LOGE, FL("Allocated memory for SSIDList"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700319#endif
320 vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
321
322 filter.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
323 vos_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
324 filter.SSIDs.numOfSSIDs = 1;
325 }
326 else
327 {
328 filter.SSIDs.numOfSSIDs = 0;
329 }
330
331 filter.ChannelInfo.numOfChannels = num_chan;
332 filter.ChannelInfo.ChannelList = chanList;
333
334 filter.fMeasurement = TRUE;
335
336 csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
337 status = sme_ScanGetResult(pMac, (tANI_U8)sessionId, &filter, &pResult);
338
339 if( filter.SSIDs.SSIDList )
340 {
341 //Free the memory allocated for SSIDList.
342 vos_mem_free( filter.SSIDs.SSIDList );
343#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800344 smsLog( pMac, LOGE, FL("Free memory for SSIDList") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700345#endif
346 }
347
348 if (NULL == pResult)
349 {
350 // no scan results
351 //
352 // Spec. doesnt say anything about such condition.
353 // Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report frame should contain
354 // one or more report IEs. It probably means dont send any respose if no matching
355 // BSS found. Moreover, there is no flag or field in measurement report IE(7.3.2.22)
356 // OR beacon report IE(7.3.2.22.6) that can be set to indicate no BSS found on a given channel.
357 //
358 // If we finished measurement on all the channels, we still need to
359 // send a xmit indication with moreToFollow set to MEASURMENT_DONE
360 // so that PE can clean any context allocated.
361 if( measurementDone )
362 status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone );
363 return status;
364 }
365
366 pScanResult = sme_ScanResultGetFirst(pMac, pResult);
367
368 if( NULL == pScanResult && measurementDone )
369 status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone );
370
371 counter=0;
372 while (pScanResult)
373 {
374 pNextResult = sme_ScanResultGetNext(pMac, pResult);
375 pScanResultsArr[counter++] = pScanResult;
376 pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult);
377 if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC)
378 break;
379 }
380
381 if (counter)
382 status = sme_RrmSendBeaconReportXmitInd( pMac, pScanResultsArr, measurementDone);
383
384 sme_ScanResultPurge(pMac, pResult);
385
386 return status;
387}
388/**---------------------------------------------------------------------------
389
390 \brief sme_RrmScanRequestCallback() -
391
392 The sme module calls this callback function once it finish the scan request
393 and this function send the beacon report xmit to PE and starts a timer of
394 random interval to issue next request.
395
396 \param - halHandle - Pointer to the Hal Handle.
397 - pContext - Pointer to the data context.
398 - scanId - Scan ID.
399 - status - CSR Status.
400 \return - 0 for success, non zero for failure
401
402 --------------------------------------------------------------------------*/
403
404static eHalStatus sme_RrmScanRequestCallback(tHalHandle halHandle, void *pContext,
405 tANI_U32 scanId, eCsrScanStatus status)
406{
407
408 tANI_U16 interval;
409 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
410 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
411 tANI_U32 time_tick;
412
413
414
415#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800416 smsLog( pMac, LOGE, "Scan Request callback ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700417#endif
418 //if any more channels are pending, start a timer of a random value within randomization interval.
419 //
420 //
421 if( (pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels )
422 {
423 sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false );
424
425 pSmeRrmContext->currentIndex++; //Advance the current index.
426 //start the timer to issue next request.
427 //From timer tick get a random number within 10ms and max randmization interval.
428 time_tick = vos_timer_get_system_ticks();
429 interval = time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10;
430
431#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800432 smsLog( pMac, LOGE, "Set timer for interval %d ", interval);
Jeff Johnson295189b2012-06-20 16:38:30 -0700433#endif
434 vos_timer_start( &pSmeRrmContext->IterMeasTimer, interval );
435
436 }
437 else
438 {
439 //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set.
440 sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true );
441 vos_mem_free( pSmeRrmContext->channelList.ChannelList );
442#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800443 smsLog( pMac, LOGE, FL("Free memory for ChannelList") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700444#endif
445 }
446
447 return eHAL_STATUS_SUCCESS;
448}
449
450/*--------------------------------------------------------------------------
451 \brief sme_RrmIssueScanReq() - This is called to send a scan request as part
452 of beacon report request .
453
454 \param
455
456 \return eHAL_STATUS_SUCCESS - Validation is successful.
457
458 \sa
459
460 --------------------------------------------------------------------------*/
461eHalStatus sme_RrmIssueScanReq( tpAniSirGlobal pMac )
462{
463 //Issue scan request.
464 tCsrScanRequest scanRequest;
465 v_U32_t scanId = 0;
466 eHalStatus status = eHAL_STATUS_SUCCESS;
467 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
468 tANI_U32 sessionId;
469
470#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800471 smsLog( pMac, LOGE, "Issue scan request " );
Jeff Johnson295189b2012-06-20 16:38:30 -0700472#endif
473
474 vos_mem_zero( &scanRequest, sizeof(scanRequest));
475
476 /* set scanType, active or passive */
477
478 scanRequest.scanType = pSmeRrmContext->measMode;
479
480 vos_mem_copy(scanRequest.bssid,
481 pSmeRrmContext->bssId, sizeof(scanRequest.bssid) );
482
483 if( pSmeRrmContext->ssId.length )
484 {
485 scanRequest.SSIDs.numOfSSIDs = 1;
486 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
487 if( scanRequest.SSIDs.SSIDList == NULL )
488 {
489 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
490 return eHAL_STATUS_FAILURE;
491 }
492#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800493 smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700494#endif
495 vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
496 scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
497 vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
498 }
499
500 /* set min and max channel time */
501 scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout.
502 scanRequest.maxChnTime = pSmeRrmContext->duration;
503#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800504 smsLog( pMac, LOGE, "For Duration %d ", pSmeRrmContext->duration );
Jeff Johnson295189b2012-06-20 16:38:30 -0700505#endif
506
507 /* set BSSType to default type */
508 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
509
510 /*Scan all the channels */
511 scanRequest.ChannelInfo.numOfChannels = 1;
512
513 scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex];
514#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800515 smsLog( pMac, LOGE, "On channel %d ", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] );
Jeff Johnson295189b2012-06-20 16:38:30 -0700516#endif
517
518 /* set requestType to full scan */
519 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
520
521 csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
522 status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL );
523
524 if ( pSmeRrmContext->ssId.length )
525 {
526 vos_mem_free(scanRequest.SSIDs.SSIDList);
527#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800528 smsLog( pMac, LOGE, FL("Free memory for SSIDList"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700529#endif
530 }
531
532 return status;
533}
534
535/*--------------------------------------------------------------------------
536 \brief sme_RrmProcessBeaconReportReqInd() - This is called to process the Beacon
537 report request from peer AP forwarded through PE .
538
539 \param pMsgBuf - a pointer to a buffer that maps to various structures base
540 on the message type.
541 The beginning of the buffer can always map to tSirSmeRsp.
542
543 \return eHAL_STATUS_SUCCESS - Validation is successful.
544
545 \sa
546
547 --------------------------------------------------------------------------*/
548void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf)
549{
550 tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
551 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
552 tANI_U32 len,i;
553
554#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800555 smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d", pBeaconReq->channelInfo.channelNum );
Jeff Johnson295189b2012-06-20 16:38:30 -0700556#endif
557 //section 11.10.8.1 (IEEE Std 802.11k-2008)
558 //channel 0 and 255 has special meaning.
559 if( (pBeaconReq->channelInfo.channelNum == 0) ||
560 ((pBeaconReq->channelInfo.channelNum == 255) && (pBeaconReq->channelList.numChannels == 0) ) )
561 {
562 //Add all the channel in the regulatory domain.
563 wlan_cfgGetStrLen( pMac, WNI_CFG_VALID_CHANNEL_LIST, &len );
564 pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
565 if( pSmeRrmContext->channelList.ChannelList == NULL )
566 {
567 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
568 return;
569 }
570#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800571 smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700572#endif
573 csrGetCfgValidChannels( pMac, pSmeRrmContext->channelList.ChannelList, &len );
574 pSmeRrmContext->channelList.numOfChannels = (tANI_U8)len;
575#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800576 smsLog( pMac, LOGE, "channel == 0 performing on all channels");
Jeff Johnson295189b2012-06-20 16:38:30 -0700577#endif
578 }
579 else
580 {
581 len = 0;
582 pSmeRrmContext->channelList.numOfChannels = 0;
583
584 //If valid channel is present. We firt Measure on the given channel. and
585 //if there are additional channels present in APchannelreport, measure on these also.
586 if ( pBeaconReq->channelInfo.channelNum != 255 )
587 len = 1;
588#if defined WLAN_VOWIFI_DEBUG
589 else
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800590 smsLog( pMac, LOGE, "channel == 255");
Jeff Johnson295189b2012-06-20 16:38:30 -0700591#endif
592
593 len += pBeaconReq->channelList.numChannels;
594
595 pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
596 if( pSmeRrmContext->channelList.ChannelList == NULL )
597 {
598 smsLog( pMac, LOGP, FL("vos_mem_malloc failed") );
599 return;
600 }
601#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800602 smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700603#endif
604
605 if ( pBeaconReq->channelInfo.channelNum != 255 )
606 {
607#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800608 smsLog( pMac, LOGE, "channel == %d ", pBeaconReq->channelInfo.channelNum );
Jeff Johnson295189b2012-06-20 16:38:30 -0700609#endif
610 if(csrRoamIsChannelValid( pMac, pBeaconReq->channelInfo.channelNum ))
611 pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels++] = pBeaconReq->channelInfo.channelNum;
612#if defined WLAN_VOWIFI_DEBUG
613 else
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800614 smsLog( pMac, LOGE, "is Invalid channel, Ignoring this channel" );
Jeff Johnson295189b2012-06-20 16:38:30 -0700615#endif
616 }
617
618 for ( i = 0 ; i < pBeaconReq->channelList.numChannels; i++ )
619 {
620 if(csrRoamIsChannelValid( pMac, pBeaconReq->channelList.channelNumber[i] ))
621 {
622 pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels] = pBeaconReq->channelList.channelNumber[i];
623 pSmeRrmContext->channelList.numOfChannels++;
624 }
625 }
626 }
627
628 //Copy session bssid
629 vos_mem_copy( pSmeRrmContext->sessionBssId, pBeaconReq->bssId, sizeof(tSirMacAddr) );
630
631 //copy measurement bssid
632 vos_mem_copy( pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, sizeof(tSirMacAddr) );
633
634 //Copy ssid
635 vos_mem_copy( &pSmeRrmContext->ssId, &pBeaconReq->ssId, sizeof(tAniSSID) );
636
637 pSmeRrmContext->token = pBeaconReq->uDialogToken;
638 pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass;
639
640 switch( pBeaconReq->fMeasurementtype )
641 {
642 case 0: //Passive
643 case 1: //Active
644 pSmeRrmContext->measMode = pBeaconReq->fMeasurementtype? eSIR_ACTIVE_SCAN : eSIR_PASSIVE_SCAN ;
645 pSmeRrmContext->duration = pBeaconReq->measurementDuration;
646 pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval );
647 pSmeRrmContext->currentIndex = 0;
648#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800649 smsLog( pMac, LOGE, "Send beacon report after scan " );
Jeff Johnson295189b2012-06-20 16:38:30 -0700650#endif
651 sme_RrmIssueScanReq( pMac );
652 break;
653 case 2: //Table
654 //Get the current scan results for the given channel and send it.
655#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800656 smsLog( pMac, LOGE, "Send beacon report from table " );
Jeff Johnson295189b2012-06-20 16:38:30 -0700657#endif
658 sme_RrmSendScanResult( pMac, pSmeRrmContext->channelList.numOfChannels, pSmeRrmContext->channelList.ChannelList, true );
659 vos_mem_free( pSmeRrmContext->channelList.ChannelList );
660#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800661 smsLog( pMac, LOGE, FL("Free memory for ChannelList") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700662#endif
663 break;
664 default:
665#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800666 smsLog( pMac, LOGE, "Unknown beacon report request mode");
Jeff Johnson295189b2012-06-20 16:38:30 -0700667#endif
668 /* Indicate measurement completion to PE */
669 /* If this is not done, pCurrentReq pointer will not be freed and
670 PE will not handle subsequent Beacon requests */
671 sme_RrmSendBeaconReportXmitInd(pMac, NULL, true);
672 break;
673
674 }
675
676 return;
677}
678
679/*--------------------------------------------------------------------------
680 \brief sme_RrmNeighborReportRequest() - This is API can be used to trigger a
681 Neighbor report from the peer.
682
683 \param sessionId - session identifier on which the request should be made.
684 \param pNeighborReq - a pointer to a neighbor report request.
685
686 \return eHAL_STATUS_SUCCESS - Validation is successful.
687
688 \sa
689
690 --------------------------------------------------------------------------*/
691VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId,
692 tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo)
693{
694 eHalStatus status = eHAL_STATUS_SUCCESS;
695 tpSirNeighborReportReqInd pMsg;
696 tCsrRoamSession *pSession;
697
698#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800699 smsLog( pMac, LOGE, FL("Request to send Neighbor report request received "));
Jeff Johnson295189b2012-06-20 16:38:30 -0700700#endif
701 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
702 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800703 smsLog( pMac, LOGE, FL("Invalid session %d"), sessionId );
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 return VOS_STATUS_E_INVAL;
705 }
706 pSession = CSR_GET_SESSION( pMac, sessionId );
707
708 /* If already a report is pending, return failure */
709 if (eANI_BOOLEAN_TRUE == pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending)
710 {
711 smsLog( pMac, LOGE, FL("Neighbor request already pending.. Not allowed"));
712 return VOS_STATUS_E_AGAIN;
713 }
714
715 pMsg = vos_mem_malloc ( sizeof(tSirNeighborReportReqInd) );
716 if ( NULL == pMsg )
717 {
718 smsLog( pMac, LOGE, "Unable to allocate memory for Neighbor request");
719 return VOS_STATUS_E_NOMEM;
720 }
721
722
723 vos_mem_zero( pMsg, sizeof(tSirNeighborReportReqInd) );
724#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800725 smsLog( pMac, LOGE, FL(" Allocated memory for Neighbor request") );
Jeff Johnson295189b2012-06-20 16:38:30 -0700726#endif
727
728 rrmLLPurgeNeighborCache(pMac, &pMac->rrm.rrmSmeContext.neighborReportCache);
729
730#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800731 smsLog( pMac, LOGE, FL("Purged the neighbor cache before sending Neighbor request: Status = %d"), status );
Jeff Johnson295189b2012-06-20 16:38:30 -0700732#endif
733
734 pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND;
735 pMsg->length = sizeof( tSirNeighborReportReqInd );
736 vos_mem_copy( &pMsg->bssId, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
737 pMsg->noSSID = pNeighborReq->no_ssid;
738 vos_mem_copy( &pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid));
739
740 status = palSendMBMessage(pMac->hHdd, pMsg);
741 if( status != eHAL_STATUS_SUCCESS )
742 return VOS_STATUS_E_FAILURE;
743
744 /* Neighbor report request message sent successfully to PE. Now register the callbacks */
745 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback =
746 callbackInfo->neighborRspCallback;
747 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext =
748 callbackInfo->neighborRspCallbackContext;
749 pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_TRUE;
750
751 /* Start neighbor response wait timer now */
752 vos_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer, callbackInfo->timeout);
753
754 return VOS_STATUS_SUCCESS;
755}
756
757/*--------------------------------------------------------------------------
758 \brief rrmCalculateNeighborAPRoamScore() - This API is called while handling
759 individual neighbor reports from the APs neighbor AP report to
760 calculate the cumulative roam score before storing it in neighbor
761 cache.
762
763 \param pNeighborReportDesc - Neighbor BSS Descriptor node for which roam score
764 should be calculated
765
766 \return void.
767--------------------------------------------------------------------------*/
768static void rrmCalculateNeighborAPRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
769{
770 tpSirNeighborBssDescripton pNeighborBssDesc;
771 tANI_U32 roamScore = 0;
772
773 VOS_ASSERT(pNeighborReportDesc != NULL);
774 VOS_ASSERT(pNeighborReportDesc->pNeighborBssDescription != NULL);
775
776 pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription;
777
778 if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain)
779 {
780 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN;
781 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode)
782 {
783 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY;
784 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator)
785 {
786 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE;
787 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement)
788 {
789 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM;
790 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement)
791 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT;
792 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos)
793 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS;
794 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd)
795 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD;
796 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck)
797 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA;
798 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck)
799 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA;
800 if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable)
801 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY;
802 }
803 }
804 }
805 }
806#ifdef FEATURE_WLAN_CCX
807 // It has come in the report so its the best score
808 if (csrNeighborRoamIs11rAssoc(pMac) == FALSE)
809 {
810 // IAPP Route so lets make use of this info
811 // save all AP, as the list does not come all the time
812 // Save and reuse till the next AP List comes to us.
813 // Even save our own MAC address. Will be useful next time around.
814 roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST;
815 }
816#endif
817 pNeighborReportDesc->roamScore = roamScore;
818
819 return;
820}
821
822/*--------------------------------------------------------------------------
823 \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given
824 Neighbor BSS descriptor to the neighbor cache. This function
825 stores the neighbor BSS descriptors in such a way that descriptors
826 are sorted by roamScore in descending order
827
828 \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
829
830 \return void.
831--------------------------------------------------------------------------*/
832void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
833{
834 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
835 tListElem *pEntry;
836 tRrmNeighborReportDesc *pTempNeighborReportDesc;
837
838 VOS_ASSERT(pNeighborReportDesc != NULL);
839 VOS_ASSERT(pNeighborReportDesc->pNeighborBssDescription != NULL);
840
841 if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK))
842 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800843 smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 /* Neighbor list cache is empty. Insert this entry in the tail */
845 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
846 return;
847 }
848 else
849 {
850 /* Should store the neighbor BSS description in the order sorted by roamScore in descending
851 order. APs with highest roamScore should be the 1st entry in the list */
852 pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK);
853 while (pEntry != NULL)
854 {
855 pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
856 if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore)
857 break;
858 pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK);
859 }
860
861 if (pEntry)
862 /* This BSS roamscore is better than something in the list. Insert this before that one */
863 csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
864 else
865 /* All the entries in the list has a better roam Score than this one. Insert this at the last */
866 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
867 }
868 return;
869}
870
871/*--------------------------------------------------------------------------
872 \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor
873 report received from PE.
874
875 \param pMsgBuf - a pointer to a buffer that maps to various structures base
876 on the message type.
877 The beginning of the buffer can always map to tSirSmeRsp.
878
879 \return eHAL_STATUS_SUCCESS - Validation is successful.
880
881 \sa
882
883 --------------------------------------------------------------------------*/
884eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf)
885{
886 eHalStatus status = eHAL_STATUS_SUCCESS;
887 tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf;
888 tpRrmNeighborReportDesc pNeighborReportDesc;
889 tANI_U8 i = 0;
890 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
891
892#ifdef FEATURE_WLAN_CCX
893 // Clear the cache for CCX.
894 if (csrNeighborRoamIsCCXAssoc(pMac))
895 {
896 rrmLLPurgeNeighborCache(pMac,
897 &pMac->rrm.rrmSmeContext.neighborReportCache);
898 }
899#endif
900
901 for (i = 0; i < pNeighborRpt->numNeighborReports; i++)
902 {
903 pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc));
904 if (NULL == pNeighborReportDesc)
905 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800906 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc");
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 status = eHAL_STATUS_FAILED_ALLOC;
908 goto end;
909
910 }
911
912 vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc));
913 pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription));
914 if (NULL == pNeighborReportDesc->pNeighborBssDescription)
915 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800916 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description");
Jeff Johnsonfb82ea52013-04-03 15:35:49 -0700917 vos_mem_free(pNeighborReportDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700918 status = eHAL_STATUS_FAILED_ALLOC;
919 goto end;
920 }
921 vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription));
922 vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i],
923 sizeof(tSirNeighborBssDescription));
924
925#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800926 smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: %02x:%02x:%02x:%02x:%02x:%02x ",
Jeff Johnson295189b2012-06-20 16:38:30 -0700927 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
928 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
929 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
930 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
931 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
932 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
933#endif
934
935 /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */
936 rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc);
937
938 /* Store the Neighbor report Desc in the cache based on the roam score */
939 if ( pNeighborReportDesc->roamScore > 0)
940 {
941 rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc);
942 }
943 else
944 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800945 smsLog(pMac, LOGE, FL("Roam score of BSSID %02x:%02x:%02x:%02x:%02x:%02x is 0, Ignoring.."),
Jeff Johnson295189b2012-06-20 16:38:30 -0700946 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
947 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
948 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
949 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
950 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
951 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
952
953 vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
954 vos_mem_free(pNeighborReportDesc);
955 }
956 }
957end:
958
959 if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache))
960 vosStatus = VOS_STATUS_E_FAILURE;
961
962 /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */
963 rrmIndicateNeighborReportResult(pMac, vosStatus);
964
965 return status;
966}
967/*--------------------------------------------------------------------------
968 \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the
969 messages that are handled by SME RRM module.
970
971 \param pMac - Pointer to the global MAC parameter structure.
972 \param msg_type - the type of msg passed by PE as defined in wniApi.h
973 \param pMsgBuf - a pointer to a buffer that maps to various structures base
974 on the message type.
975 The beginning of the buffer can always map to tSirSmeRsp.
976
977 \return eHAL_STATUS_SUCCESS - Validation is successful.
978
979 \sa
980
981 --------------------------------------------------------------------------*/
982eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type,
983 void *pMsgBuf)
984{
985 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800986 FL(" Msg = %d for RRM measurement") , msg_type );
Jeff Johnson295189b2012-06-20 16:38:30 -0700987
988 //switch on the msg type & make the state transition accordingly
989 switch(msg_type)
990 {
991 case eWNI_SME_NEIGHBOR_REPORT_IND:
992 sme_RrmProcessNeighborReport( pMac, pMsgBuf );
993 break;
994
995 case eWNI_SME_BEACON_REPORT_REQ_IND:
996 sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf );
997 break;
998
999 default:
1000 //err msg
1001 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001002 FL("sme_RrmMsgProcessor:unknown msg type = %d"), msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001003
1004 break;
1005 }
1006
1007 return eHAL_STATUS_SUCCESS;
1008}
1009
1010/* ---------------------------------------------------------------------------
1011
1012 \fn rrmIterMeasTimerHandle
1013
1014 \brief Timer handler to handlet the timeout condition when a specific BT
1015
1016 stop event does not come back, in which case to restore back the
1017
1018 heartbeat timer.
1019
1020 \param pMac - The handle returned by macOpen.
1021
1022 \return VOID
1023
1024 ---------------------------------------------------------------------------*/
1025
1026void rrmIterMeasTimerHandle( v_PVOID_t userData )
1027{
1028 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1029#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001030 smsLog( pMac, LOGE, "Randomization timer expired...send on next channel ");
Jeff Johnson295189b2012-06-20 16:38:30 -07001031#endif
1032 //Issue a scan req for next channel.
1033 sme_RrmIssueScanReq( pMac );
1034}
1035
1036/* ---------------------------------------------------------------------------
1037
1038 \fn rrmNeighborRspTimeoutHandler
1039
1040 \brief Timer handler to handle the timeout condition when a neighbor request is sent
1041 and no neighbor response is received from the AP
1042
1043 \param pMac - The handle returned by macOpen.
1044
1045 \return VOID
1046
1047---------------------------------------------------------------------------*/
1048
1049void rrmNeighborRspTimeoutHandler
1050( v_PVOID_t userData )
1051{
1052 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1053#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001054 smsLog( pMac, LOGE, "Neighbor Response timed out ");
Jeff Johnson295189b2012-06-20 16:38:30 -07001055#endif
1056 rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE);
1057 return;
1058}
1059
1060/* ---------------------------------------------------------------------------
1061
1062 \fn rrmOpen
1063
1064 \brief
1065
1066 \param pMac - The handle returned by macOpen.
1067
1068 \return VOS_STATUS
1069
1070 VOS_STATUS_E_FAILURE success
1071
1072 VOS_STATUS_SUCCESS failure
1073
1074 ---------------------------------------------------------------------------*/
1075
1076VOS_STATUS rrmOpen (tpAniSirGlobal pMac)
1077
1078{
1079
1080 VOS_STATUS vosStatus;
1081 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1082 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
1083
1084 pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms
1085
1086 vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer,
1087
1088 VOS_TIMER_TYPE_SW,
1089
1090 rrmIterMeasTimerHandle,
1091
1092 (void*) pMac);
1093
1094 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1095
1096 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1097
1098 return VOS_STATUS_E_FAILURE;
1099 }
1100
1101 vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer,
1102
1103 VOS_TIMER_TYPE_SW,
1104
1105 rrmNeighborRspTimeoutHandler,
1106
1107 (void*) pMac);
1108
1109 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1110
1111 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1112
1113 return VOS_STATUS_E_FAILURE;
1114 }
1115
1116 pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;
1117
1118 halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache);
1119 if (eHAL_STATUS_SUCCESS != halStatus)
1120 {
1121 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result");
1122 return VOS_STATUS_E_FAILURE;
1123 }
1124
1125 return VOS_STATUS_SUCCESS;
1126}
1127
1128
1129/* ---------------------------------------------------------------------------
1130
1131 \fn rrmClose
1132
1133 \brief
1134
1135 \param pMac - The handle returned by macOpen.
1136
1137 \return VOS_STATUS
1138
1139 VOS_STATUS_E_FAILURE success
1140
1141 VOS_STATUS_SUCCESS failure
1142
1143 ---------------------------------------------------------------------------*/
1144
1145VOS_STATUS rrmClose (tpAniSirGlobal pMac)
1146
1147{
1148
1149 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1150 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1151
1152 if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) )
1153 {
1154 vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer );
1155 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001156 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001157 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") );
1158 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001159 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001160
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001161 vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer );
1162 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1163 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001164
1165 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") );
1166
1167 }
1168
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001169 if( VOS_TIMER_STATE_RUNNING ==
1170 vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) )
1171 {
1172 vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1173 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1174 {
1175 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") );
1176 }
1177 }
1178
1179 vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1180 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1181 {
1182 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") );
1183
1184 }
1185
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001187
Jeff Johnson295189b2012-06-20 16:38:30 -07001188 csrLLClose(&pSmeRrmContext->neighborReportCache);
1189
1190 return vosStatus;
1191
1192}
1193
1194
1195
1196
1197/* ---------------------------------------------------------------------------
1198
1199 \fn rrmReady
1200
1201 \brief fn
1202
1203 \param pMac - The handle returned by macOpen.
1204
1205 \return VOS_STATUS
1206
1207 ---------------------------------------------------------------------------*/
1208
1209VOS_STATUS rrmReady (tpAniSirGlobal pMac)
1210
1211{
1212
1213 return VOS_STATUS_SUCCESS;
1214}
1215
1216/* ---------------------------------------------------------------------------
1217
1218 \fn rrmChangeDefaultConfigParam
1219 \brief fn
1220
1221 \param pMac - The handle returned by macOpen.
1222 \param pRrmConfig - pointer to new rrm configs.
1223
1224 \return VOS_STATUS
1225
1226 ---------------------------------------------------------------------------*/
1227VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig)
1228{
1229 vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) );
1230
1231 return VOS_STATUS_SUCCESS;
1232}
1233
1234/* ---------------------------------------------------------------------------
1235
1236 \fn smeRrmGetFirstBssEntryFromNeighborCache()
1237
1238 \brief This function returns the first entry from the neighbor cache to the caller
1239
1240 \param pMac - The handle returned by macOpen.
1241
1242 \return VOID
1243
1244---------------------------------------------------------------------------*/
1245tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac)
1246{
1247 tListElem *pEntry;
1248 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1249 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1250
1251
1252 pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK );
1253
1254 if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache))
1255 {
1256 //list empty
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001257 smsLog(pMac, LOGW, FL("List empty"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001258 return NULL;
1259 }
1260
1261 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1262
1263 return pTempBssEntry;
1264}
1265
1266/* ---------------------------------------------------------------------------
1267
1268 \fn smeRrmGetNextBssEntryFromNeighborCache()
1269
1270 \brief This function returns the entry next to the given entry from the
1271 neighbor cache to the caller
1272
1273 \param pMac - The handle returned by macOpen.
1274
1275 \return VOID
1276
1277---------------------------------------------------------------------------*/
1278tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac,
1279 tpRrmNeighborReportDesc pBssEntry)
1280{
1281 tListElem *pEntry;
1282 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1283
1284 pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK);
1285
1286 if(!pEntry)
1287 {
1288 //list empty
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001289 smsLog(pMac, LOGW, FL("List empty"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001290 return NULL;
1291 }
1292
1293 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1294
1295 return pTempBssEntry;
1296}
1297
1298#ifdef FEATURE_WLAN_CCX
1299void csrCcxSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
1300{
1301 tpSirAdjacentApRepInd pAdjRep;
1302 tANI_U16 length;
1303 tANI_U32 roamTS2;
1304
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001305 smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE");
Jeff Johnson295189b2012-06-20 16:38:30 -07001306
1307 length = sizeof(tSirAdjacentApRepInd );
1308 pAdjRep = vos_mem_malloc ( length );
1309
1310 if ( NULL == pAdjRep )
1311 {
1312 smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report");
1313 return;
1314 }
1315
1316 vos_mem_zero( pAdjRep, length );
1317 pAdjRep->messageType = eWNI_SME_CCX_ADJACENT_AP_REPORT;
1318 pAdjRep->length = length;
1319 pAdjRep->channelNum = pSession->prevOpChannel;
1320 vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
1321 vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) );
1322 vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) );
1323 roamTS2 = vos_timer_get_system_time();
1324 pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1;
1325 pAdjRep->roamReason =SIR_CCX_ASSOC_REASON_UNSPECIFIED;
1326 pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000);
1327
1328 palSendMBMessage(pMac->hHdd, pAdjRep);
1329
1330 return;
1331}
1332#endif /* FEATURE_WLAN_CCX */
1333#endif