blob: 6cbc426f510aaa5ee0e0c729e3295a7d8f4d9b76 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**========================================================================
43
44 \file wlan_hdd_scan.c
45
46 \brief WLAN Host Device Driver implementation
47
48 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
49
50 Qualcomm Confidential and Proprietary.
51
52 ========================================================================*/
53
54/**=========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66 when who what, where, why
67 -------- --- --------------------------------------------------------
68 04/5/09 Shailender Created module.
69
70 ==========================================================================*/
71 /* To extract the Scan results */
72
73/* Add a stream event */
74
75#include <wlan_qct_driver.h>
76#include <wlan_hdd_includes.h>
77#include <vos_api.h>
78#include <palTypes.h>
79#include <aniGlobal.h>
80#include <dot11f.h>
81#ifdef WLAN_BTAMP_FEATURE
82#include "bap_hdd_misc.h"
83#endif
84
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <linux/wireless.h>
86#include <net/cfg80211.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070087
88#define GET_IE_LEN_IN_BSS(lenInBss) ( lenInBss + sizeof(lenInBss) - \
89 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
90
91#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
92#define WEXT_CSCAN_HEADER_SIZE 12
93#define WEXT_CSCAN_SSID_SECTION 'S'
94#define WEXT_CSCAN_CHANNEL_SECTION 'C'
95#define WEXT_CSCAN_NPROBE_SECTION 'N'
96#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
97#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
98#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
99#define WEXT_CSCAN_TYPE_SECTION 'T'
100#define WEXT_CSCAN_PENDING_SECTION 'O'
101#define WEXT_CSCAN_TYPE_DEFAULT 0
102#define WEXT_CSCAN_TYPE_PASSIVE 1
103#define WEXT_CSCAN_PASV_DWELL_TIME 130
104#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
105#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
106#define WEXT_CSCAN_HOME_DWELL_TIME 130
107#define MAX_RATES 12
108
109#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000
110
111typedef struct hdd_scan_info{
112 struct net_device *dev;
113 struct iw_request_info *info;
114 char *start;
115 char *end;
116} hdd_scan_info_t, *hdd_scan_info_tp;
117
118static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate)
119{
120
121 /** Slightly more sophisticated processing has to take place here.
122 Basic rates are rounded DOWN. HT rates are rounded UP.*/
123 return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2);
124}
125
126
127static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event )
128{
129 struct iw_event event;
130
131 *last_event = *current_event;
132 vos_mem_zero(&event, sizeof (struct iw_event));
133 event.cmd = cmd;
134 event.u.data.flags = 1;
135 event.u.data.length = length;
136 *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data);
137
138 if(*last_event == *current_event)
139 {
140 /* no space to add event */
141 return -E2BIG; /* Error code, may be E2BIG */
142 }
143
144 return 0;
145}
146
147/**---------------------------------------------------------------------------
148
149 \brief hdd_GetWPARSNIEs() -
150
151 This function extract the WPA/RSN IE from the Bss descriptor IEs fields
152
153 \param - ieFields - Pointer to the Bss Descriptor IEs.
154 - ie_length - IE Length.
155 - last_event -Points to the last event.
156 - current_event - Points to the
157 \return - 0 for success, non zero for failure
158
159 --------------------------------------------------------------------------*/
160
161
162/* Extract the WPA and/or RSN IEs */
163static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo )
164{
165 v_U8_t eid, elen, *element;
166 v_U16_t tie_length=0;
167
168 ENTER();
169
170 element = ieFields;
171 tie_length = ie_length;
172
173 while( tie_length > 2 && element != NULL )
174 {
175 eid = element[0];
176 elen = element[1];
177
178 /*If element length is greater than total remaining ie length,
179 *break the loop*/
180 if ((elen+2) > tie_length)
181 break;
182
183 switch(eid)
184 {
185 case DOT11F_EID_WPA:
186 case DOT11F_EID_RSN:
187#ifdef FEATURE_WLAN_WAPI
188 case DOT11F_EID_WAPI:
189#endif
190 if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 )
191 return -E2BIG;
192 break;
193
194 default:
195 break;
196 }
197
198 /* Next element */
199 tie_length -= (2 + elen);
200 element += 2 + elen;
201 }
202
203 return 0;
204}
205
206/**---------------------------------------------------------------------------
207
208 \brief hdd_IndicateScanResult() -
209
210 This function returns the scan results to the wpa_supplicant
211
212 \param - scanInfo - Pointer to the scan info structure.
213 - descriptor - Pointer to the Bss Descriptor.
214
215 \return - 0 for success, non zero for failure
216
217 --------------------------------------------------------------------------*/
218#define MAX_CUSTOM_LEN 64
219static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result)
220{
221 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ;
222 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
223 tSirBssDescription *descriptor = &scan_result->BssDescriptor;
224 struct iw_event event;
225 char *current_event = scanInfo->start;
226 char *end = scanInfo->end;
227 char *last_event;
228 char *current_pad;
229 v_U16_t ie_length = 0;
230 v_U16_t capabilityInfo;
231 char *modestr;
232 int error;
233 char custom[MAX_CUSTOM_LEN];
234 char *p;
235
236 hddLog( LOG1, "hdd_IndicateScanResult %02x:%02x:%02x:%02x:%02x:%02x",
237 descriptor->bssId[0],
238 descriptor->bssId[1],
239 descriptor->bssId[2],
240 descriptor->bssId[3],
241 descriptor->bssId[4],
242 descriptor->bssId[5]);
243
244 error = 0;
245 last_event = current_event;
246 vos_mem_zero(&event, sizeof (event));
247
248 /* BSSID */
249 event.cmd = SIOCGIWAP;
250 event.u.ap_addr.sa_family = ARPHRD_ETHER;
251 vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId,
252 sizeof (descriptor->bssId));
253 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
254 &event, IW_EV_ADDR_LEN);
255
256 if (last_event == current_event)
257 {
258 /* no space to add event */
259 /* Error code may be E2BIG */
260 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP ");
261 return -E2BIG;
262 }
263
264 last_event = current_event;
265 vos_mem_zero(&event, sizeof (struct iw_event));
266
267 /* Protocol Name */
268 event.cmd = SIOCGIWNAME;
269
270 switch (descriptor->nwType)
271 {
272 case eSIR_11A_NW_TYPE:
273 modestr = "a";
274 break;
275 case eSIR_11B_NW_TYPE:
276 modestr = "b";
277 break;
278 case eSIR_11G_NW_TYPE:
279 modestr = "g";
280 break;
281 case eSIR_11N_NW_TYPE:
282 modestr = "n";
283 break;
284 default:
285 hddLog( LOGW, "%s: Unknown network type [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700286 __func__, descriptor->nwType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 modestr = "?";
288 break;
289 }
290 snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr);
291 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
292 &event, IW_EV_CHAR_LEN);
293
294 if (last_event == current_event)
295 { /* no space to add event */
296 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME");
297 /* Error code, may be E2BIG */
298 return -E2BIG;
299 }
300
301 last_event = current_event;
302 vos_mem_zero( &event, sizeof (struct iw_event));
303
304 /*Freq*/
305 event.cmd = SIOCGIWFREQ;
306
307 event.u.freq.m = descriptor->channelId;
308 event.u.freq.e = 0;
309 event.u.freq.i = 0;
310 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
311 &event, IW_EV_FREQ_LEN);
312
313 if (last_event == current_event)
314 { /* no space to add event */
315 return -E2BIG;
316 }
317
318 last_event = current_event;
319 vos_mem_zero( &event, sizeof (struct iw_event));
320
321 /* BSS Mode */
322 event.cmd = SIOCGIWMODE;
323
324 capabilityInfo = descriptor->capabilityInfo;
325
326 if (SIR_MAC_GET_ESS(capabilityInfo))
327 {
328 event.u.mode = IW_MODE_INFRA;
329 }
330 else if (SIR_MAC_GET_IBSS(capabilityInfo))
331 {
332 event.u.mode = IW_MODE_ADHOC;
333 }
334 else
335 {
336 /* neither ESS or IBSS */
337 event.u.mode = IW_MODE_AUTO;
338 }
339
340 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
341 &event, IW_EV_UINT_LEN);
342
343 if (last_event == current_event)
344 { /* no space to add event */
345 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE");
346 return -E2BIG;
347 }
348 /* To extract SSID */
349 ie_length = GET_IE_LEN_IN_BSS( descriptor->length );
350
351 if (ie_length > 0)
352 {
Madan Mohan Koyyalamudi729972c2012-10-21 12:39:24 -0700353 /* dot11BeaconIEs is a large struct, so we make it static to
354 avoid stack overflow. This API is only invoked via ioctl,
355 so it is serialized by the kernel rtnl_lock and hence does
356 not need to be reentrant */
357 static tDot11fBeaconIEs dot11BeaconIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 tDot11fIESSID *pDot11SSID;
359 tDot11fIESuppRates *pDot11SuppRates;
360 tDot11fIEExtSuppRates *pDot11ExtSuppRates;
361 tDot11fIEHTCaps *pDot11IEHTCaps;
362 int numBasicRates = 0;
363 int maxNumRates = 0;
364
365 pDot11IEHTCaps = NULL;
366
367 dot11fUnpackBeaconIEs ((tpAniSirGlobal)
368 hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs);
369
370 pDot11SSID = &dot11BeaconIEs.SSID;
371
372
373 if (pDot11SSID->present ) {
374 last_event = current_event;
375 vos_mem_zero (&event, sizeof (struct iw_event));
376
377 event.cmd = SIOCGIWESSID;
378 event.u.data.flags = 1;
379 event.u.data.length = scan_result->ssId.length;
380 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
381 &event, (char *)scan_result->ssId.ssId);
382
383 if(last_event == current_event)
384 { /* no space to add event */
385 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
386 return -E2BIG;
387 }
388 }
389
390 if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, &current_event, scanInfo ) < 0 )
391 {
392 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
393 return -E2BIG;
394 }
395
396 last_event = current_event;
397 current_pad = current_event + IW_EV_LCP_LEN;
398 vos_mem_zero( &event, sizeof (struct iw_event));
399
400 /*Rates*/
401 event.cmd = SIOCGIWRATE;
402
403
404 pDot11SuppRates = &dot11BeaconIEs.SuppRates;
405
406 if (pDot11SuppRates->present )
407 {
408 int i;
409
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700410 numBasicRates = pDot11SuppRates->num_rates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700411 for (i=0; i<pDot11SuppRates->num_rates; i++)
412 {
413 if (0 != (pDot11SuppRates->rates[i] & 0x7F))
414 {
415 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
416 &pDot11SuppRates->rates[i]);
417
418 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
419 current_pad, end, &event, IW_EV_PARAM_LEN);
420 }
421 }
422
423 }
424
425 pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates;
426
427 if (pDot11ExtSuppRates->present )
428 {
429 int i,no_of_rates;
430 maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates;
431
432 /* Check to make sure the total number of rates
433 doesn't exceed IW_MAX_BITRATES */
434
435 maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES);
436
437 if((maxNumRates - numBasicRates) > MAX_RATES)
438 {
439 no_of_rates = MAX_RATES;
440 hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates ");
441 }
442 else
443 {
444 no_of_rates = maxNumRates - numBasicRates;
445 }
446 for ( i=0; i< no_of_rates ; i++ )
447 {
448 if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F))
449 {
450 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
451 &pDot11ExtSuppRates->rates[i]);
452
453 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
454 current_pad, end, &event, IW_EV_PARAM_LEN);
455 }
456 }
457 }
458
459
460 if ((current_pad - current_event) >= IW_EV_LCP_LEN)
461 {
462 current_event = current_pad;
463 }
464 else
465 {
466 if (last_event == current_event)
467 { /* no space to add event */
468 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE");
469 return -E2BIG;
470 }
471 }
472
473 last_event = current_event;
474 vos_mem_zero (&event, sizeof (struct iw_event));
475
476
477 event.cmd = SIOCGIWENCODE;
478
479 if (SIR_MAC_GET_PRIVACY(capabilityInfo))
480 {
481 event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
482 }
483 else
484 {
485 event.u.data.flags = IW_ENCODE_DISABLED;
486 }
487 event.u.data.length = 0;
488
489 current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid);
490
491
492 if(last_event == current_event)
493 { /* no space to add event
494 Error code, may be E2BIG */
495 return -E2BIG;
496 }
497 }
498
499 last_event = current_event;
500 vos_mem_zero( &event, sizeof (struct iw_event));
501
502 /*RSSI*/
503 event.cmd = IWEVQUAL;
504 event.u.qual.qual = descriptor->rssi;
505 event.u.qual.noise = descriptor->sinr;
506
507 /*To keep the rssi icon of the connected AP in the scan window
508 *and the rssi icon of the wireless networks in sync */
509 if (( eConnectionState_Associated ==
510 pAdapter->sessionCtx.station.conn_info.connState ) &&
511 ( VOS_TRUE == vos_mem_compare(descriptor->bssId,
512 pAdapter->sessionCtx.station.conn_info.bssId,
513 WNI_CFG_BSSID_LEN)))
514 {
515 event.u.qual.level = pAdapter->rssi;
516 }
517 else
518 {
519 event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0);
520 }
521
522 event.u.qual.updated = IW_QUAL_ALL_UPDATED;
523
524 current_event = iwe_stream_add_event(scanInfo->info,current_event,
525 end, &event, IW_EV_QUAL_LEN);
526
527 if(last_event == current_event)
528 { /* no space to add event */
529 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL");
530 return -E2BIG;
531 }
532
533
534 /* AGE */
535 event.cmd = IWEVCUSTOM;
536 p = custom;
Sameer Thalappilb0a30232013-09-27 15:37:48 -0700537 p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu",
Jeff Johnson295189b2012-06-20 16:38:30 -0700538 vos_timer_get_system_ticks() - descriptor->nReceivedTime);
539 event.u.data.length = p - custom;
540 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
541 &event, custom);
542 if(last_event == current_event)
543 { /* no space to add event */
544 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)");
545 return -E2BIG;
546 }
547
548 scanInfo->start = current_event;
549
550 return 0;
551}
552
553/**---------------------------------------------------------------------------
554
555 \brief hdd_ScanRequestCallback() -
556
557 The sme module calls this callback function once it finish the scan request
558 and this function notifies the scan complete event to the wpa_supplicant.
559
560 \param - halHandle - Pointer to the Hal Handle.
561 - pContext - Pointer to the data context.
562 - scanId - Scan ID.
563 - status - CSR Status.
564 \return - 0 for success, non zero for failure
565
566 --------------------------------------------------------------------------*/
567
568static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext,
569 tANI_U32 scanId, eCsrScanStatus status)
570{
571 struct net_device *dev = (struct net_device *) pContext;
572 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700573 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700574 union iwreq_data wrqu;
575 int we_event;
576 char *msg;
577
578 ENTER();
579
580 hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700581 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 (int) scanId, (int) status);
583
584 /* if there is a scan request pending when the wlan driver is unloaded
585 we may be invoked as SME flushes its pending queue. If that is the
586 case, the underlying net_device may have already been destroyed, so
587 do some quick sanity before proceeding */
588 if (pAdapter->dev != dev)
589 {
590 hddLog(LOGW, "%s: device mismatch %p vs %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700591 __func__, pAdapter->dev, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700592 return eHAL_STATUS_SUCCESS;
593 }
594
595 /* Check the scanId */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700596 if (pHddCtx->scan_info.scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700597 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700598 hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700599 "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 (int) scanId);
601 }
602
603 /* Scan is no longer pending */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700604 pHddCtx->scan_info.mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700605
606 // notify any applications that may be interested
607 memset(&wrqu, '\0', sizeof(wrqu));
608 we_event = SIOCGIWSCAN;
609 msg = NULL;
610 wireless_send_event(dev, we_event, &wrqu, msg);
611
612 EXIT();
613
614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
615
616 return eHAL_STATUS_SUCCESS;
617}
618
619/**---------------------------------------------------------------------------
620
621 \brief iw_set_scan() -
622
623 This function process the scan request from the wpa_supplicant
624 and set the scan request to the SME
625
626 \param - dev - Pointer to the net device.
627 - info - Pointer to the iw_request_info.
628 - wrqu - Pointer to the iwreq_data.
629 - extra - Pointer to the data.
630 \return - 0 for success, non zero for failure
631
632 --------------------------------------------------------------------------*/
633
634
635int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
636 union iwreq_data *wrqu, char *extra)
637{
638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700639 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700640 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
641 tCsrScanRequest scanRequest;
642 v_U32_t scanId = 0;
643 eHalStatus status = eHAL_STATUS_SUCCESS;
644 struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
645
646 ENTER();
647
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
649
650#ifdef WLAN_BTAMP_FEATURE
651 //Scan not supported when AMP traffic is on.
652 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
653 {
654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
655 return eHAL_STATUS_SUCCESS;
656 }
657#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700658 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 {
660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
661 return eHAL_STATUS_SUCCESS;
662 }
663
664 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
666 return eHAL_STATUS_SUCCESS;
667 }
668 vos_mem_zero( &scanRequest, sizeof(scanRequest));
669
670 if (NULL != wrqu->data.pointer)
671 {
672 /* set scanType, active or passive */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700673 if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 {
675 scanRequest.scanType = eSIR_ACTIVE_SCAN;
676 }
677 else
678 {
679 scanRequest.scanType = eSIR_PASSIVE_SCAN;
680 }
681
682 /* set bssid using sockaddr from iw_scan_req */
683 vos_mem_copy(scanRequest.bssid,
684 &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );
685
686 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
687
688 if(scanReq->essid_len) {
689 scanRequest.SSIDs.numOfSSIDs = 1;
690 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
691 if(scanRequest.SSIDs.SSIDList) {
692 scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len;
693 vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len);
694 }
695 else
696 {
697 scanRequest.SSIDs.numOfSSIDs = 0;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 VOS_ASSERT(0);
700 }
701 }
702 }
703
704 /* set min and max channel time */
705 scanRequest.minChnTime = scanReq->min_channel_time;
706 scanRequest.maxChnTime = scanReq->max_channel_time;
707
708 }
709 else
710 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700711 if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700712 /* set the scan type to active */
713 scanRequest.scanType = eSIR_ACTIVE_SCAN;
714 } else {
715 scanRequest.scanType = eSIR_PASSIVE_SCAN;
716 }
717
718 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
719
720 /* set min and max channel time to zero */
721 scanRequest.minChnTime = 0;
722 scanRequest.maxChnTime = 0;
723 }
724
725 /* set BSSType to default type */
726 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
727
728 /*Scan all the channels */
729 scanRequest.ChannelInfo.numOfChannels = 0;
730
731 scanRequest.ChannelInfo.ChannelList = NULL;
732
733 /* set requestType to full scan */
734 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
735
736 /* if previous genIE is not NULL, update ScanIE */
737 if (0 != pwextBuf->genIE.length)
738 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700739 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
740 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -0700741 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700742 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Jeff Johnson295189b2012-06-20 16:38:30 -0700743
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700744 pwextBuf->roamProfile.pAddIEScan = pHddCtx->scan_info.scanAddIE.addIEdata;
745 pwextBuf->roamProfile.nAddIEScanLength = pHddCtx->scan_info.scanAddIE.length;
Jeff Johnson295189b2012-06-20 16:38:30 -0700746
747 /* clear previous genIE after use it */
748 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
749 }
750
751 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700752 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
753 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -0700754 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700755 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
756 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 }
758
759 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
760 if (!HAL_STATUS_SUCCESS(status))
761 {
762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status);
763 goto error;
764 }
765
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700766 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700767
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700768 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700769
770error:
771 if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
772 vos_mem_free(scanRequest.SSIDs.SSIDList);
773
774 EXIT();
775
776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
777 return status;
778}
779
780/**---------------------------------------------------------------------------
781
782 \brief iw_get_scan() -
783
784 This function returns the scan results to the wpa_supplicant
785
786 \param - dev - Pointer to the net device.
787 - info - Pointer to the iw_request_info.
788 - wrqu - Pointer to the iwreq_data.
789 - extra - Pointer to the data.
790 \return - 0 for success, non zero for failure
791
792 --------------------------------------------------------------------------*/
793
794
795int iw_get_scan(struct net_device *dev,
796 struct iw_request_info *info,
797 union iwreq_data *wrqu, char *extra)
798{
799 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700800 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700801 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
802 tCsrScanResultInfo *pScanResult;
803 eHalStatus status = eHAL_STATUS_SUCCESS;
804 hdd_scan_info_t scanInfo;
805 tScanResultHandle pResult;
806 int i = 0;
807
808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
809 __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
810 ENTER();
811
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700812 if (TRUE == pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 {
814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
815 return -EAGAIN;
816 }
817
818 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
820 return -EAGAIN;
821 }
822
823 scanInfo.dev = dev;
824 scanInfo.start = extra;
825 scanInfo.info = info;
826
827 if (0 == wrqu->data.length)
828 {
829 scanInfo.end = extra + IW_SCAN_MAX_DATA;
830 }
831 else
832 {
833 scanInfo.end = extra + wrqu->data.length;
834 }
835
836 status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult);
837
838 if (NULL == pResult)
839 {
840 // no scan results
841 hddLog(LOG1,"iw_get_scan: NULL Scan Result ");
842 return 0;
843 }
844
845 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
846
847 while (pScanResult)
848 {
849 status = hdd_IndicateScanResult(&scanInfo, pScanResult);
850 if (0 != status)
851 {
852 break;
853 }
854 i++;
855 pScanResult = sme_ScanResultGetNext(hHal, pResult);
856 }
857
858 sme_ScanResultPurge(hHal, pResult);
859
860 EXIT();
861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
862 return status;
863}
864
865#if 0
866static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext,
867 tANI_U32 scanId, eCsrScanStatus status)
868{
869 struct net_device *dev = (struct net_device *) pContext;
870 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
871 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
872 union iwreq_data wrqu;
873 int we_event;
874 char *msg;
875 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
876 ENTER();
877
878 hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700879 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700880 (int) scanId, (int) status);
881
882 /* Check the scanId */
883 if (pwextBuf->scanId != scanId)
884 {
885 hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700886 "scanId = %d ", __func__, (int) pwextBuf->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 (int) scanId);
888 }
889
890 /* Scan is no longer pending */
891 pwextBuf->mScanPending = VOS_FALSE;
892
893 // notify any applications that may be interested
894 memset(&wrqu, '\0', sizeof(wrqu));
895 we_event = SIOCGIWSCAN;
896 msg = NULL;
897 wireless_send_event(dev, we_event, &wrqu, msg);
898
899 vos_status = vos_event_set(&pwextBuf->vosevent);
900
901 if (!VOS_IS_STATUS_SUCCESS(vos_status))
902 {
903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!"));
904 return VOS_STATUS_E_FAILURE;
905 }
906
907 EXIT();
908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
909
910 return eHAL_STATUS_SUCCESS;
911}
912#endif
913
914int iw_set_cscan(struct net_device *dev, struct iw_request_info *info,
915 union iwreq_data *wrqu, char *extra)
916{
917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700918 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
920 tCsrScanRequest scanRequest;
921 v_U32_t scanId = 0;
922 eHalStatus status = eHAL_STATUS_SUCCESS;
923 v_U8_t channelIdx;
924
925 ENTER();
926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
927
928#ifdef WLAN_BTAMP_FEATURE
929 //Scan not supported when AMP traffic is on.
930 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
931 {
932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
933 return eHAL_STATUS_SUCCESS;
934 }
935#endif
936
937 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
938 {
939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
940 return eHAL_STATUS_SUCCESS;
941 }
942
943 vos_mem_zero( &scanRequest, sizeof(scanRequest));
944 if (NULL != wrqu->data.pointer)
945 {
946 char *str_ptr = NULL;
947 tCsrSSIDInfo *SsidInfo = NULL;
948 int num_ssid = 0;
949 int i, j, ssid_start;
950 hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP;
951
952 /* save the original buffer */
953 str_ptr = wrqu->data.pointer;
954
955 i = WEXT_CSCAN_HEADER_SIZE;
956
957 if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] )
958 {
959 scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i];
960 ++i;
961 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700962 pHddCtx->scan_info.scan_pending_option = scanPendingOption;
Jeff Johnson295189b2012-06-20 16:38:30 -0700963
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700964 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 {
966 hddLog(LOG1,"%s: mScanPending is TRUE",__func__);
967 /* If any scan is pending, just giveup this scan request */
968 if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption)
969 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700970 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 return eHAL_STATUS_SUCCESS;
972 }
973 /* If any scan pending, wait till finish current scan,
974 and try this scan request when previous scan finish */
975 else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption)
976 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700977 pHddCtx->scan_info.waitScanResult = TRUE;
978 vos_event_reset(&pHddCtx->scan_info.scan_finished_event);
979 if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event,
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 WEXT_CSCAN_SCAN_DONE_WAIT_TIME))
981 {
982 hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__);
983 return eHAL_STATUS_SUCCESS;
984 }
985 }
986 /* Piggyback previous scan result */
987 else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption)
988 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700989 pHddCtx->scan_info.waitScanResult = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 return eHAL_STATUS_SUCCESS;
991 }
992 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700993 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700994
995 /* Check for scan IE */
996 while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] )
997 {
998 /* ssid_len */
999 if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION)
1000 {
1001 /* total number of ssid's */
1002 num_ssid++;
1003 /* increment length filed */
1004 i += str_ptr[i] + 1;
1005 }
1006 /* i should be saved and it will be pointing to 'C' */
1007 }
1008
1009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid);
1010 if( num_ssid )
1011 {
1012 /* To be fixed in SME and PE: override the number of ssid with 1,
1013 * as SME and PE does not handle multiple SSID in scan request
1014 * */
1015 scanRequest.SSIDs.numOfSSIDs = num_ssid;
1016 /* Allocate num_ssid tCsrSSIDInfo structure */
1017 SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo));
1018 if(NULL == scanRequest.SSIDs.SSIDList) {
1019 hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer");
1020 return -ENOMEM;
1021 }
1022
1023 /* copy all the ssid's and their length */
1024 ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */
1025 for(j = 0; j < num_ssid; j++) {
1026 if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){
1027 scanRequest.SSIDs.numOfSSIDs -= 1;
1028 } else{
1029 /* get the ssid length */
1030 SsidInfo->SSID.length = str_ptr[ssid_start++];
1031 vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length);
1032 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s\n", j, SsidInfo->SSID.ssId);
1033 }
1034 /* skipping length */
1035 ssid_start += str_ptr[ssid_start - 1] + 1;
1036 /* Store next ssid info */
1037 SsidInfo++;
1038 }
1039 }
1040
1041 /* Check for Channel IE */
1042 if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i])
1043 {
1044 if( str_ptr[++i] == 0 )
1045 {
1046 scanRequest.ChannelInfo.numOfChannels = 0;
1047 scanRequest.ChannelInfo.ChannelList = NULL;
1048 i++;
1049 }
1050 else {
1051
1052 /* increment the counter */
1053 scanRequest.ChannelInfo.numOfChannels = str_ptr[i++];
1054 /* store temp channel list */
1055 /* SME expects 1 byte channel content */
1056 scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t));
1057 if(NULL == scanRequest.ChannelInfo.ChannelList)
1058 {
1059 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "memory alloc failed for channel list creation");
1060 status = -ENOMEM;
1061 goto exit_point;
1062 }
1063
1064 for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++)
1065 {
1066 /* SCAN request from upper layer has 2 bytes channel */
1067 scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i];
1068 i += sizeof(v_U16_t);
1069 }
1070 }
1071 }
1072
1073 /* Set default */
1074 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1075 scanRequest.minChnTime = 0;
1076 scanRequest.maxChnTime = 0;
1077
1078 /* Now i is pointing to passive dwell dwell time */
1079 /* 'P',min dwell time, max dwell time */
1080 /* next two offsets contain min and max channel time */
1081 if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) )
1082 {
1083 /* No SSID specified, num_ssid == 0, then start paasive scan */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001084 if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001085 {
1086 scanRequest.scanType = eSIR_PASSIVE_SCAN;
1087 scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time;
1088 scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time;
1089 i++;
1090 }
1091 else
1092 {
1093 i += 3;
1094 }
1095 }
1096
1097 /* H indicates active channel time */
1098 if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) )
1099 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001100 if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001101 {
1102 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1103 scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time;
1104 scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time;
1105 i++;
1106 }
1107 else
1108 {
1109 i +=3;
1110 }
1111 }
1112 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
1113 /* set requestType to full scan */
1114 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001115 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001116
1117 /* if previous genIE is not NULL, update ScanIE */
1118 if(0 != pwextBuf->genIE.length)
1119 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001120 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
1121 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001123 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Jeff Johnson295189b2012-06-20 16:38:30 -07001124
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001125 pwextBuf->roamProfile.pAddIEScan = pHddCtx->scan_info.scanAddIE.addIEdata;
1126 pwextBuf->roamProfile.nAddIEScanLength = pHddCtx->scan_info.scanAddIE.length;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127
1128 /* clear previous genIE after use it */
1129 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
1130 }
1131
1132 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001133 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
1134 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -07001135 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001136 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
1137 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 }
1139
1140 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal,
1141 pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
1142 if( !HAL_STATUS_SUCCESS(status) )
1143 {
1144 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 -07001145 pHddCtx->scan_info.mScanPending = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001146 status = -EINVAL;
1147 goto exit_point;
1148 }
1149
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001150 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001151
1152 } //end of data->pointer
1153 else {
1154 status = -1;
1155 }
1156
1157exit_point:
1158
1159 /* free ssidlist */
1160 if (scanRequest.SSIDs.SSIDList)
1161 {
1162 vos_mem_free(scanRequest.SSIDs.SSIDList);
1163 }
1164 /* free the channel list */
1165 if(scanRequest.ChannelInfo.ChannelList)
1166 {
1167 vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList);
1168 }
1169
1170 EXIT();
1171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1172 return status;
1173}
1174
1175/* Abort any MAC scan if in progress */
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05301176void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId)
Jeff Johnson295189b2012-06-20 16:38:30 -07001177{
Madan Mohan Koyyalamudiff3a7152013-06-13 14:47:55 +05301178 sme_AbortMacScan(pHddCtx->hHal, sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001179}
1180