blob: 549cff9b289849a7b3d904d1da433e38eb6c849e [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 */
c_hpothu7f63e882013-10-02 19:13:35 +0530141 hddLog( LOGW, "%s: no space left to add event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700142 return -E2BIG; /* Error code, may be E2BIG */
143 }
144
145 return 0;
146}
147
148/**---------------------------------------------------------------------------
149
150 \brief hdd_GetWPARSNIEs() -
151
152 This function extract the WPA/RSN IE from the Bss descriptor IEs fields
153
154 \param - ieFields - Pointer to the Bss Descriptor IEs.
155 - ie_length - IE Length.
156 - last_event -Points to the last event.
157 - current_event - Points to the
158 \return - 0 for success, non zero for failure
159
160 --------------------------------------------------------------------------*/
161
162
163/* Extract the WPA and/or RSN IEs */
164static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo )
165{
166 v_U8_t eid, elen, *element;
167 v_U16_t tie_length=0;
168
169 ENTER();
170
171 element = ieFields;
172 tie_length = ie_length;
173
174 while( tie_length > 2 && element != NULL )
175 {
176 eid = element[0];
177 elen = element[1];
178
179 /*If element length is greater than total remaining ie length,
180 *break the loop*/
181 if ((elen+2) > tie_length)
182 break;
183
184 switch(eid)
185 {
186 case DOT11F_EID_WPA:
187 case DOT11F_EID_RSN:
188#ifdef FEATURE_WLAN_WAPI
189 case DOT11F_EID_WAPI:
190#endif
191 if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 )
192 return -E2BIG;
193 break;
194
195 default:
196 break;
197 }
198
199 /* Next element */
200 tie_length -= (2 + elen);
201 element += 2 + elen;
202 }
203
204 return 0;
205}
206
207/**---------------------------------------------------------------------------
208
209 \brief hdd_IndicateScanResult() -
210
211 This function returns the scan results to the wpa_supplicant
212
213 \param - scanInfo - Pointer to the scan info structure.
214 - descriptor - Pointer to the Bss Descriptor.
215
216 \return - 0 for success, non zero for failure
217
218 --------------------------------------------------------------------------*/
219#define MAX_CUSTOM_LEN 64
220static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result)
221{
222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ;
223 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
224 tSirBssDescription *descriptor = &scan_result->BssDescriptor;
225 struct iw_event event;
226 char *current_event = scanInfo->start;
227 char *end = scanInfo->end;
228 char *last_event;
229 char *current_pad;
230 v_U16_t ie_length = 0;
231 v_U16_t capabilityInfo;
232 char *modestr;
233 int error;
234 char custom[MAX_CUSTOM_LEN];
235 char *p;
236
Arif Hussain24bafea2013-11-15 15:10:03 -0800237 hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR,
238 MAC_ADDR_ARRAY(descriptor->bssId));
Jeff Johnson295189b2012-06-20 16:38:30 -0700239
240 error = 0;
241 last_event = current_event;
242 vos_mem_zero(&event, sizeof (event));
243
244 /* BSSID */
245 event.cmd = SIOCGIWAP;
246 event.u.ap_addr.sa_family = ARPHRD_ETHER;
247 vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId,
248 sizeof (descriptor->bssId));
249 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
250 &event, IW_EV_ADDR_LEN);
251
252 if (last_event == current_event)
253 {
254 /* no space to add event */
255 /* Error code may be E2BIG */
256 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP ");
257 return -E2BIG;
258 }
259
260 last_event = current_event;
261 vos_mem_zero(&event, sizeof (struct iw_event));
262
263 /* Protocol Name */
264 event.cmd = SIOCGIWNAME;
265
266 switch (descriptor->nwType)
267 {
268 case eSIR_11A_NW_TYPE:
269 modestr = "a";
270 break;
271 case eSIR_11B_NW_TYPE:
272 modestr = "b";
273 break;
274 case eSIR_11G_NW_TYPE:
275 modestr = "g";
276 break;
277 case eSIR_11N_NW_TYPE:
278 modestr = "n";
279 break;
280 default:
281 hddLog( LOGW, "%s: Unknown network type [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700282 __func__, descriptor->nwType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 modestr = "?";
284 break;
285 }
286 snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr);
287 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
288 &event, IW_EV_CHAR_LEN);
289
290 if (last_event == current_event)
291 { /* no space to add event */
292 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME");
293 /* Error code, may be E2BIG */
294 return -E2BIG;
295 }
296
297 last_event = current_event;
298 vos_mem_zero( &event, sizeof (struct iw_event));
299
300 /*Freq*/
301 event.cmd = SIOCGIWFREQ;
302
303 event.u.freq.m = descriptor->channelId;
304 event.u.freq.e = 0;
305 event.u.freq.i = 0;
306 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
307 &event, IW_EV_FREQ_LEN);
308
309 if (last_event == current_event)
310 { /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530311 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWFREQ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 return -E2BIG;
313 }
314
315 last_event = current_event;
316 vos_mem_zero( &event, sizeof (struct iw_event));
317
318 /* BSS Mode */
319 event.cmd = SIOCGIWMODE;
320
321 capabilityInfo = descriptor->capabilityInfo;
322
323 if (SIR_MAC_GET_ESS(capabilityInfo))
324 {
325 event.u.mode = IW_MODE_INFRA;
326 }
327 else if (SIR_MAC_GET_IBSS(capabilityInfo))
328 {
329 event.u.mode = IW_MODE_ADHOC;
330 }
331 else
332 {
333 /* neither ESS or IBSS */
334 event.u.mode = IW_MODE_AUTO;
335 }
336
337 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
338 &event, IW_EV_UINT_LEN);
339
340 if (last_event == current_event)
341 { /* no space to add event */
342 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE");
343 return -E2BIG;
344 }
345 /* To extract SSID */
346 ie_length = GET_IE_LEN_IN_BSS( descriptor->length );
347
348 if (ie_length > 0)
349 {
Madan Mohan Koyyalamudi729972c2012-10-21 12:39:24 -0700350 /* dot11BeaconIEs is a large struct, so we make it static to
351 avoid stack overflow. This API is only invoked via ioctl,
352 so it is serialized by the kernel rtnl_lock and hence does
353 not need to be reentrant */
354 static tDot11fBeaconIEs dot11BeaconIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -0700355 tDot11fIESSID *pDot11SSID;
356 tDot11fIESuppRates *pDot11SuppRates;
357 tDot11fIEExtSuppRates *pDot11ExtSuppRates;
358 tDot11fIEHTCaps *pDot11IEHTCaps;
359 int numBasicRates = 0;
360 int maxNumRates = 0;
361
362 pDot11IEHTCaps = NULL;
363
364 dot11fUnpackBeaconIEs ((tpAniSirGlobal)
365 hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs);
366
367 pDot11SSID = &dot11BeaconIEs.SSID;
368
369
370 if (pDot11SSID->present ) {
371 last_event = current_event;
372 vos_mem_zero (&event, sizeof (struct iw_event));
373
374 event.cmd = SIOCGIWESSID;
375 event.u.data.flags = 1;
376 event.u.data.length = scan_result->ssId.length;
377 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
378 &event, (char *)scan_result->ssId.ssId);
379
380 if(last_event == current_event)
381 { /* no space to add event */
382 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
383 return -E2BIG;
384 }
385 }
386
387 if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, &current_event, scanInfo ) < 0 )
388 {
389 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
390 return -E2BIG;
391 }
392
393 last_event = current_event;
394 current_pad = current_event + IW_EV_LCP_LEN;
395 vos_mem_zero( &event, sizeof (struct iw_event));
396
397 /*Rates*/
398 event.cmd = SIOCGIWRATE;
399
400
401 pDot11SuppRates = &dot11BeaconIEs.SuppRates;
402
403 if (pDot11SuppRates->present )
404 {
405 int i;
406
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700407 numBasicRates = pDot11SuppRates->num_rates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700408 for (i=0; i<pDot11SuppRates->num_rates; i++)
409 {
410 if (0 != (pDot11SuppRates->rates[i] & 0x7F))
411 {
412 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
413 &pDot11SuppRates->rates[i]);
414
415 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
416 current_pad, end, &event, IW_EV_PARAM_LEN);
417 }
418 }
419
420 }
421
422 pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates;
423
424 if (pDot11ExtSuppRates->present )
425 {
426 int i,no_of_rates;
427 maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates;
428
429 /* Check to make sure the total number of rates
430 doesn't exceed IW_MAX_BITRATES */
431
432 maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES);
433
434 if((maxNumRates - numBasicRates) > MAX_RATES)
435 {
436 no_of_rates = MAX_RATES;
437 hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates ");
438 }
439 else
440 {
441 no_of_rates = maxNumRates - numBasicRates;
442 }
443 for ( i=0; i< no_of_rates ; i++ )
444 {
445 if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F))
446 {
447 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
448 &pDot11ExtSuppRates->rates[i]);
449
450 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
451 current_pad, end, &event, IW_EV_PARAM_LEN);
452 }
453 }
454 }
455
456
457 if ((current_pad - current_event) >= IW_EV_LCP_LEN)
458 {
459 current_event = current_pad;
460 }
461 else
462 {
463 if (last_event == current_event)
464 { /* no space to add event */
465 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE");
466 return -E2BIG;
467 }
468 }
469
470 last_event = current_event;
471 vos_mem_zero (&event, sizeof (struct iw_event));
472
473
474 event.cmd = SIOCGIWENCODE;
475
476 if (SIR_MAC_GET_PRIVACY(capabilityInfo))
477 {
478 event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
479 }
480 else
481 {
482 event.u.data.flags = IW_ENCODE_DISABLED;
483 }
484 event.u.data.length = 0;
485
486 current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid);
487
488
489 if(last_event == current_event)
490 { /* no space to add event
491 Error code, may be E2BIG */
c_hpothu7f63e882013-10-02 19:13:35 +0530492 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWENCODE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700493 return -E2BIG;
494 }
495 }
496
497 last_event = current_event;
498 vos_mem_zero( &event, sizeof (struct iw_event));
499
500 /*RSSI*/
501 event.cmd = IWEVQUAL;
502 event.u.qual.qual = descriptor->rssi;
503 event.u.qual.noise = descriptor->sinr;
504
505 /*To keep the rssi icon of the connected AP in the scan window
506 *and the rssi icon of the wireless networks in sync */
507 if (( eConnectionState_Associated ==
508 pAdapter->sessionCtx.station.conn_info.connState ) &&
509 ( VOS_TRUE == vos_mem_compare(descriptor->bssId,
510 pAdapter->sessionCtx.station.conn_info.bssId,
511 WNI_CFG_BSSID_LEN)))
512 {
513 event.u.qual.level = pAdapter->rssi;
514 }
515 else
516 {
517 event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0);
518 }
519
520 event.u.qual.updated = IW_QUAL_ALL_UPDATED;
521
522 current_event = iwe_stream_add_event(scanInfo->info,current_event,
523 end, &event, IW_EV_QUAL_LEN);
524
525 if(last_event == current_event)
526 { /* no space to add event */
527 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL");
528 return -E2BIG;
529 }
530
531
532 /* AGE */
533 event.cmd = IWEVCUSTOM;
534 p = custom;
Sameer Thalappilb0a30232013-09-27 15:37:48 -0700535 p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu",
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 vos_timer_get_system_ticks() - descriptor->nReceivedTime);
537 event.u.data.length = p - custom;
538 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
539 &event, custom);
540 if(last_event == current_event)
541 { /* no space to add event */
542 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)");
543 return -E2BIG;
544 }
545
546 scanInfo->start = current_event;
547
548 return 0;
549}
550
551/**---------------------------------------------------------------------------
552
553 \brief hdd_ScanRequestCallback() -
554
555 The sme module calls this callback function once it finish the scan request
556 and this function notifies the scan complete event to the wpa_supplicant.
557
558 \param - halHandle - Pointer to the Hal Handle.
559 - pContext - Pointer to the data context.
560 - scanId - Scan ID.
561 - status - CSR Status.
562 \return - 0 for success, non zero for failure
563
564 --------------------------------------------------------------------------*/
565
566static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext,
567 tANI_U32 scanId, eCsrScanStatus status)
568{
569 struct net_device *dev = (struct net_device *) pContext;
570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700571 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700572 union iwreq_data wrqu;
573 int we_event;
574 char *msg;
575
576 ENTER();
577
578 hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700579 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700580 (int) scanId, (int) status);
581
582 /* if there is a scan request pending when the wlan driver is unloaded
583 we may be invoked as SME flushes its pending queue. If that is the
584 case, the underlying net_device may have already been destroyed, so
585 do some quick sanity before proceeding */
586 if (pAdapter->dev != dev)
587 {
588 hddLog(LOGW, "%s: device mismatch %p vs %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700589 __func__, pAdapter->dev, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 return eHAL_STATUS_SUCCESS;
591 }
592
593 /* Check the scanId */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700594 if (pHddCtx->scan_info.scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700595 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700596 hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700597 "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 (int) scanId);
599 }
600
601 /* Scan is no longer pending */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700602 pHddCtx->scan_info.mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700603
604 // notify any applications that may be interested
605 memset(&wrqu, '\0', sizeof(wrqu));
606 we_event = SIOCGIWSCAN;
607 msg = NULL;
608 wireless_send_event(dev, we_event, &wrqu, msg);
609
610 EXIT();
611
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
613
614 return eHAL_STATUS_SUCCESS;
615}
616
617/**---------------------------------------------------------------------------
618
619 \brief iw_set_scan() -
620
621 This function process the scan request from the wpa_supplicant
622 and set the scan request to the SME
623
624 \param - dev - Pointer to the net device.
625 - info - Pointer to the iw_request_info.
626 - wrqu - Pointer to the iwreq_data.
627 - extra - Pointer to the data.
628 \return - 0 for success, non zero for failure
629
630 --------------------------------------------------------------------------*/
631
632
633int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
634 union iwreq_data *wrqu, char *extra)
635{
636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700637 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
639 tCsrScanRequest scanRequest;
640 v_U32_t scanId = 0;
641 eHalStatus status = eHAL_STATUS_SUCCESS;
642 struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
643
644 ENTER();
645
646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
647
648#ifdef WLAN_BTAMP_FEATURE
649 //Scan not supported when AMP traffic is on.
650 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
653 return eHAL_STATUS_SUCCESS;
654 }
655#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700656 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700657 {
658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
659 return eHAL_STATUS_SUCCESS;
660 }
661
662 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
664 return eHAL_STATUS_SUCCESS;
665 }
666 vos_mem_zero( &scanRequest, sizeof(scanRequest));
667
668 if (NULL != wrqu->data.pointer)
669 {
670 /* set scanType, active or passive */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700671 if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -0700672 {
673 scanRequest.scanType = eSIR_ACTIVE_SCAN;
674 }
675 else
676 {
677 scanRequest.scanType = eSIR_PASSIVE_SCAN;
678 }
679
680 /* set bssid using sockaddr from iw_scan_req */
681 vos_mem_copy(scanRequest.bssid,
682 &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );
683
684 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
685
686 if(scanReq->essid_len) {
687 scanRequest.SSIDs.numOfSSIDs = 1;
688 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
689 if(scanRequest.SSIDs.SSIDList) {
690 scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len;
691 vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len);
692 }
693 else
694 {
695 scanRequest.SSIDs.numOfSSIDs = 0;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700697 VOS_ASSERT(0);
698 }
699 }
700 }
701
702 /* set min and max channel time */
703 scanRequest.minChnTime = scanReq->min_channel_time;
704 scanRequest.maxChnTime = scanReq->max_channel_time;
705
706 }
707 else
708 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700709 if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 /* set the scan type to active */
711 scanRequest.scanType = eSIR_ACTIVE_SCAN;
712 } else {
713 scanRequest.scanType = eSIR_PASSIVE_SCAN;
714 }
715
716 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
717
718 /* set min and max channel time to zero */
719 scanRequest.minChnTime = 0;
720 scanRequest.maxChnTime = 0;
721 }
722
723 /* set BSSType to default type */
724 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
725
726 /*Scan all the channels */
727 scanRequest.ChannelInfo.numOfChannels = 0;
728
729 scanRequest.ChannelInfo.ChannelList = NULL;
730
731 /* set requestType to full scan */
732 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
733
734 /* if previous genIE is not NULL, update ScanIE */
735 if (0 != pwextBuf->genIE.length)
736 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700737 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
738 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700740 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +0530741 /* Maximum length of each IE is SIR_MAC_MAX_IE_LENGTH */
742 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
743 {
744 memcpy( pwextBuf->roamProfile.addIEScan,
745 pHddCtx->scan_info.scanAddIE.addIEdata,
746 pHddCtx->scan_info.scanAddIE.length);
747 pwextBuf->roamProfile.nAddIEScanLength =
748 pHddCtx->scan_info.scanAddIE.length;
749 }
750 else
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
753 "Invalid ScanIE, Length is %d", pwextBuf->genIE.length);
754 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 /* clear previous genIE after use it */
756 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
757 }
758
759 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700760 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
761 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -0700762 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700763 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
764 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 }
766
767 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
768 if (!HAL_STATUS_SUCCESS(status))
769 {
770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status);
771 goto error;
772 }
773
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700774 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700776 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700777
778error:
779 if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
780 vos_mem_free(scanRequest.SSIDs.SSIDList);
781
782 EXIT();
783
784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
785 return status;
786}
787
788/**---------------------------------------------------------------------------
789
790 \brief iw_get_scan() -
791
792 This function returns the scan results to the wpa_supplicant
793
794 \param - dev - Pointer to the net device.
795 - info - Pointer to the iw_request_info.
796 - wrqu - Pointer to the iwreq_data.
797 - extra - Pointer to the data.
798 \return - 0 for success, non zero for failure
799
800 --------------------------------------------------------------------------*/
801
802
803int iw_get_scan(struct net_device *dev,
804 struct iw_request_info *info,
805 union iwreq_data *wrqu, char *extra)
806{
807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700808 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700809 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
810 tCsrScanResultInfo *pScanResult;
811 eHalStatus status = eHAL_STATUS_SUCCESS;
812 hdd_scan_info_t scanInfo;
813 tScanResultHandle pResult;
814 int i = 0;
815
816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
817 __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
818 ENTER();
819
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700820 if (TRUE == pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 {
822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
823 return -EAGAIN;
824 }
825
826 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
828 return -EAGAIN;
829 }
830
831 scanInfo.dev = dev;
832 scanInfo.start = extra;
833 scanInfo.info = info;
834
835 if (0 == wrqu->data.length)
836 {
837 scanInfo.end = extra + IW_SCAN_MAX_DATA;
838 }
839 else
840 {
841 scanInfo.end = extra + wrqu->data.length;
842 }
843
844 status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult);
845
846 if (NULL == pResult)
847 {
848 // no scan results
849 hddLog(LOG1,"iw_get_scan: NULL Scan Result ");
850 return 0;
851 }
852
853 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
854
855 while (pScanResult)
856 {
857 status = hdd_IndicateScanResult(&scanInfo, pScanResult);
858 if (0 != status)
859 {
860 break;
861 }
862 i++;
863 pScanResult = sme_ScanResultGetNext(hHal, pResult);
864 }
865
866 sme_ScanResultPurge(hHal, pResult);
867
868 EXIT();
869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
870 return status;
871}
872
873#if 0
874static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext,
875 tANI_U32 scanId, eCsrScanStatus status)
876{
877 struct net_device *dev = (struct net_device *) pContext;
878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
879 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
880 union iwreq_data wrqu;
881 int we_event;
882 char *msg;
883 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
884 ENTER();
885
886 hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700887 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700888 (int) scanId, (int) status);
889
890 /* Check the scanId */
891 if (pwextBuf->scanId != scanId)
892 {
893 hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700894 "scanId = %d ", __func__, (int) pwextBuf->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700895 (int) scanId);
896 }
897
898 /* Scan is no longer pending */
899 pwextBuf->mScanPending = VOS_FALSE;
900
901 // notify any applications that may be interested
902 memset(&wrqu, '\0', sizeof(wrqu));
903 we_event = SIOCGIWSCAN;
904 msg = NULL;
905 wireless_send_event(dev, we_event, &wrqu, msg);
906
907 vos_status = vos_event_set(&pwextBuf->vosevent);
908
909 if (!VOS_IS_STATUS_SUCCESS(vos_status))
910 {
911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!"));
912 return VOS_STATUS_E_FAILURE;
913 }
914
915 EXIT();
916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
917
918 return eHAL_STATUS_SUCCESS;
919}
920#endif
921
922int iw_set_cscan(struct net_device *dev, struct iw_request_info *info,
923 union iwreq_data *wrqu, char *extra)
924{
925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700926 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700927 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
928 tCsrScanRequest scanRequest;
929 v_U32_t scanId = 0;
930 eHalStatus status = eHAL_STATUS_SUCCESS;
931 v_U8_t channelIdx;
932
933 ENTER();
934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
935
936#ifdef WLAN_BTAMP_FEATURE
937 //Scan not supported when AMP traffic is on.
938 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
939 {
940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
941 return eHAL_STATUS_SUCCESS;
942 }
943#endif
944
945 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
946 {
947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
948 return eHAL_STATUS_SUCCESS;
949 }
950
951 vos_mem_zero( &scanRequest, sizeof(scanRequest));
952 if (NULL != wrqu->data.pointer)
953 {
954 char *str_ptr = NULL;
955 tCsrSSIDInfo *SsidInfo = NULL;
956 int num_ssid = 0;
957 int i, j, ssid_start;
958 hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP;
959
Rajeev Kumarbe97df02013-10-24 18:30:39 -0700960 str_ptr = extra;
Jeff Johnson295189b2012-06-20 16:38:30 -0700961
962 i = WEXT_CSCAN_HEADER_SIZE;
963
964 if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] )
965 {
966 scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i];
967 ++i;
968 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700969 pHddCtx->scan_info.scan_pending_option = scanPendingOption;
Jeff Johnson295189b2012-06-20 16:38:30 -0700970
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700971 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 {
973 hddLog(LOG1,"%s: mScanPending is TRUE",__func__);
974 /* If any scan is pending, just giveup this scan request */
975 if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption)
976 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700977 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700978 return eHAL_STATUS_SUCCESS;
979 }
980 /* If any scan pending, wait till finish current scan,
981 and try this scan request when previous scan finish */
982 else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption)
983 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700984 pHddCtx->scan_info.waitScanResult = TRUE;
985 vos_event_reset(&pHddCtx->scan_info.scan_finished_event);
986 if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event,
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 WEXT_CSCAN_SCAN_DONE_WAIT_TIME))
988 {
989 hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__);
990 return eHAL_STATUS_SUCCESS;
991 }
992 }
993 /* Piggyback previous scan result */
994 else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption)
995 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700996 pHddCtx->scan_info.waitScanResult = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700997 return eHAL_STATUS_SUCCESS;
998 }
999 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001000 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001001
1002 /* Check for scan IE */
1003 while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] )
1004 {
1005 /* ssid_len */
1006 if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION)
1007 {
1008 /* total number of ssid's */
1009 num_ssid++;
1010 /* increment length filed */
1011 i += str_ptr[i] + 1;
1012 }
1013 /* i should be saved and it will be pointing to 'C' */
1014 }
1015
1016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid);
1017 if( num_ssid )
1018 {
1019 /* To be fixed in SME and PE: override the number of ssid with 1,
1020 * as SME and PE does not handle multiple SSID in scan request
1021 * */
1022 scanRequest.SSIDs.numOfSSIDs = num_ssid;
1023 /* Allocate num_ssid tCsrSSIDInfo structure */
1024 SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo));
1025 if(NULL == scanRequest.SSIDs.SSIDList) {
1026 hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer");
1027 return -ENOMEM;
1028 }
1029
1030 /* copy all the ssid's and their length */
1031 ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */
1032 for(j = 0; j < num_ssid; j++) {
1033 if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){
1034 scanRequest.SSIDs.numOfSSIDs -= 1;
1035 } else{
1036 /* get the ssid length */
1037 SsidInfo->SSID.length = str_ptr[ssid_start++];
1038 vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length);
Arif Hussain6d2a3322013-11-17 19:50:10 -08001039 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 }
1041 /* skipping length */
1042 ssid_start += str_ptr[ssid_start - 1] + 1;
1043 /* Store next ssid info */
1044 SsidInfo++;
1045 }
1046 }
1047
1048 /* Check for Channel IE */
1049 if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i])
1050 {
1051 if( str_ptr[++i] == 0 )
1052 {
1053 scanRequest.ChannelInfo.numOfChannels = 0;
1054 scanRequest.ChannelInfo.ChannelList = NULL;
1055 i++;
1056 }
1057 else {
1058
1059 /* increment the counter */
1060 scanRequest.ChannelInfo.numOfChannels = str_ptr[i++];
1061 /* store temp channel list */
1062 /* SME expects 1 byte channel content */
1063 scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t));
1064 if(NULL == scanRequest.ChannelInfo.ChannelList)
1065 {
c_hpothu7f63e882013-10-02 19:13:35 +05301066 hddLog(LOGE, "memory alloc failed for channel list creation");
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 status = -ENOMEM;
1068 goto exit_point;
1069 }
1070
1071 for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++)
1072 {
1073 /* SCAN request from upper layer has 2 bytes channel */
1074 scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i];
1075 i += sizeof(v_U16_t);
1076 }
1077 }
1078 }
1079
1080 /* Set default */
1081 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1082 scanRequest.minChnTime = 0;
1083 scanRequest.maxChnTime = 0;
1084
1085 /* Now i is pointing to passive dwell dwell time */
1086 /* 'P',min dwell time, max dwell time */
1087 /* next two offsets contain min and max channel time */
1088 if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) )
1089 {
1090 /* No SSID specified, num_ssid == 0, then start paasive scan */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001091 if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 {
1093 scanRequest.scanType = eSIR_PASSIVE_SCAN;
1094 scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time;
1095 scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time;
1096 i++;
1097 }
1098 else
1099 {
1100 i += 3;
1101 }
1102 }
1103
1104 /* H indicates active channel time */
1105 if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) )
1106 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001107 if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001108 {
1109 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1110 scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time;
1111 scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time;
1112 i++;
1113 }
1114 else
1115 {
1116 i +=3;
1117 }
1118 }
1119 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
1120 /* set requestType to full scan */
1121 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001122 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001123
1124 /* if previous genIE is not NULL, update ScanIE */
1125 if(0 != pwextBuf->genIE.length)
1126 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001127 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
1128 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -07001129 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001130 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +05301131 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
1132 {
1133 memcpy( pwextBuf->roamProfile.addIEScan,
1134 pHddCtx->scan_info.scanAddIE.addIEdata,
1135 pHddCtx->scan_info.scanAddIE.length);
1136 pwextBuf->roamProfile.nAddIEScanLength =
1137 pHddCtx->scan_info.scanAddIE.length;
1138 }
1139 else
1140 {
1141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1142 "Invalid ScanIE, Length is %d",
1143 pwextBuf->genIE.length);
1144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001145
1146 /* clear previous genIE after use it */
1147 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
1148 }
1149
1150 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001151 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
1152 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001154 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
1155 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -07001156 }
1157
1158 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal,
1159 pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
1160 if( !HAL_STATUS_SUCCESS(status) )
1161 {
1162 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 -07001163 pHddCtx->scan_info.mScanPending = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 status = -EINVAL;
1165 goto exit_point;
1166 }
1167
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001168 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001169
1170 } //end of data->pointer
1171 else {
1172 status = -1;
1173 }
1174
1175exit_point:
1176
1177 /* free ssidlist */
1178 if (scanRequest.SSIDs.SSIDList)
1179 {
1180 vos_mem_free(scanRequest.SSIDs.SSIDList);
1181 }
1182 /* free the channel list */
1183 if(scanRequest.ChannelInfo.ChannelList)
1184 {
1185 vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList);
1186 }
1187
1188 EXIT();
1189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1190 return status;
1191}
1192
1193/* Abort any MAC scan if in progress */
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301194void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId,
1195 eCsrAbortReason reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07001196{
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301197 sme_AbortMacScan(pHddCtx->hHal, sessionId, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07001198}
1199