1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "11n.h"
26#include "cfg80211.h"
27
28
29#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14
30
31#define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD 4
32#define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD 15
33#define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD 27
34#define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD 35
35
36
37#define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \
38 + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN \
39 *sizeof(struct mwifiex_chan_scan_param_set)))
40
41
42#define RATE_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_rates_param_set) \
43 + HOSTCMD_SUPPORTED_RATES)
44
45
46
47#define WILDCARD_SSID_TLV_MAX_SIZE \
48 (MWIFIEX_MAX_SSID_LIST_LENGTH * \
49 (sizeof(struct mwifiex_ie_types_wildcard_ssid_params) \
50 + IEEE80211_MAX_SSID_LEN))
51
52
53#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config) \
54 + sizeof(struct mwifiex_ie_types_num_probes) \
55 + sizeof(struct mwifiex_ie_types_htcap) \
56 + CHAN_TLV_MAX_SIZE \
57 + RATE_TLV_MAX_SIZE \
58 + WILDCARD_SSID_TLV_MAX_SIZE)
59
60
61union mwifiex_scan_cmd_config_tlv {
62
63 struct mwifiex_scan_cmd_config config;
64
65 u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
66};
67
68enum cipher_suite {
69 CIPHER_SUITE_TKIP,
70 CIPHER_SUITE_CCMP,
71 CIPHER_SUITE_MAX
72};
73static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
74 { 0x00, 0x50, 0xf2, 0x02 },
75 { 0x00, 0x50, 0xf2, 0x04 },
76};
77static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
78 { 0x00, 0x0f, 0xac, 0x02 },
79 { 0x00, 0x0f, 0xac, 0x04 },
80};
81
82
83
84
85
86
87
88static u8
89mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
90{
91 u8 count;
92
93 count = iebody->ptk_cnt[0];
94
95
96
97
98
99 while (count) {
100 if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
101 return MWIFIEX_OUI_PRESENT;
102
103 --count;
104 if (count)
105 iebody = (struct ie_body *) ((u8 *) iebody +
106 sizeof(iebody->ptk_body));
107 }
108
109 pr_debug("info: %s: OUI is not found in PTK\n", __func__);
110 return MWIFIEX_OUI_NOT_PRESENT;
111}
112
113
114
115
116
117
118
119
120static u8
121mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
122{
123 u8 *oui;
124 struct ie_body *iebody;
125 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
126
127 if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
128 ieee_hdr.element_id == WLAN_EID_RSN))) {
129 iebody = (struct ie_body *)
130 (((u8 *) bss_desc->bcn_rsn_ie->data) +
131 RSN_GTK_OUI_OFFSET);
132 oui = &mwifiex_rsn_oui[cipher][0];
133 ret = mwifiex_search_oui_in_ie(iebody, oui);
134 if (ret)
135 return ret;
136 }
137 return ret;
138}
139
140
141
142
143
144
145
146
147static u8
148mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
149{
150 u8 *oui;
151 struct ie_body *iebody;
152 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
153
154 if (((bss_desc->bcn_wpa_ie) &&
155 ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id ==
156 WLAN_EID_VENDOR_SPECIFIC))) {
157 iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
158 oui = &mwifiex_wpa_oui[cipher][0];
159 ret = mwifiex_search_oui_in_ie(iebody, oui);
160 if (ret)
161 return ret;
162 }
163 return ret;
164}
165
166
167
168
169s32
170mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
171{
172 if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
173 return -1;
174 return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
175}
176
177
178
179
180
181static bool
182mwifiex_is_bss_wapi(struct mwifiex_private *priv,
183 struct mwifiex_bssdescriptor *bss_desc)
184{
185 if (priv->sec_info.wapi_enabled &&
186 (bss_desc->bcn_wapi_ie &&
187 ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
188 WLAN_EID_BSS_AC_ACCESS_DELAY))) {
189 return true;
190 }
191 return false;
192}
193
194
195
196
197
198static bool
199mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
200 struct mwifiex_bssdescriptor *bss_desc)
201{
202 if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
203 !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
204 ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
205 WLAN_EID_VENDOR_SPECIFIC)) &&
206 ((!bss_desc->bcn_rsn_ie) ||
207 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
208 WLAN_EID_RSN)) &&
209 !priv->sec_info.encryption_mode && !bss_desc->privacy) {
210 return true;
211 }
212 return false;
213}
214
215
216
217
218
219static bool
220mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
221 struct mwifiex_bssdescriptor *bss_desc)
222{
223 if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
224 !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
225 return true;
226 }
227 return false;
228}
229
230
231
232
233
234static bool
235mwifiex_is_bss_wpa(struct mwifiex_private *priv,
236 struct mwifiex_bssdescriptor *bss_desc)
237{
238 if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
239 !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
240 ((*(bss_desc->bcn_wpa_ie)).
241 vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC))
242
243
244
245
246 ) {
247 dev_dbg(priv->adapter->dev, "info: %s: WPA:"
248 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
249 "EncMode=%#x privacy=%#x\n", __func__,
250 (bss_desc->bcn_wpa_ie) ?
251 (*(bss_desc->bcn_wpa_ie)).
252 vend_hdr.element_id : 0,
253 (bss_desc->bcn_rsn_ie) ?
254 (*(bss_desc->bcn_rsn_ie)).
255 ieee_hdr.element_id : 0,
256 (priv->sec_info.wep_enabled) ? "e" : "d",
257 (priv->sec_info.wpa_enabled) ? "e" : "d",
258 (priv->sec_info.wpa2_enabled) ? "e" : "d",
259 priv->sec_info.encryption_mode,
260 bss_desc->privacy);
261 return true;
262 }
263 return false;
264}
265
266
267
268
269
270static bool
271mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
272 struct mwifiex_bssdescriptor *bss_desc)
273{
274 if (!priv->sec_info.wep_enabled &&
275 !priv->sec_info.wpa_enabled &&
276 priv->sec_info.wpa2_enabled &&
277 ((bss_desc->bcn_rsn_ie) &&
278 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) {
279
280
281
282
283 dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
284 " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
285 "EncMode=%#x privacy=%#x\n", __func__,
286 (bss_desc->bcn_wpa_ie) ?
287 (*(bss_desc->bcn_wpa_ie)).
288 vend_hdr.element_id : 0,
289 (bss_desc->bcn_rsn_ie) ?
290 (*(bss_desc->bcn_rsn_ie)).
291 ieee_hdr.element_id : 0,
292 (priv->sec_info.wep_enabled) ? "e" : "d",
293 (priv->sec_info.wpa_enabled) ? "e" : "d",
294 (priv->sec_info.wpa2_enabled) ? "e" : "d",
295 priv->sec_info.encryption_mode,
296 bss_desc->privacy);
297 return true;
298 }
299 return false;
300}
301
302
303
304
305
306static bool
307mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
308 struct mwifiex_bssdescriptor *bss_desc)
309{
310 if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
311 !priv->sec_info.wpa2_enabled &&
312 ((!bss_desc->bcn_wpa_ie) ||
313 ((*(bss_desc->bcn_wpa_ie)).
314 vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
315 ((!bss_desc->bcn_rsn_ie) ||
316 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
317 !priv->sec_info.encryption_mode && bss_desc->privacy) {
318 return true;
319 }
320 return false;
321}
322
323
324
325
326
327static bool
328mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
329 struct mwifiex_bssdescriptor *bss_desc)
330{
331 if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
332 !priv->sec_info.wpa2_enabled &&
333 ((!bss_desc->bcn_wpa_ie) ||
334 ((*(bss_desc->bcn_wpa_ie)).
335 vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
336 ((!bss_desc->bcn_rsn_ie) ||
337 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
338 priv->sec_info.encryption_mode && bss_desc->privacy) {
339 dev_dbg(priv->adapter->dev, "info: %s: dynamic "
340 "WEP: wpa_ie=%#x wpa2_ie=%#x "
341 "EncMode=%#x privacy=%#x\n",
342 __func__,
343 (bss_desc->bcn_wpa_ie) ?
344 (*(bss_desc->bcn_wpa_ie)).
345 vend_hdr.element_id : 0,
346 (bss_desc->bcn_rsn_ie) ?
347 (*(bss_desc->bcn_rsn_ie)).
348 ieee_hdr.element_id : 0,
349 priv->sec_info.encryption_mode,
350 bss_desc->privacy);
351 return true;
352 }
353 return false;
354}
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374static s32
375mwifiex_is_network_compatible(struct mwifiex_private *priv,
376 struct mwifiex_bssdescriptor *bss_desc, u32 mode)
377{
378 struct mwifiex_adapter *adapter = priv->adapter;
379
380 bss_desc->disable_11n = false;
381
382
383 if (priv->media_connected &&
384 (priv->bss_mode == NL80211_IFTYPE_STATION) &&
385 (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
386 return 0;
387
388 if (priv->wps.session_enable) {
389 dev_dbg(adapter->dev,
390 "info: return success directly in WPS period\n");
391 return 0;
392 }
393
394 if (bss_desc->chan_sw_ie_present) {
395 dev_err(adapter->dev,
396 "Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
397 return -1;
398 }
399
400 if (mwifiex_is_bss_wapi(priv, bss_desc)) {
401 dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
402 return 0;
403 }
404
405 if (bss_desc->bss_mode == mode) {
406 if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
407
408 return 0;
409 } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
410
411 dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
412 bss_desc->disable_11n = true;
413 return 0;
414 } else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
415
416 if (((priv->adapter->config_bands & BAND_GN ||
417 priv->adapter->config_bands & BAND_AN) &&
418 bss_desc->bcn_ht_cap) &&
419 !mwifiex_is_wpa_oui_present(bss_desc,
420 CIPHER_SUITE_CCMP)) {
421
422 if (mwifiex_is_wpa_oui_present
423 (bss_desc, CIPHER_SUITE_TKIP)) {
424 dev_dbg(adapter->dev,
425 "info: Disable 11n if AES "
426 "is not supported by AP\n");
427 bss_desc->disable_11n = true;
428 } else {
429 return -1;
430 }
431 }
432 return 0;
433 } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
434
435 if (((priv->adapter->config_bands & BAND_GN ||
436 priv->adapter->config_bands & BAND_AN) &&
437 bss_desc->bcn_ht_cap) &&
438 !mwifiex_is_rsn_oui_present(bss_desc,
439 CIPHER_SUITE_CCMP)) {
440
441 if (mwifiex_is_rsn_oui_present
442 (bss_desc, CIPHER_SUITE_TKIP)) {
443 dev_dbg(adapter->dev,
444 "info: Disable 11n if AES "
445 "is not supported by AP\n");
446 bss_desc->disable_11n = true;
447 } else {
448 return -1;
449 }
450 }
451 return 0;
452 } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) {
453
454 return 0;
455 } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
456
457 return 0;
458 }
459
460
461 dev_dbg(adapter->dev,
462 "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s "
463 "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__,
464 (bss_desc->bcn_wpa_ie) ?
465 (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0,
466 (bss_desc->bcn_rsn_ie) ?
467 (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0,
468 (priv->sec_info.wep_enabled) ? "e" : "d",
469 (priv->sec_info.wpa_enabled) ? "e" : "d",
470 (priv->sec_info.wpa2_enabled) ? "e" : "d",
471 priv->sec_info.encryption_mode, bss_desc->privacy);
472 return -1;
473 }
474
475
476 return -1;
477}
478
479
480
481
482
483
484
485
486static int
487mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
488 const struct mwifiex_user_scan_cfg
489 *user_scan_in,
490 struct mwifiex_chan_scan_param_set
491 *scan_chan_list,
492 u8 filtered_scan)
493{
494 enum ieee80211_band band;
495 struct ieee80211_supported_band *sband;
496 struct ieee80211_channel *ch;
497 struct mwifiex_adapter *adapter = priv->adapter;
498 int chan_idx = 0, i;
499
500 for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
501
502 if (!priv->wdev->wiphy->bands[band])
503 continue;
504
505 sband = priv->wdev->wiphy->bands[band];
506
507 for (i = 0; (i < sband->n_channels) ; i++) {
508 ch = &sband->channels[i];
509 if (ch->flags & IEEE80211_CHAN_DISABLED)
510 continue;
511 scan_chan_list[chan_idx].radio_type = band;
512
513 if (user_scan_in &&
514 user_scan_in->chan_list[0].scan_time)
515 scan_chan_list[chan_idx].max_scan_time =
516 cpu_to_le16((u16) user_scan_in->
517 chan_list[0].scan_time);
518 else if (ch->flags & IEEE80211_CHAN_NO_IR)
519 scan_chan_list[chan_idx].max_scan_time =
520 cpu_to_le16(adapter->passive_scan_time);
521 else
522 scan_chan_list[chan_idx].max_scan_time =
523 cpu_to_le16(adapter->active_scan_time);
524
525 if (ch->flags & IEEE80211_CHAN_NO_IR)
526 scan_chan_list[chan_idx].chan_scan_mode_bitmap
527 |= MWIFIEX_PASSIVE_SCAN;
528 else
529 scan_chan_list[chan_idx].chan_scan_mode_bitmap
530 &= ~MWIFIEX_PASSIVE_SCAN;
531 scan_chan_list[chan_idx].chan_number =
532 (u32) ch->hw_value;
533 if (filtered_scan) {
534 scan_chan_list[chan_idx].max_scan_time =
535 cpu_to_le16(adapter->specific_scan_time);
536 scan_chan_list[chan_idx].chan_scan_mode_bitmap
537 |= MWIFIEX_DISABLE_CHAN_FILT;
538 }
539 chan_idx++;
540 }
541
542 }
543 return chan_idx;
544}
545
546
547static int
548mwifiex_append_rate_tlv(struct mwifiex_private *priv,
549 struct mwifiex_scan_cmd_config *scan_cfg_out,
550 u8 radio)
551{
552 struct mwifiex_ie_types_rates_param_set *rates_tlv;
553 u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
554 u32 rates_size;
555
556 memset(rates, 0, sizeof(rates));
557
558 tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
559
560 if (priv->scan_request)
561 rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
562 radio);
563 else
564 rates_size = mwifiex_get_supported_rates(priv, rates);
565
566 dev_dbg(priv->adapter->dev, "info: SCAN_CMD: Rates size = %d\n",
567 rates_size);
568 rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
569 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
570 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
571 memcpy(rates_tlv->rates, rates, rates_size);
572 scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
573
574 return rates_size;
575}
576
577
578
579
580
581
582
583
584
585
586static int
587mwifiex_scan_channel_list(struct mwifiex_private *priv,
588 u32 max_chan_per_scan, u8 filtered_scan,
589 struct mwifiex_scan_cmd_config *scan_cfg_out,
590 struct mwifiex_ie_types_chan_list_param_set
591 *chan_tlv_out,
592 struct mwifiex_chan_scan_param_set *scan_chan_list)
593{
594 struct mwifiex_adapter *adapter = priv->adapter;
595 int ret = 0;
596 struct mwifiex_chan_scan_param_set *tmp_chan_list;
597 struct mwifiex_chan_scan_param_set *start_chan;
598 struct cmd_ctrl_node *cmd_node, *tmp_node;
599 unsigned long flags;
600 u32 tlv_idx, rates_size, cmd_no;
601 u32 total_scan_time;
602 u32 done_early;
603 u8 radio_type;
604
605 if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
606 dev_dbg(priv->adapter->dev,
607 "info: Scan: Null detect: %p, %p, %p\n",
608 scan_cfg_out, chan_tlv_out, scan_chan_list);
609 return -1;
610 }
611
612
613 mwifiex_11h_get_csa_closed_channel(priv);
614
615 chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
616
617
618
619 tmp_chan_list = scan_chan_list;
620
621
622
623
624 while (tmp_chan_list->chan_number) {
625
626 tlv_idx = 0;
627 total_scan_time = 0;
628 radio_type = 0;
629 chan_tlv_out->header.len = 0;
630 start_chan = tmp_chan_list;
631 done_early = false;
632
633
634
635
636
637
638
639
640
641
642 while (tlv_idx < max_chan_per_scan &&
643 tmp_chan_list->chan_number && !done_early) {
644
645 if (tmp_chan_list->chan_number == priv->csa_chan) {
646 tmp_chan_list++;
647 continue;
648 }
649
650 radio_type = tmp_chan_list->radio_type;
651 dev_dbg(priv->adapter->dev,
652 "info: Scan: Chan(%3d), Radio(%d),"
653 " Mode(%d, %d), Dur(%d)\n",
654 tmp_chan_list->chan_number,
655 tmp_chan_list->radio_type,
656 tmp_chan_list->chan_scan_mode_bitmap
657 & MWIFIEX_PASSIVE_SCAN,
658 (tmp_chan_list->chan_scan_mode_bitmap
659 & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
660 le16_to_cpu(tmp_chan_list->max_scan_time));
661
662
663
664 memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
665 tmp_chan_list,
666 sizeof(chan_tlv_out->chan_scan_param));
667
668
669
670 le16_add_cpu(&chan_tlv_out->header.len,
671 sizeof(chan_tlv_out->chan_scan_param));
672
673
674
675
676
677
678
679 scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
680 scan_cfg_out->tlv_buf);
681
682
683
684 scan_cfg_out->tlv_buf_len +=
685 (sizeof(chan_tlv_out->header)
686 + le16_to_cpu(chan_tlv_out->header.len));
687
688
689
690 tlv_idx++;
691
692
693 total_scan_time +=
694 le16_to_cpu(tmp_chan_list->max_scan_time);
695
696 done_early = false;
697
698
699
700
701 if (!filtered_scan &&
702 (tmp_chan_list->chan_number == 1 ||
703 tmp_chan_list->chan_number == 6 ||
704 tmp_chan_list->chan_number == 11))
705 done_early = true;
706
707
708
709 tmp_chan_list++;
710
711
712
713
714 if (!filtered_scan &&
715 (tmp_chan_list->chan_number == 1 ||
716 tmp_chan_list->chan_number == 6 ||
717 tmp_chan_list->chan_number == 11))
718 done_early = true;
719 }
720
721
722
723 if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
724 dev_err(priv->adapter->dev, "total scan time %dms"
725 " is over limit (%dms), scan skipped\n",
726 total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
727 ret = -1;
728 break;
729 }
730
731 rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
732 radio_type);
733
734 priv->adapter->scan_channels = start_chan;
735
736
737
738 if (priv->adapter->ext_scan)
739 cmd_no = HostCmd_CMD_802_11_SCAN_EXT;
740 else
741 cmd_no = HostCmd_CMD_802_11_SCAN;
742
743 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
744 0, scan_cfg_out, false);
745
746
747
748
749
750 scan_cfg_out->tlv_buf_len -=
751 sizeof(struct mwifiex_ie_types_header) + rates_size;
752
753 if (ret) {
754 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
755 list_for_each_entry_safe(cmd_node, tmp_node,
756 &adapter->scan_pending_q,
757 list) {
758 list_del(&cmd_node->list);
759 cmd_node->wait_q_enabled = false;
760 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
761 }
762 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
763 flags);
764 break;
765 }
766 }
767
768 if (ret)
769 return -1;
770
771 return 0;
772}
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794static void
795mwifiex_config_scan(struct mwifiex_private *priv,
796 const struct mwifiex_user_scan_cfg *user_scan_in,
797 struct mwifiex_scan_cmd_config *scan_cfg_out,
798 struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
799 struct mwifiex_chan_scan_param_set *scan_chan_list,
800 u8 *max_chan_per_scan, u8 *filtered_scan,
801 u8 *scan_current_only)
802{
803 struct mwifiex_adapter *adapter = priv->adapter;
804 struct mwifiex_ie_types_num_probes *num_probes_tlv;
805 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
806 struct mwifiex_ie_types_bssid_list *bssid_tlv;
807 u8 *tlv_pos;
808 u32 num_probes;
809 u32 ssid_len;
810 u32 chan_idx;
811 u32 chan_num;
812 u32 scan_type;
813 u16 scan_dur;
814 u8 channel;
815 u8 radio_type;
816 int i;
817 u8 ssid_filter;
818 struct mwifiex_ie_types_htcap *ht_cap;
819
820
821
822
823
824
825 scan_cfg_out->tlv_buf_len = 0;
826
827
828
829
830 tlv_pos = scan_cfg_out->tlv_buf;
831
832
833
834 *filtered_scan = false;
835
836
837
838
839 *scan_current_only = false;
840
841 if (user_scan_in) {
842
843
844
845
846 ssid_filter = true;
847
848
849
850 scan_cfg_out->bss_mode =
851 (user_scan_in->bss_mode ? (u8) user_scan_in->
852 bss_mode : (u8) adapter->scan_mode);
853
854
855
856 num_probes =
857 (user_scan_in->num_probes ? user_scan_in->
858 num_probes : adapter->scan_probes);
859
860
861
862
863
864
865 memcpy(scan_cfg_out->specific_bssid,
866 user_scan_in->specific_bssid,
867 sizeof(scan_cfg_out->specific_bssid));
868
869 if (adapter->ext_scan &&
870 !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
871 bssid_tlv =
872 (struct mwifiex_ie_types_bssid_list *)tlv_pos;
873 bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
874 bssid_tlv->header.len = cpu_to_le16(ETH_ALEN);
875 memcpy(bssid_tlv->bssid, user_scan_in->specific_bssid,
876 ETH_ALEN);
877 tlv_pos += sizeof(struct mwifiex_ie_types_bssid_list);
878 }
879
880 for (i = 0; i < user_scan_in->num_ssids; i++) {
881 ssid_len = user_scan_in->ssid_list[i].ssid_len;
882
883 wildcard_ssid_tlv =
884 (struct mwifiex_ie_types_wildcard_ssid_params *)
885 tlv_pos;
886 wildcard_ssid_tlv->header.type =
887 cpu_to_le16(TLV_TYPE_WILDCARDSSID);
888 wildcard_ssid_tlv->header.len = cpu_to_le16(
889 (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
890 max_ssid_length)));
891
892
893
894
895
896
897
898 if (ssid_len)
899 wildcard_ssid_tlv->max_ssid_length = 0;
900 else
901 wildcard_ssid_tlv->max_ssid_length =
902 IEEE80211_MAX_SSID_LEN;
903
904 memcpy(wildcard_ssid_tlv->ssid,
905 user_scan_in->ssid_list[i].ssid, ssid_len);
906
907 tlv_pos += (sizeof(wildcard_ssid_tlv->header)
908 + le16_to_cpu(wildcard_ssid_tlv->header.len));
909
910 dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n",
911 i, wildcard_ssid_tlv->ssid,
912 wildcard_ssid_tlv->max_ssid_length);
913
914
915
916
917
918 if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
919 ssid_filter = false;
920 }
921
922
923
924
925
926
927
928 if ((i && ssid_filter) ||
929 !is_zero_ether_addr(scan_cfg_out->specific_bssid))
930 *filtered_scan = true;
931 } else {
932 scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
933 num_probes = adapter->scan_probes;
934 }
935
936
937
938
939
940 if (*filtered_scan)
941 *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
942 else
943 *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
944
945
946
947 if (num_probes) {
948
949 dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
950 num_probes);
951
952 num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
953 num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
954 num_probes_tlv->header.len =
955 cpu_to_le16(sizeof(num_probes_tlv->num_probes));
956 num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
957
958 tlv_pos += sizeof(num_probes_tlv->header) +
959 le16_to_cpu(num_probes_tlv->header.len);
960
961 }
962
963 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
964 (priv->adapter->config_bands & BAND_GN ||
965 priv->adapter->config_bands & BAND_AN)) {
966 ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
967 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
968 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
969 ht_cap->header.len =
970 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
971 radio_type =
972 mwifiex_band_to_radio_type(priv->adapter->config_bands);
973 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
974 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
975 }
976
977
978 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
979
980
981
982
983
984
985
986 *chan_list_out =
987 (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
988
989 if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
990
991 dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
992
993 for (chan_idx = 0;
994 chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
995 user_scan_in->chan_list[chan_idx].chan_number;
996 chan_idx++) {
997
998 channel = user_scan_in->chan_list[chan_idx].chan_number;
999 (scan_chan_list + chan_idx)->chan_number = channel;
1000
1001 radio_type =
1002 user_scan_in->chan_list[chan_idx].radio_type;
1003 (scan_chan_list + chan_idx)->radio_type = radio_type;
1004
1005 scan_type = user_scan_in->chan_list[chan_idx].scan_type;
1006
1007 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1008 (scan_chan_list +
1009 chan_idx)->chan_scan_mode_bitmap
1010 |= MWIFIEX_PASSIVE_SCAN;
1011 else
1012 (scan_chan_list +
1013 chan_idx)->chan_scan_mode_bitmap
1014 &= ~MWIFIEX_PASSIVE_SCAN;
1015
1016 if (*filtered_scan)
1017 (scan_chan_list +
1018 chan_idx)->chan_scan_mode_bitmap
1019 |= MWIFIEX_DISABLE_CHAN_FILT;
1020
1021 if (user_scan_in->chan_list[chan_idx].scan_time) {
1022 scan_dur = (u16) user_scan_in->
1023 chan_list[chan_idx].scan_time;
1024 } else {
1025 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1026 scan_dur = adapter->passive_scan_time;
1027 else if (*filtered_scan)
1028 scan_dur = adapter->specific_scan_time;
1029 else
1030 scan_dur = adapter->active_scan_time;
1031 }
1032
1033 (scan_chan_list + chan_idx)->min_scan_time =
1034 cpu_to_le16(scan_dur);
1035 (scan_chan_list + chan_idx)->max_scan_time =
1036 cpu_to_le16(scan_dur);
1037 }
1038
1039
1040 if ((chan_idx == 1) &&
1041 (user_scan_in->chan_list[0].chan_number ==
1042 priv->curr_bss_params.bss_descriptor.channel)) {
1043 *scan_current_only = true;
1044 dev_dbg(adapter->dev,
1045 "info: Scan: Scanning current channel only\n");
1046 }
1047 chan_num = chan_idx;
1048 } else {
1049 dev_dbg(adapter->dev,
1050 "info: Scan: Creating full region channel list\n");
1051 chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in,
1052 scan_chan_list,
1053 *filtered_scan);
1054 }
1055
1056
1057
1058
1059
1060
1061
1062 if (priv->media_connected) {
1063 if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD)
1064 *max_chan_per_scan = 1;
1065 else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD)
1066 *max_chan_per_scan = 2;
1067 else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD)
1068 *max_chan_per_scan = 3;
1069 else
1070 *max_chan_per_scan = 4;
1071 }
1072}
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083static void
1084mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1085 struct mwifiex_ie_types_data *tlv,
1086 u32 tlv_buf_size, u32 req_tlv_type,
1087 struct mwifiex_ie_types_data **tlv_data)
1088{
1089 struct mwifiex_ie_types_data *current_tlv;
1090 u32 tlv_buf_left;
1091 u32 tlv_type;
1092 u32 tlv_len;
1093
1094 current_tlv = tlv;
1095 tlv_buf_left = tlv_buf_size;
1096 *tlv_data = NULL;
1097
1098 dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
1099 tlv_buf_size);
1100
1101 while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
1102
1103 tlv_type = le16_to_cpu(current_tlv->header.type);
1104 tlv_len = le16_to_cpu(current_tlv->header.len);
1105
1106 if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
1107 dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
1108 break;
1109 }
1110
1111 if (req_tlv_type == tlv_type) {
1112 switch (tlv_type) {
1113 case TLV_TYPE_TSFTIMESTAMP:
1114 dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
1115 "timestamp TLV, len = %d\n", tlv_len);
1116 *tlv_data = current_tlv;
1117 break;
1118 case TLV_TYPE_CHANNELBANDLIST:
1119 dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
1120 " band list TLV, len = %d\n", tlv_len);
1121 *tlv_data = current_tlv;
1122 break;
1123 default:
1124 dev_err(adapter->dev,
1125 "SCAN_RESP: unhandled TLV = %d\n",
1126 tlv_type);
1127
1128 return;
1129 }
1130 }
1131
1132 if (*tlv_data)
1133 break;
1134
1135
1136 tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
1137 current_tlv =
1138 (struct mwifiex_ie_types_data *) (current_tlv->data +
1139 tlv_len);
1140
1141 }
1142}
1143
1144
1145
1146
1147
1148int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1149 struct mwifiex_bssdescriptor *bss_entry)
1150{
1151 int ret = 0;
1152 u8 element_id;
1153 struct ieee_types_fh_param_set *fh_param_set;
1154 struct ieee_types_ds_param_set *ds_param_set;
1155 struct ieee_types_cf_param_set *cf_param_set;
1156 struct ieee_types_ibss_param_set *ibss_param_set;
1157 u8 *current_ptr;
1158 u8 *rate;
1159 u8 element_len;
1160 u16 total_ie_len;
1161 u8 bytes_to_copy;
1162 u8 rate_size;
1163 u8 found_data_rate_ie;
1164 u32 bytes_left;
1165 struct ieee_types_vendor_specific *vendor_ie;
1166 const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1167 const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1168
1169 found_data_rate_ie = false;
1170 rate_size = 0;
1171 current_ptr = bss_entry->beacon_buf;
1172 bytes_left = bss_entry->beacon_buf_size;
1173
1174
1175 while (bytes_left >= 2) {
1176 element_id = *current_ptr;
1177 element_len = *(current_ptr + 1);
1178 total_ie_len = element_len + sizeof(struct ieee_types_header);
1179
1180 if (bytes_left < total_ie_len) {
1181 dev_err(adapter->dev, "err: InterpretIE: in processing"
1182 " IE, bytes left < IE length\n");
1183 return -1;
1184 }
1185 switch (element_id) {
1186 case WLAN_EID_SSID:
1187 bss_entry->ssid.ssid_len = element_len;
1188 memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1189 element_len);
1190 dev_dbg(adapter->dev,
1191 "info: InterpretIE: ssid: %-32s\n",
1192 bss_entry->ssid.ssid);
1193 break;
1194
1195 case WLAN_EID_SUPP_RATES:
1196 memcpy(bss_entry->data_rates, current_ptr + 2,
1197 element_len);
1198 memcpy(bss_entry->supported_rates, current_ptr + 2,
1199 element_len);
1200 rate_size = element_len;
1201 found_data_rate_ie = true;
1202 break;
1203
1204 case WLAN_EID_FH_PARAMS:
1205 fh_param_set =
1206 (struct ieee_types_fh_param_set *) current_ptr;
1207 memcpy(&bss_entry->phy_param_set.fh_param_set,
1208 fh_param_set,
1209 sizeof(struct ieee_types_fh_param_set));
1210 break;
1211
1212 case WLAN_EID_DS_PARAMS:
1213 ds_param_set =
1214 (struct ieee_types_ds_param_set *) current_ptr;
1215
1216 bss_entry->channel = ds_param_set->current_chan;
1217
1218 memcpy(&bss_entry->phy_param_set.ds_param_set,
1219 ds_param_set,
1220 sizeof(struct ieee_types_ds_param_set));
1221 break;
1222
1223 case WLAN_EID_CF_PARAMS:
1224 cf_param_set =
1225 (struct ieee_types_cf_param_set *) current_ptr;
1226 memcpy(&bss_entry->ss_param_set.cf_param_set,
1227 cf_param_set,
1228 sizeof(struct ieee_types_cf_param_set));
1229 break;
1230
1231 case WLAN_EID_IBSS_PARAMS:
1232 ibss_param_set =
1233 (struct ieee_types_ibss_param_set *)
1234 current_ptr;
1235 memcpy(&bss_entry->ss_param_set.ibss_param_set,
1236 ibss_param_set,
1237 sizeof(struct ieee_types_ibss_param_set));
1238 break;
1239
1240 case WLAN_EID_ERP_INFO:
1241 bss_entry->erp_flags = *(current_ptr + 2);
1242 break;
1243
1244 case WLAN_EID_PWR_CONSTRAINT:
1245 bss_entry->local_constraint = *(current_ptr + 2);
1246 bss_entry->sensed_11h = true;
1247 break;
1248
1249 case WLAN_EID_CHANNEL_SWITCH:
1250 bss_entry->chan_sw_ie_present = true;
1251 case WLAN_EID_PWR_CAPABILITY:
1252 case WLAN_EID_TPC_REPORT:
1253 case WLAN_EID_QUIET:
1254 bss_entry->sensed_11h = true;
1255 break;
1256
1257 case WLAN_EID_EXT_SUPP_RATES:
1258
1259
1260
1261
1262
1263
1264 if (found_data_rate_ie) {
1265 if ((element_len + rate_size) >
1266 MWIFIEX_SUPPORTED_RATES)
1267 bytes_to_copy =
1268 (MWIFIEX_SUPPORTED_RATES -
1269 rate_size);
1270 else
1271 bytes_to_copy = element_len;
1272
1273 rate = (u8 *) bss_entry->data_rates;
1274 rate += rate_size;
1275 memcpy(rate, current_ptr + 2, bytes_to_copy);
1276
1277 rate = (u8 *) bss_entry->supported_rates;
1278 rate += rate_size;
1279 memcpy(rate, current_ptr + 2, bytes_to_copy);
1280 }
1281 break;
1282
1283 case WLAN_EID_VENDOR_SPECIFIC:
1284 vendor_ie = (struct ieee_types_vendor_specific *)
1285 current_ptr;
1286
1287 if (!memcmp
1288 (vendor_ie->vend_hdr.oui, wpa_oui,
1289 sizeof(wpa_oui))) {
1290 bss_entry->bcn_wpa_ie =
1291 (struct ieee_types_vendor_specific *)
1292 current_ptr;
1293 bss_entry->wpa_offset = (u16)
1294 (current_ptr - bss_entry->beacon_buf);
1295 } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
1296 sizeof(wmm_oui))) {
1297 if (total_ie_len ==
1298 sizeof(struct ieee_types_wmm_parameter) ||
1299 total_ie_len ==
1300 sizeof(struct ieee_types_wmm_info))
1301
1302
1303
1304
1305
1306 memcpy((u8 *) &bss_entry->wmm_ie,
1307 current_ptr, total_ie_len);
1308 }
1309 break;
1310 case WLAN_EID_RSN:
1311 bss_entry->bcn_rsn_ie =
1312 (struct ieee_types_generic *) current_ptr;
1313 bss_entry->rsn_offset = (u16) (current_ptr -
1314 bss_entry->beacon_buf);
1315 break;
1316 case WLAN_EID_BSS_AC_ACCESS_DELAY:
1317 bss_entry->bcn_wapi_ie =
1318 (struct ieee_types_generic *) current_ptr;
1319 bss_entry->wapi_offset = (u16) (current_ptr -
1320 bss_entry->beacon_buf);
1321 break;
1322 case WLAN_EID_HT_CAPABILITY:
1323 bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
1324 (current_ptr +
1325 sizeof(struct ieee_types_header));
1326 bss_entry->ht_cap_offset = (u16) (current_ptr +
1327 sizeof(struct ieee_types_header) -
1328 bss_entry->beacon_buf);
1329 break;
1330 case WLAN_EID_HT_OPERATION:
1331 bss_entry->bcn_ht_oper =
1332 (struct ieee80211_ht_operation *)(current_ptr +
1333 sizeof(struct ieee_types_header));
1334 bss_entry->ht_info_offset = (u16) (current_ptr +
1335 sizeof(struct ieee_types_header) -
1336 bss_entry->beacon_buf);
1337 break;
1338 case WLAN_EID_VHT_CAPABILITY:
1339 bss_entry->disable_11ac = false;
1340 bss_entry->bcn_vht_cap =
1341 (void *)(current_ptr +
1342 sizeof(struct ieee_types_header));
1343 bss_entry->vht_cap_offset =
1344 (u16)((u8 *)bss_entry->bcn_vht_cap -
1345 bss_entry->beacon_buf);
1346 break;
1347 case WLAN_EID_VHT_OPERATION:
1348 bss_entry->bcn_vht_oper =
1349 (void *)(current_ptr +
1350 sizeof(struct ieee_types_header));
1351 bss_entry->vht_info_offset =
1352 (u16)((u8 *)bss_entry->bcn_vht_oper -
1353 bss_entry->beacon_buf);
1354 break;
1355 case WLAN_EID_BSS_COEX_2040:
1356 bss_entry->bcn_bss_co_2040 = current_ptr +
1357 sizeof(struct ieee_types_header);
1358 bss_entry->bss_co_2040_offset = (u16) (current_ptr +
1359 sizeof(struct ieee_types_header) -
1360 bss_entry->beacon_buf);
1361 break;
1362 case WLAN_EID_EXT_CAPABILITY:
1363 bss_entry->bcn_ext_cap = current_ptr +
1364 sizeof(struct ieee_types_header);
1365 bss_entry->ext_cap_offset = (u16) (current_ptr +
1366 sizeof(struct ieee_types_header) -
1367 bss_entry->beacon_buf);
1368 break;
1369 case WLAN_EID_OPMODE_NOTIF:
1370 bss_entry->oper_mode =
1371 (void *)(current_ptr +
1372 sizeof(struct ieee_types_header));
1373 bss_entry->oper_mode_offset =
1374 (u16)((u8 *)bss_entry->oper_mode -
1375 bss_entry->beacon_buf);
1376 break;
1377 default:
1378 break;
1379 }
1380
1381 current_ptr += element_len + 2;
1382
1383
1384 bytes_left -= (element_len + 2);
1385
1386 }
1387 return ret;
1388}
1389
1390
1391
1392
1393
1394static u8
1395mwifiex_radio_type_to_band(u8 radio_type)
1396{
1397 switch (radio_type) {
1398 case HostCmd_SCAN_RADIO_TYPE_A:
1399 return BAND_A;
1400 case HostCmd_SCAN_RADIO_TYPE_BG:
1401 default:
1402 return BAND_G;
1403 }
1404}
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414int mwifiex_scan_networks(struct mwifiex_private *priv,
1415 const struct mwifiex_user_scan_cfg *user_scan_in)
1416{
1417 int ret;
1418 struct mwifiex_adapter *adapter = priv->adapter;
1419 struct cmd_ctrl_node *cmd_node;
1420 union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
1421 struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
1422 struct mwifiex_chan_scan_param_set *scan_chan_list;
1423 u8 filtered_scan;
1424 u8 scan_current_chan_only;
1425 u8 max_chan_per_scan;
1426 unsigned long flags;
1427
1428 if (adapter->scan_processing) {
1429 dev_err(adapter->dev, "cmd: Scan already in process...\n");
1430 return -EBUSY;
1431 }
1432
1433 if (priv->scan_block) {
1434 dev_err(adapter->dev,
1435 "cmd: Scan is blocked during association...\n");
1436 return -EBUSY;
1437 }
1438
1439 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1440 adapter->scan_processing = true;
1441 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1442
1443 scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
1444 GFP_KERNEL);
1445 if (!scan_cfg_out) {
1446 ret = -ENOMEM;
1447 goto done;
1448 }
1449
1450 scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
1451 sizeof(struct mwifiex_chan_scan_param_set),
1452 GFP_KERNEL);
1453 if (!scan_chan_list) {
1454 kfree(scan_cfg_out);
1455 ret = -ENOMEM;
1456 goto done;
1457 }
1458
1459 mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
1460 &chan_list_out, scan_chan_list, &max_chan_per_scan,
1461 &filtered_scan, &scan_current_chan_only);
1462
1463 ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
1464 &scan_cfg_out->config, chan_list_out,
1465 scan_chan_list);
1466
1467
1468 if (!ret) {
1469 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1470 if (!list_empty(&adapter->scan_pending_q)) {
1471 cmd_node = list_first_entry(&adapter->scan_pending_q,
1472 struct cmd_ctrl_node, list);
1473 list_del(&cmd_node->list);
1474 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1475 flags);
1476 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1477 true);
1478 queue_work(adapter->workqueue, &adapter->main_work);
1479
1480
1481 if (!priv->scan_request) {
1482 dev_dbg(adapter->dev, "wait internal scan\n");
1483 mwifiex_wait_queue_complete(adapter, cmd_node);
1484 }
1485 } else {
1486 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1487 flags);
1488 }
1489 }
1490
1491 kfree(scan_cfg_out);
1492 kfree(scan_chan_list);
1493done:
1494 if (ret) {
1495 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1496 adapter->scan_processing = false;
1497 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1498 }
1499 return ret;
1500}
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
1517 struct mwifiex_scan_cmd_config *scan_cfg)
1518{
1519 struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
1520
1521
1522 scan_cmd->bss_mode = scan_cfg->bss_mode;
1523 memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
1524 sizeof(scan_cmd->bssid));
1525 memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1526
1527 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
1528
1529
1530 cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
1531 + sizeof(scan_cmd->bssid)
1532 + scan_cfg->tlv_buf_len + S_DS_GEN));
1533
1534 return 0;
1535}
1536
1537
1538
1539
1540
1541int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1542 struct mwifiex_bssdescriptor *bss_desc)
1543{
1544 int ret = -1;
1545
1546 if (!bss_desc)
1547 return -1;
1548
1549 if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
1550 (u16) bss_desc->channel, 0))) {
1551 switch (priv->bss_mode) {
1552 case NL80211_IFTYPE_STATION:
1553 case NL80211_IFTYPE_ADHOC:
1554 ret = mwifiex_is_network_compatible(priv, bss_desc,
1555 priv->bss_mode);
1556 if (ret)
1557 dev_err(priv->adapter->dev,
1558 "Incompatible network settings\n");
1559 break;
1560 default:
1561 ret = 0;
1562 }
1563 }
1564
1565 return ret;
1566}
1567
1568static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1569 struct cfg80211_bss *bss)
1570{
1571 struct mwifiex_bssdescriptor *bss_desc;
1572 int ret;
1573 unsigned long flags;
1574
1575
1576 bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
1577 if (!bss_desc)
1578 return -ENOMEM;
1579
1580 ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1581 if (ret)
1582 goto done;
1583
1584 ret = mwifiex_check_network_compatibility(priv, bss_desc);
1585 if (ret)
1586 goto done;
1587
1588 spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1589
1590 memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1591 sizeof(priv->curr_bss_params.bss_descriptor));
1592
1593
1594
1595
1596 mwifiex_save_curr_bcn(priv);
1597 spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1598
1599done:
1600
1601
1602
1603 kfree(bss_desc->beacon_buf);
1604 kfree(bss_desc);
1605 return 0;
1606}
1607
1608static int
1609mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1610 u32 *bytes_left, u64 fw_tsf, u8 *radio_type,
1611 bool ext_scan, s32 rssi_val)
1612{
1613 struct mwifiex_adapter *adapter = priv->adapter;
1614 struct mwifiex_chan_freq_power *cfp;
1615 struct cfg80211_bss *bss;
1616 u8 bssid[ETH_ALEN];
1617 s32 rssi;
1618 const u8 *ie_buf;
1619 size_t ie_len;
1620 u16 channel = 0;
1621 u16 beacon_size = 0;
1622 u32 curr_bcn_bytes;
1623 u32 freq;
1624 u16 beacon_period;
1625 u16 cap_info_bitmap;
1626 u8 *current_ptr;
1627 u64 timestamp;
1628 struct mwifiex_fixed_bcn_param *bcn_param;
1629 struct mwifiex_bss_priv *bss_priv;
1630
1631 if (*bytes_left >= sizeof(beacon_size)) {
1632
1633 memcpy(&beacon_size, *bss_info, sizeof(beacon_size));
1634 *bytes_left -= sizeof(beacon_size);
1635 *bss_info += sizeof(beacon_size);
1636 }
1637
1638 if (!beacon_size || beacon_size > *bytes_left) {
1639 *bss_info += *bytes_left;
1640 *bytes_left = 0;
1641 return -EFAULT;
1642 }
1643
1644
1645
1646
1647 current_ptr = *bss_info;
1648
1649
1650 *bss_info += beacon_size;
1651 *bytes_left -= beacon_size;
1652
1653 curr_bcn_bytes = beacon_size;
1654
1655
1656
1657
1658 if (curr_bcn_bytes < ETH_ALEN + sizeof(u8) +
1659 sizeof(struct mwifiex_fixed_bcn_param)) {
1660 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1661 return -EFAULT;
1662 }
1663
1664 memcpy(bssid, current_ptr, ETH_ALEN);
1665 current_ptr += ETH_ALEN;
1666 curr_bcn_bytes -= ETH_ALEN;
1667
1668 if (!ext_scan) {
1669 rssi = (s32) *current_ptr;
1670 rssi = (-rssi) * 100;
1671 current_ptr += sizeof(u8);
1672 curr_bcn_bytes -= sizeof(u8);
1673 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1674 } else {
1675 rssi = rssi_val;
1676 }
1677
1678 bcn_param = (struct mwifiex_fixed_bcn_param *)current_ptr;
1679 current_ptr += sizeof(*bcn_param);
1680 curr_bcn_bytes -= sizeof(*bcn_param);
1681
1682 timestamp = le64_to_cpu(bcn_param->timestamp);
1683 beacon_period = le16_to_cpu(bcn_param->beacon_period);
1684
1685 cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1686 dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1687 cap_info_bitmap);
1688
1689
1690 ie_buf = current_ptr;
1691 ie_len = curr_bcn_bytes;
1692 dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1693 curr_bcn_bytes);
1694
1695 while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1696 u8 element_id, element_len;
1697
1698 element_id = *current_ptr;
1699 element_len = *(current_ptr + 1);
1700 if (curr_bcn_bytes < element_len +
1701 sizeof(struct ieee_types_header)) {
1702 dev_err(adapter->dev,
1703 "%s: bytes left < IE length\n", __func__);
1704 return -EFAULT;
1705 }
1706 if (element_id == WLAN_EID_DS_PARAMS) {
1707 channel = *(current_ptr +
1708 sizeof(struct ieee_types_header));
1709 break;
1710 }
1711
1712 current_ptr += element_len + sizeof(struct ieee_types_header);
1713 curr_bcn_bytes -= element_len +
1714 sizeof(struct ieee_types_header);
1715 }
1716
1717 if (channel) {
1718 struct ieee80211_channel *chan;
1719 u8 band;
1720
1721
1722 if (channel == priv->csa_chan) {
1723 dev_dbg(adapter->dev,
1724 "Dropping entry on csa closed channel\n");
1725 return 0;
1726 }
1727
1728 band = BAND_G;
1729 if (radio_type)
1730 band = mwifiex_radio_type_to_band(*radio_type &
1731 (BIT(0) | BIT(1)));
1732
1733 cfp = mwifiex_get_cfp(priv, band, channel, 0);
1734
1735 freq = cfp ? cfp->freq : 0;
1736
1737 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1738
1739 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1740 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1741 chan, bssid, timestamp,
1742 cap_info_bitmap, beacon_period,
1743 ie_buf, ie_len, rssi, GFP_KERNEL);
1744 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1745 bss_priv->band = band;
1746 bss_priv->fw_tsf = fw_tsf;
1747 if (priv->media_connected &&
1748 !memcmp(bssid, priv->curr_bss_params.bss_descriptor
1749 .mac_address, ETH_ALEN))
1750 mwifiex_update_curr_bss_params(priv, bss);
1751 cfg80211_put_bss(priv->wdev->wiphy, bss);
1752 }
1753 } else {
1754 dev_dbg(adapter->dev, "missing BSS channel IE\n");
1755 }
1756
1757 return 0;
1758}
1759
1760static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1761{
1762 struct mwifiex_adapter *adapter = priv->adapter;
1763 struct cmd_ctrl_node *cmd_node;
1764 unsigned long flags;
1765
1766 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1767 if (list_empty(&adapter->scan_pending_q)) {
1768 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1769 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1770 adapter->scan_processing = false;
1771 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1772
1773
1774 if (adapter->curr_cmd->wait_q_enabled) {
1775 adapter->cmd_wait_q.status = 0;
1776 if (!priv->scan_request) {
1777 dev_dbg(adapter->dev,
1778 "complete internal scan\n");
1779 mwifiex_complete_cmd(adapter,
1780 adapter->curr_cmd);
1781 }
1782 }
1783 if (priv->report_scan_result)
1784 priv->report_scan_result = false;
1785
1786 if (priv->scan_request) {
1787 dev_dbg(adapter->dev, "info: notifying scan done\n");
1788 cfg80211_scan_done(priv->scan_request, 0);
1789 priv->scan_request = NULL;
1790 } else {
1791 priv->scan_aborting = false;
1792 dev_dbg(adapter->dev, "info: scan already aborted\n");
1793 }
1794 } else {
1795 if ((priv->scan_aborting && !priv->scan_request) ||
1796 priv->scan_block) {
1797 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1798 flags);
1799 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1800 mod_timer(&priv->scan_delay_timer, jiffies);
1801 dev_dbg(priv->adapter->dev,
1802 "info: %s: triggerring scan abort\n", __func__);
1803 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1804 (priv->scan_request && (priv->scan_request->flags &
1805 NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1806 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1807 flags);
1808 adapter->scan_delay_cnt = 1;
1809 mod_timer(&priv->scan_delay_timer, jiffies +
1810 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1811 dev_dbg(priv->adapter->dev,
1812 "info: %s: deferring scan\n", __func__);
1813 } else {
1814
1815
1816
1817 cmd_node = list_first_entry(&adapter->scan_pending_q,
1818 struct cmd_ctrl_node, list);
1819 list_del(&cmd_node->list);
1820 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1821 flags);
1822 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1823 true);
1824 }
1825 }
1826
1827 return;
1828}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1850 struct host_cmd_ds_command *resp)
1851{
1852 int ret = 0;
1853 struct mwifiex_adapter *adapter = priv->adapter;
1854 struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
1855 struct mwifiex_ie_types_data *tlv_data;
1856 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
1857 u8 *bss_info;
1858 u32 scan_resp_size;
1859 u32 bytes_left;
1860 u32 idx;
1861 u32 tlv_buf_size;
1862 struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
1863 struct chan_band_param_set *chan_band;
1864 u8 is_bgscan_resp;
1865 __le64 fw_tsf = 0;
1866 u8 *radio_type;
1867
1868 is_bgscan_resp = (le16_to_cpu(resp->command)
1869 == HostCmd_CMD_802_11_BG_SCAN_QUERY);
1870 if (is_bgscan_resp)
1871 scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
1872 else
1873 scan_rsp = &resp->params.scan_resp;
1874
1875
1876 if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
1877 dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
1878 scan_rsp->number_of_sets);
1879 ret = -1;
1880 goto check_next_scan;
1881 }
1882
1883
1884 mwifiex_11h_get_csa_closed_channel(priv);
1885
1886 bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
1887 dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
1888 bytes_left);
1889
1890 scan_resp_size = le16_to_cpu(resp->size);
1891
1892 dev_dbg(adapter->dev,
1893 "info: SCAN_RESP: returned %d APs before parsing\n",
1894 scan_rsp->number_of_sets);
1895
1896 bss_info = scan_rsp->bss_desc_and_tlv_buffer;
1897
1898
1899
1900
1901
1902
1903
1904 tlv_buf_size = scan_resp_size - (bytes_left
1905 + sizeof(scan_rsp->bss_descript_size)
1906 + sizeof(scan_rsp->number_of_sets)
1907 + S_DS_GEN);
1908
1909 tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
1910 bss_desc_and_tlv_buffer +
1911 bytes_left);
1912
1913
1914
1915 mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1916 TLV_TYPE_TSFTIMESTAMP,
1917 (struct mwifiex_ie_types_data **)
1918 &tsf_tlv);
1919
1920
1921
1922 mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1923 TLV_TYPE_CHANNELBANDLIST,
1924 (struct mwifiex_ie_types_data **)
1925 &chan_band_tlv);
1926
1927 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
1928
1929
1930
1931
1932
1933
1934 if (tsf_tlv)
1935 memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1936 sizeof(fw_tsf));
1937
1938 if (chan_band_tlv) {
1939 chan_band = &chan_band_tlv->chan_band_param[idx];
1940 radio_type = &chan_band->radio_type;
1941 } else {
1942 radio_type = NULL;
1943 }
1944
1945 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
1946 &bytes_left,
1947 le64_to_cpu(fw_tsf),
1948 radio_type, false, 0);
1949 if (ret)
1950 goto check_next_scan;
1951 }
1952
1953check_next_scan:
1954 mwifiex_check_next_scan_command(priv);
1955 return ret;
1956}
1957
1958
1959
1960
1961
1962
1963
1964
1965int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1966 struct host_cmd_ds_command *cmd,
1967 void *data_buf)
1968{
1969 struct host_cmd_ds_802_11_scan_ext *ext_scan = &cmd->params.ext_scan;
1970 struct mwifiex_scan_cmd_config *scan_cfg = data_buf;
1971
1972 memcpy(ext_scan->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1973
1974 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN_EXT);
1975
1976
1977 cmd->size = cpu_to_le16((u16)(sizeof(ext_scan->reserved)
1978 + scan_cfg->tlv_buf_len + S_DS_GEN));
1979
1980 return 0;
1981}
1982
1983
1984int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1985{
1986 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1987 return 0;
1988}
1989
1990
1991
1992
1993int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1994 void *buf)
1995{
1996 int ret = 0;
1997 struct mwifiex_adapter *adapter = priv->adapter;
1998 u8 *bss_info;
1999 u32 bytes_left, bytes_left_for_tlv, idx;
2000 u16 type, len;
2001 struct mwifiex_ie_types_data *tlv;
2002 struct mwifiex_ie_types_bss_scan_rsp *scan_rsp_tlv;
2003 struct mwifiex_ie_types_bss_scan_info *scan_info_tlv;
2004 u8 *radio_type;
2005 u64 fw_tsf = 0;
2006 s32 rssi = 0;
2007 struct mwifiex_event_scan_result *event_scan = buf;
2008 u8 num_of_set = event_scan->num_of_set;
2009 u8 *scan_resp = buf + sizeof(struct mwifiex_event_scan_result);
2010 u16 scan_resp_size = le16_to_cpu(event_scan->buf_size);
2011
2012 if (num_of_set > MWIFIEX_MAX_AP) {
2013 dev_err(adapter->dev,
2014 "EXT_SCAN: Invalid number of AP returned (%d)!!\n",
2015 num_of_set);
2016 ret = -1;
2017 goto check_next_scan;
2018 }
2019
2020 bytes_left = scan_resp_size;
2021 dev_dbg(adapter->dev,
2022 "EXT_SCAN: size %d, returned %d APs...",
2023 scan_resp_size, num_of_set);
2024
2025 tlv = (struct mwifiex_ie_types_data *)scan_resp;
2026
2027 for (idx = 0; idx < num_of_set && bytes_left; idx++) {
2028 type = le16_to_cpu(tlv->header.type);
2029 len = le16_to_cpu(tlv->header.len);
2030 if (bytes_left < sizeof(struct mwifiex_ie_types_header) + len) {
2031 dev_err(adapter->dev, "EXT_SCAN: Error bytes left < TLV length\n");
2032 break;
2033 }
2034 scan_rsp_tlv = NULL;
2035 scan_info_tlv = NULL;
2036 bytes_left_for_tlv = bytes_left;
2037
2038
2039
2040
2041 if (type != TLV_TYPE_BSS_SCAN_RSP)
2042 break;
2043
2044 bss_info = (u8 *)tlv;
2045 scan_rsp_tlv = (struct mwifiex_ie_types_bss_scan_rsp *)tlv;
2046 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2047 bytes_left_for_tlv -=
2048 (len + sizeof(struct mwifiex_ie_types_header));
2049
2050 while (bytes_left_for_tlv >=
2051 sizeof(struct mwifiex_ie_types_header) &&
2052 le16_to_cpu(tlv->header.type) != TLV_TYPE_BSS_SCAN_RSP) {
2053 type = le16_to_cpu(tlv->header.type);
2054 len = le16_to_cpu(tlv->header.len);
2055 if (bytes_left_for_tlv <
2056 sizeof(struct mwifiex_ie_types_header) + len) {
2057 dev_err(adapter->dev,
2058 "EXT_SCAN: Error in processing TLV, bytes left < TLV length\n");
2059 scan_rsp_tlv = NULL;
2060 bytes_left_for_tlv = 0;
2061 continue;
2062 }
2063 switch (type) {
2064 case TLV_TYPE_BSS_SCAN_INFO:
2065 scan_info_tlv =
2066 (struct mwifiex_ie_types_bss_scan_info *)tlv;
2067 if (len !=
2068 sizeof(struct mwifiex_ie_types_bss_scan_info) -
2069 sizeof(struct mwifiex_ie_types_header)) {
2070 bytes_left_for_tlv = 0;
2071 continue;
2072 }
2073 break;
2074 default:
2075 break;
2076 }
2077 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2078 bytes_left -=
2079 (len + sizeof(struct mwifiex_ie_types_header));
2080 bytes_left_for_tlv -=
2081 (len + sizeof(struct mwifiex_ie_types_header));
2082 }
2083
2084 if (!scan_rsp_tlv)
2085 break;
2086
2087
2088
2089
2090
2091
2092 bss_info += sizeof(u16);
2093 bytes_left -= sizeof(u16);
2094
2095 if (scan_info_tlv) {
2096 rssi = (s32)(s16)(le16_to_cpu(scan_info_tlv->rssi));
2097 rssi *= 100;
2098 dev_dbg(adapter->dev,
2099 "info: InterpretIE: RSSI=%d\n", rssi);
2100 fw_tsf = le64_to_cpu(scan_info_tlv->tsf);
2101 radio_type = &scan_info_tlv->radio_type;
2102 } else {
2103 radio_type = NULL;
2104 }
2105 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2106 &bytes_left, fw_tsf,
2107 radio_type, true, rssi);
2108 if (ret)
2109 goto check_next_scan;
2110 }
2111
2112check_next_scan:
2113 if (!event_scan->more_event)
2114 mwifiex_check_next_scan_command(priv);
2115
2116 return ret;
2117}
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
2128{
2129 struct host_cmd_ds_802_11_bg_scan_query *bg_query =
2130 &cmd->params.bg_scan_query;
2131
2132 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
2133 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
2134 + S_DS_GEN);
2135
2136 bg_query->flush = 1;
2137
2138 return 0;
2139}
2140
2141
2142
2143
2144void
2145mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2146 struct cmd_ctrl_node *cmd_node)
2147{
2148 struct mwifiex_adapter *adapter = priv->adapter;
2149 unsigned long flags;
2150
2151 cmd_node->wait_q_enabled = true;
2152 cmd_node->condition = &adapter->scan_wait_q_woken;
2153 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2154 list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
2155 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
2156}
2157
2158
2159
2160
2161
2162static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2163 struct cfg80211_ssid *req_ssid)
2164{
2165 struct mwifiex_adapter *adapter = priv->adapter;
2166 int ret;
2167 struct mwifiex_user_scan_cfg *scan_cfg;
2168
2169 if (adapter->scan_processing) {
2170 dev_err(adapter->dev, "cmd: Scan already in process...\n");
2171 return -EBUSY;
2172 }
2173
2174 if (priv->scan_block) {
2175 dev_err(adapter->dev,
2176 "cmd: Scan is blocked during association...\n");
2177 return -EBUSY;
2178 }
2179
2180 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2181 if (!scan_cfg)
2182 return -ENOMEM;
2183
2184 scan_cfg->ssid_list = req_ssid;
2185 scan_cfg->num_ssids = 1;
2186
2187 ret = mwifiex_scan_networks(priv, scan_cfg);
2188
2189 kfree(scan_cfg);
2190 return ret;
2191}
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202int mwifiex_request_scan(struct mwifiex_private *priv,
2203 struct cfg80211_ssid *req_ssid)
2204{
2205 int ret;
2206
2207 if (down_interruptible(&priv->async_sem)) {
2208 dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
2209 __func__);
2210 return -1;
2211 }
2212
2213 priv->adapter->scan_wait_q_woken = false;
2214
2215 if (req_ssid && req_ssid->ssid_len != 0)
2216
2217 ret = mwifiex_scan_specific_ssid(priv, req_ssid);
2218 else
2219
2220 ret = mwifiex_scan_networks(priv, NULL);
2221
2222 up(&priv->async_sem);
2223
2224 return ret;
2225}
2226
2227
2228
2229
2230int
2231mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
2232 u16 vsie_mask, u8 **buffer)
2233{
2234 int id, ret_len = 0;
2235 struct mwifiex_ie_types_vendor_param_set *vs_param_set;
2236
2237 if (!buffer)
2238 return 0;
2239 if (!(*buffer))
2240 return 0;
2241
2242
2243
2244
2245
2246 for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
2247 if (priv->vs_ie[id].mask & vsie_mask) {
2248 vs_param_set =
2249 (struct mwifiex_ie_types_vendor_param_set *)
2250 *buffer;
2251 vs_param_set->header.type =
2252 cpu_to_le16(TLV_TYPE_PASSTHROUGH);
2253 vs_param_set->header.len =
2254 cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
2255 & 0x00FF) + 2);
2256 memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
2257 le16_to_cpu(vs_param_set->header.len));
2258 *buffer += le16_to_cpu(vs_param_set->header.len) +
2259 sizeof(struct mwifiex_ie_types_header);
2260 ret_len += le16_to_cpu(vs_param_set->header.len) +
2261 sizeof(struct mwifiex_ie_types_header);
2262 }
2263 }
2264 return ret_len;
2265}
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276void
2277mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2278{
2279 struct mwifiex_bssdescriptor *curr_bss =
2280 &priv->curr_bss_params.bss_descriptor;
2281
2282 if (!curr_bss->beacon_buf_size)
2283 return;
2284
2285
2286 if (!priv->curr_bcn_buf ||
2287 priv->curr_bcn_size != curr_bss->beacon_buf_size) {
2288 priv->curr_bcn_size = curr_bss->beacon_buf_size;
2289
2290 kfree(priv->curr_bcn_buf);
2291 priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
2292 GFP_ATOMIC);
2293 if (!priv->curr_bcn_buf)
2294 return;
2295 }
2296
2297 memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
2298 curr_bss->beacon_buf_size);
2299 dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
2300 priv->curr_bcn_size);
2301
2302 curr_bss->beacon_buf = priv->curr_bcn_buf;
2303
2304
2305 if (curr_bss->bcn_wpa_ie)
2306 curr_bss->bcn_wpa_ie =
2307 (struct ieee_types_vendor_specific *)
2308 (curr_bss->beacon_buf +
2309 curr_bss->wpa_offset);
2310
2311 if (curr_bss->bcn_rsn_ie)
2312 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
2313 (curr_bss->beacon_buf +
2314 curr_bss->rsn_offset);
2315
2316 if (curr_bss->bcn_ht_cap)
2317 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
2318 (curr_bss->beacon_buf +
2319 curr_bss->ht_cap_offset);
2320
2321 if (curr_bss->bcn_ht_oper)
2322 curr_bss->bcn_ht_oper = (struct ieee80211_ht_operation *)
2323 (curr_bss->beacon_buf +
2324 curr_bss->ht_info_offset);
2325
2326 if (curr_bss->bcn_vht_cap)
2327 curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf +
2328 curr_bss->vht_cap_offset);
2329
2330 if (curr_bss->bcn_vht_oper)
2331 curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf +
2332 curr_bss->vht_info_offset);
2333
2334 if (curr_bss->bcn_bss_co_2040)
2335 curr_bss->bcn_bss_co_2040 =
2336 (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
2337
2338 if (curr_bss->bcn_ext_cap)
2339 curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2340 curr_bss->ext_cap_offset;
2341
2342 if (curr_bss->oper_mode)
2343 curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2344 curr_bss->oper_mode_offset);
2345}
2346
2347
2348
2349
2350void
2351mwifiex_free_curr_bcn(struct mwifiex_private *priv)
2352{
2353 kfree(priv->curr_bcn_buf);
2354 priv->curr_bcn_buf = NULL;
2355}
2356