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