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