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