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 "wmm.h"
26#include "11n.h"
27#include "11ac.h"
28
29#define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
30
31
32
33
34
35
36
37
38
39static int
40mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
41{
42 int ret_len = 0;
43 struct mwifiex_ie_types_header ie_header;
44
45
46 if (!buffer)
47 return 0;
48 if (!(*buffer))
49 return 0;
50
51
52
53
54
55 if (priv->gen_ie_buf_len) {
56 dev_dbg(priv->adapter->dev,
57 "info: %s: append generic ie len %d to %p\n",
58 __func__, priv->gen_ie_buf_len, *buffer);
59
60
61 ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
62 ie_header.len = cpu_to_le16(priv->gen_ie_buf_len);
63 memcpy(*buffer, &ie_header, sizeof(ie_header));
64
65
66
67 *buffer += sizeof(ie_header);
68 ret_len += sizeof(ie_header);
69
70
71
72 memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
73
74
75
76 *buffer += priv->gen_ie_buf_len;
77 ret_len += priv->gen_ie_buf_len;
78
79
80 priv->gen_ie_buf_len = 0;
81 }
82
83
84 return ret_len;
85}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100static int
101mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
102 struct mwifiex_bssdescriptor *bss_desc)
103{
104 struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
105 __le64 tsf_val;
106
107
108 if (buffer == NULL)
109 return 0;
110 if (*buffer == NULL)
111 return 0;
112
113 memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp));
114
115 tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
116 tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val));
117
118 memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
119 *buffer += sizeof(tsf_tlv.header);
120
121
122 tsf_val = cpu_to_le64(bss_desc->fw_tsf);
123 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
124 *buffer += sizeof(tsf_val);
125
126 tsf_val = cpu_to_le64(bss_desc->timestamp);
127
128 dev_dbg(priv->adapter->dev,
129 "info: %s: TSF offset calc: %016llx - %016llx\n",
130 __func__, bss_desc->timestamp, bss_desc->fw_tsf);
131
132 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
133 *buffer += sizeof(tsf_val);
134
135 return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val));
136}
137
138
139
140
141
142
143
144
145
146static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
147 u32 rate1_size, u8 *rate2, u32 rate2_size)
148{
149 int ret;
150 u8 *ptr = rate1, *tmp;
151 u32 i, j;
152
153 tmp = kmemdup(rate1, rate1_size, GFP_KERNEL);
154 if (!tmp) {
155 dev_err(priv->adapter->dev, "failed to alloc tmp buf\n");
156 return -ENOMEM;
157 }
158
159 memset(rate1, 0, rate1_size);
160
161 for (i = 0; i < rate2_size && rate2[i]; i++) {
162 for (j = 0; j < rate1_size && tmp[j]; j++) {
163
164
165 if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
166 *rate1++ = tmp[j];
167 break;
168 }
169 }
170 }
171
172 dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
173 priv->data_rate);
174
175 if (!priv->is_data_rate_auto) {
176 while (*ptr) {
177 if ((*ptr & 0x7f) == priv->data_rate) {
178 ret = 0;
179 goto done;
180 }
181 ptr++;
182 }
183 dev_err(priv->adapter->dev, "previously set fixed data rate %#x"
184 " is not compatible with the network\n",
185 priv->data_rate);
186
187 ret = -1;
188 goto done;
189 }
190
191 ret = 0;
192done:
193 kfree(tmp);
194 return ret;
195}
196
197
198
199
200
201static int
202mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
203 struct mwifiex_bssdescriptor *bss_desc,
204 u8 *out_rates, u32 *out_rates_size)
205{
206 u8 card_rates[MWIFIEX_SUPPORTED_RATES];
207 u32 card_rates_size;
208
209
210 memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
211
212 card_rates_size = mwifiex_get_active_data_rates(priv, card_rates);
213
214 if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES,
215 card_rates, card_rates_size)) {
216 *out_rates_size = 0;
217 dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
218 __func__);
219 return -1;
220 }
221
222 *out_rates_size =
223 min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES);
224
225 return 0;
226}
227
228
229
230
231
232
233
234
235static int
236mwifiex_cmd_append_wps_ie(struct mwifiex_private *priv, u8 **buffer)
237{
238 int retLen = 0;
239 struct mwifiex_ie_types_header ie_header;
240
241 if (!buffer || !*buffer)
242 return 0;
243
244
245
246
247
248 if (priv->wps_ie_len) {
249 dev_dbg(priv->adapter->dev, "cmd: append wps ie %d to %p\n",
250 priv->wps_ie_len, *buffer);
251
252
253 ie_header.type = cpu_to_le16(TLV_TYPE_MGMT_IE);
254 ie_header.len = cpu_to_le16(priv->wps_ie_len);
255 memcpy(*buffer, &ie_header, sizeof(ie_header));
256 *buffer += sizeof(ie_header);
257 retLen += sizeof(ie_header);
258
259 memcpy(*buffer, priv->wps_ie, priv->wps_ie_len);
260 *buffer += priv->wps_ie_len;
261 retLen += priv->wps_ie_len;
262
263 }
264
265 kfree(priv->wps_ie);
266 priv->wps_ie_len = 0;
267 return retLen;
268}
269
270
271
272
273
274
275
276
277
278static int
279mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
280{
281 int retLen = 0;
282 struct mwifiex_ie_types_header ie_header;
283
284
285 if (buffer == NULL)
286 return 0;
287 if (*buffer == NULL)
288 return 0;
289
290
291
292
293
294 if (priv->wapi_ie_len) {
295 dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
296 priv->wapi_ie_len, *buffer);
297
298
299 ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
300 ie_header.len = cpu_to_le16(priv->wapi_ie_len);
301 memcpy(*buffer, &ie_header, sizeof(ie_header));
302
303
304
305 *buffer += sizeof(ie_header);
306 retLen += sizeof(ie_header);
307
308
309
310 memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len);
311
312
313
314 *buffer += priv->wapi_ie_len;
315 retLen += priv->wapi_ie_len;
316
317 }
318
319 return retLen;
320}
321
322
323
324
325
326static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
327 u8 **buffer)
328{
329 struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv;
330 int rsn_ie_len;
331
332 if (!buffer || !(*buffer))
333 return 0;
334
335 rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer);
336 rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]);
337 rsn_ie_tlv->header.type = cpu_to_le16(
338 le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
339 rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
340 rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
341 & 0x00FF);
342 if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
343 memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
344 le16_to_cpu(rsn_ie_tlv->header.len));
345 else
346 return -1;
347
348 rsn_ie_len = sizeof(rsn_ie_tlv->header) +
349 le16_to_cpu(rsn_ie_tlv->header.len);
350 *buffer += rsn_ie_len;
351
352 return rsn_ie_len;
353}
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
384 struct host_cmd_ds_command *cmd,
385 struct mwifiex_bssdescriptor *bss_desc)
386{
387 struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate;
388 struct mwifiex_ie_types_ssid_param_set *ssid_tlv;
389 struct mwifiex_ie_types_phy_param_set *phy_tlv;
390 struct mwifiex_ie_types_ss_param_set *ss_tlv;
391 struct mwifiex_ie_types_rates_param_set *rates_tlv;
392 struct mwifiex_ie_types_auth_type *auth_tlv;
393 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
394 u8 rates[MWIFIEX_SUPPORTED_RATES];
395 u32 rates_size;
396 u16 tmp_cap;
397 u8 *pos;
398 int rsn_ie_len = 0;
399
400 pos = (u8 *) assoc;
401
402 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
403
404
405 priv->attempted_bss_desc = bss_desc;
406
407 memcpy(assoc->peer_sta_addr,
408 bss_desc->mac_address, sizeof(assoc->peer_sta_addr));
409 pos += sizeof(assoc->peer_sta_addr);
410
411
412 assoc->listen_interval = cpu_to_le16(priv->listen_interval);
413
414 assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period);
415
416 pos += sizeof(assoc->cap_info_bitmap);
417 pos += sizeof(assoc->listen_interval);
418 pos += sizeof(assoc->beacon_period);
419 pos += sizeof(assoc->dtim_period);
420
421 ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos;
422 ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
423 ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
424 memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
425 le16_to_cpu(ssid_tlv->header.len));
426 pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
427
428 phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
429 phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
430 phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
431 memcpy(&phy_tlv->fh_ds.ds_param_set,
432 &bss_desc->phy_param_set.ds_param_set.current_chan,
433 sizeof(phy_tlv->fh_ds.ds_param_set));
434 pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
435
436 ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
437 ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
438 ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
439 pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
440
441
442 if (mwifiex_setup_rates_from_bssdesc
443 (priv, bss_desc, rates, &rates_size))
444 return -1;
445
446
447 priv->curr_bss_params.num_of_rates = rates_size;
448 memcpy(&priv->curr_bss_params.data_rates, rates, rates_size);
449
450
451 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos;
452 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
453 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
454 memcpy(rates_tlv->rates, rates, rates_size);
455 pos += sizeof(rates_tlv->header) + rates_size;
456 dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
457 rates_size);
458
459
460 auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
461 auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
462 auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
463 if (priv->sec_info.wep_enabled)
464 auth_tlv->auth_type = cpu_to_le16(
465 (u16) priv->sec_info.authentication_mode);
466 else
467 auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM);
468
469 pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
470
471 if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
472 !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
473 (!bss_desc->disable_11n) &&
474 (priv->adapter->config_bands & BAND_GN ||
475 priv->adapter->config_bands & BAND_AN) &&
476 (bss_desc->bcn_ht_cap)
477 )
478 ) {
479
480
481 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
482 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
483 chan_tlv->header.len =
484 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
485
486 memset(chan_tlv->chan_scan_param, 0x00,
487 sizeof(struct mwifiex_chan_scan_param_set));
488 chan_tlv->chan_scan_param[0].chan_number =
489 (bss_desc->phy_param_set.ds_param_set.current_chan);
490 dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
491 chan_tlv->chan_scan_param[0].chan_number);
492
493 chan_tlv->chan_scan_param[0].radio_type =
494 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
495
496 dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
497 chan_tlv->chan_scan_param[0].radio_type);
498 pos += sizeof(chan_tlv->header) +
499 sizeof(struct mwifiex_chan_scan_param_set);
500 }
501
502 if (!priv->wps.session_enable) {
503 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
504 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
505
506 if (rsn_ie_len == -1)
507 return -1;
508 }
509
510 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
511 (!bss_desc->disable_11n) &&
512 (priv->adapter->config_bands & BAND_GN ||
513 priv->adapter->config_bands & BAND_AN))
514 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
515
516 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
517 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
518 (priv->adapter->config_bands & BAND_GAC ||
519 priv->adapter->config_bands & BAND_AAC))
520 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
521
522
523 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
524
525 mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
526 bss_desc->bcn_ht_cap);
527 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
528 mwifiex_cmd_append_wapi_ie(priv, &pos);
529
530 if (priv->wps.session_enable && priv->wps_ie_len)
531 mwifiex_cmd_append_wps_ie(priv, &pos);
532
533 mwifiex_cmd_append_generic_ie(priv, &pos);
534
535 mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
536
537 mwifiex_11h_process_join(priv, &pos, bss_desc);
538
539 cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
540
541
542 tmp_cap = bss_desc->cap_info_bitmap;
543
544 if (priv->adapter->config_bands == BAND_B)
545 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
546
547 tmp_cap &= CAPINFO_MASK;
548 dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
549 tmp_cap, CAPINFO_MASK);
550 assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
551
552 return 0;
553}
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
618 struct host_cmd_ds_command *resp)
619{
620 struct mwifiex_adapter *adapter = priv->adapter;
621 int ret = 0;
622 struct ieee_types_assoc_rsp *assoc_rsp;
623 struct mwifiex_bssdescriptor *bss_desc;
624 u8 enable_data = true;
625 u16 cap_info, status_code;
626
627 assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
628
629 cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
630 status_code = le16_to_cpu(assoc_rsp->status_code);
631
632 priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
633 sizeof(priv->assoc_rsp_buf));
634
635 memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
636
637 if (status_code) {
638 priv->adapter->dbg.num_cmd_assoc_failure++;
639 dev_err(priv->adapter->dev,
640 "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n",
641 status_code, cap_info, le16_to_cpu(assoc_rsp->a_id));
642
643 if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) {
644 if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT)
645 ret = WLAN_STATUS_AUTH_TIMEOUT;
646 else
647 ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
648 } else {
649 ret = status_code;
650 }
651
652 goto done;
653 }
654
655
656 priv->media_connected = true;
657
658 priv->adapter->ps_state = PS_STATE_AWAKE;
659 priv->adapter->pps_uapsd_mode = false;
660 priv->adapter->tx_lock_flag = false;
661
662
663 bss_desc = priv->attempted_bss_desc;
664
665 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
666 bss_desc->ssid.ssid);
667
668
669 memcpy(&priv->curr_bss_params.bss_descriptor,
670 bss_desc, sizeof(struct mwifiex_bssdescriptor));
671
672
673 priv->curr_bss_params.bss_descriptor.channel
674 = bss_desc->phy_param_set.ds_param_set.current_chan;
675
676 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
677
678 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
679 priv->curr_bss_params.wmm_enabled = true;
680 else
681 priv->curr_bss_params.wmm_enabled = false;
682
683 if ((priv->wmm_required || bss_desc->bcn_ht_cap) &&
684 priv->curr_bss_params.wmm_enabled)
685 priv->wmm_enabled = true;
686 else
687 priv->wmm_enabled = false;
688
689 priv->curr_bss_params.wmm_uapsd_enabled = false;
690
691 if (priv->wmm_enabled)
692 priv->curr_bss_params.wmm_uapsd_enabled
693 = ((bss_desc->wmm_ie.qos_info_bitmap &
694 IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
695
696 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
697 priv->curr_pkt_filter);
698 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
699 priv->wpa_is_gtk_set = false;
700
701 if (priv->wmm_enabled) {
702
703
704 enable_data = false;
705 } else {
706
707
708 mwifiex_wmm_setup_queue_priorities(priv, NULL);
709 mwifiex_wmm_setup_ac_downgrade(priv);
710 }
711
712 if (enable_data)
713 dev_dbg(priv->adapter->dev,
714 "info: post association, re-enabling data flow\n");
715
716
717 priv->data_rssi_last = 0;
718 priv->data_nf_last = 0;
719 priv->data_rssi_avg = 0;
720 priv->data_nf_avg = 0;
721 priv->bcn_rssi_last = 0;
722 priv->bcn_nf_last = 0;
723 priv->bcn_rssi_avg = 0;
724 priv->bcn_nf_avg = 0;
725 priv->rxpd_rate = 0;
726 priv->rxpd_htinfo = 0;
727
728 mwifiex_save_curr_bcn(priv);
729
730 priv->adapter->dbg.num_cmd_assoc_success++;
731
732 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n");
733
734
735
736 mwifiex_ralist_add(priv,
737 priv->curr_bss_params.bss_descriptor.mac_address);
738
739 if (!netif_carrier_ok(priv->netdev))
740 netif_carrier_on(priv->netdev);
741 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
742
743 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
744 priv->scan_block = true;
745
746done:
747
748 if (adapter->curr_cmd->wait_q_enabled) {
749 if (ret)
750 adapter->cmd_wait_q.status = -1;
751 else
752 adapter->cmd_wait_q.status = 0;
753 }
754
755 return ret;
756}
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776int
777mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
778 struct host_cmd_ds_command *cmd,
779 struct cfg80211_ssid *req_ssid)
780{
781 int rsn_ie_len = 0;
782 struct mwifiex_adapter *adapter = priv->adapter;
783 struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
784 &cmd->params.adhoc_start;
785 struct mwifiex_bssdescriptor *bss_desc;
786 u32 cmd_append_size = 0;
787 u32 i;
788 u16 tmp_cap;
789 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
790 u8 radio_type;
791
792 struct mwifiex_ie_types_htcap *ht_cap;
793 struct mwifiex_ie_types_htinfo *ht_info;
794 u8 *pos = (u8 *) adhoc_start +
795 sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
796
797 if (!adapter)
798 return -1;
799
800 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
801
802 bss_desc = &priv->curr_bss_params.bss_descriptor;
803 priv->attempted_bss_desc = bss_desc;
804
805
806
807
808
809
810
811
812
813
814
815 memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
816
817 memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
818
819 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
820 adhoc_start->ssid);
821
822 memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
823 memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
824
825 bss_desc->ssid.ssid_len = req_ssid->ssid_len;
826
827
828 adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
829 bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
830 adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
831 bss_desc->beacon_period = priv->beacon_period;
832
833
834
835#define DS_PARA_IE_ID 3
836
837#define DS_PARA_IE_LEN 1
838
839 adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
840 adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
841
842 if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
843 (u16) priv->adhoc_channel, 0)) {
844 struct mwifiex_chan_freq_power *cfp;
845 cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
846 FIRST_VALID_CHANNEL, 0);
847 if (cfp)
848 priv->adhoc_channel = (u8) cfp->channel;
849 }
850
851 if (!priv->adhoc_channel) {
852 dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
853 return -1;
854 }
855
856 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
857 priv->adhoc_channel);
858
859 priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
860 priv->curr_bss_params.band = adapter->adhoc_start_band;
861
862 bss_desc->channel = priv->adhoc_channel;
863 adhoc_start->phy_param_set.ds_param_set.current_chan =
864 priv->adhoc_channel;
865
866 memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
867 sizeof(union ieee_types_phy_param_set));
868
869
870
871#define IBSS_PARA_IE_ID 6
872
873#define IBSS_PARA_IE_LEN 2
874
875 adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
876 adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
877 adhoc_start->ss_param_set.ibss_param_set.atim_window
878 = cpu_to_le16(priv->atim_window);
879 memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
880 sizeof(union ieee_types_ss_param_set));
881
882
883 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
884 tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap);
885 tmp_cap &= ~WLAN_CAPABILITY_ESS;
886 tmp_cap |= WLAN_CAPABILITY_IBSS;
887
888
889 if (priv->sec_info.encryption_mode) {
890
891 dev_dbg(adapter->dev,
892 "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
893 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
894 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
895 } else {
896 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set,"
897 " setting privacy to ACCEPT ALL\n");
898 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
899 }
900
901 memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate));
902 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
903 if ((adapter->adhoc_start_band & BAND_G) &&
904 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
905 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
906 HostCmd_ACT_GEN_SET, 0,
907 &priv->curr_pkt_filter)) {
908 dev_err(adapter->dev,
909 "ADHOC_S_CMD: G Protection config failed\n");
910 return -1;
911 }
912 }
913
914 for (i = 0; i < sizeof(adhoc_start->data_rate); i++)
915 if (!adhoc_start->data_rate[i])
916 break;
917
918 priv->curr_bss_params.num_of_rates = i;
919
920
921 memcpy(&priv->curr_bss_params.data_rates,
922 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
923
924 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%4ph\n",
925 adhoc_start->data_rate);
926
927 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
928
929 if (IS_SUPPORT_MULTI_BANDS(adapter)) {
930
931 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
932 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
933 chan_tlv->header.len =
934 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
935
936 memset(chan_tlv->chan_scan_param, 0x00,
937 sizeof(struct mwifiex_chan_scan_param_set));
938 chan_tlv->chan_scan_param[0].chan_number =
939 (u8) priv->curr_bss_params.bss_descriptor.channel;
940
941 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
942 chan_tlv->chan_scan_param[0].chan_number);
943
944 chan_tlv->chan_scan_param[0].radio_type
945 = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
946 if (adapter->adhoc_start_band & BAND_GN ||
947 adapter->adhoc_start_band & BAND_AN) {
948 if (adapter->sec_chan_offset ==
949 IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
950 chan_tlv->chan_scan_param[0].radio_type |=
951 (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
952 else if (adapter->sec_chan_offset ==
953 IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
954 chan_tlv->chan_scan_param[0].radio_type |=
955 (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
956 }
957 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
958 chan_tlv->chan_scan_param[0].radio_type);
959 pos += sizeof(chan_tlv->header) +
960 sizeof(struct mwifiex_chan_scan_param_set);
961 cmd_append_size +=
962 sizeof(chan_tlv->header) +
963 sizeof(struct mwifiex_chan_scan_param_set);
964 }
965
966
967 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
968 MWIFIEX_VSIE_MASK_ADHOC, &pos);
969
970 if (priv->sec_info.wpa_enabled) {
971 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
972 if (rsn_ie_len == -1)
973 return -1;
974 cmd_append_size += rsn_ie_len;
975 }
976
977 if (adapter->adhoc_11n_enabled) {
978
979 ht_cap = (struct mwifiex_ie_types_htcap *) pos;
980 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
981 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
982 ht_cap->header.len =
983 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
984 radio_type = mwifiex_band_to_radio_type(
985 priv->adapter->config_bands);
986 mwifiex_fill_cap_info(priv, radio_type, ht_cap);
987
988 if (adapter->sec_chan_offset ==
989 IEEE80211_HT_PARAM_CHA_SEC_NONE) {
990 u16 tmp_ht_cap;
991
992 tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
993 tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
994 tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
995 ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
996 }
997
998 pos += sizeof(struct mwifiex_ie_types_htcap);
999 cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
1000
1001
1002 ht_info = (struct mwifiex_ie_types_htinfo *) pos;
1003 memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
1004 ht_info->header.type = cpu_to_le16(WLAN_EID_HT_OPERATION);
1005 ht_info->header.len =
1006 cpu_to_le16(sizeof(struct ieee80211_ht_operation));
1007
1008 ht_info->ht_oper.primary_chan =
1009 (u8) priv->curr_bss_params.bss_descriptor.channel;
1010 if (adapter->sec_chan_offset) {
1011 ht_info->ht_oper.ht_param = adapter->sec_chan_offset;
1012 ht_info->ht_oper.ht_param |=
1013 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1014 }
1015 ht_info->ht_oper.operation_mode =
1016 cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1017 ht_info->ht_oper.basic_set[0] = 0xff;
1018 pos += sizeof(struct mwifiex_ie_types_htinfo);
1019 cmd_append_size +=
1020 sizeof(struct mwifiex_ie_types_htinfo);
1021 }
1022
1023 cmd->size =
1024 cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
1025 + S_DS_GEN + cmd_append_size));
1026
1027 if (adapter->adhoc_start_band == BAND_B)
1028 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
1029 else
1030 tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1031
1032 adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
1033
1034 return 0;
1035}
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053int
1054mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1055 struct host_cmd_ds_command *cmd,
1056 struct mwifiex_bssdescriptor *bss_desc)
1057{
1058 int rsn_ie_len = 0;
1059 struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
1060 &cmd->params.adhoc_join;
1061 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
1062 u32 cmd_append_size = 0;
1063 u16 tmp_cap;
1064 u32 i, rates_size = 0;
1065 u16 curr_pkt_filter;
1066 u8 *pos =
1067 (u8 *) adhoc_join +
1068 sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
1069
1070
1071#define USE_G_PROTECTION 0x02
1072 if (bss_desc->erp_flags & USE_G_PROTECTION) {
1073 curr_pkt_filter =
1074 priv->
1075 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1076
1077 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
1078 HostCmd_ACT_GEN_SET, 0,
1079 &curr_pkt_filter)) {
1080 dev_err(priv->adapter->dev,
1081 "ADHOC_J_CMD: G Protection config failed\n");
1082 return -1;
1083 }
1084 }
1085
1086 priv->attempted_bss_desc = bss_desc;
1087
1088 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
1089
1090 adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
1091
1092 adhoc_join->bss_descriptor.beacon_period
1093 = cpu_to_le16(bss_desc->beacon_period);
1094
1095 memcpy(&adhoc_join->bss_descriptor.bssid,
1096 &bss_desc->mac_address, ETH_ALEN);
1097
1098 memcpy(&adhoc_join->bss_descriptor.ssid,
1099 &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
1100
1101 memcpy(&adhoc_join->bss_descriptor.phy_param_set,
1102 &bss_desc->phy_param_set,
1103 sizeof(union ieee_types_phy_param_set));
1104
1105 memcpy(&adhoc_join->bss_descriptor.ss_param_set,
1106 &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
1107
1108 tmp_cap = bss_desc->cap_info_bitmap;
1109
1110 tmp_cap &= CAPINFO_MASK;
1111
1112 dev_dbg(priv->adapter->dev,
1113 "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
1114 tmp_cap, CAPINFO_MASK);
1115
1116
1117 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
1118 adhoc_join->bss_descriptor.bssid,
1119 adhoc_join->bss_descriptor.ssid);
1120
1121 for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
1122 bss_desc->supported_rates[i]; i++)
1123 ;
1124 rates_size = i;
1125
1126
1127 memset(adhoc_join->bss_descriptor.data_rates, 0,
1128 sizeof(adhoc_join->bss_descriptor.data_rates));
1129 memcpy(adhoc_join->bss_descriptor.data_rates,
1130 bss_desc->supported_rates, rates_size);
1131
1132
1133 priv->curr_bss_params.num_of_rates = rates_size;
1134 memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
1135 rates_size);
1136
1137
1138 priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
1139 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
1140
1141 if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled)
1142 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
1143
1144 if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
1145
1146 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
1147 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
1148 chan_tlv->header.len =
1149 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
1150
1151 memset(chan_tlv->chan_scan_param, 0x00,
1152 sizeof(struct mwifiex_chan_scan_param_set));
1153 chan_tlv->chan_scan_param[0].chan_number =
1154 (bss_desc->phy_param_set.ds_param_set.current_chan);
1155 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n",
1156 chan_tlv->chan_scan_param[0].chan_number);
1157
1158 chan_tlv->chan_scan_param[0].radio_type =
1159 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
1160
1161 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n",
1162 chan_tlv->chan_scan_param[0].radio_type);
1163 pos += sizeof(chan_tlv->header) +
1164 sizeof(struct mwifiex_chan_scan_param_set);
1165 cmd_append_size += sizeof(chan_tlv->header) +
1166 sizeof(struct mwifiex_chan_scan_param_set);
1167 }
1168
1169 if (priv->sec_info.wpa_enabled)
1170 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1171 if (rsn_ie_len == -1)
1172 return -1;
1173 cmd_append_size += rsn_ie_len;
1174
1175 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
1176 cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
1177 bss_desc, &pos);
1178
1179
1180 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1181 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1182
1183 cmd->size = cpu_to_le16
1184 ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
1185 + S_DS_GEN + cmd_append_size));
1186
1187 adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
1188
1189 return 0;
1190}
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1201 struct host_cmd_ds_command *resp)
1202{
1203 int ret = 0;
1204 struct mwifiex_adapter *adapter = priv->adapter;
1205 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
1206 struct mwifiex_bssdescriptor *bss_desc;
1207 u16 reason_code;
1208
1209 adhoc_result = &resp->params.adhoc_result;
1210
1211 bss_desc = priv->attempted_bss_desc;
1212
1213
1214 reason_code = le16_to_cpu(resp->result);
1215 if (reason_code) {
1216 dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
1217 if (priv->media_connected)
1218 mwifiex_reset_connect_state(priv, reason_code);
1219
1220 memset(&priv->curr_bss_params.bss_descriptor,
1221 0x00, sizeof(struct mwifiex_bssdescriptor));
1222
1223 ret = -1;
1224 goto done;
1225 }
1226
1227
1228 priv->media_connected = true;
1229
1230 if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
1231 dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
1232 bss_desc->ssid.ssid);
1233
1234
1235 memcpy(bss_desc->mac_address,
1236 adhoc_result->bssid, ETH_ALEN);
1237
1238 priv->adhoc_state = ADHOC_STARTED;
1239 } else {
1240
1241
1242
1243
1244 dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
1245 bss_desc->ssid.ssid);
1246
1247
1248
1249
1250
1251
1252 memcpy(&priv->curr_bss_params.bss_descriptor,
1253 bss_desc, sizeof(struct mwifiex_bssdescriptor));
1254
1255 priv->adhoc_state = ADHOC_JOINED;
1256 }
1257
1258 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
1259 priv->adhoc_channel);
1260 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
1261 priv->curr_bss_params.bss_descriptor.mac_address);
1262
1263 if (!netif_carrier_ok(priv->netdev))
1264 netif_carrier_on(priv->netdev);
1265 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
1266
1267 mwifiex_save_curr_bcn(priv);
1268
1269done:
1270
1271 if (adapter->curr_cmd->wait_q_enabled) {
1272 if (ret)
1273 adapter->cmd_wait_q.status = -1;
1274 else
1275 adapter->cmd_wait_q.status = 0;
1276
1277 }
1278
1279 return ret;
1280}
1281
1282
1283
1284
1285
1286
1287
1288
1289int mwifiex_associate(struct mwifiex_private *priv,
1290 struct mwifiex_bssdescriptor *bss_desc)
1291{
1292 u8 current_bssid[ETH_ALEN];
1293
1294
1295
1296
1297 if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
1298 (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1299 return -1;
1300
1301 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1302 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1303 (priv->adapter->config_bands & BAND_GAC ||
1304 priv->adapter->config_bands & BAND_AAC))
1305 mwifiex_set_11ac_ba_params(priv);
1306 else
1307 mwifiex_set_ba_params(priv);
1308
1309 memcpy(¤t_bssid,
1310 &priv->curr_bss_params.bss_descriptor.mac_address,
1311 sizeof(current_bssid));
1312
1313
1314
1315 priv->assoc_rsp_size = 0;
1316
1317 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE,
1318 HostCmd_ACT_GEN_SET, 0, bss_desc);
1319}
1320
1321
1322
1323
1324
1325
1326int
1327mwifiex_adhoc_start(struct mwifiex_private *priv,
1328 struct cfg80211_ssid *adhoc_ssid)
1329{
1330 dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
1331 priv->adhoc_channel);
1332 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1333 priv->curr_bss_params.bss_descriptor.channel);
1334 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
1335 priv->curr_bss_params.band);
1336
1337 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1338 (priv->adapter->config_bands & BAND_GAC ||
1339 priv->adapter->config_bands & BAND_AAC))
1340 mwifiex_set_11ac_ba_params(priv);
1341 else
1342 mwifiex_set_ba_params(priv);
1343
1344 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
1345 HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
1346}
1347
1348
1349
1350
1351
1352
1353
1354int mwifiex_adhoc_join(struct mwifiex_private *priv,
1355 struct mwifiex_bssdescriptor *bss_desc)
1356{
1357 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
1358 priv->curr_bss_params.bss_descriptor.ssid.ssid);
1359 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
1360 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
1361 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
1362 bss_desc->ssid.ssid);
1363 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
1364 bss_desc->ssid.ssid_len);
1365
1366
1367 if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
1368 !mwifiex_ssid_cmp(&bss_desc->ssid,
1369 &priv->curr_bss_params.bss_descriptor.ssid) &&
1370 (priv->curr_bss_params.bss_descriptor.bss_mode ==
1371 NL80211_IFTYPE_ADHOC)) {
1372 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID"
1373 " is the same as current; not attempting to re-join\n");
1374 return -1;
1375 }
1376
1377 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1378 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1379 (priv->adapter->config_bands & BAND_GAC ||
1380 priv->adapter->config_bands & BAND_AAC))
1381 mwifiex_set_11ac_ba_params(priv);
1382 else
1383 mwifiex_set_ba_params(priv);
1384
1385 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1386 priv->curr_bss_params.bss_descriptor.channel);
1387 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1388 priv->curr_bss_params.band);
1389
1390 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1391 HostCmd_ACT_GEN_SET, 0, bss_desc);
1392}
1393
1394
1395
1396
1397
1398static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1399{
1400 u8 mac_address[ETH_ALEN];
1401 int ret;
1402
1403 if (!mac || is_zero_ether_addr(mac))
1404 memcpy(mac_address,
1405 priv->curr_bss_params.bss_descriptor.mac_address,
1406 ETH_ALEN);
1407 else
1408 memcpy(mac_address, mac, ETH_ALEN);
1409
1410 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1411 HostCmd_ACT_GEN_SET, 0, mac_address);
1412
1413 return ret;
1414}
1415
1416
1417
1418
1419
1420
1421
1422
1423int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1424{
1425 int ret = 0;
1426
1427 if (!priv->media_connected)
1428 return 0;
1429
1430 switch (priv->bss_mode) {
1431 case NL80211_IFTYPE_STATION:
1432 case NL80211_IFTYPE_P2P_CLIENT:
1433 ret = mwifiex_deauthenticate_infra(priv, mac);
1434 if (ret)
1435 cfg80211_disconnected(priv->netdev, 0, NULL, 0,
1436 GFP_KERNEL);
1437 break;
1438 case NL80211_IFTYPE_ADHOC:
1439 return mwifiex_send_cmd_sync(priv,
1440 HostCmd_CMD_802_11_AD_HOC_STOP,
1441 HostCmd_ACT_GEN_SET, 0, NULL);
1442 case NL80211_IFTYPE_AP:
1443 return mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
1444 HostCmd_ACT_GEN_SET, 0, NULL);
1445 default:
1446 break;
1447 }
1448
1449 return ret;
1450}
1451EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
1452
1453
1454
1455
1456u8
1457mwifiex_band_to_radio_type(u8 band)
1458{
1459 switch (band) {
1460 case BAND_A:
1461 case BAND_AN:
1462 case BAND_A | BAND_AN:
1463 case BAND_A | BAND_AN | BAND_AAC:
1464 return HostCmd_SCAN_RADIO_TYPE_A;
1465 case BAND_B:
1466 case BAND_G:
1467 case BAND_B | BAND_G:
1468 default:
1469 return HostCmd_SCAN_RADIO_TYPE_BG;
1470 }
1471}
1472