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