blob: c1934809d30d71f083734a9fb91fa72ed78ce617 [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 {
Gopichand Nakkalaecdb2a82013-05-30 12:57:51 +0530148 smsLog( pMac, LOG1, FL("No entry in neighbor report cache"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700149 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
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -0700773 if (NULL == pNeighborReportDesc)
774 {
775 VOS_ASSERT(0);
776 return;
777 }
778 if (NULL == pNeighborReportDesc->pNeighborBssDescription)
779 {
780 VOS_ASSERT(0);
781 return;
782 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700783
784 pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription;
785
786 if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain)
787 {
788 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN;
789 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode)
790 {
791 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY;
792 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator)
793 {
794 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE;
795 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement)
796 {
797 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM;
798 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement)
799 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT;
800 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos)
801 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS;
802 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd)
803 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD;
804 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck)
805 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA;
806 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck)
807 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA;
808 if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable)
809 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY;
810 }
811 }
812 }
813 }
814#ifdef FEATURE_WLAN_CCX
815 // It has come in the report so its the best score
816 if (csrNeighborRoamIs11rAssoc(pMac) == FALSE)
817 {
818 // IAPP Route so lets make use of this info
819 // save all AP, as the list does not come all the time
820 // Save and reuse till the next AP List comes to us.
821 // Even save our own MAC address. Will be useful next time around.
822 roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST;
823 }
824#endif
825 pNeighborReportDesc->roamScore = roamScore;
826
827 return;
828}
829
830/*--------------------------------------------------------------------------
831 \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given
832 Neighbor BSS descriptor to the neighbor cache. This function
833 stores the neighbor BSS descriptors in such a way that descriptors
834 are sorted by roamScore in descending order
835
836 \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
837
838 \return void.
839--------------------------------------------------------------------------*/
840void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
841{
842 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
843 tListElem *pEntry;
844 tRrmNeighborReportDesc *pTempNeighborReportDesc;
845
Gopichand Nakkalacc8cf8e2013-04-25 06:03:10 -0700846 if (NULL == pNeighborReportDesc)
847 {
848 VOS_ASSERT(0);
849 return;
850 }
851 if (NULL == pNeighborReportDesc->pNeighborBssDescription)
852 {
853 VOS_ASSERT(0);
854 return;
855 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700856
857 if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK))
858 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800859 smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now"));
Jeff Johnson295189b2012-06-20 16:38:30 -0700860 /* Neighbor list cache is empty. Insert this entry in the tail */
861 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
862 return;
863 }
864 else
865 {
866 /* Should store the neighbor BSS description in the order sorted by roamScore in descending
867 order. APs with highest roamScore should be the 1st entry in the list */
868 pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK);
869 while (pEntry != NULL)
870 {
871 pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
872 if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore)
873 break;
874 pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK);
875 }
876
877 if (pEntry)
878 /* This BSS roamscore is better than something in the list. Insert this before that one */
879 csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
880 else
881 /* All the entries in the list has a better roam Score than this one. Insert this at the last */
882 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
883 }
884 return;
885}
886
887/*--------------------------------------------------------------------------
888 \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor
889 report received from PE.
890
891 \param pMsgBuf - a pointer to a buffer that maps to various structures base
892 on the message type.
893 The beginning of the buffer can always map to tSirSmeRsp.
894
895 \return eHAL_STATUS_SUCCESS - Validation is successful.
896
897 \sa
898
899 --------------------------------------------------------------------------*/
900eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf)
901{
902 eHalStatus status = eHAL_STATUS_SUCCESS;
903 tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf;
904 tpRrmNeighborReportDesc pNeighborReportDesc;
905 tANI_U8 i = 0;
906 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
907
908#ifdef FEATURE_WLAN_CCX
909 // Clear the cache for CCX.
910 if (csrNeighborRoamIsCCXAssoc(pMac))
911 {
912 rrmLLPurgeNeighborCache(pMac,
913 &pMac->rrm.rrmSmeContext.neighborReportCache);
914 }
915#endif
916
917 for (i = 0; i < pNeighborRpt->numNeighborReports; i++)
918 {
919 pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc));
920 if (NULL == pNeighborReportDesc)
921 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800922 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc");
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 status = eHAL_STATUS_FAILED_ALLOC;
924 goto end;
925
926 }
927
928 vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc));
929 pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription));
930 if (NULL == pNeighborReportDesc->pNeighborBssDescription)
931 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800932 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description");
Jeff Johnsonfb82ea52013-04-03 15:35:49 -0700933 vos_mem_free(pNeighborReportDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 status = eHAL_STATUS_FAILED_ALLOC;
935 goto end;
936 }
937 vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription));
938 vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i],
939 sizeof(tSirNeighborBssDescription));
940
941#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800942 smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: %02x:%02x:%02x:%02x:%02x:%02x ",
Jeff Johnson295189b2012-06-20 16:38:30 -0700943 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
944 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
945 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
946 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
947 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
948 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
949#endif
950
951 /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */
952 rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc);
953
954 /* Store the Neighbor report Desc in the cache based on the roam score */
955 if ( pNeighborReportDesc->roamScore > 0)
956 {
957 rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc);
958 }
959 else
960 {
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -0800961 smsLog(pMac, LOGE, FL("Roam score of BSSID %02x:%02x:%02x:%02x:%02x:%02x is 0, Ignoring.."),
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
963 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
964 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
965 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
966 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
967 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
968
969 vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
970 vos_mem_free(pNeighborReportDesc);
971 }
972 }
973end:
974
975 if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache))
976 vosStatus = VOS_STATUS_E_FAILURE;
977
978 /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */
979 rrmIndicateNeighborReportResult(pMac, vosStatus);
980
981 return status;
982}
983/*--------------------------------------------------------------------------
984 \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the
985 messages that are handled by SME RRM module.
986
987 \param pMac - Pointer to the global MAC parameter structure.
988 \param msg_type - the type of msg passed by PE as defined in wniApi.h
989 \param pMsgBuf - a pointer to a buffer that maps to various structures base
990 on the message type.
991 The beginning of the buffer can always map to tSirSmeRsp.
992
993 \return eHAL_STATUS_SUCCESS - Validation is successful.
994
995 \sa
996
997 --------------------------------------------------------------------------*/
998eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type,
999 void *pMsgBuf)
1000{
1001 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001002 FL(" Msg = %d for RRM measurement") , msg_type );
Jeff Johnson295189b2012-06-20 16:38:30 -07001003
1004 //switch on the msg type & make the state transition accordingly
1005 switch(msg_type)
1006 {
1007 case eWNI_SME_NEIGHBOR_REPORT_IND:
1008 sme_RrmProcessNeighborReport( pMac, pMsgBuf );
1009 break;
1010
1011 case eWNI_SME_BEACON_REPORT_REQ_IND:
1012 sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf );
1013 break;
1014
1015 default:
1016 //err msg
1017 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001018 FL("sme_RrmMsgProcessor:unknown msg type = %d"), msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07001019
1020 break;
1021 }
1022
1023 return eHAL_STATUS_SUCCESS;
1024}
1025
1026/* ---------------------------------------------------------------------------
1027
1028 \fn rrmIterMeasTimerHandle
1029
1030 \brief Timer handler to handlet the timeout condition when a specific BT
1031
1032 stop event does not come back, in which case to restore back the
1033
1034 heartbeat timer.
1035
1036 \param pMac - The handle returned by macOpen.
1037
1038 \return VOID
1039
1040 ---------------------------------------------------------------------------*/
1041
1042void rrmIterMeasTimerHandle( v_PVOID_t userData )
1043{
1044 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1045#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001046 smsLog( pMac, LOGE, "Randomization timer expired...send on next channel ");
Jeff Johnson295189b2012-06-20 16:38:30 -07001047#endif
1048 //Issue a scan req for next channel.
1049 sme_RrmIssueScanReq( pMac );
1050}
1051
1052/* ---------------------------------------------------------------------------
1053
1054 \fn rrmNeighborRspTimeoutHandler
1055
1056 \brief Timer handler to handle the timeout condition when a neighbor request is sent
1057 and no neighbor response is received from the AP
1058
1059 \param pMac - The handle returned by macOpen.
1060
1061 \return VOID
1062
1063---------------------------------------------------------------------------*/
1064
1065void rrmNeighborRspTimeoutHandler
1066( v_PVOID_t userData )
1067{
1068 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1069#if defined WLAN_VOWIFI_DEBUG
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001070 smsLog( pMac, LOGE, "Neighbor Response timed out ");
Jeff Johnson295189b2012-06-20 16:38:30 -07001071#endif
1072 rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE);
1073 return;
1074}
1075
1076/* ---------------------------------------------------------------------------
1077
1078 \fn rrmOpen
1079
1080 \brief
1081
1082 \param pMac - The handle returned by macOpen.
1083
1084 \return VOS_STATUS
1085
1086 VOS_STATUS_E_FAILURE success
1087
1088 VOS_STATUS_SUCCESS failure
1089
1090 ---------------------------------------------------------------------------*/
1091
1092VOS_STATUS rrmOpen (tpAniSirGlobal pMac)
1093
1094{
1095
1096 VOS_STATUS vosStatus;
1097 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1098 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
1099
1100 pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms
1101
1102 vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer,
1103
1104 VOS_TIMER_TYPE_SW,
1105
1106 rrmIterMeasTimerHandle,
1107
1108 (void*) pMac);
1109
1110 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1111
1112 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1113
1114 return VOS_STATUS_E_FAILURE;
1115 }
1116
1117 vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer,
1118
1119 VOS_TIMER_TYPE_SW,
1120
1121 rrmNeighborRspTimeoutHandler,
1122
1123 (void*) pMac);
1124
1125 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1126
1127 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1128
1129 return VOS_STATUS_E_FAILURE;
1130 }
1131
1132 pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;
1133
1134 halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache);
1135 if (eHAL_STATUS_SUCCESS != halStatus)
1136 {
1137 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result");
1138 return VOS_STATUS_E_FAILURE;
1139 }
1140
1141 return VOS_STATUS_SUCCESS;
1142}
1143
1144
1145/* ---------------------------------------------------------------------------
1146
1147 \fn rrmClose
1148
1149 \brief
1150
1151 \param pMac - The handle returned by macOpen.
1152
1153 \return VOS_STATUS
1154
1155 VOS_STATUS_E_FAILURE success
1156
1157 VOS_STATUS_SUCCESS failure
1158
1159 ---------------------------------------------------------------------------*/
1160
1161VOS_STATUS rrmClose (tpAniSirGlobal pMac)
1162
1163{
1164
1165 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1166 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1167
1168 if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) )
1169 {
1170 vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer );
1171 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001172 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") );
1174 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001176
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001177 vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer );
1178 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1179 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001180
1181 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") );
1182
1183 }
1184
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001185 if( VOS_TIMER_STATE_RUNNING ==
1186 vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) )
1187 {
1188 vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1189 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1190 {
1191 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") );
1192 }
1193 }
1194
1195 vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1196 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1197 {
1198 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") );
1199
1200 }
1201
Jeff Johnson295189b2012-06-20 16:38:30 -07001202 rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001203
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 csrLLClose(&pSmeRrmContext->neighborReportCache);
1205
1206 return vosStatus;
1207
1208}
1209
1210
1211
1212
1213/* ---------------------------------------------------------------------------
1214
1215 \fn rrmReady
1216
1217 \brief fn
1218
1219 \param pMac - The handle returned by macOpen.
1220
1221 \return VOS_STATUS
1222
1223 ---------------------------------------------------------------------------*/
1224
1225VOS_STATUS rrmReady (tpAniSirGlobal pMac)
1226
1227{
1228
1229 return VOS_STATUS_SUCCESS;
1230}
1231
1232/* ---------------------------------------------------------------------------
1233
1234 \fn rrmChangeDefaultConfigParam
1235 \brief fn
1236
1237 \param pMac - The handle returned by macOpen.
1238 \param pRrmConfig - pointer to new rrm configs.
1239
1240 \return VOS_STATUS
1241
1242 ---------------------------------------------------------------------------*/
1243VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig)
1244{
1245 vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) );
1246
1247 return VOS_STATUS_SUCCESS;
1248}
1249
1250/* ---------------------------------------------------------------------------
1251
1252 \fn smeRrmGetFirstBssEntryFromNeighborCache()
1253
1254 \brief This function returns the first entry from the neighbor cache to the caller
1255
1256 \param pMac - The handle returned by macOpen.
1257
1258 \return VOID
1259
1260---------------------------------------------------------------------------*/
1261tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac)
1262{
1263 tListElem *pEntry;
1264 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1265 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1266
1267
1268 pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK );
1269
1270 if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache))
1271 {
1272 //list empty
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001273 smsLog(pMac, LOGW, FL("List empty"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 return NULL;
1275 }
1276
1277 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1278
1279 return pTempBssEntry;
1280}
1281
1282/* ---------------------------------------------------------------------------
1283
1284 \fn smeRrmGetNextBssEntryFromNeighborCache()
1285
1286 \brief This function returns the entry next to the given entry from the
1287 neighbor cache to the caller
1288
1289 \param pMac - The handle returned by macOpen.
1290
1291 \return VOID
1292
1293---------------------------------------------------------------------------*/
1294tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac,
1295 tpRrmNeighborReportDesc pBssEntry)
1296{
1297 tListElem *pEntry;
1298 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1299
1300 pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK);
1301
1302 if(!pEntry)
1303 {
1304 //list empty
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001305 smsLog(pMac, LOGW, FL("List empty"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 return NULL;
1307 }
1308
1309 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1310
1311 return pTempBssEntry;
1312}
1313
1314#ifdef FEATURE_WLAN_CCX
1315void csrCcxSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
1316{
1317 tpSirAdjacentApRepInd pAdjRep;
1318 tANI_U16 length;
1319 tANI_U32 roamTS2;
1320
Kiran Kumar Lokere691dde12013-03-06 17:00:31 -08001321 smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE");
Jeff Johnson295189b2012-06-20 16:38:30 -07001322
1323 length = sizeof(tSirAdjacentApRepInd );
1324 pAdjRep = vos_mem_malloc ( length );
1325
1326 if ( NULL == pAdjRep )
1327 {
1328 smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report");
1329 return;
1330 }
1331
1332 vos_mem_zero( pAdjRep, length );
1333 pAdjRep->messageType = eWNI_SME_CCX_ADJACENT_AP_REPORT;
1334 pAdjRep->length = length;
1335 pAdjRep->channelNum = pSession->prevOpChannel;
1336 vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
1337 vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) );
1338 vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) );
1339 roamTS2 = vos_timer_get_system_time();
1340 pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1;
1341 pAdjRep->roamReason =SIR_CCX_ASSOC_REASON_UNSPECIFIED;
1342 pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000);
1343
1344 palSendMBMessage(pMac->hHdd, pAdjRep);
1345
1346 return;
1347}
1348#endif /* FEATURE_WLAN_CCX */
1349#endif