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