blob: cd5037e5dbf4f3545217bd3e351036923de3ec3e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05302 * Copyright (c) 2012-2019 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
Jeff Johnson295189b2012-06-20 16:38:30 -070034
35 ========================================================================*/
36
37/**=========================================================================
38
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45
46 $Header:$ $DateTime: $ $Author: $
47
48
49 when who what, where, why
50 -------- --- --------------------------------------------------------
51 04/5/09 Shailender Created module.
52
53 ==========================================================================*/
54 /* To extract the Scan results */
55
56/* Add a stream event */
57
58#include <wlan_qct_driver.h>
59#include <wlan_hdd_includes.h>
60#include <vos_api.h>
61#include <palTypes.h>
62#include <aniGlobal.h>
63#include <dot11f.h>
64#ifdef WLAN_BTAMP_FEATURE
65#include "bap_hdd_misc.h"
66#endif
67
Jeff Johnson295189b2012-06-20 16:38:30 -070068#include <linux/wireless.h>
69#include <net/cfg80211.h>
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053070#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071
72#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
73#define WEXT_CSCAN_HEADER_SIZE 12
74#define WEXT_CSCAN_SSID_SECTION 'S'
75#define WEXT_CSCAN_CHANNEL_SECTION 'C'
76#define WEXT_CSCAN_NPROBE_SECTION 'N'
77#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
78#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
79#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
80#define WEXT_CSCAN_TYPE_SECTION 'T'
81#define WEXT_CSCAN_PENDING_SECTION 'O'
82#define WEXT_CSCAN_TYPE_DEFAULT 0
83#define WEXT_CSCAN_TYPE_PASSIVE 1
84#define WEXT_CSCAN_PASV_DWELL_TIME 130
85#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
86#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
87#define WEXT_CSCAN_HOME_DWELL_TIME 130
88#define MAX_RATES 12
89
90#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000
91
92typedef struct hdd_scan_info{
93 struct net_device *dev;
94 struct iw_request_info *info;
95 char *start;
96 char *end;
97} hdd_scan_info_t, *hdd_scan_info_tp;
98
99static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate)
100{
101
102 /** Slightly more sophisticated processing has to take place here.
103 Basic rates are rounded DOWN. HT rates are rounded UP.*/
104 return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2);
105}
106
107
108static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event )
109{
110 struct iw_event event;
111
112 *last_event = *current_event;
113 vos_mem_zero(&event, sizeof (struct iw_event));
114 event.cmd = cmd;
115 event.u.data.flags = 1;
116 event.u.data.length = length;
117 *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data);
118
119 if(*last_event == *current_event)
120 {
121 /* no space to add event */
c_hpothu7f63e882013-10-02 19:13:35 +0530122 hddLog( LOGW, "%s: no space left to add event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700123 return -E2BIG; /* Error code, may be E2BIG */
124 }
125
126 return 0;
127}
128
129/**---------------------------------------------------------------------------
130
131 \brief hdd_GetWPARSNIEs() -
132
133 This function extract the WPA/RSN IE from the Bss descriptor IEs fields
134
135 \param - ieFields - Pointer to the Bss Descriptor IEs.
136 - ie_length - IE Length.
137 - last_event -Points to the last event.
138 - current_event - Points to the
139 \return - 0 for success, non zero for failure
140
141 --------------------------------------------------------------------------*/
142
143
144/* Extract the WPA and/or RSN IEs */
145static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo )
146{
147 v_U8_t eid, elen, *element;
148 v_U16_t tie_length=0;
149
150 ENTER();
151
152 element = ieFields;
153 tie_length = ie_length;
154
155 while( tie_length > 2 && element != NULL )
156 {
157 eid = element[0];
158 elen = element[1];
159
160 /*If element length is greater than total remaining ie length,
161 *break the loop*/
162 if ((elen+2) > tie_length)
163 break;
164
165 switch(eid)
166 {
167 case DOT11F_EID_WPA:
168 case DOT11F_EID_RSN:
169#ifdef FEATURE_WLAN_WAPI
170 case DOT11F_EID_WAPI:
171#endif
172 if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 )
173 return -E2BIG;
174 break;
175
176 default:
177 break;
178 }
179
180 /* Next element */
181 tie_length -= (2 + elen);
182 element += 2 + elen;
183 }
184
185 return 0;
186}
187
188/**---------------------------------------------------------------------------
189
190 \brief hdd_IndicateScanResult() -
191
192 This function returns the scan results to the wpa_supplicant
193
194 \param - scanInfo - Pointer to the scan info structure.
195 - descriptor - Pointer to the Bss Descriptor.
196
197 \return - 0 for success, non zero for failure
198
199 --------------------------------------------------------------------------*/
200#define MAX_CUSTOM_LEN 64
201static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result)
202{
203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ;
204 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
205 tSirBssDescription *descriptor = &scan_result->BssDescriptor;
206 struct iw_event event;
207 char *current_event = scanInfo->start;
208 char *end = scanInfo->end;
209 char *last_event;
210 char *current_pad;
211 v_U16_t ie_length = 0;
212 v_U16_t capabilityInfo;
213 char *modestr;
214 int error;
215 char custom[MAX_CUSTOM_LEN];
216 char *p;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +0530217 tANI_U32 status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
Arif Hussain24bafea2013-11-15 15:10:03 -0800219 hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR,
220 MAC_ADDR_ARRAY(descriptor->bssId));
Jeff Johnson295189b2012-06-20 16:38:30 -0700221
222 error = 0;
223 last_event = current_event;
224 vos_mem_zero(&event, sizeof (event));
225
226 /* BSSID */
227 event.cmd = SIOCGIWAP;
228 event.u.ap_addr.sa_family = ARPHRD_ETHER;
229 vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId,
230 sizeof (descriptor->bssId));
231 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
232 &event, IW_EV_ADDR_LEN);
233
234 if (last_event == current_event)
235 {
236 /* no space to add event */
237 /* Error code may be E2BIG */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530238 hddLog(LOGE, "hdd_IndicateScanResult: no space for SIOCGIWAP ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 return -E2BIG;
240 }
241
242 last_event = current_event;
243 vos_mem_zero(&event, sizeof (struct iw_event));
244
245 /* Protocol Name */
246 event.cmd = SIOCGIWNAME;
247
248 switch (descriptor->nwType)
249 {
250 case eSIR_11A_NW_TYPE:
251 modestr = "a";
252 break;
253 case eSIR_11B_NW_TYPE:
254 modestr = "b";
255 break;
256 case eSIR_11G_NW_TYPE:
257 modestr = "g";
258 break;
259 case eSIR_11N_NW_TYPE:
260 modestr = "n";
261 break;
262 default:
263 hddLog( LOGW, "%s: Unknown network type [%d]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700264 __func__, descriptor->nwType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700265 modestr = "?";
266 break;
267 }
268 snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr);
269 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
270 &event, IW_EV_CHAR_LEN);
271
272 if (last_event == current_event)
273 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530274 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWNAME");
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 /* Error code, may be E2BIG */
276 return -E2BIG;
277 }
278
279 last_event = current_event;
280 vos_mem_zero( &event, sizeof (struct iw_event));
281
282 /*Freq*/
283 event.cmd = SIOCGIWFREQ;
284
285 event.u.freq.m = descriptor->channelId;
286 event.u.freq.e = 0;
287 event.u.freq.i = 0;
288 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
289 &event, IW_EV_FREQ_LEN);
290
291 if (last_event == current_event)
292 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530293 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWFREQ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700294 return -E2BIG;
295 }
296
297 last_event = current_event;
298 vos_mem_zero( &event, sizeof (struct iw_event));
299
300 /* BSS Mode */
301 event.cmd = SIOCGIWMODE;
302
303 capabilityInfo = descriptor->capabilityInfo;
304
305 if (SIR_MAC_GET_ESS(capabilityInfo))
306 {
307 event.u.mode = IW_MODE_INFRA;
308 }
309 else if (SIR_MAC_GET_IBSS(capabilityInfo))
310 {
311 event.u.mode = IW_MODE_ADHOC;
312 }
313 else
314 {
315 /* neither ESS or IBSS */
316 event.u.mode = IW_MODE_AUTO;
317 }
318
319 current_event = iwe_stream_add_event(scanInfo->info,current_event, end,
320 &event, IW_EV_UINT_LEN);
321
322 if (last_event == current_event)
323 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530324 hddLog(LOGE, "hdd_IndicateScanResult: no space for SIOCGIWMODE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 return -E2BIG;
326 }
327 /* To extract SSID */
328 ie_length = GET_IE_LEN_IN_BSS( descriptor->length );
329
330 if (ie_length > 0)
331 {
Madan Mohan Koyyalamudi729972c2012-10-21 12:39:24 -0700332 /* dot11BeaconIEs is a large struct, so we make it static to
333 avoid stack overflow. This API is only invoked via ioctl,
334 so it is serialized by the kernel rtnl_lock and hence does
335 not need to be reentrant */
336 static tDot11fBeaconIEs dot11BeaconIEs;
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 tDot11fIESSID *pDot11SSID;
338 tDot11fIESuppRates *pDot11SuppRates;
339 tDot11fIEExtSuppRates *pDot11ExtSuppRates;
340 tDot11fIEHTCaps *pDot11IEHTCaps;
341 int numBasicRates = 0;
342 int maxNumRates = 0;
343
344 pDot11IEHTCaps = NULL;
345
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +0530346 status = dot11fUnpackBeaconIEs ((tpAniSirGlobal)
Jeff Johnson295189b2012-06-20 16:38:30 -0700347 hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +0530348 if (DOT11F_FAILED(status))
349 {
350 hddLog(LOGE,
351 FL("unpack failed for Beacon IE status:(0x%08x)"),
352 status);
353 return -EINVAL;
354 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700355
356 pDot11SSID = &dot11BeaconIEs.SSID;
357
358
359 if (pDot11SSID->present ) {
360 last_event = current_event;
361 vos_mem_zero (&event, sizeof (struct iw_event));
362
363 event.cmd = SIOCGIWESSID;
364 event.u.data.flags = 1;
365 event.u.data.length = scan_result->ssId.length;
366 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
367 &event, (char *)scan_result->ssId.ssId);
368
369 if(last_event == current_event)
370 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530371 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 return -E2BIG;
373 }
374 }
375
376 if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, &current_event, scanInfo ) < 0 )
377 {
Sushant Kaushik125ae692014-11-25 17:38:48 +0530378 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID");
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 return -E2BIG;
380 }
381
382 last_event = current_event;
383 current_pad = current_event + IW_EV_LCP_LEN;
384 vos_mem_zero( &event, sizeof (struct iw_event));
385
386 /*Rates*/
387 event.cmd = SIOCGIWRATE;
388
389
390 pDot11SuppRates = &dot11BeaconIEs.SuppRates;
391
392 if (pDot11SuppRates->present )
393 {
394 int i;
395
Madan Mohan Koyyalamudi4e31b132012-11-02 13:13:52 -0700396 numBasicRates = pDot11SuppRates->num_rates;
Jeff Johnson295189b2012-06-20 16:38:30 -0700397 for (i=0; i<pDot11SuppRates->num_rates; i++)
398 {
399 if (0 != (pDot11SuppRates->rates[i] & 0x7F))
400 {
401 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
402 &pDot11SuppRates->rates[i]);
403
404 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
405 current_pad, end, &event, IW_EV_PARAM_LEN);
406 }
407 }
408
409 }
410
411 pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates;
412
413 if (pDot11ExtSuppRates->present )
414 {
415 int i,no_of_rates;
416 maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates;
417
418 /* Check to make sure the total number of rates
419 doesn't exceed IW_MAX_BITRATES */
420
421 maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES);
422
423 if((maxNumRates - numBasicRates) > MAX_RATES)
424 {
425 no_of_rates = MAX_RATES;
426 hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates ");
427 }
428 else
429 {
430 no_of_rates = maxNumRates - numBasicRates;
431 }
432 for ( i=0; i< no_of_rates ; i++ )
433 {
434 if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F))
435 {
436 event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate (
437 &pDot11ExtSuppRates->rates[i]);
438
439 current_pad = iwe_stream_add_value (scanInfo->info,current_event,
440 current_pad, end, &event, IW_EV_PARAM_LEN);
441 }
442 }
443 }
444
445
446 if ((current_pad - current_event) >= IW_EV_LCP_LEN)
447 {
448 current_event = current_pad;
449 }
450 else
451 {
452 if (last_event == current_event)
453 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530454 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWRATE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700455 return -E2BIG;
456 }
457 }
458
459 last_event = current_event;
460 vos_mem_zero (&event, sizeof (struct iw_event));
461
462
463 event.cmd = SIOCGIWENCODE;
464
465 if (SIR_MAC_GET_PRIVACY(capabilityInfo))
466 {
467 event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
468 }
469 else
470 {
471 event.u.data.flags = IW_ENCODE_DISABLED;
472 }
473 event.u.data.length = 0;
474
475 current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid);
476
477
478 if(last_event == current_event)
479 { /* no space to add event
480 Error code, may be E2BIG */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530481 hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWENCODE");
Jeff Johnson295189b2012-06-20 16:38:30 -0700482 return -E2BIG;
483 }
484 }
485
486 last_event = current_event;
487 vos_mem_zero( &event, sizeof (struct iw_event));
488
489 /*RSSI*/
490 event.cmd = IWEVQUAL;
491 event.u.qual.qual = descriptor->rssi;
492 event.u.qual.noise = descriptor->sinr;
493
494 /*To keep the rssi icon of the connected AP in the scan window
495 *and the rssi icon of the wireless networks in sync */
496 if (( eConnectionState_Associated ==
497 pAdapter->sessionCtx.station.conn_info.connState ) &&
498 ( VOS_TRUE == vos_mem_compare(descriptor->bssId,
499 pAdapter->sessionCtx.station.conn_info.bssId,
500 WNI_CFG_BSSID_LEN)))
501 {
502 event.u.qual.level = pAdapter->rssi;
503 }
504 else
505 {
506 event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0);
507 }
508
509 event.u.qual.updated = IW_QUAL_ALL_UPDATED;
510
511 current_event = iwe_stream_add_event(scanInfo->info,current_event,
512 end, &event, IW_EV_QUAL_LEN);
513
514 if(last_event == current_event)
515 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530516 hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVQUAL");
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 return -E2BIG;
518 }
519
520
521 /* AGE */
522 event.cmd = IWEVCUSTOM;
523 p = custom;
Sameer Thalappilb0a30232013-09-27 15:37:48 -0700524 p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu",
Deepthi Gowri2f435132016-05-18 19:30:17 +0530525 vos_timer_get_system_time() - descriptor->nReceivedTime);
Jeff Johnson295189b2012-06-20 16:38:30 -0700526 event.u.data.length = p - custom;
527 current_event = iwe_stream_add_point (scanInfo->info,current_event, end,
528 &event, custom);
529 if(last_event == current_event)
530 { /* no space to add event */
Sushant Kaushik125ae692014-11-25 17:38:48 +0530531 hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)");
Jeff Johnson295189b2012-06-20 16:38:30 -0700532 return -E2BIG;
533 }
534
535 scanInfo->start = current_event;
536
537 return 0;
538}
539
540/**---------------------------------------------------------------------------
541
Siddharth Bhal76972212014-10-15 16:22:51 +0530542 \brief hdd_processSpoofMacAddrRequest() -
543
544 The function is called from scan completion callback and from
545 cfg80211 vendor command
546
547 \param - pHddCtx - Pointer to the HDD Context.
548
549 \return - 0 for success, non zero for failure
550
551 --------------------------------------------------------------------------*/
552
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +0530553void __hdd_processSpoofMacAddrRequest(struct work_struct *work)
Siddharth Bhal76972212014-10-15 16:22:51 +0530554{
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +0530555 hdd_context_t *pHddCtx =
556 container_of(to_delayed_work(work), hdd_context_t, spoof_mac_addr_work);
Siddharth Bhal76972212014-10-15 16:22:51 +0530557
558 ENTER();
559
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +0530560 if (wlan_hdd_validate_context(pHddCtx))
561 return;
562
Siddharth Bhal76972212014-10-15 16:22:51 +0530563 mutex_lock(&pHddCtx->spoofMacAddr.macSpoofingLock);
564
565 if (pHddCtx->spoofMacAddr.isEnabled) {
566 if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes(
567 (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]),
568 VOS_MAC_ADDR_LAST_3_BYTES)) {
Siddharth Bhal76972212014-10-15 16:22:51 +0530569 pHddCtx->spoofMacAddr.isEnabled = FALSE;
570 mutex_unlock(&pHddCtx->spoofMacAddr.macSpoofingLock);
Hema Aparna Medicharla8bb6f782015-03-09 12:35:05 +0530571 hddLog(LOGE, FL("Failed to generate random Mac Addr"));
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +0530572 return;
Siddharth Bhal76972212014-10-15 16:22:51 +0530573 }
574 }
575
576 hddLog(LOG1, FL("New Mac Addr Generated "MAC_ADDRESS_STR),
577 MAC_ADDR_ARRAY(pHddCtx->spoofMacAddr.randomMacAddr.bytes));
578
579 if (pHddCtx->scan_info.mScanPending != TRUE)
580 {
581 pHddCtx->spoofMacAddr.isReqDeferred = FALSE;
582 hddLog(LOG1, FL("Processing Spoof request now"));
583 /* Inform SME about spoof mac addr request*/
584 if ( eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal,
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +0530585 &pHddCtx->spoofMacAddr.randomMacAddr, true))
Siddharth Bhal76972212014-10-15 16:22:51 +0530586 {
587 hddLog(LOGE, FL("Sending Spoof request failed - Disable spoofing"));
588 pHddCtx->spoofMacAddr.isEnabled = FALSE;
589 }
590 } else
591 {
592 hddLog(LOG1, FL("Scan in Progress. Spoofing Deferred"));
593 pHddCtx->spoofMacAddr.isReqDeferred = TRUE;
594 }
595
596 mutex_unlock(&pHddCtx->spoofMacAddr.macSpoofingLock);
597
598 EXIT();
599
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +0530600 return;
601}
602
603void hdd_processSpoofMacAddrRequest(struct work_struct *work)
604{
605 vos_ssr_protect(__func__);
606 __hdd_processSpoofMacAddrRequest(work);
607 vos_ssr_unprotect(__func__);
Siddharth Bhal76972212014-10-15 16:22:51 +0530608}
609
610/**---------------------------------------------------------------------------
611
Jeff Johnson295189b2012-06-20 16:38:30 -0700612 \brief hdd_ScanRequestCallback() -
613
614 The sme module calls this callback function once it finish the scan request
615 and this function notifies the scan complete event to the wpa_supplicant.
616
617 \param - halHandle - Pointer to the Hal Handle.
618 - pContext - Pointer to the data context.
619 - scanId - Scan ID.
620 - status - CSR Status.
621 \return - 0 for success, non zero for failure
622
623 --------------------------------------------------------------------------*/
624
625static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext,
626 tANI_U32 scanId, eCsrScanStatus status)
627{
628 struct net_device *dev = (struct net_device *) pContext;
629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700630 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 union iwreq_data wrqu;
632 int we_event;
633 char *msg;
634
635 ENTER();
636
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700637 hddLog(LOGW,"%s called with halHandle = %pK, pContext = %pK, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700638 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -0700639 (int) scanId, (int) status);
640
641 /* if there is a scan request pending when the wlan driver is unloaded
642 we may be invoked as SME flushes its pending queue. If that is the
643 case, the underlying net_device may have already been destroyed, so
644 do some quick sanity before proceeding */
645 if (pAdapter->dev != dev)
646 {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -0700647 hddLog(LOGW, "%s: device mismatch %pK vs %pK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700648 __func__, pAdapter->dev, dev);
Jeff Johnson295189b2012-06-20 16:38:30 -0700649 return eHAL_STATUS_SUCCESS;
650 }
651
652 /* Check the scanId */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700653 if (pHddCtx->scan_info.scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700655 hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700656 "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -0700657 (int) scanId);
658 }
659
660 /* Scan is no longer pending */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700661 pHddCtx->scan_info.mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700662
663 // notify any applications that may be interested
664 memset(&wrqu, '\0', sizeof(wrqu));
665 we_event = SIOCGIWSCAN;
666 msg = NULL;
667 wireless_send_event(dev, we_event, &wrqu, msg);
668
669 EXIT();
670
671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
672
673 return eHAL_STATUS_SUCCESS;
674}
675
676/**---------------------------------------------------------------------------
677
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530678 \brief __iw_set_scan() -
Jeff Johnson295189b2012-06-20 16:38:30 -0700679
680 This function process the scan request from the wpa_supplicant
681 and set the scan request to the SME
682
683 \param - dev - Pointer to the net device.
684 - info - Pointer to the iw_request_info.
685 - wrqu - Pointer to the iwreq_data.
686 - extra - Pointer to the data.
687 \return - 0 for success, non zero for failure
688
689 --------------------------------------------------------------------------*/
690
691
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530692int __iw_set_scan(struct net_device *dev, struct iw_request_info *info,
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 union iwreq_data *wrqu, char *extra)
694{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530695 hdd_adapter_t *pAdapter;
696 hdd_context_t *pHddCtx;
697 hdd_wext_state_t *pwextBuf;
Jeff Johnson295189b2012-06-20 16:38:30 -0700698 tCsrScanRequest scanRequest;
699 v_U32_t scanId = 0;
700 eHalStatus status = eHAL_STATUS_SUCCESS;
701 struct iw_scan_req *scanReq = (struct iw_scan_req *)extra;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530702 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700703
704 ENTER();
705
706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
707
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530708 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
709 if (NULL == pAdapter)
710 {
711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
712 "%s: Adapter is NULL",__func__);
713 return -EINVAL;
714 }
715
716 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
717 ret = wlan_hdd_validate_context(pHddCtx);
718 if (0 != ret)
719 {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530720 return ret;
721 }
722 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
723 if (NULL == pwextBuf)
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "%s: pwextBuf is NULL",__func__);
727 return -EINVAL;
728 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700729#ifdef WLAN_BTAMP_FEATURE
730 //Scan not supported when AMP traffic is on.
731 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
732 {
733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
734 return eHAL_STATUS_SUCCESS;
735 }
736#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700737 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 {
739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
740 return eHAL_STATUS_SUCCESS;
741 }
742
Jeff Johnson295189b2012-06-20 16:38:30 -0700743 vos_mem_zero( &scanRequest, sizeof(scanRequest));
744
745 if (NULL != wrqu->data.pointer)
746 {
747 /* set scanType, active or passive */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700748 if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -0700749 {
750 scanRequest.scanType = eSIR_ACTIVE_SCAN;
751 }
752 else
753 {
754 scanRequest.scanType = eSIR_PASSIVE_SCAN;
755 }
756
757 /* set bssid using sockaddr from iw_scan_req */
758 vos_mem_copy(scanRequest.bssid,
759 &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) );
760
761 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
762
Arun Khandavalli40d60102015-11-09 10:28:18 +0530763 if(scanReq->essid_len &&
764 (scanReq->essid_len <= SIR_MAC_MAX_SSID_LENGTH)) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700765 scanRequest.SSIDs.numOfSSIDs = 1;
766 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
767 if(scanRequest.SSIDs.SSIDList) {
768 scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len;
769 vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len);
770 }
771 else
772 {
773 scanRequest.SSIDs.numOfSSIDs = 0;
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700775 VOS_ASSERT(0);
776 }
777 }
Arun Khandavalli40d60102015-11-09 10:28:18 +0530778 else
779 {
780 hddLog(LOGE, FL("Invalid essid length : %d"), scanReq->essid_len);
781 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 }
783
784 /* set min and max channel time */
785 scanRequest.minChnTime = scanReq->min_channel_time;
786 scanRequest.maxChnTime = scanReq->max_channel_time;
787
788 }
789 else
790 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700791 if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) {
Jeff Johnson295189b2012-06-20 16:38:30 -0700792 /* set the scan type to active */
793 scanRequest.scanType = eSIR_ACTIVE_SCAN;
794 } else {
795 scanRequest.scanType = eSIR_PASSIVE_SCAN;
796 }
797
798 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
799
800 /* set min and max channel time to zero */
801 scanRequest.minChnTime = 0;
802 scanRequest.maxChnTime = 0;
803 }
804
805 /* set BSSType to default type */
806 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
807
808 /*Scan all the channels */
809 scanRequest.ChannelInfo.numOfChannels = 0;
810
811 scanRequest.ChannelInfo.ChannelList = NULL;
812
813 /* set requestType to full scan */
814 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
815
816 /* if previous genIE is not NULL, update ScanIE */
817 if (0 != pwextBuf->genIE.length)
818 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700819 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
820 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -0700821 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700822 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +0530823 /* Maximum length of each IE is SIR_MAC_MAX_IE_LENGTH */
824 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
825 {
826 memcpy( pwextBuf->roamProfile.addIEScan,
827 pHddCtx->scan_info.scanAddIE.addIEdata,
828 pHddCtx->scan_info.scanAddIE.length);
829 pwextBuf->roamProfile.nAddIEScanLength =
830 pHddCtx->scan_info.scanAddIE.length;
831 }
832 else
833 {
834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
835 "Invalid ScanIE, Length is %d", pwextBuf->genIE.length);
836 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700837 /* clear previous genIE after use it */
838 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
839 }
840
841 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700842 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
843 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -0700844 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700845 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
846 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -0700847 }
Abhishek Singh99489492016-07-21 15:57:24 +0530848 if (pHddCtx->spoofMacAddr.isEnabled &&
849 pHddCtx->cfg_ini->enableMacSpoofing == 1)
850 {
851 hddLog(LOG1, FL("MAC Spoofing enabled for current scan"));
852 /*
853 * Updating SelfSta Mac Addr in TL which will be used to get
854 * staidx to fill TxBds for probe request during current scan
855 */
856 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
857 &pHddCtx->spoofMacAddr.randomMacAddr,
858 &pAdapter->macAddressCurrent);
Jeff Johnson295189b2012-06-20 16:38:30 -0700859
Abhishek Singh99489492016-07-21 15:57:24 +0530860 if (status != eHAL_STATUS_SUCCESS)
861 {
862 hddLog(LOGE, FL("Failed to update MAC Spoof Addr in TL"));
863 goto error;
864 }
865 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700866 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
867 if (!HAL_STATUS_SUCCESS(status))
868 {
869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status);
870 goto error;
871 }
872
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700873 pHddCtx->scan_info.mScanPending = TRUE;
Kaushik, Sushantdedd4ea2014-11-06 11:55:14 +0530874 pHddCtx->scan_info.sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700875
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700876 pHddCtx->scan_info.scanId = scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700877
878error:
879 if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len))
880 vos_mem_free(scanRequest.SSIDs.SSIDList);
881
882 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 return status;
884}
885
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530886int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
887 union iwreq_data *wrqu, char *extra)
888{
889 int ret;
890
891 vos_ssr_protect(__func__);
892 ret = __iw_set_scan(dev, info, wrqu, extra);
893 vos_ssr_unprotect(__func__);
894
895 return ret;
896}
897
Jeff Johnson295189b2012-06-20 16:38:30 -0700898/**---------------------------------------------------------------------------
899
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530900 \brief __iw_get_scan() -
Jeff Johnson295189b2012-06-20 16:38:30 -0700901
902 This function returns the scan results to the wpa_supplicant
903
904 \param - dev - Pointer to the net device.
905 - info - Pointer to the iw_request_info.
906 - wrqu - Pointer to the iwreq_data.
907 - extra - Pointer to the data.
908 \return - 0 for success, non zero for failure
909
910 --------------------------------------------------------------------------*/
911
912
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530913int __iw_get_scan(struct net_device *dev,
914 struct iw_request_info *info,
915 union iwreq_data *wrqu, char *extra)
Jeff Johnson295189b2012-06-20 16:38:30 -0700916{
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530917 hdd_adapter_t *pAdapter;
918 hdd_context_t *pHddCtx;
919 tHalHandle hHal;
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 tCsrScanResultInfo *pScanResult;
921 eHalStatus status = eHAL_STATUS_SUCCESS;
922 hdd_scan_info_t scanInfo;
923 tScanResultHandle pResult;
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530924 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -0700925
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530926 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!",
928 __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA);
Jeff Johnson295189b2012-06-20 16:38:30 -0700929
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530930 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
931 if (NULL == pAdapter)
932 {
933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
934 "%s: Adapter is NULL",__func__);
935 return -EINVAL;
936 }
937
938 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
939 ret = wlan_hdd_validate_context(pHddCtx);
940 if (0 != ret)
941 {
Mahesh A Saptasagar153c4662015-02-06 12:13:08 +0530942 return ret;
943 }
944 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
945 if (NULL == hHal)
946 {
947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
948 "%s: Hal Context is NULL",__func__);
949 return -EINVAL;
950 }
951
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700952 if (TRUE == pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 {
954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__);
955 return -EAGAIN;
956 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 scanInfo.dev = dev;
958 scanInfo.start = extra;
959 scanInfo.info = info;
960
961 if (0 == wrqu->data.length)
962 {
963 scanInfo.end = extra + IW_SCAN_MAX_DATA;
964 }
965 else
966 {
967 scanInfo.end = extra + wrqu->data.length;
968 }
969
970 status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult);
971
972 if (NULL == pResult)
973 {
974 // no scan results
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530975 hddLog(LOG1,"__iw_get_scan: NULL Scan Result ");
Jeff Johnson295189b2012-06-20 16:38:30 -0700976 return 0;
977 }
978
979 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
980
981 while (pScanResult)
982 {
983 status = hdd_IndicateScanResult(&scanInfo, pScanResult);
984 if (0 != status)
985 {
986 break;
987 }
988 i++;
989 pScanResult = sme_ScanResultGetNext(hHal, pResult);
990 }
991
992 sme_ScanResultPurge(hHal, pResult);
993
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +0530995 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 return status;
997}
998
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +0530999int iw_get_scan(struct net_device *dev,
1000 struct iw_request_info *info,
1001 union iwreq_data *wrqu, char *extra)
1002{
1003 int ret;
1004
1005 vos_ssr_protect(__func__);
1006 ret = __iw_get_scan(dev, info, wrqu, extra);
1007 vos_ssr_unprotect(__func__);
1008
1009 return ret;
1010}
1011
Jeff Johnson295189b2012-06-20 16:38:30 -07001012#if 0
1013static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext,
1014 tANI_U32 scanId, eCsrScanStatus status)
1015{
1016 struct net_device *dev = (struct net_device *) pContext;
1017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
1018 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1019 union iwreq_data wrqu;
1020 int we_event;
1021 char *msg;
1022 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1023 ENTER();
1024
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001025 hddLog(LOG1,"%s called with halHandle = %pK, pContext = %pK, scanID = %d,"
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001026 " returned status = %d", __func__, halHandle, pContext,
Jeff Johnson295189b2012-06-20 16:38:30 -07001027 (int) scanId, (int) status);
1028
1029 /* Check the scanId */
1030 if (pwextBuf->scanId != scanId)
1031 {
1032 hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001033 "scanId = %d ", __func__, (int) pwextBuf->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 (int) scanId);
1035 }
1036
1037 /* Scan is no longer pending */
1038 pwextBuf->mScanPending = VOS_FALSE;
1039
1040 // notify any applications that may be interested
1041 memset(&wrqu, '\0', sizeof(wrqu));
1042 we_event = SIOCGIWSCAN;
1043 msg = NULL;
1044 wireless_send_event(dev, we_event, &wrqu, msg);
1045
1046 vos_status = vos_event_set(&pwextBuf->vosevent);
1047
1048 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!"));
1051 return VOS_STATUS_E_FAILURE;
1052 }
1053
1054 EXIT();
1055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1056
1057 return eHAL_STATUS_SUCCESS;
1058}
1059#endif
1060
1061int iw_set_cscan(struct net_device *dev, struct iw_request_info *info,
1062 union iwreq_data *wrqu, char *extra)
1063{
1064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1067 tCsrScanRequest scanRequest;
1068 v_U32_t scanId = 0;
1069 eHalStatus status = eHAL_STATUS_SUCCESS;
1070 v_U8_t channelIdx;
1071
1072 ENTER();
1073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__);
1074
1075#ifdef WLAN_BTAMP_FEATURE
1076 //Scan not supported when AMP traffic is on.
1077 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
1078 {
1079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__);
1080 return eHAL_STATUS_SUCCESS;
1081 }
1082#endif
1083
1084 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1085 {
1086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1087 return eHAL_STATUS_SUCCESS;
1088 }
1089
1090 vos_mem_zero( &scanRequest, sizeof(scanRequest));
1091 if (NULL != wrqu->data.pointer)
1092 {
1093 char *str_ptr = NULL;
1094 tCsrSSIDInfo *SsidInfo = NULL;
1095 int num_ssid = 0;
1096 int i, j, ssid_start;
1097 hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP;
1098
Rajeev Kumarbe97df02013-10-24 18:30:39 -07001099 str_ptr = extra;
Jeff Johnson295189b2012-06-20 16:38:30 -07001100
1101 i = WEXT_CSCAN_HEADER_SIZE;
1102
1103 if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] )
1104 {
1105 scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i];
1106 ++i;
1107 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001108 pHddCtx->scan_info.scan_pending_option = scanPendingOption;
Jeff Johnson295189b2012-06-20 16:38:30 -07001109
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001110 if(pHddCtx->scan_info.mScanPending == TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 {
1112 hddLog(LOG1,"%s: mScanPending is TRUE",__func__);
1113 /* If any scan is pending, just giveup this scan request */
1114 if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption)
1115 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001116 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001117 return eHAL_STATUS_SUCCESS;
1118 }
1119 /* If any scan pending, wait till finish current scan,
1120 and try this scan request when previous scan finish */
1121 else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption)
1122 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001123 pHddCtx->scan_info.waitScanResult = TRUE;
1124 vos_event_reset(&pHddCtx->scan_info.scan_finished_event);
1125 if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event,
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 WEXT_CSCAN_SCAN_DONE_WAIT_TIME))
1127 {
1128 hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__);
1129 return eHAL_STATUS_SUCCESS;
1130 }
1131 }
1132 /* Piggyback previous scan result */
1133 else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption)
1134 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001135 pHddCtx->scan_info.waitScanResult = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 return eHAL_STATUS_SUCCESS;
1137 }
1138 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001139 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001140
1141 /* Check for scan IE */
1142 while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] )
1143 {
1144 /* ssid_len */
1145 if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION)
1146 {
1147 /* total number of ssid's */
1148 num_ssid++;
1149 /* increment length filed */
1150 i += str_ptr[i] + 1;
1151 }
1152 /* i should be saved and it will be pointing to 'C' */
1153 }
1154
1155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid);
1156 if( num_ssid )
1157 {
1158 /* To be fixed in SME and PE: override the number of ssid with 1,
1159 * as SME and PE does not handle multiple SSID in scan request
1160 * */
1161 scanRequest.SSIDs.numOfSSIDs = num_ssid;
1162 /* Allocate num_ssid tCsrSSIDInfo structure */
1163 SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo));
1164 if(NULL == scanRequest.SSIDs.SSIDList) {
1165 hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer");
1166 return -ENOMEM;
1167 }
1168
1169 /* copy all the ssid's and their length */
1170 ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */
1171 for(j = 0; j < num_ssid; j++) {
1172 if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){
1173 scanRequest.SSIDs.numOfSSIDs -= 1;
1174 } else{
1175 /* get the ssid length */
1176 SsidInfo->SSID.length = str_ptr[ssid_start++];
1177 vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length);
Arif Hussain6d2a3322013-11-17 19:50:10 -08001178 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001179 }
1180 /* skipping length */
1181 ssid_start += str_ptr[ssid_start - 1] + 1;
1182 /* Store next ssid info */
1183 SsidInfo++;
1184 }
1185 }
1186
1187 /* Check for Channel IE */
1188 if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i])
1189 {
1190 if( str_ptr[++i] == 0 )
1191 {
1192 scanRequest.ChannelInfo.numOfChannels = 0;
1193 scanRequest.ChannelInfo.ChannelList = NULL;
1194 i++;
1195 }
1196 else {
1197
1198 /* increment the counter */
1199 scanRequest.ChannelInfo.numOfChannels = str_ptr[i++];
1200 /* store temp channel list */
1201 /* SME expects 1 byte channel content */
1202 scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t));
1203 if(NULL == scanRequest.ChannelInfo.ChannelList)
1204 {
c_hpothu7f63e882013-10-02 19:13:35 +05301205 hddLog(LOGE, "memory alloc failed for channel list creation");
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 status = -ENOMEM;
1207 goto exit_point;
1208 }
1209
1210 for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++)
1211 {
1212 /* SCAN request from upper layer has 2 bytes channel */
1213 scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i];
1214 i += sizeof(v_U16_t);
1215 }
1216 }
1217 }
1218
1219 /* Set default */
1220 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1221 scanRequest.minChnTime = 0;
1222 scanRequest.maxChnTime = 0;
1223
1224 /* Now i is pointing to passive dwell dwell time */
1225 /* 'P',min dwell time, max dwell time */
1226 /* next two offsets contain min and max channel time */
1227 if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) )
1228 {
1229 /* No SSID specified, num_ssid == 0, then start paasive scan */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001230 if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 {
1232 scanRequest.scanType = eSIR_PASSIVE_SCAN;
1233 scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time;
1234 scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time;
1235 i++;
1236 }
1237 else
1238 {
1239 i += 3;
1240 }
1241 }
1242
1243 /* H indicates active channel time */
1244 if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) )
1245 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001246 if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07001247 {
1248 scanRequest.scanType = eSIR_ACTIVE_SCAN;
1249 scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time;
1250 scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time;
1251 i++;
1252 }
1253 else
1254 {
1255 i +=3;
1256 }
1257 }
1258 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
1259 /* set requestType to full scan */
1260 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001261 pHddCtx->scan_info.mScanPending = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001262
1263 /* if previous genIE is not NULL, update ScanIE */
1264 if(0 != pwextBuf->genIE.length)
1265 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001266 memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) );
1267 memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata,
Jeff Johnson295189b2012-06-20 16:38:30 -07001268 pwextBuf->genIE.length );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001269 pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length;
Agarwal Ashish4f616132013-12-30 23:32:50 +05301270 if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length)
1271 {
1272 memcpy( pwextBuf->roamProfile.addIEScan,
1273 pHddCtx->scan_info.scanAddIE.addIEdata,
1274 pHddCtx->scan_info.scanAddIE.length);
1275 pwextBuf->roamProfile.nAddIEScanLength =
1276 pHddCtx->scan_info.scanAddIE.length;
1277 }
1278 else
1279 {
1280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1281 "Invalid ScanIE, Length is %d",
1282 pwextBuf->genIE.length);
1283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001284
1285 /* clear previous genIE after use it */
1286 memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) );
1287 }
1288
1289 /* push addIEScan in scanRequset if exist */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001290 if (pHddCtx->scan_info.scanAddIE.addIEdata &&
1291 pHddCtx->scan_info.scanAddIE.length)
Jeff Johnson295189b2012-06-20 16:38:30 -07001292 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001293 scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length;
1294 scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata;
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 }
1296
1297 status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal,
1298 pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev );
1299 if( !HAL_STATUS_SUCCESS(status) )
1300 {
1301 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 -07001302 pHddCtx->scan_info.mScanPending = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001303 status = -EINVAL;
1304 goto exit_point;
1305 }
1306
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07001307 pHddCtx->scan_info.scanId = scanId;
Kaushik, Sushantdedd4ea2014-11-06 11:55:14 +05301308 pHddCtx->scan_info.sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001309
1310 } //end of data->pointer
1311 else {
1312 status = -1;
1313 }
1314
1315exit_point:
1316
1317 /* free ssidlist */
1318 if (scanRequest.SSIDs.SSIDList)
1319 {
1320 vos_mem_free(scanRequest.SSIDs.SSIDList);
1321 }
1322 /* free the channel list */
1323 if(scanRequest.ChannelInfo.ChannelList)
1324 {
1325 vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList);
1326 }
1327
1328 EXIT();
1329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__);
1330 return status;
1331}
1332
1333/* Abort any MAC scan if in progress */
c_hpothua3d45d52015-01-05 14:11:17 +05301334tSirAbortScanStatus hdd_abort_mac_scan(hdd_context_t* pHddCtx,
1335 tANI_U8 sessionId,
1336 eCsrAbortReason reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07001337{
c_hpothua3d45d52015-01-05 14:11:17 +05301338 return sme_AbortMacScan(pHddCtx->hHal, sessionId, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07001339}
1340