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