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