blob: a4ce315e9a50e07260689ad5168c7f5542fd62eb [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08005 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006/**========================================================================
7
8 \file wlan_hdd_scan.c
9
10 \brief WLAN Host Device Driver implementation
11
12 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
13
14 Qualcomm Confidential and Proprietary.
15
16 ========================================================================*/
17
18/**=========================================================================
19
20 EDIT HISTORY FOR FILE
21
22
23 This section contains comments describing changes made to the module.
24 Notice that changes are listed in reverse chronological order.
25
26
27 $Header:$ $DateTime: $ $Author: $
28
29
30 when who what, where, why
31 -------- --- --------------------------------------------------------
32 04/5/09 Shailender Created module.
33
34 ==========================================================================*/
35 /* To extract the Scan results */
36
37/* Add a stream event */
38
39#include <wlan_qct_driver.h>
40#include <wlan_hdd_includes.h>
41#include <vos_api.h>
42#include <palTypes.h>
43#include <aniGlobal.h>
44#include <dot11f.h>
45#ifdef WLAN_BTAMP_FEATURE
46#include "bap_hdd_misc.h"
47#endif
48
Jeff Johnson295189b2012-06-20 16:38:30 -070049#include <linux/wireless.h>
50#include <net/cfg80211.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070051
52#define GET_IE_LEN_IN_BSS(lenInBss) ( lenInBss + sizeof(lenInBss) - \
53 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
54
55#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
56#define WEXT_CSCAN_HEADER_SIZE 12
57#define WEXT_CSCAN_SSID_SECTION 'S'
58#define WEXT_CSCAN_CHANNEL_SECTION 'C'
59#define WEXT_CSCAN_NPROBE_SECTION 'N'
60#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
61#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
62#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
63#define WEXT_CSCAN_TYPE_SECTION 'T'
64#define WEXT_CSCAN_PENDING_SECTION 'O'
65#define WEXT_CSCAN_TYPE_DEFAULT 0
66#define WEXT_CSCAN_TYPE_PASSIVE 1
67#define WEXT_CSCAN_PASV_DWELL_TIME 130
68#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
69#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
70#define WEXT_CSCAN_HOME_DWELL_TIME 130
71#define MAX_RATES 12
72
73#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000
74
75typedef struct hdd_scan_info{
76 struct net_device *dev;
77 struct iw_request_info *info;
78 char *start;
79 char *end;
80} hdd_scan_info_t, *hdd_scan_info_tp;
81
82static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate)
83{
84
85 /** Slightly more sophisticated processing has to take place here.
86 Basic rates are rounded DOWN. HT rates are rounded UP.*/
87 return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2);
88}
89
90
91static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event )
92{
93 struct iw_event event;
94
95 *last_event = *current_event;
96 vos_mem_zero(&event, sizeof (struct iw_event));
97 event.cmd = cmd;
98 event.u.data.flags = 1;
99 event.u.data.length = length;
100 *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data);
101
102 if(*last_event == *current_event)
103 {
104 /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530105 hddLog( LOGW, "%s: no space left to add event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700106 return -E2BIG; /* Error code, may be E2BIG */
107 }
108
109 return 0;
110}
111
112/**---------------------------------------------------------------------------
113
114 \brief hdd_GetWPARSNIEs() -
115
116 This function extract the WPA/RSN IE from the Bss descriptor IEs fields
117
118 \param - ieFields - Pointer to the Bss Descriptor IEs.
119 - ie_length - IE Length.
120 - last_event -Points to the last event.
121 - current_event - Points to the
122 \return - 0 for success, non zero for failure
123
124 --------------------------------------------------------------------------*/
125
126
127/* Extract the WPA and/or RSN IEs */
128static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo )
129{
130 v_U8_t eid, elen, *element;
131 v_U16_t tie_length=0;
132
133 ENTER();
134
135 element = ieFields;
136 tie_length = ie_length;
137
138 while( tie_length > 2 && element != NULL )
139 {
140 eid = element[0];
141 elen = element[1];
142
143 /*If element length is greater than total remaining ie length,
144 *break the loop*/
145 if ((elen+2) > tie_length)
146 break;
147
148 switch(eid)
149 {
150 case DOT11F_EID_WPA:
151 case DOT11F_EID_RSN:
152#ifdef FEATURE_WLAN_WAPI
153 case DOT11F_EID_WAPI:
154#endif
155 if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 )
156 return -E2BIG;
157 break;
158
159 default:
160 break;
161 }
162
163 /* Next element */
164 tie_length -= (2 + elen);
165 element += 2 + elen;
166 }
167
168 return 0;
169}
170
171/**---------------------------------------------------------------------------
172
173 \brief hdd_IndicateScanResult() -
174
175 This function returns the scan results to the wpa_supplicant
176
177 \param - scanInfo - Pointer to the scan info structure.
178 - descriptor - Pointer to the Bss Descriptor.
179
180 \return - 0 for success, non zero for failure
181
182 --------------------------------------------------------------------------*/
183#define MAX_CUSTOM_LEN 64
184static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result)
185{
186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ;
187 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
188 tSirBssDescription *descriptor = &scan_result->BssDescriptor;
189 struct iw_event event;
190 char *current_event = scanInfo->start;
191 char *end = scanInfo->end;
192 char *last_event;
193 char *current_pad;
194 v_U16_t ie_length = 0;
195 v_U16_t capabilityInfo;
196 char *modestr;
197 int error;
198 char custom[MAX_CUSTOM_LEN];
199 char *p;
200
Arif Hussain24bafea2013-11-15 15:10:03 -0800201 hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR,
202 MAC_ADDR_ARRAY(descriptor->bssId));
Jeff Johnson295189b2012-06-20 16:38:30 -0700203
204 error = 0;
205 last_event = current_event;
206 vos_mem_zero(&event, sizeof (event));
207
208 /* BSSID */
209 event.cmd = SIOCGIWAP;
210 event.u.ap_addr.sa_family = ARPHRD_ETHER;
211 vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId,
212 sizeof (descriptor->bssId));
213 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
214 &event, IW_EV_ADDR_LEN);
215
216 if (last_event == current_event)
217 {
218 /* no space to add event */
219 /* Error code may be E2BIG */
220 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP ");
221 return -E2BIG;
222 }
223
224 last_event = current_event;
225 vos_mem_zero(&event, sizeof (struct iw_event));
226
227 /* Protocol Name */
228 event.cmd = SIOCGIWNAME;
229
230 switch (descriptor->nwType)
231 {
232 case eSIR_11A_NW_TYPE:
233 modestr = "a";
234 break;
235 case eSIR_11B_NW_TYPE:
236 modestr = "b";
237 break;
238 case eSIR_11G_NW_TYPE:
239 modestr = "g";
240 break;
241 case eSIR_11N_NW_TYPE:
242 modestr = "n";
243 break;
244 default:
245 hddLog( LOGW, "%s: Unknown network type [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700246 __func__, descriptor->nwType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 modestr = "?";
248 break;
249 }
250 snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr);
251 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
252 &event, IW_EV_CHAR_LEN);
253
254 if (last_event == current_event)
255 { /* no space to add event */
256 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME");
257 /* Error code, may be E2BIG */
258 return -E2BIG;
259 }
260
261 last_event = current_event;
262 vos_mem_zero( &event, sizeof (struct iw_event));
263
264 /*Freq*/
265 event.cmd = SIOCGIWFREQ;
266
267 event.u.freq.m = descriptor->channelId;
268 event.u.freq.e = 0;
269 event.u.freq.i = 0;
270 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
271 &event, IW_EV_FREQ_LEN);
272
273 if (last_event == current_event)
274 { /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530275 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWFREQ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 return -E2BIG;
277 }
278
279 last_event = current_event;
280 vos_mem_zero( &event, sizeof (struct iw_event));
281
282 /* BSS Mode */
283 event.cmd = SIOCGIWMODE;
284
285 capabilityInfo = descriptor->capabilityInfo;
286
287 if (SIR_MAC_GET_ESS(capabilityInfo))
288 {
289 event.u.mode = IW_MODE_INFRA;
290 }
291 else if (SIR_MAC_GET_IBSS(capabilityInfo))
292 {
293 event.u.mode = IW_MODE_ADHOC;
294 }
295 else
296 {
297 /* neither ESS or IBSS */
298 event.u.mode = IW_MODE_AUTO;
299 }
300
301 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
302 &event, IW_EV_UINT_LEN);
303
304 if (last_event == current_event)
305 { /* no space to add event */
306 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE");
307 return -E2BIG;
308 }
309 /* To extract SSID */
310 ie_length = GET_IE_LEN_IN_BSS( descriptor->length );
311
312 if (ie_length > 0)
313 {
Madan Mohan Koyyalamudi729972c2012-10-21 12:39:24 -0700314 /* dot11BeaconIEs is a large struct, so we make it static to
315 avoid stack overflow. This API is only invoked via ioctl,
316 so it is serialized by the kernel rtnl_lock and hence does
317 not need to be reentrant */
318 static tDot11fBeaconIEs dot11BeaconIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 tDot11fIESSID *pDot11SSID;
320 tDot11fIESuppRates *pDot11SuppRates;
321 tDot11fIEExtSuppRates *pDot11ExtSuppRates;
322 tDot11fIEHTCaps *pDot11IEHTCaps;
323 int numBasicRates = 0;
324 int maxNumRates = 0;
325
326 pDot11IEHTCaps = NULL;
327
328 dot11fUnpackBeaconIEs ((tpAniSirGlobal)
329 hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs);
330
331 pDot11SSID = &dot11BeaconIEs.SSID;
332
333
334 if (pDot11SSID->present ) {
335 last_event = current_event;
336 vos_mem_zero (&event, sizeof (struct iw_event));
337
338 event.cmd = SIOCGIWESSID;
339 event.u.data.flags = 1;
340 event.u.data.length = scan_result->ssId.length;
341 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
342 &event, (char *)scan_result->ssId.ssId);
343
344 if(last_event == current_event)
345 { /* no space to add event */
346 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
347 return -E2BIG;
348 }
349 }
350
351 if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, &current_event, scanInfo ) < 0 )
352 {
353 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
354 return -E2BIG;
355 }
356
357 last_event = current_event;
358 current_pad = current_event + IW_EV_LCP_LEN;
359 vos_mem_zero( &event, sizeof (struct iw_event));
360
361 /*Rates*/
362 event.cmd = SIOCGIWRATE;
363
364
365 pDot11SuppRates = &dot11BeaconIEs.SuppRates;
366
367 if (pDot11SuppRates->present )
368 {
369 int i;
370
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700371 numBasicRates = pDot11SuppRates->num_rates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 for (i=0; i<pDot11SuppRates->num_rates; i++)
373 {
374 if (0 != (pDot11SuppRates->rates[i] & 0x7F))
375 {
376 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
377 &pDot11SuppRates->rates[i]);
378
379 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
380 current_pad, end, &event, IW_EV_PARAM_LEN);
381 }
382 }
383
384 }
385
386 pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates;
387
388 if (pDot11ExtSuppRates->present )
389 {
390 int i,no_of_rates;
391 maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates;
392
393 /* Check to make sure the total number of rates
394 doesn't exceed IW_MAX_BITRATES */
395
396 maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES);
397
398 if((maxNumRates - numBasicRates) > MAX_RATES)
399 {
400 no_of_rates = MAX_RATES;
401 hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates ");
402 }
403 else
404 {
405 no_of_rates = maxNumRates - numBasicRates;
406 }
407 for ( i=0; i< no_of_rates ; i++ )
408 {
409 if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F))
410 {
411 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
412 &pDot11ExtSuppRates->rates[i]);
413
414 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
415 current_pad, end, &event, IW_EV_PARAM_LEN);
416 }
417 }
418 }
419
420
421 if ((current_pad - current_event) >= IW_EV_LCP_LEN)
422 {
423 current_event = current_pad;
424 }
425 else
426 {
427 if (last_event == current_event)
428 { /* no space to add event */
429 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE");
430 return -E2BIG;
431 }
432 }
433
434 last_event = current_event;
435 vos_mem_zero (&event, sizeof (struct iw_event));
436
437
438 event.cmd = SIOCGIWENCODE;
439
440 if (SIR_MAC_GET_PRIVACY(capabilityInfo))
441 {
442 event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
443 }
444 else
445 {
446 event.u.data.flags = IW_ENCODE_DISABLED;
447 }
448 event.u.data.length = 0;
449
450 current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid);
451
452
453 if(last_event == current_event)
454 { /* no space to add event
455 Error code, may be E2BIG */
c_hpothu7f63e882013-10-02 19:13:35 +0530456 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWENCODE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700457 return -E2BIG;
458 }
459 }
460
461 last_event = current_event;
462 vos_mem_zero( &event, sizeof (struct iw_event));
463
464 /*RSSI*/
465 event.cmd = IWEVQUAL;
466 event.u.qual.qual = descriptor->rssi;
467 event.u.qual.noise = descriptor->sinr;
468
469 /*To keep the rssi icon of the connected AP in the scan window
470 *and the rssi icon of the wireless networks in sync */
471 if (( eConnectionState_Associated ==
472 pAdapter->sessionCtx.station.conn_info.connState ) &&
473 ( VOS_TRUE == vos_mem_compare(descriptor->bssId,
474 pAdapter->sessionCtx.station.conn_info.bssId,
475 WNI_CFG_BSSID_LEN)))
476 {
477 event.u.qual.level = pAdapter->rssi;
478 }
479 else
480 {
481 event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0);
482 }
483
484 event.u.qual.updated = IW_QUAL_ALL_UPDATED;
485
486 current_event = iwe_stream_add_event(scanInfo->info,current_event,
487 end, &event, IW_EV_QUAL_LEN);
488
489 if(last_event == current_event)
490 { /* no space to add event */
491 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL");
492 return -E2BIG;
493 }
494
495
496 /* AGE */
497 event.cmd = IWEVCUSTOM;
498 p = custom;
Sameer Thalappilb0a30232013-09-27 15:37:48 -0700499 p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu",
Jeff Johnson295189b2012-06-20 16:38:30 -0700500 vos_timer_get_system_ticks() - descriptor->nReceivedTime);
501 event.u.data.length = p - custom;
502 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
503 &event, custom);
504 if(last_event == current_event)
505 { /* no space to add event */
506 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)");
507 return -E2BIG;
508 }
509
510 scanInfo->start = current_event;
511
512 return 0;
513}
514
515/**---------------------------------------------------------------------------
516
517 \brief hdd_ScanRequestCallback() -
518
519 The sme module calls this callback function once it finish the scan request
520 and this function notifies the scan complete event to the wpa_supplicant.
521
522 \param - halHandle - Pointer to the Hal Handle.
523 - pContext - Pointer to the data context.
524 - scanId - Scan ID.
525 - status - CSR Status.
526 \return - 0 for success, non zero for failure
527
528 --------------------------------------------------------------------------*/
529
530static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext,
531 tANI_U32 scanId, eCsrScanStatus status)
532{
533 struct net_device *dev = (struct net_device *) pContext;
534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700535 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 union iwreq_data wrqu;
537 int we_event;
538 char *msg;
539
540 ENTER();
541
542 hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700543 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700544 (int) scanId, (int) status);
545
546 /* if there is a scan request pending when the wlan driver is unloaded
547 we may be invoked as SME flushes its pending queue. If that is the
548 case, the underlying net_device may have already been destroyed, so
549 do some quick sanity before proceeding */
550 if (pAdapter->dev != dev)
551 {
552 hddLog(LOGW, "%s: device mismatch %p vs %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700553 __func__, pAdapter->dev, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700554 return eHAL_STATUS_SUCCESS;
555 }
556
557 /* Check the scanId */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700558 if (pHddCtx->scan_info.scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700559 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700560 hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700561 "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700562 (int) scanId);
563 }
564
565 /* Scan is no longer pending */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700566 pHddCtx->scan_info.mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700567
568 // notify any applications that may be interested
569 memset(&wrqu, '\0', sizeof(wrqu));
570 we_event = SIOCGIWSCAN;
571 msg = NULL;
572 wireless_send_event(dev, we_event, &wrqu, msg);
573
574 EXIT();
575
576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
577
578 return eHAL_STATUS_SUCCESS;
579}
580
581/**---------------------------------------------------------------------------
582
583 \brief iw_set_scan() -
584
585 This function process the scan request from the wpa_supplicant
586 and set the scan request to the SME
587
588 \param - dev - Pointer to the net device.
589 - info - Pointer to the iw_request_info.
590 - wrqu - Pointer to the iwreq_data.
591 - extra - Pointer to the data.
592 \return - 0 for success, non zero for failure
593
594 --------------------------------------------------------------------------*/
595
596
597int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
598 union iwreq_data *wrqu, char *extra)
599{
600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700601 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
603 tCsrScanRequest scanRequest;
604 v_U32_t scanId = 0;
605 eHalStatus status = eHAL_STATUS_SUCCESS;
606 struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
607
608 ENTER();
609
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
611
612#ifdef WLAN_BTAMP_FEATURE
613 //Scan not supported when AMP traffic is on.
614 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
617 return eHAL_STATUS_SUCCESS;
618 }
619#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700620 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700621 {
622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
623 return eHAL_STATUS_SUCCESS;
624 }
625
626 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
628 return eHAL_STATUS_SUCCESS;
629 }
630 vos_mem_zero( &scanRequest, sizeof(scanRequest));
631
632 if (NULL != wrqu->data.pointer)
633 {
634 /* set scanType, active or passive */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700635 if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -0700636 {
637 scanRequest.scanType = eSIR_ACTIVE_SCAN;
638 }
639 else
640 {
641 scanRequest.scanType = eSIR_PASSIVE_SCAN;
642 }
643
644 /* set bssid using sockaddr from iw_scan_req */
645 vos_mem_copy(scanRequest.bssid,
646 &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );
647
648 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
649
650 if(scanReq->essid_len) {
651 scanRequest.SSIDs.numOfSSIDs = 1;
652 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
653 if(scanRequest.SSIDs.SSIDList) {
654 scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len;
655 vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len);
656 }
657 else
658 {
659 scanRequest.SSIDs.numOfSSIDs = 0;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 VOS_ASSERT(0);
662 }
663 }
664 }
665
666 /* set min and max channel time */
667 scanRequest.minChnTime = scanReq->min_channel_time;
668 scanRequest.maxChnTime = scanReq->max_channel_time;
669
670 }
671 else
672 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700673 if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 /* set the scan type to active */
675 scanRequest.scanType = eSIR_ACTIVE_SCAN;
676 } else {
677 scanRequest.scanType = eSIR_PASSIVE_SCAN;
678 }
679
680 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
681
682 /* set min and max channel time to zero */
683 scanRequest.minChnTime = 0;
684 scanRequest.maxChnTime = 0;
685 }
686
687 /* set BSSType to default type */
688 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
689
690 /*Scan all the channels */
691 scanRequest.ChannelInfo.numOfChannels = 0;
692
693 scanRequest.ChannelInfo.ChannelList = NULL;
694
695 /* set requestType to full scan */
696 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
697
698 /* if previous genIE is not NULL, update ScanIE */
699 if (0 != pwextBuf->genIE.length)
700 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700701 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
702 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -0700703 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700704 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +0530705 /* Maximum length of each IE is SIR_MAC_MAX_IE_LENGTH */
706 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
707 {
708 memcpy( pwextBuf->roamProfile.addIEScan,
709 pHddCtx->scan_info.scanAddIE.addIEdata,
710 pHddCtx->scan_info.scanAddIE.length);
711 pwextBuf->roamProfile.nAddIEScanLength =
712 pHddCtx->scan_info.scanAddIE.length;
713 }
714 else
715 {
716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
717 "Invalid ScanIE, Length is %d", pwextBuf->genIE.length);
718 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 /* clear previous genIE after use it */
720 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
721 }
722
723 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700724 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
725 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -0700726 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700727 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
728 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -0700729 }
730
731 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
732 if (!HAL_STATUS_SUCCESS(status))
733 {
734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status);
735 goto error;
736 }
737
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700738 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700739
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700740 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700741
742error:
743 if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
744 vos_mem_free(scanRequest.SSIDs.SSIDList);
745
746 EXIT();
747
748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
749 return status;
750}
751
752/**---------------------------------------------------------------------------
753
754 \brief iw_get_scan() -
755
756 This function returns the scan results to the wpa_supplicant
757
758 \param - dev - Pointer to the net device.
759 - info - Pointer to the iw_request_info.
760 - wrqu - Pointer to the iwreq_data.
761 - extra - Pointer to the data.
762 \return - 0 for success, non zero for failure
763
764 --------------------------------------------------------------------------*/
765
766
767int iw_get_scan(struct net_device *dev,
768 struct iw_request_info *info,
769 union iwreq_data *wrqu, char *extra)
770{
771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700772 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700773 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
774 tCsrScanResultInfo *pScanResult;
775 eHalStatus status = eHAL_STATUS_SUCCESS;
776 hdd_scan_info_t scanInfo;
777 tScanResultHandle pResult;
778 int i = 0;
779
780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
781 __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
782 ENTER();
783
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700784 if (TRUE == pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -0700785 {
786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
787 return -EAGAIN;
788 }
789
790 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
792 return -EAGAIN;
793 }
794
795 scanInfo.dev = dev;
796 scanInfo.start = extra;
797 scanInfo.info = info;
798
799 if (0 == wrqu->data.length)
800 {
801 scanInfo.end = extra + IW_SCAN_MAX_DATA;
802 }
803 else
804 {
805 scanInfo.end = extra + wrqu->data.length;
806 }
807
808 status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult);
809
810 if (NULL == pResult)
811 {
812 // no scan results
813 hddLog(LOG1,"iw_get_scan: NULL Scan Result ");
814 return 0;
815 }
816
817 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
818
819 while (pScanResult)
820 {
821 status = hdd_IndicateScanResult(&scanInfo, pScanResult);
822 if (0 != status)
823 {
824 break;
825 }
826 i++;
827 pScanResult = sme_ScanResultGetNext(hHal, pResult);
828 }
829
830 sme_ScanResultPurge(hHal, pResult);
831
832 EXIT();
833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
834 return status;
835}
836
837#if 0
838static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext,
839 tANI_U32 scanId, eCsrScanStatus status)
840{
841 struct net_device *dev = (struct net_device *) pContext;
842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
843 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
844 union iwreq_data wrqu;
845 int we_event;
846 char *msg;
847 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
848 ENTER();
849
850 hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700851 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700852 (int) scanId, (int) status);
853
854 /* Check the scanId */
855 if (pwextBuf->scanId != scanId)
856 {
857 hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700858 "scanId = %d ", __func__, (int) pwextBuf->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 (int) scanId);
860 }
861
862 /* Scan is no longer pending */
863 pwextBuf->mScanPending = VOS_FALSE;
864
865 // notify any applications that may be interested
866 memset(&wrqu, '\0', sizeof(wrqu));
867 we_event = SIOCGIWSCAN;
868 msg = NULL;
869 wireless_send_event(dev, we_event, &wrqu, msg);
870
871 vos_status = vos_event_set(&pwextBuf->vosevent);
872
873 if (!VOS_IS_STATUS_SUCCESS(vos_status))
874 {
875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!"));
876 return VOS_STATUS_E_FAILURE;
877 }
878
879 EXIT();
880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
881
882 return eHAL_STATUS_SUCCESS;
883}
884#endif
885
886int iw_set_cscan(struct net_device *dev, struct iw_request_info *info,
887 union iwreq_data *wrqu, char *extra)
888{
889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700891 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
892 tCsrScanRequest scanRequest;
893 v_U32_t scanId = 0;
894 eHalStatus status = eHAL_STATUS_SUCCESS;
895 v_U8_t channelIdx;
896
897 ENTER();
898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
899
900#ifdef WLAN_BTAMP_FEATURE
901 //Scan not supported when AMP traffic is on.
902 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
903 {
904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
905 return eHAL_STATUS_SUCCESS;
906 }
907#endif
908
909 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
910 {
911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
912 return eHAL_STATUS_SUCCESS;
913 }
914
915 vos_mem_zero( &scanRequest, sizeof(scanRequest));
916 if (NULL != wrqu->data.pointer)
917 {
918 char *str_ptr = NULL;
919 tCsrSSIDInfo *SsidInfo = NULL;
920 int num_ssid = 0;
921 int i, j, ssid_start;
922 hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP;
923
Rajeev Kumarbe97df02013-10-24 18:30:39 -0700924 str_ptr = extra;
Jeff Johnson295189b2012-06-20 16:38:30 -0700925
926 i = WEXT_CSCAN_HEADER_SIZE;
927
928 if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] )
929 {
930 scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i];
931 ++i;
932 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700933 pHddCtx->scan_info.scan_pending_option = scanPendingOption;
Jeff Johnson295189b2012-06-20 16:38:30 -0700934
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700935 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 {
937 hddLog(LOG1,"%s: mScanPending is TRUE",__func__);
938 /* If any scan is pending, just giveup this scan request */
939 if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption)
940 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700941 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 return eHAL_STATUS_SUCCESS;
943 }
944 /* If any scan pending, wait till finish current scan,
945 and try this scan request when previous scan finish */
946 else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption)
947 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700948 pHddCtx->scan_info.waitScanResult = TRUE;
949 vos_event_reset(&pHddCtx->scan_info.scan_finished_event);
950 if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event,
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 WEXT_CSCAN_SCAN_DONE_WAIT_TIME))
952 {
953 hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__);
954 return eHAL_STATUS_SUCCESS;
955 }
956 }
957 /* Piggyback previous scan result */
958 else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption)
959 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700960 pHddCtx->scan_info.waitScanResult = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700961 return eHAL_STATUS_SUCCESS;
962 }
963 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700964 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700965
966 /* Check for scan IE */
967 while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] )
968 {
969 /* ssid_len */
970 if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION)
971 {
972 /* total number of ssid's */
973 num_ssid++;
974 /* increment length filed */
975 i += str_ptr[i] + 1;
976 }
977 /* i should be saved and it will be pointing to 'C' */
978 }
979
980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid);
981 if( num_ssid )
982 {
983 /* To be fixed in SME and PE: override the number of ssid with 1,
984 * as SME and PE does not handle multiple SSID in scan request
985 * */
986 scanRequest.SSIDs.numOfSSIDs = num_ssid;
987 /* Allocate num_ssid tCsrSSIDInfo structure */
988 SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo));
989 if(NULL == scanRequest.SSIDs.SSIDList) {
990 hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer");
991 return -ENOMEM;
992 }
993
994 /* copy all the ssid's and their length */
995 ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */
996 for(j = 0; j < num_ssid; j++) {
997 if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){
998 scanRequest.SSIDs.numOfSSIDs -= 1;
999 } else{
1000 /* get the ssid length */
1001 SsidInfo->SSID.length = str_ptr[ssid_start++];
1002 vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length);
Arif Hussain6d2a3322013-11-17 19:50:10 -08001003 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001004 }
1005 /* skipping length */
1006 ssid_start += str_ptr[ssid_start - 1] + 1;
1007 /* Store next ssid info */
1008 SsidInfo++;
1009 }
1010 }
1011
1012 /* Check for Channel IE */
1013 if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i])
1014 {
1015 if( str_ptr[++i] == 0 )
1016 {
1017 scanRequest.ChannelInfo.numOfChannels = 0;
1018 scanRequest.ChannelInfo.ChannelList = NULL;
1019 i++;
1020 }
1021 else {
1022
1023 /* increment the counter */
1024 scanRequest.ChannelInfo.numOfChannels = str_ptr[i++];
1025 /* store temp channel list */
1026 /* SME expects 1 byte channel content */
1027 scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t));
1028 if(NULL == scanRequest.ChannelInfo.ChannelList)
1029 {
c_hpothu7f63e882013-10-02 19:13:35 +05301030 hddLog(LOGE, "memory alloc failed for channel list creation");
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 status = -ENOMEM;
1032 goto exit_point;
1033 }
1034
1035 for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++)
1036 {
1037 /* SCAN request from upper layer has 2 bytes channel */
1038 scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i];
1039 i += sizeof(v_U16_t);
1040 }
1041 }
1042 }
1043
1044 /* Set default */
1045 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1046 scanRequest.minChnTime = 0;
1047 scanRequest.maxChnTime = 0;
1048
1049 /* Now i is pointing to passive dwell dwell time */
1050 /* 'P',min dwell time, max dwell time */
1051 /* next two offsets contain min and max channel time */
1052 if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) )
1053 {
1054 /* No SSID specified, num_ssid == 0, then start paasive scan */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001055 if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 {
1057 scanRequest.scanType = eSIR_PASSIVE_SCAN;
1058 scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time;
1059 scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time;
1060 i++;
1061 }
1062 else
1063 {
1064 i += 3;
1065 }
1066 }
1067
1068 /* H indicates active channel time */
1069 if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) )
1070 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001071 if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 {
1073 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1074 scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time;
1075 scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time;
1076 i++;
1077 }
1078 else
1079 {
1080 i +=3;
1081 }
1082 }
1083 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
1084 /* set requestType to full scan */
1085 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001086 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001087
1088 /* if previous genIE is not NULL, update ScanIE */
1089 if(0 != pwextBuf->genIE.length)
1090 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001091 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
1092 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001094 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +05301095 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
1096 {
1097 memcpy( pwextBuf->roamProfile.addIEScan,
1098 pHddCtx->scan_info.scanAddIE.addIEdata,
1099 pHddCtx->scan_info.scanAddIE.length);
1100 pwextBuf->roamProfile.nAddIEScanLength =
1101 pHddCtx->scan_info.scanAddIE.length;
1102 }
1103 else
1104 {
1105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1106 "Invalid ScanIE, Length is %d",
1107 pwextBuf->genIE.length);
1108 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001109
1110 /* clear previous genIE after use it */
1111 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
1112 }
1113
1114 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001115 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
1116 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001118 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
1119 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 }
1121
1122 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal,
1123 pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
1124 if( !HAL_STATUS_SUCCESS(status) )
1125 {
1126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: SME scan fail status %d !!!",__func__, status);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001127 pHddCtx->scan_info.mScanPending = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001128 status = -EINVAL;
1129 goto exit_point;
1130 }
1131
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001132 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001133
1134 } //end of data->pointer
1135 else {
1136 status = -1;
1137 }
1138
1139exit_point:
1140
1141 /* free ssidlist */
1142 if (scanRequest.SSIDs.SSIDList)
1143 {
1144 vos_mem_free(scanRequest.SSIDs.SSIDList);
1145 }
1146 /* free the channel list */
1147 if(scanRequest.ChannelInfo.ChannelList)
1148 {
1149 vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList);
1150 }
1151
1152 EXIT();
1153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1154 return status;
1155}
1156
1157/* Abort any MAC scan if in progress */
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301158void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId,
1159 eCsrAbortReason reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07001160{
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301161 sme_AbortMacScan(pHddCtx->hHal, sessionId, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07001162}
1163