blob: 33e3736e7b3ad283f6eacba290f653158cac811d [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
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07002044/*
2045 * NOTE: This routine is being added to make
2046 * sure that scan results are not being flushed
2047 * while roaming. If the scan results are flushed,
2048 * we are unable to recover from
2049 * csrRoamRoamingStateDisassocRspProcessor.
2050 * If it is needed to remove this routine,
2051 * first ensure that we recover gracefully from
2052 * csrRoamRoamingStateDisassocRspProcessor if
2053 * csrScanGetResult returns with a failure because
2054 * of not being able to find the roaming BSS.
2055 */
2056tANI_U8 csrScanFlushDenied(tpAniSirGlobal pMac)
2057{
2058 switch(pMac->roam.neighborRoamInfo.neighborRoamState) {
2059 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
2060 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
2061 case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
2062 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2063 return (pMac->roam.neighborRoamInfo.neighborRoamState);
2064 default:
2065 return 0;
2066 }
2067}
2068
Jeff Johnson295189b2012-06-20 16:38:30 -07002069eHalStatus csrScanFlushResult(tpAniSirGlobal pMac)
2070{
Madan Mohan Koyyalamudiab41d0f2012-10-31 17:17:10 -07002071 tANI_U8 isFlushDenied = csrScanFlushDenied(pMac);
2072 if (isFlushDenied) {
2073 smsLog(pMac, LOGW, "%s: scan flush denied in roam state %d",
2074 __func__, isFlushDenied);
2075 return eHAL_STATUS_FAILURE;
2076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 return ( csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList) );
2078}
2079
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07002080eHalStatus csrScanFlushP2PResult(tpAniSirGlobal pMac)
2081{
2082 eHalStatus status = eHAL_STATUS_SUCCESS;
2083 tListElem *pEntry,*pFreeElem;
2084 tCsrScanResult *pBssDesc;
2085 tDblLinkList *pList = &pMac->scan.scanResultList;
2086
2087 csrLLLock(pList);
2088
2089 pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK );
2090 while( pEntry != NULL)
2091 {
2092 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2093 if( vos_mem_compare( pBssDesc->Result.ssId.ssId, "DIRECT-", 7) )
2094 {
2095 pFreeElem = pEntry;
2096 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
2097 csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK);
2098 csrFreeScanResultEntry( pMac, pBssDesc );
2099 continue;
2100 }
2101 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
2102 }
2103
2104 csrLLUnlock(pList);
2105
2106 return (status);
2107}
2108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109/**
2110 * csrCheck11dChannel
2111 *
2112 *FUNCTION:
2113 * This function is called from csrScanFilter11dResult function and
2114 * compare channel number with given channel list.
2115 *
2116 *LOGIC:
2117 * Check Scan result channel number with CFG channel list
2118 *
2119 *ASSUMPTIONS:
2120 *
2121 *
2122 *NOTE:
2123 *
2124 * @param channelId channel number
2125 * @param pChannelList Pointer to channel list
2126 * @param numChannels Number of channel in channel list
2127 *
2128 * @return Status
2129 */
2130
2131eHalStatus csrCheck11dChannel(tANI_U8 channelId, tANI_U8 *pChannelList, tANI_U32 numChannels)
2132{
2133 eHalStatus status = eHAL_STATUS_FAILURE;
2134 tANI_U8 i = 0;
2135
2136 for (i = 0; i < numChannels; i++)
2137 {
2138 if(pChannelList[ i ] == channelId)
2139 {
2140 status = eHAL_STATUS_SUCCESS;
2141 break;
2142 }
2143 }
2144 return status;
2145}
2146
2147/**
2148 * csrScanFilter11dResult
2149 *
2150 *FUNCTION:
2151 * This function is called from csrApplyCountryInformation function and
2152 * filter scan result based on valid channel list number.
2153 *
2154 *LOGIC:
2155 * Get scan result from scan list and Check Scan result channel number
2156 * with 11d channel list if channel number is found in 11d channel list
2157 * then do not remove scan result entry from scan list
2158 *
2159 *ASSUMPTIONS:
2160 *
2161 *
2162 *NOTE:
2163 *
2164 * @param pMac Pointer to Global MAC structure
2165 *
2166 * @return Status
2167 */
2168
2169eHalStatus csrScanFilter11dResult(tpAniSirGlobal pMac)
2170{
2171 eHalStatus status = eHAL_STATUS_SUCCESS;
2172 tListElem *pEntry,*pTempEntry;
2173 tCsrScanResult *pBssDesc;
2174 tANI_U32 len = sizeof(pMac->roam.validChannelList);
2175
2176 /* Get valid channels list from CFG */
2177 if (!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac,
2178 pMac->roam.validChannelList, &len)))
2179 {
2180 smsLog( pMac, LOG1, "Failed to get Channel list from CFG");
2181 }
2182
2183 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
2184 while( pEntry )
2185 {
2186 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2187 pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry,
2188 LL_ACCESS_LOCK );
2189 if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId,
2190 pMac->roam.validChannelList, len))
2191 {
2192 /* Remove Scan result which does not have 11d channel */
2193 if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry,
2194 LL_ACCESS_LOCK ))
2195 {
2196 csrFreeScanResultEntry( pMac, pBssDesc );
2197 }
2198 }
2199 pEntry = pTempEntry;
2200 }
2201 return status;
2202}
2203
2204
2205eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult)
2206{
2207 eHalStatus status = eHAL_STATUS_SUCCESS;
2208 tScanResultList *pRetList, *pInList = (tScanResultList *)hIn;
2209 tCsrScanResult *pResult, *pScanResult;
2210 tANI_U32 count = 0;
2211 tListElem *pEntry;
2212 tANI_U32 bssLen, allocLen;
2213
2214 if(phResult)
2215 {
2216 *phResult = CSR_INVALID_SCANRESULT_HANDLE;
2217 }
2218 status = palAllocateMemory(pMac->hHdd, (void **)&pRetList, sizeof(tScanResultList));
2219 if(HAL_STATUS_SUCCESS(status))
2220 {
2221 palZeroMemory(pMac->hHdd, pRetList, sizeof(tScanResultList));
2222 csrLLOpen(pMac->hHdd, &pRetList->List);
2223 pRetList->pCurEntry = NULL;
2224 csrLLLock(&pMac->scan.scanResultList);
2225 csrLLLock(&pInList->List);
2226
2227 pEntry = csrLLPeekHead( &pInList->List, LL_ACCESS_NOLOCK );
2228 while( pEntry )
2229 {
2230 pScanResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2231 bssLen = pScanResult->Result.BssDescriptor.length + sizeof(pScanResult->Result.BssDescriptor.length);
2232 allocLen = sizeof( tCsrScanResult ) + bssLen;
2233 status = palAllocateMemory(pMac->hHdd, (void **)&pResult, allocLen);
2234 if(!HAL_STATUS_SUCCESS(status))
2235 {
2236 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2237 count = 0;
2238 break;
2239 }
2240 palZeroMemory(pMac->hHdd, pResult, allocLen);
2241 status = palCopyMemory(pMac->hHdd, &pResult->Result.BssDescriptor, &pScanResult->Result.BssDescriptor, bssLen);
2242 if(!HAL_STATUS_SUCCESS(status))
2243 {
2244 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2245 count = 0;
2246 break;
2247 }
2248 if( pScanResult->Result.pvIes )
2249 {
2250 status = palAllocateMemory(pMac->hHdd, (void **)&pResult->Result.pvIes, sizeof( tDot11fBeaconIEs ));
2251 if(!HAL_STATUS_SUCCESS(status))
2252 {
2253 //Free the memory we allocate above first
2254 palFreeMemory( pMac->hHdd, pResult );
2255 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2256 count = 0;
2257 break;
2258 }
2259 status = palCopyMemory(pMac->hHdd, pResult->Result.pvIes,
2260 pScanResult->Result.pvIes, sizeof( tDot11fBeaconIEs ));
2261 if(!HAL_STATUS_SUCCESS(status))
2262 {
2263 //Free the memory we allocate above first
2264 palFreeMemory( pMac->hHdd, pResult );
2265 csrScanResultPurge(pMac, (tScanResultHandle *)pRetList);
2266 count = 0;
2267 break;
2268 }
2269 }
2270 csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_LOCK);
2271 count++;
2272 pEntry = csrLLNext( &pInList->List, pEntry, LL_ACCESS_NOLOCK );
2273 }//while
2274 csrLLUnlock(&pInList->List);
2275 csrLLUnlock(&pMac->scan.scanResultList);
2276
2277 if(HAL_STATUS_SUCCESS(status))
2278 {
2279 if(0 == count)
2280 {
2281 csrLLClose(&pRetList->List);
2282 palFreeMemory(pMac->hHdd, pRetList);
2283 status = eHAL_STATUS_E_NULL_VALUE;
2284 }
2285 else if(phResult)
2286 {
2287 *phResult = pRetList;
2288 }
2289 }
2290 }//Allocated pRetList
2291
2292 return (status);
2293}
2294
2295
2296
2297eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf )
2298{
2299 eHalStatus status = eHAL_STATUS_SUCCESS;
2300 tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf;
2301
2302 if((eWNI_SME_SCAN_RSP == pMsg->type) || (eWNI_SME_GET_SCANNED_CHANNEL_RSP == pMsg->type))
2303 {
2304 status = csrScanSmeScanResponse( pMac, pMsgBuf );
2305 }
2306 else
2307 {
2308 if( csrIsAnySessionInConnectState( pMac ) )
2309 {
2310 //In case of we are connected, we need to check whether connect status changes
2311 //because scan may also run while connected.
2312 csrRoamCheckForLinkStatusChange( pMac, ( tSirSmeRsp * )pMsgBuf );
2313 }
2314 else
2315 {
2316 smsLog( pMac, LOGW, "Message [0x%04x] received in state, when expecting Scan Response\n", pMsg->type );
2317 }
2318 }
2319
2320 return (status);
2321}
2322
2323
2324
2325void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr, tSirBssDescription *pOldBssDescr)
2326{
2327 int idx, len;
2328 tANI_U8 *pbIe;
2329
2330 //If failed to remove, assuming someone else got it.
2331 if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) &&
2332 (0 == pNewBssDescr->WscIeLen))
2333 {
2334 idx = 0;
2335 len = pOldBssDescr->length - sizeof(tSirBssDescription) +
2336 sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
2337 pbIe = (tANI_U8 *)pOldBssDescr->ieFields;
2338 //Save WPS IE if it exists
2339 pNewBssDescr->WscIeLen = 0;
2340 while(idx < len)
2341 {
2342 if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
2343 (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
2344 {
2345 //Founrd it
2346 if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
2347 {
2348 palCopyMemory(pMac->hHdd, pNewBssDescr->WscIeProbeRsp,
2349 pbIe, pbIe[1] + 2);
2350 pNewBssDescr->WscIeLen = pbIe[1] + 2;
2351 }
2352 break;
2353 }
2354 idx += pbIe[1] + 2;
2355 pbIe += pbIe[1] + 2;
2356 }
2357 }
2358}
2359
2360
2361
2362//pIes may be NULL
2363tANI_BOOLEAN csrRemoveDupBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDescr,
2364 tDot11fBeaconIEs *pIes, tAniSSID *pSsid , v_TIME_t *timer )
2365{
2366 tListElem *pEntry;
2367
2368 tCsrScanResult *pBssDesc;
2369 tANI_BOOLEAN fRC = FALSE;
2370
2371 // Walk through all the chained BssDescriptions. If we find a chained BssDescription that
2372 // matches the BssID of the BssDescription passed in, then these must be duplicate scan
2373 // results for this Bss. In that case, remove the 'old' Bss description from the linked list.
2374 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK );
2375
2376 while( pEntry )
2377 {
2378 pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2379
2380 // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
2381 // matches
2382 if ( csrIsDuplicateBssDescription( pMac, &pBssDesc->Result.BssDescriptor,
2383 pSirBssDescr, pIes ) )
2384 {
2385 pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
2386 ((tANI_S32)pBssDesc->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );
2387 // Remove the 'old' entry from the list....
2388 if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ) )
2389 {
2390 // !we need to free the memory associated with this node
2391 //If failed to remove, assuming someone else got it.
2392 *pSsid = pBssDesc->Result.ssId;
2393 *timer = pBssDesc->Result.timer;
2394 csrCheckNSaveWscIe(pMac, pSirBssDescr, &pBssDesc->Result.BssDescriptor);
2395
2396 csrFreeScanResultEntry( pMac, pBssDesc );
2397 }
2398 else
2399 {
2400 smsLog( pMac, LOGW, FL( " fail to remove entry\n" ) );
2401 }
2402 fRC = TRUE;
2403
2404 // If we found a match, we can stop looking through the list.
2405 break;
2406 }
2407
2408 pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK );
2409 }
2410
2411 return fRC;
2412}
2413
2414
2415eHalStatus csrAddPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
2416 tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
2417{
2418 eHalStatus status = eHAL_STATUS_FAILURE;
2419 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2420
Jeff Johnson32d95a32012-09-10 13:15:23 -07002421 if(!pSession)
2422 {
2423 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
2424 return eHAL_STATUS_FAILURE;
2425 }
2426
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 smsLog(pMac, LOGW, "csrAddPMKIDCandidateList called pMac->scan.NumPmkidCandidate = %d\n", pSession->NumPmkidCandidate);
2428 if( pIes )
2429 {
2430 // check if this is a RSN BSS
2431 if( pIes->RSN.present )
2432 {
2433 // Check if the BSS is capable of doing pre-authentication
2434 if( pSession->NumPmkidCandidate < CSR_MAX_PMKID_ALLOWED )
2435 {
2436
2437#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2438 {
2439 WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type);
2440 palZeroMemory(pMac->hHdd, &secEvent, sizeof(vos_event_wlan_security_payload_type));
2441 secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND;
2442 secEvent.encryptionModeMulticast =
2443 (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType);
2444 secEvent.encryptionModeUnicast =
2445 (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType);
2446 palCopyMemory( pMac->hHdd, secEvent.bssid, pSession->connectedProfile.bssid, 6 );
2447 secEvent.authMode =
2448 (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType);
2449 WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY);
2450 }
2451#endif//#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
2452
2453 // if yes, then add to PMKIDCandidateList
2454 status = palCopyMemory(pMac->hHdd, pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].BSSID,
2455 pBssDesc->bssId, WNI_CFG_BSSID_LEN);
2456
2457 if( HAL_STATUS_SUCCESS( status ) )
2458 {
2459 if ( pIes->RSN.preauth )
2460 {
2461 pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported = eANI_BOOLEAN_TRUE;
2462 }
2463 else
2464 {
2465 pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported = eANI_BOOLEAN_FALSE;
2466 }
2467 pSession->NumPmkidCandidate++;
2468 }
2469 }
2470 else
2471 {
2472 status = eHAL_STATUS_FAILURE;
2473 }
2474 }
2475 }
2476
2477 return (status);
2478}
2479
2480//This function checks whether new AP is found for the current connected profile
2481//If it is found, it return the sessionId, else it return invalid sessionID
2482tANI_U32 csrProcessBSSDescForPMKIDList(tpAniSirGlobal pMac,
2483 tSirBssDescription *pBssDesc,
2484 tDot11fBeaconIEs *pIes)
2485{
2486 tANI_U32 i, bRet = CSR_SESSION_ID_INVALID;
2487 tCsrRoamSession *pSession;
2488 tDot11fBeaconIEs *pIesLocal = pIes;
2489
2490 if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
2491 {
2492 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
2493 {
2494 if( CSR_IS_SESSION_VALID( pMac, i ) )
2495 {
2496 pSession = CSR_GET_SESSION( pMac, i );
2497 if( csrIsConnStateConnectedInfra( pMac, i ) &&
2498 ( eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType ) )
2499 {
2500 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pBssDesc, pIesLocal))
2501 {
2502 //this new BSS fits the current profile connected
2503 if(HAL_STATUS_SUCCESS(csrAddPMKIDCandidateList(pMac, i, pBssDesc, pIesLocal)))
2504 {
2505 bRet = i;
2506 }
2507 break;
2508 }
2509 }
2510 }
2511 }
2512 if( !pIes )
2513 {
2514 palFreeMemory(pMac->hHdd, pIesLocal);
2515 }
2516 }
2517
2518 return (tANI_U8)bRet;
2519}
2520
2521#ifdef FEATURE_WLAN_WAPI
2522eHalStatus csrAddBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId,
2523 tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
2524{
2525 eHalStatus status = eHAL_STATUS_FAILURE;
2526 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2527
Jeff Johnson32d95a32012-09-10 13:15:23 -07002528 if(!pSession)
2529 {
2530 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
2531 return eHAL_STATUS_FAILURE;
2532 }
2533
Jeff Johnson295189b2012-06-20 16:38:30 -07002534 smsLog(pMac, LOGW, "csrAddBKIDCandidateList called pMac->scan.NumBkidCandidate = %d\n", pSession->NumBkidCandidate);
2535 if( pIes )
2536 {
2537 // check if this is a WAPI BSS
2538 if( pIes->WAPI.present )
2539 {
2540 // Check if the BSS is capable of doing pre-authentication
2541 if( pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED )
2542 {
2543
2544 // if yes, then add to BKIDCandidateList
2545 status = palCopyMemory(pMac->hHdd, pSession->BkidCandidateInfo[pSession->NumBkidCandidate].BSSID,
2546 pBssDesc->bssId, WNI_CFG_BSSID_LEN);
2547
2548 if( HAL_STATUS_SUCCESS( status ) )
2549 {
2550 if ( pIes->WAPI.preauth )
2551 {
2552 pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported = eANI_BOOLEAN_TRUE;
2553 }
2554 else
2555 {
2556 pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported = eANI_BOOLEAN_FALSE;
2557 }
2558 pSession->NumBkidCandidate++;
2559 }
2560 }
2561 else
2562 {
2563 status = eHAL_STATUS_FAILURE;
2564 }
2565 }
2566 }
2567
2568 return (status);
2569}
2570
2571//This function checks whether new AP is found for the current connected profile
2572//if so add to BKIDCandidateList
2573tANI_BOOLEAN csrProcessBSSDescForBKIDList(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc,
2574 tDot11fBeaconIEs *pIes)
2575{
2576 tANI_BOOLEAN fRC = FALSE;
2577 tDot11fBeaconIEs *pIesLocal = pIes;
2578 tANI_U32 sessionId;
2579 tCsrRoamSession *pSession;
2580
2581 if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) )
2582 {
2583 for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
2584 {
2585 if( CSR_IS_SESSION_VALID( pMac, sessionId) )
2586 {
2587 pSession = CSR_GET_SESSION( pMac, sessionId );
2588 if( csrIsConnStateConnectedInfra( pMac, sessionId ) &&
2589 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == pSession->connectedProfile.AuthType)
2590 {
2591 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile,pBssDesc, pIesLocal))
2592 {
2593 //this new BSS fits the current profile connected
2594 if(HAL_STATUS_SUCCESS(csrAddBKIDCandidateList(pMac, sessionId, pBssDesc, pIesLocal)))
2595 {
2596 fRC = TRUE;
2597 }
2598 }
2599 }
2600 }
2601 }
2602 if(!pIes)
2603 {
2604 palFreeMemory(pMac->hHdd, pIesLocal);
2605 }
2606
2607 }
2608 return fRC;
2609}
2610
2611#endif
2612
2613
2614static void csrMoveTempScanResultsToMainList( tpAniSirGlobal pMac )
2615{
2616 tListElem *pEntry;
2617 tCsrScanResult *pBssDescription;
2618 tANI_S8 cand_Bss_rssi;
2619 tANI_BOOLEAN fDupBss;
2620#ifdef FEATURE_WLAN_WAPI
2621 tANI_BOOLEAN fNewWapiBSSForCurConnection = eANI_BOOLEAN_FALSE;
2622#endif /* FEATURE_WLAN_WAPI */
2623 tDot11fBeaconIEs *pIesLocal = NULL;
2624 tANI_U32 sessionId = CSR_SESSION_ID_INVALID;
2625 tAniSSID tmpSsid;
2626 v_TIME_t timer=0;
2627
2628 tmpSsid.length = 0;
2629 cand_Bss_rssi = -128; // RSSI coming from PE is -ve
2630
2631 // remove the BSS descriptions from temporary list
2632 while( ( pEntry = csrLLRemoveTail( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ) ) != NULL)
2633 {
2634 pBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
2635
Mohit Khanna23863762012-09-11 17:40:09 -07002636 smsLog( pMac, LOG2, "...Bssid= %02x-%02x-%02x-%02x-%02x-%02x chan= %d, rssi = -%d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 pBssDescription->Result.BssDescriptor.bssId[ 0 ], pBssDescription->Result.BssDescriptor.bssId[ 1 ],
2638 pBssDescription->Result.BssDescriptor.bssId[ 2 ], pBssDescription->Result.BssDescriptor.bssId[ 3 ],
2639 pBssDescription->Result.BssDescriptor.bssId[ 4 ], pBssDescription->Result.BssDescriptor.bssId[ 5 ],
2640 pBssDescription->Result.BssDescriptor.channelId,
2641 pBssDescription->Result.BssDescriptor.rssi * (-1) );
2642
2643 //At this time, pBssDescription->Result.pvIes may be NULL
2644 pIesLocal = (tDot11fBeaconIEs *)( pBssDescription->Result.pvIes );
2645 if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssDescription->Result.BssDescriptor, &pIesLocal))) )
2646 {
2647 smsLog(pMac, LOGE, FL(" Cannot pared IEs\n"));
2648 csrFreeScanResultEntry(pMac, pBssDescription);
2649 continue;
2650 }
2651 fDupBss = csrRemoveDupBssDescription( pMac, &pBssDescription->Result.BssDescriptor, pIesLocal, &tmpSsid , &timer );
2652 //Check whether we have reach out limit
2653 if( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) )
2654 {
2655 //Limit reach
2656 smsLog(pMac, LOGW, FL(" BSS limit reached\n"));
2657 //Free the resources
2658 if( (pBssDescription->Result.pvIes == NULL) && pIesLocal )
2659 {
2660 palFreeMemory(pMac->hHdd, pIesLocal);
2661 }
2662 csrFreeScanResultEntry(pMac, pBssDescription);
2663 //Continue because there may be duplicated BSS
2664 continue;
2665 }
2666 // check for duplicate scan results
2667 if ( !fDupBss )
2668 {
2669 //Found a new BSS
2670 sessionId = csrProcessBSSDescForPMKIDList(pMac,
2671 &pBssDescription->Result.BssDescriptor, pIesLocal);
2672 if( CSR_SESSION_ID_INVALID != sessionId)
2673 {
2674 csrRoamCallCallback(pMac, sessionId, NULL, 0,
2675 eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NONE);
2676 }
2677 }
2678 else
2679 {
2680 //Check if the new one has SSID it it, if not, use the older SSID if it exists.
2681 if( (0 == pBssDescription->Result.ssId.length) && tmpSsid.length )
2682 {
2683 //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only
2684 //if diff of saved SSID time and current time is less than 1 min to avoid
2685 //side effect of saving SSID with old one is that if AP changes its SSID while remain
2686 //hidden, we may never see it and also to address the requirement of
2687 //When we remove hidden ssid from the profile i.e., forget the SSID via
2688 // GUI that SSID shouldn't see in the profile
2689 if( (vos_timer_get_system_time() - timer) <= HIDDEN_TIMER)
2690 {
2691 pBssDescription->Result.timer = timer;
2692 pBssDescription->Result.ssId = tmpSsid;
2693 }
2694 }
2695 }
2696
2697 //Tush: find a good AP for 11d info
2698 if( csrIs11dSupported( pMac ) )
2699 {
2700 if(cand_Bss_rssi < pBssDescription->Result.BssDescriptor.rssi)
2701 {
2702 // check if country information element is present
2703 if(pIesLocal->Country.present)
2704 {
2705 cand_Bss_rssi = pBssDescription->Result.BssDescriptor.rssi;
2706 // learn country information
2707 csrLearnCountryInformation( pMac, &pBssDescription->Result.BssDescriptor,
2708 pIesLocal, eANI_BOOLEAN_FALSE );
2709 }
2710
2711 }
2712 }
2713
Jeff Johnsone7245742012-09-05 17:12:55 -07002714 else if( csrIs11hSupported( pMac ) && pIesLocal->Country.present &&
2715 !pMac->roam.configParam.fSupplicantCountryCodeHasPriority )
2716 {
2717 /* If 11h is supported, store the power information received in the Country IE */
2718 csrSaveToChannelPower2G_5G( pMac, pIesLocal->Country.num_triplets * sizeof(tSirMacChanInfo),
2719 (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]) );
2720 }
2721
Jeff Johnson295189b2012-06-20 16:38:30 -07002722 // append to main list
2723 csrScanAddResult(pMac, pBssDescription, pIesLocal);
2724 if( (pBssDescription->Result.pvIes == NULL) && pIesLocal )
2725 {
2726 palFreeMemory(pMac->hHdd, pIesLocal);
2727 }
2728 }
2729
2730 //Tush: If we can find the current 11d info in any of the scan results, or
2731 // a good enough AP with the 11d info from the scan results then no need to
2732 // get into ambiguous state
2733 if(pMac->scan.fAmbiguous11dInfoFound)
2734 {
2735 if((pMac->scan.fCurrent11dInfoMatch) || (cand_Bss_rssi != -128))
2736 {
2737 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
2738 }
2739 }
2740
2741#ifdef FEATURE_WLAN_WAPI
2742 if(fNewWapiBSSForCurConnection)
2743 {
2744 //remember it first
2745 csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NEW_WAPI_BSS);
2746 }
2747#endif /* FEATURE_WLAN_WAPI */
2748
2749 return;
2750}
2751
2752
2753static tCsrScanResult *csrScanSaveBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription,
2754 tDot11fBeaconIEs *pIes)
2755{
2756 tCsrScanResult *pCsrBssDescription = NULL;
2757 tANI_U32 cbBSSDesc;
2758 tANI_U32 cbAllocated;
2759 eHalStatus halStatus;
2760
2761 // figure out how big the BSS description is (the BSSDesc->length does NOT
2762 // include the size of the length field itself).
2763 cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );
2764
2765 cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;
2766
2767 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pCsrBssDescription, cbAllocated );
2768 if ( HAL_STATUS_SUCCESS(halStatus) )
2769 {
2770 palZeroMemory( pMac->hHdd, pCsrBssDescription, cbAllocated );
2771 pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
2772 palCopyMemory(pMac->hHdd, &pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc );
2773#if defined(VOSS_ENSBALED)
2774 VOS_ASSERT( pCsrBssDescription->Result.pvIes == NULL );
2775#endif
2776 csrScanAddResult(pMac, pCsrBssDescription, pIes);
2777 }
2778
2779 return( pCsrBssDescription );
2780}
2781
2782// Append a Bss Description...
2783tCsrScanResult *csrScanAppendBssDescription( tpAniSirGlobal pMac,
2784 tSirBssDescription *pSirBssDescription,
2785 tDot11fBeaconIEs *pIes )
2786{
2787 tCsrScanResult *pCsrBssDescription = NULL;
2788 tAniSSID tmpSsid;
2789 v_TIME_t timer = 0;
2790 int result;
2791
2792 tmpSsid.length = 0;
2793 result = csrRemoveDupBssDescription( pMac, pSirBssDescription, pIes, &tmpSsid, &timer );
2794 pCsrBssDescription = csrScanSaveBssDescription( pMac, pSirBssDescription, pIes );
2795 if (result && (pCsrBssDescription != NULL))
2796 {
2797 //Check if the new one has SSID it it, if not, use the older SSID if it exists.
2798 if( (0 == pCsrBssDescription->Result.ssId.length) && tmpSsid.length )
2799 {
2800 //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only
2801 //if diff of saved SSID time and current time is less than 1 min to avoid
2802 //side effect of saving SSID with old one is that if AP changes its SSID while remain
2803 //hidden, we may never see it and also to address the requirement of
2804 //When we remove hidden ssid from the profile i.e., forget the SSID via
2805 // GUI that SSID shouldn't see in the profile
2806 if((vos_timer_get_system_time()-timer) <= HIDDEN_TIMER)
2807 {
2808 pCsrBssDescription->Result.ssId = tmpSsid;
2809 pCsrBssDescription->Result.timer = timer;
2810 }
2811 }
2812 }
2813
2814
2815 return( pCsrBssDescription );
2816}
2817
2818
2819
2820void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList )
2821{
2822 tCsrChannelPowerInfo *pChannelSet;
2823 tListElem *pEntry;
2824
2825 csrLLLock(pChannelList);
2826 // Remove the channel sets from the learned list and put them in the free list
2827 while( ( pEntry = csrLLRemoveHead( pChannelList, LL_ACCESS_NOLOCK ) ) != NULL)
2828 {
2829 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
2830 if( pChannelSet )
2831 {
2832 palFreeMemory( pMac->hHdd, pChannelSet );
2833 }
2834 }
2835 csrLLUnlock(pChannelList);
2836 return;
2837}
2838
2839
2840/*
2841 * Save the channelList into the ultimate storage as the final stage of channel
2842 * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power limit are all stored inside this data structure
2843 */
Jeff Johnsone7245742012-09-05 17:12:55 -07002844eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable )
Jeff Johnson295189b2012-06-20 16:38:30 -07002845{
2846 tANI_U32 i = tableSize / sizeof( tSirMacChanInfo );
2847 tSirMacChanInfo *pChannelInfo;
2848 tCsrChannelPowerInfo *pChannelSet;
2849 tANI_BOOLEAN f2GHzInfoFound = FALSE;
2850 tANI_BOOLEAN f2GListPurged = FALSE, f5GListPurged = FALSE;
2851 eHalStatus halStatus;
2852
2853 pChannelInfo = channelTable;
2854 // atleast 3 bytes have to be remaining -- from "countryString"
2855 while ( i-- )
2856 {
2857 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pChannelSet, sizeof(tCsrChannelPowerInfo) );
2858 if ( eHAL_STATUS_SUCCESS == halStatus )
2859 {
2860 palZeroMemory(pMac->hHdd, pChannelSet, sizeof(tCsrChannelPowerInfo));
2861 pChannelSet->firstChannel = pChannelInfo->firstChanNum;
2862 pChannelSet->numChannels = pChannelInfo->numChannels;
2863
2864 // Now set the inter-channel offset based on the frequency band the channel set lies in
Jeff Johnsone7245742012-09-05 17:12:55 -07002865 if( (CSR_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) &&
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002866 ((pChannelSet->firstChannel + (pChannelSet->numChannels - 1)) <= CSR_MAX_24GHz_CHANNEL_NUMBER) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002867
Jeff Johnson295189b2012-06-20 16:38:30 -07002868 {
2869 pChannelSet->interChannelOffset = 1;
2870 f2GHzInfoFound = TRUE;
2871 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002872 else if ( (CSR_IS_CHANNEL_5GHZ(pChannelSet->firstChannel)) &&
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002873 ((pChannelSet->firstChannel + ((pChannelSet->numChannels - 1) * 4)) <= CSR_MAX_5GHz_CHANNEL_NUMBER) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002874 {
2875 pChannelSet->interChannelOffset = 4;
2876 f2GHzInfoFound = FALSE;
2877 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002878 else
2879 {
Madan Mohan Koyyalamudi5904d7c2012-09-24 13:49:03 -07002880 smsLog( pMac, LOGW, FL("Invalid Channel %d Present in Country IE"),
Jeff Johnsone7245742012-09-05 17:12:55 -07002881 pChannelSet->firstChannel);
2882 palFreeMemory(pMac->hHdd, pChannelSet);
2883 return eHAL_STATUS_FAILURE;
2884 }
2885
Jeff Johnson295189b2012-06-20 16:38:30 -07002886 pChannelSet->txPower = CSR_ROAM_MIN( pChannelInfo->maxTxPower, pMac->roam.configParam.nTxPowerCap );
2887
2888 if( f2GHzInfoFound )
2889 {
2890 if( !f2GListPurged )
2891 {
2892 // purge previous results if found new
2893 csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList24 );
2894 f2GListPurged = TRUE;
2895 }
2896
2897 if(CSR_IS_OPERATING_BG_BAND(pMac))
2898 {
2899 // add to the list of 2.4 GHz channel sets
2900 csrLLInsertTail( &pMac->scan.channelPowerInfoList24, &pChannelSet->link, LL_ACCESS_LOCK );
2901 }
2902 else {
2903 smsLog( pMac, LOGW, FL("Adding 11B/G channels in 11A mode -- First Channel is %d"),
2904 pChannelSet->firstChannel);
2905 palFreeMemory(pMac->hHdd, pChannelSet);
2906 }
2907 }
2908 else
2909 {
2910 // 5GHz info found
2911 if( !f5GListPurged )
2912 {
2913 // purge previous results if found new
2914 csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList5G );
2915 f5GListPurged = TRUE;
2916 }
2917
2918 if(CSR_IS_OPERATING_A_BAND(pMac))
2919 {
2920 // add to the list of 5GHz channel sets
2921 csrLLInsertTail( &pMac->scan.channelPowerInfoList5G, &pChannelSet->link, LL_ACCESS_LOCK );
2922 }
2923 else {
2924 smsLog( pMac, LOGW, FL("Adding 11A channels in B/G mode -- First Channel is %d"),
2925 pChannelSet->firstChannel);
2926 palFreeMemory(pMac->hHdd, pChannelSet);
2927 }
2928 }
2929 }
2930
2931 pChannelInfo++; // move to next entry
2932 }
2933
Jeff Johnsone7245742012-09-05 17:12:55 -07002934 return eHAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002935}
2936
2937
2938
2939void csrApplyPower2Current( tpAniSirGlobal pMac )
2940{
2941 smsLog( pMac, LOG3, FL(" Updating Cfg with power settings\n"));
2942 csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList24, WNI_CFG_MAX_TX_POWER_2_4 );
2943 csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList5G, WNI_CFG_MAX_TX_POWER_5 );
2944}
2945
2946
2947void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode)
2948{
2949 int i;
2950 eNVChannelEnabledType channelEnabledType;
2951 tANI_U8 numChannels = 0;
2952 tANI_U8 tempNumChannels = 0;
2953 tCsrChannel ChannelList;
2954 if( pChannelList->numChannels )
2955 {
2956 tempNumChannels = CSR_MIN(pChannelList->numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2957 /* If user doesn't want to scan the DFS channels lets trim them from
2958 the valid channel list*/
2959 if(FALSE == pMac->scan.fEnableDFSChnlScan)
2960 {
2961 for(i = 0; i< tempNumChannels; i++)
2962 {
2963 channelEnabledType =
2964 vos_nv_getChannelEnabledState(pChannelList->channelList[i]);
2965 if( NV_CHANNEL_ENABLE == channelEnabledType)
2966 {
2967 ChannelList.channelList[numChannels] =
2968 pChannelList->channelList[i];
2969 numChannels++;
2970 }
2971 }
2972 ChannelList.numChannels = numChannels;
2973 }
2974 else
2975 {
2976 ChannelList.numChannels = tempNumChannels;
2977 vos_mem_copy(ChannelList.channelList,
2978 pChannelList->channelList,
2979 ChannelList.numChannels);
2980 }
2981
2982 csrSetCfgValidChannelList(pMac, ChannelList.channelList, ChannelList.numChannels);
2983 // extend scan capability
2984 csrSetCfgScanControlList(pMac, countryCode, &ChannelList); // build a scan list based on the channel list : channel# + active/passive scan
2985#ifdef FEATURE_WLAN_SCAN_PNO
Madan Mohan Koyyalamudi255b0972012-10-31 15:51:24 -07002986 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 -07002987 // Send HAL UpdateScanParams message
Madan Mohan Koyyalamudi255b0972012-10-31 15:51:24 -07002988 pmcUpdateScanParams(pMac, &(pMac->roam.configParam), &ChannelList, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002989#endif // FEATURE_WLAN_SCAN_PNO
2990 }
2991 else
2992 {
2993 smsLog( pMac, LOGE, FL(" 11D channel list is empty\n"));
2994 }
2995 csrApplyPower2Current( pMac ); // Store the channel+power info in the global place: Cfg
2996 csrSetCfgCountryCode(pMac, countryCode);
2997}
2998
2999
3000void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce )
3001{
3002 if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset)))
3003 {
3004
3005#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3006 {
3007 vos_log_802_11d_pkt_type *p11dLog;
3008 int Index;
3009
3010 WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
3011 if(p11dLog)
3012 {
3013 p11dLog->eventId = WLAN_80211D_EVENT_RESET;
3014 palCopyMemory(pMac->hHdd, p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3);
3015 p11dLog->numChannel = pMac->scan.base20MHzChannels.numChannels;
3016 if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
3017 {
3018 palCopyMemory(pMac->hHdd, p11dLog->Channels, pMac->scan.base20MHzChannels.channelList,
3019 p11dLog->numChannel);
3020 for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++)
3021 {
3022 p11dLog->TxPwr[Index] = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
3023 }
3024 }
3025 if(!pMac->roam.configParam.Is11dSupportEnabled)
3026 {
3027 p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
3028 }
3029 else if(pMac->roam.configParam.fEnforceDefaultDomain)
3030 {
3031 p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
3032 }
3033 else
3034 {
3035 p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
3036 }
3037 WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
3038 }
3039 }
3040#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3041
3042 // switch to passive scans only when 11d is enabled
3043 if( csrIs11dSupported( pMac ) )
3044 {
3045 pMac->scan.curScanType = eSIR_PASSIVE_SCAN;
3046 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003047
3048 csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels);
3049 csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels);
3050
Jeff Johnson295189b2012-06-20 16:38:30 -07003051 csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE);
3052 csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE);
3053 // ... and apply the channel list, power settings, and the country code.
3054 csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent );
3055 // clear the 11d channel list
3056 palZeroMemory( pMac->hHdd, &pMac->scan.channels11d, sizeof(pMac->scan.channels11d) );
3057 pMac->scan.f11dInfoReset = eANI_BOOLEAN_TRUE;
3058 pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE;
3059 }
3060
3061 return;
3062}
3063
3064
3065eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded)
3066{
3067 eHalStatus status = eHAL_STATUS_SUCCESS;
3068 tANI_BOOLEAN fRestart = eANI_BOOLEAN_FALSE;
3069
3070 //Use the Country code and domain from EEPROM
3071 palCopyMemory(pMac->hHdd, pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN);
3072 csrSetRegulatoryDomain(pMac, pMac->scan.domainIdCurrent, &fRestart);
Jeff Johnson43971f52012-07-17 12:26:56 -07003073 if( ((eANI_BOOLEAN_FALSE == fRestart) || (pfRestartNeeded == NULL) )
3074 && !csrIsInfraConnected(pMac))
Jeff Johnson295189b2012-06-20 16:38:30 -07003075 {
3076 //Only reset the country info if we don't need to restart
3077 csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE);
3078 }
3079 if(pfRestartNeeded)
3080 {
3081 *pfRestartNeeded = fRestart;
3082 }
3083
3084 return (status);
3085}
3086
3087
3088eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded)
3089{
3090 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
3091 v_REGDOMAIN_t domainId;
3092
3093 if(pCountry)
3094 {
3095 status = csrGetRegulatoryDomainForCountry(pMac, pCountry, &domainId);
3096 if(HAL_STATUS_SUCCESS(status))
3097 {
3098 status = csrSetRegulatoryDomain(pMac, domainId, pfRestartNeeded);
3099 if(HAL_STATUS_SUCCESS(status))
3100 {
3101 //We don't need to check the pMac->roam.configParam.fEnforceDefaultDomain flag here,
3102 //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria.
3103 palCopyMemory(pMac->hHdd, pMac->scan.countryCodeCurrent, pCountry, WNI_CFG_COUNTRY_CODE_LEN);
3104 if((pfRestartNeeded == NULL) || !(*pfRestartNeeded))
3105 {
3106 //Simply set it to cfg. If we need to restart, restart will apply it to the CFG
3107 csrSetCfgCountryCode(pMac, pCountry);
3108 }
3109 }
3110 }
3111 }
3112
3113 return (status);
3114}
3115
3116
3117
3118//caller allocated memory for pNumChn and pChnPowerInfo
3119//As input, *pNumChn has the size of the array of pChnPowerInfo
3120//Upon return, *pNumChn has the number of channels assigned.
3121void csrGetChannelPowerInfo( tpAniSirGlobal pMac, tDblLinkList *pList,
3122 tANI_U32 *pNumChn, tChannelListWithPower *pChnPowerInfo)
3123{
3124 tListElem *pEntry;
3125 tANI_U32 chnIdx = 0, idx;
3126 tCsrChannelPowerInfo *pChannelSet;
3127
3128 //Get 2.4Ghz first
3129 pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
3130 while( pEntry && (chnIdx < *pNumChn) )
3131 {
3132 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
3133 if ( 1 != pChannelSet->interChannelOffset )
3134 {
3135 for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
3136 {
3137 pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
3138 pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
3139 }
3140 }
3141 else
3142 {
3143 for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ )
3144 {
3145 pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + idx);
3146 pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower;
3147 }
3148 }
3149
3150 pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
3151 }
3152 *pNumChn = chnIdx;
3153
3154 return ;
3155}
3156
3157
3158
3159void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce )
3160{
3161 v_REGDOMAIN_t domainId;
3162 eHalStatus status = eHAL_STATUS_SUCCESS;
3163
3164 do
3165 {
3166 if( !csrIs11dSupported( pMac ) || 0 == pMac->scan.channelOf11dInfo) break;
3167 if( pMac->scan.fAmbiguous11dInfoFound )
3168 {
3169 // ambiguous info found
3170 //Restore te default domain as well
3171 if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pMac->scan.countryCodeCurrent, &domainId )))
3172 {
3173 pMac->scan.domainIdCurrent = domainId;
3174 }
3175 else
3176 {
3177 smsLog(pMac, LOGE, FL(" failed to get domain from currentCountryCode %02X%02X\n"),
3178 pMac->scan.countryCodeCurrent[0], pMac->scan.countryCodeCurrent[1]);
3179 }
3180 csrResetCountryInformation( pMac, eANI_BOOLEAN_FALSE );
3181 break;
3182 }
3183 if ( pMac->scan.f11dInfoApplied && !fForce ) break;
3184 if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pMac->scan.countryCode11d, &domainId )))
3185 {
3186 //Check whether we need to enforce default domain
3187 if( ( !pMac->roam.configParam.fEnforceDefaultDomain ) ||
3188 (pMac->scan.domainIdCurrent == domainId) )
3189 {
3190
3191#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3192 {
3193 vos_log_802_11d_pkt_type *p11dLog;
3194 tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3195 tANI_U32 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp;
3196
3197 WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C);
3198 if(p11dLog)
3199 {
3200 p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET;
3201 palCopyMemory(pMac->hHdd, p11dLog->countryCode, pMac->scan.countryCode11d, 3);
3202 p11dLog->numChannel = pMac->scan.channels11d.numChannels;
3203 if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL)
3204 {
3205 palCopyMemory(pMac->hHdd, p11dLog->Channels, pMac->scan.channels11d.channelList,
3206 p11dLog->numChannel);
3207 csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList24,
3208 &nChnInfo, chnPwrInfo);
3209 nTmp = nChnInfo;
3210 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp;
3211 csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList5G,
3212 &nChnInfo, &chnPwrInfo[nTmp]);
3213 for(nTmp = 0; nTmp < p11dLog->numChannel; nTmp++)
3214 {
3215 for(nChnInfo = 0; nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN; nChnInfo++)
3216 {
3217 if(p11dLog->Channels[nTmp] == chnPwrInfo[nChnInfo].chanId)
3218 {
3219 p11dLog->TxPwr[nTmp] = chnPwrInfo[nChnInfo].pwr;
3220 break;
3221 }
3222 }
3223 }
3224 }
3225 if(!pMac->roam.configParam.Is11dSupportEnabled)
3226 {
3227 p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED;
3228 }
3229 else if(pMac->roam.configParam.fEnforceDefaultDomain)
3230 {
3231 p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN;
3232 }
3233 else
3234 {
3235 p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN;
3236 }
3237 WLAN_VOS_DIAG_LOG_REPORT(p11dLog);
3238 }
3239 }
3240#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3241 if(pMac->scan.domainIdCurrent != domainId)
3242 {
3243 /* Regulatory Domain Changed, Purge Only scan result
3244 * which does not have channel number belong to 11d
3245 * channel list
3246 * */
3247 smsLog(pMac, LOGW, FL("Domain Changed Old %d, new %d"),
3248 pMac->scan.domainIdCurrent, domainId);
3249 csrScanFilter11dResult(pMac);
3250 }
3251 status = WDA_SetRegDomain(pMac, domainId);
3252 if (status != eHAL_STATUS_SUCCESS)
3253 {
3254 smsLog( pMac, LOGE, FL(" fail to set regId %d\n"), domainId );
3255 }
3256 pMac->scan.domainIdCurrent = domainId;
3257 csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.channels11d, pMac->scan.countryCode11d );
3258 // switch to active scans using this new channel list
3259 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
3260 pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE;
3261 pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE;
3262 }
3263 }
3264
3265 } while( 0 );
3266
3267 return;
3268}
3269
3270
3271
3272tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode,
3273 tANI_BOOLEAN fForce)
3274{
3275 tANI_BOOLEAN fCountryStringChanged = FALSE, fUnknownCountryCode = FALSE;
3276 tANI_U32 i;
3277
3278 // convert to UPPER here so we are assured the strings are always in upper case.
3279 for( i = 0; i < 3; i++ )
3280 {
3281 pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] );
3282 }
3283
3284 // Some of the 'old' Cisco 350 series AP's advertise NA as the country code (for North America ??).
3285 // NA is not a valid country code or domain so let's allow this by changing it to the proper
3286 // country code (which is US). We've also seen some NETGEAR AP's that have "XX " as the country code
3287 // with valid 2.4 GHz US channel information. If we cannot find the country code advertised in the
3288 // 11d information element, let's default to US.
3289 if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, pCountryCode, NULL ) ) )
3290 {
3291 // Check the enforcement first
3292 if( pMac->roam.configParam.fEnforceDefaultDomain || pMac->roam.configParam.fEnforceCountryCodeMatch )
3293 {
3294 fUnknownCountryCode = TRUE;
3295 }
3296 else
3297 {
3298 pCountryCode[ 0 ] = 'U';
3299 pCountryCode[ 1 ] = 'S';
3300 }
3301 }
3302
3303 // We've seen some of the AP's improperly put a 0 for the third character of the country code.
3304 // spec says valid charcters are 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either).
3305 // if we see a 0 in this third character, let's change it to a ' '.
3306 if ( 0 == pCountryCode[ 2 ] )
3307 {
3308 pCountryCode[ 2 ] = ' ';
3309 }
3310
3311 if( !fUnknownCountryCode )
3312 {
3313 fCountryStringChanged = (!palEqualMemory( pMac->hHdd,
3314 pMac->scan.countryCode11d, pCountryCode, 2));
3315
3316
3317 if(( 0 == pMac->scan.countryCode11d[ 0 ] && 0 == pMac->scan.countryCode11d[ 1 ] )
3318 || (fForce))
3319 {
3320 // this is the first .11d information
3321 palCopyMemory( pMac->hHdd, pMac->scan.countryCode11d, pCountryCode, sizeof( pMac->scan.countryCode11d ) );
3322 }
3323 }
3324
3325 return( fCountryStringChanged );
3326}
3327
3328
3329void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand )
3330{
3331 tANI_U32 Index, count=0;
3332 tSirMacChanInfo *pChanInfo;
3333 tSirMacChanInfo *pChanInfoStart;
3334
3335 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN)))
3336 {
3337 palZeroMemory(pMac->hHdd, pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN);
3338 pChanInfoStart = pChanInfo;
3339 for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++)
3340 {
3341 if ((fPopulate5GBand && (CSR_IS_CHANNEL_5GHZ(pMac->scan.defaultPowerTable[Index].chanId))) ||
3342 (!fPopulate5GBand && (CSR_IS_CHANNEL_24GHZ(pMac->scan.defaultPowerTable[Index].chanId))) )
3343 {
3344 pChanInfo->firstChanNum = pMac->scan.defaultPowerTable[Index].chanId;
3345 pChanInfo->numChannels = 1;
3346 pChanInfo->maxTxPower = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap );
3347 pChanInfo++;
3348 count++;
3349 }
3350 }
3351 if(count)
3352 {
3353 csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart );
3354 }
3355 palFreeMemory(pMac->hHdd, pChanInfoStart);
3356 }
3357}
3358
3359
3360void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac )
3361{
3362 tANI_BOOLEAN fPopulate5GBand = FALSE;
3363
3364 do
3365 {
3366 // if this is not a dual band product, then we don't need to set the opposite
3367 // band info. We only work in one band so no need to look in the other band.
3368 if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) break;
3369 // if we found channel info on the 5.0 band and...
3370 if ( CSR_IS_CHANNEL_5GHZ( pMac->scan.channelOf11dInfo ) )
3371 {
3372 // and the 2.4 band is empty, then populate the 2.4 channel info
3373 if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList24, LL_ACCESS_LOCK ) ) break;
3374 fPopulate5GBand = FALSE;
3375 }
3376 else
3377 {
3378 // else, we found channel info in the 2.4 GHz band. If the 5.0 band is empty
3379 // set the 5.0 band info from the 2.4 country code.
3380 if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList5G, LL_ACCESS_LOCK ) ) break;
3381 fPopulate5GBand = TRUE;
3382 }
3383 csrSaveChannelPowerForBand( pMac, fPopulate5GBand );
3384
3385 } while( 0 );
3386}
3387
3388
3389tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId)
3390{
3391 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
3392 tANI_U32 i;
3393
3394 //Make sure it is a channel that is in our supported list.
3395 for ( i = 0; i < pMac->scan.baseChannels.numChannels; i++ )
3396 {
3397 if ( channelId == pMac->scan.baseChannels.channelList[i] )
3398 {
3399 fRet = eANI_BOOLEAN_TRUE;
3400 break;
3401 }
3402 }
3403
3404 //If it is configured to limit a set of the channels
3405 if( fRet && pMac->roam.configParam.fEnforce11dChannels )
3406 {
3407 fRet = eANI_BOOLEAN_FALSE;
3408 for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ )
3409 {
3410 if ( channelId == pMac->scan.base20MHzChannels.channelList[i] )
3411 {
3412 fRet = eANI_BOOLEAN_TRUE;
3413 break;
3414 }
3415 }
3416 }
3417
3418 return (fRet);
3419}
3420
3421
3422
3423//bSize specify the buffer size of pChannelList
3424tANI_U8 csrGetChannelListFromChannelSet( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 bSize, tCsrChannelPowerInfo *pChannelSet )
3425{
3426 tANI_U8 i, j = 0, chnId;
3427
3428 bSize = CSR_MIN(bSize, pChannelSet->numChannels);
3429 for( i = 0; i < bSize; i++ )
3430 {
3431 chnId = (tANI_U8)(pChannelSet->firstChannel + ( i * pChannelSet->interChannelOffset ));
3432 if ( csrIsSupportedChannel( pMac, chnId ) )
3433 {
3434 pChannelList[j++] = chnId;
3435 }
3436 }
3437
3438 return (j);
3439}
3440
3441
3442
3443//bSize -- specify the buffer size of pChannelList
3444void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList,
3445 tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels )
3446{
3447 tListElem *pEntry;
3448 tCsrChannelPowerInfo *pChannelSet;
3449 tANI_U8 numChannels;
3450 tANI_U8 *pChannels;
3451
3452 if( pChannelSetList && pChannelList && pNumChannels )
3453 {
3454 pChannels = pChannelList;
3455 *pNumChannels = 0;
3456 pEntry = csrLLPeekHead( pChannelSetList, LL_ACCESS_LOCK );
3457 while( pEntry )
3458 {
3459 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
3460 numChannels = csrGetChannelListFromChannelSet( pMac, pChannels, bSize, pChannelSet );
3461 pChannels += numChannels;
3462 *pNumChannels += numChannels;
3463 pEntry = csrLLNext( pChannelSetList, pEntry, LL_ACCESS_LOCK );
3464 }
3465 }
3466}
3467
3468
3469/*
3470 * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d
3471*/
3472tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
3473 tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce)
3474{
3475 tANI_U8 Num2GChannels, bMaxNumChn;
3476 eHalStatus status;
3477 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
3478 v_REGDOMAIN_t domainId;
3479 tDot11fBeaconIEs *pIesLocal = pIes;
3480
3481#ifdef WLAN_SOFTAP_FEATURE
3482 if (VOS_STA_SAP_MODE == vos_get_conparam ())
3483 return eHAL_STATUS_SUCCESS;
3484#endif
3485
3486 do
3487 {
3488 // check if .11d support is enabled
3489 if( !csrIs11dSupported( pMac ) ) break;
3490 if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
3491 {
3492 break;
3493 }
3494 // check if country information element is present
3495 if(!pIesLocal->Country.present)
3496 {
3497 //No country info
3498 break;
3499 }
3500
3501 if( csrSave11dCountryString( pMac, pIesLocal->Country.country, fForce ) )
3502 {
3503 // country string changed, this should not happen
3504 //Need to check whether we care about this BSS' domain info
3505 //If it doesn't match of the connected profile or roaming profile, let's ignore it
3506 tANI_U32 i;
3507 tCsrRoamSession *pSession;
3508
3509 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
3510 {
3511 if( CSR_IS_SESSION_VALID( pMac, i ) )
3512 {
3513 pSession = CSR_GET_SESSION( pMac, i );
3514 if(pSession->pCurRoamProfile)
3515 {
3516 tCsrScanResultFilter filter;
3517
3518 palZeroMemory(pMac->hHdd, &filter, sizeof(tCsrScanResultFilter));
3519 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, &filter);
3520 if(HAL_STATUS_SUCCESS(status))
3521 {
3522 tANI_BOOLEAN fMatch = csrMatchBSS(pMac, pSirBssDesc, &filter, NULL, NULL, NULL, NULL);
3523 //Free the resource first
3524 csrFreeScanFilter( pMac, &filter );
3525 if(fMatch)
3526 {
3527 smsLog(pMac, LOGW, " Matching roam profile BSSID %02X-%02X-%02X-%02X-%02X-%02X causing ambiguous domain info\n",
3528 pSirBssDesc->bssId[0], pSirBssDesc->bssId[1], pSirBssDesc->bssId[2],
3529 pSirBssDesc->bssId[3], pSirBssDesc->bssId[4], pSirBssDesc->bssId[5]);
3530 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3531 break;
3532 }
3533 }
3534 }
3535 else if( csrIsConnStateConnected(pMac, i))
3536 {
3537 //Reach here only when the currention is base on no profile.
3538 //User doesn't give profile and just connect to anything.
3539 if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pSirBssDesc, pIesLocal))
3540 {
3541 smsLog(pMac, LOGW, " Matching connect profile BSSID %02X-%02X-%02X-%02X-%02X-%02X causing ambiguous domain info\n",
3542 pSirBssDesc->bssId[0], pSirBssDesc->bssId[1], pSirBssDesc->bssId[2],
3543 pSirBssDesc->bssId[3], pSirBssDesc->bssId[4], pSirBssDesc->bssId[5]);
3544 //Tush
3545 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3546 if(csrIsBssidMatch(pMac, (tCsrBssid *)&pSirBssDesc->bssId,
3547 &pSession->connectedProfile.bssid))
3548 {
3549 //AP changed the 11d info on the fly, modify cfg
3550 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
3551 fRet = eANI_BOOLEAN_TRUE;
3552 }
3553 break;
3554 }
3555 }
3556 } //valid session
3557 } //for
3558 if ( i == CSR_ROAM_SESSION_MAX )
3559 {
3560 //Check whether we can use this country's 11d information
3561 if( !pMac->roam.configParam.fEnforceDefaultDomain )
3562 {
3563 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_TRUE;
3564 }
3565 else
3566 {
3567 VOS_ASSERT( pMac->scan.domainIdCurrent == pMac->scan.domainIdDefault );
3568 if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(
3569 pMac, pIesLocal->Country.country, &domainId )) &&
3570 ( domainId == pMac->scan.domainIdCurrent ) )
3571 {
3572 //Two countries in the same domain
3573 }
3574 }
3575 }
3576 }
3577 else //Tush
3578 {
3579 pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_TRUE;
3580 }
3581
3582 //In case that some channels in 5GHz have the same channel number as 2.4GHz (<= 14)
3583 if(CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId))
3584 {
3585 tANI_U8 iC;
3586 tSirMacChanInfo* pMacChnSet = (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]);
3587
3588 for(iC = 0; iC < pIesLocal->Country.num_triplets; iC++)
3589 {
3590 if(CSR_IS_CHANNEL_24GHZ(pMacChnSet[iC].firstChanNum))
3591 {
3592 pMacChnSet[iC].firstChanNum += 200; //*** Where is this 200 defined?
3593 }
3594 }
3595 }
Mohit Khanna23863762012-09-11 17:40:09 -07003596 smsLog(pMac, LOG3, FL(" %d sets each one is %d\n"), pIesLocal->Country.num_triplets, sizeof(tSirMacChanInfo));
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 // save the channel/power information from the Channel IE.
3598 //sizeof(tSirMacChanInfo) has to be 3
Jeff Johnsone7245742012-09-05 17:12:55 -07003599 if (eHAL_STATUS_SUCCESS != csrSaveToChannelPower2G_5G( pMac, pIesLocal->Country.num_triplets * sizeof(tSirMacChanInfo),
3600 (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]) ))
3601 {
3602 fRet = eANI_BOOLEAN_FALSE;
3603 return fRet;
3604 }
3605
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 // set the indicator of the channel where the country IE was found...
3607 pMac->scan.channelOf11dInfo = pSirBssDesc->channelId;
3608 // Populate both band channel lists based on what we found in the country information...
3609 csrSetOppositeBandChannelInfo( pMac );
3610 bMaxNumChn = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3611 // construct 2GHz channel list first
3612 csrConstructCurrentValidChannelList( pMac, &pMac->scan.channelPowerInfoList24, pMac->scan.channels11d.channelList,
3613 bMaxNumChn, &Num2GChannels );
3614 // construct 5GHz channel list now
3615 if(bMaxNumChn > Num2GChannels)
3616 {
3617 csrConstructCurrentValidChannelList( pMac, &pMac->scan.channelPowerInfoList5G, pMac->scan.channels11d.channelList + Num2GChannels,
3618 bMaxNumChn - Num2GChannels,
3619 &pMac->scan.channels11d.numChannels );
3620 }
3621
3622 pMac->scan.channels11d.numChannels += Num2GChannels;
3623 fRet = eANI_BOOLEAN_TRUE;
3624
3625 } while( 0 );
3626
3627 if( !pIes && pIesLocal )
3628 {
3629 //locally allocated
3630 palFreeMemory(pMac->hHdd, pIesLocal);
3631 }
3632
3633 return( fRet );
3634}
3635
3636
3637static void csrSaveScanResults( tpAniSirGlobal pMac )
3638{
3639 // initialize this to FALSE. profMoveInterimScanResultsToMainList() routine
3640 // will set this to the channel where an .11d beacon is seen
3641 pMac->scan.channelOf11dInfo = 0;
3642 // if we get any ambiguous .11d information then this will be set to TRUE
3643 pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE;
3644 //Tush
3645 // if we get any ambiguous .11d information, then this will be set to TRUE
3646 // only if the applied 11d info could be found in one of the scan results
3647 pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_FALSE;
3648 // move the scan results from interim list to the main scan list
3649 csrMoveTempScanResultsToMainList( pMac );
3650
3651 // Now check if we gathered any domain/country specific information
3652 // If so, we should update channel list and apply Tx power settings
Jeff Johnsone7245742012-09-05 17:12:55 -07003653 if( csrIs11dSupported(pMac) )
3654 {
3655 csrApplyCountryInformation( pMac, FALSE );
3656 }
3657 else if( csrIs11hSupported(pMac) && !pMac->roam.configParam.fSupplicantCountryCodeHasPriority)
3658 {
3659 // If llh is enabled, store the channel + power information gathered in the cfg
3660 csrApplyPower2Current( pMac );
3661 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003662}
3663
3664
3665void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3666{
3667 switch (pCommand->u.scanCmd.reason)
3668 {
3669 case eCsrScanSetBGScanParam:
3670 case eCsrScanAbortBgScan:
3671 if(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList)
3672 {
3673 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList);
3674 pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
3675 }
3676 break;
3677 case eCsrScanBGScanAbort:
3678 case eCsrScanBGScanEnable:
3679 case eCsrScanGetScanChnInfo:
3680 break;
3681 case eCsrScanAbortNormalScan:
3682 default:
3683 csrScanFreeRequest(pMac, &pCommand->u.scanCmd.u.scanRequest);
3684 break;
3685 }
3686 if(pCommand->u.scanCmd.pToRoamProfile)
3687 {
3688 csrReleaseProfile(pMac, pCommand->u.scanCmd.pToRoamProfile);
3689 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.pToRoamProfile);
3690 }
3691 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
3692}
3693
3694
3695tANI_BOOLEAN csrGetRemainingChannelsFor11dScan( tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U8 *pcChannels )
3696{
3697 tANI_U32 index11dChannels, index;
3698 tANI_U32 indexCurrentChannels;
3699 tANI_BOOLEAN fChannelAlreadyScanned;
3700 tANI_U32 len = sizeof(pMac->roam.validChannelList);
3701
3702 *pcChannels = 0;
3703 if ( CSR_IS_11D_INFO_FOUND(pMac) && csrRoamIsChannelValid(pMac, pMac->scan.channelOf11dInfo) )
3704 {
3705 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
3706 {
3707 //Find the channel index where we found the 11d info
3708 for(index = 0; index < len; index++)
3709 {
3710 if(pMac->scan.channelOf11dInfo == pMac->roam.validChannelList[index])
3711 break;
3712 }
3713 //check whether we found the channel index
3714 if(index < len)
3715 {
3716 // Now, look through the 11d channel list and create a list of all channels in the 11d list that are
3717 // NOT in the current channel list. This gives us a list of the new channels that have not been
3718 // scanned. We'll scan this new list so we have a complete set of scan results on all of the domain channels
3719 // initially.
3720 for ( index11dChannels = 0; index11dChannels < pMac->scan.channels11d.numChannels; index11dChannels++ )
3721 {
3722 fChannelAlreadyScanned = eANI_BOOLEAN_FALSE;
3723
3724 for( indexCurrentChannels = 0; indexCurrentChannels < index; indexCurrentChannels++ )
3725 {
3726 if ( pMac->roam.validChannelList[ indexCurrentChannels ] == pMac->scan.channels11d.channelList[ index11dChannels ] )
3727 {
3728 fChannelAlreadyScanned = eANI_BOOLEAN_TRUE;
3729 break;
3730 }
3731 }
3732
3733 if ( !fChannelAlreadyScanned )
3734 {
3735 pChannels[ *pcChannels ] = pMac->scan.channels11d.channelList[ index11dChannels ];
3736 ( *pcChannels )++;
3737 }
3738 }
3739 }
3740 }//GetCFG
3741 }
3742 return( *pcChannels );
3743}
3744
3745
3746eCsrScanCompleteNextCommand csrScanGetNextCommandState( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fSuccess )
3747{
3748 eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
3749
3750 switch( pCommand->u.scanCmd.reason )
3751 {
3752 case eCsrScan11d1:
3753 NextCommand = (fSuccess) ? eCsrNext11dScan1Success : eCsrNext11dScan1Failure;
3754 break;
3755 case eCsrScan11d2:
3756 NextCommand = (fSuccess) ? eCsrNext11dScan2Success : eCsrNext11dScan2Failure;
3757 break;
3758 case eCsrScan11dDone:
3759 NextCommand = eCsrNext11dScanComplete;
3760 break;
3761 case eCsrScanLostLink1:
3762 NextCommand = (fSuccess) ? eCsrNextLostLinkScan1Success : eCsrNextLostLinkScan1Failed;
3763 break;
3764 case eCsrScanLostLink2:
3765 NextCommand = (fSuccess) ? eCsrNextLostLinkScan2Success : eCsrNextLostLinkScan2Failed;
3766 break;
3767 case eCsrScanLostLink3:
3768 NextCommand = (fSuccess) ? eCsrNextLostLinkScan3Success : eCsrNextLostLinkScan3Failed;
3769 break;
3770 case eCsrScanForSsid:
3771 NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess : eCsrNexteScanForSsidFailure;
3772 break;
3773 case eCsrScanForCapsChange:
3774 NextCommand = eCsrNextCapChangeScanComplete; //don't care success or not
3775 break;
3776 case eCsrScanIdleScan:
3777 NextCommand = eCsrNextIdleScanComplete;
3778 break;
3779 default:
3780 NextCommand = eCsrNextScanNothing;
3781 break;
3782 }
3783 return( NextCommand );
3784}
3785
3786
3787//Return whether the pCommand is finished.
3788tANI_BOOLEAN csrHandleScan11d1Failure(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3789{
3790 tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
3791
3792 //Apply back the default setting and passively scan one more time.
3793 csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE);
3794 pCommand->u.scanCmd.reason = eCsrScan11d2;
3795 if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
3796 {
3797 fRet = eANI_BOOLEAN_FALSE;
3798 }
3799
3800 return (fRet);
3801}
3802
3803
3804tANI_BOOLEAN csrHandleScan11dSuccess(tpAniSirGlobal pMac, tSmeCmd *pCommand)
3805{
3806 tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
3807 tANI_U8 *pChannels;
3808 tANI_U8 cChannels;
3809
3810 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN)))
3811 {
3812 palZeroMemory(pMac->hHdd, pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3813 if ( csrGetRemainingChannelsFor11dScan( pMac, pChannels, &cChannels ) )
3814 {
3815 pCommand->u.scanCmd.reason = eCsrScan11dDone;
3816 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
3817 {
3818 palFreeMemory(pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
3819 }
3820 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, cChannels)))
3821 {
3822 palCopyMemory(pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, pChannels, cChannels);
3823 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = cChannels;
3824 pCommand->u.scanCmd.u.scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
3825 pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
3826 if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand)))
3827 {
3828 //Reuse the same command buffer
3829 fRet = eANI_BOOLEAN_FALSE;
3830 }
3831 }
3832 }
3833 palFreeMemory(pMac->hHdd, pChannels);
3834 }
3835
3836 return (fRet);
3837}
3838
3839//Return whether the command should be removed
3840tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp )
3841{
3842 eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
3843 tListElem *pEntry;
3844 tSmeCmd *pCommand;
3845 tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
3846 tANI_BOOLEAN fSuccess;
3847
3848 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
3849
3850 if ( pEntry )
3851 {
3852 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
3853
3854 // If the head of the queue is Active and it is a SCAN command, remove
3855 // and put this on the Free queue.
3856 if ( eSmeCommandScan == pCommand->command )
3857 {
3858 tANI_U32 sessionId = pCommand->sessionId;
3859
3860 if(eSIR_SME_SUCCESS != pScanRsp->statusCode)
3861 {
3862 fSuccess = eANI_BOOLEAN_FALSE;
3863 }
3864 else
3865 {
3866 //pMac->scan.tempScanResults is not empty meaning the scan found something
3867 //This check only valid here because csrSaveScanresults is not yet called
3868 fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK));
3869 }
3870 csrSaveScanResults(pMac);
3871
3872#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3873 {
3874 vos_log_scan_pkt_type *pScanLog = NULL;
3875 tScanResultHandle hScanResult;
3876 tCsrScanResultInfo *pScanResult;
3877 tDot11fBeaconIEs *pIes;
3878 int n = 0, c = 0;
3879
3880 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
3881 if(pScanLog)
3882 {
3883 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
3884 eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
3885 eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
3886 {
3887 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP;
3888 }
3889 else
3890 {
3891 if( eSIR_PASSIVE_SCAN != pMac->scan.curScanType )
3892 {
3893 pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP;
3894 }
3895 else
3896 {
3897 pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP;
3898 }
3899 }
3900 if(eSIR_SME_SUCCESS == pScanRsp->statusCode)
3901 {
3902 if(HAL_STATUS_SUCCESS(csrScanGetResult(pMac, NULL, &hScanResult)))
3903 {
3904 while(((pScanResult = csrScanResultGetNext(pMac, hScanResult)) != NULL))
3905 {
3906 if( n < VOS_LOG_MAX_NUM_BSSID )
3907 {
3908 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->BssDescriptor, &pIes)))
3909 {
3910 smsLog(pMac, LOGE, FL(" fail to parse IEs\n"));
3911 break;
3912 }
3913 palCopyMemory(pMac->hHdd, pScanLog->bssid[n], pScanResult->BssDescriptor.bssId, 6);
3914 if(pIes && pIes->SSID.present && VOS_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid)
3915 {
3916 palCopyMemory(pMac->hHdd, pScanLog->ssid[n],
3917 pIes->SSID.ssid, pIes->SSID.num_ssid);
3918 }
3919 palFreeMemory(pMac->hHdd, pIes);
3920 n++;
3921 }
3922 c++;
3923 }
3924 pScanLog->numSsid = (v_U8_t)n;
3925 pScanLog->totalSsid = (v_U8_t)c;
3926 csrScanResultPurge(pMac, hScanResult);
3927 }
3928 }
3929 else
3930 {
3931 pScanLog->status = WLAN_SCAN_STATUS_FAILURE;
3932 }
3933 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
3934 }
3935 }
3936#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
3937
3938 NextCommand = csrScanGetNextCommandState(pMac, pCommand, fSuccess);
3939 //We reuse the command here instead reissue a new command
3940 switch(NextCommand)
3941 {
3942 case eCsrNext11dScan1Success:
3943 case eCsrNext11dScan2Success:
3944 smsLog( pMac, LOG2, FL("11dScan1/3 produced results. Reissue Active scan...\n"));
3945 // if we found country information, no need to continue scanning further, bail out
3946 fRemoveCommand = eANI_BOOLEAN_TRUE;
3947 NextCommand = eCsrNext11dScanComplete;
3948 break;
3949 case eCsrNext11dScan1Failure:
3950 //We are not done yet. 11d scan fail once. We will try to reset anything and do it over again
3951 //The only meaningful thing for this retry is that we cannot find 11d information after a reset so
3952 //we clear the "old" 11d info and give it once more chance
3953 fRemoveCommand = csrHandleScan11d1Failure(pMac, pCommand);
3954 if(fRemoveCommand)
3955 {
3956 NextCommand = eCsrNext11dScanComplete;
3957 }
3958 break;
3959 case eCsrNextLostLinkScan1Success:
3960 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink1)))
3961 {
3962 csrScanHandleFailedLostlink1(pMac, sessionId);
3963 }
3964 break;
3965 case eCsrNextLostLinkScan2Success:
3966 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink2)))
3967 {
3968 csrScanHandleFailedLostlink2(pMac, sessionId);
3969 }
3970 break;
3971 case eCsrNextLostLinkScan3Success:
3972 if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink3)))
3973 {
3974 csrScanHandleFailedLostlink3(pMac, sessionId);
3975 }
3976 break;
3977 case eCsrNextLostLinkScan1Failed:
3978 csrScanHandleFailedLostlink1(pMac, sessionId);
3979 break;
3980 case eCsrNextLostLinkScan2Failed:
3981 csrScanHandleFailedLostlink2(pMac, sessionId);
3982 break;
3983 case eCsrNextLostLinkScan3Failed:
3984 csrScanHandleFailedLostlink3(pMac, sessionId);
3985 break;
3986 case eCsrNexteScanForSsidSuccess:
3987 csrScanHandleSearchForSSID(pMac, pCommand);
3988 break;
3989 case eCsrNexteScanForSsidFailure:
3990 csrScanHandleSearchForSSIDFailure(pMac, pCommand);
3991 break;
3992 case eCsrNextIdleScanComplete:
3993 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
3994 break;
3995 case eCsrNextCapChangeScanComplete:
3996 csrScanHandleCapChangeScanComplete(pMac, sessionId);
3997 break;
3998 default:
3999
4000 break;
4001 }
4002 }
4003 else
4004 {
4005 smsLog( pMac, LOGW, FL("Scan Completion called but SCAN command is not ACTIVE ...\n"));
4006 fRemoveCommand = eANI_BOOLEAN_FALSE;
4007 }
4008 }
4009 else
4010 {
4011 smsLog( pMac, LOGW, FL("Scan Completion called but NO commands are ACTIVE ...\n"));
4012 fRemoveCommand = eANI_BOOLEAN_FALSE;
4013 }
4014
4015 return( fRemoveCommand );
4016}
4017
4018
4019
4020static void csrScanRemoveDupBssDescriptionFromInterimList( tpAniSirGlobal pMac,
4021 tSirBssDescription *pSirBssDescr,
4022 tDot11fBeaconIEs *pIes)
4023{
4024 tListElem *pEntry;
4025 tCsrScanResult *pCsrBssDescription;
4026
4027 // Walk through all the chained BssDescriptions. If we find a chained BssDescription that
4028 // matches the BssID of the BssDescription passed in, then these must be duplicate scan
4029 // results for this Bss. In that case, remove the 'old' Bss description from the linked list.
4030 pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK );
4031 while( pEntry )
4032 {
4033 pCsrBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
4034
4035 // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType
4036 // matches
4037
4038 if ( csrIsDuplicateBssDescription( pMac, &pCsrBssDescription->Result.BssDescriptor,
4039 pSirBssDescr, pIes ) )
4040 {
4041 pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) +
4042 ((tANI_S32)pCsrBssDescription->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 );
4043
4044 // Remove the 'old' entry from the list....
4045 if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ) )
4046 {
4047 csrCheckNSaveWscIe(pMac, pSirBssDescr, &pCsrBssDescription->Result.BssDescriptor);
4048 // we need to free the memory associated with this node
4049 csrFreeScanResultEntry( pMac, pCsrBssDescription );
4050 }
4051
4052 // If we found a match, we can stop looking through the list.
4053 break;
4054 }
4055
4056 pEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK );
4057 }
4058}
4059
4060
4061
4062//Caller allocated memory pfNewBssForConn to return whether new candidate for
4063//current connection is found. Cannot be NULL
4064tCsrScanResult *csrScanSaveBssDescriptionToInterimList( tpAniSirGlobal pMac,
4065 tSirBssDescription *pBSSDescription,
4066 tDot11fBeaconIEs *pIes)
4067{
4068 tCsrScanResult *pCsrBssDescription = NULL;
4069 tANI_U32 cbBSSDesc;
4070 tANI_U32 cbAllocated;
4071 eHalStatus halStatus;
4072
4073 // figure out how big the BSS description is (the BSSDesc->length does NOT
4074 // include the size of the length field itself).
4075 cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length );
4076
4077 cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc;
4078
4079 halStatus = palAllocateMemory( pMac->hHdd, (void **)&pCsrBssDescription, cbAllocated );
4080 if ( HAL_STATUS_SUCCESS(halStatus) )
4081 {
4082 palZeroMemory(pMac->hHdd, pCsrBssDescription, cbAllocated);
4083 pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
4084 palCopyMemory(pMac->hHdd, &pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc );
4085 //Save SSID separately for later use
4086 if( pIes->SSID.present && !csrIsNULLSSID(pIes->SSID.ssid, pIes->SSID.num_ssid) )
4087 {
4088 //SSID not hidden
4089 tANI_U32 len = pIes->SSID.num_ssid;;
4090 if (len > SIR_MAC_MAX_SSID_LENGTH)
4091 {
4092 // truncate to fit in our struct
4093 len = SIR_MAC_MAX_SSID_LENGTH;
4094 }
4095 pCsrBssDescription->Result.ssId.length = len;
4096 pCsrBssDescription->Result.timer = vos_timer_get_system_time();
4097 palCopyMemory(pMac->hHdd, pCsrBssDescription->Result.ssId.ssId,
4098 pIes->SSID.ssid, len );
4099 }
4100 csrLLInsertTail( &pMac->scan.tempScanResults, &pCsrBssDescription->Link, LL_ACCESS_LOCK );
4101 }
4102
4103 return( pCsrBssDescription );
4104}
4105
4106
4107
4108
4109tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1,
4110 tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 )
4111{
4112 tANI_BOOLEAN fMatch = FALSE;
4113 tSirMacCapabilityInfo *pCap1, *pCap2;
4114 tDot11fBeaconIEs *pIes1 = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004115 tDot11fBeaconIEs *pIesTemp = pIes2;
Jeff Johnson295189b2012-06-20 16:38:30 -07004116
4117 pCap1 = (tSirMacCapabilityInfo *)&pSirBssDesc1->capabilityInfo;
4118 pCap2 = (tSirMacCapabilityInfo *)&pSirBssDesc2->capabilityInfo;
4119 if(pCap1->ess == pCap2->ess)
4120 {
4121 if (pCap1->ess &&
Jeff Johnsone7245742012-09-05 17:12:55 -07004122 csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)&&
4123 (pSirBssDesc1->channelId == pSirBssDesc2->channelId))
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 {
4125 fMatch = TRUE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004126 // Check for SSID match, if exists
4127 do
4128 {
4129 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
4130 {
4131 break;
4132 }
4133 if( NULL == pIesTemp )
4134 {
4135 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
4136 {
4137 break;
4138 }
4139 }
4140 if(pIes1->SSID.present && pIesTemp->SSID.present)
4141 {
4142 fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid,
4143 pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
4144 }
4145 }while(0);
4146
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 }
4148 else if (pCap1->ibss && (pSirBssDesc1->channelId == pSirBssDesc2->channelId))
4149 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004150
4151 do
4152 {
4153 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
4154 {
4155 break;
4156 }
4157 if( NULL == pIesTemp )
4158 {
4159 if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp)))
4160 {
4161 break;
4162 }
4163 }
4164 //Same channel cannot have same SSID for different IBSS
4165 if(pIes1->SSID.present && pIesTemp->SSID.present)
4166 {
4167 fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid,
4168 pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE);
4169 }
4170 }while(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 }
4172#if defined WLAN_FEATURE_P2P
4173 /* In case of P2P devices, ess and ibss will be set to zero */
4174 else if (!pCap1->ess &&
4175 csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId))
4176 {
4177 fMatch = TRUE;
4178 }
4179#endif
4180 }
4181
4182 if(pIes1)
4183 {
4184 palFreeMemory(pMac->hHdd, pIes1);
4185 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004186
4187 if( (NULL == pIes2) && pIesTemp )
4188 {
4189 //locally allocated
4190 palFreeMemory(pMac->hHdd, pIesTemp);
4191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004192
4193 return( fMatch );
4194}
4195
4196
4197tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 )
4198{
4199 return( pSirBssDesc1->nwType == pSirBssDesc2->nwType );
4200}
4201
4202
4203//to check whether the BSS matches the dot11Mode
4204static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc,
4205 tDot11fBeaconIEs *pIes)
4206{
4207 tANI_BOOLEAN fAllowed = eANI_BOOLEAN_FALSE;
4208 eCsrPhyMode phyMode;
4209
4210 if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pBssDesc, &phyMode, pIes)))
4211 {
4212 switch(pMac->roam.configParam.phyMode)
4213 {
4214 case eCSR_DOT11_MODE_11b:
4215 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
4216 break;
4217 case eCSR_DOT11_MODE_11g:
4218 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode);
4219 break;
4220 case eCSR_DOT11_MODE_11g_ONLY:
4221 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11g == phyMode);
4222 break;
4223 case eCSR_DOT11_MODE_11a:
4224 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11b != phyMode) && (eCSR_DOT11_MODE_11g != phyMode));
4225 break;
4226 case eCSR_DOT11_MODE_11n_ONLY:
4227 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11n == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
4228 break;
Jeff Johnsone7245742012-09-05 17:12:55 -07004229
4230#ifdef WLAN_FEATURE_11AC
4231 case eCSR_DOT11_MODE_11ac_ONLY:
4232 fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11ac == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode));
4233 break;
4234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 case eCSR_DOT11_MODE_11b_ONLY:
4236 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode);
4237 break;
4238 case eCSR_DOT11_MODE_11a_ONLY:
4239 fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode);
4240 break;
4241 case eCSR_DOT11_MODE_11n:
Jeff Johnsone7245742012-09-05 17:12:55 -07004242#ifdef WLAN_FEATURE_11AC
4243 case eCSR_DOT11_MODE_11ac:
4244#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004245 case eCSR_DOT11_MODE_TAURUS:
4246 default:
4247 fAllowed = eANI_BOOLEAN_TRUE;
4248 break;
4249 }
4250 }
4251
4252 return (fAllowed);
4253}
4254
4255
4256
4257//Return pIes to caller for future use when returning TRUE.
4258static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels,
4259 tANI_U8 numChn, tSirBssDescription *pBssDesc,
4260 tDot11fBeaconIEs **ppIes )
4261{
4262 tANI_BOOLEAN fValidChannel = FALSE;
4263 tDot11fBeaconIEs *pIes = NULL;
4264 tANI_U8 index;
4265
4266 for( index = 0; index < numChn; index++ )
4267 {
4268 // This check relies on the fact that a single BSS description is returned in each
4269 // ScanRsp call, which is the way LIM implemented the scan req/rsp funtions. We changed
4270 // to this model when we ran with a large number of APs. If this were to change, then
4271 // this check would have to mess with removing the bssDescription from somewhere in an
4272 // arbitrary index in the bssDescription array.
4273 if ( pChannels[ index ] == pBssDesc->channelId )
4274 {
4275 fValidChannel = TRUE;
4276 break;
4277 }
4278 }
4279 *ppIes = NULL;
4280 if(fValidChannel)
4281 {
4282 if( HAL_STATUS_SUCCESS( csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes) ) )
4283 {
4284 fValidChannel = csrScanIsBssAllowed(pMac, pBssDesc, pIes);
4285 if( fValidChannel )
4286 {
4287 *ppIes = pIes;
4288 }
4289 else
4290 {
4291 palFreeMemory( pMac->hHdd, pIes );
4292 }
4293 }
4294 else
4295 {
4296 fValidChannel = FALSE;
4297 }
4298 }
4299
4300 return( fValidChannel );
4301}
4302
4303
4304//Return whether last scan result is received
4305static tANI_BOOLEAN csrScanProcessScanResults( tpAniSirGlobal pMac, tSmeCmd *pCommand,
4306 tSirSmeScanRsp *pScanRsp, tANI_BOOLEAN *pfRemoveCommand )
4307{
4308 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE, fRemoveCommand = eANI_BOOLEAN_FALSE;
4309 tDot11fBeaconIEs *pIes = NULL;
4310 tANI_U32 cbParsed;
4311 tSirBssDescription *pSirBssDescription;
4312 tANI_U32 cbBssDesc;
4313 tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription )
4314 + sizeof(tSirBssDescription); //We need at least one CB
4315
4316 // don't consider the scan rsp to be valid if the status code is Scan Failure. Scan Failure
4317 // is returned when the scan could not find anything. so if we get scan failure return that
4318 // the scan response is invalid. Also check the lenght in the scan result for valid scan
4319 // BssDescriptions....
4320 do
4321 {
4322 if ( ( cbScanResult <= pScanRsp->length ) &&
4323 (( eSIR_SME_SUCCESS == pScanRsp->statusCode ) ||
4324 ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW == pScanRsp->statusCode ) ) )
4325 {
4326 tANI_U8 *pChannelList = NULL;
4327 tANI_U8 cChannels = 0;
4328
4329 //Different scan type can reach this point, we need to distinguish it
4330 if( eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason )
4331 {
4332 //eCsrScanSetBGScanParam uses different structure
4333 tCsrBGScanRequest *pBgScanReq = &pCommand->u.scanCmd.u.bgScanRequest;
4334
4335 cChannels = pBgScanReq->ChannelInfo.numOfChannels;
4336 pChannelList = pBgScanReq->ChannelInfo.ChannelList;
4337 }
4338 else
4339 {
4340 //the rest use generic scan request
4341 cChannels = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
4342 pChannelList = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
4343 }
4344
4345 // if the scan result is not on one of the channels in the Valid channel list, then it
4346 // must have come from an AP on an overlapping channel (in the 2.4GHz band). In this case,
4347 // let's drop the scan result.
4348 //
4349 // The other situation is where the scan request is for a scan on a particular channel set
4350 // and the scan result is from a
4351
4352 // if the NumChannels is 0, then we are supposed to be scanning all channels. Use the full channel
4353 // list as the 'valid' channel list. Otherwise, use the specific channel list in the scan parms
4354 // as the valid channels.
4355 if ( 0 == cChannels )
4356 {
4357 tANI_U32 len = sizeof(pMac->roam.validChannelList);
4358
4359 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
4360 {
4361 pChannelList = pMac->roam.validChannelList;
4362 cChannels = (tANI_U8)len;
4363 }
4364 else
4365 {
4366 //Cannot continue
4367 smsLog( pMac, LOGE, "CSR: Processing internal SCAN results...csrGetCfgValidChannels failed\n" );
4368 break;
4369 }
4370 }
4371
4372 smsLog( pMac, LOG2, "CSR: Processing internal SCAN results..." );
4373 cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription );
4374 pSirBssDescription = pScanRsp->bssDescription;
4375 while( cbParsed < pScanRsp->length )
4376 {
4377 if ( csrScanValidateScanResult( pMac, pChannelList, cChannels, pSirBssDescription, &pIes ) )
4378 {
4379 csrScanRemoveDupBssDescriptionFromInterimList(pMac, pSirBssDescription, pIes);
4380 csrScanSaveBssDescriptionToInterimList( pMac, pSirBssDescription, pIes );
4381 if( eSIR_PASSIVE_SCAN == pMac->scan.curScanType )
4382 {
4383 if( csrIs11dSupported( pMac) )
4384 {
4385 //Check whether the BSS is acceptable base on 11d info and our configs.
4386 if( csrMatchCountryCode( pMac, NULL, pIes ) )
4387 {
4388 //Double check whether the channel is acceptable by us.
4389 if( csrIsSupportedChannel( pMac, pSirBssDescription->channelId ) )
4390 {
4391 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
4392 }
4393 }
4394 }
4395 else
4396 {
4397 pMac->scan.curScanType = eSIR_ACTIVE_SCAN;
4398 }
4399 }
4400 //Free the resource
4401 palFreeMemory( pMac->hHdd, pIes );
4402 }
4403 // skip over the BSS description to the next one...
4404 cbBssDesc = pSirBssDescription->length + sizeof( pSirBssDescription->length );
4405
4406 cbParsed += cbBssDesc;
4407 pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + cbBssDesc );
4408
4409 } //while
4410 }
4411 else
4412 {
4413 smsLog( pMac, LOGW, " Scanrsp fail (0x%08X), length = %d\n", pScanRsp->statusCode, pScanRsp->length );
4414 //HO bg scan/probe failed no need to try autonomously
4415 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
4416 eCsrScanProbeBss == pCommand->u.scanCmd.reason ||
4417 eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason)
4418 {
4419 fRemoveCommand = eANI_BOOLEAN_TRUE;
4420 }
4421 }
4422 }while(0);
4423 if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
4424 {
4425 smsLog(pMac, LOG1, " Scan received %d unique BSS scan reason is %d\n", csrLLCount(&pMac->scan.tempScanResults), pCommand->u.scanCmd.reason);
4426 fRemoveCommand = csrScanComplete( pMac, pScanRsp );
4427 fRet = eANI_BOOLEAN_TRUE;
4428 }//if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode )
4429 if(pfRemoveCommand)
4430 {
4431 *pfRemoveCommand = fRemoveCommand;
4432 }
4433
4434#ifdef WLAN_AP_STA_CONCURRENCY
4435 if (!csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK ))
4436 {
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -07004437 VOS_ASSERT(pCommand->u.scanCmd.u.scanRequest.restTime != 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004438 palTimerStart(pMac->hHdd, pMac->scan.hTimerStaApConcTimer,
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -07004439 pCommand->u.scanCmd.u.scanRequest.restTime * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07004440 }
4441#endif
4442 return (fRet);
4443}
4444
4445
4446tANI_BOOLEAN csrScanIsWildCardScan( tpAniSirGlobal pMac, tSmeCmd *pCommand )
4447{
4448 tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
4449 tANI_BOOLEAN f = palEqualMemory( pMac->hHdd, pCommand->u.scanCmd.u.scanRequest.bssid,
4450 bssid, sizeof(tCsrBssid) );
4451
4452 //It is not a wild card scan if the bssid is not broadcast and the number of SSID is 1.
4453 return ((tANI_BOOLEAN)( (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid[0])) &&
4454 (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1) ));
4455}
4456
4457
4458eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf )
4459{
4460 eHalStatus status = eHAL_STATUS_SUCCESS;
4461 tListElem *pEntry;
4462 tSmeCmd *pCommand;
4463 eCsrScanStatus scanStatus;
4464 tSirSmeScanRsp *pScanRsp = (tSirSmeScanRsp *)pMsgBuf;
4465 tSmeGetScanChnRsp *pScanChnInfo;
4466 tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
4467 eCsrScanReason reason = eCsrScanOther;
4468
4469 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
4470
4471 if ( pEntry )
4472 {
4473 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
4474 if ( eSmeCommandScan == pCommand->command )
4475 {
4476 scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
4477 reason = pCommand->u.scanCmd.reason;
4478 switch(pCommand->u.scanCmd.reason)
4479 {
4480 case eCsrScanAbortBgScan:
4481 case eCsrScanAbortNormalScan:
4482 case eCsrScanBGScanAbort:
4483 case eCsrScanBGScanEnable:
4484 break;
4485 case eCsrScanGetScanChnInfo:
4486 pScanChnInfo = (tSmeGetScanChnRsp *)pMsgBuf;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004487 /*
4488 * status code not available in tSmeGetScanChnRsp, so
4489 * by default considereing it to be success
4490 */
4491 scanStatus = eSIR_SME_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004492 csrScanAgeResults(pMac, pScanChnInfo);
4493 break;
4494 case eCsrScanForCapsChange:
4495 csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand );
4496 break;
4497#if WLAN_FEATURE_P2P
4498 case eCsrScanP2PFindPeer:
4499 scanStatus = ((eSIR_SME_SUCCESS == pScanRsp->statusCode) && (pScanRsp->length > 50)) ? eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE;
4500 csrScanProcessScanResults( pMac, pCommand, pScanRsp, NULL );
4501 break;
4502#endif
4503 case eCsrScanSetBGScanParam:
4504 default:
4505 if(csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand ))
4506 {
4507 //Not to get channel info if the scan is not a wildcard scan because
4508 //it may cause scan results got aged out incorrectly.
4509 if( csrScanIsWildCardScan( pMac, pCommand ) && (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) )
4510 {
4511 //Get the list of channels scanned
Jeff Johnson32d95a32012-09-10 13:15:23 -07004512 if( pCommand->u.scanCmd.reason != eCsrScanUserRequest)
4513 {
4514 csrScanGetScanChnInfo(pMac, NULL, NULL);
4515 }
4516 else
4517 {
4518 csrScanGetScanChnInfo(pMac, pCommand->u.scanCmd.callback, pCommand->u.scanCmd.pContext);
4519 pCommand->u.scanCmd.callback = NULL;
4520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004521 }
4522 }
4523 break;
4524 }//switch
4525 if(fRemoveCommand)
4526 {
4527
4528 csrReleaseScanCommand(pMac, pCommand, scanStatus);
4529
4530 }
4531 smeProcessPendingQueue( pMac );
4532 }
4533 else
4534 {
4535 smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." );
4536 status = eHAL_STATUS_FAILURE;
4537 }
4538 }
4539 else
4540 {
4541 smsLog( pMac, LOGW, "CSR: Scan Completion called but NO commands are ACTIVE ..." );
4542 status = eHAL_STATUS_FAILURE;
4543 }
4544
4545 return (status);
4546}
4547
4548
4549
4550
4551tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
4552{
4553 tListElem *pEntry;
4554 tCsrScanResult *pResult;
4555 tCsrScanResultInfo *pRet = NULL;
4556 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4557
4558 if(pResultList)
4559 {
4560 csrLLLock(&pResultList->List);
4561 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
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
4575tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal pMac, tScanResultHandle hScanResult)
4576{
4577 tListElem *pEntry = NULL;
4578 tCsrScanResult *pResult = NULL;
4579 tCsrScanResultInfo *pRet = NULL;
4580 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4581
4582 if(pResultList)
4583 {
4584 csrLLLock(&pResultList->List);
4585 if(NULL == pResultList->pCurEntry)
4586 {
4587 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
4588 }
4589 else
4590 {
4591 pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
4592 }
4593 if(pEntry)
4594 {
4595 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
4596 pRet = &pResult->Result;
4597 }
4598 pResultList->pCurEntry = pEntry;
4599 csrLLUnlock(&pResultList->List);
4600 }
4601
4602 return pRet;
4603}
4604
4605
4606//This function moves the first BSS that matches the bssid to the head of the result
4607eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult)
4608{
4609 eHalStatus status = eHAL_STATUS_FAILURE;
4610 tScanResultList *pResultList = (tScanResultList *)hScanResult;
4611 tCsrScanResult *pResult = NULL;
4612 tListElem *pEntry = NULL;
4613
4614 if(pResultList && bssid)
4615 {
4616 csrLLLock(&pResultList->List);
4617 pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK);
4618 while(pEntry)
4619 {
4620 pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link);
4621 if(palEqualMemory(pMac->hHdd, bssid, pResult->Result.BssDescriptor.bssId, sizeof(tCsrBssid)))
4622 {
4623 status = eHAL_STATUS_SUCCESS;
4624 csrLLRemoveEntry(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
4625 csrLLInsertHead(&pResultList->List, pEntry, LL_ACCESS_NOLOCK);
4626 break;
4627 }
4628 pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK);
4629 }
4630 csrLLUnlock(&pResultList->List);
4631 }
4632
4633 return (status);
4634}
4635
4636
4637//Remove the BSS if possible.
4638//Return -- TRUE == the BSS is remove. False == Fail to remove it
4639//This function is called when list lock is held. Be caution what functions it can call.
4640tANI_BOOLEAN csrScanAgeOutBss(tpAniSirGlobal pMac, tCsrScanResult *pResult)
4641{
4642 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
4643 tANI_U32 i;
4644 tCsrRoamSession *pSession;
4645
4646 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
4647 {
4648 if( CSR_IS_SESSION_VALID( pMac, i ) )
4649 {
4650 pSession = CSR_GET_SESSION( pMac, i );
4651 //Not to remove the BSS we are connected to.
4652 if(csrIsConnStateDisconnected(pMac, i) || (NULL == pSession->pConnectBssDesc) ||
4653 (!csrIsDuplicateBssDescription(pMac, &pResult->Result.BssDescriptor,
4654 pSession->pConnectBssDesc, NULL))
4655 )
4656 {
Mohit Khanna23863762012-09-11 17:40:09 -07004657 smsLog(pMac, LOG2, "Aging out BSS %02X-%02X-%02X-%02X-%02X-%02X Channel %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004658 pResult->Result.BssDescriptor.bssId[0],
4659 pResult->Result.BssDescriptor.bssId[1],
4660 pResult->Result.BssDescriptor.bssId[2],
4661 pResult->Result.BssDescriptor.bssId[3],
4662 pResult->Result.BssDescriptor.bssId[4],
4663 pResult->Result.BssDescriptor.bssId[5],
4664 pResult->Result.BssDescriptor.channelId);
4665 //No need to hold the spin lock because caller should hold the lock for pMac->scan.scanResultList
4666 if( csrLLRemoveEntry(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_NOLOCK) )
4667 {
4668 csrFreeScanResultEntry(pMac, pResult);
Madan Mohan Koyyalamudi2e068bc2012-10-22 14:58:47 -07004669 fRet = eANI_BOOLEAN_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004670 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 break;
4672 }
4673 } //valid session
4674 } //for
Madan Mohan Koyyalamudi2e068bc2012-10-22 14:58:47 -07004675 if( CSR_ROAM_SESSION_MAX == i && fRet != eANI_BOOLEAN_TRUE )
Jeff Johnson295189b2012-06-20 16:38:30 -07004676 {
4677 //reset the counter so this won't hapeen too soon
4678 pResult->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount;
4679 pResult->Result.BssDescriptor.nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
4680 }
4681
4682 return (fRet);
4683}
4684
4685
4686eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo)
4687{
4688 eHalStatus status = eHAL_STATUS_SUCCESS;
4689 tListElem *pEntry, *tmpEntry;
4690 tCsrScanResult *pResult;
4691 tLimScanChn *pChnInfo;
4692 tANI_U8 i;
4693
4694 csrLLLock(&pMac->scan.scanResultList);
4695 for(i = 0; i < pScanChnInfo->numChn; i++)
4696 {
4697 pChnInfo = &pScanChnInfo->scanChn[i];
4698 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
4699 while( pEntry )
4700 {
4701 tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
4702 pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
4703 if(pResult->Result.BssDescriptor.channelId == pChnInfo->channelId)
4704 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 if(pResult->AgingCount <= 0)
4706 {
4707 smsLog(pMac, LOGW, " age out due to ref count");
4708 csrScanAgeOutBss(pMac, pResult);
4709 }
Madan Mohan Koyyalamudib9d3dcc2012-09-28 16:47:50 -07004710 else
4711 {
4712 pResult->AgingCount--;
4713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004714 }
4715 pEntry = tmpEntry;
4716 }
4717 }
4718 csrLLUnlock(&pMac->scan.scanResultList);
4719
4720 return (status);
4721}
4722
4723
4724eHalStatus csrSendMBScanReq( tpAniSirGlobal pMac, tANI_U16 sessionId,
4725 tCsrScanRequest *pScanReq, tScanReqParam *pScanReqParam )
4726{
4727 eHalStatus status = eHAL_STATUS_SUCCESS;
4728 tSirSmeScanReq *pMsg;
4729 tANI_U16 msgLen;
4730 tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0};
4731 tSirScanType scanType = pScanReq->scanType;
4732 tANI_U32 minChnTime; //in units of milliseconds
4733 tANI_U32 maxChnTime; //in units of milliseconds
4734 tANI_U32 i;
4735 tANI_U8 selfMacAddr[WNI_CFG_BSSID_LEN];
4736 tANI_U8 *pSelfMac = NULL;
4737
4738 msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) +
4739 ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) +
4740 ( pScanReq->uIEFieldLen ) ;
4741
4742 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
4743 if(HAL_STATUS_SUCCESS(status))
4744 {
4745 do
4746 {
4747 palZeroMemory(pMac->hHdd, pMsg, msgLen);
4748 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
4749 pMsg->length = pal_cpu_to_be16(msgLen);
4750 //ToDO: Fill in session info when we need to do scan base on session.
4751 pMsg->sessionId = 0;
4752 pMsg->transactionId = 0;
4753 pMsg->dot11mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
4754 pMsg->bssType = pal_cpu_to_be32(csrTranslateBsstypeToMacType(pScanReq->BSSType));
4755
4756 if ( CSR_IS_SESSION_VALID( pMac, sessionId ) )
4757 {
4758 pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[sessionId].selfMacAddr;
4759 }
4760 else
4761 {
4762 // Since we don't have session for the scanning, we find a valid session. In case we fail to
4763 // do so, get the WNI_CFG_STA_ID
4764 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
4765 {
4766 if( CSR_IS_SESSION_VALID( pMac, i ) )
4767 {
4768 pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[i].selfMacAddr;
4769 break;
4770 }
4771 }
4772 if( CSR_ROAM_SESSION_MAX == i )
4773 {
4774 tANI_U32 len = WNI_CFG_BSSID_LEN;
4775 pSelfMac = selfMacAddr;
4776 status = ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pSelfMac, &len );
4777 if( !HAL_STATUS_SUCCESS( status ) ||
4778 ( len < WNI_CFG_BSSID_LEN ) )
4779 {
4780 smsLog( pMac, LOGE, FL(" Can not get self MAC address from CFG status = %d"), status );
4781 //Force failed status
4782 status = eHAL_STATUS_FAILURE;
4783 break;
4784 }
4785 }
4786 }
4787 palCopyMemory( pMac->hHdd, (tANI_U8 *)pMsg->selfMacAddr, pSelfMac, sizeof(tSirMacAddr) );
4788
4789 //sirCopyMacAddr
4790 palCopyMemory( pMac->hHdd, (tANI_U8 *)pMsg->bssId, (tANI_U8 *)&pScanReq->bssid, sizeof(tSirMacAddr) );
4791 if( palEqualMemory( pMac->hHdd, pScanReq->bssid, bssid, sizeof(tCsrBssid) ) )
4792 {
4793 palFillMemory( pMac->hHdd, pMsg->bssId, sizeof(tSirMacAddr), 0xff );
4794 }
4795 else
4796 {
4797 palCopyMemory(pMac->hHdd, pMsg->bssId, pScanReq->bssid, WNI_CFG_BSSID_LEN);
4798 }
4799 minChnTime = pScanReq->minChnTime;
4800 maxChnTime = pScanReq->maxChnTime;
4801
4802 //Verify the scan type first, if the scan is active scan, we need to make sure we
4803 //are allowed to do so.
4804 /* if 11d is enabled & we don't see any beacon around, scan type falls
4805 back to passive. But in BT AMP STA mode we need to send out a
4806 directed probe*/
4807 if( (eSIR_PASSIVE_SCAN != scanType) && (eCSR_SCAN_P2P_DISCOVERY != pScanReq->requestType)
4808 && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType)
4809 && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d))
4810 {
4811 scanType = pMac->scan.curScanType;
4812 if(eSIR_PASSIVE_SCAN == pMac->scan.curScanType)
4813 {
4814 if(minChnTime < pMac->roam.configParam.nPassiveMinChnTime)
4815 {
4816 minChnTime = pMac->roam.configParam.nPassiveMinChnTime;
4817 }
4818 if(maxChnTime < pMac->roam.configParam.nPassiveMaxChnTime)
4819 {
4820 maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime;
4821 }
4822 }
4823 }
4824 pMsg->scanType = pal_cpu_to_be32(scanType);
4825
4826 pMsg->numSsid = (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ? pScanReq->SSIDs.numOfSSIDs :
4827 SIR_SCAN_MAX_NUM_SSID;
4828 if((pScanReq->SSIDs.numOfSSIDs != 0) && ( eSIR_PASSIVE_SCAN != scanType ))
4829 {
4830 for (i = 0; i < pMsg->numSsid; i++)
4831 {
4832 palCopyMemory(pMac->hHdd, &pMsg->ssId[i], &pScanReq->SSIDs.SSIDList[i].SSID, sizeof(tSirMacSSid));
4833 }
4834 }
4835 else
4836 {
4837 //Otherwise we scan all SSID and let the result filter later
4838 for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++)
4839 {
4840 pMsg->ssId[i].length = 0;
4841 }
4842 }
4843
4844//TODO: This preprocessor macro should be removed from CSR for production driver
4845//This is a temperarory fix for scanning on FPGA.
4846#if defined (ANI_CHIPSET_VIRGO) || defined (LIBRA_FPGA)|| defined (VOLANS_FPGA)
4847 pMsg->minChannelTime = pal_cpu_to_be32(minChnTime * 8);
4848 pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime * 8);
4849#elif defined (ANI_CHIPSET_TAURUS) || defined(ANI_CHIPSET_LIBRA) || defined(ANI_CHIPSET_VOLANS)
4850 pMsg->minChannelTime = pal_cpu_to_be32(minChnTime);
4851 pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime);
4852#else
4853#error unknown chipset
4854#endif
4855 //hidden SSID option
4856 pMsg->hiddenSsid = pScanReqParam->hiddenSsid;
4857 //rest time
4858 //pMsg->restTime = pScanReq->restTime;
4859 pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
4860 // All the scan results caching will be done by Roaming
4861 // We do not want LIM to do any caching of scan results,
4862 // so delete the LIM cache on all scan requests
4863 pMsg->returnFreshResults = pScanReqParam->freshScan;
4864 //Always ask for unique result
4865 pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
4866 pMsg->channelList.numChannels = (tANI_U8)pScanReq->ChannelInfo.numOfChannels;
4867 if(pScanReq->ChannelInfo.numOfChannels)
4868 {
4869 //Assuming the channelNumber is tANI_U8 (1 byte)
4870 status = palCopyMemory(pMac->hHdd, pMsg->channelList.channelNumber, pScanReq->ChannelInfo.ChannelList,
4871 pScanReq->ChannelInfo.numOfChannels);
4872 }
4873
4874 pMsg->uIEFieldLen = (tANI_U16) pScanReq->uIEFieldLen;
4875 pMsg->uIEFieldOffset = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) +
4876 ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) ;
4877 if(pScanReq->uIEFieldLen != 0)
4878 {
4879 palCopyMemory(pMac->hHdd, (tANI_U8 *)pMsg+pMsg->uIEFieldOffset,
4880 pScanReq->pIEField, pScanReq->uIEFieldLen );
4881 }
4882#ifdef WLAN_FEATURE_P2P
4883 pMsg->p2pSearch = pScanReq->p2pSearch;
Jeff Johnsone7245742012-09-05 17:12:55 -07004884 pMsg->skipDfsChnlInP2pSearch = pScanReq->skipDfsChnlInP2pSearch;
Jeff Johnson295189b2012-06-20 16:38:30 -07004885#endif
4886
Madan Mohan Koyyalamudi9b876782012-10-11 16:22:51 -07004887 if (pScanReq->requestType == eCSR_SCAN_HO_BG_SCAN)
4888 {
4889 pMsg->backgroundScanMode = eSIR_ROAMING_SCAN;
4890 }
4891
Jeff Johnson295189b2012-06-20 16:38:30 -07004892 }while(0);
4893 if(HAL_STATUS_SUCCESS(status))
4894 {
4895 status = palSendMBMessage(pMac->hHdd, pMsg);
4896 }
4897 else {
4898 palFreeMemory(pMac->hHdd, pMsg);
4899 }
4900 }//Success allocated memory
4901
4902
4903 return( status );
4904}
4905
4906eHalStatus csrSendMBScanResultReq( tpAniSirGlobal pMac, tScanReqParam *pScanReqParam )
4907{
4908 eHalStatus status = eHAL_STATUS_SUCCESS;
4909 tSirSmeScanReq *pMsg;
4910 tANI_U16 msgLen;
4911
4912 msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ));
4913 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
4914 if(HAL_STATUS_SUCCESS(status))
4915 {
4916 palZeroMemory(pMac->hHdd, pMsg, msgLen);
4917 pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ);
4918 pMsg->length = pal_cpu_to_be16(msgLen);
4919 pMsg->sessionId = 0;
4920 pMsg->returnFreshResults = pScanReqParam->freshScan;
4921 //Always ask for unique result
4922 pMsg->returnUniqueResults = pScanReqParam->fUniqueResult;
4923 pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch;
4924 status = palSendMBMessage(pMac->hHdd, pMsg);
4925 }
4926
4927 return( status );
4928}
4929
4930
4931
4932eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand )
4933{
4934 eHalStatus status = eHAL_STATUS_FAILURE;
4935 tScanReqParam scanReq;
4936
4937 do
4938 {
4939 scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE | TRUE;
4940 scanReq.fUniqueResult = TRUE;
4941 scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID;
4942 if(eCsrScanForSsid == pCommand->u.scanCmd.reason)
4943 {
4944 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_FIRST_MATCH;
4945 }
4946 else
4947 {
4948 // Basically do scan on all channels even for 11D 1st scan case.
4949 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
4950 }
4951 if((eCsrScanBgScan == pCommand->u.scanCmd.reason)||
4952 (eCsrScanProbeBss == pCommand->u.scanCmd.reason))
4953 {
4954 scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION;
4955 }
4956
4957#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4958 {
4959 vos_log_scan_pkt_type *pScanLog = NULL;
4960
4961 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
4962 if(pScanLog)
4963 {
4964 if(eCsrScanBgScan == pCommand->u.scanCmd.reason ||
4965 eCsrScanProbeBss == pCommand->u.scanCmd.reason)
4966 {
4967 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
4968 }
4969 else
4970 {
4971 if( (eSIR_PASSIVE_SCAN != pCommand->u.scanCmd.u.scanRequest.scanType) &&
4972 (eSIR_PASSIVE_SCAN != pMac->scan.curScanType) )
4973 {
4974 pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ;
4975 }
4976 else
4977 {
4978 pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ;
4979 }
4980 }
4981 pScanLog->minChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.minChnTime;
4982 pScanLog->maxChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.maxChnTime;
4983 pScanLog->numChannel = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
4984 if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
4985 {
4986 palCopyMemory(pMac->hHdd, pScanLog->channels,
4987 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
4988 pScanLog->numChannel);
4989 }
4990 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
4991 }
4992 }
4993#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
4994
4995
4996 status = csrSendMBScanReq(pMac, pCommand->sessionId,
4997 &pCommand->u.scanCmd.u.scanRequest, &scanReq);
4998 }while(0);
4999
5000 return( status );
5001}
5002
5003
5004eHalStatus csrScanRetrieveResult(tpAniSirGlobal pMac)
5005{
5006 eHalStatus status = eHAL_STATUS_FAILURE;
5007 tScanReqParam scanReq;
5008
5009 do
5010 {
5011 //not a fresh scan
5012 scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE;
5013 scanReq.fUniqueResult = TRUE;
5014 scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS;
5015 status = csrSendMBScanResultReq(pMac, &scanReq);
5016 }while(0);
5017
5018 return (status);
5019}
5020
5021
5022
5023eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand )
5024{
5025 eHalStatus status = eHAL_STATUS_SUCCESS;
5026 tCsrChannelInfo newChannelInfo = {0, NULL};
5027 int i, j;
5028 tANI_U8 *pChannel = NULL;
5029 tANI_U32 len = 0;
5030
5031 // Transition to Scanning state...
5032 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
5033 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005034 pCommand->u.scanCmd.lastRoamState[i] = csrRoamStateChange( pMac, eCSR_ROAMING_STATE_SCANNING, i);
5035 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 -07005036 }
5037
5038 switch(pCommand->u.scanCmd.reason)
5039 {
5040 case eCsrScanGetResult:
5041 case eCsrScanForCapsChange: //For cap change, LIM already save BSS description
5042 status = csrScanRetrieveResult(pMac);
5043 break;
5044 case eCsrScanSetBGScanParam:
5045 status = csrProcessSetBGScanParam(pMac, pCommand);
5046 break;
5047 case eCsrScanBGScanAbort:
5048 status = csrSetCfgBackgroundScanPeriod(pMac, 0);
5049 break;
5050 case eCsrScanBGScanEnable:
5051 status = csrSetCfgBackgroundScanPeriod(pMac, pMac->roam.configParam.bgScanInterval);
5052 break;
5053 case eCsrScanGetScanChnInfo:
5054 status = csrScanGetScanChannelInfo(pMac);
5055 break;
5056 case eCsrScanUserRequest:
5057 if(pMac->roam.configParam.fScanTwice)
5058 {
5059 //We scan 2.4 channel twice
5060 if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels &&
5061 (NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList))
5062 {
5063 len = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
5064 //allocate twice the channel
5065 newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(newChannelInfo.numOfChannels * 2);
5066 pChannel = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList;
5067 }
5068 else
5069 {
5070 //get the valid channel list to scan all.
5071 len = sizeof(pMac->roam.validChannelList);
5072
5073 if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len)))
5074 {
5075 //allocate twice the channel
5076 newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2);
5077 pChannel = pMac->roam.validChannelList;
5078 }
5079 }
5080 if(NULL == newChannelInfo.ChannelList)
5081 {
5082 newChannelInfo.numOfChannels = 0;
5083 }
5084 else
5085 {
5086 j = 0;
5087 for(i = 0; i < len; i++)
5088 {
5089 newChannelInfo.ChannelList[j++] = pChannel[i];
5090 if(CSR_MAX_24GHz_CHANNEL_NUMBER >= pChannel[i])
5091 {
5092 newChannelInfo.ChannelList[j++] = pChannel[i];
5093 }
5094 }
5095 if(NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)
5096 {
5097 //pChannel points to the channellist from the command, free it.
5098 vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList);
5099 }
5100 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j;
5101 pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = newChannelInfo.ChannelList;
5102 }
5103 } //if(pMac->roam.configParam.fScanTwice)
5104
5105 status = csrScanChannels(pMac, pCommand);
5106
5107 break;
5108 default:
5109 status = csrScanChannels(pMac, pCommand);
5110 break;
5111 }
5112
5113 if(!HAL_STATUS_SUCCESS(status))
5114 {
5115 csrReleaseScanCommand(pMac, pCommand, eCSR_SCAN_FAILURE);
5116 }
5117
5118 return (status);
5119}
5120
5121
5122eHalStatus csrScanSetBGScanparams(tpAniSirGlobal pMac, tCsrBGScanRequest *pScanReq)
5123{
5124 eHalStatus status = eHAL_STATUS_SUCCESS;
5125 tSmeCmd *pCommand = NULL;
5126
5127 if(pScanReq)
5128 {
5129 do
5130 {
5131 pCommand = csrGetCommandBuffer(pMac);
5132 if(!pCommand)
5133 {
5134 status = eHAL_STATUS_RESOURCES;
5135 break;
5136 }
5137 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5138 pCommand->command = eSmeCommandScan;
5139 pCommand->u.scanCmd.reason = eCsrScanSetBGScanParam;
5140 pCommand->u.scanCmd.callback = NULL;
5141 pCommand->u.scanCmd.pContext = NULL;
5142 palCopyMemory(pMac->hHdd, &pCommand->u.scanCmd.u.bgScanRequest, pScanReq, sizeof(tCsrBGScanRequest));
5143 //we have to do the follow
5144 if(pScanReq->ChannelInfo.numOfChannels == 0)
5145 {
5146 pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL;
5147 }
5148 else
5149 {
5150 status = palAllocateMemory(pMac->hHdd, (void **)&pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList,
5151 pScanReq->ChannelInfo.numOfChannels);
5152 if(HAL_STATUS_SUCCESS(status))
5153 {
5154 palCopyMemory(pMac->hHdd, pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList,
5155 pScanReq->ChannelInfo.ChannelList, pScanReq->ChannelInfo.numOfChannels);
5156 }
5157 else
5158 {
5159 smsLog(pMac, LOGE, FL("ran out of memory\n"));
5160 csrReleaseCommandScan(pMac, pCommand);
5161 break;
5162 }
5163 }
5164
5165 //scan req for SSID
5166 if(pScanReq->SSID.length)
5167 {
5168 palCopyMemory(pMac->hHdd,
5169 pCommand->u.scanCmd.u.bgScanRequest.SSID.ssId,
5170 pScanReq->SSID.ssId,
5171 pScanReq->SSID.length);
5172 pCommand->u.scanCmd.u.bgScanRequest.SSID.length = pScanReq->SSID.length;
5173
5174 }
5175 pCommand->u.scanCmd.u.bgScanRequest.maxChnTime= pScanReq->maxChnTime;
5176 pCommand->u.scanCmd.u.bgScanRequest.minChnTime = pScanReq->minChnTime;
5177 pCommand->u.scanCmd.u.bgScanRequest.scanInterval = pScanReq->scanInterval;
5178
5179
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
5190 return (status);
5191}
5192
5193eHalStatus csrScanBGScanAbort( tpAniSirGlobal pMac )
5194{
5195 eHalStatus status = eHAL_STATUS_SUCCESS;
5196 tSmeCmd *pCommand = NULL;
5197
5198 do
5199 {
5200 pCommand = csrGetCommandBuffer(pMac);
5201 if(!pCommand)
5202 {
5203 status = eHAL_STATUS_RESOURCES;
5204 break;
5205 }
5206 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5207 pCommand->command = eSmeCommandScan;
5208 pCommand->u.scanCmd.reason = eCsrScanBGScanAbort;
5209 pCommand->u.scanCmd.callback = NULL;
5210 pCommand->u.scanCmd.pContext = NULL;
5211 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
5212 if( !HAL_STATUS_SUCCESS( status ) )
5213 {
5214 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
5215 csrReleaseCommandScan( pMac, pCommand );
5216 break;
5217 }
5218 }while(0);
5219
5220 return (status);
5221}
5222
5223
5224//This will enable the background scan with the non-zero interval
5225eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac)
5226{
5227 eHalStatus status = eHAL_STATUS_SUCCESS;
5228 tSmeCmd *pCommand = NULL;
5229
5230 if(pMac->roam.configParam.bgScanInterval)
5231 {
5232 do
5233 {
5234 pCommand = csrGetCommandBuffer(pMac);
5235 if(!pCommand)
5236 {
5237 status = eHAL_STATUS_RESOURCES;
5238 break;
5239 }
5240 palZeroMemory(pMac->hHdd, &pCommand->u.scanCmd, sizeof(tScanCmd));
5241 pCommand->command = eSmeCommandScan;
5242 pCommand->u.scanCmd.reason = eCsrScanBGScanEnable;
5243 pCommand->u.scanCmd.callback = NULL;
5244 pCommand->u.scanCmd.pContext = NULL;
5245 status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE);
5246 if( !HAL_STATUS_SUCCESS( status ) )
5247 {
5248 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
5249 csrReleaseCommandScan( pMac, pCommand );
5250 break;
5251 }
5252 }while(0);
5253 //BG scan results are reported automatically by PE to SME once the scan is done.
5254 //No need to fetch the results explicitly.
5255 //csrScanStartGetResultTimer(pMac);
5256 csrScanStartResultAgingTimer(pMac);
5257 }
5258 else
5259 {
5260 //We don't have BG scan so stop the aging timer
5261 csrScanStopResultAgingTimer(pMac);
5262 smsLog(pMac, LOGE, FL("cannot continue because the bgscan interval is 0\n"));
5263 status = eHAL_STATUS_INVALID_PARAMETER;
5264 }
5265
5266 return (status);
5267}
5268
5269
5270eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq)
5271{
5272 eHalStatus status = eHAL_STATUS_SUCCESS;
5273 tANI_U32 len = sizeof(pMac->roam.validChannelList);
5274 tANI_U32 index = 0;
5275 tANI_U32 new_index = 0;
5276
5277 do
5278 {
5279 status = csrScanFreeRequest(pMac, pDstReq);
5280 if(HAL_STATUS_SUCCESS(status))
5281 {
5282 status = palCopyMemory(pMac->hHdd, pDstReq, pSrcReq, sizeof(tCsrScanRequest));
5283 if(pSrcReq->uIEFieldLen == 0)
5284 {
5285 pDstReq->pIEField = NULL;
5286 }
5287 else
5288 {
5289 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->pIEField, pSrcReq->uIEFieldLen);
5290 if(HAL_STATUS_SUCCESS(status))
5291 {
5292 palCopyMemory(pMac->hHdd, pDstReq->pIEField, pSrcReq->pIEField, pSrcReq->uIEFieldLen);
5293 pDstReq->uIEFieldLen = pSrcReq->uIEFieldLen;
5294 }
5295 else
5296 {
5297 smsLog(pMac, LOGE, "No memory for scanning IE fields\n");
5298 break;
5299 }
5300 }//Allocate memory for IE field
5301 {
5302 if(pSrcReq->ChannelInfo.numOfChannels == 0)
5303 {
5304 pDstReq->ChannelInfo.ChannelList = NULL;
5305 pDstReq->ChannelInfo.numOfChannels = 0;
5306 }
5307 else
5308 {
5309 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->ChannelInfo.ChannelList,
5310 pSrcReq->ChannelInfo.numOfChannels * sizeof(*pDstReq->ChannelInfo.ChannelList));
5311 if(!HAL_STATUS_SUCCESS(status))
5312 {
5313 pDstReq->ChannelInfo.numOfChannels = 0;
5314 smsLog(pMac, LOGE, "No memory for scanning Channel List\n");
5315 break;
5316 }
5317
5318 if((pSrcReq->scanType == eSIR_PASSIVE_SCAN) && (pSrcReq->requestType == eCSR_SCAN_REQUEST_11D_SCAN))
5319 {
5320 for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
5321 {
5322 pDstReq->ChannelInfo.ChannelList[new_index] =
5323 pSrcReq->ChannelInfo.ChannelList[index];
5324 new_index++;
5325 }
5326 pDstReq->ChannelInfo.numOfChannels = new_index;
5327 }
5328 else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
5329 {
5330 new_index = 0;
5331 pMac->roam.numValidChannels = len;
5332 for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
5333 {
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -07005334 /* Allow scan on valid channels only.
5335 * If it is p2p scan and valid channel list doesnt contain
5336 * social channels, enforce scan on social channels because
5337 * that is the only way to find p2p peers.
5338 * This can happen only if band is set to 5Ghz mode.
5339 */
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -07005340 if((csrRoamIsValidChannel(pMac, pSrcReq->ChannelInfo.ChannelList[index])) ||
Madan Mohan Koyyalamudi783b2362012-10-21 11:54:41 -07005341 ((eCSR_SCAN_P2P_DISCOVERY == pSrcReq->requestType) &&
5342 CSR_IS_SOCIAL_CHANNEL(pSrcReq->ChannelInfo.ChannelList[index])))
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 {
5344 pDstReq->ChannelInfo.ChannelList[new_index] =
5345 pSrcReq->ChannelInfo.ChannelList[index];
5346 new_index++;
5347 }
5348 }
5349 pDstReq->ChannelInfo.numOfChannels = new_index;
5350 }
5351 else
5352 {
5353 smsLog(pMac, LOGE, "Couldn't get the valid Channel List, keeping requester's list\n");
5354 palCopyMemory(pMac->hHdd, pDstReq->ChannelInfo.ChannelList, pSrcReq->ChannelInfo.ChannelList,
5355 pSrcReq->ChannelInfo.numOfChannels * sizeof(*pDstReq->ChannelInfo.ChannelList));
5356 pDstReq->ChannelInfo.numOfChannels = pSrcReq->ChannelInfo.numOfChannels;
5357 }
5358 }//Allocate memory for Channel List
5359 }
5360 if(pSrcReq->SSIDs.numOfSSIDs == 0)
5361 {
5362 pDstReq->SSIDs.numOfSSIDs = 0;
5363 pDstReq->SSIDs.SSIDList = NULL;
5364 }
5365 else
5366 {
5367 status = palAllocateMemory(pMac->hHdd, (void **)&pDstReq->SSIDs.SSIDList,
5368 pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
5369 if(HAL_STATUS_SUCCESS(status))
5370 {
5371 pDstReq->SSIDs.numOfSSIDs = pSrcReq->SSIDs.numOfSSIDs;
5372 palCopyMemory(pMac->hHdd, pDstReq->SSIDs.SSIDList, pSrcReq->SSIDs.SSIDList,
5373 pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList));
5374 }
5375 else
5376 {
5377 pDstReq->SSIDs.numOfSSIDs = 0;
5378 smsLog(pMac, LOGE, "No memory for scanning SSID List\n");
5379 break;
5380 }
5381 }//Allocate memory for SSID List
5382#ifdef WLAN_FEATURE_P2P
5383 pDstReq->p2pSearch = pSrcReq->p2pSearch;
Jeff Johnsone7245742012-09-05 17:12:55 -07005384 pDstReq->skipDfsChnlInP2pSearch = pSrcReq->skipDfsChnlInP2pSearch;
Jeff Johnson295189b2012-06-20 16:38:30 -07005385#endif
5386
5387 }
5388 }while(0);
5389
5390 if(!HAL_STATUS_SUCCESS(status))
5391 {
5392 csrScanFreeRequest(pMac, pDstReq);
5393 }
5394
5395 return (status);
5396}
5397
5398
5399eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq)
5400{
5401 eHalStatus status = eHAL_STATUS_SUCCESS;
5402
5403 if(pReq->ChannelInfo.ChannelList)
5404 {
5405 status = palFreeMemory(pMac->hHdd, pReq->ChannelInfo.ChannelList);
5406 pReq->ChannelInfo.ChannelList = NULL;
5407 }
5408 pReq->ChannelInfo.numOfChannels = 0;
5409 if(pReq->pIEField)
5410 {
5411 status = palFreeMemory(pMac->hHdd, pReq->pIEField);
5412 pReq->pIEField = NULL;
5413 }
5414 pReq->uIEFieldLen = 0;
5415 if(pReq->SSIDs.SSIDList)
5416 {
5417 palFreeMemory(pMac->hHdd, pReq->SSIDs.SSIDList);
5418 pReq->SSIDs.SSIDList = NULL;
5419 }
5420 pReq->SSIDs.numOfSSIDs = 0;
5421
5422 return (status);
5423}
5424
5425
5426void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
5427{
5428 if(pCommand->u.scanCmd.callback)
5429 {
5430// sme_ReleaseGlobalLock( &pMac->sme );
5431 pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, pCommand->u.scanCmd.scanID, scanStatus);
5432// sme_AcquireGlobalLock( &pMac->sme );
5433 } else {
Mohit Khanna23863762012-09-11 17:40:09 -07005434 smsLog( pMac, LOG2, "%s:%d - Callback NULL!!!\n", __FUNCTION__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 }
5436}
5437
5438
5439void csrScanStopTimers(tpAniSirGlobal pMac)
5440{
5441 csrScanStopResultAgingTimer(pMac);
5442 csrScanStopIdleScanTimer(pMac);
5443 csrScanStopGetResultTimer(pMac);
5444}
5445
5446
5447eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac)
5448{
5449 eHalStatus status;
5450
5451 if(pMac->scan.fScanEnable)
5452 {
5453 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL, eANI_BOOLEAN_TRUE);
5454 }
5455 else
5456 {
5457 status = eHAL_STATUS_FAILURE;
5458 }
5459
5460 return (status);
5461}
5462
5463
5464eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac)
5465{
5466 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerGetResult));
5467}
5468
5469
5470void csrScanGetResultTimerHandler(void *pv)
5471{
5472 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5473
5474 csrScanRequestResult(pMac);
5475}
5476
5477#ifdef WLAN_AP_STA_CONCURRENCY
5478static void csrStaApConcTimerHandler(void *pv)
5479{
5480 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5481 tListElem *pEntry;
5482 tSmeCmd *pScanCmd;
5483
5484 csrLLLock(&pMac->scan.scanCmdPendingList);
5485
5486 if ( NULL != ( pEntry = csrLLPeekHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) )
5487 {
5488 tCsrScanRequest scanReq;
5489 tSmeCmd *pSendScanCmd = NULL;
5490 tANI_U8 numChn = 0;
5491 tANI_U8 i;
5492 tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
5493 tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5494 eHalStatus status;
5495
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 pScanCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
5497 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
5498 if (numChn > 1)
5499 {
5500 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
5501
5502 pSendScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
5503 if (!pSendScanCmd)
5504 {
5505 smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer\n") );
5506 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5507 return;
5508 }
5509 pSendScanCmd->command = pScanCmd->command;
5510 pSendScanCmd->sessionId = pScanCmd->sessionId;
5511 pSendScanCmd->u.scanCmd.callback = NULL;
5512 pSendScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
5513 pSendScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
5514 pSendScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
5515
Madan Mohan Koyyalamudiaf2a8b92012-10-09 14:58:07 -07005516 /* First copy all the parameters to local variable of scan request */
5517 csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
5518
5519 /* Now modify the elements of local var scan request required to be modified for split scan */
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 pChnInfo->numOfChannels = 1;
5521 palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0],
5522 1 * sizeof(tANI_U8)); //just send one channel
5523 pChnInfo->ChannelList = &channelToScan[0];
5524
Madan Mohan Koyyalamudiaf2a8b92012-10-09 14:58:07 -07005525 for (i = 0; i <= (numChn-2); i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 {
5527 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] =
5528 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i+1]; //Move all the channels one step
5529 }
5530
5531 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn -1; //reduce outstanding # of channels to be scanned
5532
5533 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
5534 //Modify callers parameters in case of concurrency
5535 scanReq.scanType = eSIR_ACTIVE_SCAN;
Madan Mohan Koyyalamudi4ff9cd62012-10-30 17:48:57 -07005536 //Use concurrency values for min/maxChnTime.
5537 //We know csrIsAnySessionConnected(pMac) returns TRUE here
5538 csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
5540 status = csrScanCopyRequest(pMac, &pSendScanCmd->u.scanCmd.u.scanRequest, &scanReq);
5541 if(!HAL_STATUS_SUCCESS(status))
5542 {
5543 smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d\n"), status );
5544 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5545 return;
5546 }
5547 }
5548 else
5549 { //numChn ==1 This is the last channel to be scanned
5550 //last channel remaining to scan
5551 pSendScanCmd = pScanCmd;
5552 //remove this command from pending list
5553 if (csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) == NULL)
5554 { //In case between PeekHead and here, the entry got removed by another thread.
5555 smsLog( pMac, LOGE, FL(" Failed to remove entry from scanCmdPendingList\n"));
5556 }
5557
5558 }
5559 csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);
5560
5561 }
5562
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 csrLLUnlock(&pMac->scan.scanCmdPendingList);
5564
5565}
5566#endif
5567
5568eHalStatus csrScanStartResultAgingTimer(tpAniSirGlobal pMac)
5569{
5570 eHalStatus status;
5571
5572 if(pMac->scan.fScanEnable)
5573 {
5574 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerResultAging, CSR_SCAN_RESULT_AGING_INTERVAL, eANI_BOOLEAN_TRUE);
5575 }
5576 else
5577 {
5578 status = eHAL_STATUS_FAILURE;
5579 }
5580
5581 return (status);
5582}
5583
5584
5585eHalStatus csrScanStopResultAgingTimer(tpAniSirGlobal pMac)
5586{
5587 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerResultAging));
5588}
5589
5590
5591//This function returns the maximum time a BSS is allowed in the scan result.
5592//The time varies base on connection and power saving factors.
5593//Not connected, No PS
5594//Not connected, with PS
5595//Connected w/o traffic, No PS
5596//Connected w/o traffic, with PS
5597//Connected w/ traffic, no PS -- Not supported
5598//Connected w/ traffic, with PS -- Not supported
5599//the return unit is in seconds.
5600tANI_U32 csrScanGetAgeOutTime(tpAniSirGlobal pMac)
5601{
5602 tANI_U32 nRet;
5603
5604 if(pMac->scan.nAgingCountDown)
5605 {
5606 //Calculate what should be the timeout value for this
5607 nRet = pMac->scan.nLastAgeTimeOut * pMac->scan.nAgingCountDown;
5608 pMac->scan.nAgingCountDown--;
5609 }
5610 else
5611 {
5612 if( csrIsAllSessionDisconnected( pMac ) )
5613 {
5614 if(pmcIsPowerSaveEnabled(pMac, ePMC_IDLE_MODE_POWER_SAVE))
5615 {
5616 nRet = pMac->roam.configParam.scanAgeTimeNCPS;
5617 }
5618 else
5619 {
5620 nRet = pMac->roam.configParam.scanAgeTimeNCNPS;
5621 }
5622 }
5623 else
5624 {
5625 if(pmcIsPowerSaveEnabled(pMac, ePMC_BEACON_MODE_POWER_SAVE))
5626 {
5627 nRet = pMac->roam.configParam.scanAgeTimeCPS;
5628 }
5629 else
5630 {
5631 nRet = pMac->roam.configParam.scanAgeTimeCNPS;
5632 }
5633 }
5634 //If state-change causing aging time out change, we want to delay it somewhat to avoid
5635 //unnecessary removal of BSS. This is mostly due to transition from connect to disconnect.
5636 if(pMac->scan.nLastAgeTimeOut > nRet)
5637 {
5638 if(nRet)
5639 {
5640 pMac->scan.nAgingCountDown = (pMac->scan.nLastAgeTimeOut / nRet);
5641 }
5642 pMac->scan.nLastAgeTimeOut = nRet;
5643 nRet *= pMac->scan.nAgingCountDown;
5644 }
5645 else
5646 {
5647 pMac->scan.nLastAgeTimeOut = nRet;
5648 }
5649 }
5650
5651 return (nRet);
5652}
5653
5654
5655void csrScanResultAgingTimerHandler(void *pv)
5656{
5657 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5658 tANI_BOOLEAN fDisconnected = csrIsAllSessionDisconnected(pMac);
5659
5660 //no scan, no aging
5661 if(pMac->scan.fScanEnable &&
5662 (((eANI_BOOLEAN_FALSE == fDisconnected) && pMac->roam.configParam.bgScanInterval)
5663 || (fDisconnected && (pMac->scan.fCancelIdleScan == eANI_BOOLEAN_FALSE)))
5664 )
5665 {
5666 tListElem *pEntry, *tmpEntry;
5667 tCsrScanResult *pResult;
5668 tANI_TIMESTAMP ageOutTime = (tANI_TIMESTAMP)(csrScanGetAgeOutTime(pMac) * PAL_TICKS_PER_SECOND); //turn it into 10ms units
5669 tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
5670
5671 csrLLLock(&pMac->scan.scanResultList);
5672 pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK );
5673 while( pEntry )
5674 {
5675 tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK);
5676 pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
5677 if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime)
5678 {
5679 smsLog(pMac, LOGW, " age out due to time out");
5680 csrScanAgeOutBss(pMac, pResult);
5681 }
5682 pEntry = tmpEntry;
5683 }
5684 csrLLUnlock(&pMac->scan.scanResultList);
5685 }
5686}
5687
5688
5689eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval)
5690{
5691 eHalStatus status;
5692
5693 smsLog(pMac, LOG1, " csrScanStartIdleScanTimer \n ");
5694 if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) && interval)
5695 {
5696 pMac->scan.nIdleScanTimeGap += interval;
5697 palTimerStop(pMac->hHdd, pMac->scan.hTimerIdleScan);
5698 status = palTimerStart(pMac->hHdd, pMac->scan.hTimerIdleScan, interval, eANI_BOOLEAN_FALSE);
5699 if( !HAL_STATUS_SUCCESS(status) )
5700 {
5701 smsLog(pMac, LOGE, " Fail to start Idle scan timer. status = %d interval = %d\n", status, interval);
5702 //This should not happen but set the flag to restart when ready
5703 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5704 }
5705 }
5706 else
5707 {
5708 if( pMac->scan.fScanEnable && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) )
5709 {
5710 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5711 }
5712 status = eHAL_STATUS_FAILURE;
5713 }
5714
5715 return (status);
5716}
5717
5718
5719eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac)
5720{
5721 return (palTimerStop(pMac->hHdd, pMac->scan.hTimerIdleScan));
5722}
5723
5724
5725//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR
5726void csrScanSuspendIMPS( tpAniSirGlobal pMac )
5727{
5728 csrScanCancelIdleScan(pMac);
5729}
5730
5731
5732//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS
5733//because IMPS maybe disabled.
5734void csrScanResumeIMPS( tpAniSirGlobal pMac )
5735{
5736 csrScanStartIdleScan( pMac );
5737}
5738
5739
5740void csrScanIMPSCallback(void *callbackContext, eHalStatus status)
5741{
5742 tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext );
5743
5744 if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5745 {
5746 if(pMac->roam.configParam.IsIdleScanEnabled)
5747 {
5748 if(HAL_STATUS_SUCCESS(status))
5749 {
5750 if(csrIsAllSessionDisconnected(pMac) && !csrIsRoamCommandWaiting(pMac))
5751 {
5752 smsLog(pMac, LOGW, FL("starts idle mode full scan\n"));
5753 csrScanAllChannels(pMac, eCSR_SCAN_IDLE_MODE_SCAN);
5754 }
5755 else
5756 {
5757 smsLog(pMac, LOGW, FL("cannot start idle mode full scan\n"));
5758 //even though we are in timer handle, calling stop timer will make sure the timer
5759 //doesn't get to restart.
5760 csrScanStopIdleScanTimer(pMac);
5761 }
5762 }
5763 else
5764 {
5765 smsLog(pMac, LOGE, FL("sees not success status (%d)\n"), status);
5766 }
5767 }
5768 else
5769 {//we might need another flag to check if CSR needs to request imps at all
5770
5771 tANI_U32 nTime = 0;
5772
5773 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE;
5774 if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime)))
5775 {
5776 csrScanStartIdleScanTimer(pMac, nTime);
5777 }
5778 }
5779 }
5780}
5781
5782
5783//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for
5784//idle scan timer interval
5785//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan
5786eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval)
5787{
5788 eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;
5789
5790 //Do not trigger IMPS in case of concurrency
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005791 if (vos_concurrent_sessions_running() && csrIsAnySessionInConnectState(pMac))
5792 {
Mohit Khanna23863762012-09-11 17:40:09 -07005793 smsLog( pMac, LOG1, FL("Cannot request IMPS because Concurrent Sessions Running\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07005794 return (status);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005796
5797 if(pTimeInterval)
5798 {
5799 *pTimeInterval = 0;
5800 }
5801
Mohit Khanna23863762012-09-11 17:40:09 -07005802 smsLog(pMac, LOG3, FL("called\n"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 if( smeCommandPending( pMac ) )
5804 {
Mohit Khanna23863762012-09-11 17:40:09 -07005805 smsLog( pMac, LOG1, FL(" Cannot request IMPS because command pending\n") );
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 //Not to enter IMPS because more work to do
5807 if(pTimeInterval)
5808 {
5809 *pTimeInterval = 0;
5810 }
5811 //restart when ready
5812 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5813
5814 return (status);
5815 }
5816
5817 if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5818 /*&& pMac->roam.configParam.impsSleepTime*/)
5819 {
5820 //Stop get result timer because idle scan gets scan result out of PE
5821 csrScanStopGetResultTimer(pMac);
5822 if(pTimeInterval)
5823 {
5824 *pTimeInterval = pMac->roam.configParam.impsSleepTime;
5825 }
5826 //pmcRequestImps take a period in millisecond unit.
5827 status = pmcRequestImps(pMac, pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_MS_UNIT, csrScanIMPSCallback, pMac);
5828 if(!HAL_STATUS_SUCCESS(status))
5829 {
5830 if(eHAL_STATUS_PMC_ALREADY_IN_IMPS != status)
5831 {
5832 //Do restart the timer if CSR thinks it cannot do IMPS
5833 if( !csrCheckPSReady( pMac ) )
5834 {
5835 if(pTimeInterval)
5836 {
5837 *pTimeInterval = 0;
5838 }
5839 //Set the restart flag to true because that idle scan
5840 //can be restarted even though the timer will not be running
5841 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5842 }
5843 else
5844 {
5845 //For not now, we do a quicker retry
5846 if(pTimeInterval)
5847 {
5848 *pTimeInterval = CSR_IDLE_SCAN_WAIT_TIME;
5849 }
5850 }
5851 smsLog(pMac, LOGW, FL("call pmcRequestImps and it returns status code (%d)\n"), status);
5852 }
5853 else
5854 {
5855 smsLog(pMac, LOGW, FL("already in IMPS\n"));
5856 //Since CSR is the only module to request for IMPS. If it is already in IMPS, CSR assumes
5857 //the callback will be called in the future. Should not happen though.
5858 status = eHAL_STATUS_SUCCESS;
5859 pMac->scan.nIdleScanTimeGap = 0;
5860 }
5861 }
5862 else
5863 {
5864 //requested so let's reset the value
5865 pMac->scan.nIdleScanTimeGap = 0;
5866 }
5867 }
5868
5869 return (status);
5870}
5871
5872
5873eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac)
5874{
5875 eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE;
5876 tANI_U32 nTime = 0;
5877
5878 smsLog(pMac, LOGW, FL("called\n"));
5879 if(pMac->roam.configParam.IsIdleScanEnabled)
5880 {
5881 //stop bg scan first
5882 csrScanBGScanAbort(pMac);
5883 //Stop get result timer because idle scan gets scan result out of PE
5884 csrScanStopGetResultTimer(pMac);
5885 //Enable aging timer since idle scan is going on
5886 csrScanStartResultAgingTimer(pMac);
5887 }
5888 pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE;
5889 status = csrScanTriggerIdleScan(pMac, &nTime);
5890 if(!HAL_STATUS_SUCCESS(status))
5891 {
5892 csrScanStartIdleScanTimer(pMac, nTime);
5893 }
5894
5895 return (status);
5896}
5897
5898
5899void csrScanCancelIdleScan(tpAniSirGlobal pMac)
5900{
5901 if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)
5902 {
5903#ifdef WLAN_SOFTAP_FEATURE
5904 if (vos_concurrent_sessions_running()) {
5905 return;
5906 }
5907#endif
5908 smsLog(pMac, LOG1, " csrScanCancelIdleScan\n");
5909 pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE;
5910 //Set the restart flag in case later on it is uncancelled
5911 pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE;
5912 csrScanStopIdleScanTimer(pMac);
5913 csrScanRemoveNotRoamingScanCommand(pMac);
5914 }
5915}
5916
5917
5918void csrScanIdleScanTimerHandler(void *pv)
5919{
5920 tpAniSirGlobal pMac = PMAC_STRUCT( pv );
5921 eHalStatus status;
5922 tANI_U32 nTime = 0;
5923
5924 smsLog(pMac, LOGW, " csrScanIdleScanTimerHandler called ");
5925 status = csrScanTriggerIdleScan(pMac, &nTime);
5926 if(!HAL_STATUS_SUCCESS(status) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan))
5927 {
5928 //Check whether it is time to actually do an idle scan
5929 if(pMac->scan.nIdleScanTimeGap >= pMac->roam.configParam.impsSleepTime)
5930 {
5931 pMac->scan.nIdleScanTimeGap = 0;
5932 csrScanIMPSCallback(pMac, eHAL_STATUS_SUCCESS);
5933 }
5934 else
5935 {
5936 csrScanStartIdleScanTimer(pMac, nTime);
5937 }
5938 }
5939}
5940
5941
5942
5943
5944tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac)
5945{
5946 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
5947 tListElem *pEntry, *pEntryTmp;
5948 tSmeCmd *pCommand;
5949 tDblLinkList localList;
5950
5951 vos_mem_zero(&localList, sizeof(tDblLinkList));
5952 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
5953 {
5954 smsLog(pMac, LOGE, FL(" failed to open list"));
5955 return fRet;
5956 }
5957
5958 csrLLLock(&pMac->sme.smeCmdPendingList);
5959 pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
5960 while(pEntry)
5961 {
5962 pEntryTmp = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK);
5963 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
5964 if( eSmeCommandScan == pCommand->command )
5965 {
5966 switch( pCommand->u.scanCmd.reason )
5967 {
5968 case eCsrScanIdleScan:
5969 if( csrLLRemoveEntry(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK) )
5970 {
5971 csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
5972 }
5973 fRet = eANI_BOOLEAN_TRUE;
5974 break;
5975
5976 default:
5977 break;
5978 } //switch
5979 }
5980 pEntry = pEntryTmp;
5981 }
5982
5983 csrLLUnlock(&pMac->sme.smeCmdPendingList);
5984
5985 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
5986 {
5987 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
5988 csrReleaseCommandScan( pMac, pCommand );
5989 }
5990
5991 csrLLClose(&localList);
5992
5993 return (fRet);
5994}
5995
5996
5997tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId)
5998{
5999 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
6000 tListElem *pEntry, *pEntryTmp;
6001 tSmeCmd *pCommand;
6002 tDblLinkList localList;
6003
6004 vos_mem_zero(&localList, sizeof(tDblLinkList));
6005 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
6006 {
6007 smsLog(pMac, LOGE, FL(" failed to open list"));
6008 return fRet;
6009 }
6010
6011 csrLLLock(&pMac->sme.smeCmdPendingList);
6012 pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK);
6013 while(pEntry)
6014 {
6015 pEntryTmp = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK);
6016 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6017 if( (eSmeCommandScan == pCommand->command) && (sessionId == pCommand->sessionId) )
6018 {
6019 switch(pCommand->u.scanCmd.reason)
6020 {
6021 case eCsrScanGetResult:
6022 case eCsrScanSetBGScanParam:
6023 case eCsrScanBGScanAbort:
6024 case eCsrScanBGScanEnable:
6025 case eCsrScanGetScanChnInfo:
6026 break;
6027 default:
6028 smsLog (pMac, LOGW, "%s: -------- abort scan command reason = %d\n",
6029 __FUNCTION__, pCommand->u.scanCmd.reason);
6030 //The rest are fresh scan requests
6031 if( csrLLRemoveEntry(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK) )
6032 {
6033 csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK);
6034 }
6035 fRet = eANI_BOOLEAN_TRUE;
6036 break;
6037 }
6038 }
6039 pEntry = pEntryTmp;
6040 }
6041
6042 csrLLUnlock(&pMac->sme.smeCmdPendingList);
6043
6044 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
6045 {
6046 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
6047 if (pCommand->u.scanCmd.callback)
6048 {
6049 /* User scan request is pending,
6050 * send response with status eCSR_SCAN_ABORT*/
6051 pCommand->u.scanCmd.callback(pMac,
6052 pCommand->u.scanCmd.pContext,
6053 pCommand->u.scanCmd.scanID,
6054 eCSR_SCAN_ABORT);
6055 }
6056 csrReleaseCommandScan( pMac, pCommand );
6057 }
6058 csrLLClose(&localList);
6059
6060 return (fRet);
6061}
6062
6063
6064void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus)
6065{
6066 eCsrScanReason reason = pCommand->u.scanCmd.reason;
6067 tANI_U32 i;
6068 for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
6069 {
Jeff Johnson43971f52012-07-17 12:26:56 -07006070 csrRoamStateChange( pMac, pCommand->u.scanCmd.lastRoamState[i], i);
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 }
6072
6073 csrScanCallCallback(pMac, pCommand, scanStatus);
6074
6075 smsLog(pMac, LOG3, " Remove Scan command reason = %d\n", reason);
6076 if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_LOCK ) )
6077 {
6078 csrReleaseCommandScan( pMac, pCommand );
6079 }
6080 else
6081 {
6082 smsLog(pMac, LOGE, " ********csrReleaseScanCommand cannot release command reason %d\n", pCommand->u.scanCmd.reason );
6083 }
6084}
6085
6086
6087eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
6088 tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems )
6089{
6090 eHalStatus status = eHAL_STATUS_SUCCESS;
6091 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
6092
Jeff Johnson32d95a32012-09-10 13:15:23 -07006093 if(!pSession)
6094 {
6095 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
6096 return eHAL_STATUS_FAILURE;
6097 }
6098
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 smsLog(pMac, LOGW, " pMac->scan.NumPmkidCandidate = %d\n ", pSession->NumPmkidCandidate);
6100 csrResetPMKIDCandidateList(pMac, sessionId);
6101 if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
6102 {
6103 tCsrScanResultFilter *pScanFilter;
6104 tCsrScanResultInfo *pScanResult;
6105 tScanResultHandle hBSSList;
6106 tANI_U32 nItems = *pNumItems;
6107
6108 *pNumItems = 0;
6109 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
6110 if(HAL_STATUS_SUCCESS(status))
6111 {
6112 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
6113 //Here is the profile we need to connect to
6114 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
6115 if(HAL_STATUS_SUCCESS(status))
6116 {
6117 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
6118 if(HAL_STATUS_SUCCESS(status))
6119 {
6120 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumPmkidCandidate < nItems))
6121 {
6122 //NumPmkidCandidate adds up here
6123 csrProcessBSSDescForPMKIDList(pMac, &pScanResult->BssDescriptor,
6124 (tDot11fBeaconIEs *)( pScanResult->pvIes ));
6125 }
6126 if(pSession->NumPmkidCandidate)
6127 {
6128 *pNumItems = pSession->NumPmkidCandidate;
6129 palCopyMemory(pMac->hHdd, pPmkidList, pSession->PmkidCandidateInfo,
6130 pSession->NumPmkidCandidate * sizeof(tPmkidCandidateInfo));
6131 }
6132 csrScanResultPurge(pMac, hBSSList);
6133 }//Have scan result
6134 csrFreeScanFilter(pMac, pScanFilter);
6135 }
6136 palFreeMemory(pMac->hHdd, pScanFilter);
6137 }
6138 }
6139
6140 return (status);
6141}
6142
6143
6144
6145#ifdef FEATURE_WLAN_WAPI
6146eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId,
6147 tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems )
6148{
6149 eHalStatus status = eHAL_STATUS_SUCCESS;
6150 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
6151
Jeff Johnson32d95a32012-09-10 13:15:23 -07006152 if(!pSession)
6153 {
6154 smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
6155 return eHAL_STATUS_FAILURE;
6156 }
6157
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 smsLog(pMac, LOGW, " pMac->scan.NumBkidCandidate = %d\n ", pSession->NumBkidCandidate);
6159 csrResetBKIDCandidateList(pMac, sessionId);
6160 if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile)
6161 {
6162 tCsrScanResultFilter *pScanFilter;
6163 tCsrScanResultInfo *pScanResult;
6164 tScanResultHandle hBSSList;
6165 tANI_U32 nItems = *pNumItems;
6166 *pNumItems = 0;
6167 status = palAllocateMemory(pMac->hHdd, (void **)&pScanFilter, sizeof(tCsrScanResultFilter));
6168 if(HAL_STATUS_SUCCESS(status))
6169 {
6170 palZeroMemory(pMac->hHdd, pScanFilter, sizeof(tCsrScanResultFilter));
6171 //Here is the profile we need to connect to
6172 status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter);
6173 if(HAL_STATUS_SUCCESS(status))
6174 {
6175 status = csrScanGetResult(pMac, pScanFilter, &hBSSList);
6176 if(HAL_STATUS_SUCCESS(status))
6177 {
6178 while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumBkidCandidate < nItems))
6179 {
6180 //pMac->scan.NumBkidCandidate adds up here
6181 csrProcessBSSDescForBKIDList(pMac, &pScanResult->BssDescriptor,
6182 (tDot11fBeaconIEs *)( pScanResult->pvIes ));
6183
6184 }
6185 if(pSession->NumBkidCandidate)
6186 {
6187 *pNumItems = pSession->NumBkidCandidate;
6188 palCopyMemory(pMac->hHdd, pBkidList, pSession->BkidCandidateInfo, pSession->NumBkidCandidate * sizeof(tBkidCandidateInfo));
6189 }
6190 csrScanResultPurge(pMac, hBSSList);
6191 }//Have scan result
6192 }
6193 palFreeMemory(pMac->hHdd, pScanFilter);
6194 }
6195 }
6196
6197 return (status);
6198}
6199#endif /* FEATURE_WLAN_WAPI */
6200
6201
6202
6203//This function is usually used for BSSs that suppresses SSID so the profile
6204//shall have one and only one SSID
6205eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId)
6206{
6207 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6208 tSmeCmd *pScanCmd = NULL;
6209 tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6210 tANI_U8 index = 0;
6211 tANI_U32 numSsid = pProfile->SSIDs.numOfSSIDs;
6212
6213 smsLog(pMac, LOG2, FL("called\n"));
6214 //For WDS, we use the index 0. There must be at least one in there
6215 if( CSR_IS_WDS_STA( pProfile ) && numSsid )
6216 {
6217 numSsid = 1;
6218 }
6219 if(pMac->scan.fScanEnable && ( numSsid == 1 ) )
6220 {
6221 do
6222 {
6223 pScanCmd = csrGetCommandBuffer(pMac);
6224 if(!pScanCmd)
6225 {
6226 smsLog(pMac, LOGE, FL("failed to allocate command buffer\n"));
6227 break;
6228 }
6229 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
6230 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.pToRoamProfile, sizeof(tCsrRoamProfile));
6231 if(!HAL_STATUS_SUCCESS(status))
6232 break;
6233 status = csrRoamCopyProfile(pMac, pScanCmd->u.scanCmd.pToRoamProfile, pProfile);
6234 if(!HAL_STATUS_SUCCESS(status))
6235 break;
6236 pScanCmd->u.scanCmd.roamId = roamId;
6237 pScanCmd->command = eSmeCommandScan;
Jeff Johnsone7245742012-09-05 17:12:55 -07006238 pScanCmd->sessionId = (tANI_U8)sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 pScanCmd->u.scanCmd.callback = NULL;
6240 pScanCmd->u.scanCmd.pContext = NULL;
6241 pScanCmd->u.scanCmd.reason = eCsrScanForSsid;
6242 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
6243 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest));
6244 pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 pScanCmd->u.scanCmd.u.scanRequest.BSSType = pProfile->BSSType;
Jeff Johnsone7245742012-09-05 17:12:55 -07006246 // To avoid 11b rate in probe request Set p2pSearch flag as 1 for P2P Client Mode
6247 if(VOS_P2P_CLIENT_MODE == pProfile->csrPersona)
6248 {
6249 pScanCmd->u.scanCmd.u.scanRequest.p2pSearch = 1;
6250 }
6251 if(pProfile->pAddIEScan)
6252 {
6253 status = palAllocateMemory(pMac->hHdd,
6254 (void **)&pScanCmd->u.scanCmd.u.scanRequest.pIEField,
6255 pProfile->nAddIEScanLength);
6256 palZeroMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.pIEField, pProfile->nAddIEScanLength);
6257 if(HAL_STATUS_SUCCESS(status))
6258 {
6259 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.pIEField, pProfile->pAddIEScan, pProfile->nAddIEScanLength);
6260 pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = pProfile->nAddIEScanLength;
6261 }
6262 else
6263 {
6264 smsLog(pMac, LOGE, "No memory for scanning IE fields\n");
6265 }
6266 } //Allocate memory for IE field
6267 else
6268 {
6269 pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = 0;
6270 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07006271 /* For one channel be good enpugh time to receive beacon atleast */
6272 if( 1 == pProfile->ChannelInfo.numOfChannels )
6273 {
6274 pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL;
6275 pScanCmd->u.scanCmd.u.scanRequest.minChnTime = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL;
6276 }
6277 else
6278 {
6279 pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime;
6280 pScanCmd->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime;
6281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 if(pProfile->BSSIDs.numOfBSSIDs == 1)
6283 {
6284 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.bssid, pProfile->BSSIDs.bssid, sizeof(tCsrBssid));
6285 }
6286 else
6287 {
6288 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.bssid, bAddr, 6);
6289 }
6290 if(pProfile->ChannelInfo.numOfChannels)
6291 {
6292 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, sizeof(*pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) * pProfile->ChannelInfo.numOfChannels);
6293 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
6294 if(HAL_STATUS_SUCCESS(status))
6295 {
6296 csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[0]);
6297 for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++)
6298 {
6299 if(csrRoamIsValidChannel(pMac, pProfile->ChannelInfo.ChannelList[index]))
6300 {
6301 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels]
6302 = pProfile->ChannelInfo.ChannelList[index];
6303 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++;
6304 }
6305 else
6306 {
6307 smsLog(pMac, LOGW, FL("process a channel (%d) that is invalid\n"), pProfile->ChannelInfo.ChannelList[index]);
6308 }
6309
6310 }
6311 }
6312 else
6313 {
6314 break;
6315 }
6316
6317 }
6318 else
6319 {
6320 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0;
6321 }
6322 if(pProfile->SSIDs.numOfSSIDs)
6323 {
6324 status = palAllocateMemory(pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList,
6325 pProfile->SSIDs.numOfSSIDs * sizeof(tCsrSSIDInfo));
6326 if(!HAL_STATUS_SUCCESS(status))
6327 {
6328 break;
6329 }
6330 pScanCmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1;
6331 palCopyMemory(pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList, pProfile->SSIDs.SSIDList,
6332 sizeof(tCsrSSIDInfo));
6333 }
6334 //Start process the command
6335 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
6336 if( !HAL_STATUS_SUCCESS( status ) )
6337 {
6338 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
6339 break;
6340 }
6341 }while(0);
6342 if(!HAL_STATUS_SUCCESS(status))
6343 {
6344 if(pScanCmd)
6345 {
6346 csrReleaseCommandScan(pMac, pScanCmd);
6347 //TODO:free the memory that is allocated in this function
6348 }
6349 csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
6350 }
6351 }//valid
6352 else
6353 {
6354 smsLog(pMac, LOGE, FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid\n"),
6355 pMac->scan.fScanEnable, pProfile->SSIDs.numOfSSIDs);
6356 }
6357
6358 return (status);
6359}
6360
6361
6362//Issue a scan base on the new capability infomation
6363//This should only happen when the associated AP changes its capability.
6364//After this scan is done, CSR reroams base on the new scan results
6365eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps)
6366{
6367 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6368 tSmeCmd *pScanCmd = NULL;
6369
6370 if(pNewCaps)
6371 {
6372 do
6373 {
6374 pScanCmd = csrGetCommandBuffer(pMac);
6375 if(!pScanCmd)
6376 {
6377 smsLog(pMac, LOGE, FL("failed to allocate command buffer\n"));
6378 status = eHAL_STATUS_RESOURCES;
6379 break;
6380 }
6381 palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd, sizeof(tScanCmd));
6382 status = eHAL_STATUS_SUCCESS;
6383 pScanCmd->u.scanCmd.roamId = 0;
6384 pScanCmd->command = eSmeCommandScan;
6385 pScanCmd->u.scanCmd.callback = NULL;
6386 pScanCmd->u.scanCmd.pContext = NULL;
6387 pScanCmd->u.scanCmd.reason = eCsrScanForCapsChange;
6388 pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
6389 status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
6390 if( !HAL_STATUS_SUCCESS( status ) )
6391 {
6392 smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status );
6393 break;
6394 }
6395 }while(0);
6396 if(!HAL_STATUS_SUCCESS(status))
6397 {
6398 if(pScanCmd)
6399 {
6400 csrReleaseCommandScan(pMac, pScanCmd);
6401 }
6402 }
6403 }
6404
6405 return (status);
6406}
6407
6408
6409
6410void csrInitBGScanChannelList(tpAniSirGlobal pMac)
6411{
6412 tANI_U32 len = CSR_MIN(sizeof(pMac->roam.validChannelList), sizeof(pMac->scan.bgScanChannelList));
6413
6414 palZeroMemory(pMac->hHdd, pMac->scan.bgScanChannelList, len);
6415 pMac->scan.numBGScanChannel = 0;
6416
6417 if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
6418 {
6419 pMac->roam.numValidChannels = len;
6420 pMac->scan.numBGScanChannel = (tANI_U8)CSR_MIN(len, WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN);
6421 palCopyMemory(pMac->hHdd, pMac->scan.bgScanChannelList, pMac->roam.validChannelList, pMac->scan.numBGScanChannel);
6422 csrSetBGScanChannelList(pMac, pMac->scan.bgScanChannelList, pMac->scan.numBGScanChannel);
6423 }
6424}
6425
6426
6427//This function return TRUE if background scan channel list is adjusted.
6428//this function will only shrink the background scan channel list
6429tANI_BOOLEAN csrAdjustBGScanChannelList(tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels,
6430 tANI_U8 *pAdjustChannels, tANI_U8 *pNumAdjustChannels)
6431{
6432 tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
6433 tANI_U8 i, j, count = *pNumAdjustChannels;
6434
6435 i = 0;
6436 while(i < count)
6437 {
6438 for(j = 0; j < NumChannels; j++)
6439 {
6440 if(pChannelList[j] == pAdjustChannels[i])
6441 break;
6442 }
6443 if(j == NumChannels)
6444 {
6445 //This channel is not in the list, remove it
6446 fRet = eANI_BOOLEAN_TRUE;
6447 count--;
6448 if(count - i)
6449 {
6450 palCopyMemory(pMac->hHdd, &pAdjustChannels[i], &pAdjustChannels[i+1], count - i);
6451 }
6452 else
6453 {
6454 //already remove the last one. Done.
6455 break;
6456 }
6457 }
6458 else
6459 {
6460 i++;
6461 }
6462 }//while(i<count)
6463 *pNumAdjustChannels = count;
6464
6465 return (fRet);
6466}
6467
6468
6469//Get the list of the base channels to scan for passively 11d info
6470eHalStatus csrScanGetSupportedChannels( tpAniSirGlobal pMac )
6471{
6472 eHalStatus status = eHAL_STATUS_SUCCESS;
6473 int n = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6474
6475 status = vos_nv_getSupportedChannels( pMac->scan.baseChannels.channelList, &n, NULL, NULL );
6476 if( HAL_STATUS_SUCCESS(status) )
6477 {
6478 pMac->scan.baseChannels.numChannels = (tANI_U8)n;
6479 }
6480 else
6481 {
6482 smsLog( pMac, LOGE, FL(" failed\n") );
6483 pMac->scan.baseChannels.numChannels = 0;
6484 }
6485
6486 return ( status );
6487}
6488
6489//This function use the input pChannelList to validate the current saved channel list
6490eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels)
6491{
6492 tANI_U32 dataLen = sizeof( tANI_U8 ) * NumAdjustChannels;
6493
6494 return (ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pAdjustChannels, dataLen, NULL, eANI_BOOLEAN_FALSE));
6495}
6496
6497
6498void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels )
6499{
6500 tANI_U32 dataLen = sizeof( tANI_U8 ) * NumChannels;
6501
6502
6503 ccmCfgSetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
6504
6505 return;
6506}
6507
6508
6509
6510/*
6511 * The Tx power limits are saved in the cfg for future usage.
6512 */
6513void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId )
6514{
6515 tListElem *pEntry;
6516 tANI_U32 cbLen = 0, dataLen;
6517 tCsrChannelPowerInfo *pChannelSet;
6518 tANI_U32 idx;
6519 tSirMacChanInfo *pChannelPowerSet;
6520 tANI_U8 *pBuf = NULL;
6521
6522 //allocate maximum space for all channels
6523 dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo);
6524 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pBuf, dataLen)))
6525 {
6526 palZeroMemory(pMac->hHdd, pBuf, dataLen);
6527 pChannelPowerSet = (tSirMacChanInfo *)(pBuf);
6528
6529 pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK );
6530 // write the tuples (startChan, numChan, txPower) for each channel found in the channel power list.
6531 while( pEntry )
6532 {
6533 pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link );
6534 if ( 1 != pChannelSet->interChannelOffset )
6535 {
6536 // we keep the 5G channel sets internally with an interchannel offset of 4. Expand these
6537 // to the right format... (inter channel offset of 1 is the only option for the triplets
6538 // that 11d advertises.
6539 if ((cbLen + (pChannelSet->numChannels * sizeof(tSirMacChanInfo))) >= dataLen)
6540 {
6541 // expanding this entry will overflow our allocation
6542 smsLog(pMac, LOGE,
6543 "%s: Buffer overflow, start %d, num %d, offset %d",
6544 __FUNCTION__,
6545 pChannelSet->firstChannel,
6546 pChannelSet->numChannels,
6547 pChannelSet->interChannelOffset);
6548 break;
6549 }
6550
6551 for( idx = 0; idx < pChannelSet->numChannels; idx++ )
6552 {
6553 pChannelPowerSet->firstChanNum = (tSirMacChanNum)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset ));
6554 smsLog(pMac, LOG3, " Setting Channel Number %d\n", pChannelPowerSet->firstChanNum);
6555 pChannelPowerSet->numChannels = 1;
6556#ifdef WLAN_SOFTAP_FEATURE
6557 pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
6558#else
6559 pChannelPowerSet->maxTxPower = pChannelSet->txPower;
6560#endif
6561 smsLog(pMac, LOG3, " Setting Max Transmit Power %d\n", pChannelPowerSet->maxTxPower);
6562 cbLen += sizeof( tSirMacChanInfo );
6563 pChannelPowerSet++;
6564 }
6565 }
6566 else
6567 {
6568 if (cbLen >= dataLen)
6569 {
6570 // this entry will overflow our allocation
6571 smsLog(pMac, LOGE,
6572 "%s: Buffer overflow, start %d, num %d, offset %d",
6573 __FUNCTION__,
6574 pChannelSet->firstChannel,
6575 pChannelSet->numChannels,
6576 pChannelSet->interChannelOffset);
6577 break;
6578 }
6579 pChannelPowerSet->firstChanNum = pChannelSet->firstChannel;
6580 smsLog(pMac, LOG3, " Setting Channel Number %d\n", pChannelPowerSet->firstChanNum);
6581 pChannelPowerSet->numChannels = pChannelSet->numChannels;
6582#ifdef WLAN_SOFTAP_FEATURE
6583 pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap );
6584#else
6585 pChannelPowerSet->maxTxPower = pChannelSet->txPower;
6586#endif
6587 smsLog(pMac, LOG3, " Setting Max Transmit Power %d, nTxPower %d\n", pChannelPowerSet->maxTxPower,pMac->roam.configParam.nTxPowerCap );
6588
6589
6590 cbLen += sizeof( tSirMacChanInfo );
6591 pChannelPowerSet++;
6592 }
6593
6594 pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK );
6595 }
6596
6597 if(cbLen)
6598 {
6599 ccmCfgSetStr(pMac, cfgId, (tANI_U8 *)pBuf, cbLen, NULL, eANI_BOOLEAN_FALSE);
6600 }
6601 palFreeMemory( pMac->hHdd, pBuf );
6602 }//Allocate memory
6603}
6604
6605
6606void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode )
6607{
6608 tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN];
6609 ///v_REGDOMAIN_t DomainId;
6610
6611 smsLog( pMac, LOG3, "Setting Country Code in Cfg from csrSetCfgCountryCode %s\n",countryCode );
6612 palCopyMemory( pMac->hHdd, cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN );
6613
6614 // don't program the bogus country codes that we created for Korea in the MAC. if we see
6615 // the bogus country codes, program the MAC with the right country code.
6616 if ( ( 'K' == countryCode[ 0 ] && '1' == countryCode[ 1 ] ) ||
6617 ( 'K' == countryCode[ 0 ] && '2' == countryCode[ 1 ] ) ||
6618 ( 'K' == countryCode[ 0 ] && '3' == countryCode[ 1 ] ) ||
6619 ( 'K' == countryCode[ 0 ] && '4' == countryCode[ 1 ] ) )
6620 {
6621 // replace the alternate Korea country codes, 'K1', 'K2', .. with 'KR' for Korea
6622 cc[ 1 ] = 'R';
6623 }
6624 ccmCfgSetStr(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN, NULL, eANI_BOOLEAN_FALSE);
6625
6626 //Need to let HALPHY know about the current domain so it can apply some
6627 //domain-specific settings (TX filter...)
6628 /*if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, cc, &DomainId)))
6629 {
6630 halPhySetRegDomain(pMac, DomainId);
6631 }*/
6632}
6633
6634
6635
6636eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen)
6637{
6638 eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
6639 tANI_U32 len;
6640
6641 if(pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN))
6642 {
6643 len = *pbLen;
6644 status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len);
6645 if(HAL_STATUS_SUCCESS(status))
6646 {
6647 *pbLen = (tANI_U8)len;
6648 }
6649 }
6650
6651 return (status);
6652}
6653
6654
6655void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList )
6656{
6657 tANI_U8 i, j;
6658 tANI_BOOLEAN found=FALSE;
6659 tANI_U8 *pControlList = NULL;
6660 tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
6661
6662 if(HAL_STATUS_SUCCESS(palAllocateMemory(pMac->hHdd, (void **)&pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN)))
6663 {
6664 palZeroMemory(pMac->hHdd, (void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN);
6665 if(HAL_STATUS_SUCCESS(ccmCfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, &len)))
6666 {
6667 for (i = 0; i < pChannelList->numChannels; i++)
6668 {
6669 for (j = 0; j < len; j += 2)
6670 {
6671 if (pControlList[j] == pChannelList->channelList[i])
6672 {
6673 found = TRUE;
6674 break;
6675 }
6676 }
6677
6678 if (found) // insert a pair(channel#, flag)
6679 {
6680 if (CSR_IS_CHANNEL_5GHZ(pControlList[j]))
6681 {
6682 pControlList[j+1] = csrGetScanType(pMac, pControlList[j]);
6683 }
6684 else
6685 {
6686 pControlList[j+1] = eSIR_ACTIVE_SCAN;
6687 }
6688
6689 found = FALSE; // reset the flag
6690 }
6691
6692 }
6693
6694 ccmCfgSetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, len, NULL, eANI_BOOLEAN_FALSE);
6695 }//Successfully getting scan control list
6696 palFreeMemory(pMac->hHdd, pControlList);
6697 }//AllocateMemory
6698}
6699
6700
6701//if bgPeriod is 0, background scan is disabled. It is in millisecond units
6702eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod)
6703{
6704 return (ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, bgPeriod, (tCcmCfgSetCallback) csrScanCcmCfgSetCallback, eANI_BOOLEAN_FALSE));
6705}
6706
6707
6708void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result)
6709{
6710 tListElem *pEntry = NULL;
6711 tSmeCmd *pCommand = NULL;
6712 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
6713
6714 pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK );
6715 if ( pEntry )
6716 {
6717 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6718 if ( eSmeCommandScan == pCommand->command )
6719 {
6720 eCsrScanStatus scanStatus = (CCM_IS_RESULT_SUCCESS(result)) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE;
6721 csrReleaseScanCommand(pMac, pCommand, scanStatus);
6722 }
6723 else
6724 {
6725 smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ...\n" );
6726 }
6727 }
6728 smeProcessPendingQueue( pMac );
6729}
6730
6731eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand)
6732{
6733 eHalStatus status;
6734 tCsrBGScanRequest *pScanReq = &pCommand->u.scanCmd.u.bgScanRequest;
6735 tANI_U32 dataLen = sizeof( tANI_U8 ) * pScanReq->ChannelInfo.numOfChannels;
6736
6737 //***setcfg for background scan channel list
6738 status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, pScanReq->minChnTime, NULL, eANI_BOOLEAN_FALSE);
6739 status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, pScanReq->maxChnTime, NULL, eANI_BOOLEAN_FALSE);
6740 //Not set the background scan interval if not connected because bd scan should not be run if not connected
6741 if(!csrIsAllSessionDisconnected(pMac))
6742 {
6743 //If disbaling BG scan here, we need to stop aging as well
6744 if(pScanReq->scanInterval == 0)
6745 {
6746 //Stop aging because no new result is coming in
6747 csrScanStopResultAgingTimer(pMac);
6748 }
6749
6750#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
6751 {
6752 vos_log_scan_pkt_type *pScanLog = NULL;
6753
6754 WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C);
6755 if(pScanLog)
6756 {
6757 pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ;
6758 pScanLog->minChnTime = (v_U8_t)pScanReq->minChnTime;
6759 pScanLog->maxChnTime = (v_U8_t)pScanReq->maxChnTime;
6760 pScanLog->timeBetweenBgScan = (v_U8_t)pScanReq->scanInterval;
6761 pScanLog->numChannel = pScanReq->ChannelInfo.numOfChannels;
6762 if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL))
6763 {
6764 palCopyMemory(pMac->hHdd, pScanLog->channels, pScanReq->ChannelInfo.ChannelList,
6765 pScanLog->numChannel);
6766 }
6767 WLAN_VOS_DIAG_LOG_REPORT(pScanLog);
6768 }
6769 }
6770#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
6771
6772 status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, pScanReq->scanInterval, NULL, eANI_BOOLEAN_FALSE);
6773 }
6774 else
6775 {
6776 //No need to stop aging because IDLE scan is still running
6777 status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, 0, NULL, eANI_BOOLEAN_FALSE);
6778 }
6779
6780 if(pScanReq->SSID.length > WNI_CFG_SSID_LEN)
6781 {
6782 pScanReq->SSID.length = WNI_CFG_SSID_LEN;
6783 }
6784
6785 status = ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pScanReq->ChannelInfo.ChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE);
6786 status = ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pScanReq->SSID.ssId, pScanReq->SSID.length, NULL, eANI_BOOLEAN_FALSE);
6787
6788
6789
6790 return (status);
6791}
6792
6793
6794eHalStatus csrScanAbortMacScan(tpAniSirGlobal pMac)
6795{
6796 eHalStatus status = eHAL_STATUS_SUCCESS;
6797 tSirMbMsg *pMsg;
6798 tANI_U16 msgLen;
6799 tListElem *pEntry;
6800 tSmeCmd *pCommand;
6801
6802#ifdef WLAN_AP_STA_CONCURRENCY
6803 csrLLLock(&pMac->scan.scanCmdPendingList);
6804 while( NULL != ( pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) )
6805 {
6806
6807 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6808 csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
6809 }
6810 csrLLUnlock(&pMac->scan.scanCmdPendingList);
6811#endif
6812
6813 pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
6814 csrRemoveCmdFromPendingList( pMac, &pMac->roam.roamCmdPendingList, eSmeCommandScan);
6815 csrRemoveCmdFromPendingList( pMac, &pMac->sme.smeCmdPendingList, eSmeCommandScan);
6816 pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
6817
6818 //We need to abort scan only if we are scanning
6819 if(NULL != (pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK)))
6820 {
6821 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6822 if(eSmeCommandScan == pCommand->command)
6823 {
6824 msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
6825 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
6826 if(HAL_STATUS_SUCCESS(status))
6827 {
6828 palZeroMemory(pMac->hHdd, (void *)pMsg, msgLen);
6829 pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND);
6830 pMsg->msgLen = pal_cpu_to_be16(msgLen);
6831 status = palSendMBMessage(pMac->hHdd, pMsg);
6832 }
6833 }
6834 }
6835
6836 return( status );
6837}
6838
6839void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList,
6840 eSmeCommandType commandType )
6841{
6842 tDblLinkList localList;
6843 tListElem *pEntry;
6844 tSmeCmd *pCommand;
6845 tListElem *pEntryToRemove;
6846
6847 vos_mem_zero(&localList, sizeof(tDblLinkList));
6848 if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
6849 {
6850 smsLog(pMac, LOGE, FL(" failed to open list"));
6851 return;
6852 }
6853
6854 csrLLLock(pList);
6855 if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) )
6856 {
6857 pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK);
6858
6859 // Have to make sure we don't loop back to the head of the list, which will
6860 // happen if the entry is NOT on the list...
6861 while( pEntry )
6862 {
6863 pEntryToRemove = pEntry;
6864 pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
6865 pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
6866 if ( pCommand->command == commandType )
6867 {
6868 // Remove that entry only
6869 if(csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
6870 {
6871 csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK);
6872 }
6873 }
6874 }
6875
6876
6877 }
6878 csrLLUnlock(pList);
6879
6880 while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
6881 {
6882 pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
6883 csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
6884 }
6885 csrLLClose(&localList);
6886
6887}
6888
6889
6890eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac)
6891{
6892 eHalStatus status = eHAL_STATUS_SUCCESS;
6893
6894 if( !csrIsScanForRoamCommandActive( pMac ) )
6895 {
6896 //Only abort the scan if it is not used for other roam/connect purpose
6897 status = csrScanAbortMacScan(pMac);
6898 }
6899
6900 return (status);
6901}
6902
6903
6904eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac)
6905{
6906 eHalStatus status = eHAL_STATUS_SUCCESS;
6907 tSirMbMsg *pMsg;
6908 tANI_U16 msgLen;
6909
6910 msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
6911 status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
6912 if(HAL_STATUS_SUCCESS(status))
6913 {
6914 palZeroMemory(pMac->hHdd, pMsg, msgLen);
6915 pMsg->type = eWNI_SME_GET_SCANNED_CHANNEL_REQ;
6916 pMsg->msgLen = msgLen;
6917 status = palSendMBMessage(pMac->hHdd, pMsg);
6918 }
6919
6920 return( status );
6921}
6922
6923tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel )
6924{
6925 tANI_BOOLEAN fValid = FALSE;
6926 tANI_U32 idxValidChannels;
6927 tANI_U32 len = pMac->roam.numValidChannels;
6928
6929 for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ )
6930 {
6931 if ( channel == pMac->roam.validChannelList[ idxValidChannels ] )
6932 {
6933 fValid = TRUE;
6934 break;
6935 }
6936 }
6937
6938 return fValid;
6939}
6940
6941