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