blob: 3e135e994ccca886bfaeb5dbe21c9ab2c90bb609 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/** ------------------------------------------------------------------------- *
23 ------------------------------------------------------------------------- *
24
25
26 \file csrApiScan.c
27
28 Implementation for the Common Scan interfaces.
29
30 Copyright (C) 2006 Airgo Networks, Incorporated
31 ========================================================================== */
32
33#include "aniGlobal.h"
34
35#include "palApi.h"
36#include "csrInsideApi.h"
37#include "smeInside.h"
38#include "smsDebug.h"
39
40#include "csrSupport.h"
41#include "wlan_qct_tl.h"
42
43#include "vos_diag_core_log.h"
44#include "vos_diag_core_event.h"
45
46#include "vos_nvitem.h"
47#include "wlan_qct_wda.h"
48
49#define CSR_VALIDATE_LIST //This portion of code need to be removed once the issue is resolved.
50
51#ifdef CSR_VALIDATE_LIST
52tDblLinkList *g_pchannelPowerInfoList24 = NULL, * g_pchannelPowerInfoList5 = NULL;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070053tpAniSirGlobal g_pMac;
Jeff Johnson295189b2012-06-20 16:38:30 -070054#endif
55
56/* Purpose of HIDDEN_TIMER
57** When we remove hidden ssid from the profile i.e., forget the SSID via GUI that SSID shouldn't see in the profile
58** For above requirement we used timer limit, logic is explained below
59** Timer value is initialsed to current time when it receives corresponding probe response of hidden SSID (The probe request is
60** received regularly till SSID in the profile. Once it is removed from profile probe request is not sent.) when we receive probe response
61** for broadcast probe request, during update SSID with saved SSID we will diff current time with saved SSID time if it is greater than 1 min
62** then we are not updating with old one
63*/
64
65#define HIDDEN_TIMER (1*60*1000)
66#define CSR_SCAN_RESULT_RSSI_WEIGHT 80 // must be less than 100, represent the persentage of new RSSI
67
68/*---------------------------------------------------------------------------
69 PER filter constant fraction: it is a %
70---------------------------------------------------------------------------*/
71#define CSR_SCAN_PER_FILTER_FRAC 100
72
73/*---------------------------------------------------------------------------
74 RSSI filter constant fraction: it is a %
75---------------------------------------------------------------------------*/
76#define CSR_SCAN_RSSI_FILTER_FRAC 100
77
78/*---------------------------------------------------------------------------
79Convert RSSI into overall score: Since RSSI is in -dBm values, and the
80overall needs to be weighted inversely (where greater value means better
81system), we convert.
82RSSI *cannot* be more than 0xFF or less than 0 for meaningful WLAN operation
83---------------------------------------------------------------------------*/
84#define CSR_SCAN_MAX_SCORE_VAL 0xFF
85#define CSR_SCAN_MIN_SCORE_VAL 0x0
86#define CSR_SCAN_HANDOFF_DELTA 10
Jeff Johnson32d95a32012-09-10 13:15:23 -070087#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140
88#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120
Madan Mohan Koyyalamudia53c4dc2012-11-13 10:35:42 -080089#define CSR_SCAN_OVERALL_SCORE( rssi ) \
90 (( rssi < CSR_SCAN_MAX_SCORE_VAL ) \
91 ? (CSR_SCAN_MAX_SCORE_VAL-rssi) : CSR_SCAN_MIN_SCORE_VAL)
Jeff Johnson295189b2012-06-20 16:38:30 -070092
93
94#define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) \
95 ( (pMac)->scan.nBssLimit <= (csrLLCount(&(pMac)->scan.scanResultList)) )
96
97//*** This is temporary work around. It need to call CCM api to get to CFG later
98/// Get string parameter value
99extern tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*);
100
101void csrScanGetResultTimerHandler(void *);
102void csrScanResultAgingTimerHandler(void *pv);
103void csrScanIdleScanTimerHandler(void *);
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700104static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest);
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#ifdef WLAN_AP_STA_CONCURRENCY
106static void csrStaApConcTimerHandler(void *);
107#endif
Jeff Johnsone7245742012-09-05 17:12:55 -0700108tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700109eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand );
110void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels );
111void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId );
112void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode );
113void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList );
114//if bgPeriod is 0, background scan is disabled. It is in millisecond units
115eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod);
116eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand);
117void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus);
118static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels,
119 tANI_U8 numChn, tSirBssDescription *pBssDesc,
120 tDot11fBeaconIEs **ppIes );
121eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels);
122void csrReleaseCmdSingle(tpAniSirGlobal pMac, tSmeCmd *pCommand);
123tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel );
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700124void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList );
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -0700126#define CSR_IS_SOCIAL_CHANNEL(channel) (((channel) == 1) || ((channel) == 6) || ((channel) == 11) )
127
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -0700128
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -0700129
Madan Mohan Koyyalamudi923c1e12012-11-30 17:53:27 -0800130static void csrReleaseScanCmdPendingList(tpAniSirGlobal pMac)
131{
132 tListElem *pEntry;
133 tSmeCmd *pCommand;
134
135 while((pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK)) != NULL)
136 {
137 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
138 if ( eSmeCsrCommandMask & pCommand->command )
139 {
140 csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_TRUE );
141 }
142 else
143 {
144 smsLog(pMac, LOGE, FL("Error: Received command : %d\n"),pCommand->command);
145 }
146 }
147}
Jeff Johnson295189b2012-06-20 16:38:30 -0700148//pResult is invalid calling this function.
149void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult )
150{
151 if( NULL != pResult->Result.pvIes )
152 {
153 palFreeMemory( pMac->hHdd, pResult->Result.pvIes );
154 }
155 palFreeMemory(pMac->hHdd, pResult);
156}
157
158
159static eHalStatus csrLLScanPurgeResult(tpAniSirGlobal pMac, tDblLinkList *pList)
160{
161 eHalStatus status = eHAL_STATUS_SUCCESS;
162 tListElem *pEntry;
163 tCsrScanResult *pBssDesc;
164
165 csrLLLock(pList);
166
167 while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL)
168 {
169 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
170 csrFreeScanResultEntry( pMac, pBssDesc );
171 }
172
173 csrLLUnlock(pList);
174
175 return (status);
176}
177
178
179int csrCheckValidateLists(void * dest, const void *src, v_SIZE_t num, int idx)
180{
181#ifdef CSR_VALIDATE_LIST
182
183 int ii = 1;
184
185 if( (NULL == g_pMac) || (!g_pMac->scan.fValidateList ) )
186 {
187 return ii;
188 }
189 if(g_pchannelPowerInfoList24)
190 {
191 //check 2.4 list
192 tListElem *pElem, *pHead;
193 int count;
194
195 count = (int)(g_pchannelPowerInfoList24->Count);
196 pHead = &g_pchannelPowerInfoList24->ListHead;
197 pElem = pHead->next;
198 if((tANI_U32)(pHead->next) > 0x00010000) //Assuming kernel address is not that low.
199 {
200 //this loop crashes if the pointer is not right
201 while(pElem->next != pHead)
202 {
203 if((tANI_U32)(pElem->next) > 0x00010000)
204 {
205 pElem = pElem->next;
206 VOS_ASSERT(count > 0);
207 count--;
208 }
209 else
210 {
211 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
212 " %d Detect 1 list(0x%X) error Head(0x%X) next(0x%X) Count %d, dest(0x%X) src(0x%X) numBytes(%d)",
213 idx, (unsigned int)g_pchannelPowerInfoList24, (unsigned int)pHead,
214 (unsigned int)(pHead->next), (int)g_pchannelPowerInfoList24->Count,
215 (unsigned int)dest, (unsigned int)src, (int)num);
216 VOS_ASSERT(0);
217 ii = 0;
218 break;
219 }
220 }
221 }
222 else
223 {
224 //Bad list
225 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, " %d Detect list(0x%X) error Head(0x%X) next(0x%X) Count %d, dest(0x%X) src(0x%X) numBytes(%d)",
226 idx, (unsigned int)g_pchannelPowerInfoList24, (unsigned int)pHead,
227 (unsigned int)(pHead->next), (int)g_pchannelPowerInfoList24->Count,
228 (unsigned int)dest, (unsigned int)src, (int)num);
229 VOS_ASSERT(0);
230 ii = 0;
231 }
232 }
233 else
234 {
235 //list ok
236 ii = 1;
237 }
238
239
240 return ii;
241
242#else
243 return 1;
244#endif //#ifdef CSR_VALIDATE_LIST
245}
246
247
248eHalStatus csrScanOpen( tpAniSirGlobal pMac )
249{
250 eHalStatus status;
251
252 do
253 {
254 csrLLOpen(pMac->hHdd, &pMac->scan.scanResultList);
255 csrLLOpen(pMac->hHdd, &pMac->scan.tempScanResults);
256 csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList24);
257 csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList5G);
258#ifdef WLAN_AP_STA_CONCURRENCY
259 csrLLOpen(pMac->hHdd, &pMac->scan.scanCmdPendingList);
260#endif
261#ifdef CSR_VALIDATE_LIST
262 g_pchannelPowerInfoList5 = &pMac->scan.channelPowerInfoList5G;
263 g_pMac = pMac;
264 g_pchannelPowerInfoList24 = &pMac->scan.channelPowerInfoList24;
265#endif
266 pMac->scan.fFullScanIssued = eANI_BOOLEAN_FALSE;
267 pMac->scan.nBssLimit = CSR_MAX_BSS_SUPPORT;
268 status = palTimerAlloc(pMac->hHdd, &pMac->scan.hTimerGetResult, csrScanGetResultTimerHandler, pMac);
269 if(!HAL_STATUS_SUCCESS(status))
270 {
271 smsLog(pMac, LOGE, FL("cannot allocate memory for getResult timer\n"));
272 break;
273 }
274#ifdef WLAN_AP_STA_CONCURRENCY
275 status = palTimerAlloc(pMac->hHdd, &pMac->scan.hTimerStaApConcTimer, csrStaApConcTimerHandler, pMac);
276 if(!HAL_STATUS_SUCCESS(status))
277 {
278 smsLog(pMac, LOGE, FL("cannot allocate memory for hTimerStaApConcTimer timer\n"));
279 break;
280 }
281#endif
282 status = palTimerAlloc(pMac->hHdd, &pMac->scan.hTimerIdleScan, csrScanIdleScanTimerHandler, pMac);
283 if(!HAL_STATUS_SUCCESS(status))
284 {
285 smsLog(pMac, LOGE, FL("cannot allocate memory for idleScan timer\n"));
286 break;
287 }
288 status = palTimerAlloc(pMac->hHdd, &pMac->scan.hTimerResultAging, csrScanResultAgingTimerHandler, pMac);
289 if(!HAL_STATUS_SUCCESS(status))
290 {
291 smsLog(pMac, LOGE, FL("cannot allocate memory for ResultAging timer\n"));
292 break;
293 }
294 }while(0);
295
296 return (status);
297}
298
299
300eHalStatus csrScanClose( tpAniSirGlobal pMac )
301{
302#ifdef CSR_VALIDATE_LIST
303 g_pchannelPowerInfoList24 = NULL;
304 g_pchannelPowerInfoList5 = NULL;
305 g_pMac = NULL;
306#endif
307 csrLLScanPurgeResult(pMac, &pMac->scan.tempScanResults);
308 csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList);
309#ifdef WLAN_AP_STA_CONCURRENCY
Madan Mohan Koyyalamudi923c1e12012-11-30 17:53:27 -0800310 csrReleaseScanCmdPendingList(pMac);
Jeff Johnson295189b2012-06-20 16:38:30 -0700311#endif
312 csrLLClose(&pMac->scan.scanResultList);
313 csrLLClose(&pMac->scan.tempScanResults);
314#ifdef WLAN_AP_STA_CONCURRENCY
315 csrLLClose(&pMac->scan.scanCmdPendingList);
316#endif
317 csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList24);
318 csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList5G);
319 csrLLClose(&pMac->scan.channelPowerInfoList24);
320 csrLLClose(&pMac->scan.channelPowerInfoList5G);
321 csrScanDisable(pMac);
322 palTimerFree(pMac->hHdd, pMac->scan.hTimerResultAging);
323 palTimerFree(pMac->hHdd, pMac->scan.hTimerGetResult);
324#ifdef WLAN_AP_STA_CONCURRENCY
325 palTimerFree(pMac->hHdd, pMac->scan.hTimerStaApConcTimer);
326#endif
327 palTimerFree(pMac->hHdd, pMac->scan.hTimerIdleScan);
328 return eHAL_STATUS_SUCCESS;
329}
330
331
332eHalStatus csrScanEnable( tpAniSirGlobal pMac )
333{
334
335 pMac->scan.fScanEnable = eANI_BOOLEAN_TRUE;
336 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
337
338 return eHAL_STATUS_SUCCESS;
339}
340
341
342eHalStatus csrScanDisable( tpAniSirGlobal pMac )
343{
344
345 csrScanStopTimers(pMac);
346 pMac->scan.fScanEnable = eANI_BOOLEAN_FALSE;
347
348 return eHAL_STATUS_SUCCESS;
349}
350
351
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700352//Set scan timing parameters according to state of other driver sessions
353//No validation of the parameters is performed.
354static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest)
355{
356#ifdef WLAN_AP_STA_CONCURRENCY
357 if(csrIsAnySessionConnected(pMac))
358 {
359 //If multi-session, use the appropriate default scan times
360 if(scanType == eSIR_ACTIVE_SCAN)
361 {
362 pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTimeConc;
363 pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTimeConc;
364 }
365 else
366 {
367 pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTimeConc;
368 pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTimeConc;
369 }
370
371 pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
372
373 //Return so that fields set above will not be overwritten.
374 return;
375 }
376#endif
377
378 //This portion of the code executed if multi-session not supported
379 //(WLAN_AP_STA_CONCURRENCY not defined) or no multi-session.
380 //Use the "regular" (non-concurrency) default scan timing.
381 if(pScanRequest->scanType == eSIR_ACTIVE_SCAN)
382 {
383 pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
384 pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTime;
385 }
386 else
387 {
388 pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
389 pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
390 }
391
392#ifdef WLAN_AP_STA_CONCURRENCY
393 //No rest time if no sessions are connected.
394 pScanRequest->restTime = 0;
395#endif
396}
397
Jeff Johnson295189b2012-06-20 16:38:30 -0700398#ifdef WLAN_AP_STA_CONCURRENCY
399//Return SUCCESS is the command is queued, else returns eHAL_STATUS_FAILURE
400eHalStatus csrQueueScanRequest( tpAniSirGlobal pMac, tSmeCmd *pScanCmd )
401{
402 eHalStatus status = eHAL_STATUS_SUCCESS;
403
404 tANI_BOOLEAN fNoCmdPending;
405 tSmeCmd *pQueueScanCmd=NULL;
406 tSmeCmd *pSendScanCmd=NULL;
407
Madan Mohan Koyyalamudi48081ef2012-12-04 16:49:55 -0800408 /* split scan if any one of the following:
409 * - STA session is connected and the scan is not a P2P search
410 * - any P2P session is connected
411 */
412 if ( (csrIsStaSessionConnected(pMac) && (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
413 (csrIsP2pSessionConnected(pMac)) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700414 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700415 tCsrScanRequest scanReq;
416 tANI_U8 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
417 tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
418 tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
419 tANI_U8 i = 0;
420 tANI_BOOLEAN bMemAlloc = eANI_BOOLEAN_FALSE;
421
422 if (numChn == 0)
423 {
424
425 numChn = pMac->scan.baseChannels.numChannels;
426
427 status = palAllocateMemory( pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn );
428 if( !HAL_STATUS_SUCCESS( status ) )
429 {
430 smsLog( pMac, LOGE, FL(" Failed to get memory for channel list \n") );
431 return eHAL_STATUS_FAILURE;
432 }
433 bMemAlloc = eANI_BOOLEAN_TRUE;
434 status = palCopyMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
435 pMac->scan.baseChannels.channelList, numChn );
436 if( !HAL_STATUS_SUCCESS( status ) )
437 {
438 palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
439 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
440 smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list \n") );
441 return eHAL_STATUS_FAILURE;
442 }
443 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn;
444 }
445
446 //Whenever we get a scan request with multiple channels we break it up into 2 requests
447 //First request for first channel to scan and second request to scan remaining channels
448 for (i=0; i < 2; i++)
449 { //go through max 2 iterations.
450 //Once for using the existing command when number of channels is 1
451 //Second to go over the remaining channels after creating a new command
452
453 if (1 == numChn)
454 {
455 pSendScanCmd = pScanCmd;
456 pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1;
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700457 //Use concurrency values for min/maxChnTime.
458 //We know csrIsAnySessionConnected(pMac) returns TRUE here
459 csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
Jeff Johnson295189b2012-06-20 16:38:30 -0700460 if (i != 0)
461 { //Callback should be NULL for all except last channel So hdd_callback will be called only after last command
462 //i!=0 then we came here in second iteration
463 pSendScanCmd->u.scanCmd.callback = NULL;
464 }
465 break; //break out of this loop in case there is only 1 channel then no need for 2nd iteration
466
467 } else { //if number of channels > 1 then
468
469 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
470
471 pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
472 if (!pQueueScanCmd)
473 {
474 if (bMemAlloc)
475 {
476 palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
477 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
478
479 }
480 smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer\n") );
481 return eHAL_STATUS_FAILURE;
482 }
483 pQueueScanCmd->command = pScanCmd->command;
484 pQueueScanCmd->sessionId = pScanCmd->sessionId;
485 pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback;
486 pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
487 pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
488 pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
489
Madan Mohan Koyyalamudiaf2a8b92012-10-09 14:58:07 -0700490 /* First copy all the parameters to local variable of scan request */
491 csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
492
493 /* Now modify the elements of local var scan request required to be modified for split scan */
Madan Mohan Koyyalamudi0c626f32012-11-30 15:10:25 -0800494 if(scanReq.ChannelInfo.ChannelList != NULL)
495 {
496 palFreeMemory(pMac->hHdd, scanReq.ChannelInfo.ChannelList);
497 scanReq.ChannelInfo.ChannelList = NULL;
498 }
499
Jeff Johnson295189b2012-06-20 16:38:30 -0700500 pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - 1;
501
502 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
503 FL(" &channelToScan %0x pScanCmd(0x%X) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(0x%X)numChn(%d)"),
504 &channelToScan[0], (unsigned int)pScanCmd,
505 (unsigned int)pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn);
506
507 palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[1],
508 pChnInfo->numOfChannels * sizeof(tANI_U8));
509
510 pChnInfo->ChannelList = &channelToScan[0];
511
Jeff Johnson295189b2012-06-20 16:38:30 -0700512 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
513 //Modify callers parameters in case of concurrency
514 scanReq.scanType = eSIR_ACTIVE_SCAN;
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700515 //Use concurrency values for min/maxChnTime.
516 //We know csrIsAnySessionConnected(pMac) returns TRUE here
517 csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);
Jeff Johnson295189b2012-06-20 16:38:30 -0700518
519 status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq);
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700520
Jeff Johnson295189b2012-06-20 16:38:30 -0700521 if(!HAL_STATUS_SUCCESS(status))
522 {
523 if (bMemAlloc)
524 {
525 palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
526 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
527
528 }
Madan Mohan Koyyalamudi0c626f32012-11-30 15:10:25 -0800529 if( scanReq.pIEField != NULL)
530 {
531 palFreeMemory(pMac->hHdd, scanReq.pIEField);
532 scanReq.pIEField = NULL;
533 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700534 smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d\n"), status );
535 return eHAL_STATUS_FAILURE;
Madan Mohan Koyyalamudi0c626f32012-11-30 15:10:25 -0800536 }
537 /* Clean the local scan variable */
538 scanReq.ChannelInfo.ChannelList = NULL;
539 scanReq.ChannelInfo.numOfChannels = 0;
540 csrScanFreeRequest(pMac, &scanReq);
Jeff Johnson295189b2012-06-20 16:38:30 -0700541 numChn = 1; //make numChn to be 1 for second iteration to create a send command
542 }
543
544 }
545
546 fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK );
547
548 //Logic Below is as follows
549 // If the scanCmdPendingList is empty then we directly send that command
550 // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue
551 if( fNoCmdPending )
552 {
553
554 if (pQueueScanCmd != NULL)
555 {
556 csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
557 }
558
559 if (pSendScanCmd != NULL)
560 {
561 return csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);
562 }
563 }
564 else
565 {
566 if (pSendScanCmd != NULL)
567 {
568 csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pSendScanCmd->Link, LL_ACCESS_LOCK );
569 }
570 if (pQueueScanCmd != NULL)
571 {
572 csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
573 }
574 }
575
576 }
577 else
578 { //No concurrency case
579 return csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
580 }
581
582
583
584 return ( status );
585
586}
587#endif
588
Jeff Johnsone7245742012-09-05 17:12:55 -0700589/* ---------------------------------------------------------------------------
590 \fn csrScan2GOnyRequest
591 \brief This function will update the scan request with only
592 2.4GHz valid cahnnel list.
593 \param pMac
594 \param pScanCmd
595 \param pScanRequest
596 \return None
597 -------------------------------------------------------------------------------*/
598static void csrScan2GOnyRequest(tpAniSirGlobal pMac,tSmeCmd *pScanCmd,
599 tCsrScanRequest *pScanRequest)
600{
601 tANI_U8 index, channelId, channelListSize = 0;
602 tANI_U8 channelList2G[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
603 static tANI_U8 validchannelList[CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS] = {0};
604
605 VOS_ASSERT(pScanCmd && pScanRequest);
Madan Mohan Koyyalamudi33ef6a22012-10-30 17:44:43 -0700606 /* To silence the KW tool null check is added */
607 if((pScanCmd == NULL) || (pScanRequest == NULL))
608 {
609 smsLog( pMac, LOGE, FL(" pScanCmd or pScanRequest is NULL \n"));
610 return;
611 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700612
613 if (pScanCmd->u.scanCmd.scanID ||
614 (eCSR_SCAN_REQUEST_FULL_SCAN != pScanRequest->requestType))
615 return;
616
617 //Contsruct valid Supported 2.4 GHz Channel List
618 for( index = 0; index < ARRAY_SIZE(channelList2G); index++ )
619 {
620 channelId = channelList2G[index];
621 if ( csrIsSupportedChannel( pMac, channelId ) )
622 {
623 validchannelList[channelListSize++] = channelId;
624 }
625 }
626
627 pScanRequest->ChannelInfo.numOfChannels = channelListSize;
628 pScanRequest->ChannelInfo.ChannelList = validchannelList;
629}
630
Jeff Johnson295189b2012-06-20 16:38:30 -0700631eHalStatus csrScanRequest(tpAniSirGlobal pMac, tANI_U16 sessionId,
632 tCsrScanRequest *pScanRequest, tANI_U32 *pScanRequestID,
633 csrScanCompleteCallback callback, void *pContext)
634{
635 eHalStatus status = eHAL_STATUS_FAILURE;
636 tSmeCmd *pScanCmd = NULL;
Madan Mohan Koyyalamudicb90bb22012-10-30 18:24:43 -0700637 eCsrConnectState ConnectState;
Jeff Johnson295189b2012-06-20 16:38:30 -0700638
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700639 VOS_ASSERT(pScanRequest != NULL);
640
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 do
642 {
643 if(pMac->scan.fScanEnable)
644 {
645 pScanCmd = csrGetCommandBuffer(pMac);
646 if(pScanCmd)
647 {
648 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
649 pScanCmd->command = eSmeCommandScan;
650 pScanCmd->sessionId = sessionId;
651 pScanCmd->u.scanCmd.callback = callback;
652 pScanCmd->u.scanCmd.pContext = pContext;
653 if(eCSR_SCAN_REQUEST_11D_SCAN == pScanRequest->requestType)
654 {
655 pScanCmd->u.scanCmd.reason = eCsrScan11d1;
656 }
657 else if((eCSR_SCAN_REQUEST_FULL_SCAN == pScanRequest->requestType) ||
658 (eCSR_SCAN_P2P_DISCOVERY == pScanRequest->requestType)
659#ifdef SOFTAP_CHANNEL_RANGE
660 ||(eCSR_SCAN_SOFTAP_CHANNEL_RANGE == pScanRequest->requestType)
661#endif
662 )
663 {
664 pScanCmd->u.scanCmd.reason = eCsrScanUserRequest;
665 }
666 else if(eCSR_SCAN_HO_BG_SCAN == pScanRequest->requestType)
667 {
668 pScanCmd->u.scanCmd.reason = eCsrScanBgScan;
669 }
670 else if(eCSR_SCAN_HO_PROBE_SCAN == pScanRequest->requestType)
671 {
672 pScanCmd->u.scanCmd.reason = eCsrScanProbeBss;
673 }
674#if defined WLAN_FEATURE_P2P
675 else if(eCSR_SCAN_P2P_FIND_PEER == pScanRequest->requestType)
676 {
677 pScanCmd->u.scanCmd.reason = eCsrScanP2PFindPeer;
678 }
679#endif
680 else
681 {
682 pScanCmd->u.scanCmd.reason = eCsrScanIdleScan;
683 }
684 if(pScanRequest->minChnTime == 0 && pScanRequest->maxChnTime == 0)
685 {
686 //The caller doesn't set the time correctly. Set it here
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700687 csrSetDefaultScanTiming(pMac, pScanRequest->scanType, pScanRequest);
688 }
689#ifdef WLAN_AP_STA_CONCURRENCY
690 if(pScanRequest->restTime == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700691 {
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700692 //Need to set restTime only if at least one session is connected
693 if(csrIsAnySessionConnected(pMac))
Jeff Johnson295189b2012-06-20 16:38:30 -0700694 {
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700695 pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc;
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 }
697 }
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -0700698#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -0700699 /*For Standalone wlan : channel time will remain the same.
700 For BTC with A2DP up: Channel time = Channel time * 2 , if station is not already associated.
701 This has been done to provide a larger scan window for faster connection during btc.Else Scan is seen
702 to take a long time.
703 For BTC with A2DP up: Channel time will not be doubled, if station is already associated.
704 */
705 status = csrRoamGetConnectState(pMac,sessionId,&ConnectState);
706 if(pMac->btc.fA2DPUp &&
707 (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED != ConnectState) &&
708 (eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED != ConnectState))
709 {
710 pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1;
711 pScanRequest->minChnTime = pScanRequest->minChnTime << 1;
712 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 //Need to make the following atomic
714 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
715
716 if(pScanRequestID)
717 {
718 *pScanRequestID = pScanCmd->u.scanCmd.scanID;
719 }
720
721 //Tush : If it is the first scan request from HDD, CSR checks if it is for 11d.
722 // If it is not, CSR will save the scan request in the pending cmd queue
723 // & issue an 11d scan request to PE.
724 if(((0 == pScanCmd->u.scanCmd.scanID)
725 && (eCSR_SCAN_REQUEST_11D_SCAN != pScanRequest->requestType))
726#ifdef SOFTAP_CHANNEL_RANGE
727 && (eCSR_SCAN_SOFTAP_CHANNEL_RANGE != pScanRequest->requestType)
728#endif
729 && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d)
730 )
731 {
732 tSmeCmd *p11dScanCmd;
733 tCsrScanRequest scanReq;
734 tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
735
736 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
737
738 p11dScanCmd = csrGetCommandBuffer(pMac);
739 if(p11dScanCmd)
740 {
741 tANI_U32 numChn = pMac->scan.baseChannels.numChannels;
742
743 palZeroMemory(pMac->hHdd, &p11dScanCmd->u.scanCmd, sizeof(tScanCmd));
744 status = palAllocateMemory( pMac->hHdd, (void **)&pChnInfo->ChannelList, numChn );
745 if( !HAL_STATUS_SUCCESS( status ) )
746 {
747 break;
748 }
749 status = palCopyMemory( pMac->hHdd, pChnInfo->ChannelList,
750 pMac->scan.baseChannels.channelList, numChn );
751 if( !HAL_STATUS_SUCCESS( status ) )
752 {
753 palFreeMemory( pMac->hHdd, pChnInfo->ChannelList );
754 pChnInfo->ChannelList = NULL;
755 break;
756 }
757 pChnInfo->numOfChannels = (tANI_U8)numChn;
758 p11dScanCmd->command = eSmeCommandScan;
759 p11dScanCmd->u.scanCmd.callback = NULL;
760 p11dScanCmd->u.scanCmd.pContext = NULL;
761 p11dScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++;
762 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
763
764 if ( csrIs11dSupported(pMac) )
765 {
766 scanReq.scanType = eSIR_PASSIVE_SCAN;
767 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
768 p11dScanCmd->u.scanCmd.reason = eCsrScan11d1;
769 scanReq.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
770 scanReq.minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
771 }
772 else
773 {
774 scanReq.scanType = eSIR_ACTIVE_SCAN;
775 scanReq.requestType = eCSR_SCAN_IDLE_MODE_SCAN;
776 p11dScanCmd->u.scanCmd.reason = eCsrScanIdleScan;
777 scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
778 scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
779 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 status = csrScanCopyRequest(pMac, &p11dScanCmd->u.scanCmd.u.scanRequest, &scanReq);
782 //Free the channel list
783 palFreeMemory( pMac->hHdd, pChnInfo->ChannelList );
784
785 if(HAL_STATUS_SUCCESS(status))
786 {
787 //Start process the command
788#ifdef WLAN_AP_STA_CONCURRENCY
789 status = csrQueueScanRequest(pMac, p11dScanCmd);
790#else
791 status = csrQueueSmeCommand(pMac, p11dScanCmd, eANI_BOOLEAN_FALSE);
792#endif
793 if( !HAL_STATUS_SUCCESS( status ) )
794 {
795 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
796 break;
797 }
798 }
799 else
800 {
801 break;
802 }
803 }
804 else
805 {
806 //error
807 break;
808 }
809 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700810
811 //Scan only 2G Channels if set in ini file
812 //This is mainly to reduce the First Scan duration
813 //Once we turn on Wifi
814 if(pMac->scan.fFirstScanOnly2GChnl)
815 {
816 csrScan2GOnyRequest(pMac, pScanCmd, pScanRequest);
817 }
818
Jeff Johnson295189b2012-06-20 16:38:30 -0700819 status = csrScanCopyRequest(pMac, &pScanCmd->u.scanCmd.u.scanRequest, pScanRequest);
820 if(HAL_STATUS_SUCCESS(status))
821 {
822 //Start process the command
823#ifdef WLAN_AP_STA_CONCURRENCY
824 status = csrQueueScanRequest(pMac,pScanCmd);
825#else
826 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
827#endif
828 if( !HAL_STATUS_SUCCESS( status ) )
829 {
830 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
831 break;
832 }
833 }
834 else
835 {
836 smsLog( pMac, LOGE, FL(" fail to copy request status = %d\n"), status );
837 break;
838 }
839 }
840 else
841 {
842 //log error
843 break;
844 }
845 }
846 } while(0);
847 if(!HAL_STATUS_SUCCESS(status) && pScanCmd)
848 {
849 if( eCsrScanIdleScan == pScanCmd->u.scanCmd.reason )
850 {
851 //Set the flag back for restarting idle scan
852 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
853 }
854 csrReleaseCommandScan(pMac, pScanCmd);
855 }
856
857 return (status);
858}
859
860
861eHalStatus csrScanRequestResult(tpAniSirGlobal pMac)
862{
863 eHalStatus status = eHAL_STATUS_SUCCESS;
864 tSmeCmd *pScanCmd;
865
866 if(pMac->scan.fScanEnable)
867 {
868 pScanCmd = csrGetCommandBuffer(pMac);
869 if(pScanCmd)
870 {
871 pScanCmd->command = eSmeCommandScan;
872 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
873 pScanCmd->u.scanCmd.callback = NULL;
874 pScanCmd->u.scanCmd.pContext = NULL;
875 pScanCmd->u.scanCmd.reason = eCsrScanGetResult;
876 //Need to make the following atomic
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700877 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around
Jeff Johnson295189b2012-06-20 16:38:30 -0700878 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
879 if( !HAL_STATUS_SUCCESS( status ) )
880 {
881 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
882 csrReleaseCommandScan(pMac, pScanCmd);
883 }
884 }
885 else
886 {
887 //log error
888 smsLog(pMac, LOGE, FL("can not obtain a common buffer\n"));
889 status = eHAL_STATUS_RESOURCES;
890 }
891 }
892
893 return (status);
894}
895
896
897eHalStatus csrScanAllChannels(tpAniSirGlobal pMac, eCsrRequestType reqType)
898{
899 eHalStatus status = eHAL_STATUS_SUCCESS;
900 tANI_U32 scanId;
901 tCsrScanRequest scanReq;
902
903 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
904 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
905 scanReq.scanType = eSIR_ACTIVE_SCAN;
906 scanReq.requestType = reqType;
907 scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
908 scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
909 //Scan with invalid sessionId.
910 //This results in SME using the first available session to scan.
911 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
912 &scanId, NULL, NULL);
913
914 return (status);
915}
916
917
918
919
920eHalStatus csrIssueRoamAfterLostlinkScan(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamReason reason)
921{
922 eHalStatus status = eHAL_STATUS_FAILURE;
923 tScanResultHandle hBSSList = NULL;
924 tCsrScanResultFilter *pScanFilter = NULL;
925 tANI_U32 roamId = 0;
926 tCsrRoamProfile *pProfile = NULL;
927 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
928
Jeff Johnson32d95a32012-09-10 13:15:23 -0700929 if(!pSession)
930 {
931 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
932 return eHAL_STATUS_FAILURE;
933 }
934
Jeff Johnson295189b2012-06-20 16:38:30 -0700935 do
936 {
937 smsLog(pMac, LOG1, " csrIssueRoamAfterLostlinkScan called\n");
938 if(pSession->fCancelRoaming)
939 {
940 smsLog(pMac, LOGW, " lostlink roaming is cancelled\n");
941 csrScanStartIdleScan(pMac);
942 status = eHAL_STATUS_SUCCESS;
943 break;
944 }
945 //Here is the profile we need to connect to
946 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
947 if(!HAL_STATUS_SUCCESS(status))
948 break;
949 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
950 if(NULL == pSession->pCurRoamProfile)
951 {
952 pScanFilter->EncryptionType.numEntries = 1;
953 pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
954 }
955 else
956 {
957 //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect
958 status = palAllocateMemory(pMac->hHdd, (void **)&pProfile, sizeof(tCsrRoamProfile));
959 if(!HAL_STATUS_SUCCESS(status))
960 break;
961 palZeroMemory(pMac->hHdd, pProfile, sizeof(tCsrRoamProfile));
962 status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile);
963 if(!HAL_STATUS_SUCCESS(status))
964 break;
965 status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
966 }//We have a profile
967 roamId = GET_NEXT_ROAM_ID(&pMac->roam);
968 if(HAL_STATUS_SUCCESS(status))
969 {
970 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
971 if(HAL_STATUS_SUCCESS(status))
972 {
973 if(eCsrLostLink1 == reason)
974 {
975 //we want to put the last connected BSS to the very beginning, if possible
976 csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList);
977 }
978 status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, reason,
979 roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
980 if(!HAL_STATUS_SUCCESS(status))
981 {
982 csrScanResultPurge(pMac, hBSSList);
983 }
984 }//Have scan result
985 }
986 }while(0);
987 if(pScanFilter)
988 {
989 //we need to free memory for filter if profile exists
990 csrFreeScanFilter(pMac, pScanFilter);
991 palFreeMemory(pMac->hHdd, pScanFilter);
992 }
993 if(NULL != pProfile)
994 {
995 csrReleaseProfile(pMac, pProfile);
996 palFreeMemory(pMac->hHdd, (void *)pProfile);
997 }
998
999 return (status);
1000}
1001
1002
Jeff Johnson32d95a32012-09-10 13:15:23 -07001003eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, void *callback, void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07001004{
1005 eHalStatus status = eHAL_STATUS_SUCCESS;
1006 tSmeCmd *pScanCmd;
1007
1008 if(pMac->scan.fScanEnable)
1009 {
1010 pScanCmd = csrGetCommandBuffer(pMac);
1011 if(pScanCmd)
1012 {
1013 pScanCmd->command = eSmeCommandScan;
1014 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
Jeff Johnson32d95a32012-09-10 13:15:23 -07001015 pScanCmd->u.scanCmd.callback = callback;
1016 pScanCmd->u.scanCmd.pContext = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07001017 pScanCmd->u.scanCmd.reason = eCsrScanGetScanChnInfo;
1018 //Need to make the following atomic
1019 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
1020 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
1021 if( !HAL_STATUS_SUCCESS( status ) )
1022 {
1023 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
1024 csrReleaseCommandScan(pMac, pScanCmd);
1025 }
1026 }
1027 else
1028 {
1029 //log error
1030 smsLog(pMac, LOGE, FL("can not obtain a common buffer\n"));
1031 status = eHAL_STATUS_RESOURCES;
1032 }
1033 }
1034
1035 return (status);
1036}
1037
1038
1039eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId)
1040{
1041 eHalStatus status = eHAL_STATUS_FAILURE;
1042 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1043
Jeff Johnson32d95a32012-09-10 13:15:23 -07001044 if(!pSession)
1045 {
1046 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
1047 return eHAL_STATUS_FAILURE;
1048 }
1049
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 smsLog(pMac, LOGW, " Lostlink scan 1 failed\n");
1051 if(pSession->fCancelRoaming)
1052 {
1053 csrScanStartIdleScan(pMac);
1054 }
1055 else if(pSession->pCurRoamProfile)
1056 {
1057 //We fail lostlink1 but there may be other BSS in the cached result fit the profile. Give it a try first
1058 if(pSession->pCurRoamProfile->SSIDs.numOfSSIDs == 0 ||
1059 pSession->pCurRoamProfile->SSIDs.numOfSSIDs > 1)
1060 {
1061 //try lostlink scan2
1062 status = csrScanRequestLostLink2(pMac, sessionId);
1063 }
1064 else if(!pSession->pCurRoamProfile->ChannelInfo.ChannelList ||
1065 pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0)
1066 {
1067 //go straight to lostlink scan3
1068 status = csrScanRequestLostLink3(pMac, sessionId);
1069 }
1070 else
1071 {
1072 //we are done with lostlink
1073 if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
1074 {
1075 csrScanStartIdleScan(pMac);
1076 }
1077 status = eHAL_STATUS_SUCCESS;
1078 }
1079 }
1080 else
1081 {
1082 status = csrScanRequestLostLink3(pMac, sessionId);
1083 }
1084
1085 return (status);
1086}
1087
1088
1089
1090eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId)
1091{
1092 eHalStatus status = eHAL_STATUS_FAILURE;
1093 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1094
Jeff Johnson32d95a32012-09-10 13:15:23 -07001095 if(!pSession)
1096 {
1097 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
1098 return eHAL_STATUS_FAILURE;
1099 }
1100
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 smsLog(pMac, LOGW, " Lostlink scan 2 failed\n");
1102 if(pSession->fCancelRoaming)
1103 {
1104 csrScanStartIdleScan(pMac);
1105 }
1106 else if(!pSession->pCurRoamProfile || !pSession->pCurRoamProfile->ChannelInfo.ChannelList ||
1107 pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0)
1108 {
1109 //try lostlink scan3
1110 status = csrScanRequestLostLink3(pMac, sessionId);
1111 }
1112 else
1113 {
1114 //we are done with lostlink
1115 if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
1116 {
1117 csrScanStartIdleScan(pMac);
1118 }
1119 }
1120
1121 return (status);
1122}
1123
1124
1125
1126eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId)
1127{
1128 eHalStatus status = eHAL_STATUS_SUCCESS;
1129
1130 smsLog(pMac, LOGW, " Lostlink scan 3 failed\n");
1131 if(eANI_BOOLEAN_TRUE == csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
1132 {
1133 //we are done with lostlink
1134 csrScanStartIdleScan(pMac);
1135 }
1136
1137 return (status);
1138}
1139
1140
1141
1142
1143//Lostlink1 scan is to actively scan the last connected profile's SSID on all matched BSS channels.
1144//If no roam profile (it should not), it is like lostlinkscan3
1145eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId )
1146{
1147 eHalStatus status = eHAL_STATUS_SUCCESS;
1148 tSmeCmd *pCommand = NULL;
1149 tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1150 tCsrScanResultFilter *pScanFilter = NULL;
1151 tScanResultHandle hBSSList = NULL;
1152 tCsrScanResultInfo *pScanResult = NULL;
1153 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1154
Jeff Johnson32d95a32012-09-10 13:15:23 -07001155 if(!pSession)
1156 {
1157 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
1158 return eHAL_STATUS_FAILURE;
1159 }
1160
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 smsLog(pMac, LOGW, FL(" called\n"));
1162 do
1163 {
1164 pCommand = csrGetCommandBuffer(pMac);
1165 if(!pCommand)
1166 {
1167 status = eHAL_STATUS_RESOURCES;
1168 break;
1169 }
1170 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
1171 pCommand->command = eSmeCommandScan;
1172 pCommand->sessionId = (tANI_U8)sessionId;
1173 pCommand->u.scanCmd.reason = eCsrScanLostLink1;
1174 pCommand->u.scanCmd.callback = NULL;
1175 pCommand->u.scanCmd.pContext = NULL;
1176 pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
1177 pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
1178 pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
1179 if(pSession->connectedProfile.SSID.length)
1180 {
1181 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo));
1182 if(!HAL_STATUS_SUCCESS(status))
1183 {
1184 break;
1185 }
1186 pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1;
1187 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID,
1188 &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
1189 }
1190 else
1191 {
1192 pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 0;
1193 }
1194 if(pSession->pCurRoamProfile)
1195 {
1196 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
1197 if(!HAL_STATUS_SUCCESS(status))
1198 {
1199 break;
1200 }
1201 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
1202 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
1203 if(!HAL_STATUS_SUCCESS(status))
1204 {
1205 break;
1206 }
1207 //Don't change variable status here because whether we can get result or not, the command goes to PE.
1208 //The status is also used to indicate whether the command is queued. Not success meaning not queue
1209 if(HAL_STATUS_SUCCESS((csrScanGetResult(pMac, pScanFilter, &hBSSList))) && hBSSList)
1210 {
1211 tANI_U8 i, nChn = 0;
1212 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
1213 WNI_CFG_VALID_CHANNEL_LIST_LEN);
1214 if(!HAL_STATUS_SUCCESS(status))
1215 {
1216 break;
1217 }
1218 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) &&
1219 nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN)
1220 {
1221 for(i = 0; i < nChn; i++)
1222 {
1223 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] ==
1224 pScanResult->BssDescriptor.channelId)
1225 {
1226 break;
1227 }
1228 }
1229 if(i == nChn)
1230 {
1231 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId;
1232 }
1233 }
1234 //Include the last connected BSS' channel
1235 if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel))
1236 {
1237 for(i = 0; i < nChn; i++)
1238 {
1239 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] ==
1240 pSession->connectedProfile.operationChannel)
1241 {
1242 break;
1243 }
1244 }
1245 if(i == nChn)
1246 {
1247 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pSession->connectedProfile.operationChannel;
1248 }
1249 }
1250 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn;
1251 }
1252 else
1253 {
1254 if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel))
1255 {
1256 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
1257 1);
1258 //just try the last connected channel
1259 if(HAL_STATUS_SUCCESS(status))
1260 {
1261 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0] = pSession->connectedProfile.operationChannel;
1262 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1;
1263 }
1264 else
1265 {
1266 break;
1267 }
1268 }
1269 }
1270 }
1271 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
1272 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
1273 if( !HAL_STATUS_SUCCESS( status ) )
1274 {
1275 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
1276 break;
1277 }
1278 } while( 0 );
1279
1280 if(!HAL_STATUS_SUCCESS(status))
1281 {
1282 smsLog(pMac, LOGW, " csrScanRequestLostLink1 failed with status %d\n", status);
1283 if(pCommand)
1284 {
1285 csrReleaseCommandScan(pMac, pCommand);
1286 }
1287 status = csrScanHandleFailedLostlink1( pMac, sessionId );
1288 }
1289 if(pScanFilter)
1290 {
1291 csrFreeScanFilter(pMac, pScanFilter);
1292 palFreeMemory(pMac->hHdd, pScanFilter);
1293 }
1294 if(hBSSList)
1295 {
1296 csrScanResultPurge(pMac, hBSSList);
1297 }
1298
1299 return( status );
1300}
1301
1302
1303//Lostlink2 scan is to actively scan the all SSIDs of the last roaming profile's on all matched BSS channels.
1304//Since MAC doesn't support multiple SSID, we scan all SSIDs and filter them afterwards
1305eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId )
1306{
1307 eHalStatus status = eHAL_STATUS_SUCCESS;
1308 tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1309 tCsrScanResultFilter *pScanFilter = NULL;
1310 tScanResultHandle hBSSList = NULL;
1311 tCsrScanResultInfo *pScanResult = NULL;
1312 tSmeCmd *pCommand = NULL;
1313 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1314
Jeff Johnson32d95a32012-09-10 13:15:23 -07001315 if(!pSession)
1316 {
1317 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
1318 return eHAL_STATUS_FAILURE;
1319 }
1320
Jeff Johnson295189b2012-06-20 16:38:30 -07001321 smsLog(pMac, LOGW, FL(" called\n"));
1322 do
1323 {
1324 pCommand = csrGetCommandBuffer(pMac);
1325 if(!pCommand)
1326 {
1327 status = eHAL_STATUS_RESOURCES;
1328 break;
1329 }
1330 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
1331 pCommand->command = eSmeCommandScan;
1332 pCommand->sessionId = (tANI_U8)sessionId;
1333 pCommand->u.scanCmd.reason = eCsrScanLostLink2;
1334 pCommand->u.scanCmd.callback = NULL;
1335 pCommand->u.scanCmd.pContext = NULL;
1336 pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
1337 pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
1338 pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
1339 if(pSession->pCurRoamProfile)
1340 {
1341 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
1342 if(!HAL_STATUS_SUCCESS(status))
1343 {
1344 break;
1345 }
1346 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
1347 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
1348 if(!HAL_STATUS_SUCCESS(status))
1349 {
1350 break;
1351 }
1352 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
1353 if(!HAL_STATUS_SUCCESS(status))
1354 {
1355 break;
1356 }
1357 if(hBSSList)
1358 {
1359 tANI_U8 i, nChn = 0;
1360 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
1361 WNI_CFG_VALID_CHANNEL_LIST_LEN);
1362 if(!HAL_STATUS_SUCCESS(status))
1363 {
1364 break;
1365 }
1366 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) &&
1367 nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN)
1368 {
1369 for(i = 0; i < nChn; i++)
1370 {
1371 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] ==
1372 pScanResult->BssDescriptor.channelId)
1373 {
1374 break;
1375 }
1376 }
1377 if(i == nChn)
1378 {
1379 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId;
1380 }
1381 }
1382 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn;
1383 }
1384 }
1385 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
1386 //Put to the head in pending queue
1387 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE);
1388 if( !HAL_STATUS_SUCCESS( status ) )
1389 {
1390 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
1391 break;
1392 }
1393 } while( 0 );
1394
1395 if(!HAL_STATUS_SUCCESS(status))
1396 {
1397 smsLog(pMac, LOGW, " csrScanRequestLostLink2 failed with status %d\n", status);
1398 if(pCommand)
1399 {
1400 csrReleaseCommandScan(pMac, pCommand);
1401 }
1402 status = csrScanHandleFailedLostlink2( pMac, sessionId );
1403 }
1404 if(pScanFilter)
1405 {
1406 csrFreeScanFilter(pMac, pScanFilter);
1407 palFreeMemory(pMac->hHdd, pScanFilter);
1408 }
1409 if(hBSSList)
1410 {
1411 csrScanResultPurge(pMac, hBSSList);
1412 }
1413
1414 return( status );
1415}
1416
1417
1418//To actively scan all valid channels
1419eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId )
1420{
1421 eHalStatus status = eHAL_STATUS_SUCCESS;
1422 tSmeCmd *pCommand;
1423 tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1424
1425 smsLog(pMac, LOGW, FL(" called\n"));
1426 do
1427 {
1428 pCommand = csrGetCommandBuffer(pMac);
1429 if(!pCommand)
1430 {
1431 status = eHAL_STATUS_RESOURCES;
1432 break;
1433 }
1434 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
1435 pCommand->command = eSmeCommandScan;
1436 pCommand->sessionId = (tANI_U8)sessionId;
1437 pCommand->u.scanCmd.reason = eCsrScanLostLink3;
1438 pCommand->u.scanCmd.callback = NULL;
1439 pCommand->u.scanCmd.pContext = NULL;
1440 pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
1441 pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
1442 pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
1443 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid));
1444 //Put to the head of pending queue
1445 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE);
1446 if( !HAL_STATUS_SUCCESS( status ) )
1447 {
1448 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
1449 break;
1450 }
1451 } while( 0 );
1452 if(!HAL_STATUS_SUCCESS(status))
1453 {
1454 smsLog(pMac, LOGW, " csrScanRequestLostLink3 failed with status %d\n", status);
1455 if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE))
1456 {
1457 csrScanStartIdleScan(pMac);
1458 }
1459 if(pCommand)
1460 {
1461 csrReleaseCommandScan(pMac, pCommand);
1462 }
1463 }
1464
1465 return( status );
1466}
1467
1468
1469eHalStatus csrScanHandleSearchForSSID(tpAniSirGlobal pMac, tSmeCmd *pCommand)
1470{
1471 eHalStatus status = eHAL_STATUS_FAILURE;
1472 tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE;
1473 tCsrScanResultFilter *pScanFilter = NULL;
1474 tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
1475 tANI_U32 sessionId = pCommand->sessionId;
1476#ifdef FEATURE_WLAN_BTAMP_UT_RF
1477 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1478#endif
1479 do
1480 {
1481 //If there is roam command waiting, ignore this roam because the newer roam command is the one to execute
1482 if(csrIsRoamCommandWaitingForSession(pMac, sessionId))
1483 {
1484 smsLog(pMac, LOGW, FL(" aborts because roam command waiting\n"));
1485 break;
1486 }
1487 if(pProfile == NULL)
1488 break;
1489 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
1490 if(!HAL_STATUS_SUCCESS(status))
1491 break;
1492 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
1493 status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
1494 if(!HAL_STATUS_SUCCESS(status))
1495 break;
1496 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
1497 if(!HAL_STATUS_SUCCESS(status))
1498 break;
1499 status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued,
1500 pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
1501 if(!HAL_STATUS_SUCCESS(status))
1502 {
1503 break;
1504 }
1505 }while(0);
1506 if(!HAL_STATUS_SUCCESS(status))
1507 {
1508 if(CSR_INVALID_SCANRESULT_HANDLE != hBSSList)
1509 {
1510 csrScanResultPurge(pMac, hBSSList);
1511 }
1512 //We haven't done anything to this profile
1513 csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId,
1514 eCSR_ROAM_ASSOCIATION_FAILURE, eCSR_ROAM_RESULT_FAILURE);
1515 //In case we have nothing else to do, restart idle scan
1516 if(csrIsConnStateDisconnected(pMac, sessionId) && !csrIsRoamCommandWaiting(pMac))
1517 {
1518 status = csrScanStartIdleScan(pMac);
1519 }
1520#ifdef FEATURE_WLAN_BTAMP_UT_RF
1521 //In case of WDS station, let it retry.
1522 if( CSR_IS_WDS_STA(pProfile) )
1523 {
1524 //Save the roma profile so we can retry
1525 csrFreeRoamProfile( pMac, sessionId );
1526 if (HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd,
1527 (void **)&pSession->pCurRoamProfile,
1528 sizeof(tCsrRoamProfile))))
1529 {
1530 palZeroMemory(pMac->hHdd, pSession->pCurRoamProfile, sizeof(tCsrRoamProfile));
1531 csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile);
1532 }
1533 csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD);
1534 }
1535#endif
1536 }
1537 if(pScanFilter)
1538 {
1539 csrFreeScanFilter(pMac, pScanFilter);
1540 palFreeMemory(pMac->hHdd, pScanFilter);
1541 }
1542
1543 return (status);
1544}
1545
1546
1547eHalStatus csrScanHandleSearchForSSIDFailure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
1548{
1549 eHalStatus status = eHAL_STATUS_SUCCESS;
1550 tANI_U32 sessionId = pCommand->sessionId;
1551 tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
1552 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1553
Jeff Johnson32d95a32012-09-10 13:15:23 -07001554 if(!pSession)
1555 {
1556 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
1557 return eHAL_STATUS_FAILURE;
1558 }
1559
Jeff Johnson295189b2012-06-20 16:38:30 -07001560#if defined(WLAN_DEBUG)
1561 if(pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs == 1)
1562 {
1563 char str[36];
1564 palCopyMemory(pMac->hHdd, str, pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.ssId,
1565 pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length);
1566 str[pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length] = 0;
1567 smsLog(pMac, LOGW, FL(" SSID = %s\n"), str);
1568 }
1569#endif
1570 //Check whether it is for start ibss. No need to do anything if it is a JOIN request
1571 if(pProfile && CSR_IS_START_IBSS(pProfile))
1572 {
1573 status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued,
1574 pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
1575 if(!HAL_STATUS_SUCCESS(status))
1576 {
1577 smsLog(pMac, LOGE, FL("failed to issue startIBSS command with status = 0x%08X\n"), status);
1578 csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
1579 }
1580 }
1581 else
1582 {
1583 eCsrRoamResult roamResult = eCSR_ROAM_RESULT_FAILURE;
1584
1585 if(csrIsConnStateDisconnected(pMac, sessionId) &&
1586 !csrIsRoamCommandWaitingForSession(pMac, sessionId))
1587 {
1588 status = csrScanStartIdleScan(pMac);
1589 }
1590 if((NULL == pProfile) || !csrIsBssTypeIBSS(pProfile->BSSType))
1591 {
1592 //Only indicate assoc_completion if we indicate assoc_start.
1593 if(pSession->bRefAssocStartCnt > 0)
1594 {
1595 tCsrRoamInfo *pRoamInfo = NULL, roamInfo;
1596 palZeroMemory(pMac->hHdd, &roamInfo, sizeof(tCsrRoamInfo));
1597 pRoamInfo = &roamInfo;
1598 if(pCommand->u.roamCmd.pRoamBssEntry)
1599 {
1600 tCsrScanResult *pScanResult =
1601 GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
1602 tCsrScanResult, Link);
1603 roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor;
1604 }
1605 roamInfo.statusCode = pSession->joinFailStatusCode.statusCode;
1606 roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode;
1607 pSession->bRefAssocStartCnt--;
1608 csrRoamCallCallback(pMac, sessionId, pRoamInfo,
1609 pCommand->u.scanCmd.roamId,
1610 eCSR_ROAM_ASSOCIATION_COMPLETION,
1611 eCSR_ROAM_RESULT_FAILURE);
1612 }
Madan Mohan Koyyalamudiee255f12012-09-28 15:41:19 -07001613 else
1614 {
1615 csrRoamCallCallback(pMac, sessionId, NULL,
1616 pCommand->u.scanCmd.roamId,
1617 eCSR_ROAM_ASSOCIATION_FAILURE,
1618 eCSR_ROAM_RESULT_FAILURE);
1619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001620#ifdef FEATURE_WLAN_BTAMP_UT_RF
1621 //In case of WDS station, let it retry.
1622 if( CSR_IS_WDS_STA(pProfile) )
1623 {
1624 //Save the roma profile so we can retry
1625 csrFreeRoamProfile( pMac, sessionId );
1626 if (HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd,
1627 (void **)&pSession->pCurRoamProfile,
1628 sizeof(tCsrRoamProfile))))
1629 {
1630 palZeroMemory(pMac->hHdd, pSession->pCurRoamProfile, sizeof(tCsrRoamProfile));
1631 csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile);
1632 }
1633 csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD);
1634 }
1635#endif
1636 }
1637 else
1638 {
1639 roamResult = eCSR_ROAM_RESULT_IBSS_START_FAILED;
1640 }
1641 csrRoamCompletion(pMac, sessionId, NULL, pCommand, roamResult, eANI_BOOLEAN_FALSE);
1642 }
1643
1644 return (status);
1645}
1646
1647
1648//After scan for cap changes, issue a roaming command to either reconnect to the AP or pick another one to connect
1649eHalStatus csrScanHandleCapChangeScanComplete(tpAniSirGlobal pMac, tANI_U32 sessionId)
1650{
1651 eHalStatus status = eHAL_STATUS_FAILURE;
1652 tScanResultHandle hBSSList = NULL;
1653 tCsrScanResultFilter *pScanFilter = NULL;
1654 tANI_U32 roamId = 0;
1655 tCsrRoamProfile *pProfile = NULL;
1656 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
1657
1658 do
1659 {
1660 //Here is the profile we need to connect to
1661 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
1662 if(!HAL_STATUS_SUCCESS(status))
1663 break;
1664 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
1665 if(NULL == pSession) break;
1666 if(NULL == pSession->pCurRoamProfile)
1667 {
1668 pScanFilter->EncryptionType.numEntries = 1;
1669 pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
1670 }
1671 else
1672 {
1673 //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect
1674 status = palAllocateMemory(pMac->hHdd, (void **)&pProfile, sizeof(tCsrRoamProfile));
1675 if(!HAL_STATUS_SUCCESS(status))
1676 break;
1677 status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile);
1678 if(!HAL_STATUS_SUCCESS(status))
1679 break;
1680 status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter);
1681 }//We have a profile
1682 roamId = GET_NEXT_ROAM_ID(&pMac->roam);
1683 if(HAL_STATUS_SUCCESS(status))
1684 {
1685 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
1686 if(HAL_STATUS_SUCCESS(status))
1687 {
1688 //we want to put the last connected BSS to the very beginning, if possible
1689 csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList);
1690 status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList,
1691 eCsrCapsChange, 0, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
1692 if(!HAL_STATUS_SUCCESS(status))
1693 {
1694 csrScanResultPurge(pMac, hBSSList);
1695 }
1696 }//Have scan result
1697 else
1698 {
1699 smsLog(pMac, LOGW, FL("cannot find matching BSS of %02X-%02X-%02X-%02X-%02X-%02X\n"),
1700 pSession->connectedProfile.bssid[0],
1701 pSession->connectedProfile.bssid[1],
1702 pSession->connectedProfile.bssid[2],
1703 pSession->connectedProfile.bssid[3],
1704 pSession->connectedProfile.bssid[4],
1705 pSession->connectedProfile.bssid[5]);
1706 //Disconnect
1707 csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
1708 }
1709 }
1710 }while(0);
1711 if(pScanFilter)
1712 {
1713 csrFreeScanFilter(pMac, pScanFilter);
1714 palFreeMemory(pMac->hHdd, pScanFilter);
1715 }
1716 if(NULL != pProfile)
1717 {
1718 csrReleaseProfile(pMac, pProfile);
1719 palFreeMemory(pMac->hHdd, pProfile);
1720 }
1721
1722 return (status);
1723}
1724
1725
1726
1727eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanList)
1728{
1729 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
1730 tScanResultList *pScanList = (tScanResultList *)hScanList;
1731
1732 if(pScanList)
1733 {
1734 status = csrLLScanPurgeResult(pMac, &pScanList->List);
1735 csrLLClose(&pScanList->List);
1736 palFreeMemory(pMac->hHdd, pScanList);
1737 }
1738 return (status);
1739}
1740
1741
1742static tANI_U32 csrGetBssPreferValue(tpAniSirGlobal pMac, int rssi)
1743{
1744 tANI_U32 ret = 0;
1745 int i = CSR_NUM_RSSI_CAT - 1;
1746
1747 while(i >= 0)
1748 {
1749 if(rssi >= pMac->roam.configParam.RSSICat[i])
1750 {
1751 ret = pMac->roam.configParam.BssPreferValue[i];
1752 break;
1753 }
1754 i--;
1755 };
1756
1757 return (ret);
1758}
1759
1760
1761//Return a CapValue base on the capabilities of a BSS
1762static tANI_U32 csrGetBssCapValue(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes)
1763{
1764 tANI_U32 ret = CSR_BSS_CAP_VALUE_NONE;
Madan Mohan Koyyalamudid5026072012-11-30 14:56:21 -08001765#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
1766 if(CSR_IS_ROAM_PREFER_5GHZ(pMac))
1767 {
1768 if((pBssDesc) && CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId))
1769 {
1770 ret += CSR_BSS_CAP_VALUE_5GHZ;
1771 }
1772 }
1773#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 if( pIes )
1775 {
1776 //We only care about 11N capability
1777 if(pIes->HTCaps.present)
1778 {
1779 ret += CSR_BSS_CAP_VALUE_HT;
1780 }
1781 if(CSR_IS_QOS_BSS(pIes))
1782 {
1783 ret += CSR_BSS_CAP_VALUE_WMM;
1784 //Give advantage to UAPSD
1785 if(CSR_IS_UAPSD_BSS(pIes))
1786 {
1787 ret += CSR_BSS_CAP_VALUE_UAPSD;
1788 }
1789 }
1790 }
1791
1792 return (ret);
1793}
1794
1795
1796//To check whther pBss1 is better than pBss2
1797static tANI_BOOLEAN csrIsBetterBss(tCsrScanResult *pBss1, tCsrScanResult *pBss2)
1798{
1799 tANI_BOOLEAN ret;
1800
1801 if(CSR_IS_BETTER_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue))
1802 {
1803 ret = eANI_BOOLEAN_TRUE;
1804 }
1805 else if(CSR_IS_EQUAL_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue))
1806 {
1807 if(CSR_IS_BETTER_CAP_VALUE(pBss1->capValue, pBss2->capValue))
1808 {
1809 ret = eANI_BOOLEAN_TRUE;
1810 }
1811 else
1812 {
1813 ret = eANI_BOOLEAN_FALSE;
1814 }
1815 }
1816 else
1817 {
1818 ret = eANI_BOOLEAN_FALSE;
1819 }
1820
1821 return (ret);
1822}
1823
1824
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001825#ifdef FEATURE_WLAN_LFR
1826//Add the channel to the occupiedChannels array
1827static void csrScanAddToOccupiedChannels(
1828 tpAniSirGlobal pMac,
1829 tCsrScanResult *pResult,
1830 tCsrChannel *pOccupiedChannels,
1831 tDot11fBeaconIEs *pIes)
1832{
1833 eHalStatus status;
1834 tANI_U8 channel;
1835 tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels;
1836 tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList;
1837
1838 channel = pResult->Result.BssDescriptor.channelId;
1839
1840 if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, channel)
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001841 && csrNeighborRoamConnectedProfileMatch(pMac, pResult, pIes))
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001842 {
1843 status = csrAddToChannelListFront(pOccupiedChannelList, numOccupiedChannels, channel);
1844 if(HAL_STATUS_SUCCESS(status))
1845 {
1846 pOccupiedChannels->numChannels++;
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08001847 smsLog(pMac, LOG2, FL("%s: added channel %d to the list (count=%d)\n"),
1848 __func__, channel, pOccupiedChannels->numChannels);
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001849 if (pOccupiedChannels->numChannels > CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN)
1850 pOccupiedChannels->numChannels = CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN;
1851 }
1852 }
1853}
1854#endif
1855
Jeff Johnson295189b2012-06-20 16:38:30 -07001856//Put the BSS into the scan result list
1857//pIes can not be NULL
1858static void csrScanAddResult(tpAniSirGlobal pMac, tCsrScanResult *pResult, tDot11fBeaconIEs *pIes)
1859{
1860 pResult->preferValue = csrGetBssPreferValue(pMac, (int)pResult->Result.BssDescriptor.rssi);
1861 pResult->capValue = csrGetBssCapValue(pMac, &pResult->Result.BssDescriptor, pIes);
1862 csrLLInsertTail( &pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK );
Madan Mohan Koyyalamudi470d2cf2012-09-28 14:43:44 -07001863#ifdef FEATURE_WLAN_LFR
1864 csrScanAddToOccupiedChannels(pMac, pResult, &pMac->scan.occupiedChannels, pIes);
1865#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001866}
1867
1868
1869eHalStatus csrScanGetResult(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult)
1870{
1871 eHalStatus status;
1872 tScanResultList *pRetList;
1873 tCsrScanResult *pResult, *pBssDesc;
1874 tANI_U32 count = 0;
1875 tListElem *pEntry;
1876 tANI_U32 bssLen, allocLen;
1877 eCsrEncryptionType uc = eCSR_ENCRYPT_TYPE_NONE, mc = eCSR_ENCRYPT_TYPE_NONE;
1878 eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
1879 tDot11fBeaconIEs *pIes, *pNewIes;
1880 tANI_BOOLEAN fMatch;
1881
1882 if(phResult)
1883 {
1884 *phResult = CSR_INVALID_SCANRESULT_HANDLE;
1885 }
1886 status = palAllocateMemory(pMac->hHdd, (void **)&pRetList, sizeof(tScanResultList));
1887 if(HAL_STATUS_SUCCESS(status))
1888 {
1889 palZeroMemory(pMac->hHdd, pRetList, sizeof(tScanResultList));
1890 csrLLOpen(pMac->hHdd, &pRetList->List);
1891 pRetList->pCurEntry = NULL;
1892
1893 csrLLLock(&pMac->scan.scanResultList);
1894 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
1895 while( pEntry )
1896 {
1897 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
1898 pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes );
1899 //if pBssDesc->Result.pvIes is NULL, we need to free any memory allocated by csrMatchBSS
1900 //for any error condition, otherwiase, it will be freed later.
1901 //reset
1902 fMatch = eANI_BOOLEAN_FALSE;
1903 pNewIes = NULL;
1904
1905 if(pFilter)
1906 {
1907 fMatch = csrMatchBSS(pMac, &pBssDesc->Result.BssDescriptor, pFilter, &auth, &uc, &mc, &pIes);
1908 if( NULL != pIes )
1909 {
1910 //Only save it when matching
1911 if(fMatch)
1912 {
1913 if( !pBssDesc->Result.pvIes )
1914 {
1915 //csrMatchBSS allocates the memory. Simply pass it and it is freed later
1916 pNewIes = pIes;
1917 }
1918 else
1919 {
1920 //The pIes is allocated by someone else. make a copy
1921 //Only to save parsed IEs if caller provides a filter. Most likely the caller
1922 //is using to for association, hence save the parsed IEs
1923 status = palAllocateMemory(pMac->hHdd, (void **)&pNewIes, sizeof(tDot11fBeaconIEs));
1924 if( HAL_STATUS_SUCCESS( status ) )
1925 {
1926 palCopyMemory( pMac->hHdd, pNewIes, pIes, sizeof( tDot11fBeaconIEs ) );
1927 }
1928 else
1929 {
1930 smsLog(pMac, LOGE, FL(" fail to allocate memory for IEs\n"));
1931 //Need to free memory allocated by csrMatchBSS
1932 if( !pBssDesc->Result.pvIes )
1933 {
1934 palFreeMemory(pMac->hHdd, pIes);
1935 }
1936 break;
1937 }
1938 }
1939 }//fMatch
1940 else if( !pBssDesc->Result.pvIes )
1941 {
1942 palFreeMemory(pMac->hHdd, pIes);
1943 }
1944 }
1945 }
1946 if(NULL == pFilter || fMatch)
1947 {
1948 bssLen = pBssDesc->Result.BssDescriptor.length + sizeof(pBssDesc->Result.BssDescriptor.length);
1949 allocLen = sizeof( tCsrScanResult ) + bssLen;
1950 status = palAllocateMemory(pMac->hHdd, (void **)&pResult, allocLen);
1951 if(!HAL_STATUS_SUCCESS(status))
1952 {
1953 smsLog(pMac, LOGE, FL(" fail to allocate memory for scan result, len=%d\n"), allocLen);
1954 if(pNewIes)
1955 {
1956 palFreeMemory(pMac->hHdd, pNewIes);
1957 }
1958 break;
1959 }
1960 palZeroMemory(pMac->hHdd, pResult, allocLen);
1961 pResult->capValue = pBssDesc->capValue;
1962 pResult->preferValue = pBssDesc->preferValue;
1963 pResult->ucEncryptionType = uc;
1964 pResult->mcEncryptionType = mc;
1965 pResult->authType = auth;
1966 pResult->Result.ssId = pBssDesc->Result.ssId;
1967 pResult->Result.timer = 0;
1968 //save the pIes for later use
1969 pResult->Result.pvIes = pNewIes;
1970 //save bss description
1971 status = palCopyMemory(pMac->hHdd, &pResult->Result.BssDescriptor, &pBssDesc->Result.BssDescriptor, bssLen);
1972 if(!HAL_STATUS_SUCCESS(status))
1973 {
1974 smsLog(pMac, LOGE, FL(" fail to copy memory for scan result\n"));
1975 palFreeMemory(pMac->hHdd, pResult);
1976 if(pNewIes)
1977 {
1978 palFreeMemory(pMac->hHdd, pNewIes);
1979 }
1980 break;
1981 }
1982 //No need to lock pRetList because it is locally allocated and no outside can access it at this time
1983 if(csrLLIsListEmpty(&pRetList->List, LL_ACCESS_NOLOCK))
1984 {
1985 csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_NOLOCK);
1986 }
1987 else
1988 {
1989 //To sort the list
1990 tListElem *pTmpEntry;
1991 tCsrScanResult *pTmpResult;
1992
1993 pTmpEntry = csrLLPeekHead(&pRetList->List, LL_ACCESS_NOLOCK);
1994 while(pTmpEntry)
1995 {
1996 pTmpResult = GET_BASE_ADDR( pTmpEntry, tCsrScanResult, Link );
1997 if(csrIsBetterBss(pResult, pTmpResult))
1998 {
1999 csrLLInsertEntry(&pRetList->List, pTmpEntry, &pResult->Link, LL_ACCESS_NOLOCK);
2000 //To indicate we are done
2001 pResult = NULL;
2002 break;
2003 }
2004 pTmpEntry = csrLLNext(&pRetList->List, pTmpEntry, LL_ACCESS_NOLOCK);
2005 }
2006 if(pResult != NULL)
2007 {
2008 //This one is not better than any one
2009 csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_NOLOCK);
2010 }
2011 }
2012 count++;
2013 }
2014 pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK );
2015 }//while
2016 csrLLUnlock(&pMac->scan.scanResultList);
2017
2018 smsLog(pMac, LOG2, FL("return %d BSS\n"), csrLLCount(&pRetList->List));
2019
2020 if( !HAL_STATUS_SUCCESS(status) || (phResult == NULL) )
2021 {
2022 //Fail or No one wants the result.
2023 csrScanResultPurge(pMac, (tScanResultHandle)pRetList);
2024 }
2025 else
2026 {
2027 if(0 == count)
2028 {
2029 //We are here meaning the there is no match
2030 csrLLClose(&pRetList->List);
2031 palFreeMemory(pMac->hHdd, pRetList);
2032 status = eHAL_STATUS_E_NULL_VALUE;
2033 }
2034 else if(phResult)
2035 {
2036 *phResult = pRetList;
2037 }
2038 }
2039 }//Allocated pRetList
2040
2041 return (status);
2042}
2043
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07002044/*
2045 * NOTE: This routine is being added to make
2046 * sure that scan results are not being flushed
2047 * while roaming. If the scan results are flushed,
2048 * we are unable to recover from
2049 * csrRoamRoamingStateDisassocRspProcessor.
2050 * If it is needed to remove this routine,
2051 * first ensure that we recover gracefully from
2052 * csrRoamRoamingStateDisassocRspProcessor if
2053 * csrScanGetResult returns with a failure because
2054 * of not being able to find the roaming BSS.
2055 */
2056tANI_U8 csrScanFlushDenied(tpAniSirGlobal pMac)
2057{
2058 switch(pMac->roam.neighborRoamInfo.neighborRoamState) {
2059 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2060 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2061 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
2062 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2063 return (pMac->roam.neighborRoamInfo.neighborRoamState);
2064 default:
2065 return 0;
2066 }
2067}
2068
Jeff Johnson295189b2012-06-20 16:38:30 -07002069eHalStatus csrScanFlushResult(tpAniSirGlobal pMac)
2070{
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07002071 tANI_U8 isFlushDenied = csrScanFlushDenied(pMac);
2072 if (isFlushDenied) {
2073 smsLog(pMac, LOGW, "%s: scan flush denied in roam state %d",
2074 __func__, isFlushDenied);
2075 return eHAL_STATUS_FAILURE;
2076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 return ( csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList) );
2078}
2079
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302080eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal pMac, v_BOOL_t flushP2P)
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002081{
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302082 eHalStatus status = eHAL_STATUS_SUCCESS;
2083 tListElem *pEntry,*pFreeElem;
2084 tCsrScanResult *pBssDesc;
2085 tDblLinkList *pList = &pMac->scan.scanResultList;
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002086
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302087 csrLLLock(pList);
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002088
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302089 pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK );
2090 while( pEntry != NULL)
2091 {
2092 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2093 if( flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId,
2094 "DIRECT-", 7) )
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002095 {
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302096 pFreeElem = pEntry;
2097 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
2098 csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK);
2099 csrFreeScanResultEntry( pMac, pBssDesc );
2100 continue;
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002101 }
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302102 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
2103 }
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002104
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302105 csrLLUnlock(pList);
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002106
Madan Mohan Koyyalamudi5850f312012-11-27 19:00:25 +05302107 return (status);
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002108}
2109
Jeff Johnson295189b2012-06-20 16:38:30 -07002110/**
2111 * csrCheck11dChannel
2112 *
2113 *FUNCTION:
2114 * This function is called from csrScanFilter11dResult function and
2115 * compare channel number with given channel list.
2116 *
2117 *LOGIC:
2118 * Check Scan result channel number with CFG channel list
2119 *
2120 *ASSUMPTIONS:
2121 *
2122 *
2123 *NOTE:
2124 *
2125 * @param channelId channel number
2126 * @param pChannelList Pointer to channel list
2127 * @param numChannels Number of channel in channel list
2128 *
2129 * @return Status
2130 */
2131
2132eHalStatus csrCheck11dChannel(tANI_U8 channelId, tANI_U8 *pChannelList, tANI_U32 numChannels)
2133{
2134 eHalStatus status = eHAL_STATUS_FAILURE;
2135 tANI_U8 i = 0;
2136
2137 for (i = 0; i < numChannels; i++)
2138 {
2139 if(pChannelList[ i ] == channelId)
2140 {
2141 status = eHAL_STATUS_SUCCESS;
2142 break;
2143 }
2144 }
2145 return status;
2146}
2147
2148/**
2149 * csrScanFilter11dResult
2150 *
2151 *FUNCTION:
2152 * This function is called from csrApplyCountryInformation function and
2153 * filter scan result based on valid channel list number.
2154 *
2155 *LOGIC:
2156 * Get scan result from scan list and Check Scan result channel number
2157 * with 11d channel list if channel number is found in 11d channel list
2158 * then do not remove scan result entry from scan list
2159 *
2160 *ASSUMPTIONS:
2161 *
2162 *
2163 *NOTE:
2164 *
2165 * @param pMac Pointer to Global MAC structure
2166 *
2167 * @return Status
2168 */
2169
2170eHalStatus csrScanFilter11dResult(tpAniSirGlobal pMac)
2171{
2172 eHalStatus status = eHAL_STATUS_SUCCESS;
2173 tListElem *pEntry,*pTempEntry;
2174 tCsrScanResult *pBssDesc;
2175 tANI_U32 len = sizeof(pMac->roam.validChannelList);
2176
2177 /* Get valid channels list from CFG */
2178 if (!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac,
2179 pMac->roam.validChannelList, &len)))
2180 {
2181 smsLog( pMac, LOG1, "Failed to get Channel list from CFG");
2182 }
2183
2184 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
2185 while( pEntry )
2186 {
2187 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2188 pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry,
2189 LL_ACCESS_LOCK );
2190 if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId,
2191 pMac->roam.validChannelList, len))
2192 {
2193 /* Remove Scan result which does not have 11d channel */
2194 if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry,
2195 LL_ACCESS_LOCK ))
2196 {
2197 csrFreeScanResultEntry( pMac, pBssDesc );
2198 }
2199 }
2200 pEntry = pTempEntry;
2201 }
2202 return status;
2203}
2204
2205
2206eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult)
2207{
2208 eHalStatus status = eHAL_STATUS_SUCCESS;
2209 tScanResultList *pRetList, *pInList = (tScanResultList *)hIn;
2210 tCsrScanResult *pResult, *pScanResult;
2211 tANI_U32 count = 0;
2212 tListElem *pEntry;
2213 tANI_U32 bssLen, allocLen;
2214
2215 if(phResult)
2216 {
2217 *phResult = CSR_INVALID_SCANRESULT_HANDLE;
2218 }
2219 status = palAllocateMemory(pMac->hHdd, (void **)&pRetList, sizeof(tScanResultList));
2220 if(HAL_STATUS_SUCCESS(status))
2221 {
2222 palZeroMemory(pMac->hHdd, pRetList, sizeof(tScanResultList));
2223 csrLLOpen(pMac->hHdd, &pRetList->List);
2224 pRetList->pCurEntry = NULL;
2225 csrLLLock(&pMac->scan.scanResultList);
2226 csrLLLock(&pInList->List);
2227
2228 pEntry = csrLLPeekHead( &pInList->List, LL_ACCESS_NOLOCK );
2229 while( pEntry )
2230 {
2231 pScanResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2232 bssLen = pScanResult->Result.BssDescriptor.length + sizeof(pScanResult->Result.BssDescriptor.length);
2233 allocLen = sizeof( tCsrScanResult ) + bssLen;
2234 status = palAllocateMemory(pMac->hHdd, (void **)&pResult, allocLen);
2235 if(!HAL_STATUS_SUCCESS(status))
2236 {
2237 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2238 count = 0;
2239 break;
2240 }
2241 palZeroMemory(pMac->hHdd, pResult, allocLen);
2242 status = palCopyMemory(pMac->hHdd, &pResult->Result.BssDescriptor, &pScanResult->Result.BssDescriptor, bssLen);
2243 if(!HAL_STATUS_SUCCESS(status))
2244 {
2245 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2246 count = 0;
2247 break;
2248 }
2249 if( pScanResult->Result.pvIes )
2250 {
2251 status = palAllocateMemory(pMac->hHdd, (void **)&pResult->Result.pvIes, sizeof( tDot11fBeaconIEs ));
2252 if(!HAL_STATUS_SUCCESS(status))
2253 {
2254 //Free the memory we allocate above first
2255 palFreeMemory( pMac->hHdd, pResult );
2256 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2257 count = 0;
2258 break;
2259 }
2260 status = palCopyMemory(pMac->hHdd, pResult->Result.pvIes,
2261 pScanResult->Result.pvIes, sizeof( tDot11fBeaconIEs ));
2262 if(!HAL_STATUS_SUCCESS(status))
2263 {
2264 //Free the memory we allocate above first
2265 palFreeMemory( pMac->hHdd, pResult );
2266 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2267 count = 0;
2268 break;
2269 }
2270 }
2271 csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_LOCK);
2272 count++;
2273 pEntry = csrLLNext( &pInList->List, pEntry, LL_ACCESS_NOLOCK );
2274 }//while
2275 csrLLUnlock(&pInList->List);
2276 csrLLUnlock(&pMac->scan.scanResultList);
2277
2278 if(HAL_STATUS_SUCCESS(status))
2279 {
2280 if(0 == count)
2281 {
2282 csrLLClose(&pRetList->List);
2283 palFreeMemory(pMac->hHdd, pRetList);
2284 status = eHAL_STATUS_E_NULL_VALUE;
2285 }
2286 else if(phResult)
2287 {
2288 *phResult = pRetList;
2289 }
2290 }
2291 }//Allocated pRetList
2292
2293 return (status);
2294}
2295
2296
2297
2298eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf )
2299{
2300 eHalStatus status = eHAL_STATUS_SUCCESS;
2301 tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf;
2302
2303 if((eWNI_SME_SCAN_RSP == pMsg->type) || (eWNI_SME_GET_SCANNED_CHANNEL_RSP == pMsg->type))
2304 {
2305 status = csrScanSmeScanResponse( pMac, pMsgBuf );
2306 }
2307 else
2308 {
2309 if( csrIsAnySessionInConnectState( pMac ) )
2310 {
2311 //In case of we are connected, we need to check whether connect status changes
2312 //because scan may also run while connected.
2313 csrRoamCheckForLinkStatusChange( pMac, ( tSirSmeRsp * )pMsgBuf );
2314 }
2315 else
2316 {
2317 smsLog( pMac, LOGW, "Message [0x%04x] received in state, when expecting Scan Response\n", pMsg->type );
2318 }
2319 }
2320
2321 return (status);
2322}
2323
2324
2325
2326void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr, tSirBssDescription *pOldBssDescr)
2327{
2328 int idx, len;
2329 tANI_U8 *pbIe;
2330
2331 //If failed to remove, assuming someone else got it.
2332 if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) &&
2333 (0 == pNewBssDescr->WscIeLen))
2334 {
2335 idx = 0;
2336 len = pOldBssDescr->length - sizeof(tSirBssDescription) +
2337 sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
2338 pbIe = (tANI_U8 *)pOldBssDescr->ieFields;
2339 //Save WPS IE if it exists
2340 pNewBssDescr->WscIeLen = 0;
2341 while(idx < len)
2342 {
2343 if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
2344 (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
2345 {
2346 //Founrd it
2347 if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
2348 {
2349 palCopyMemory(pMac->hHdd, pNewBssDescr->WscIeProbeRsp,
2350 pbIe, pbIe[1] + 2);
2351 pNewBssDescr->WscIeLen = pbIe[1] + 2;
2352 }
2353 break;
2354 }
2355 idx += pbIe[1] + 2;
2356 pbIe += pbIe[1] + 2;
2357 }
2358 }
2359}
2360
2361
2362
2363//pIes may be NULL
2364tANI_BOOLEAN csrRemoveDupBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDescr,
2365 tDot11fBeaconIEs *pIes, tAniSSID *pSsid , v_TIME_t *timer )
2366{
2367 tListElem *pEntry;
2368
2369 tCsrScanResult *pBssDesc;
2370 tANI_BOOLEAN fRC = FALSE;
2371
2372 // Walk through all the chained BssDescriptions. If we find a chained BssDescription that
2373 // matches the BssID of the BssDescription passed in, then these must be duplicate scan
2374 // results for this Bss. In that case, remove the 'old' Bss description from the linked list.
2375 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
2376
2377 while( pEntry )
2378 {
2379 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2380
2381 // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
2382 // matches
2383 if ( csrIsDuplicateBssDescription( pMac, &pBssDesc->Result.BssDescriptor,
2384 pSirBssDescr, pIes ) )
2385 {
2386 pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
2387 ((tANI_S32)pBssDesc->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );
2388 // Remove the 'old' entry from the list....
2389 if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ) )
2390 {
2391 // !we need to free the memory associated with this node
2392 //If failed to remove, assuming someone else got it.
2393 *pSsid = pBssDesc->Result.ssId;
2394 *timer = pBssDesc->Result.timer;
2395 csrCheckNSaveWscIe(pMac, pSirBssDescr, &pBssDesc->Result.BssDescriptor);
2396
2397 csrFreeScanResultEntry( pMac, pBssDesc );
2398 }
2399 else
2400 {
2401 smsLog( pMac, LOGW, FL( " fail to remove entry\n" ) );
2402 }
2403 fRC = TRUE;
2404
2405 // If we found a match, we can stop looking through the list.
2406 break;
2407 }
2408
2409 pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK );
2410 }
2411
2412 return fRC;
2413}
2414
2415
2416eHalStatus csrAddPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
2417 tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
2418{
2419 eHalStatus status = eHAL_STATUS_FAILURE;
2420 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2421
Jeff Johnson32d95a32012-09-10 13:15:23 -07002422 if(!pSession)
2423 {
2424 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
2425 return eHAL_STATUS_FAILURE;
2426 }
2427
Jeff Johnson295189b2012-06-20 16:38:30 -07002428 smsLog(pMac, LOGW, "csrAddPMKIDCandidateList called pMac->scan.NumPmkidCandidate = %d\n", pSession->NumPmkidCandidate);
2429 if( pIes )
2430 {
2431 // check if this is a RSN BSS
2432 if( pIes->RSN.present )
2433 {
2434 // Check if the BSS is capable of doing pre-authentication
2435 if( pSession->NumPmkidCandidate < CSR_MAX_PMKID_ALLOWED )
2436 {
2437
2438#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2439 {
2440 WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type);
2441 palZeroMemory(pMac->hHdd, &secEvent, sizeof(vos_event_wlan_security_payload_type));
2442 secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND;
2443 secEvent.encryptionModeMulticast =
2444 (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType);
2445 secEvent.encryptionModeUnicast =
2446 (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType);
2447 palCopyMemory( pMac->hHdd, secEvent.bssid, pSession->connectedProfile.bssid, 6 );
2448 secEvent.authMode =
2449 (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType);
2450 WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
2451 }
2452#endif//#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2453
2454 // if yes, then add to PMKIDCandidateList
2455 status = palCopyMemory(pMac->hHdd, pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].BSSID,
2456 pBssDesc->bssId, WNI_CFG_BSSID_LEN);
2457
2458 if( HAL_STATUS_SUCCESS( status ) )
2459 {
2460 if ( pIes->RSN.preauth )
2461 {
2462 pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported = eANI_BOOLEAN_TRUE;
2463 }
2464 else
2465 {
2466 pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported = eANI_BOOLEAN_FALSE;
2467 }
2468 pSession->NumPmkidCandidate++;
2469 }
2470 }
2471 else
2472 {
2473 status = eHAL_STATUS_FAILURE;
2474 }
2475 }
2476 }
2477
2478 return (status);
2479}
2480
2481//This function checks whether new AP is found for the current connected profile
2482//If it is found, it return the sessionId, else it return invalid sessionID
2483tANI_U32 csrProcessBSSDescForPMKIDList(tpAniSirGlobal pMac,
2484 tSirBssDescription *pBssDesc,
2485 tDot11fBeaconIEs *pIes)
2486{
2487 tANI_U32 i, bRet = CSR_SESSION_ID_INVALID;
2488 tCsrRoamSession *pSession;
2489 tDot11fBeaconIEs *pIesLocal = pIes;
2490
2491 if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
2492 {
2493 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
2494 {
2495 if( CSR_IS_SESSION_VALID( pMac, i ) )
2496 {
2497 pSession = CSR_GET_SESSION( pMac, i );
2498 if( csrIsConnStateConnectedInfra( pMac, i ) &&
2499 ( eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType ) )
2500 {
2501 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pBssDesc, pIesLocal))
2502 {
2503 //this new BSS fits the current profile connected
2504 if(HAL_STATUS_SUCCESS(csrAddPMKIDCandidateList(pMac, i, pBssDesc, pIesLocal)))
2505 {
2506 bRet = i;
2507 }
2508 break;
2509 }
2510 }
2511 }
2512 }
2513 if( !pIes )
2514 {
2515 palFreeMemory(pMac->hHdd, pIesLocal);
2516 }
2517 }
2518
2519 return (tANI_U8)bRet;
2520}
2521
2522#ifdef FEATURE_WLAN_WAPI
2523eHalStatus csrAddBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
2524 tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
2525{
2526 eHalStatus status = eHAL_STATUS_FAILURE;
2527 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2528
Jeff Johnson32d95a32012-09-10 13:15:23 -07002529 if(!pSession)
2530 {
2531 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
2532 return eHAL_STATUS_FAILURE;
2533 }
2534
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 smsLog(pMac, LOGW, "csrAddBKIDCandidateList called pMac->scan.NumBkidCandidate = %d\n", pSession->NumBkidCandidate);
2536 if( pIes )
2537 {
2538 // check if this is a WAPI BSS
2539 if( pIes->WAPI.present )
2540 {
2541 // Check if the BSS is capable of doing pre-authentication
2542 if( pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED )
2543 {
2544
2545 // if yes, then add to BKIDCandidateList
2546 status = palCopyMemory(pMac->hHdd, pSession->BkidCandidateInfo[pSession->NumBkidCandidate].BSSID,
2547 pBssDesc->bssId, WNI_CFG_BSSID_LEN);
2548
2549 if( HAL_STATUS_SUCCESS( status ) )
2550 {
2551 if ( pIes->WAPI.preauth )
2552 {
2553 pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported = eANI_BOOLEAN_TRUE;
2554 }
2555 else
2556 {
2557 pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported = eANI_BOOLEAN_FALSE;
2558 }
2559 pSession->NumBkidCandidate++;
2560 }
2561 }
2562 else
2563 {
2564 status = eHAL_STATUS_FAILURE;
2565 }
2566 }
2567 }
2568
2569 return (status);
2570}
2571
2572//This function checks whether new AP is found for the current connected profile
2573//if so add to BKIDCandidateList
2574tANI_BOOLEAN csrProcessBSSDescForBKIDList(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc,
2575 tDot11fBeaconIEs *pIes)
2576{
2577 tANI_BOOLEAN fRC = FALSE;
2578 tDot11fBeaconIEs *pIesLocal = pIes;
2579 tANI_U32 sessionId;
2580 tCsrRoamSession *pSession;
2581
2582 if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
2583 {
2584 for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
2585 {
2586 if( CSR_IS_SESSION_VALID( pMac, sessionId) )
2587 {
2588 pSession = CSR_GET_SESSION( pMac, sessionId );
2589 if( csrIsConnStateConnectedInfra( pMac, sessionId ) &&
2590 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == pSession->connectedProfile.AuthType)
2591 {
2592 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile,pBssDesc, pIesLocal))
2593 {
2594 //this new BSS fits the current profile connected
2595 if(HAL_STATUS_SUCCESS(csrAddBKIDCandidateList(pMac, sessionId, pBssDesc, pIesLocal)))
2596 {
2597 fRC = TRUE;
2598 }
2599 }
2600 }
2601 }
2602 }
2603 if(!pIes)
2604 {
2605 palFreeMemory(pMac->hHdd, pIesLocal);
2606 }
2607
2608 }
2609 return fRC;
2610}
2611
2612#endif
2613
2614
2615static void csrMoveTempScanResultsToMainList( tpAniSirGlobal pMac )
2616{
2617 tListElem *pEntry;
2618 tCsrScanResult *pBssDescription;
2619 tANI_S8 cand_Bss_rssi;
2620 tANI_BOOLEAN fDupBss;
2621#ifdef FEATURE_WLAN_WAPI
2622 tANI_BOOLEAN fNewWapiBSSForCurConnection = eANI_BOOLEAN_FALSE;
2623#endif /* FEATURE_WLAN_WAPI */
2624 tDot11fBeaconIEs *pIesLocal = NULL;
2625 tANI_U32 sessionId = CSR_SESSION_ID_INVALID;
2626 tAniSSID tmpSsid;
2627 v_TIME_t timer=0;
2628
2629 tmpSsid.length = 0;
2630 cand_Bss_rssi = -128; // RSSI coming from PE is -ve
2631
2632 // remove the BSS descriptions from temporary list
2633 while( ( pEntry = csrLLRemoveTail( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ) ) != NULL)
2634 {
2635 pBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2636
Mohit Khanna23863762012-09-11 17:40:09 -07002637 smsLog( pMac, LOG2, "...Bssid= %02x-%02x-%02x-%02x-%02x-%02x chan= %d, rssi = -%d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07002638 pBssDescription->Result.BssDescriptor.bssId[ 0 ], pBssDescription->Result.BssDescriptor.bssId[ 1 ],
2639 pBssDescription->Result.BssDescriptor.bssId[ 2 ], pBssDescription->Result.BssDescriptor.bssId[ 3 ],
2640 pBssDescription->Result.BssDescriptor.bssId[ 4 ], pBssDescription->Result.BssDescriptor.bssId[ 5 ],
2641 pBssDescription->Result.BssDescriptor.channelId,
2642 pBssDescription->Result.BssDescriptor.rssi * (-1) );
2643
2644 //At this time, pBssDescription->Result.pvIes may be NULL
2645 pIesLocal = (tDot11fBeaconIEs *)( pBssDescription->Result.pvIes );
2646 if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssDescription->Result.BssDescriptor, &pIesLocal))) )
2647 {
2648 smsLog(pMac, LOGE, FL(" Cannot pared IEs\n"));
2649 csrFreeScanResultEntry(pMac, pBssDescription);
2650 continue;
2651 }
2652 fDupBss = csrRemoveDupBssDescription( pMac, &pBssDescription->Result.BssDescriptor, pIesLocal, &tmpSsid , &timer );
2653 //Check whether we have reach out limit
2654 if( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) )
2655 {
2656 //Limit reach
2657 smsLog(pMac, LOGW, FL(" BSS limit reached\n"));
2658 //Free the resources
2659 if( (pBssDescription->Result.pvIes == NULL) && pIesLocal )
2660 {
2661 palFreeMemory(pMac->hHdd, pIesLocal);
2662 }
2663 csrFreeScanResultEntry(pMac, pBssDescription);
2664 //Continue because there may be duplicated BSS
2665 continue;
2666 }
2667 // check for duplicate scan results
2668 if ( !fDupBss )
2669 {
2670 //Found a new BSS
2671 sessionId = csrProcessBSSDescForPMKIDList(pMac,
2672 &pBssDescription->Result.BssDescriptor, pIesLocal);
2673 if( CSR_SESSION_ID_INVALID != sessionId)
2674 {
2675 csrRoamCallCallback(pMac, sessionId, NULL, 0,
2676 eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NONE);
2677 }
2678 }
2679 else
2680 {
2681 //Check if the new one has SSID it it, if not, use the older SSID if it exists.
2682 if( (0 == pBssDescription->Result.ssId.length) && tmpSsid.length )
2683 {
2684 //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only
2685 //if diff of saved SSID time and current time is less than 1 min to avoid
2686 //side effect of saving SSID with old one is that if AP changes its SSID while remain
2687 //hidden, we may never see it and also to address the requirement of
2688 //When we remove hidden ssid from the profile i.e., forget the SSID via
2689 // GUI that SSID shouldn't see in the profile
2690 if( (vos_timer_get_system_time() - timer) <= HIDDEN_TIMER)
2691 {
2692 pBssDescription->Result.timer = timer;
2693 pBssDescription->Result.ssId = tmpSsid;
2694 }
2695 }
2696 }
2697
2698 //Tush: find a good AP for 11d info
2699 if( csrIs11dSupported( pMac ) )
2700 {
2701 if(cand_Bss_rssi < pBssDescription->Result.BssDescriptor.rssi)
2702 {
2703 // check if country information element is present
2704 if(pIesLocal->Country.present)
2705 {
2706 cand_Bss_rssi = pBssDescription->Result.BssDescriptor.rssi;
2707 // learn country information
2708 csrLearnCountryInformation( pMac, &pBssDescription->Result.BssDescriptor,
2709 pIesLocal, eANI_BOOLEAN_FALSE );
2710 }
2711
2712 }
2713 }
2714
Jeff Johnsone7245742012-09-05 17:12:55 -07002715 else if( csrIs11hSupported( pMac ) && pIesLocal->Country.present &&
2716 !pMac->roam.configParam.fSupplicantCountryCodeHasPriority )
2717 {
2718 /* If 11h is supported, store the power information received in the Country IE */
2719 csrSaveToChannelPower2G_5G( pMac, pIesLocal->Country.num_triplets * sizeof(tSirMacChanInfo),
2720 (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]) );
2721 }
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08002722 if(pIesLocal->HTCaps.present && pIesLocal->HTInfo.present)
2723 {
2724 pBssDescription->Result.BssDescriptor.channelWidth = pIesLocal->HTCaps.supportedChannelWidthSet;
2725 pBssDescription->Result.BssDescriptor.secondaryChannelOffset = pIesLocal->HTInfo.secondaryChannelOffset;
2726 if(pIesLocal->VHTOperation.present)
2727 {
2728 pBssDescription->Result.BssDescriptor.vhtSupport = pIesLocal->VHTOperation.present;
2729 if(pIesLocal->VHTOperation.chanWidth > eHT_CHANNEL_WIDTH_20MHZ)
2730 {
2731 pBssDescription->Result.BssDescriptor.channelWidth = eHT_CHANNEL_WIDTH_80MHZ;
2732 pBssDescription->Result.BssDescriptor.centerFreq = pIesLocal->VHTOperation.chanCenterFreqSeg1;
2733 }
2734 }
2735 }
2736 else
2737 {
2738 pBssDescription->Result.BssDescriptor.channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
2739 pBssDescription->Result.BssDescriptor.secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
2740 pBssDescription->Result.BssDescriptor.vhtSupport = 0;
2741 pBssDescription->Result.BssDescriptor.centerFreq = 0;
2742 }
2743
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 // append to main list
2745 csrScanAddResult(pMac, pBssDescription, pIesLocal);
2746 if( (pBssDescription->Result.pvIes == NULL) && pIesLocal )
2747 {
2748 palFreeMemory(pMac->hHdd, pIesLocal);
2749 }
2750 }
2751
2752 //Tush: If we can find the current 11d info in any of the scan results, or
2753 // a good enough AP with the 11d info from the scan results then no need to
2754 // get into ambiguous state
2755 if(pMac->scan.fAmbiguous11dInfoFound)
2756 {
2757 if((pMac->scan.fCurrent11dInfoMatch) || (cand_Bss_rssi != -128))
2758 {
2759 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
2760 }
2761 }
2762
2763#ifdef FEATURE_WLAN_WAPI
2764 if(fNewWapiBSSForCurConnection)
2765 {
2766 //remember it first
2767 csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NEW_WAPI_BSS);
2768 }
2769#endif /* FEATURE_WLAN_WAPI */
2770
2771 return;
2772}
2773
2774
2775static tCsrScanResult *csrScanSaveBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription,
2776 tDot11fBeaconIEs *pIes)
2777{
2778 tCsrScanResult *pCsrBssDescription = NULL;
2779 tANI_U32 cbBSSDesc;
2780 tANI_U32 cbAllocated;
2781 eHalStatus halStatus;
2782
2783 // figure out how big the BSS description is (the BSSDesc->length does NOT
2784 // include the size of the length field itself).
2785 cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );
2786
2787 cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;
2788
2789 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pCsrBssDescription, cbAllocated );
2790 if ( HAL_STATUS_SUCCESS(halStatus) )
2791 {
2792 palZeroMemory( pMac->hHdd, pCsrBssDescription, cbAllocated );
2793 pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
2794 palCopyMemory(pMac->hHdd, &pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc );
2795#if defined(VOSS_ENSBALED)
2796 VOS_ASSERT( pCsrBssDescription->Result.pvIes == NULL );
2797#endif
2798 csrScanAddResult(pMac, pCsrBssDescription, pIes);
2799 }
2800
2801 return( pCsrBssDescription );
2802}
2803
2804// Append a Bss Description...
2805tCsrScanResult *csrScanAppendBssDescription( tpAniSirGlobal pMac,
2806 tSirBssDescription *pSirBssDescription,
2807 tDot11fBeaconIEs *pIes )
2808{
2809 tCsrScanResult *pCsrBssDescription = NULL;
2810 tAniSSID tmpSsid;
2811 v_TIME_t timer = 0;
2812 int result;
2813
2814 tmpSsid.length = 0;
2815 result = csrRemoveDupBssDescription( pMac, pSirBssDescription, pIes, &tmpSsid, &timer );
2816 pCsrBssDescription = csrScanSaveBssDescription( pMac, pSirBssDescription, pIes );
2817 if (result && (pCsrBssDescription != NULL))
2818 {
2819 //Check if the new one has SSID it it, if not, use the older SSID if it exists.
2820 if( (0 == pCsrBssDescription->Result.ssId.length) && tmpSsid.length )
2821 {
2822 //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only
2823 //if diff of saved SSID time and current time is less than 1 min to avoid
2824 //side effect of saving SSID with old one is that if AP changes its SSID while remain
2825 //hidden, we may never see it and also to address the requirement of
2826 //When we remove hidden ssid from the profile i.e., forget the SSID via
2827 // GUI that SSID shouldn't see in the profile
2828 if((vos_timer_get_system_time()-timer) <= HIDDEN_TIMER)
2829 {
2830 pCsrBssDescription->Result.ssId = tmpSsid;
2831 pCsrBssDescription->Result.timer = timer;
2832 }
2833 }
2834 }
2835
2836
2837 return( pCsrBssDescription );
2838}
2839
2840
2841
2842void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList )
2843{
2844 tCsrChannelPowerInfo *pChannelSet;
2845 tListElem *pEntry;
2846
2847 csrLLLock(pChannelList);
2848 // Remove the channel sets from the learned list and put them in the free list
2849 while( ( pEntry = csrLLRemoveHead( pChannelList, LL_ACCESS_NOLOCK ) ) != NULL)
2850 {
2851 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
2852 if( pChannelSet )
2853 {
2854 palFreeMemory( pMac->hHdd, pChannelSet );
2855 }
2856 }
2857 csrLLUnlock(pChannelList);
2858 return;
2859}
2860
2861
2862/*
2863 * Save the channelList into the ultimate storage as the final stage of channel
2864 * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power limit are all stored inside this data structure
2865 */
Jeff Johnsone7245742012-09-05 17:12:55 -07002866eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable )
Jeff Johnson295189b2012-06-20 16:38:30 -07002867{
2868 tANI_U32 i = tableSize / sizeof( tSirMacChanInfo );
2869 tSirMacChanInfo *pChannelInfo;
2870 tCsrChannelPowerInfo *pChannelSet;
2871 tANI_BOOLEAN f2GHzInfoFound = FALSE;
2872 tANI_BOOLEAN f2GListPurged = FALSE, f5GListPurged = FALSE;
2873 eHalStatus halStatus;
2874
2875 pChannelInfo = channelTable;
2876 // atleast 3 bytes have to be remaining -- from "countryString"
2877 while ( i-- )
2878 {
2879 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pChannelSet, sizeof(tCsrChannelPowerInfo) );
2880 if ( eHAL_STATUS_SUCCESS == halStatus )
2881 {
2882 palZeroMemory(pMac->hHdd, pChannelSet, sizeof(tCsrChannelPowerInfo));
2883 pChannelSet->firstChannel = pChannelInfo->firstChanNum;
2884 pChannelSet->numChannels = pChannelInfo->numChannels;
2885
2886 // Now set the inter-channel offset based on the frequency band the channel set lies in
Jeff Johnsone7245742012-09-05 17:12:55 -07002887 if( (CSR_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) &&
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002888 ((pChannelSet->firstChannel + (pChannelSet->numChannels - 1)) <= CSR_MAX_24GHz_CHANNEL_NUMBER) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002889
Jeff Johnson295189b2012-06-20 16:38:30 -07002890 {
2891 pChannelSet->interChannelOffset = 1;
2892 f2GHzInfoFound = TRUE;
2893 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002894 else if ( (CSR_IS_CHANNEL_5GHZ(pChannelSet->firstChannel)) &&
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002895 ((pChannelSet->firstChannel + ((pChannelSet->numChannels - 1) * 4)) <= CSR_MAX_5GHz_CHANNEL_NUMBER) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002896 {
2897 pChannelSet->interChannelOffset = 4;
2898 f2GHzInfoFound = FALSE;
2899 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002900 else
2901 {
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002902 smsLog( pMac, LOGW, FL("Invalid Channel %d Present in Country IE"),
Jeff Johnsone7245742012-09-05 17:12:55 -07002903 pChannelSet->firstChannel);
2904 palFreeMemory(pMac->hHdd, pChannelSet);
2905 return eHAL_STATUS_FAILURE;
2906 }
2907
Jeff Johnson295189b2012-06-20 16:38:30 -07002908 pChannelSet->txPower = CSR_ROAM_MIN( pChannelInfo->maxTxPower, pMac->roam.configParam.nTxPowerCap );
2909
2910 if( f2GHzInfoFound )
2911 {
2912 if( !f2GListPurged )
2913 {
2914 // purge previous results if found new
2915 csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList24 );
2916 f2GListPurged = TRUE;
2917 }
2918
2919 if(CSR_IS_OPERATING_BG_BAND(pMac))
2920 {
2921 // add to the list of 2.4 GHz channel sets
2922 csrLLInsertTail( &pMac->scan.channelPowerInfoList24, &pChannelSet->link, LL_ACCESS_LOCK );
2923 }
2924 else {
2925 smsLog( pMac, LOGW, FL("Adding 11B/G channels in 11A mode -- First Channel is %d"),
2926 pChannelSet->firstChannel);
2927 palFreeMemory(pMac->hHdd, pChannelSet);
2928 }
2929 }
2930 else
2931 {
2932 // 5GHz info found
2933 if( !f5GListPurged )
2934 {
2935 // purge previous results if found new
2936 csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList5G );
2937 f5GListPurged = TRUE;
2938 }
2939
2940 if(CSR_IS_OPERATING_A_BAND(pMac))
2941 {
2942 // add to the list of 5GHz channel sets
2943 csrLLInsertTail( &pMac->scan.channelPowerInfoList5G, &pChannelSet->link, LL_ACCESS_LOCK );
2944 }
2945 else {
2946 smsLog( pMac, LOGW, FL("Adding 11A channels in B/G mode -- First Channel is %d"),
2947 pChannelSet->firstChannel);
2948 palFreeMemory(pMac->hHdd, pChannelSet);
2949 }
2950 }
2951 }
2952
2953 pChannelInfo++; // move to next entry
2954 }
2955
Jeff Johnsone7245742012-09-05 17:12:55 -07002956 return eHAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002957}
2958
2959
2960
2961void csrApplyPower2Current( tpAniSirGlobal pMac )
2962{
2963 smsLog( pMac, LOG3, FL(" Updating Cfg with power settings\n"));
2964 csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList24, WNI_CFG_MAX_TX_POWER_2_4 );
2965 csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList5G, WNI_CFG_MAX_TX_POWER_5 );
2966}
2967
2968
2969void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode)
2970{
2971 int i;
2972 eNVChannelEnabledType channelEnabledType;
2973 tANI_U8 numChannels = 0;
2974 tANI_U8 tempNumChannels = 0;
2975 tCsrChannel ChannelList;
2976 if( pChannelList->numChannels )
2977 {
2978 tempNumChannels = CSR_MIN(pChannelList->numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2979 /* If user doesn't want to scan the DFS channels lets trim them from
2980 the valid channel list*/
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08002981 for(i = 0; i< tempNumChannels; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 {
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08002983 if(FALSE == pMac->scan.fEnableDFSChnlScan)
2984 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002985 channelEnabledType =
2986 vos_nv_getChannelEnabledState(pChannelList->channelList[i]);
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08002987 }
2988 else
2989 {
2990 channelEnabledType = NV_CHANNEL_ENABLE;
2991 }
2992 if( NV_CHANNEL_ENABLE == channelEnabledType)
2993 {
2994 // Ignore the channel 165 for the country INDONESIA
Madan Mohan Koyyalamudi895cdee2012-11-06 19:13:19 -08002995 if (( pChannelList->channelList[i] == 165 )
2996 && ( pMac->scan.fIgnore_chan165 == VOS_TRUE )
2997 && vos_mem_compare(countryCode, "ID", VOS_COUNTRY_CODE_LEN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07002998 {
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08002999 continue;
3000 }
3001 else
3002 {
3003 ChannelList.channelList[numChannels] = pChannelList->channelList[i];
Jeff Johnson295189b2012-06-20 16:38:30 -07003004 numChannels++;
3005 }
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08003006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003007 }
Madan Mohan Koyyalamudi3f65e312012-11-06 15:31:12 -08003008 ChannelList.numChannels = numChannels;
Jeff Johnson295189b2012-06-20 16:38:30 -07003009
3010 csrSetCfgValidChannelList(pMac, ChannelList.channelList, ChannelList.numChannels);
3011 // extend scan capability
3012 csrSetCfgScanControlList(pMac, countryCode, &ChannelList); // build a scan list based on the channel list : channel# + active/passive scan
3013#ifdef FEATURE_WLAN_SCAN_PNO
Madan Mohan Koyyalamudi255b0972012-10-31 15:51:24 -07003014 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, FL(" Sending 11d PNO info to Riva\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07003015 // Send HAL UpdateScanParams message
Madan Mohan Koyyalamudi255b0972012-10-31 15:51:24 -07003016 pmcUpdateScanParams(pMac, &(pMac->roam.configParam), &ChannelList, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07003017#endif // FEATURE_WLAN_SCAN_PNO
3018 }
3019 else
3020 {
3021 smsLog( pMac, LOGE, FL(" 11D channel list is empty\n"));
3022 }
3023 csrApplyPower2Current( pMac ); // Store the channel+power info in the global place: Cfg
3024 csrSetCfgCountryCode(pMac, countryCode);
3025}
3026
3027
3028void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce )
3029{
3030 if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset)))
3031 {
3032
3033#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3034 {
3035 vos_log_802_11d_pkt_type *p11dLog;
3036 int Index;
3037
3038 WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
3039 if(p11dLog)
3040 {
3041 p11dLog->eventId = WLAN_80211D_EVENT_RESET;
3042 palCopyMemory(pMac->hHdd, p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3);
3043 p11dLog->numChannel = pMac->scan.base20MHzChannels.numChannels;
3044 if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
3045 {
3046 palCopyMemory(pMac->hHdd, p11dLog->Channels, pMac->scan.base20MHzChannels.channelList,
3047 p11dLog->numChannel);
3048 for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++)
3049 {
3050 p11dLog->TxPwr[Index] = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
3051 }
3052 }
3053 if(!pMac->roam.configParam.Is11dSupportEnabled)
3054 {
3055 p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
3056 }
3057 else if(pMac->roam.configParam.fEnforceDefaultDomain)
3058 {
3059 p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
3060 }
3061 else
3062 {
3063 p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
3064 }
3065 WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
3066 }
3067 }
3068#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3069
3070 // switch to passive scans only when 11d is enabled
3071 if( csrIs11dSupported( pMac ) )
3072 {
3073 pMac->scan.curScanType = eSIR_PASSIVE_SCAN;
3074 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003075
3076 csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels);
3077 csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels);
3078
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE);
3080 csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE);
3081 // ... and apply the channel list, power settings, and the country code.
3082 csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent );
3083 // clear the 11d channel list
3084 palZeroMemory( pMac->hHdd, &pMac->scan.channels11d, sizeof(pMac->scan.channels11d) );
3085 pMac->scan.f11dInfoReset = eANI_BOOLEAN_TRUE;
3086 pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE;
3087 }
3088
3089 return;
3090}
3091
3092
3093eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded)
3094{
3095 eHalStatus status = eHAL_STATUS_SUCCESS;
3096 tANI_BOOLEAN fRestart = eANI_BOOLEAN_FALSE;
3097
3098 //Use the Country code and domain from EEPROM
3099 palCopyMemory(pMac->hHdd, pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
3100 csrSetRegulatoryDomain(pMac, pMac->scan.domainIdCurrent, &fRestart);
Jeff Johnson43971f52012-07-17 12:26:56 -07003101 if( ((eANI_BOOLEAN_FALSE == fRestart) || (pfRestartNeeded == NULL) )
3102 && !csrIsInfraConnected(pMac))
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 {
3104 //Only reset the country info if we don't need to restart
3105 csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE);
3106 }
3107 if(pfRestartNeeded)
3108 {
3109 *pfRestartNeeded = fRestart;
3110 }
3111
3112 return (status);
3113}
3114
3115
3116eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded)
3117{
3118 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
3119 v_REGDOMAIN_t domainId;
3120
3121 if(pCountry)
3122 {
3123 status = csrGetRegulatoryDomainForCountry(pMac, pCountry, &domainId);
3124 if(HAL_STATUS_SUCCESS(status))
3125 {
3126 status = csrSetRegulatoryDomain(pMac, domainId, pfRestartNeeded);
3127 if(HAL_STATUS_SUCCESS(status))
3128 {
3129 //We don't need to check the pMac->roam.configParam.fEnforceDefaultDomain flag here,
3130 //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria.
3131 palCopyMemory(pMac->hHdd, pMac->scan.countryCodeCurrent, pCountry, WNI_CFG_COUNTRY_CODE_LEN);
3132 if((pfRestartNeeded == NULL) || !(*pfRestartNeeded))
3133 {
3134 //Simply set it to cfg. If we need to restart, restart will apply it to the CFG
3135 csrSetCfgCountryCode(pMac, pCountry);
3136 }
3137 }
3138 }
3139 }
3140
3141 return (status);
3142}
3143
3144
3145
3146//caller allocated memory for pNumChn and pChnPowerInfo
3147//As input, *pNumChn has the size of the array of pChnPowerInfo
3148//Upon return, *pNumChn has the number of channels assigned.
3149void csrGetChannelPowerInfo( tpAniSirGlobal pMac, tDblLinkList *pList,
3150 tANI_U32 *pNumChn, tChannelListWithPower *pChnPowerInfo)
3151{
3152 tListElem *pEntry;
3153 tANI_U32 chnIdx = 0, idx;
3154 tCsrChannelPowerInfo *pChannelSet;
3155
3156 //Get 2.4Ghz first
3157 pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
3158 while( pEntry && (chnIdx < *pNumChn) )
3159 {
3160 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
3161 if ( 1 != pChannelSet->interChannelOffset )
3162 {
3163 for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
3164 {
3165 pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
3166 pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
3167 }
3168 }
3169 else
3170 {
3171 for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
3172 {
3173 pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + idx);
3174 pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
3175 }
3176 }
3177
3178 pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
3179 }
3180 *pNumChn = chnIdx;
3181
3182 return ;
3183}
3184
3185
3186
3187void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce )
3188{
3189 v_REGDOMAIN_t domainId;
3190 eHalStatus status = eHAL_STATUS_SUCCESS;
3191
3192 do
3193 {
3194 if( !csrIs11dSupported( pMac ) || 0 == pMac->scan.channelOf11dInfo) break;
3195 if( pMac->scan.fAmbiguous11dInfoFound )
3196 {
3197 // ambiguous info found
3198 //Restore te default domain as well
3199 if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pMac->scan.countryCodeCurrent, &domainId )))
3200 {
3201 pMac->scan.domainIdCurrent = domainId;
3202 }
3203 else
3204 {
3205 smsLog(pMac, LOGE, FL(" failed to get domain from currentCountryCode %02X%02X\n"),
3206 pMac->scan.countryCodeCurrent[0], pMac->scan.countryCodeCurrent[1]);
3207 }
3208 csrResetCountryInformation( pMac, eANI_BOOLEAN_FALSE );
3209 break;
3210 }
3211 if ( pMac->scan.f11dInfoApplied && !fForce ) break;
3212 if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pMac->scan.countryCode11d, &domainId )))
3213 {
3214 //Check whether we need to enforce default domain
3215 if( ( !pMac->roam.configParam.fEnforceDefaultDomain ) ||
3216 (pMac->scan.domainIdCurrent == domainId) )
3217 {
3218
3219#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3220 {
3221 vos_log_802_11d_pkt_type *p11dLog;
3222 tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3223 tANI_U32 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp;
3224
3225 WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
3226 if(p11dLog)
3227 {
3228 p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET;
3229 palCopyMemory(pMac->hHdd, p11dLog->countryCode, pMac->scan.countryCode11d, 3);
3230 p11dLog->numChannel = pMac->scan.channels11d.numChannels;
3231 if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
3232 {
3233 palCopyMemory(pMac->hHdd, p11dLog->Channels, pMac->scan.channels11d.channelList,
3234 p11dLog->numChannel);
3235 csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList24,
3236 &nChnInfo, chnPwrInfo);
3237 nTmp = nChnInfo;
3238 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp;
3239 csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList5G,
3240 &nChnInfo, &chnPwrInfo[nTmp]);
3241 for(nTmp = 0; nTmp < p11dLog->numChannel; nTmp++)
3242 {
3243 for(nChnInfo = 0; nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN; nChnInfo++)
3244 {
3245 if(p11dLog->Channels[nTmp] == chnPwrInfo[nChnInfo].chanId)
3246 {
3247 p11dLog->TxPwr[nTmp] = chnPwrInfo[nChnInfo].pwr;
3248 break;
3249 }
3250 }
3251 }
3252 }
3253 if(!pMac->roam.configParam.Is11dSupportEnabled)
3254 {
3255 p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
3256 }
3257 else if(pMac->roam.configParam.fEnforceDefaultDomain)
3258 {
3259 p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
3260 }
3261 else
3262 {
3263 p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
3264 }
3265 WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
3266 }
3267 }
3268#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3269 if(pMac->scan.domainIdCurrent != domainId)
3270 {
3271 /* Regulatory Domain Changed, Purge Only scan result
3272 * which does not have channel number belong to 11d
3273 * channel list
3274 * */
3275 smsLog(pMac, LOGW, FL("Domain Changed Old %d, new %d"),
3276 pMac->scan.domainIdCurrent, domainId);
3277 csrScanFilter11dResult(pMac);
3278 }
3279 status = WDA_SetRegDomain(pMac, domainId);
3280 if (status != eHAL_STATUS_SUCCESS)
3281 {
3282 smsLog( pMac, LOGE, FL(" fail to set regId %d\n"), domainId );
3283 }
3284 pMac->scan.domainIdCurrent = domainId;
3285 csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.channels11d, pMac->scan.countryCode11d );
3286 // switch to active scans using this new channel list
3287 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
3288 pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE;
3289 pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE;
3290 }
3291 }
3292
3293 } while( 0 );
3294
3295 return;
3296}
3297
3298
3299
3300tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode,
3301 tANI_BOOLEAN fForce)
3302{
3303 tANI_BOOLEAN fCountryStringChanged = FALSE, fUnknownCountryCode = FALSE;
3304 tANI_U32 i;
3305
3306 // convert to UPPER here so we are assured the strings are always in upper case.
3307 for( i = 0; i < 3; i++ )
3308 {
3309 pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] );
3310 }
3311
3312 // Some of the 'old' Cisco 350 series AP's advertise NA as the country code (for North America ??).
3313 // NA is not a valid country code or domain so let's allow this by changing it to the proper
3314 // country code (which is US). We've also seen some NETGEAR AP's that have "XX " as the country code
3315 // with valid 2.4 GHz US channel information. If we cannot find the country code advertised in the
3316 // 11d information element, let's default to US.
3317 if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pCountryCode, NULL ) ) )
3318 {
3319 // Check the enforcement first
3320 if( pMac->roam.configParam.fEnforceDefaultDomain || pMac->roam.configParam.fEnforceCountryCodeMatch )
3321 {
3322 fUnknownCountryCode = TRUE;
3323 }
3324 else
3325 {
3326 pCountryCode[ 0 ] = 'U';
3327 pCountryCode[ 1 ] = 'S';
3328 }
3329 }
3330
3331 // We've seen some of the AP's improperly put a 0 for the third character of the country code.
3332 // spec says valid charcters are 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either).
3333 // if we see a 0 in this third character, let's change it to a ' '.
3334 if ( 0 == pCountryCode[ 2 ] )
3335 {
3336 pCountryCode[ 2 ] = ' ';
3337 }
3338
3339 if( !fUnknownCountryCode )
3340 {
3341 fCountryStringChanged = (!palEqualMemory( pMac->hHdd,
3342 pMac->scan.countryCode11d, pCountryCode, 2));
3343
3344
3345 if(( 0 == pMac->scan.countryCode11d[ 0 ] && 0 == pMac->scan.countryCode11d[ 1 ] )
3346 || (fForce))
3347 {
3348 // this is the first .11d information
3349 palCopyMemory( pMac->hHdd, pMac->scan.countryCode11d, pCountryCode, sizeof( pMac->scan.countryCode11d ) );
3350 }
3351 }
3352
3353 return( fCountryStringChanged );
3354}
3355
3356
3357void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand )
3358{
3359 tANI_U32 Index, count=0;
3360 tSirMacChanInfo *pChanInfo;
3361 tSirMacChanInfo *pChanInfoStart;
3362
3363 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN)))
3364 {
3365 palZeroMemory(pMac->hHdd, pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN);
3366 pChanInfoStart = pChanInfo;
3367 for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++)
3368 {
3369 if ((fPopulate5GBand && (CSR_IS_CHANNEL_5GHZ(pMac->scan.defaultPowerTable[Index].chanId))) ||
3370 (!fPopulate5GBand && (CSR_IS_CHANNEL_24GHZ(pMac->scan.defaultPowerTable[Index].chanId))) )
3371 {
3372 pChanInfo->firstChanNum = pMac->scan.defaultPowerTable[Index].chanId;
3373 pChanInfo->numChannels = 1;
3374 pChanInfo->maxTxPower = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
3375 pChanInfo++;
3376 count++;
3377 }
3378 }
3379 if(count)
3380 {
3381 csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart );
3382 }
3383 palFreeMemory(pMac->hHdd, pChanInfoStart);
3384 }
3385}
3386
3387
3388void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac )
3389{
3390 tANI_BOOLEAN fPopulate5GBand = FALSE;
3391
3392 do
3393 {
3394 // if this is not a dual band product, then we don't need to set the opposite
3395 // band info. We only work in one band so no need to look in the other band.
3396 if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) break;
3397 // if we found channel info on the 5.0 band and...
3398 if ( CSR_IS_CHANNEL_5GHZ( pMac->scan.channelOf11dInfo ) )
3399 {
3400 // and the 2.4 band is empty, then populate the 2.4 channel info
3401 if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList24, LL_ACCESS_LOCK ) ) break;
3402 fPopulate5GBand = FALSE;
3403 }
3404 else
3405 {
3406 // else, we found channel info in the 2.4 GHz band. If the 5.0 band is empty
3407 // set the 5.0 band info from the 2.4 country code.
3408 if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList5G, LL_ACCESS_LOCK ) ) break;
3409 fPopulate5GBand = TRUE;
3410 }
3411 csrSaveChannelPowerForBand( pMac, fPopulate5GBand );
3412
3413 } while( 0 );
3414}
3415
3416
3417tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId)
3418{
3419 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
3420 tANI_U32 i;
3421
3422 //Make sure it is a channel that is in our supported list.
3423 for ( i = 0; i < pMac->scan.baseChannels.numChannels; i++ )
3424 {
3425 if ( channelId == pMac->scan.baseChannels.channelList[i] )
3426 {
3427 fRet = eANI_BOOLEAN_TRUE;
3428 break;
3429 }
3430 }
3431
3432 //If it is configured to limit a set of the channels
3433 if( fRet && pMac->roam.configParam.fEnforce11dChannels )
3434 {
3435 fRet = eANI_BOOLEAN_FALSE;
3436 for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ )
3437 {
3438 if ( channelId == pMac->scan.base20MHzChannels.channelList[i] )
3439 {
3440 fRet = eANI_BOOLEAN_TRUE;
3441 break;
3442 }
3443 }
3444 }
3445
3446 return (fRet);
3447}
3448
3449
3450
3451//bSize specify the buffer size of pChannelList
3452tANI_U8 csrGetChannelListFromChannelSet( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 bSize, tCsrChannelPowerInfo *pChannelSet )
3453{
3454 tANI_U8 i, j = 0, chnId;
3455
3456 bSize = CSR_MIN(bSize, pChannelSet->numChannels);
3457 for( i = 0; i < bSize; i++ )
3458 {
3459 chnId = (tANI_U8)(pChannelSet->firstChannel + ( i * pChannelSet->interChannelOffset ));
3460 if ( csrIsSupportedChannel( pMac, chnId ) )
3461 {
3462 pChannelList[j++] = chnId;
3463 }
3464 }
3465
3466 return (j);
3467}
3468
3469
3470
3471//bSize -- specify the buffer size of pChannelList
3472void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList,
3473 tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels )
3474{
3475 tListElem *pEntry;
3476 tCsrChannelPowerInfo *pChannelSet;
3477 tANI_U8 numChannels;
3478 tANI_U8 *pChannels;
3479
3480 if( pChannelSetList && pChannelList && pNumChannels )
3481 {
3482 pChannels = pChannelList;
3483 *pNumChannels = 0;
3484 pEntry = csrLLPeekHead( pChannelSetList, LL_ACCESS_LOCK );
3485 while( pEntry )
3486 {
3487 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
3488 numChannels = csrGetChannelListFromChannelSet( pMac, pChannels, bSize, pChannelSet );
3489 pChannels += numChannels;
3490 *pNumChannels += numChannels;
3491 pEntry = csrLLNext( pChannelSetList, pEntry, LL_ACCESS_LOCK );
3492 }
3493 }
3494}
3495
3496
3497/*
3498 * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d
3499*/
3500tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
3501 tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce)
3502{
3503 tANI_U8 Num2GChannels, bMaxNumChn;
3504 eHalStatus status;
3505 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
3506 v_REGDOMAIN_t domainId;
3507 tDot11fBeaconIEs *pIesLocal = pIes;
3508
3509#ifdef WLAN_SOFTAP_FEATURE
3510 if (VOS_STA_SAP_MODE == vos_get_conparam ())
3511 return eHAL_STATUS_SUCCESS;
3512#endif
3513
3514 do
3515 {
3516 // check if .11d support is enabled
3517 if( !csrIs11dSupported( pMac ) ) break;
3518 if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
3519 {
3520 break;
3521 }
3522 // check if country information element is present
3523 if(!pIesLocal->Country.present)
3524 {
3525 //No country info
3526 break;
3527 }
3528
3529 if( csrSave11dCountryString( pMac, pIesLocal->Country.country, fForce ) )
3530 {
3531 // country string changed, this should not happen
3532 //Need to check whether we care about this BSS' domain info
3533 //If it doesn't match of the connected profile or roaming profile, let's ignore it
3534 tANI_U32 i;
3535 tCsrRoamSession *pSession;
3536
3537 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
3538 {
3539 if( CSR_IS_SESSION_VALID( pMac, i ) )
3540 {
3541 pSession = CSR_GET_SESSION( pMac, i );
3542 if(pSession->pCurRoamProfile)
3543 {
3544 tCsrScanResultFilter filter;
3545
3546 palZeroMemory(pMac->hHdd, &filter, sizeof(tCsrScanResultFilter));
3547 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, &filter);
3548 if(HAL_STATUS_SUCCESS(status))
3549 {
3550 tANI_BOOLEAN fMatch = csrMatchBSS(pMac, pSirBssDesc, &filter, NULL, NULL, NULL, NULL);
3551 //Free the resource first
3552 csrFreeScanFilter( pMac, &filter );
3553 if(fMatch)
3554 {
3555 smsLog(pMac, LOGW, " Matching roam profile BSSID %02X-%02X-%02X-%02X-%02X-%02X causing ambiguous domain info\n",
3556 pSirBssDesc->bssId[0], pSirBssDesc->bssId[1], pSirBssDesc->bssId[2],
3557 pSirBssDesc->bssId[3], pSirBssDesc->bssId[4], pSirBssDesc->bssId[5]);
3558 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3559 break;
3560 }
3561 }
3562 }
3563 else if( csrIsConnStateConnected(pMac, i))
3564 {
3565 //Reach here only when the currention is base on no profile.
3566 //User doesn't give profile and just connect to anything.
3567 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pSirBssDesc, pIesLocal))
3568 {
3569 smsLog(pMac, LOGW, " Matching connect profile BSSID %02X-%02X-%02X-%02X-%02X-%02X causing ambiguous domain info\n",
3570 pSirBssDesc->bssId[0], pSirBssDesc->bssId[1], pSirBssDesc->bssId[2],
3571 pSirBssDesc->bssId[3], pSirBssDesc->bssId[4], pSirBssDesc->bssId[5]);
3572 //Tush
3573 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3574 if(csrIsBssidMatch(pMac, (tCsrBssid *)&pSirBssDesc->bssId,
3575 &pSession->connectedProfile.bssid))
3576 {
3577 //AP changed the 11d info on the fly, modify cfg
3578 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
3579 fRet = eANI_BOOLEAN_TRUE;
3580 }
3581 break;
3582 }
3583 }
3584 } //valid session
3585 } //for
3586 if ( i == CSR_ROAM_SESSION_MAX )
3587 {
3588 //Check whether we can use this country's 11d information
3589 if( !pMac->roam.configParam.fEnforceDefaultDomain )
3590 {
3591 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3592 }
3593 else
3594 {
3595 VOS_ASSERT( pMac->scan.domainIdCurrent == pMac->scan.domainIdDefault );
3596 if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(
3597 pMac, pIesLocal->Country.country, &domainId )) &&
3598 ( domainId == pMac->scan.domainIdCurrent ) )
3599 {
3600 //Two countries in the same domain
3601 }
3602 }
3603 }
3604 }
3605 else //Tush
3606 {
3607 pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_TRUE;
3608 }
3609
3610 //In case that some channels in 5GHz have the same channel number as 2.4GHz (<= 14)
3611 if(CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId))
3612 {
3613 tANI_U8 iC;
3614 tSirMacChanInfo* pMacChnSet = (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]);
3615
3616 for(iC = 0; iC < pIesLocal->Country.num_triplets; iC++)
3617 {
3618 if(CSR_IS_CHANNEL_24GHZ(pMacChnSet[iC].firstChanNum))
3619 {
3620 pMacChnSet[iC].firstChanNum += 200; //*** Where is this 200 defined?
3621 }
3622 }
3623 }
Mohit Khanna23863762012-09-11 17:40:09 -07003624 smsLog(pMac, LOG3, FL(" %d sets each one is %d\n"), pIesLocal->Country.num_triplets, sizeof(tSirMacChanInfo));
Jeff Johnson295189b2012-06-20 16:38:30 -07003625 // save the channel/power information from the Channel IE.
3626 //sizeof(tSirMacChanInfo) has to be 3
Jeff Johnsone7245742012-09-05 17:12:55 -07003627 if (eHAL_STATUS_SUCCESS != csrSaveToChannelPower2G_5G( pMac, pIesLocal->Country.num_triplets * sizeof(tSirMacChanInfo),
3628 (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]) ))
3629 {
3630 fRet = eANI_BOOLEAN_FALSE;
3631 return fRet;
3632 }
3633
Jeff Johnson295189b2012-06-20 16:38:30 -07003634 // set the indicator of the channel where the country IE was found...
3635 pMac->scan.channelOf11dInfo = pSirBssDesc->channelId;
3636 // Populate both band channel lists based on what we found in the country information...
3637 csrSetOppositeBandChannelInfo( pMac );
3638 bMaxNumChn = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3639 // construct 2GHz channel list first
3640 csrConstructCurrentValidChannelList( pMac, &pMac->scan.channelPowerInfoList24, pMac->scan.channels11d.channelList,
3641 bMaxNumChn, &Num2GChannels );
3642 // construct 5GHz channel list now
3643 if(bMaxNumChn > Num2GChannels)
3644 {
3645 csrConstructCurrentValidChannelList( pMac, &pMac->scan.channelPowerInfoList5G, pMac->scan.channels11d.channelList + Num2GChannels,
3646 bMaxNumChn - Num2GChannels,
3647 &pMac->scan.channels11d.numChannels );
3648 }
3649
3650 pMac->scan.channels11d.numChannels += Num2GChannels;
3651 fRet = eANI_BOOLEAN_TRUE;
3652
3653 } while( 0 );
3654
3655 if( !pIes && pIesLocal )
3656 {
3657 //locally allocated
3658 palFreeMemory(pMac->hHdd, pIesLocal);
3659 }
3660
3661 return( fRet );
3662}
3663
3664
3665static void csrSaveScanResults( tpAniSirGlobal pMac )
3666{
3667 // initialize this to FALSE. profMoveInterimScanResultsToMainList() routine
3668 // will set this to the channel where an .11d beacon is seen
3669 pMac->scan.channelOf11dInfo = 0;
3670 // if we get any ambiguous .11d information then this will be set to TRUE
3671 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
3672 //Tush
3673 // if we get any ambiguous .11d information, then this will be set to TRUE
3674 // only if the applied 11d info could be found in one of the scan results
3675 pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_FALSE;
3676 // move the scan results from interim list to the main scan list
3677 csrMoveTempScanResultsToMainList( pMac );
3678
3679 // Now check if we gathered any domain/country specific information
3680 // If so, we should update channel list and apply Tx power settings
Jeff Johnsone7245742012-09-05 17:12:55 -07003681 if( csrIs11dSupported(pMac) )
3682 {
3683 csrApplyCountryInformation( pMac, FALSE );
3684 }
3685 else if( csrIs11hSupported(pMac) && !pMac->roam.configParam.fSupplicantCountryCodeHasPriority)
3686 {
3687 // If llh is enabled, store the channel + power information gathered in the cfg
3688 csrApplyPower2Current( pMac );
3689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003690}
3691
3692
3693void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3694{
3695 switch (pCommand->u.scanCmd.reason)
3696 {
3697 case eCsrScanSetBGScanParam:
3698 case eCsrScanAbortBgScan:
3699 if(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList)
3700 {
3701 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList);
3702 pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
3703 }
3704 break;
3705 case eCsrScanBGScanAbort:
3706 case eCsrScanBGScanEnable:
3707 case eCsrScanGetScanChnInfo:
3708 break;
3709 case eCsrScanAbortNormalScan:
3710 default:
3711 csrScanFreeRequest(pMac, &pCommand->u.scanCmd.u.scanRequest);
3712 break;
3713 }
3714 if(pCommand->u.scanCmd.pToRoamProfile)
3715 {
3716 csrReleaseProfile(pMac, pCommand->u.scanCmd.pToRoamProfile);
3717 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.pToRoamProfile);
3718 }
3719 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
3720}
3721
3722
3723tANI_BOOLEAN csrGetRemainingChannelsFor11dScan( tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U8 *pcChannels )
3724{
3725 tANI_U32 index11dChannels, index;
3726 tANI_U32 indexCurrentChannels;
3727 tANI_BOOLEAN fChannelAlreadyScanned;
3728 tANI_U32 len = sizeof(pMac->roam.validChannelList);
3729
3730 *pcChannels = 0;
3731 if ( CSR_IS_11D_INFO_FOUND(pMac) && csrRoamIsChannelValid(pMac, pMac->scan.channelOf11dInfo) )
3732 {
3733 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
3734 {
3735 //Find the channel index where we found the 11d info
3736 for(index = 0; index < len; index++)
3737 {
3738 if(pMac->scan.channelOf11dInfo == pMac->roam.validChannelList[index])
3739 break;
3740 }
3741 //check whether we found the channel index
3742 if(index < len)
3743 {
3744 // Now, look through the 11d channel list and create a list of all channels in the 11d list that are
3745 // NOT in the current channel list. This gives us a list of the new channels that have not been
3746 // scanned. We'll scan this new list so we have a complete set of scan results on all of the domain channels
3747 // initially.
3748 for ( index11dChannels = 0; index11dChannels < pMac->scan.channels11d.numChannels; index11dChannels++ )
3749 {
3750 fChannelAlreadyScanned = eANI_BOOLEAN_FALSE;
3751
3752 for( indexCurrentChannels = 0; indexCurrentChannels < index; indexCurrentChannels++ )
3753 {
3754 if ( pMac->roam.validChannelList[ indexCurrentChannels ] == pMac->scan.channels11d.channelList[ index11dChannels ] )
3755 {
3756 fChannelAlreadyScanned = eANI_BOOLEAN_TRUE;
3757 break;
3758 }
3759 }
3760
3761 if ( !fChannelAlreadyScanned )
3762 {
3763 pChannels[ *pcChannels ] = pMac->scan.channels11d.channelList[ index11dChannels ];
3764 ( *pcChannels )++;
3765 }
3766 }
3767 }
3768 }//GetCFG
3769 }
3770 return( *pcChannels );
3771}
3772
3773
3774eCsrScanCompleteNextCommand csrScanGetNextCommandState( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fSuccess )
3775{
3776 eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
3777
3778 switch( pCommand->u.scanCmd.reason )
3779 {
3780 case eCsrScan11d1:
3781 NextCommand = (fSuccess) ? eCsrNext11dScan1Success : eCsrNext11dScan1Failure;
3782 break;
3783 case eCsrScan11d2:
3784 NextCommand = (fSuccess) ? eCsrNext11dScan2Success : eCsrNext11dScan2Failure;
3785 break;
3786 case eCsrScan11dDone:
3787 NextCommand = eCsrNext11dScanComplete;
3788 break;
3789 case eCsrScanLostLink1:
3790 NextCommand = (fSuccess) ? eCsrNextLostLinkScan1Success : eCsrNextLostLinkScan1Failed;
3791 break;
3792 case eCsrScanLostLink2:
3793 NextCommand = (fSuccess) ? eCsrNextLostLinkScan2Success : eCsrNextLostLinkScan2Failed;
3794 break;
3795 case eCsrScanLostLink3:
3796 NextCommand = (fSuccess) ? eCsrNextLostLinkScan3Success : eCsrNextLostLinkScan3Failed;
3797 break;
3798 case eCsrScanForSsid:
3799 NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess : eCsrNexteScanForSsidFailure;
3800 break;
3801 case eCsrScanForCapsChange:
3802 NextCommand = eCsrNextCapChangeScanComplete; //don't care success or not
3803 break;
3804 case eCsrScanIdleScan:
3805 NextCommand = eCsrNextIdleScanComplete;
3806 break;
3807 default:
3808 NextCommand = eCsrNextScanNothing;
3809 break;
3810 }
3811 return( NextCommand );
3812}
3813
3814
3815//Return whether the pCommand is finished.
3816tANI_BOOLEAN csrHandleScan11d1Failure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3817{
3818 tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
3819
3820 //Apply back the default setting and passively scan one more time.
3821 csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE);
3822 pCommand->u.scanCmd.reason = eCsrScan11d2;
3823 if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
3824 {
3825 fRet = eANI_BOOLEAN_FALSE;
3826 }
3827
3828 return (fRet);
3829}
3830
3831
3832tANI_BOOLEAN csrHandleScan11dSuccess(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3833{
3834 tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
3835 tANI_U8 *pChannels;
3836 tANI_U8 cChannels;
3837
3838 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN)))
3839 {
3840 palZeroMemory(pMac->hHdd, pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3841 if ( csrGetRemainingChannelsFor11dScan( pMac, pChannels, &cChannels ) )
3842 {
3843 pCommand->u.scanCmd.reason = eCsrScan11dDone;
3844 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
3845 {
3846 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
3847 }
3848 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, cChannels)))
3849 {
3850 palCopyMemory(pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, pChannels, cChannels);
3851 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = cChannels;
3852 pCommand->u.scanCmd.u.scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
3853 pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
3854 if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
3855 {
3856 //Reuse the same command buffer
3857 fRet = eANI_BOOLEAN_FALSE;
3858 }
3859 }
3860 }
3861 palFreeMemory(pMac->hHdd, pChannels);
3862 }
3863
3864 return (fRet);
3865}
3866
3867//Return whether the command should be removed
3868tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp )
3869{
3870 eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
3871 tListElem *pEntry;
3872 tSmeCmd *pCommand;
3873 tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
3874 tANI_BOOLEAN fSuccess;
3875
3876 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
3877
3878 if ( pEntry )
3879 {
3880 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
3881
3882 // If the head of the queue is Active and it is a SCAN command, remove
3883 // and put this on the Free queue.
3884 if ( eSmeCommandScan == pCommand->command )
3885 {
3886 tANI_U32 sessionId = pCommand->sessionId;
3887
3888 if(eSIR_SME_SUCCESS != pScanRsp->statusCode)
3889 {
3890 fSuccess = eANI_BOOLEAN_FALSE;
3891 }
3892 else
3893 {
3894 //pMac->scan.tempScanResults is not empty meaning the scan found something
3895 //This check only valid here because csrSaveScanresults is not yet called
3896 fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK));
3897 }
3898 csrSaveScanResults(pMac);
3899
3900#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3901 {
3902 vos_log_scan_pkt_type *pScanLog = NULL;
3903 tScanResultHandle hScanResult;
3904 tCsrScanResultInfo *pScanResult;
3905 tDot11fBeaconIEs *pIes;
3906 int n = 0, c = 0;
3907
3908 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
3909 if(pScanLog)
3910 {
3911 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
3912 eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
3913 eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
3914 {
3915 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP;
3916 }
3917 else
3918 {
3919 if( eSIR_PASSIVE_SCAN != pMac->scan.curScanType )
3920 {
3921 pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP;
3922 }
3923 else
3924 {
3925 pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP;
3926 }
3927 }
3928 if(eSIR_SME_SUCCESS == pScanRsp->statusCode)
3929 {
3930 if(HAL_STATUS_SUCCESS(csrScanGetResult(pMac, NULL, &hScanResult)))
3931 {
3932 while(((pScanResult = csrScanResultGetNext(pMac, hScanResult)) != NULL))
3933 {
3934 if( n < VOS_LOG_MAX_NUM_BSSID )
3935 {
3936 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->BssDescriptor, &pIes)))
3937 {
3938 smsLog(pMac, LOGE, FL(" fail to parse IEs\n"));
3939 break;
3940 }
3941 palCopyMemory(pMac->hHdd, pScanLog->bssid[n], pScanResult->BssDescriptor.bssId, 6);
3942 if(pIes && pIes->SSID.present && VOS_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid)
3943 {
3944 palCopyMemory(pMac->hHdd, pScanLog->ssid[n],
3945 pIes->SSID.ssid, pIes->SSID.num_ssid);
3946 }
3947 palFreeMemory(pMac->hHdd, pIes);
3948 n++;
3949 }
3950 c++;
3951 }
3952 pScanLog->numSsid = (v_U8_t)n;
3953 pScanLog->totalSsid = (v_U8_t)c;
3954 csrScanResultPurge(pMac, hScanResult);
3955 }
3956 }
3957 else
3958 {
3959 pScanLog->status = WLAN_SCAN_STATUS_FAILURE;
3960 }
3961 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
3962 }
3963 }
3964#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3965
3966 NextCommand = csrScanGetNextCommandState(pMac, pCommand, fSuccess);
3967 //We reuse the command here instead reissue a new command
3968 switch(NextCommand)
3969 {
3970 case eCsrNext11dScan1Success:
3971 case eCsrNext11dScan2Success:
3972 smsLog( pMac, LOG2, FL("11dScan1/3 produced results. Reissue Active scan...\n"));
3973 // if we found country information, no need to continue scanning further, bail out
3974 fRemoveCommand = eANI_BOOLEAN_TRUE;
3975 NextCommand = eCsrNext11dScanComplete;
3976 break;
3977 case eCsrNext11dScan1Failure:
3978 //We are not done yet. 11d scan fail once. We will try to reset anything and do it over again
3979 //The only meaningful thing for this retry is that we cannot find 11d information after a reset so
3980 //we clear the "old" 11d info and give it once more chance
3981 fRemoveCommand = csrHandleScan11d1Failure(pMac, pCommand);
3982 if(fRemoveCommand)
3983 {
3984 NextCommand = eCsrNext11dScanComplete;
3985 }
3986 break;
3987 case eCsrNextLostLinkScan1Success:
3988 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink1)))
3989 {
3990 csrScanHandleFailedLostlink1(pMac, sessionId);
3991 }
3992 break;
3993 case eCsrNextLostLinkScan2Success:
3994 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink2)))
3995 {
3996 csrScanHandleFailedLostlink2(pMac, sessionId);
3997 }
3998 break;
3999 case eCsrNextLostLinkScan3Success:
4000 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink3)))
4001 {
4002 csrScanHandleFailedLostlink3(pMac, sessionId);
4003 }
4004 break;
4005 case eCsrNextLostLinkScan1Failed:
4006 csrScanHandleFailedLostlink1(pMac, sessionId);
4007 break;
4008 case eCsrNextLostLinkScan2Failed:
4009 csrScanHandleFailedLostlink2(pMac, sessionId);
4010 break;
4011 case eCsrNextLostLinkScan3Failed:
4012 csrScanHandleFailedLostlink3(pMac, sessionId);
4013 break;
4014 case eCsrNexteScanForSsidSuccess:
4015 csrScanHandleSearchForSSID(pMac, pCommand);
4016 break;
4017 case eCsrNexteScanForSsidFailure:
4018 csrScanHandleSearchForSSIDFailure(pMac, pCommand);
4019 break;
4020 case eCsrNextIdleScanComplete:
4021 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
4022 break;
4023 case eCsrNextCapChangeScanComplete:
4024 csrScanHandleCapChangeScanComplete(pMac, sessionId);
4025 break;
4026 default:
4027
4028 break;
4029 }
4030 }
4031 else
4032 {
4033 smsLog( pMac, LOGW, FL("Scan Completion called but SCAN command is not ACTIVE ...\n"));
4034 fRemoveCommand = eANI_BOOLEAN_FALSE;
4035 }
4036 }
4037 else
4038 {
4039 smsLog( pMac, LOGW, FL("Scan Completion called but NO commands are ACTIVE ...\n"));
4040 fRemoveCommand = eANI_BOOLEAN_FALSE;
4041 }
4042
4043 return( fRemoveCommand );
4044}
4045
4046
4047
4048static void csrScanRemoveDupBssDescriptionFromInterimList( tpAniSirGlobal pMac,
4049 tSirBssDescription *pSirBssDescr,
4050 tDot11fBeaconIEs *pIes)
4051{
4052 tListElem *pEntry;
4053 tCsrScanResult *pCsrBssDescription;
4054
4055 // Walk through all the chained BssDescriptions. If we find a chained BssDescription that
4056 // matches the BssID of the BssDescription passed in, then these must be duplicate scan
4057 // results for this Bss. In that case, remove the 'old' Bss description from the linked list.
4058 pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK );
4059 while( pEntry )
4060 {
4061 pCsrBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
4062
4063 // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
4064 // matches
4065
4066 if ( csrIsDuplicateBssDescription( pMac, &pCsrBssDescription->Result.BssDescriptor,
4067 pSirBssDescr, pIes ) )
4068 {
4069 pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
4070 ((tANI_S32)pCsrBssDescription->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );
4071
4072 // Remove the 'old' entry from the list....
4073 if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ) )
4074 {
4075 csrCheckNSaveWscIe(pMac, pSirBssDescr, &pCsrBssDescription->Result.BssDescriptor);
4076 // we need to free the memory associated with this node
4077 csrFreeScanResultEntry( pMac, pCsrBssDescription );
4078 }
4079
4080 // If we found a match, we can stop looking through the list.
4081 break;
4082 }
4083
4084 pEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK );
4085 }
4086}
4087
4088
4089
4090//Caller allocated memory pfNewBssForConn to return whether new candidate for
4091//current connection is found. Cannot be NULL
4092tCsrScanResult *csrScanSaveBssDescriptionToInterimList( tpAniSirGlobal pMac,
4093 tSirBssDescription *pBSSDescription,
4094 tDot11fBeaconIEs *pIes)
4095{
4096 tCsrScanResult *pCsrBssDescription = NULL;
4097 tANI_U32 cbBSSDesc;
4098 tANI_U32 cbAllocated;
4099 eHalStatus halStatus;
4100
4101 // figure out how big the BSS description is (the BSSDesc->length does NOT
4102 // include the size of the length field itself).
4103 cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );
4104
4105 cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;
4106
4107 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pCsrBssDescription, cbAllocated );
4108 if ( HAL_STATUS_SUCCESS(halStatus) )
4109 {
4110 palZeroMemory(pMac->hHdd, pCsrBssDescription, cbAllocated);
4111 pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
4112 palCopyMemory(pMac->hHdd, &pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc );
4113 //Save SSID separately for later use
4114 if( pIes->SSID.present && !csrIsNULLSSID(pIes->SSID.ssid, pIes->SSID.num_ssid) )
4115 {
4116 //SSID not hidden
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -07004117 tANI_U32 len = pIes->SSID.num_ssid;
Jeff Johnson295189b2012-06-20 16:38:30 -07004118 if (len > SIR_MAC_MAX_SSID_LENGTH)
4119 {
4120 // truncate to fit in our struct
4121 len = SIR_MAC_MAX_SSID_LENGTH;
4122 }
4123 pCsrBssDescription->Result.ssId.length = len;
4124 pCsrBssDescription->Result.timer = vos_timer_get_system_time();
4125 palCopyMemory(pMac->hHdd, pCsrBssDescription->Result.ssId.ssId,
4126 pIes->SSID.ssid, len );
4127 }
4128 csrLLInsertTail( &pMac->scan.tempScanResults, &pCsrBssDescription->Link, LL_ACCESS_LOCK );
4129 }
4130
4131 return( pCsrBssDescription );
4132}
4133
4134
4135
4136
4137tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1,
4138 tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 )
4139{
4140 tANI_BOOLEAN fMatch = FALSE;
4141 tSirMacCapabilityInfo *pCap1, *pCap2;
4142 tDot11fBeaconIEs *pIes1 = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004143 tDot11fBeaconIEs *pIesTemp = pIes2;
Jeff Johnson295189b2012-06-20 16:38:30 -07004144
4145 pCap1 = (tSirMacCapabilityInfo *)&pSirBssDesc1->capabilityInfo;
4146 pCap2 = (tSirMacCapabilityInfo *)&pSirBssDesc2->capabilityInfo;
4147 if(pCap1->ess == pCap2->ess)
4148 {
4149 if (pCap1->ess &&
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)&&
4151 (pSirBssDesc1->channelId == pSirBssDesc2->channelId))
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 {
4153 fMatch = TRUE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004154 // Check for SSID match, if exists
4155 do
4156 {
4157 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
4158 {
4159 break;
4160 }
4161 if( NULL == pIesTemp )
4162 {
4163 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
4164 {
4165 break;
4166 }
4167 }
4168 if(pIes1->SSID.present && pIesTemp->SSID.present)
4169 {
4170 fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid,
4171 pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
4172 }
4173 }while(0);
4174
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 }
4176 else if (pCap1->ibss && (pSirBssDesc1->channelId == pSirBssDesc2->channelId))
4177 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004178
4179 do
4180 {
4181 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
4182 {
4183 break;
4184 }
4185 if( NULL == pIesTemp )
4186 {
4187 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
4188 {
4189 break;
4190 }
4191 }
4192 //Same channel cannot have same SSID for different IBSS
4193 if(pIes1->SSID.present && pIesTemp->SSID.present)
4194 {
4195 fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid,
4196 pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
4197 }
4198 }while(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004199 }
4200#if defined WLAN_FEATURE_P2P
4201 /* In case of P2P devices, ess and ibss will be set to zero */
4202 else if (!pCap1->ess &&
4203 csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId))
4204 {
4205 fMatch = TRUE;
4206 }
4207#endif
4208 }
4209
4210 if(pIes1)
4211 {
4212 palFreeMemory(pMac->hHdd, pIes1);
4213 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004214
4215 if( (NULL == pIes2) && pIesTemp )
4216 {
4217 //locally allocated
4218 palFreeMemory(pMac->hHdd, pIesTemp);
4219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004220
4221 return( fMatch );
4222}
4223
4224
4225tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 )
4226{
4227 return( pSirBssDesc1->nwType == pSirBssDesc2->nwType );
4228}
4229
4230
4231//to check whether the BSS matches the dot11Mode
4232static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc,
4233 tDot11fBeaconIEs *pIes)
4234{
4235 tANI_BOOLEAN fAllowed = eANI_BOOLEAN_FALSE;
4236 eCsrPhyMode phyMode;
4237
4238 if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pBssDesc, &phyMode, pIes)))
4239 {
4240 switch(pMac->roam.configParam.phyMode)
4241 {
4242 case eCSR_DOT11_MODE_11b:
4243 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
4244 break;
4245 case eCSR_DOT11_MODE_11g:
4246 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
4247 break;
4248 case eCSR_DOT11_MODE_11g_ONLY:
4249 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11g == phyMode);
4250 break;
4251 case eCSR_DOT11_MODE_11a:
4252 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11b != phyMode) && (eCSR_DOT11_MODE_11g != phyMode));
4253 break;
4254 case eCSR_DOT11_MODE_11n_ONLY:
4255 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11n == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
4256 break;
Jeff Johnsone7245742012-09-05 17:12:55 -07004257
4258#ifdef WLAN_FEATURE_11AC
4259 case eCSR_DOT11_MODE_11ac_ONLY:
4260 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11ac == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
4261 break;
4262#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 case eCSR_DOT11_MODE_11b_ONLY:
4264 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode);
4265 break;
4266 case eCSR_DOT11_MODE_11a_ONLY:
4267 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode);
4268 break;
4269 case eCSR_DOT11_MODE_11n:
Jeff Johnsone7245742012-09-05 17:12:55 -07004270#ifdef WLAN_FEATURE_11AC
4271 case eCSR_DOT11_MODE_11ac:
4272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 case eCSR_DOT11_MODE_TAURUS:
4274 default:
4275 fAllowed = eANI_BOOLEAN_TRUE;
4276 break;
4277 }
4278 }
4279
4280 return (fAllowed);
4281}
4282
4283
4284
4285//Return pIes to caller for future use when returning TRUE.
4286static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels,
4287 tANI_U8 numChn, tSirBssDescription *pBssDesc,
4288 tDot11fBeaconIEs **ppIes )
4289{
4290 tANI_BOOLEAN fValidChannel = FALSE;
4291 tDot11fBeaconIEs *pIes = NULL;
4292 tANI_U8 index;
4293
4294 for( index = 0; index < numChn; index++ )
4295 {
4296 // This check relies on the fact that a single BSS description is returned in each
4297 // ScanRsp call, which is the way LIM implemented the scan req/rsp funtions. We changed
4298 // to this model when we ran with a large number of APs. If this were to change, then
4299 // this check would have to mess with removing the bssDescription from somewhere in an
4300 // arbitrary index in the bssDescription array.
4301 if ( pChannels[ index ] == pBssDesc->channelId )
4302 {
4303 fValidChannel = TRUE;
4304 break;
4305 }
4306 }
4307 *ppIes = NULL;
4308 if(fValidChannel)
4309 {
4310 if( HAL_STATUS_SUCCESS( csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes) ) )
4311 {
4312 fValidChannel = csrScanIsBssAllowed(pMac, pBssDesc, pIes);
4313 if( fValidChannel )
4314 {
4315 *ppIes = pIes;
4316 }
4317 else
4318 {
4319 palFreeMemory( pMac->hHdd, pIes );
4320 }
4321 }
4322 else
4323 {
4324 fValidChannel = FALSE;
4325 }
4326 }
4327
4328 return( fValidChannel );
4329}
4330
4331
4332//Return whether last scan result is received
4333static tANI_BOOLEAN csrScanProcessScanResults( tpAniSirGlobal pMac, tSmeCmd *pCommand,
4334 tSirSmeScanRsp *pScanRsp, tANI_BOOLEAN *pfRemoveCommand )
4335{
4336 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE, fRemoveCommand = eANI_BOOLEAN_FALSE;
4337 tDot11fBeaconIEs *pIes = NULL;
4338 tANI_U32 cbParsed;
4339 tSirBssDescription *pSirBssDescription;
4340 tANI_U32 cbBssDesc;
4341 tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription )
4342 + sizeof(tSirBssDescription); //We need at least one CB
4343
4344 // don't consider the scan rsp to be valid if the status code is Scan Failure. Scan Failure
4345 // is returned when the scan could not find anything. so if we get scan failure return that
4346 // the scan response is invalid. Also check the lenght in the scan result for valid scan
4347 // BssDescriptions....
4348 do
4349 {
4350 if ( ( cbScanResult <= pScanRsp->length ) &&
4351 (( eSIR_SME_SUCCESS == pScanRsp->statusCode ) ||
4352 ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW == pScanRsp->statusCode ) ) )
4353 {
4354 tANI_U8 *pChannelList = NULL;
4355 tANI_U8 cChannels = 0;
4356
4357 //Different scan type can reach this point, we need to distinguish it
4358 if( eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason )
4359 {
4360 //eCsrScanSetBGScanParam uses different structure
4361 tCsrBGScanRequest *pBgScanReq = &pCommand->u.scanCmd.u.bgScanRequest;
4362
4363 cChannels = pBgScanReq->ChannelInfo.numOfChannels;
4364 pChannelList = pBgScanReq->ChannelInfo.ChannelList;
4365 }
4366 else
4367 {
4368 //the rest use generic scan request
4369 cChannels = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
4370 pChannelList = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
4371 }
4372
4373 // if the scan result is not on one of the channels in the Valid channel list, then it
4374 // must have come from an AP on an overlapping channel (in the 2.4GHz band). In this case,
4375 // let's drop the scan result.
4376 //
4377 // The other situation is where the scan request is for a scan on a particular channel set
4378 // and the scan result is from a
4379
4380 // if the NumChannels is 0, then we are supposed to be scanning all channels. Use the full channel
4381 // list as the 'valid' channel list. Otherwise, use the specific channel list in the scan parms
4382 // as the valid channels.
4383 if ( 0 == cChannels )
4384 {
4385 tANI_U32 len = sizeof(pMac->roam.validChannelList);
4386
4387 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
4388 {
4389 pChannelList = pMac->roam.validChannelList;
4390 cChannels = (tANI_U8)len;
4391 }
4392 else
4393 {
4394 //Cannot continue
4395 smsLog( pMac, LOGE, "CSR: Processing internal SCAN results...csrGetCfgValidChannels failed\n" );
4396 break;
4397 }
4398 }
4399
4400 smsLog( pMac, LOG2, "CSR: Processing internal SCAN results..." );
4401 cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription );
4402 pSirBssDescription = pScanRsp->bssDescription;
4403 while( cbParsed < pScanRsp->length )
4404 {
4405 if ( csrScanValidateScanResult( pMac, pChannelList, cChannels, pSirBssDescription, &pIes ) )
4406 {
4407 csrScanRemoveDupBssDescriptionFromInterimList(pMac, pSirBssDescription, pIes);
4408 csrScanSaveBssDescriptionToInterimList( pMac, pSirBssDescription, pIes );
4409 if( eSIR_PASSIVE_SCAN == pMac->scan.curScanType )
4410 {
4411 if( csrIs11dSupported( pMac) )
4412 {
4413 //Check whether the BSS is acceptable base on 11d info and our configs.
4414 if( csrMatchCountryCode( pMac, NULL, pIes ) )
4415 {
4416 //Double check whether the channel is acceptable by us.
4417 if( csrIsSupportedChannel( pMac, pSirBssDescription->channelId ) )
4418 {
4419 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
4420 }
4421 }
4422 }
4423 else
4424 {
4425 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
4426 }
4427 }
4428 //Free the resource
4429 palFreeMemory( pMac->hHdd, pIes );
4430 }
4431 // skip over the BSS description to the next one...
4432 cbBssDesc = pSirBssDescription->length + sizeof( pSirBssDescription->length );
4433
4434 cbParsed += cbBssDesc;
4435 pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + cbBssDesc );
4436
4437 } //while
4438 }
4439 else
4440 {
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08004441 smsLog( pMac, LOGW, " Scanrsp fail (0x%08X), length = %d (expected %d)\n",
4442 pScanRsp->statusCode, pScanRsp->length, cbScanResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004443 //HO bg scan/probe failed no need to try autonomously
4444 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
4445 eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
4446 eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
4447 {
4448 fRemoveCommand = eANI_BOOLEAN_TRUE;
4449 }
4450 }
4451 }while(0);
4452 if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
4453 {
4454 smsLog(pMac, LOG1, " Scan received %d unique BSS scan reason is %d\n", csrLLCount(&pMac->scan.tempScanResults), pCommand->u.scanCmd.reason);
4455 fRemoveCommand = csrScanComplete( pMac, pScanRsp );
4456 fRet = eANI_BOOLEAN_TRUE;
4457 }//if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
4458 if(pfRemoveCommand)
4459 {
4460 *pfRemoveCommand = fRemoveCommand;
4461 }
4462
4463#ifdef WLAN_AP_STA_CONCURRENCY
4464 if (!csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK ))
4465 {
Madan Mohan Koyyalamudi48081ef2012-12-04 16:49:55 -08004466 /* Pending scan commands in the list because the previous scan command
4467 * was split into a scan command on one channel + a scan command for all
4468 * remaining channels.
4469 *
4470 * Start timer to trigger processing of the next scan command.
4471 */
4472 if ( (csrIsStaSessionConnected(pMac) && (pCommand->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
4473 (csrIsP2pSessionConnected(pMac)) )
4474 {
Madan Mohan Koyyalamudid6713582012-11-09 16:56:56 -08004475 /* if active connected sessions present then continue to split scan
4476 * with specified interval between consecutive scans */
4477 csrSetDefaultScanTiming(pMac, pCommand->u.scanCmd.u.scanRequest.scanType, &(pCommand->u.scanCmd.u.scanRequest));
4478 palTimerStart(pMac->hHdd, pMac->scan.hTimerStaApConcTimer,
4479 pCommand->u.scanCmd.u.scanRequest.restTime * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
4480 } else {
4481 /* if no connected sessions present then initiate next scan command immediately */
4482 /* minimum timer granularity is 10ms */
4483 palTimerStart(pMac->hHdd, pMac->scan.hTimerStaApConcTimer, 10 * 1000, eANI_BOOLEAN_FALSE);
4484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 }
4486#endif
4487 return (fRet);
4488}
4489
4490
4491tANI_BOOLEAN csrScanIsWildCardScan( tpAniSirGlobal pMac, tSmeCmd *pCommand )
4492{
4493 tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
4494 tANI_BOOLEAN f = palEqualMemory( pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.bssid,
4495 bssid, sizeof(tCsrBssid) );
4496
4497 //It is not a wild card scan if the bssid is not broadcast and the number of SSID is 1.
4498 return ((tANI_BOOLEAN)( (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid[0])) &&
4499 (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1) ));
4500}
4501
4502
4503eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf )
4504{
4505 eHalStatus status = eHAL_STATUS_SUCCESS;
4506 tListElem *pEntry;
4507 tSmeCmd *pCommand;
4508 eCsrScanStatus scanStatus;
4509 tSirSmeScanRsp *pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
4510 tSmeGetScanChnRsp *pScanChnInfo;
4511 tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
4512 eCsrScanReason reason = eCsrScanOther;
4513
4514 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
4515
4516 if ( pEntry )
4517 {
4518 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
4519 if ( eSmeCommandScan == pCommand->command )
4520 {
4521 scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
4522 reason = pCommand->u.scanCmd.reason;
4523 switch(pCommand->u.scanCmd.reason)
4524 {
4525 case eCsrScanAbortBgScan:
4526 case eCsrScanAbortNormalScan:
4527 case eCsrScanBGScanAbort:
4528 case eCsrScanBGScanEnable:
4529 break;
4530 case eCsrScanGetScanChnInfo:
4531 pScanChnInfo = (tSmeGetScanChnRsp *)pMsgBuf;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004532 /*
4533 * status code not available in tSmeGetScanChnRsp, so
4534 * by default considereing it to be success
4535 */
4536 scanStatus = eSIR_SME_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004537 csrScanAgeResults(pMac, pScanChnInfo);
4538 break;
4539 case eCsrScanForCapsChange:
4540 csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand );
4541 break;
4542#if WLAN_FEATURE_P2P
4543 case eCsrScanP2PFindPeer:
4544 scanStatus = ((eSIR_SME_SUCCESS == pScanRsp->statusCode) && (pScanRsp->length > 50)) ? eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE;
4545 csrScanProcessScanResults( pMac, pCommand, pScanRsp, NULL );
4546 break;
4547#endif
4548 case eCsrScanSetBGScanParam:
4549 default:
4550 if(csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand ))
4551 {
4552 //Not to get channel info if the scan is not a wildcard scan because
4553 //it may cause scan results got aged out incorrectly.
4554 if( csrScanIsWildCardScan( pMac, pCommand ) && (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) )
4555 {
4556 //Get the list of channels scanned
Jeff Johnson32d95a32012-09-10 13:15:23 -07004557 if( pCommand->u.scanCmd.reason != eCsrScanUserRequest)
4558 {
4559 csrScanGetScanChnInfo(pMac, NULL, NULL);
4560 }
4561 else
4562 {
4563 csrScanGetScanChnInfo(pMac, pCommand->u.scanCmd.callback, pCommand->u.scanCmd.pContext);
4564 pCommand->u.scanCmd.callback = NULL;
4565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004566 }
4567 }
4568 break;
4569 }//switch
4570 if(fRemoveCommand)
4571 {
4572
4573 csrReleaseScanCommand(pMac, pCommand, scanStatus);
4574
4575 }
4576 smeProcessPendingQueue( pMac );
4577 }
4578 else
4579 {
4580 smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." );
4581 status = eHAL_STATUS_FAILURE;
4582 }
4583 }
4584 else
4585 {
4586 smsLog( pMac, LOGW, "CSR: Scan Completion called but NO commands are ACTIVE ..." );
4587 status = eHAL_STATUS_FAILURE;
4588 }
4589
4590 return (status);
4591}
4592
4593
4594
4595
4596tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
4597{
4598 tListElem *pEntry;
4599 tCsrScanResult *pResult;
4600 tCsrScanResultInfo *pRet = NULL;
4601 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4602
4603 if(pResultList)
4604 {
4605 csrLLLock(&pResultList->List);
4606 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
4607 if(pEntry)
4608 {
4609 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
4610 pRet = &pResult->Result;
4611 }
4612 pResultList->pCurEntry = pEntry;
4613 csrLLUnlock(&pResultList->List);
4614 }
4615
4616 return pRet;
4617}
4618
4619
4620tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
4621{
4622 tListElem *pEntry = NULL;
4623 tCsrScanResult *pResult = NULL;
4624 tCsrScanResultInfo *pRet = NULL;
4625 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4626
4627 if(pResultList)
4628 {
4629 csrLLLock(&pResultList->List);
4630 if(NULL == pResultList->pCurEntry)
4631 {
4632 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
4633 }
4634 else
4635 {
4636 pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
4637 }
4638 if(pEntry)
4639 {
4640 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
4641 pRet = &pResult->Result;
4642 }
4643 pResultList->pCurEntry = pEntry;
4644 csrLLUnlock(&pResultList->List);
4645 }
4646
4647 return pRet;
4648}
4649
4650
4651//This function moves the first BSS that matches the bssid to the head of the result
4652eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult)
4653{
4654 eHalStatus status = eHAL_STATUS_FAILURE;
4655 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4656 tCsrScanResult *pResult = NULL;
4657 tListElem *pEntry = NULL;
4658
4659 if(pResultList && bssid)
4660 {
4661 csrLLLock(&pResultList->List);
4662 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
4663 while(pEntry)
4664 {
4665 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
4666 if(palEqualMemory(pMac->hHdd, bssid, pResult->Result.BssDescriptor.bssId, sizeof(tCsrBssid)))
4667 {
4668 status = eHAL_STATUS_SUCCESS;
4669 csrLLRemoveEntry(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
4670 csrLLInsertHead(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
4671 break;
4672 }
4673 pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
4674 }
4675 csrLLUnlock(&pResultList->List);
4676 }
4677
4678 return (status);
4679}
4680
4681
4682//Remove the BSS if possible.
4683//Return -- TRUE == the BSS is remove. False == Fail to remove it
4684//This function is called when list lock is held. Be caution what functions it can call.
4685tANI_BOOLEAN csrScanAgeOutBss(tpAniSirGlobal pMac, tCsrScanResult *pResult)
4686{
4687 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
4688 tANI_U32 i;
4689 tCsrRoamSession *pSession;
4690
4691 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
4692 {
4693 if( CSR_IS_SESSION_VALID( pMac, i ) )
4694 {
4695 pSession = CSR_GET_SESSION( pMac, i );
4696 //Not to remove the BSS we are connected to.
4697 if(csrIsConnStateDisconnected(pMac, i) || (NULL == pSession->pConnectBssDesc) ||
4698 (!csrIsDuplicateBssDescription(pMac, &pResult->Result.BssDescriptor,
4699 pSession->pConnectBssDesc, NULL))
4700 )
4701 {
Mohit Khanna23863762012-09-11 17:40:09 -07004702 smsLog(pMac, LOG2, "Aging out BSS %02X-%02X-%02X-%02X-%02X-%02X Channel %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004703 pResult->Result.BssDescriptor.bssId[0],
4704 pResult->Result.BssDescriptor.bssId[1],
4705 pResult->Result.BssDescriptor.bssId[2],
4706 pResult->Result.BssDescriptor.bssId[3],
4707 pResult->Result.BssDescriptor.bssId[4],
4708 pResult->Result.BssDescriptor.bssId[5],
4709 pResult->Result.BssDescriptor.channelId);
4710 //No need to hold the spin lock because caller should hold the lock for pMac->scan.scanResultList
4711 if( csrLLRemoveEntry(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_NOLOCK) )
4712 {
4713 csrFreeScanResultEntry(pMac, pResult);
Madan Mohan Koyyalamudi2e068bc2012-10-22 14:58:47 -07004714 fRet = eANI_BOOLEAN_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004715 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004716 break;
4717 }
4718 } //valid session
4719 } //for
Madan Mohan Koyyalamudi2e068bc2012-10-22 14:58:47 -07004720 if( CSR_ROAM_SESSION_MAX == i && fRet != eANI_BOOLEAN_TRUE )
Jeff Johnson295189b2012-06-20 16:38:30 -07004721 {
4722 //reset the counter so this won't hapeen too soon
4723 pResult->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
4724 pResult->Result.BssDescriptor.nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
4725 }
4726
4727 return (fRet);
4728}
4729
4730
4731eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo)
4732{
4733 eHalStatus status = eHAL_STATUS_SUCCESS;
4734 tListElem *pEntry, *tmpEntry;
4735 tCsrScanResult *pResult;
4736 tLimScanChn *pChnInfo;
4737 tANI_U8 i;
4738
4739 csrLLLock(&pMac->scan.scanResultList);
4740 for(i = 0; i < pScanChnInfo->numChn; i++)
4741 {
4742 pChnInfo = &pScanChnInfo->scanChn[i];
4743 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
4744 while( pEntry )
4745 {
4746 tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
4747 pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
4748 if(pResult->Result.BssDescriptor.channelId == pChnInfo->channelId)
4749 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 if(pResult->AgingCount <= 0)
4751 {
4752 smsLog(pMac, LOGW, " age out due to ref count");
4753 csrScanAgeOutBss(pMac, pResult);
4754 }
Madan Mohan Koyyalamudib9d3dcc2012-09-28 16:47:50 -07004755 else
4756 {
4757 pResult->AgingCount--;
4758 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 }
4760 pEntry = tmpEntry;
4761 }
4762 }
4763 csrLLUnlock(&pMac->scan.scanResultList);
4764
4765 return (status);
4766}
4767
4768
4769eHalStatus csrSendMBScanReq( tpAniSirGlobal pMac, tANI_U16 sessionId,
4770 tCsrScanRequest *pScanReq, tScanReqParam *pScanReqParam )
4771{
4772 eHalStatus status = eHAL_STATUS_SUCCESS;
4773 tSirSmeScanReq *pMsg;
4774 tANI_U16 msgLen;
4775 tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
4776 tSirScanType scanType = pScanReq->scanType;
4777 tANI_U32 minChnTime; //in units of milliseconds
4778 tANI_U32 maxChnTime; //in units of milliseconds
4779 tANI_U32 i;
4780 tANI_U8 selfMacAddr[WNI_CFG_BSSID_LEN];
4781 tANI_U8 *pSelfMac = NULL;
4782
4783 msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) +
4784 ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) +
4785 ( pScanReq->uIEFieldLen ) ;
4786
4787 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
4788 if(HAL_STATUS_SUCCESS(status))
4789 {
4790 do
4791 {
4792 palZeroMemory(pMac->hHdd, pMsg, msgLen);
4793 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
4794 pMsg->length = pal_cpu_to_be16(msgLen);
4795 //ToDO: Fill in session info when we need to do scan base on session.
4796 pMsg->sessionId = 0;
4797 pMsg->transactionId = 0;
4798 pMsg->dot11mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
4799 pMsg->bssType = pal_cpu_to_be32(csrTranslateBsstypeToMacType(pScanReq->BSSType));
4800
4801 if ( CSR_IS_SESSION_VALID( pMac, sessionId ) )
4802 {
4803 pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[sessionId].selfMacAddr;
4804 }
4805 else
4806 {
4807 // Since we don't have session for the scanning, we find a valid session. In case we fail to
4808 // do so, get the WNI_CFG_STA_ID
4809 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
4810 {
4811 if( CSR_IS_SESSION_VALID( pMac, i ) )
4812 {
4813 pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[i].selfMacAddr;
4814 break;
4815 }
4816 }
4817 if( CSR_ROAM_SESSION_MAX == i )
4818 {
4819 tANI_U32 len = WNI_CFG_BSSID_LEN;
4820 pSelfMac = selfMacAddr;
4821 status = ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pSelfMac, &len );
4822 if( !HAL_STATUS_SUCCESS( status ) ||
4823 ( len < WNI_CFG_BSSID_LEN ) )
4824 {
4825 smsLog( pMac, LOGE, FL(" Can not get self MAC address from CFG status = %d"), status );
4826 //Force failed status
4827 status = eHAL_STATUS_FAILURE;
4828 break;
4829 }
4830 }
4831 }
4832 palCopyMemory( pMac->hHdd, (tANI_U8 *)pMsg->selfMacAddr, pSelfMac, sizeof(tSirMacAddr) );
4833
4834 //sirCopyMacAddr
4835 palCopyMemory( pMac->hHdd, (tANI_U8 *)pMsg->bssId, (tANI_U8 *)&pScanReq->bssid, sizeof(tSirMacAddr) );
4836 if( palEqualMemory( pMac->hHdd, pScanReq->bssid, bssid, sizeof(tCsrBssid) ) )
4837 {
4838 palFillMemory( pMac->hHdd, pMsg->bssId, sizeof(tSirMacAddr), 0xff );
4839 }
4840 else
4841 {
4842 palCopyMemory(pMac->hHdd, pMsg->bssId, pScanReq->bssid, WNI_CFG_BSSID_LEN);
4843 }
4844 minChnTime = pScanReq->minChnTime;
4845 maxChnTime = pScanReq->maxChnTime;
4846
4847 //Verify the scan type first, if the scan is active scan, we need to make sure we
4848 //are allowed to do so.
4849 /* if 11d is enabled & we don't see any beacon around, scan type falls
4850 back to passive. But in BT AMP STA mode we need to send out a
4851 directed probe*/
4852 if( (eSIR_PASSIVE_SCAN != scanType) && (eCSR_SCAN_P2P_DISCOVERY != pScanReq->requestType)
4853 && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType)
4854 && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d))
4855 {
4856 scanType = pMac->scan.curScanType;
4857 if(eSIR_PASSIVE_SCAN == pMac->scan.curScanType)
4858 {
4859 if(minChnTime < pMac->roam.configParam.nPassiveMinChnTime)
4860 {
4861 minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
4862 }
4863 if(maxChnTime < pMac->roam.configParam.nPassiveMaxChnTime)
4864 {
4865 maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
4866 }
4867 }
4868 }
4869 pMsg->scanType = pal_cpu_to_be32(scanType);
4870
4871 pMsg->numSsid = (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ? pScanReq->SSIDs.numOfSSIDs :
4872 SIR_SCAN_MAX_NUM_SSID;
4873 if((pScanReq->SSIDs.numOfSSIDs != 0) && ( eSIR_PASSIVE_SCAN != scanType ))
4874 {
4875 for (i = 0; i < pMsg->numSsid; i++)
4876 {
4877 palCopyMemory(pMac->hHdd, &pMsg->ssId[i], &pScanReq->SSIDs.SSIDList[i].SSID, sizeof(tSirMacSSid));
4878 }
4879 }
4880 else
4881 {
4882 //Otherwise we scan all SSID and let the result filter later
4883 for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++)
4884 {
4885 pMsg->ssId[i].length = 0;
4886 }
4887 }
4888
4889//TODO: This preprocessor macro should be removed from CSR for production driver
4890//This is a temperarory fix for scanning on FPGA.
4891#if defined (ANI_CHIPSET_VIRGO) || defined (LIBRA_FPGA)|| defined (VOLANS_FPGA)
4892 pMsg->minChannelTime = pal_cpu_to_be32(minChnTime * 8);
4893 pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime * 8);
4894#elif defined (ANI_CHIPSET_TAURUS) || defined(ANI_CHIPSET_LIBRA) || defined(ANI_CHIPSET_VOLANS)
4895 pMsg->minChannelTime = pal_cpu_to_be32(minChnTime);
4896 pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime);
4897#else
4898#error unknown chipset
4899#endif
4900 //hidden SSID option
4901 pMsg->hiddenSsid = pScanReqParam->hiddenSsid;
4902 //rest time
4903 //pMsg->restTime = pScanReq->restTime;
4904 pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
4905 // All the scan results caching will be done by Roaming
4906 // We do not want LIM to do any caching of scan results,
4907 // so delete the LIM cache on all scan requests
4908 pMsg->returnFreshResults = pScanReqParam->freshScan;
4909 //Always ask for unique result
4910 pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
4911 pMsg->channelList.numChannels = (tANI_U8)pScanReq->ChannelInfo.numOfChannels;
4912 if(pScanReq->ChannelInfo.numOfChannels)
4913 {
4914 //Assuming the channelNumber is tANI_U8 (1 byte)
4915 status = palCopyMemory(pMac->hHdd, pMsg->channelList.channelNumber, pScanReq->ChannelInfo.ChannelList,
4916 pScanReq->ChannelInfo.numOfChannels);
4917 }
4918
4919 pMsg->uIEFieldLen = (tANI_U16) pScanReq->uIEFieldLen;
4920 pMsg->uIEFieldOffset = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) +
4921 ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) ;
4922 if(pScanReq->uIEFieldLen != 0)
4923 {
4924 palCopyMemory(pMac->hHdd, (tANI_U8 *)pMsg+pMsg->uIEFieldOffset,
4925 pScanReq->pIEField, pScanReq->uIEFieldLen );
4926 }
4927#ifdef WLAN_FEATURE_P2P
4928 pMsg->p2pSearch = pScanReq->p2pSearch;
4929#endif
4930
Madan Mohan Koyyalamudi9b876782012-10-11 16:22:51 -07004931 if (pScanReq->requestType == eCSR_SCAN_HO_BG_SCAN)
4932 {
4933 pMsg->backgroundScanMode = eSIR_ROAMING_SCAN;
4934 }
4935
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 }while(0);
4937 if(HAL_STATUS_SUCCESS(status))
4938 {
4939 status = palSendMBMessage(pMac->hHdd, pMsg);
4940 }
4941 else {
4942 palFreeMemory(pMac->hHdd, pMsg);
4943 }
4944 }//Success allocated memory
4945
4946
4947 return( status );
4948}
4949
4950eHalStatus csrSendMBScanResultReq( tpAniSirGlobal pMac, tScanReqParam *pScanReqParam )
4951{
4952 eHalStatus status = eHAL_STATUS_SUCCESS;
4953 tSirSmeScanReq *pMsg;
4954 tANI_U16 msgLen;
4955
4956 msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ));
4957 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
4958 if(HAL_STATUS_SUCCESS(status))
4959 {
4960 palZeroMemory(pMac->hHdd, pMsg, msgLen);
4961 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
4962 pMsg->length = pal_cpu_to_be16(msgLen);
4963 pMsg->sessionId = 0;
4964 pMsg->returnFreshResults = pScanReqParam->freshScan;
4965 //Always ask for unique result
4966 pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
4967 pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
4968 status = palSendMBMessage(pMac->hHdd, pMsg);
4969 }
4970
4971 return( status );
4972}
4973
4974
4975
4976eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand )
4977{
4978 eHalStatus status = eHAL_STATUS_FAILURE;
4979 tScanReqParam scanReq;
4980
4981 do
4982 {
4983 scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE | TRUE;
4984 scanReq.fUniqueResult = TRUE;
4985 scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID;
4986 if(eCsrScanForSsid == pCommand->u.scanCmd.reason)
4987 {
4988 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_FIRST_MATCH;
4989 }
4990 else
4991 {
4992 // Basically do scan on all channels even for 11D 1st scan case.
4993 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
4994 }
4995 if((eCsrScanBgScan == pCommand->u.scanCmd.reason)||
4996 (eCsrScanProbeBss == pCommand->u.scanCmd.reason))
4997 {
4998 scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION;
4999 }
5000
5001#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
5002 {
5003 vos_log_scan_pkt_type *pScanLog = NULL;
5004
5005 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
5006 if(pScanLog)
5007 {
5008 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
5009 eCsrScanProbeBss == pCommand->u.scanCmd.reason)
5010 {
5011 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
5012 }
5013 else
5014 {
5015 if( (eSIR_PASSIVE_SCAN != pCommand->u.scanCmd.u.scanRequest.scanType) &&
5016 (eSIR_PASSIVE_SCAN != pMac->scan.curScanType) )
5017 {
5018 pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ;
5019 }
5020 else
5021 {
5022 pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ;
5023 }
5024 }
5025 pScanLog->minChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.minChnTime;
5026 pScanLog->maxChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.maxChnTime;
5027 pScanLog->numChannel = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
5028 if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
5029 {
5030 palCopyMemory(pMac->hHdd, pScanLog->channels,
5031 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
5032 pScanLog->numChannel);
5033 }
5034 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
5035 }
5036 }
5037#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
5038
5039
5040 status = csrSendMBScanReq(pMac, pCommand->sessionId,
5041 &pCommand->u.scanCmd.u.scanRequest, &scanReq);
5042 }while(0);
5043
5044 return( status );
5045}
5046
5047
5048eHalStatus csrScanRetrieveResult(tpAniSirGlobal pMac)
5049{
5050 eHalStatus status = eHAL_STATUS_FAILURE;
5051 tScanReqParam scanReq;
5052
5053 do
5054 {
5055 //not a fresh scan
5056 scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE;
5057 scanReq.fUniqueResult = TRUE;
5058 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
5059 status = csrSendMBScanResultReq(pMac, &scanReq);
5060 }while(0);
5061
5062 return (status);
5063}
5064
5065
5066
5067eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
5068{
5069 eHalStatus status = eHAL_STATUS_SUCCESS;
5070 tCsrChannelInfo newChannelInfo = {0, NULL};
5071 int i, j;
5072 tANI_U8 *pChannel = NULL;
5073 tANI_U32 len = 0;
5074
5075 // Transition to Scanning state...
5076 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
5077 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 pCommand->u.scanCmd.lastRoamState[i] = csrRoamStateChange( pMac, eCSR_ROAMING_STATE_SCANNING, i);
5079 smsLog( pMac, LOG3, "starting SCAN command from %d state.... reason is %d\n", pCommand->u.scanCmd.lastRoamState[i], pCommand->u.scanCmd.reason );
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 }
5081
5082 switch(pCommand->u.scanCmd.reason)
5083 {
5084 case eCsrScanGetResult:
5085 case eCsrScanForCapsChange: //For cap change, LIM already save BSS description
5086 status = csrScanRetrieveResult(pMac);
5087 break;
5088 case eCsrScanSetBGScanParam:
5089 status = csrProcessSetBGScanParam(pMac, pCommand);
5090 break;
5091 case eCsrScanBGScanAbort:
5092 status = csrSetCfgBackgroundScanPeriod(pMac, 0);
5093 break;
5094 case eCsrScanBGScanEnable:
5095 status = csrSetCfgBackgroundScanPeriod(pMac, pMac->roam.configParam.bgScanInterval);
5096 break;
5097 case eCsrScanGetScanChnInfo:
5098 status = csrScanGetScanChannelInfo(pMac);
5099 break;
5100 case eCsrScanUserRequest:
5101 if(pMac->roam.configParam.fScanTwice)
5102 {
5103 //We scan 2.4 channel twice
5104 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels &&
5105 (NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList))
5106 {
5107 len = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
5108 //allocate twice the channel
5109 newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(newChannelInfo.numOfChannels * 2);
5110 pChannel = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
5111 }
5112 else
5113 {
5114 //get the valid channel list to scan all.
5115 len = sizeof(pMac->roam.validChannelList);
5116
5117 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
5118 {
5119 //allocate twice the channel
5120 newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2);
5121 pChannel = pMac->roam.validChannelList;
5122 }
5123 }
5124 if(NULL == newChannelInfo.ChannelList)
5125 {
5126 newChannelInfo.numOfChannels = 0;
5127 }
5128 else
5129 {
5130 j = 0;
5131 for(i = 0; i < len; i++)
5132 {
5133 newChannelInfo.ChannelList[j++] = pChannel[i];
5134 if(CSR_MAX_24GHz_CHANNEL_NUMBER >= pChannel[i])
5135 {
5136 newChannelInfo.ChannelList[j++] = pChannel[i];
5137 }
5138 }
5139 if(NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
5140 {
5141 //pChannel points to the channellist from the command, free it.
5142 vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
5143 }
5144 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j;
5145 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = newChannelInfo.ChannelList;
5146 }
5147 } //if(pMac->roam.configParam.fScanTwice)
5148
5149 status = csrScanChannels(pMac, pCommand);
5150
5151 break;
5152 default:
5153 status = csrScanChannels(pMac, pCommand);
5154 break;
5155 }
5156
5157 if(!HAL_STATUS_SUCCESS(status))
5158 {
5159 csrReleaseScanCommand(pMac, pCommand, eCSR_SCAN_FAILURE);
5160 }
5161
5162 return (status);
5163}
5164
5165
5166eHalStatus csrScanSetBGScanparams(tpAniSirGlobal pMac, tCsrBGScanRequest *pScanReq)
5167{
5168 eHalStatus status = eHAL_STATUS_SUCCESS;
5169 tSmeCmd *pCommand = NULL;
5170
5171 if(pScanReq)
5172 {
5173 do
5174 {
5175 pCommand = csrGetCommandBuffer(pMac);
5176 if(!pCommand)
5177 {
5178 status = eHAL_STATUS_RESOURCES;
5179 break;
5180 }
5181 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5182 pCommand->command = eSmeCommandScan;
5183 pCommand->u.scanCmd.reason = eCsrScanSetBGScanParam;
5184 pCommand->u.scanCmd.callback = NULL;
5185 pCommand->u.scanCmd.pContext = NULL;
5186 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.bgScanRequest, pScanReq, sizeof(tCsrBGScanRequest));
5187 //we have to do the follow
5188 if(pScanReq->ChannelInfo.numOfChannels == 0)
5189 {
5190 pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
5191 }
5192 else
5193 {
5194 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList,
5195 pScanReq->ChannelInfo.numOfChannels);
5196 if(HAL_STATUS_SUCCESS(status))
5197 {
5198 palCopyMemory(pMac->hHdd, pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList,
5199 pScanReq->ChannelInfo.ChannelList, pScanReq->ChannelInfo.numOfChannels);
5200 }
5201 else
5202 {
5203 smsLog(pMac, LOGE, FL("ran out of memory\n"));
5204 csrReleaseCommandScan(pMac, pCommand);
5205 break;
5206 }
5207 }
5208
5209 //scan req for SSID
5210 if(pScanReq->SSID.length)
5211 {
5212 palCopyMemory(pMac->hHdd,
5213 pCommand->u.scanCmd.u.bgScanRequest.SSID.ssId,
5214 pScanReq->SSID.ssId,
5215 pScanReq->SSID.length);
5216 pCommand->u.scanCmd.u.bgScanRequest.SSID.length = pScanReq->SSID.length;
5217
5218 }
5219 pCommand->u.scanCmd.u.bgScanRequest.maxChnTime= pScanReq->maxChnTime;
5220 pCommand->u.scanCmd.u.bgScanRequest.minChnTime = pScanReq->minChnTime;
5221 pCommand->u.scanCmd.u.bgScanRequest.scanInterval = pScanReq->scanInterval;
5222
5223
5224 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
5225 if( !HAL_STATUS_SUCCESS( status ) )
5226 {
5227 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
5228 csrReleaseCommandScan( pMac, pCommand );
5229 break;
5230 }
5231 }while(0);
5232 }
5233
5234 return (status);
5235}
5236
5237eHalStatus csrScanBGScanAbort( tpAniSirGlobal pMac )
5238{
5239 eHalStatus status = eHAL_STATUS_SUCCESS;
5240 tSmeCmd *pCommand = NULL;
5241
5242 do
5243 {
5244 pCommand = csrGetCommandBuffer(pMac);
5245 if(!pCommand)
5246 {
5247 status = eHAL_STATUS_RESOURCES;
5248 break;
5249 }
5250 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5251 pCommand->command = eSmeCommandScan;
5252 pCommand->u.scanCmd.reason = eCsrScanBGScanAbort;
5253 pCommand->u.scanCmd.callback = NULL;
5254 pCommand->u.scanCmd.pContext = NULL;
5255 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
5256 if( !HAL_STATUS_SUCCESS( status ) )
5257 {
5258 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
5259 csrReleaseCommandScan( pMac, pCommand );
5260 break;
5261 }
5262 }while(0);
5263
5264 return (status);
5265}
5266
5267
5268//This will enable the background scan with the non-zero interval
5269eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac)
5270{
5271 eHalStatus status = eHAL_STATUS_SUCCESS;
5272 tSmeCmd *pCommand = NULL;
5273
5274 if(pMac->roam.configParam.bgScanInterval)
5275 {
5276 do
5277 {
5278 pCommand = csrGetCommandBuffer(pMac);
5279 if(!pCommand)
5280 {
5281 status = eHAL_STATUS_RESOURCES;
5282 break;
5283 }
5284 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5285 pCommand->command = eSmeCommandScan;
5286 pCommand->u.scanCmd.reason = eCsrScanBGScanEnable;
5287 pCommand->u.scanCmd.callback = NULL;
5288 pCommand->u.scanCmd.pContext = NULL;
5289 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
5290 if( !HAL_STATUS_SUCCESS( status ) )
5291 {
5292 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
5293 csrReleaseCommandScan( pMac, pCommand );
5294 break;
5295 }
5296 }while(0);
5297 //BG scan results are reported automatically by PE to SME once the scan is done.
5298 //No need to fetch the results explicitly.
5299 //csrScanStartGetResultTimer(pMac);
5300 csrScanStartResultAgingTimer(pMac);
5301 }
5302 else
5303 {
5304 //We don't have BG scan so stop the aging timer
5305 csrScanStopResultAgingTimer(pMac);
5306 smsLog(pMac, LOGE, FL("cannot continue because the bgscan interval is 0\n"));
5307 status = eHAL_STATUS_INVALID_PARAMETER;
5308 }
5309
5310 return (status);
5311}
5312
5313
5314eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq)
5315{
5316 eHalStatus status = eHAL_STATUS_SUCCESS;
5317 tANI_U32 len = sizeof(pMac->roam.validChannelList);
5318 tANI_U32 index = 0;
5319 tANI_U32 new_index = 0;
5320
5321 do
5322 {
5323 status = csrScanFreeRequest(pMac, pDstReq);
5324 if(HAL_STATUS_SUCCESS(status))
5325 {
5326 status = palCopyMemory(pMac->hHdd, pDstReq, pSrcReq, sizeof(tCsrScanRequest));
5327 if(pSrcReq->uIEFieldLen == 0)
5328 {
5329 pDstReq->pIEField = NULL;
5330 }
5331 else
5332 {
5333 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->pIEField, pSrcReq->uIEFieldLen);
5334 if(HAL_STATUS_SUCCESS(status))
5335 {
5336 palCopyMemory(pMac->hHdd, pDstReq->pIEField, pSrcReq->pIEField, pSrcReq->uIEFieldLen);
5337 pDstReq->uIEFieldLen = pSrcReq->uIEFieldLen;
5338 }
5339 else
5340 {
5341 smsLog(pMac, LOGE, "No memory for scanning IE fields\n");
5342 break;
5343 }
5344 }//Allocate memory for IE field
5345 {
5346 if(pSrcReq->ChannelInfo.numOfChannels == 0)
5347 {
5348 pDstReq->ChannelInfo.ChannelList = NULL;
5349 pDstReq->ChannelInfo.numOfChannels = 0;
5350 }
5351 else
5352 {
5353 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->ChannelInfo.ChannelList,
5354 pSrcReq->ChannelInfo.numOfChannels * sizeof(*pDstReq->ChannelInfo.ChannelList));
5355 if(!HAL_STATUS_SUCCESS(status))
5356 {
5357 pDstReq->ChannelInfo.numOfChannels = 0;
5358 smsLog(pMac, LOGE, "No memory for scanning Channel List\n");
5359 break;
5360 }
5361
5362 if((pSrcReq->scanType == eSIR_PASSIVE_SCAN) && (pSrcReq->requestType == eCSR_SCAN_REQUEST_11D_SCAN))
5363 {
5364 for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
5365 {
5366 pDstReq->ChannelInfo.ChannelList[new_index] =
5367 pSrcReq->ChannelInfo.ChannelList[index];
5368 new_index++;
5369 }
5370 pDstReq->ChannelInfo.numOfChannels = new_index;
5371 }
5372 else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
5373 {
5374 new_index = 0;
5375 pMac->roam.numValidChannels = len;
5376 for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
5377 {
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -07005378 /* Allow scan on valid channels only.
5379 * If it is p2p scan and valid channel list doesnt contain
5380 * social channels, enforce scan on social channels because
5381 * that is the only way to find p2p peers.
5382 * This can happen only if band is set to 5Ghz mode.
5383 */
Madan Mohan Koyyalamudic5992c92012-11-15 16:40:57 -08005384 if((csrRoamIsValidChannel(pMac, pSrcReq->ChannelInfo.ChannelList[index])) ||
5385 ((eCSR_SCAN_P2P_DISCOVERY == pSrcReq->requestType) &&
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -07005386 CSR_IS_SOCIAL_CHANNEL(pSrcReq->ChannelInfo.ChannelList[index])))
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 {
Madan Mohan Koyyalamudic5992c92012-11-15 16:40:57 -08005388
5389 if( pSrcReq->skipDfsChnlInP2pSearch &&
5390 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(pSrcReq->ChannelInfo.ChannelList[index])) )
5391 continue;
5392
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 pDstReq->ChannelInfo.ChannelList[new_index] =
5394 pSrcReq->ChannelInfo.ChannelList[index];
5395 new_index++;
5396 }
5397 }
5398 pDstReq->ChannelInfo.numOfChannels = new_index;
5399 }
5400 else
5401 {
5402 smsLog(pMac, LOGE, "Couldn't get the valid Channel List, keeping requester's list\n");
5403 palCopyMemory(pMac->hHdd, pDstReq->ChannelInfo.ChannelList, pSrcReq->ChannelInfo.ChannelList,
5404 pSrcReq->ChannelInfo.numOfChannels * sizeof(*pDstReq->ChannelInfo.ChannelList));
5405 pDstReq->ChannelInfo.numOfChannels = pSrcReq->ChannelInfo.numOfChannels;
5406 }
5407 }//Allocate memory for Channel List
5408 }
5409 if(pSrcReq->SSIDs.numOfSSIDs == 0)
5410 {
5411 pDstReq->SSIDs.numOfSSIDs = 0;
5412 pDstReq->SSIDs.SSIDList = NULL;
5413 }
5414 else
5415 {
5416 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->SSIDs.SSIDList,
5417 pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
5418 if(HAL_STATUS_SUCCESS(status))
5419 {
5420 pDstReq->SSIDs.numOfSSIDs = pSrcReq->SSIDs.numOfSSIDs;
5421 palCopyMemory(pMac->hHdd, pDstReq->SSIDs.SSIDList, pSrcReq->SSIDs.SSIDList,
5422 pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
5423 }
5424 else
5425 {
5426 pDstReq->SSIDs.numOfSSIDs = 0;
5427 smsLog(pMac, LOGE, "No memory for scanning SSID List\n");
5428 break;
5429 }
5430 }//Allocate memory for SSID List
5431#ifdef WLAN_FEATURE_P2P
5432 pDstReq->p2pSearch = pSrcReq->p2pSearch;
Jeff Johnsone7245742012-09-05 17:12:55 -07005433 pDstReq->skipDfsChnlInP2pSearch = pSrcReq->skipDfsChnlInP2pSearch;
Jeff Johnson295189b2012-06-20 16:38:30 -07005434#endif
5435
5436 }
5437 }while(0);
5438
5439 if(!HAL_STATUS_SUCCESS(status))
5440 {
5441 csrScanFreeRequest(pMac, pDstReq);
5442 }
5443
5444 return (status);
5445}
5446
5447
5448eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq)
5449{
5450 eHalStatus status = eHAL_STATUS_SUCCESS;
5451
5452 if(pReq->ChannelInfo.ChannelList)
5453 {
5454 status = palFreeMemory(pMac->hHdd, pReq->ChannelInfo.ChannelList);
5455 pReq->ChannelInfo.ChannelList = NULL;
5456 }
5457 pReq->ChannelInfo.numOfChannels = 0;
5458 if(pReq->pIEField)
5459 {
5460 status = palFreeMemory(pMac->hHdd, pReq->pIEField);
5461 pReq->pIEField = NULL;
5462 }
5463 pReq->uIEFieldLen = 0;
5464 if(pReq->SSIDs.SSIDList)
5465 {
5466 palFreeMemory(pMac->hHdd, pReq->SSIDs.SSIDList);
5467 pReq->SSIDs.SSIDList = NULL;
5468 }
5469 pReq->SSIDs.numOfSSIDs = 0;
5470
5471 return (status);
5472}
5473
5474
5475void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
5476{
5477 if(pCommand->u.scanCmd.callback)
5478 {
5479// sme_ReleaseGlobalLock( &pMac->sme );
5480 pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, pCommand->u.scanCmd.scanID, scanStatus);
5481// sme_AcquireGlobalLock( &pMac->sme );
5482 } else {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005483 smsLog( pMac, LOG2, "%s:%d - Callback NULL!!!\n", __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005484 }
5485}
5486
5487
5488void csrScanStopTimers(tpAniSirGlobal pMac)
5489{
5490 csrScanStopResultAgingTimer(pMac);
5491 csrScanStopIdleScanTimer(pMac);
5492 csrScanStopGetResultTimer(pMac);
5493}
5494
5495
5496eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac)
5497{
5498 eHalStatus status;
5499
5500 if(pMac->scan.fScanEnable)
5501 {
5502 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL, eANI_BOOLEAN_TRUE);
5503 }
5504 else
5505 {
5506 status = eHAL_STATUS_FAILURE;
5507 }
5508
5509 return (status);
5510}
5511
5512
5513eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac)
5514{
5515 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerGetResult));
5516}
5517
5518
5519void csrScanGetResultTimerHandler(void *pv)
5520{
5521 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5522
5523 csrScanRequestResult(pMac);
5524}
5525
5526#ifdef WLAN_AP_STA_CONCURRENCY
5527static void csrStaApConcTimerHandler(void *pv)
5528{
5529 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5530 tListElem *pEntry;
5531 tSmeCmd *pScanCmd;
5532
5533 csrLLLock(&pMac->scan.scanCmdPendingList);
5534
5535 if ( NULL != ( pEntry = csrLLPeekHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) )
5536 {
5537 tCsrScanRequest scanReq;
5538 tSmeCmd *pSendScanCmd = NULL;
5539 tANI_U8 numChn = 0;
5540 tANI_U8 i;
5541 tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
5542 tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5543 eHalStatus status;
5544
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 pScanCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
5546 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
Madan Mohan Koyyalamudid6713582012-11-09 16:56:56 -08005547
5548 /* if any session is connected and the number of channels to scan is
5549 * greater than 1 then split the scan into multiple scan operations
5550 * on each individual channel else continue to perform scan on all
5551 * specified channels */
Madan Mohan Koyyalamudi48081ef2012-12-04 16:49:55 -08005552
5553 /* split scan if number of channels to scan is greater than 1 and
5554 * any one of the following:
5555 * - STA session is connected and the scan is not a P2P search
5556 * - any P2P session is connected
5557 */
5558 if ( (numChn > 1) &&
5559 ((csrIsStaSessionConnected(pMac) && (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
5560 (csrIsP2pSessionConnected(pMac))))
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 {
5562 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
5563
5564 pSendScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
5565 if (!pSendScanCmd)
5566 {
5567 smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer\n") );
5568 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5569 return;
5570 }
5571 pSendScanCmd->command = pScanCmd->command;
5572 pSendScanCmd->sessionId = pScanCmd->sessionId;
5573 pSendScanCmd->u.scanCmd.callback = NULL;
5574 pSendScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
5575 pSendScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
5576 pSendScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
5577
Madan Mohan Koyyalamudiaf2a8b92012-10-09 14:58:07 -07005578 /* First copy all the parameters to local variable of scan request */
5579 csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
5580
5581 /* Now modify the elements of local var scan request required to be modified for split scan */
Madan Mohan Koyyalamudi0c626f32012-11-30 15:10:25 -08005582 if(scanReq.ChannelInfo.ChannelList != NULL)
5583 {
5584 palFreeMemory(pMac->hHdd,scanReq.ChannelInfo.ChannelList);
5585 scanReq.ChannelInfo.ChannelList = NULL;
5586 }
5587
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 pChnInfo->numOfChannels = 1;
5589 palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0],
5590 1 * sizeof(tANI_U8)); //just send one channel
5591 pChnInfo->ChannelList = &channelToScan[0];
5592
Madan Mohan Koyyalamudiaf2a8b92012-10-09 14:58:07 -07005593 for (i = 0; i <= (numChn-2); i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 {
5595 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] =
5596 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i+1]; //Move all the channels one step
5597 }
5598
5599 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn -1; //reduce outstanding # of channels to be scanned
5600
5601 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
5602 //Modify callers parameters in case of concurrency
5603 scanReq.scanType = eSIR_ACTIVE_SCAN;
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -07005604 //Use concurrency values for min/maxChnTime.
5605 //We know csrIsAnySessionConnected(pMac) returns TRUE here
5606 csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);
Jeff Johnson295189b2012-06-20 16:38:30 -07005607
5608 status = csrScanCopyRequest(pMac, &pSendScanCmd->u.scanCmd.u.scanRequest, &scanReq);
5609 if(!HAL_STATUS_SUCCESS(status))
5610 {
5611 smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d\n"), status );
5612 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5613 return;
Madan Mohan Koyyalamudi0c626f32012-11-30 15:10:25 -08005614 }
5615 /* Clean the local scan variable */
5616 scanReq.ChannelInfo.ChannelList = NULL;
5617 scanReq.ChannelInfo.numOfChannels = 0;
5618 csrScanFreeRequest(pMac, &scanReq);
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 }
5620 else
Madan Mohan Koyyalamudid6713582012-11-09 16:56:56 -08005621 {
5622 /* no active connected session present or numChn == 1
5623 * scan all remaining channels */
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 pSendScanCmd = pScanCmd;
5625 //remove this command from pending list
5626 if (csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) == NULL)
5627 { //In case between PeekHead and here, the entry got removed by another thread.
5628 smsLog( pMac, LOGE, FL(" Failed to remove entry from scanCmdPendingList\n"));
5629 }
5630
5631 }
5632 csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);
5633
5634 }
5635
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5637
5638}
5639#endif
5640
5641eHalStatus csrScanStartResultAgingTimer(tpAniSirGlobal pMac)
5642{
5643 eHalStatus status;
5644
5645 if(pMac->scan.fScanEnable)
5646 {
5647 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerResultAging, CSR_SCAN_RESULT_AGING_INTERVAL, eANI_BOOLEAN_TRUE);
5648 }
5649 else
5650 {
5651 status = eHAL_STATUS_FAILURE;
5652 }
5653
5654 return (status);
5655}
5656
5657
5658eHalStatus csrScanStopResultAgingTimer(tpAniSirGlobal pMac)
5659{
5660 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerResultAging));
5661}
5662
5663
5664//This function returns the maximum time a BSS is allowed in the scan result.
5665//The time varies base on connection and power saving factors.
5666//Not connected, No PS
5667//Not connected, with PS
5668//Connected w/o traffic, No PS
5669//Connected w/o traffic, with PS
5670//Connected w/ traffic, no PS -- Not supported
5671//Connected w/ traffic, with PS -- Not supported
5672//the return unit is in seconds.
5673tANI_U32 csrScanGetAgeOutTime(tpAniSirGlobal pMac)
5674{
5675 tANI_U32 nRet;
5676
5677 if(pMac->scan.nAgingCountDown)
5678 {
5679 //Calculate what should be the timeout value for this
5680 nRet = pMac->scan.nLastAgeTimeOut * pMac->scan.nAgingCountDown;
5681 pMac->scan.nAgingCountDown--;
5682 }
5683 else
5684 {
5685 if( csrIsAllSessionDisconnected( pMac ) )
5686 {
5687 if(pmcIsPowerSaveEnabled(pMac, ePMC_IDLE_MODE_POWER_SAVE))
5688 {
5689 nRet = pMac->roam.configParam.scanAgeTimeNCPS;
5690 }
5691 else
5692 {
5693 nRet = pMac->roam.configParam.scanAgeTimeNCNPS;
5694 }
5695 }
5696 else
5697 {
5698 if(pmcIsPowerSaveEnabled(pMac, ePMC_BEACON_MODE_POWER_SAVE))
5699 {
5700 nRet = pMac->roam.configParam.scanAgeTimeCPS;
5701 }
5702 else
5703 {
5704 nRet = pMac->roam.configParam.scanAgeTimeCNPS;
5705 }
5706 }
5707 //If state-change causing aging time out change, we want to delay it somewhat to avoid
5708 //unnecessary removal of BSS. This is mostly due to transition from connect to disconnect.
5709 if(pMac->scan.nLastAgeTimeOut > nRet)
5710 {
5711 if(nRet)
5712 {
5713 pMac->scan.nAgingCountDown = (pMac->scan.nLastAgeTimeOut / nRet);
5714 }
5715 pMac->scan.nLastAgeTimeOut = nRet;
5716 nRet *= pMac->scan.nAgingCountDown;
5717 }
5718 else
5719 {
5720 pMac->scan.nLastAgeTimeOut = nRet;
5721 }
5722 }
5723
5724 return (nRet);
5725}
5726
5727
5728void csrScanResultAgingTimerHandler(void *pv)
5729{
5730 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5731 tANI_BOOLEAN fDisconnected = csrIsAllSessionDisconnected(pMac);
5732
5733 //no scan, no aging
5734 if(pMac->scan.fScanEnable &&
5735 (((eANI_BOOLEAN_FALSE == fDisconnected) && pMac->roam.configParam.bgScanInterval)
5736 || (fDisconnected && (pMac->scan.fCancelIdleScan == eANI_BOOLEAN_FALSE)))
5737 )
5738 {
5739 tListElem *pEntry, *tmpEntry;
5740 tCsrScanResult *pResult;
5741 tANI_TIMESTAMP ageOutTime = (tANI_TIMESTAMP)(csrScanGetAgeOutTime(pMac) * PAL_TICKS_PER_SECOND); //turn it into 10ms units
5742 tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
5743
5744 csrLLLock(&pMac->scan.scanResultList);
5745 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
5746 while( pEntry )
5747 {
5748 tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
5749 pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
5750 if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime)
5751 {
5752 smsLog(pMac, LOGW, " age out due to time out");
5753 csrScanAgeOutBss(pMac, pResult);
5754 }
5755 pEntry = tmpEntry;
5756 }
5757 csrLLUnlock(&pMac->scan.scanResultList);
5758 }
5759}
5760
5761
5762eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval)
5763{
5764 eHalStatus status;
5765
5766 smsLog(pMac, LOG1, " csrScanStartIdleScanTimer \n ");
5767 if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) && interval)
5768 {
5769 pMac->scan.nIdleScanTimeGap += interval;
5770 palTimerStop(pMac->hHdd, pMac->scan.hTimerIdleScan);
5771 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerIdleScan, interval, eANI_BOOLEAN_FALSE);
5772 if( !HAL_STATUS_SUCCESS(status) )
5773 {
5774 smsLog(pMac, LOGE, " Fail to start Idle scan timer. status = %d interval = %d\n", status, interval);
5775 //This should not happen but set the flag to restart when ready
5776 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5777 }
5778 }
5779 else
5780 {
5781 if( pMac->scan.fScanEnable && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) )
5782 {
5783 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5784 }
5785 status = eHAL_STATUS_FAILURE;
5786 }
5787
5788 return (status);
5789}
5790
5791
5792eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac)
5793{
5794 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerIdleScan));
5795}
5796
5797
5798//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR
5799void csrScanSuspendIMPS( tpAniSirGlobal pMac )
5800{
5801 csrScanCancelIdleScan(pMac);
5802}
5803
5804
5805//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS
5806//because IMPS maybe disabled.
5807void csrScanResumeIMPS( tpAniSirGlobal pMac )
5808{
5809 csrScanStartIdleScan( pMac );
5810}
5811
5812
5813void csrScanIMPSCallback(void *callbackContext, eHalStatus status)
5814{
5815 tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext );
5816
5817 if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5818 {
5819 if(pMac->roam.configParam.IsIdleScanEnabled)
5820 {
5821 if(HAL_STATUS_SUCCESS(status))
5822 {
5823 if(csrIsAllSessionDisconnected(pMac) && !csrIsRoamCommandWaiting(pMac))
5824 {
5825 smsLog(pMac, LOGW, FL("starts idle mode full scan\n"));
5826 csrScanAllChannels(pMac, eCSR_SCAN_IDLE_MODE_SCAN);
5827 }
5828 else
5829 {
5830 smsLog(pMac, LOGW, FL("cannot start idle mode full scan\n"));
5831 //even though we are in timer handle, calling stop timer will make sure the timer
5832 //doesn't get to restart.
5833 csrScanStopIdleScanTimer(pMac);
5834 }
5835 }
5836 else
5837 {
5838 smsLog(pMac, LOGE, FL("sees not success status (%d)\n"), status);
5839 }
5840 }
5841 else
5842 {//we might need another flag to check if CSR needs to request imps at all
5843
5844 tANI_U32 nTime = 0;
5845
5846 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE;
5847 if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime)))
5848 {
5849 csrScanStartIdleScanTimer(pMac, nTime);
5850 }
5851 }
5852 }
5853}
5854
5855
5856//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for
5857//idle scan timer interval
5858//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan
5859eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval)
5860{
5861 eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;
5862
5863 //Do not trigger IMPS in case of concurrency
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005864 if (vos_concurrent_sessions_running() && csrIsAnySessionInConnectState(pMac))
5865 {
Mohit Khanna23863762012-09-11 17:40:09 -07005866 smsLog( pMac, LOG1, FL("Cannot request IMPS because Concurrent Sessions Running\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 return (status);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005868 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005869
5870 if(pTimeInterval)
5871 {
5872 *pTimeInterval = 0;
5873 }
5874
Mohit Khanna23863762012-09-11 17:40:09 -07005875 smsLog(pMac, LOG3, FL("called\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 if( smeCommandPending( pMac ) )
5877 {
Mohit Khanna23863762012-09-11 17:40:09 -07005878 smsLog( pMac, LOG1, FL(" Cannot request IMPS because command pending\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 //Not to enter IMPS because more work to do
5880 if(pTimeInterval)
5881 {
5882 *pTimeInterval = 0;
5883 }
5884 //restart when ready
5885 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5886
5887 return (status);
5888 }
5889
5890 if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5891 /*&& pMac->roam.configParam.impsSleepTime*/)
5892 {
5893 //Stop get result timer because idle scan gets scan result out of PE
5894 csrScanStopGetResultTimer(pMac);
5895 if(pTimeInterval)
5896 {
5897 *pTimeInterval = pMac->roam.configParam.impsSleepTime;
5898 }
5899 //pmcRequestImps take a period in millisecond unit.
5900 status = pmcRequestImps(pMac, pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_MS_UNIT, csrScanIMPSCallback, pMac);
5901 if(!HAL_STATUS_SUCCESS(status))
5902 {
5903 if(eHAL_STATUS_PMC_ALREADY_IN_IMPS != status)
5904 {
5905 //Do restart the timer if CSR thinks it cannot do IMPS
5906 if( !csrCheckPSReady( pMac ) )
5907 {
5908 if(pTimeInterval)
5909 {
5910 *pTimeInterval = 0;
5911 }
5912 //Set the restart flag to true because that idle scan
5913 //can be restarted even though the timer will not be running
5914 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5915 }
5916 else
5917 {
5918 //For not now, we do a quicker retry
5919 if(pTimeInterval)
5920 {
5921 *pTimeInterval = CSR_IDLE_SCAN_WAIT_TIME;
5922 }
5923 }
5924 smsLog(pMac, LOGW, FL("call pmcRequestImps and it returns status code (%d)\n"), status);
5925 }
5926 else
5927 {
5928 smsLog(pMac, LOGW, FL("already in IMPS\n"));
5929 //Since CSR is the only module to request for IMPS. If it is already in IMPS, CSR assumes
5930 //the callback will be called in the future. Should not happen though.
5931 status = eHAL_STATUS_SUCCESS;
5932 pMac->scan.nIdleScanTimeGap = 0;
5933 }
5934 }
5935 else
5936 {
5937 //requested so let's reset the value
5938 pMac->scan.nIdleScanTimeGap = 0;
5939 }
5940 }
5941
5942 return (status);
5943}
5944
5945
5946eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac)
5947{
5948 eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;
5949 tANI_U32 nTime = 0;
5950
5951 smsLog(pMac, LOGW, FL("called\n"));
5952 if(pMac->roam.configParam.IsIdleScanEnabled)
5953 {
5954 //stop bg scan first
5955 csrScanBGScanAbort(pMac);
5956 //Stop get result timer because idle scan gets scan result out of PE
5957 csrScanStopGetResultTimer(pMac);
5958 //Enable aging timer since idle scan is going on
5959 csrScanStartResultAgingTimer(pMac);
5960 }
5961 pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE;
5962 status = csrScanTriggerIdleScan(pMac, &nTime);
5963 if(!HAL_STATUS_SUCCESS(status))
5964 {
5965 csrScanStartIdleScanTimer(pMac, nTime);
5966 }
5967
5968 return (status);
5969}
5970
5971
5972void csrScanCancelIdleScan(tpAniSirGlobal pMac)
5973{
5974 if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5975 {
5976#ifdef WLAN_SOFTAP_FEATURE
5977 if (vos_concurrent_sessions_running()) {
5978 return;
5979 }
5980#endif
5981 smsLog(pMac, LOG1, " csrScanCancelIdleScan\n");
5982 pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE;
5983 //Set the restart flag in case later on it is uncancelled
5984 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5985 csrScanStopIdleScanTimer(pMac);
5986 csrScanRemoveNotRoamingScanCommand(pMac);
5987 }
5988}
5989
5990
5991void csrScanIdleScanTimerHandler(void *pv)
5992{
5993 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5994 eHalStatus status;
5995 tANI_U32 nTime = 0;
5996
5997 smsLog(pMac, LOGW, " csrScanIdleScanTimerHandler called ");
5998 status = csrScanTriggerIdleScan(pMac, &nTime);
5999 if(!HAL_STATUS_SUCCESS(status) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan))
6000 {
6001 //Check whether it is time to actually do an idle scan
6002 if(pMac->scan.nIdleScanTimeGap >= pMac->roam.configParam.impsSleepTime)
6003 {
6004 pMac->scan.nIdleScanTimeGap = 0;
6005 csrScanIMPSCallback(pMac, eHAL_STATUS_SUCCESS);
6006 }
6007 else
6008 {
6009 csrScanStartIdleScanTimer(pMac, nTime);
6010 }
6011 }
6012}
6013
6014
6015
6016
6017tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac)
6018{
6019 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
6020 tListElem *pEntry, *pEntryTmp;
6021 tSmeCmd *pCommand;
6022 tDblLinkList localList;
6023
6024 vos_mem_zero(&localList, sizeof(tDblLinkList));
6025 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
6026 {
6027 smsLog(pMac, LOGE, FL(" failed to open list"));
6028 return fRet;
6029 }
6030
6031 csrLLLock(&pMac->sme.smeCmdPendingList);
6032 pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
6033 while(pEntry)
6034 {
6035 pEntryTmp = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK);
6036 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6037 if( eSmeCommandScan == pCommand->command )
6038 {
6039 switch( pCommand->u.scanCmd.reason )
6040 {
6041 case eCsrScanIdleScan:
6042 if( csrLLRemoveEntry(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK) )
6043 {
6044 csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
6045 }
6046 fRet = eANI_BOOLEAN_TRUE;
6047 break;
6048
6049 default:
6050 break;
6051 } //switch
6052 }
6053 pEntry = pEntryTmp;
6054 }
6055
6056 csrLLUnlock(&pMac->sme.smeCmdPendingList);
6057
6058 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
6059 {
6060 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6061 csrReleaseCommandScan( pMac, pCommand );
6062 }
6063
6064 csrLLClose(&localList);
6065
6066 return (fRet);
6067}
6068
6069
6070tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId)
6071{
6072 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
6073 tListElem *pEntry, *pEntryTmp;
6074 tSmeCmd *pCommand;
6075 tDblLinkList localList;
6076
6077 vos_mem_zero(&localList, sizeof(tDblLinkList));
6078 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
6079 {
6080 smsLog(pMac, LOGE, FL(" failed to open list"));
6081 return fRet;
6082 }
6083
6084 csrLLLock(&pMac->sme.smeCmdPendingList);
6085 pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
6086 while(pEntry)
6087 {
6088 pEntryTmp = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK);
6089 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6090 if( (eSmeCommandScan == pCommand->command) && (sessionId == pCommand->sessionId) )
6091 {
6092 switch(pCommand->u.scanCmd.reason)
6093 {
6094 case eCsrScanGetResult:
6095 case eCsrScanSetBGScanParam:
6096 case eCsrScanBGScanAbort:
6097 case eCsrScanBGScanEnable:
6098 case eCsrScanGetScanChnInfo:
6099 break;
6100 default:
6101 smsLog (pMac, LOGW, "%s: -------- abort scan command reason = %d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006102 __func__, pCommand->u.scanCmd.reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 //The rest are fresh scan requests
6104 if( csrLLRemoveEntry(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK) )
6105 {
6106 csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
6107 }
6108 fRet = eANI_BOOLEAN_TRUE;
6109 break;
6110 }
6111 }
6112 pEntry = pEntryTmp;
6113 }
6114
6115 csrLLUnlock(&pMac->sme.smeCmdPendingList);
6116
6117 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
6118 {
6119 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6120 if (pCommand->u.scanCmd.callback)
6121 {
6122 /* User scan request is pending,
6123 * send response with status eCSR_SCAN_ABORT*/
6124 pCommand->u.scanCmd.callback(pMac,
6125 pCommand->u.scanCmd.pContext,
6126 pCommand->u.scanCmd.scanID,
6127 eCSR_SCAN_ABORT);
6128 }
6129 csrReleaseCommandScan( pMac, pCommand );
6130 }
6131 csrLLClose(&localList);
6132
6133 return (fRet);
6134}
6135
6136
6137void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
6138{
6139 eCsrScanReason reason = pCommand->u.scanCmd.reason;
6140 tANI_U32 i;
6141 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
6142 {
Jeff Johnson43971f52012-07-17 12:26:56 -07006143 csrRoamStateChange( pMac, pCommand->u.scanCmd.lastRoamState[i], i);
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 }
6145
6146 csrScanCallCallback(pMac, pCommand, scanStatus);
6147
6148 smsLog(pMac, LOG3, " Remove Scan command reason = %d\n", reason);
6149 if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_LOCK ) )
6150 {
6151 csrReleaseCommandScan( pMac, pCommand );
6152 }
6153 else
6154 {
6155 smsLog(pMac, LOGE, " ********csrReleaseScanCommand cannot release command reason %d\n", pCommand->u.scanCmd.reason );
6156 }
6157}
6158
6159
6160eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
6161 tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems )
6162{
6163 eHalStatus status = eHAL_STATUS_SUCCESS;
6164 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
6165
Jeff Johnson32d95a32012-09-10 13:15:23 -07006166 if(!pSession)
6167 {
6168 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
6169 return eHAL_STATUS_FAILURE;
6170 }
6171
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 smsLog(pMac, LOGW, " pMac->scan.NumPmkidCandidate = %d\n ", pSession->NumPmkidCandidate);
6173 csrResetPMKIDCandidateList(pMac, sessionId);
6174 if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
6175 {
6176 tCsrScanResultFilter *pScanFilter;
6177 tCsrScanResultInfo *pScanResult;
6178 tScanResultHandle hBSSList;
6179 tANI_U32 nItems = *pNumItems;
6180
6181 *pNumItems = 0;
6182 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
6183 if(HAL_STATUS_SUCCESS(status))
6184 {
6185 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
6186 //Here is the profile we need to connect to
6187 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
6188 if(HAL_STATUS_SUCCESS(status))
6189 {
6190 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
6191 if(HAL_STATUS_SUCCESS(status))
6192 {
6193 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumPmkidCandidate < nItems))
6194 {
6195 //NumPmkidCandidate adds up here
6196 csrProcessBSSDescForPMKIDList(pMac, &pScanResult->BssDescriptor,
6197 (tDot11fBeaconIEs *)( pScanResult->pvIes ));
6198 }
6199 if(pSession->NumPmkidCandidate)
6200 {
6201 *pNumItems = pSession->NumPmkidCandidate;
6202 palCopyMemory(pMac->hHdd, pPmkidList, pSession->PmkidCandidateInfo,
6203 pSession->NumPmkidCandidate * sizeof(tPmkidCandidateInfo));
6204 }
6205 csrScanResultPurge(pMac, hBSSList);
6206 }//Have scan result
6207 csrFreeScanFilter(pMac, pScanFilter);
6208 }
6209 palFreeMemory(pMac->hHdd, pScanFilter);
6210 }
6211 }
6212
6213 return (status);
6214}
6215
6216
6217
6218#ifdef FEATURE_WLAN_WAPI
6219eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
6220 tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems )
6221{
6222 eHalStatus status = eHAL_STATUS_SUCCESS;
6223 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
6224
Jeff Johnson32d95a32012-09-10 13:15:23 -07006225 if(!pSession)
6226 {
6227 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
6228 return eHAL_STATUS_FAILURE;
6229 }
6230
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 smsLog(pMac, LOGW, " pMac->scan.NumBkidCandidate = %d\n ", pSession->NumBkidCandidate);
6232 csrResetBKIDCandidateList(pMac, sessionId);
6233 if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
6234 {
6235 tCsrScanResultFilter *pScanFilter;
6236 tCsrScanResultInfo *pScanResult;
6237 tScanResultHandle hBSSList;
6238 tANI_U32 nItems = *pNumItems;
6239 *pNumItems = 0;
6240 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
6241 if(HAL_STATUS_SUCCESS(status))
6242 {
6243 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
6244 //Here is the profile we need to connect to
6245 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
6246 if(HAL_STATUS_SUCCESS(status))
6247 {
6248 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
6249 if(HAL_STATUS_SUCCESS(status))
6250 {
6251 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumBkidCandidate < nItems))
6252 {
6253 //pMac->scan.NumBkidCandidate adds up here
6254 csrProcessBSSDescForBKIDList(pMac, &pScanResult->BssDescriptor,
6255 (tDot11fBeaconIEs *)( pScanResult->pvIes ));
6256
6257 }
6258 if(pSession->NumBkidCandidate)
6259 {
6260 *pNumItems = pSession->NumBkidCandidate;
6261 palCopyMemory(pMac->hHdd, pBkidList, pSession->BkidCandidateInfo, pSession->NumBkidCandidate * sizeof(tBkidCandidateInfo));
6262 }
6263 csrScanResultPurge(pMac, hBSSList);
6264 }//Have scan result
6265 }
6266 palFreeMemory(pMac->hHdd, pScanFilter);
6267 }
6268 }
6269
6270 return (status);
6271}
6272#endif /* FEATURE_WLAN_WAPI */
6273
6274
6275
6276//This function is usually used for BSSs that suppresses SSID so the profile
6277//shall have one and only one SSID
6278eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId)
6279{
6280 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6281 tSmeCmd *pScanCmd = NULL;
6282 tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6283 tANI_U8 index = 0;
6284 tANI_U32 numSsid = pProfile->SSIDs.numOfSSIDs;
6285
6286 smsLog(pMac, LOG2, FL("called\n"));
6287 //For WDS, we use the index 0. There must be at least one in there
6288 if( CSR_IS_WDS_STA( pProfile ) && numSsid )
6289 {
6290 numSsid = 1;
6291 }
6292 if(pMac->scan.fScanEnable && ( numSsid == 1 ) )
6293 {
6294 do
6295 {
6296 pScanCmd = csrGetCommandBuffer(pMac);
6297 if(!pScanCmd)
6298 {
6299 smsLog(pMac, LOGE, FL("failed to allocate command buffer\n"));
6300 break;
6301 }
6302 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
6303 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.pToRoamProfile, sizeof(tCsrRoamProfile));
6304 if(!HAL_STATUS_SUCCESS(status))
6305 break;
6306 status = csrRoamCopyProfile(pMac, pScanCmd->u.scanCmd.pToRoamProfile, pProfile);
6307 if(!HAL_STATUS_SUCCESS(status))
6308 break;
6309 pScanCmd->u.scanCmd.roamId = roamId;
6310 pScanCmd->command = eSmeCommandScan;
Jeff Johnsone7245742012-09-05 17:12:55 -07006311 pScanCmd->sessionId = (tANI_U8)sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 pScanCmd->u.scanCmd.callback = NULL;
6313 pScanCmd->u.scanCmd.pContext = NULL;
6314 pScanCmd->u.scanCmd.reason = eCsrScanForSsid;
6315 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
6316 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest));
6317 pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 pScanCmd->u.scanCmd.u.scanRequest.BSSType = pProfile->BSSType;
Jeff Johnsone7245742012-09-05 17:12:55 -07006319 // To avoid 11b rate in probe request Set p2pSearch flag as 1 for P2P Client Mode
6320 if(VOS_P2P_CLIENT_MODE == pProfile->csrPersona)
6321 {
6322 pScanCmd->u.scanCmd.u.scanRequest.p2pSearch = 1;
6323 }
6324 if(pProfile->pAddIEScan)
6325 {
6326 status = palAllocateMemory(pMac->hHdd,
6327 (void **)&pScanCmd->u.scanCmd.u.scanRequest.pIEField,
6328 pProfile->nAddIEScanLength);
6329 palZeroMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.pIEField, pProfile->nAddIEScanLength);
6330 if(HAL_STATUS_SUCCESS(status))
6331 {
6332 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.pIEField, pProfile->pAddIEScan, pProfile->nAddIEScanLength);
6333 pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = pProfile->nAddIEScanLength;
6334 }
6335 else
6336 {
6337 smsLog(pMac, LOGE, "No memory for scanning IE fields\n");
6338 }
6339 } //Allocate memory for IE field
6340 else
6341 {
6342 pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = 0;
6343 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006344 /* For one channel be good enpugh time to receive beacon atleast */
6345 if( 1 == pProfile->ChannelInfo.numOfChannels )
6346 {
6347 pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL;
6348 pScanCmd->u.scanCmd.u.scanRequest.minChnTime = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL;
6349 }
6350 else
6351 {
6352 pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
6353 pScanCmd->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
6354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 if(pProfile->BSSIDs.numOfBSSIDs == 1)
6356 {
6357 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.bssid, pProfile->BSSIDs.bssid, sizeof(tCsrBssid));
6358 }
6359 else
6360 {
6361 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.bssid, bAddr, 6);
6362 }
6363 if(pProfile->ChannelInfo.numOfChannels)
6364 {
6365 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, sizeof(*pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) * pProfile->ChannelInfo.numOfChannels);
6366 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
6367 if(HAL_STATUS_SUCCESS(status))
6368 {
6369 csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[0]);
6370 for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++)
6371 {
6372 if(csrRoamIsValidChannel(pMac, pProfile->ChannelInfo.ChannelList[index]))
6373 {
6374 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels]
6375 = pProfile->ChannelInfo.ChannelList[index];
6376 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++;
6377 }
6378 else
6379 {
6380 smsLog(pMac, LOGW, FL("process a channel (%d) that is invalid\n"), pProfile->ChannelInfo.ChannelList[index]);
6381 }
6382
6383 }
6384 }
6385 else
6386 {
6387 break;
6388 }
6389
6390 }
6391 else
6392 {
6393 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
6394 }
6395 if(pProfile->SSIDs.numOfSSIDs)
6396 {
6397 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList,
6398 pProfile->SSIDs.numOfSSIDs * sizeof(tCsrSSIDInfo));
6399 if(!HAL_STATUS_SUCCESS(status))
6400 {
6401 break;
6402 }
6403 pScanCmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1;
6404 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList, pProfile->SSIDs.SSIDList,
6405 sizeof(tCsrSSIDInfo));
6406 }
6407 //Start process the command
6408 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
6409 if( !HAL_STATUS_SUCCESS( status ) )
6410 {
6411 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
6412 break;
6413 }
6414 }while(0);
6415 if(!HAL_STATUS_SUCCESS(status))
6416 {
6417 if(pScanCmd)
6418 {
6419 csrReleaseCommandScan(pMac, pScanCmd);
6420 //TODO:free the memory that is allocated in this function
6421 }
6422 csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
6423 }
6424 }//valid
6425 else
6426 {
6427 smsLog(pMac, LOGE, FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid\n"),
6428 pMac->scan.fScanEnable, pProfile->SSIDs.numOfSSIDs);
6429 }
6430
6431 return (status);
6432}
6433
6434
6435//Issue a scan base on the new capability infomation
6436//This should only happen when the associated AP changes its capability.
6437//After this scan is done, CSR reroams base on the new scan results
6438eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps)
6439{
6440 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6441 tSmeCmd *pScanCmd = NULL;
6442
6443 if(pNewCaps)
6444 {
6445 do
6446 {
6447 pScanCmd = csrGetCommandBuffer(pMac);
6448 if(!pScanCmd)
6449 {
6450 smsLog(pMac, LOGE, FL("failed to allocate command buffer\n"));
6451 status = eHAL_STATUS_RESOURCES;
6452 break;
6453 }
6454 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
6455 status = eHAL_STATUS_SUCCESS;
6456 pScanCmd->u.scanCmd.roamId = 0;
6457 pScanCmd->command = eSmeCommandScan;
6458 pScanCmd->u.scanCmd.callback = NULL;
6459 pScanCmd->u.scanCmd.pContext = NULL;
6460 pScanCmd->u.scanCmd.reason = eCsrScanForCapsChange;
6461 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
6462 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
6463 if( !HAL_STATUS_SUCCESS( status ) )
6464 {
6465 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
6466 break;
6467 }
6468 }while(0);
6469 if(!HAL_STATUS_SUCCESS(status))
6470 {
6471 if(pScanCmd)
6472 {
6473 csrReleaseCommandScan(pMac, pScanCmd);
6474 }
6475 }
6476 }
6477
6478 return (status);
6479}
6480
6481
6482
6483void csrInitBGScanChannelList(tpAniSirGlobal pMac)
6484{
6485 tANI_U32 len = CSR_MIN(sizeof(pMac->roam.validChannelList), sizeof(pMac->scan.bgScanChannelList));
6486
6487 palZeroMemory(pMac->hHdd, pMac->scan.bgScanChannelList, len);
6488 pMac->scan.numBGScanChannel = 0;
6489
6490 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
6491 {
6492 pMac->roam.numValidChannels = len;
6493 pMac->scan.numBGScanChannel = (tANI_U8)CSR_MIN(len, WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN);
6494 palCopyMemory(pMac->hHdd, pMac->scan.bgScanChannelList, pMac->roam.validChannelList, pMac->scan.numBGScanChannel);
6495 csrSetBGScanChannelList(pMac, pMac->scan.bgScanChannelList, pMac->scan.numBGScanChannel);
6496 }
6497}
6498
6499
6500//This function return TRUE if background scan channel list is adjusted.
6501//this function will only shrink the background scan channel list
6502tANI_BOOLEAN csrAdjustBGScanChannelList(tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels,
6503 tANI_U8 *pAdjustChannels, tANI_U8 *pNumAdjustChannels)
6504{
6505 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
6506 tANI_U8 i, j, count = *pNumAdjustChannels;
6507
6508 i = 0;
6509 while(i < count)
6510 {
6511 for(j = 0; j < NumChannels; j++)
6512 {
6513 if(pChannelList[j] == pAdjustChannels[i])
6514 break;
6515 }
6516 if(j == NumChannels)
6517 {
6518 //This channel is not in the list, remove it
6519 fRet = eANI_BOOLEAN_TRUE;
6520 count--;
6521 if(count - i)
6522 {
6523 palCopyMemory(pMac->hHdd, &pAdjustChannels[i], &pAdjustChannels[i+1], count - i);
6524 }
6525 else
6526 {
6527 //already remove the last one. Done.
6528 break;
6529 }
6530 }
6531 else
6532 {
6533 i++;
6534 }
6535 }//while(i<count)
6536 *pNumAdjustChannels = count;
6537
6538 return (fRet);
6539}
6540
6541
6542//Get the list of the base channels to scan for passively 11d info
6543eHalStatus csrScanGetSupportedChannels( tpAniSirGlobal pMac )
6544{
6545 eHalStatus status = eHAL_STATUS_SUCCESS;
6546 int n = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6547
6548 status = vos_nv_getSupportedChannels( pMac->scan.baseChannels.channelList, &n, NULL, NULL );
6549 if( HAL_STATUS_SUCCESS(status) )
6550 {
6551 pMac->scan.baseChannels.numChannels = (tANI_U8)n;
6552 }
6553 else
6554 {
6555 smsLog( pMac, LOGE, FL(" failed\n") );
6556 pMac->scan.baseChannels.numChannels = 0;
6557 }
6558
6559 return ( status );
6560}
6561
6562//This function use the input pChannelList to validate the current saved channel list
6563eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels)
6564{
6565 tANI_U32 dataLen = sizeof( tANI_U8 ) * NumAdjustChannels;
6566
6567 return (ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pAdjustChannels, dataLen, NULL, eANI_BOOLEAN_FALSE));
6568}
6569
6570
6571void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels )
6572{
6573 tANI_U32 dataLen = sizeof( tANI_U8 ) * NumChannels;
6574
6575
6576 ccmCfgSetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
6577
6578 return;
6579}
6580
6581
6582
6583/*
6584 * The Tx power limits are saved in the cfg for future usage.
6585 */
6586void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId )
6587{
6588 tListElem *pEntry;
6589 tANI_U32 cbLen = 0, dataLen;
6590 tCsrChannelPowerInfo *pChannelSet;
6591 tANI_U32 idx;
6592 tSirMacChanInfo *pChannelPowerSet;
6593 tANI_U8 *pBuf = NULL;
6594
6595 //allocate maximum space for all channels
6596 dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo);
6597 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pBuf, dataLen)))
6598 {
6599 palZeroMemory(pMac->hHdd, pBuf, dataLen);
6600 pChannelPowerSet = (tSirMacChanInfo *)(pBuf);
6601
6602 pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
6603 // write the tuples (startChan, numChan, txPower) for each channel found in the channel power list.
6604 while( pEntry )
6605 {
6606 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
6607 if ( 1 != pChannelSet->interChannelOffset )
6608 {
6609 // we keep the 5G channel sets internally with an interchannel offset of 4. Expand these
6610 // to the right format... (inter channel offset of 1 is the only option for the triplets
6611 // that 11d advertises.
6612 if ((cbLen + (pChannelSet->numChannels * sizeof(tSirMacChanInfo))) >= dataLen)
6613 {
6614 // expanding this entry will overflow our allocation
6615 smsLog(pMac, LOGE,
6616 "%s: Buffer overflow, start %d, num %d, offset %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006617 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 pChannelSet->firstChannel,
6619 pChannelSet->numChannels,
6620 pChannelSet->interChannelOffset);
6621 break;
6622 }
6623
6624 for( idx = 0; idx < pChannelSet->numChannels; idx++ )
6625 {
6626 pChannelPowerSet->firstChanNum = (tSirMacChanNum)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
6627 smsLog(pMac, LOG3, " Setting Channel Number %d\n", pChannelPowerSet->firstChanNum);
6628 pChannelPowerSet->numChannels = 1;
6629#ifdef WLAN_SOFTAP_FEATURE
6630 pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
6631#else
6632 pChannelPowerSet->maxTxPower = pChannelSet->txPower;
6633#endif
6634 smsLog(pMac, LOG3, " Setting Max Transmit Power %d\n", pChannelPowerSet->maxTxPower);
6635 cbLen += sizeof( tSirMacChanInfo );
6636 pChannelPowerSet++;
6637 }
6638 }
6639 else
6640 {
6641 if (cbLen >= dataLen)
6642 {
6643 // this entry will overflow our allocation
6644 smsLog(pMac, LOGE,
6645 "%s: Buffer overflow, start %d, num %d, offset %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006646 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 pChannelSet->firstChannel,
6648 pChannelSet->numChannels,
6649 pChannelSet->interChannelOffset);
6650 break;
6651 }
6652 pChannelPowerSet->firstChanNum = pChannelSet->firstChannel;
6653 smsLog(pMac, LOG3, " Setting Channel Number %d\n", pChannelPowerSet->firstChanNum);
6654 pChannelPowerSet->numChannels = pChannelSet->numChannels;
6655#ifdef WLAN_SOFTAP_FEATURE
6656 pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
6657#else
6658 pChannelPowerSet->maxTxPower = pChannelSet->txPower;
6659#endif
6660 smsLog(pMac, LOG3, " Setting Max Transmit Power %d, nTxPower %d\n", pChannelPowerSet->maxTxPower,pMac->roam.configParam.nTxPowerCap );
6661
6662
6663 cbLen += sizeof( tSirMacChanInfo );
6664 pChannelPowerSet++;
6665 }
6666
6667 pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
6668 }
6669
6670 if(cbLen)
6671 {
6672 ccmCfgSetStr(pMac, cfgId, (tANI_U8 *)pBuf, cbLen, NULL, eANI_BOOLEAN_FALSE);
6673 }
6674 palFreeMemory( pMac->hHdd, pBuf );
6675 }//Allocate memory
6676}
6677
6678
6679void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode )
6680{
6681 tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN];
6682 ///v_REGDOMAIN_t DomainId;
6683
6684 smsLog( pMac, LOG3, "Setting Country Code in Cfg from csrSetCfgCountryCode %s\n",countryCode );
6685 palCopyMemory( pMac->hHdd, cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN );
6686
6687 // don't program the bogus country codes that we created for Korea in the MAC. if we see
6688 // the bogus country codes, program the MAC with the right country code.
6689 if ( ( 'K' == countryCode[ 0 ] && '1' == countryCode[ 1 ] ) ||
6690 ( 'K' == countryCode[ 0 ] && '2' == countryCode[ 1 ] ) ||
6691 ( 'K' == countryCode[ 0 ] && '3' == countryCode[ 1 ] ) ||
6692 ( 'K' == countryCode[ 0 ] && '4' == countryCode[ 1 ] ) )
6693 {
6694 // replace the alternate Korea country codes, 'K1', 'K2', .. with 'KR' for Korea
6695 cc[ 1 ] = 'R';
6696 }
6697 ccmCfgSetStr(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN, NULL, eANI_BOOLEAN_FALSE);
6698
6699 //Need to let HALPHY know about the current domain so it can apply some
6700 //domain-specific settings (TX filter...)
6701 /*if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, cc, &DomainId)))
6702 {
6703 halPhySetRegDomain(pMac, DomainId);
6704 }*/
6705}
6706
6707
6708
6709eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen)
6710{
6711 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6712 tANI_U32 len;
6713
6714 if(pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN))
6715 {
6716 len = *pbLen;
6717 status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len);
6718 if(HAL_STATUS_SUCCESS(status))
6719 {
6720 *pbLen = (tANI_U8)len;
6721 }
6722 }
6723
6724 return (status);
6725}
6726
6727
6728void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList )
6729{
6730 tANI_U8 i, j;
6731 tANI_BOOLEAN found=FALSE;
6732 tANI_U8 *pControlList = NULL;
6733 tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
6734
6735 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN)))
6736 {
6737 palZeroMemory(pMac->hHdd, (void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN);
6738 if(HAL_STATUS_SUCCESS(ccmCfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, &len)))
6739 {
6740 for (i = 0; i < pChannelList->numChannels; i++)
6741 {
6742 for (j = 0; j < len; j += 2)
6743 {
6744 if (pControlList[j] == pChannelList->channelList[i])
6745 {
6746 found = TRUE;
6747 break;
6748 }
6749 }
6750
6751 if (found) // insert a pair(channel#, flag)
6752 {
6753 if (CSR_IS_CHANNEL_5GHZ(pControlList[j]))
6754 {
6755 pControlList[j+1] = csrGetScanType(pMac, pControlList[j]);
6756 }
6757 else
6758 {
6759 pControlList[j+1] = eSIR_ACTIVE_SCAN;
6760 }
6761
6762 found = FALSE; // reset the flag
6763 }
6764
6765 }
6766
6767 ccmCfgSetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, len, NULL, eANI_BOOLEAN_FALSE);
6768 }//Successfully getting scan control list
6769 palFreeMemory(pMac->hHdd, pControlList);
6770 }//AllocateMemory
6771}
6772
6773
6774//if bgPeriod is 0, background scan is disabled. It is in millisecond units
6775eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod)
6776{
6777 return (ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, bgPeriod, (tCcmCfgSetCallback) csrScanCcmCfgSetCallback, eANI_BOOLEAN_FALSE));
6778}
6779
6780
6781void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result)
6782{
6783 tListElem *pEntry = NULL;
6784 tSmeCmd *pCommand = NULL;
6785 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
6786
6787 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
6788 if ( pEntry )
6789 {
6790 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6791 if ( eSmeCommandScan == pCommand->command )
6792 {
6793 eCsrScanStatus scanStatus = (CCM_IS_RESULT_SUCCESS(result)) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
6794 csrReleaseScanCommand(pMac, pCommand, scanStatus);
6795 }
6796 else
6797 {
6798 smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ...\n" );
6799 }
6800 }
6801 smeProcessPendingQueue( pMac );
6802}
6803
6804eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
6805{
6806 eHalStatus status;
6807 tCsrBGScanRequest *pScanReq = &pCommand->u.scanCmd.u.bgScanRequest;
6808 tANI_U32 dataLen = sizeof( tANI_U8 ) * pScanReq->ChannelInfo.numOfChannels;
6809
6810 //***setcfg for background scan channel list
6811 status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, pScanReq->minChnTime, NULL, eANI_BOOLEAN_FALSE);
6812 status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, pScanReq->maxChnTime, NULL, eANI_BOOLEAN_FALSE);
6813 //Not set the background scan interval if not connected because bd scan should not be run if not connected
6814 if(!csrIsAllSessionDisconnected(pMac))
6815 {
6816 //If disbaling BG scan here, we need to stop aging as well
6817 if(pScanReq->scanInterval == 0)
6818 {
6819 //Stop aging because no new result is coming in
6820 csrScanStopResultAgingTimer(pMac);
6821 }
6822
6823#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
6824 {
6825 vos_log_scan_pkt_type *pScanLog = NULL;
6826
6827 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
6828 if(pScanLog)
6829 {
6830 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
6831 pScanLog->minChnTime = (v_U8_t)pScanReq->minChnTime;
6832 pScanLog->maxChnTime = (v_U8_t)pScanReq->maxChnTime;
6833 pScanLog->timeBetweenBgScan = (v_U8_t)pScanReq->scanInterval;
6834 pScanLog->numChannel = pScanReq->ChannelInfo.numOfChannels;
6835 if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
6836 {
6837 palCopyMemory(pMac->hHdd, pScanLog->channels, pScanReq->ChannelInfo.ChannelList,
6838 pScanLog->numChannel);
6839 }
6840 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
6841 }
6842 }
6843#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
6844
6845 status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, pScanReq->scanInterval, NULL, eANI_BOOLEAN_FALSE);
6846 }
6847 else
6848 {
6849 //No need to stop aging because IDLE scan is still running
6850 status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, 0, NULL, eANI_BOOLEAN_FALSE);
6851 }
6852
6853 if(pScanReq->SSID.length > WNI_CFG_SSID_LEN)
6854 {
6855 pScanReq->SSID.length = WNI_CFG_SSID_LEN;
6856 }
6857
6858 status = ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pScanReq->ChannelInfo.ChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
6859 status = ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pScanReq->SSID.ssId, pScanReq->SSID.length, NULL, eANI_BOOLEAN_FALSE);
6860
6861
6862
6863 return (status);
6864}
6865
6866
6867eHalStatus csrScanAbortMacScan(tpAniSirGlobal pMac)
6868{
6869 eHalStatus status = eHAL_STATUS_SUCCESS;
6870 tSirMbMsg *pMsg;
6871 tANI_U16 msgLen;
6872 tListElem *pEntry;
6873 tSmeCmd *pCommand;
6874
6875#ifdef WLAN_AP_STA_CONCURRENCY
6876 csrLLLock(&pMac->scan.scanCmdPendingList);
6877 while( NULL != ( pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) )
6878 {
6879
6880 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6881 csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
6882 }
6883 csrLLUnlock(&pMac->scan.scanCmdPendingList);
6884#endif
6885
6886 pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
6887 csrRemoveCmdFromPendingList( pMac, &pMac->roam.roamCmdPendingList, eSmeCommandScan);
6888 csrRemoveCmdFromPendingList( pMac, &pMac->sme.smeCmdPendingList, eSmeCommandScan);
6889 pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
6890
6891 //We need to abort scan only if we are scanning
6892 if(NULL != (pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK)))
6893 {
6894 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6895 if(eSmeCommandScan == pCommand->command)
6896 {
6897 msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
6898 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
6899 if(HAL_STATUS_SUCCESS(status))
6900 {
6901 palZeroMemory(pMac->hHdd, (void *)pMsg, msgLen);
6902 pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND);
6903 pMsg->msgLen = pal_cpu_to_be16(msgLen);
6904 status = palSendMBMessage(pMac->hHdd, pMsg);
6905 }
6906 }
6907 }
6908
6909 return( status );
6910}
6911
6912void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList,
6913 eSmeCommandType commandType )
6914{
6915 tDblLinkList localList;
6916 tListElem *pEntry;
6917 tSmeCmd *pCommand;
6918 tListElem *pEntryToRemove;
6919
6920 vos_mem_zero(&localList, sizeof(tDblLinkList));
6921 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
6922 {
6923 smsLog(pMac, LOGE, FL(" failed to open list"));
6924 return;
6925 }
6926
6927 csrLLLock(pList);
6928 if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) )
6929 {
6930 pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK);
6931
6932 // Have to make sure we don't loop back to the head of the list, which will
6933 // happen if the entry is NOT on the list...
6934 while( pEntry )
6935 {
6936 pEntryToRemove = pEntry;
6937 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
6938 pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
6939 if ( pCommand->command == commandType )
6940 {
6941 // Remove that entry only
6942 if(csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
6943 {
6944 csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK);
6945 }
6946 }
6947 }
6948
6949
6950 }
6951 csrLLUnlock(pList);
6952
6953 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
6954 {
6955 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6956 csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
6957 }
6958 csrLLClose(&localList);
6959
6960}
6961
6962
6963eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac)
6964{
6965 eHalStatus status = eHAL_STATUS_SUCCESS;
6966
6967 if( !csrIsScanForRoamCommandActive( pMac ) )
6968 {
6969 //Only abort the scan if it is not used for other roam/connect purpose
6970 status = csrScanAbortMacScan(pMac);
6971 }
6972
6973 return (status);
6974}
6975
6976
6977eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac)
6978{
6979 eHalStatus status = eHAL_STATUS_SUCCESS;
6980 tSirMbMsg *pMsg;
6981 tANI_U16 msgLen;
6982
6983 msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
6984 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
6985 if(HAL_STATUS_SUCCESS(status))
6986 {
6987 palZeroMemory(pMac->hHdd, pMsg, msgLen);
6988 pMsg->type = eWNI_SME_GET_SCANNED_CHANNEL_REQ;
6989 pMsg->msgLen = msgLen;
6990 status = palSendMBMessage(pMac->hHdd, pMsg);
6991 }
6992
6993 return( status );
6994}
6995
6996tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel )
6997{
6998 tANI_BOOLEAN fValid = FALSE;
6999 tANI_U32 idxValidChannels;
7000 tANI_U32 len = pMac->roam.numValidChannels;
7001
7002 for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ )
7003 {
7004 if ( channel == pMac->roam.validChannelList[ idxValidChannels ] )
7005 {
7006 fValid = TRUE;
7007 break;
7008 }
7009 }
7010
7011 return fValid;
7012}
7013
Madan Mohan Koyyalamudidd3c9662012-11-09 17:39:30 -08007014#ifdef FEATURE_WLAN_LFR
7015void csrInitOccupiedChannelsList(tpAniSirGlobal pMac)
7016{
7017 tListElem *pEntry = NULL;
7018 tCsrScanResult *pBssDesc = NULL;
7019 tDot11fBeaconIEs *pIes = NULL;
7020
7021 if (!csrNeighborRoamIsNewConnectedProfile(pMac))
7022 {
7023 smsLog(pMac, LOG2, FL("%s: donot flush occupied list since current roam profile"
7024 " matches previous (numChannels = %d)\n"),
7025 __func__, pMac->scan.occupiedChannels.numChannels);
7026 return;
7027 }
7028
7029 /* Empty occupied channels here */
7030 pMac->scan.occupiedChannels.numChannels = 0;
7031
7032 csrLLLock(&pMac->scan.scanResultList);
7033 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
7034 while( pEntry )
7035 {
7036 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
7037 pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes );
7038
7039 //At this time, pBssDescription->Result.pvIes may be NULL
7040 if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
7041 &pBssDesc->Result.BssDescriptor, &pIes))) )
7042 {
7043 continue;
7044 }
7045
7046 csrScanAddToOccupiedChannels(pMac, pBssDesc, &pMac->scan.occupiedChannels, pIes);
7047
7048 /*
7049 * Free the memory allocated for pIes in csrGetParsedBssDescriptionIEs
7050 */
7051 if( (pBssDesc->Result.pvIes == NULL) && pIes )
7052 {
7053 palFreeMemory(pMac->hHdd, pIes);
7054 }
7055
7056 pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK );
7057 }//while
7058 csrLLUnlock(&pMac->scan.scanResultList);
7059
7060}
7061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007062