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