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