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