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