blob: 4366fef123e08b68ba83ec08f2da7c1c10c80013 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
krunal soni2a6a9062014-02-11 14:14:23 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**========================================================================
29
30 \file wlan_hdd_scan.c
31
32 \brief WLAN Host Device Driver implementation
33
34 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
35
36 Qualcomm Confidential and Proprietary.
37
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55
56 ==========================================================================*/
57 /* To extract the Scan results */
58
59/* Add a stream event */
60
61#include <wlan_qct_driver.h>
62#include <wlan_hdd_includes.h>
63#include <vos_api.h>
64#include <palTypes.h>
65#include <aniGlobal.h>
66#include <dot11f.h>
67#ifdef WLAN_BTAMP_FEATURE
68#include "bap_hdd_misc.h"
69#endif
70
Jeff Johnson295189b2012-06-20 16:38:30 -070071#include <linux/wireless.h>
72#include <net/cfg80211.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070073
Jeff Johnson295189b2012-06-20 16:38:30 -070074
75#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
76#define WEXT_CSCAN_HEADER_SIZE 12
77#define WEXT_CSCAN_SSID_SECTION 'S'
78#define WEXT_CSCAN_CHANNEL_SECTION 'C'
79#define WEXT_CSCAN_NPROBE_SECTION 'N'
80#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
81#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
82#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
83#define WEXT_CSCAN_TYPE_SECTION 'T'
84#define WEXT_CSCAN_PENDING_SECTION 'O'
85#define WEXT_CSCAN_TYPE_DEFAULT 0
86#define WEXT_CSCAN_TYPE_PASSIVE 1
87#define WEXT_CSCAN_PASV_DWELL_TIME 130
88#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
89#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
90#define WEXT_CSCAN_HOME_DWELL_TIME 130
91#define MAX_RATES 12
92
93#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000
94
95typedef struct hdd_scan_info{
96 struct net_device *dev;
97 struct iw_request_info *info;
98 char *start;
99 char *end;
100} hdd_scan_info_t, *hdd_scan_info_tp;
101
102static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate)
103{
104
105 /** Slightly more sophisticated processing has to take place here.
106 Basic rates are rounded DOWN. HT rates are rounded UP.*/
107 return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2);
108}
109
110
111static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event )
112{
113 struct iw_event event;
114
115 *last_event = *current_event;
116 vos_mem_zero(&event, sizeof (struct iw_event));
117 event.cmd = cmd;
118 event.u.data.flags = 1;
119 event.u.data.length = length;
120 *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data);
121
122 if(*last_event == *current_event)
123 {
124 /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530125 hddLog( LOGW, "%s: no space left to add event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700126 return -E2BIG; /* Error code, may be E2BIG */
127 }
128
129 return 0;
130}
131
132/**---------------------------------------------------------------------------
133
134 \brief hdd_GetWPARSNIEs() -
135
136 This function extract the WPA/RSN IE from the Bss descriptor IEs fields
137
138 \param - ieFields - Pointer to the Bss Descriptor IEs.
139 - ie_length - IE Length.
140 - last_event -Points to the last event.
141 - current_event - Points to the
142 \return - 0 for success, non zero for failure
143
144 --------------------------------------------------------------------------*/
145
146
147/* Extract the WPA and/or RSN IEs */
148static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo )
149{
150 v_U8_t eid, elen, *element;
151 v_U16_t tie_length=0;
152
153 ENTER();
154
155 element = ieFields;
156 tie_length = ie_length;
157
158 while( tie_length > 2 && element != NULL )
159 {
160 eid = element[0];
161 elen = element[1];
162
163 /*If element length is greater than total remaining ie length,
164 *break the loop*/
165 if ((elen+2) > tie_length)
166 break;
167
168 switch(eid)
169 {
170 case DOT11F_EID_WPA:
171 case DOT11F_EID_RSN:
172#ifdef FEATURE_WLAN_WAPI
173 case DOT11F_EID_WAPI:
174#endif
175 if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 )
176 return -E2BIG;
177 break;
178
179 default:
180 break;
181 }
182
183 /* Next element */
184 tie_length -= (2 + elen);
185 element += 2 + elen;
186 }
187
188 return 0;
189}
190
191/**---------------------------------------------------------------------------
192
193 \brief hdd_IndicateScanResult() -
194
195 This function returns the scan results to the wpa_supplicant
196
197 \param - scanInfo - Pointer to the scan info structure.
198 - descriptor - Pointer to the Bss Descriptor.
199
200 \return - 0 for success, non zero for failure
201
202 --------------------------------------------------------------------------*/
203#define MAX_CUSTOM_LEN 64
204static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result)
205{
206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ;
207 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
208 tSirBssDescription *descriptor = &scan_result->BssDescriptor;
209 struct iw_event event;
210 char *current_event = scanInfo->start;
211 char *end = scanInfo->end;
212 char *last_event;
213 char *current_pad;
214 v_U16_t ie_length = 0;
215 v_U16_t capabilityInfo;
216 char *modestr;
217 int error;
218 char custom[MAX_CUSTOM_LEN];
219 char *p;
220
Arif Hussain24bafea2013-11-15 15:10:03 -0800221 hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR,
222 MAC_ADDR_ARRAY(descriptor->bssId));
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224 error = 0;
225 last_event = current_event;
226 vos_mem_zero(&event, sizeof (event));
227
228 /* BSSID */
229 event.cmd = SIOCGIWAP;
230 event.u.ap_addr.sa_family = ARPHRD_ETHER;
231 vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId,
232 sizeof (descriptor->bssId));
233 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
234 &event, IW_EV_ADDR_LEN);
235
236 if (last_event == current_event)
237 {
238 /* no space to add event */
239 /* Error code may be E2BIG */
240 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWAP ");
241 return -E2BIG;
242 }
243
244 last_event = current_event;
245 vos_mem_zero(&event, sizeof (struct iw_event));
246
247 /* Protocol Name */
248 event.cmd = SIOCGIWNAME;
249
250 switch (descriptor->nwType)
251 {
252 case eSIR_11A_NW_TYPE:
253 modestr = "a";
254 break;
255 case eSIR_11B_NW_TYPE:
256 modestr = "b";
257 break;
258 case eSIR_11G_NW_TYPE:
259 modestr = "g";
260 break;
261 case eSIR_11N_NW_TYPE:
262 modestr = "n";
263 break;
264 default:
265 hddLog( LOGW, "%s: Unknown network type [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700266 __func__, descriptor->nwType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 modestr = "?";
268 break;
269 }
270 snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr);
271 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
272 &event, IW_EV_CHAR_LEN);
273
274 if (last_event == current_event)
275 { /* no space to add event */
276 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWNAME");
277 /* Error code, may be E2BIG */
278 return -E2BIG;
279 }
280
281 last_event = current_event;
282 vos_mem_zero( &event, sizeof (struct iw_event));
283
284 /*Freq*/
285 event.cmd = SIOCGIWFREQ;
286
287 event.u.freq.m = descriptor->channelId;
288 event.u.freq.e = 0;
289 event.u.freq.i = 0;
290 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
291 &event, IW_EV_FREQ_LEN);
292
293 if (last_event == current_event)
294 { /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530295 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWFREQ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700296 return -E2BIG;
297 }
298
299 last_event = current_event;
300 vos_mem_zero( &event, sizeof (struct iw_event));
301
302 /* BSS Mode */
303 event.cmd = SIOCGIWMODE;
304
305 capabilityInfo = descriptor->capabilityInfo;
306
307 if (SIR_MAC_GET_ESS(capabilityInfo))
308 {
309 event.u.mode = IW_MODE_INFRA;
310 }
311 else if (SIR_MAC_GET_IBSS(capabilityInfo))
312 {
313 event.u.mode = IW_MODE_ADHOC;
314 }
315 else
316 {
317 /* neither ESS or IBSS */
318 event.u.mode = IW_MODE_AUTO;
319 }
320
321 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
322 &event, IW_EV_UINT_LEN);
323
324 if (last_event == current_event)
325 { /* no space to add event */
326 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWMODE");
327 return -E2BIG;
328 }
329 /* To extract SSID */
330 ie_length = GET_IE_LEN_IN_BSS( descriptor->length );
331
332 if (ie_length > 0)
333 {
Madan Mohan Koyyalamudi729972c2012-10-21 12:39:24 -0700334 /* dot11BeaconIEs is a large struct, so we make it static to
335 avoid stack overflow. This API is only invoked via ioctl,
336 so it is serialized by the kernel rtnl_lock and hence does
337 not need to be reentrant */
338 static tDot11fBeaconIEs dot11BeaconIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -0700339 tDot11fIESSID *pDot11SSID;
340 tDot11fIESuppRates *pDot11SuppRates;
341 tDot11fIEExtSuppRates *pDot11ExtSuppRates;
342 tDot11fIEHTCaps *pDot11IEHTCaps;
343 int numBasicRates = 0;
344 int maxNumRates = 0;
345
346 pDot11IEHTCaps = NULL;
347
348 dot11fUnpackBeaconIEs ((tpAniSirGlobal)
349 hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs);
350
351 pDot11SSID = &dot11BeaconIEs.SSID;
352
353
354 if (pDot11SSID->present ) {
355 last_event = current_event;
356 vos_mem_zero (&event, sizeof (struct iw_event));
357
358 event.cmd = SIOCGIWESSID;
359 event.u.data.flags = 1;
360 event.u.data.length = scan_result->ssId.length;
361 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
362 &event, (char *)scan_result->ssId.ssId);
363
364 if(last_event == current_event)
365 { /* no space to add event */
366 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
367 return -E2BIG;
368 }
369 }
370
371 if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, &current_event, scanInfo ) < 0 )
372 {
373 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
374 return -E2BIG;
375 }
376
377 last_event = current_event;
378 current_pad = current_event + IW_EV_LCP_LEN;
379 vos_mem_zero( &event, sizeof (struct iw_event));
380
381 /*Rates*/
382 event.cmd = SIOCGIWRATE;
383
384
385 pDot11SuppRates = &dot11BeaconIEs.SuppRates;
386
387 if (pDot11SuppRates->present )
388 {
389 int i;
390
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700391 numBasicRates = pDot11SuppRates->num_rates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 for (i=0; i<pDot11SuppRates->num_rates; i++)
393 {
394 if (0 != (pDot11SuppRates->rates[i] & 0x7F))
395 {
396 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
397 &pDot11SuppRates->rates[i]);
398
399 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
400 current_pad, end, &event, IW_EV_PARAM_LEN);
401 }
402 }
403
404 }
405
406 pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates;
407
408 if (pDot11ExtSuppRates->present )
409 {
410 int i,no_of_rates;
411 maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates;
412
413 /* Check to make sure the total number of rates
414 doesn't exceed IW_MAX_BITRATES */
415
416 maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES);
417
418 if((maxNumRates - numBasicRates) > MAX_RATES)
419 {
420 no_of_rates = MAX_RATES;
421 hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates ");
422 }
423 else
424 {
425 no_of_rates = maxNumRates - numBasicRates;
426 }
427 for ( i=0; i< no_of_rates ; i++ )
428 {
429 if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F))
430 {
431 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
432 &pDot11ExtSuppRates->rates[i]);
433
434 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
435 current_pad, end, &event, IW_EV_PARAM_LEN);
436 }
437 }
438 }
439
440
441 if ((current_pad - current_event) >= IW_EV_LCP_LEN)
442 {
443 current_event = current_pad;
444 }
445 else
446 {
447 if (last_event == current_event)
448 { /* no space to add event */
449 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWRATE");
450 return -E2BIG;
451 }
452 }
453
454 last_event = current_event;
455 vos_mem_zero (&event, sizeof (struct iw_event));
456
457
458 event.cmd = SIOCGIWENCODE;
459
460 if (SIR_MAC_GET_PRIVACY(capabilityInfo))
461 {
462 event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
463 }
464 else
465 {
466 event.u.data.flags = IW_ENCODE_DISABLED;
467 }
468 event.u.data.length = 0;
469
470 current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid);
471
472
473 if(last_event == current_event)
474 { /* no space to add event
475 Error code, may be E2BIG */
c_hpothu7f63e882013-10-02 19:13:35 +0530476 hddLog( LOGW, "hdd_IndicateScanResult: no space for SIOCGIWENCODE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700477 return -E2BIG;
478 }
479 }
480
481 last_event = current_event;
482 vos_mem_zero( &event, sizeof (struct iw_event));
483
484 /*RSSI*/
485 event.cmd = IWEVQUAL;
486 event.u.qual.qual = descriptor->rssi;
487 event.u.qual.noise = descriptor->sinr;
488
489 /*To keep the rssi icon of the connected AP in the scan window
490 *and the rssi icon of the wireless networks in sync */
491 if (( eConnectionState_Associated ==
492 pAdapter->sessionCtx.station.conn_info.connState ) &&
493 ( VOS_TRUE == vos_mem_compare(descriptor->bssId,
494 pAdapter->sessionCtx.station.conn_info.bssId,
495 WNI_CFG_BSSID_LEN)))
496 {
497 event.u.qual.level = pAdapter->rssi;
498 }
499 else
500 {
501 event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0);
502 }
503
504 event.u.qual.updated = IW_QUAL_ALL_UPDATED;
505
506 current_event = iwe_stream_add_event(scanInfo->info,current_event,
507 end, &event, IW_EV_QUAL_LEN);
508
509 if(last_event == current_event)
510 { /* no space to add event */
511 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVQUAL");
512 return -E2BIG;
513 }
514
515
516 /* AGE */
517 event.cmd = IWEVCUSTOM;
518 p = custom;
Sameer Thalappilb0a30232013-09-27 15:37:48 -0700519 p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu",
Jeff Johnson295189b2012-06-20 16:38:30 -0700520 vos_timer_get_system_ticks() - descriptor->nReceivedTime);
521 event.u.data.length = p - custom;
522 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
523 &event, custom);
524 if(last_event == current_event)
525 { /* no space to add event */
526 hddLog( LOGW, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)");
527 return -E2BIG;
528 }
529
530 scanInfo->start = current_event;
531
532 return 0;
533}
534
535/**---------------------------------------------------------------------------
536
537 \brief hdd_ScanRequestCallback() -
538
539 The sme module calls this callback function once it finish the scan request
540 and this function notifies the scan complete event to the wpa_supplicant.
541
542 \param - halHandle - Pointer to the Hal Handle.
543 - pContext - Pointer to the data context.
544 - scanId - Scan ID.
545 - status - CSR Status.
546 \return - 0 for success, non zero for failure
547
548 --------------------------------------------------------------------------*/
549
550static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext,
551 tANI_U32 scanId, eCsrScanStatus status)
552{
553 struct net_device *dev = (struct net_device *) pContext;
554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700555 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700556 union iwreq_data wrqu;
557 int we_event;
558 char *msg;
559
560 ENTER();
561
562 hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700563 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700564 (int) scanId, (int) status);
565
566 /* if there is a scan request pending when the wlan driver is unloaded
567 we may be invoked as SME flushes its pending queue. If that is the
568 case, the underlying net_device may have already been destroyed, so
569 do some quick sanity before proceeding */
570 if (pAdapter->dev != dev)
571 {
572 hddLog(LOGW, "%s: device mismatch %p vs %p",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700573 __func__, pAdapter->dev, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700574 return eHAL_STATUS_SUCCESS;
575 }
576
577 /* Check the scanId */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700578 if (pHddCtx->scan_info.scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700579 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700580 hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700581 "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700582 (int) scanId);
583 }
584
585 /* Scan is no longer pending */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700586 pHddCtx->scan_info.mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700587
588 // notify any applications that may be interested
589 memset(&wrqu, '\0', sizeof(wrqu));
590 we_event = SIOCGIWSCAN;
591 msg = NULL;
592 wireless_send_event(dev, we_event, &wrqu, msg);
593
594 EXIT();
595
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
597
598 return eHAL_STATUS_SUCCESS;
599}
600
601/**---------------------------------------------------------------------------
602
603 \brief iw_set_scan() -
604
605 This function process the scan request from the wpa_supplicant
606 and set the scan request to the SME
607
608 \param - dev - Pointer to the net device.
609 - info - Pointer to the iw_request_info.
610 - wrqu - Pointer to the iwreq_data.
611 - extra - Pointer to the data.
612 \return - 0 for success, non zero for failure
613
614 --------------------------------------------------------------------------*/
615
616
617int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
618 union iwreq_data *wrqu, char *extra)
619{
620 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700621 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700622 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
623 tCsrScanRequest scanRequest;
624 v_U32_t scanId = 0;
625 eHalStatus status = eHAL_STATUS_SUCCESS;
626 struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
627
628 ENTER();
629
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
631
632#ifdef WLAN_BTAMP_FEATURE
633 //Scan not supported when AMP traffic is on.
634 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
635 {
636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
637 return eHAL_STATUS_SUCCESS;
638 }
639#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700640 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 {
642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
643 return eHAL_STATUS_SUCCESS;
644 }
645
646 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
648 return eHAL_STATUS_SUCCESS;
649 }
650 vos_mem_zero( &scanRequest, sizeof(scanRequest));
651
652 if (NULL != wrqu->data.pointer)
653 {
654 /* set scanType, active or passive */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700655 if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -0700656 {
657 scanRequest.scanType = eSIR_ACTIVE_SCAN;
658 }
659 else
660 {
661 scanRequest.scanType = eSIR_PASSIVE_SCAN;
662 }
663
664 /* set bssid using sockaddr from iw_scan_req */
665 vos_mem_copy(scanRequest.bssid,
666 &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );
667
668 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
669
670 if(scanReq->essid_len) {
671 scanRequest.SSIDs.numOfSSIDs = 1;
672 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
673 if(scanRequest.SSIDs.SSIDList) {
674 scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len;
675 vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len);
676 }
677 else
678 {
679 scanRequest.SSIDs.numOfSSIDs = 0;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700681 VOS_ASSERT(0);
682 }
683 }
684 }
685
686 /* set min and max channel time */
687 scanRequest.minChnTime = scanReq->min_channel_time;
688 scanRequest.maxChnTime = scanReq->max_channel_time;
689
690 }
691 else
692 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700693 if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700694 /* set the scan type to active */
695 scanRequest.scanType = eSIR_ACTIVE_SCAN;
696 } else {
697 scanRequest.scanType = eSIR_PASSIVE_SCAN;
698 }
699
700 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
701
702 /* set min and max channel time to zero */
703 scanRequest.minChnTime = 0;
704 scanRequest.maxChnTime = 0;
705 }
706
707 /* set BSSType to default type */
708 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
709
710 /*Scan all the channels */
711 scanRequest.ChannelInfo.numOfChannels = 0;
712
713 scanRequest.ChannelInfo.ChannelList = NULL;
714
715 /* set requestType to full scan */
716 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
717
718 /* if previous genIE is not NULL, update ScanIE */
719 if (0 != pwextBuf->genIE.length)
720 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700721 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
722 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -0700723 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700724 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +0530725 /* Maximum length of each IE is SIR_MAC_MAX_IE_LENGTH */
726 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
727 {
728 memcpy( pwextBuf->roamProfile.addIEScan,
729 pHddCtx->scan_info.scanAddIE.addIEdata,
730 pHddCtx->scan_info.scanAddIE.length);
731 pwextBuf->roamProfile.nAddIEScanLength =
732 pHddCtx->scan_info.scanAddIE.length;
733 }
734 else
735 {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "Invalid ScanIE, Length is %d", pwextBuf->genIE.length);
738 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700739 /* clear previous genIE after use it */
740 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
741 }
742
743 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700744 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
745 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -0700746 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700747 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
748 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 }
750
751 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
752 if (!HAL_STATUS_SUCCESS(status))
753 {
754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status);
755 goto error;
756 }
757
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700758 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700759
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700760 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700761
762error:
763 if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
764 vos_mem_free(scanRequest.SSIDs.SSIDList);
765
766 EXIT();
767
768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
769 return status;
770}
771
772/**---------------------------------------------------------------------------
773
774 \brief iw_get_scan() -
775
776 This function returns the scan results to the wpa_supplicant
777
778 \param - dev - Pointer to the net device.
779 - info - Pointer to the iw_request_info.
780 - wrqu - Pointer to the iwreq_data.
781 - extra - Pointer to the data.
782 \return - 0 for success, non zero for failure
783
784 --------------------------------------------------------------------------*/
785
786
787int iw_get_scan(struct net_device *dev,
788 struct iw_request_info *info,
789 union iwreq_data *wrqu, char *extra)
790{
791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700792 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
794 tCsrScanResultInfo *pScanResult;
795 eHalStatus status = eHAL_STATUS_SUCCESS;
796 hdd_scan_info_t scanInfo;
797 tScanResultHandle pResult;
798 int i = 0;
799
800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
801 __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
802 ENTER();
803
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700804 if (TRUE == pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 {
806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
807 return -EAGAIN;
808 }
809
810 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
812 return -EAGAIN;
813 }
814
815 scanInfo.dev = dev;
816 scanInfo.start = extra;
817 scanInfo.info = info;
818
819 if (0 == wrqu->data.length)
820 {
821 scanInfo.end = extra + IW_SCAN_MAX_DATA;
822 }
823 else
824 {
825 scanInfo.end = extra + wrqu->data.length;
826 }
827
828 status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult);
829
830 if (NULL == pResult)
831 {
832 // no scan results
833 hddLog(LOG1,"iw_get_scan: NULL Scan Result ");
834 return 0;
835 }
836
837 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
838
839 while (pScanResult)
840 {
841 status = hdd_IndicateScanResult(&scanInfo, pScanResult);
842 if (0 != status)
843 {
844 break;
845 }
846 i++;
847 pScanResult = sme_ScanResultGetNext(hHal, pResult);
848 }
849
850 sme_ScanResultPurge(hHal, pResult);
851
852 EXIT();
853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
854 return status;
855}
856
857#if 0
858static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext,
859 tANI_U32 scanId, eCsrScanStatus status)
860{
861 struct net_device *dev = (struct net_device *) pContext;
862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
863 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
864 union iwreq_data wrqu;
865 int we_event;
866 char *msg;
867 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
868 ENTER();
869
870 hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700871 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 (int) scanId, (int) status);
873
874 /* Check the scanId */
875 if (pwextBuf->scanId != scanId)
876 {
877 hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700878 "scanId = %d ", __func__, (int) pwextBuf->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700879 (int) scanId);
880 }
881
882 /* Scan is no longer pending */
883 pwextBuf->mScanPending = VOS_FALSE;
884
885 // notify any applications that may be interested
886 memset(&wrqu, '\0', sizeof(wrqu));
887 we_event = SIOCGIWSCAN;
888 msg = NULL;
889 wireless_send_event(dev, we_event, &wrqu, msg);
890
891 vos_status = vos_event_set(&pwextBuf->vosevent);
892
893 if (!VOS_IS_STATUS_SUCCESS(vos_status))
894 {
895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!"));
896 return VOS_STATUS_E_FAILURE;
897 }
898
899 EXIT();
900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
901
902 return eHAL_STATUS_SUCCESS;
903}
904#endif
905
906int iw_set_cscan(struct net_device *dev, struct iw_request_info *info,
907 union iwreq_data *wrqu, char *extra)
908{
909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700910 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700911 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
912 tCsrScanRequest scanRequest;
913 v_U32_t scanId = 0;
914 eHalStatus status = eHAL_STATUS_SUCCESS;
915 v_U8_t channelIdx;
916
917 ENTER();
918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
919
920#ifdef WLAN_BTAMP_FEATURE
921 //Scan not supported when AMP traffic is on.
922 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
923 {
924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
925 return eHAL_STATUS_SUCCESS;
926 }
927#endif
928
929 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
930 {
931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
932 return eHAL_STATUS_SUCCESS;
933 }
934
935 vos_mem_zero( &scanRequest, sizeof(scanRequest));
936 if (NULL != wrqu->data.pointer)
937 {
938 char *str_ptr = NULL;
939 tCsrSSIDInfo *SsidInfo = NULL;
940 int num_ssid = 0;
941 int i, j, ssid_start;
942 hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP;
943
Rajeev Kumarbe97df02013-10-24 18:30:39 -0700944 str_ptr = extra;
Jeff Johnson295189b2012-06-20 16:38:30 -0700945
946 i = WEXT_CSCAN_HEADER_SIZE;
947
948 if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] )
949 {
950 scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i];
951 ++i;
952 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700953 pHddCtx->scan_info.scan_pending_option = scanPendingOption;
Jeff Johnson295189b2012-06-20 16:38:30 -0700954
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700955 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700956 {
957 hddLog(LOG1,"%s: mScanPending is TRUE",__func__);
958 /* If any scan is pending, just giveup this scan request */
959 if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption)
960 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700961 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 return eHAL_STATUS_SUCCESS;
963 }
964 /* If any scan pending, wait till finish current scan,
965 and try this scan request when previous scan finish */
966 else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption)
967 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700968 pHddCtx->scan_info.waitScanResult = TRUE;
969 vos_event_reset(&pHddCtx->scan_info.scan_finished_event);
970 if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event,
Jeff Johnson295189b2012-06-20 16:38:30 -0700971 WEXT_CSCAN_SCAN_DONE_WAIT_TIME))
972 {
973 hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__);
974 return eHAL_STATUS_SUCCESS;
975 }
976 }
977 /* Piggyback previous scan result */
978 else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption)
979 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700980 pHddCtx->scan_info.waitScanResult = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 return eHAL_STATUS_SUCCESS;
982 }
983 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700984 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700985
986 /* Check for scan IE */
987 while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] )
988 {
989 /* ssid_len */
990 if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION)
991 {
992 /* total number of ssid's */
993 num_ssid++;
994 /* increment length filed */
995 i += str_ptr[i] + 1;
996 }
997 /* i should be saved and it will be pointing to 'C' */
998 }
999
1000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid);
1001 if( num_ssid )
1002 {
1003 /* To be fixed in SME and PE: override the number of ssid with 1,
1004 * as SME and PE does not handle multiple SSID in scan request
1005 * */
1006 scanRequest.SSIDs.numOfSSIDs = num_ssid;
1007 /* Allocate num_ssid tCsrSSIDInfo structure */
1008 SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo));
1009 if(NULL == scanRequest.SSIDs.SSIDList) {
1010 hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer");
1011 return -ENOMEM;
1012 }
1013
1014 /* copy all the ssid's and their length */
1015 ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */
1016 for(j = 0; j < num_ssid; j++) {
1017 if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){
1018 scanRequest.SSIDs.numOfSSIDs -= 1;
1019 } else{
1020 /* get the ssid length */
1021 SsidInfo->SSID.length = str_ptr[ssid_start++];
1022 vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length);
Arif Hussain6d2a3322013-11-17 19:50:10 -08001023 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001024 }
1025 /* skipping length */
1026 ssid_start += str_ptr[ssid_start - 1] + 1;
1027 /* Store next ssid info */
1028 SsidInfo++;
1029 }
1030 }
1031
1032 /* Check for Channel IE */
1033 if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i])
1034 {
1035 if( str_ptr[++i] == 0 )
1036 {
1037 scanRequest.ChannelInfo.numOfChannels = 0;
1038 scanRequest.ChannelInfo.ChannelList = NULL;
1039 i++;
1040 }
1041 else {
1042
1043 /* increment the counter */
1044 scanRequest.ChannelInfo.numOfChannels = str_ptr[i++];
1045 /* store temp channel list */
1046 /* SME expects 1 byte channel content */
1047 scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t));
1048 if(NULL == scanRequest.ChannelInfo.ChannelList)
1049 {
c_hpothu7f63e882013-10-02 19:13:35 +05301050 hddLog(LOGE, "memory alloc failed for channel list creation");
Jeff Johnson295189b2012-06-20 16:38:30 -07001051 status = -ENOMEM;
1052 goto exit_point;
1053 }
1054
1055 for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++)
1056 {
1057 /* SCAN request from upper layer has 2 bytes channel */
1058 scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i];
1059 i += sizeof(v_U16_t);
1060 }
1061 }
1062 }
1063
1064 /* Set default */
1065 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1066 scanRequest.minChnTime = 0;
1067 scanRequest.maxChnTime = 0;
1068
1069 /* Now i is pointing to passive dwell dwell time */
1070 /* 'P',min dwell time, max dwell time */
1071 /* next two offsets contain min and max channel time */
1072 if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) )
1073 {
1074 /* No SSID specified, num_ssid == 0, then start paasive scan */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001075 if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 {
1077 scanRequest.scanType = eSIR_PASSIVE_SCAN;
1078 scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time;
1079 scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time;
1080 i++;
1081 }
1082 else
1083 {
1084 i += 3;
1085 }
1086 }
1087
1088 /* H indicates active channel time */
1089 if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) )
1090 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001091 if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001092 {
1093 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1094 scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time;
1095 scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time;
1096 i++;
1097 }
1098 else
1099 {
1100 i +=3;
1101 }
1102 }
1103 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
1104 /* set requestType to full scan */
1105 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001106 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001107
1108 /* if previous genIE is not NULL, update ScanIE */
1109 if(0 != pwextBuf->genIE.length)
1110 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001111 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
1112 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -07001113 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001114 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +05301115 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
1116 {
1117 memcpy( pwextBuf->roamProfile.addIEScan,
1118 pHddCtx->scan_info.scanAddIE.addIEdata,
1119 pHddCtx->scan_info.scanAddIE.length);
1120 pwextBuf->roamProfile.nAddIEScanLength =
1121 pHddCtx->scan_info.scanAddIE.length;
1122 }
1123 else
1124 {
1125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1126 "Invalid ScanIE, Length is %d",
1127 pwextBuf->genIE.length);
1128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001129
1130 /* clear previous genIE after use it */
1131 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
1132 }
1133
1134 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001135 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
1136 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001138 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
1139 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 }
1141
1142 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal,
1143 pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
1144 if( !HAL_STATUS_SUCCESS(status) )
1145 {
1146 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 -07001147 pHddCtx->scan_info.mScanPending = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 status = -EINVAL;
1149 goto exit_point;
1150 }
1151
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001152 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001153
1154 } //end of data->pointer
1155 else {
1156 status = -1;
1157 }
1158
1159exit_point:
1160
1161 /* free ssidlist */
1162 if (scanRequest.SSIDs.SSIDList)
1163 {
1164 vos_mem_free(scanRequest.SSIDs.SSIDList);
1165 }
1166 /* free the channel list */
1167 if(scanRequest.ChannelInfo.ChannelList)
1168 {
1169 vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList);
1170 }
1171
1172 EXIT();
1173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1174 return status;
1175}
1176
1177/* Abort any MAC scan if in progress */
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301178void hdd_abort_mac_scan(hdd_context_t* pHddCtx, tANI_U8 sessionId,
1179 eCsrAbortReason reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07001180{
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05301181 sme_AbortMacScan(pHddCtx->hHal, sessionId, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07001182}
1183