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