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