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_AAC)
519 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
520
521
522 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
523
524 mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
525 bss_desc->bcn_ht_cap);
526 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
527 mwifiex_cmd_append_wapi_ie(priv, &pos);
528
529 if (priv->wps.session_enable && priv->wps_ie_len)
530 mwifiex_cmd_append_wps_ie(priv, &pos);
531
532 mwifiex_cmd_append_generic_ie(priv, &pos);
533
534 mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
535
536 mwifiex_11h_process_join(priv, &pos, bss_desc);
537
538 cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
539
540
541 tmp_cap = bss_desc->cap_info_bitmap;
542
543 if (priv->adapter->config_bands == BAND_B)
544 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
545
546 tmp_cap &= CAPINFO_MASK;
547 dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
548 tmp_cap, CAPINFO_MASK);
549 assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
550
551 return 0;
552}
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
616int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
617 struct host_cmd_ds_command *resp)
618{
619 struct mwifiex_adapter *adapter = priv->adapter;
620 int ret = 0;
621 struct ieee_types_assoc_rsp *assoc_rsp;
622 struct mwifiex_bssdescriptor *bss_desc;
623 bool enable_data = true;
624 u16 cap_info, status_code;
625
626 assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
627
628 cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
629 status_code = le16_to_cpu(assoc_rsp->status_code);
630
631 priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
632 sizeof(priv->assoc_rsp_buf));
633
634 memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
635
636 if (status_code) {
637 priv->adapter->dbg.num_cmd_assoc_failure++;
638 dev_err(priv->adapter->dev,
639 "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n",
640 status_code, cap_info, le16_to_cpu(assoc_rsp->a_id));
641
642 if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) {
643 if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT)
644 ret = WLAN_STATUS_AUTH_TIMEOUT;
645 else
646 ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
647 } else {
648 ret = status_code;
649 }
650
651 goto done;
652 }
653
654
655 priv->media_connected = true;
656
657 priv->adapter->ps_state = PS_STATE_AWAKE;
658 priv->adapter->pps_uapsd_mode = false;
659 priv->adapter->tx_lock_flag = false;
660
661
662 bss_desc = priv->attempted_bss_desc;
663
664 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
665 bss_desc->ssid.ssid);
666
667
668 memcpy(&priv->curr_bss_params.bss_descriptor,
669 bss_desc, sizeof(struct mwifiex_bssdescriptor));
670
671
672 priv->curr_bss_params.bss_descriptor.channel
673 = bss_desc->phy_param_set.ds_param_set.current_chan;
674
675 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
676
677 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
678 priv->curr_bss_params.wmm_enabled = true;
679 else
680 priv->curr_bss_params.wmm_enabled = false;
681
682 if ((priv->wmm_required || bss_desc->bcn_ht_cap) &&
683 priv->curr_bss_params.wmm_enabled)
684 priv->wmm_enabled = true;
685 else
686 priv->wmm_enabled = false;
687
688 priv->curr_bss_params.wmm_uapsd_enabled = false;
689
690 if (priv->wmm_enabled)
691 priv->curr_bss_params.wmm_uapsd_enabled
692 = ((bss_desc->wmm_ie.qos_info_bitmap &
693 IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
694
695 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
696 priv->curr_pkt_filter);
697 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
698 priv->wpa_is_gtk_set = false;
699
700 if (priv->wmm_enabled) {
701
702
703 enable_data = false;
704 } else {
705
706
707 mwifiex_wmm_setup_queue_priorities(priv, NULL);
708 mwifiex_wmm_setup_ac_downgrade(priv);
709 }
710
711 if (enable_data)
712 dev_dbg(priv->adapter->dev,
713 "info: post association, re-enabling data flow\n");
714
715
716 priv->data_rssi_last = 0;
717 priv->data_nf_last = 0;
718 priv->data_rssi_avg = 0;
719 priv->data_nf_avg = 0;
720 priv->bcn_rssi_last = 0;
721 priv->bcn_nf_last = 0;
722 priv->bcn_rssi_avg = 0;
723 priv->bcn_nf_avg = 0;
724 priv->rxpd_rate = 0;
725 priv->rxpd_htinfo = 0;
726
727 mwifiex_save_curr_bcn(priv);
728
729 priv->adapter->dbg.num_cmd_assoc_success++;
730
731 dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n");
732
733
734
735 mwifiex_ralist_add(priv,
736 priv->curr_bss_params.bss_descriptor.mac_address);
737
738 if (!netif_carrier_ok(priv->netdev))
739 netif_carrier_on(priv->netdev);
740 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
741
742 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
743 priv->scan_block = true;
744
745done:
746
747 if (adapter->curr_cmd->wait_q_enabled) {
748 if (ret)
749 adapter->cmd_wait_q.status = -1;
750 else
751 adapter->cmd_wait_q.status = 0;
752 }
753
754 return ret;
755}
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775int
776mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
777 struct host_cmd_ds_command *cmd,
778 struct cfg80211_ssid *req_ssid)
779{
780 int rsn_ie_len = 0;
781 struct mwifiex_adapter *adapter = priv->adapter;
782 struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
783 &cmd->params.adhoc_start;
784 struct mwifiex_bssdescriptor *bss_desc;
785 u32 cmd_append_size = 0;
786 u32 i;
787 u16 tmp_cap;
788 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
789 u8 radio_type;
790
791 struct mwifiex_ie_types_htcap *ht_cap;
792 struct mwifiex_ie_types_htinfo *ht_info;
793 u8 *pos = (u8 *) adhoc_start +
794 sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
795
796 if (!adapter)
797 return -1;
798
799 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
800
801 bss_desc = &priv->curr_bss_params.bss_descriptor;
802 priv->attempted_bss_desc = bss_desc;
803
804
805
806
807
808
809
810
811
812
813
814 memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
815
816 memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
817
818 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
819 adhoc_start->ssid);
820
821 memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
822 memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
823
824 bss_desc->ssid.ssid_len = req_ssid->ssid_len;
825
826
827 adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
828 bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
829 adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
830 bss_desc->beacon_period = priv->beacon_period;
831
832
833
834#define DS_PARA_IE_ID 3
835
836#define DS_PARA_IE_LEN 1
837
838 adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
839 adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
840
841 if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
842 (u16) priv->adhoc_channel, 0)) {
843 struct mwifiex_chan_freq_power *cfp;
844 cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
845 FIRST_VALID_CHANNEL, 0);
846 if (cfp)
847 priv->adhoc_channel = (u8) cfp->channel;
848 }
849
850 if (!priv->adhoc_channel) {
851 dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
852 return -1;
853 }
854
855 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
856 priv->adhoc_channel);
857
858 priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
859 priv->curr_bss_params.band = adapter->adhoc_start_band;
860
861 bss_desc->channel = priv->adhoc_channel;
862 adhoc_start->phy_param_set.ds_param_set.current_chan =
863 priv->adhoc_channel;
864
865 memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
866 sizeof(union ieee_types_phy_param_set));
867
868
869
870#define IBSS_PARA_IE_ID 6
871
872#define IBSS_PARA_IE_LEN 2
873
874 adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
875 adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
876 adhoc_start->ss_param_set.ibss_param_set.atim_window
877 = cpu_to_le16(priv->atim_window);
878 memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
879 sizeof(union ieee_types_ss_param_set));
880
881
882 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
883 tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap);
884 tmp_cap &= ~WLAN_CAPABILITY_ESS;
885 tmp_cap |= WLAN_CAPABILITY_IBSS;
886
887
888 if (priv->sec_info.encryption_mode) {
889
890 dev_dbg(adapter->dev,
891 "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
892 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
893 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
894 } else {
895 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set,"
896 " setting privacy to ACCEPT ALL\n");
897 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
898 }
899
900 memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate));
901 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
902 if ((adapter->adhoc_start_band & BAND_G) &&
903 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
904 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
905 HostCmd_ACT_GEN_SET, 0,
906 &priv->curr_pkt_filter, false)) {
907 dev_err(adapter->dev,
908 "ADHOC_S_CMD: G Protection config failed\n");
909 return -1;
910 }
911 }
912
913 for (i = 0; i < sizeof(adhoc_start->data_rate); i++)
914 if (!adhoc_start->data_rate[i])
915 break;
916
917 priv->curr_bss_params.num_of_rates = i;
918
919
920 memcpy(&priv->curr_bss_params.data_rates,
921 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
922
923 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%4ph\n",
924 adhoc_start->data_rate);
925
926 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
927
928 if (IS_SUPPORT_MULTI_BANDS(adapter)) {
929
930 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
931 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
932 chan_tlv->header.len =
933 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
934
935 memset(chan_tlv->chan_scan_param, 0x00,
936 sizeof(struct mwifiex_chan_scan_param_set));
937 chan_tlv->chan_scan_param[0].chan_number =
938 (u8) priv->curr_bss_params.bss_descriptor.channel;
939
940 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
941 chan_tlv->chan_scan_param[0].chan_number);
942
943 chan_tlv->chan_scan_param[0].radio_type
944 = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
945 if (adapter->adhoc_start_band & BAND_GN ||
946 adapter->adhoc_start_band & BAND_AN) {
947 if (adapter->sec_chan_offset ==
948 IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
949 chan_tlv->chan_scan_param[0].radio_type |=
950 (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
951 else if (adapter->sec_chan_offset ==
952 IEEE80211_HT_PARAM_CHA_SEC_BELOW)
953 chan_tlv->chan_scan_param[0].radio_type |=
954 (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
955 }
956 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
957 chan_tlv->chan_scan_param[0].radio_type);
958 pos += sizeof(chan_tlv->header) +
959 sizeof(struct mwifiex_chan_scan_param_set);
960 cmd_append_size +=
961 sizeof(chan_tlv->header) +
962 sizeof(struct mwifiex_chan_scan_param_set);
963 }
964
965
966 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
967 MWIFIEX_VSIE_MASK_ADHOC, &pos);
968
969 if (priv->sec_info.wpa_enabled) {
970 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
971 if (rsn_ie_len == -1)
972 return -1;
973 cmd_append_size += rsn_ie_len;
974 }
975
976 if (adapter->adhoc_11n_enabled) {
977
978 ht_cap = (struct mwifiex_ie_types_htcap *) pos;
979 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
980 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
981 ht_cap->header.len =
982 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
983 radio_type = mwifiex_band_to_radio_type(
984 priv->adapter->config_bands);
985 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
986
987 if (adapter->sec_chan_offset ==
988 IEEE80211_HT_PARAM_CHA_SEC_NONE) {
989 u16 tmp_ht_cap;
990
991 tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
992 tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
993 tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
994 ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
995 }
996
997 pos += sizeof(struct mwifiex_ie_types_htcap);
998 cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
999
1000
1001 ht_info = (struct mwifiex_ie_types_htinfo *) pos;
1002 memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
1003 ht_info->header.type = cpu_to_le16(WLAN_EID_HT_OPERATION);
1004 ht_info->header.len =
1005 cpu_to_le16(sizeof(struct ieee80211_ht_operation));
1006
1007 ht_info->ht_oper.primary_chan =
1008 (u8) priv->curr_bss_params.bss_descriptor.channel;
1009 if (adapter->sec_chan_offset) {
1010 ht_info->ht_oper.ht_param = adapter->sec_chan_offset;
1011 ht_info->ht_oper.ht_param |=
1012 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1013 }
1014 ht_info->ht_oper.operation_mode =
1015 cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1016 ht_info->ht_oper.basic_set[0] = 0xff;
1017 pos += sizeof(struct mwifiex_ie_types_htinfo);
1018 cmd_append_size +=
1019 sizeof(struct mwifiex_ie_types_htinfo);
1020 }
1021
1022 cmd->size =
1023 cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
1024 + S_DS_GEN + cmd_append_size));
1025
1026 if (adapter->adhoc_start_band == BAND_B)
1027 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
1028 else
1029 tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1030
1031 adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
1032
1033 return 0;
1034}
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052int
1053mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1054 struct host_cmd_ds_command *cmd,
1055 struct mwifiex_bssdescriptor *bss_desc)
1056{
1057 int rsn_ie_len = 0;
1058 struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
1059 &cmd->params.adhoc_join;
1060 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
1061 u32 cmd_append_size = 0;
1062 u16 tmp_cap;
1063 u32 i, rates_size = 0;
1064 u16 curr_pkt_filter;
1065 u8 *pos =
1066 (u8 *) adhoc_join +
1067 sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
1068
1069
1070#define USE_G_PROTECTION 0x02
1071 if (bss_desc->erp_flags & USE_G_PROTECTION) {
1072 curr_pkt_filter =
1073 priv->
1074 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1075
1076 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1077 HostCmd_ACT_GEN_SET, 0,
1078 &curr_pkt_filter, false)) {
1079 dev_err(priv->adapter->dev,
1080 "ADHOC_J_CMD: G Protection config failed\n");
1081 return -1;
1082 }
1083 }
1084
1085 priv->attempted_bss_desc = bss_desc;
1086
1087 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
1088
1089 adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
1090
1091 adhoc_join->bss_descriptor.beacon_period
1092 = cpu_to_le16(bss_desc->beacon_period);
1093
1094 memcpy(&adhoc_join->bss_descriptor.bssid,
1095 &bss_desc->mac_address, ETH_ALEN);
1096
1097 memcpy(&adhoc_join->bss_descriptor.ssid,
1098 &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
1099
1100 memcpy(&adhoc_join->bss_descriptor.phy_param_set,
1101 &bss_desc->phy_param_set,
1102 sizeof(union ieee_types_phy_param_set));
1103
1104 memcpy(&adhoc_join->bss_descriptor.ss_param_set,
1105 &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
1106
1107 tmp_cap = bss_desc->cap_info_bitmap;
1108
1109 tmp_cap &= CAPINFO_MASK;
1110
1111 dev_dbg(priv->adapter->dev,
1112 "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
1113 tmp_cap, CAPINFO_MASK);
1114
1115
1116 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
1117 adhoc_join->bss_descriptor.bssid,
1118 adhoc_join->bss_descriptor.ssid);
1119
1120 for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
1121 bss_desc->supported_rates[i]; i++)
1122 ;
1123 rates_size = i;
1124
1125
1126 memset(adhoc_join->bss_descriptor.data_rates, 0,
1127 sizeof(adhoc_join->bss_descriptor.data_rates));
1128 memcpy(adhoc_join->bss_descriptor.data_rates,
1129 bss_desc->supported_rates, rates_size);
1130
1131
1132 priv->curr_bss_params.num_of_rates = rates_size;
1133 memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
1134 rates_size);
1135
1136
1137 priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
1138 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
1139
1140 if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled)
1141 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
1142
1143 if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
1144
1145 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
1146 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
1147 chan_tlv->header.len =
1148 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
1149
1150 memset(chan_tlv->chan_scan_param, 0x00,
1151 sizeof(struct mwifiex_chan_scan_param_set));
1152 chan_tlv->chan_scan_param[0].chan_number =
1153 (bss_desc->phy_param_set.ds_param_set.current_chan);
1154 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n",
1155 chan_tlv->chan_scan_param[0].chan_number);
1156
1157 chan_tlv->chan_scan_param[0].radio_type =
1158 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
1159
1160 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n",
1161 chan_tlv->chan_scan_param[0].radio_type);
1162 pos += sizeof(chan_tlv->header) +
1163 sizeof(struct mwifiex_chan_scan_param_set);
1164 cmd_append_size += sizeof(chan_tlv->header) +
1165 sizeof(struct mwifiex_chan_scan_param_set);
1166 }
1167
1168 if (priv->sec_info.wpa_enabled)
1169 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1170 if (rsn_ie_len == -1)
1171 return -1;
1172 cmd_append_size += rsn_ie_len;
1173
1174 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
1175 cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
1176 bss_desc, &pos);
1177
1178
1179 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1180 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1181
1182 cmd->size = cpu_to_le16
1183 ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
1184 + S_DS_GEN + cmd_append_size));
1185
1186 adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
1187
1188 return 0;
1189}
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1200 struct host_cmd_ds_command *resp)
1201{
1202 int ret = 0;
1203 struct mwifiex_adapter *adapter = priv->adapter;
1204 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
1205 struct mwifiex_bssdescriptor *bss_desc;
1206 u16 reason_code;
1207
1208 adhoc_result = &resp->params.adhoc_result;
1209
1210 bss_desc = priv->attempted_bss_desc;
1211
1212
1213 reason_code = le16_to_cpu(resp->result);
1214 if (reason_code) {
1215 dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
1216 if (priv->media_connected)
1217 mwifiex_reset_connect_state(priv, reason_code);
1218
1219 memset(&priv->curr_bss_params.bss_descriptor,
1220 0x00, sizeof(struct mwifiex_bssdescriptor));
1221
1222 ret = -1;
1223 goto done;
1224 }
1225
1226
1227 priv->media_connected = true;
1228
1229 if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
1230 dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
1231 bss_desc->ssid.ssid);
1232
1233
1234 memcpy(bss_desc->mac_address,
1235 adhoc_result->bssid, ETH_ALEN);
1236
1237 priv->adhoc_state = ADHOC_STARTED;
1238 } else {
1239
1240
1241
1242
1243 dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
1244 bss_desc->ssid.ssid);
1245
1246
1247
1248
1249
1250
1251 memcpy(&priv->curr_bss_params.bss_descriptor,
1252 bss_desc, sizeof(struct mwifiex_bssdescriptor));
1253
1254 priv->adhoc_state = ADHOC_JOINED;
1255 }
1256
1257 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
1258 priv->adhoc_channel);
1259 dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
1260 priv->curr_bss_params.bss_descriptor.mac_address);
1261
1262 if (!netif_carrier_ok(priv->netdev))
1263 netif_carrier_on(priv->netdev);
1264 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
1265
1266 mwifiex_save_curr_bcn(priv);
1267
1268done:
1269
1270 if (adapter->curr_cmd->wait_q_enabled) {
1271 if (ret)
1272 adapter->cmd_wait_q.status = -1;
1273 else
1274 adapter->cmd_wait_q.status = 0;
1275
1276 }
1277
1278 return ret;
1279}
1280
1281
1282
1283
1284
1285
1286
1287
1288int mwifiex_associate(struct mwifiex_private *priv,
1289 struct mwifiex_bssdescriptor *bss_desc)
1290{
1291
1292
1293
1294 if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
1295 (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1296 return -1;
1297
1298 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1299 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1300 priv->adapter->config_bands & BAND_AAC)
1301 mwifiex_set_11ac_ba_params(priv);
1302 else
1303 mwifiex_set_ba_params(priv);
1304
1305
1306
1307 priv->assoc_rsp_size = 0;
1308
1309 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1310 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1311}
1312
1313
1314
1315
1316
1317
1318int
1319mwifiex_adhoc_start(struct mwifiex_private *priv,
1320 struct cfg80211_ssid *adhoc_ssid)
1321{
1322 dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
1323 priv->adhoc_channel);
1324 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1325 priv->curr_bss_params.bss_descriptor.channel);
1326 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
1327 priv->curr_bss_params.band);
1328
1329 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1330 priv->adapter->config_bands & BAND_AAC)
1331 mwifiex_set_11ac_ba_params(priv);
1332 else
1333 mwifiex_set_ba_params(priv);
1334
1335 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1336 HostCmd_ACT_GEN_SET, 0, adhoc_ssid, true);
1337}
1338
1339
1340
1341
1342
1343
1344
1345int mwifiex_adhoc_join(struct mwifiex_private *priv,
1346 struct mwifiex_bssdescriptor *bss_desc)
1347{
1348 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
1349 priv->curr_bss_params.bss_descriptor.ssid.ssid);
1350 dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
1351 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
1352 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
1353 bss_desc->ssid.ssid);
1354 dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
1355 bss_desc->ssid.ssid_len);
1356
1357
1358 if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
1359 !mwifiex_ssid_cmp(&bss_desc->ssid,
1360 &priv->curr_bss_params.bss_descriptor.ssid) &&
1361 (priv->curr_bss_params.bss_descriptor.bss_mode ==
1362 NL80211_IFTYPE_ADHOC)) {
1363 dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID"
1364 " is the same as current; not attempting to re-join\n");
1365 return -1;
1366 }
1367
1368 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1369 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1370 priv->adapter->config_bands & BAND_AAC)
1371 mwifiex_set_11ac_ba_params(priv);
1372 else
1373 mwifiex_set_ba_params(priv);
1374
1375 dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
1376 priv->curr_bss_params.bss_descriptor.channel);
1377 dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
1378 priv->curr_bss_params.band);
1379
1380 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1381 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1382}
1383
1384
1385
1386
1387
1388static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1389{
1390 u8 mac_address[ETH_ALEN];
1391 int ret;
1392
1393 if (!mac || is_zero_ether_addr(mac))
1394 memcpy(mac_address,
1395 priv->curr_bss_params.bss_descriptor.mac_address,
1396 ETH_ALEN);
1397 else
1398 memcpy(mac_address, mac, ETH_ALEN);
1399
1400 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1401 HostCmd_ACT_GEN_SET, 0, mac_address, true);
1402
1403 return ret;
1404}
1405
1406
1407
1408
1409
1410
1411
1412
1413int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1414{
1415 int ret = 0;
1416
1417 if (!priv->media_connected)
1418 return 0;
1419
1420 switch (priv->bss_mode) {
1421 case NL80211_IFTYPE_STATION:
1422 case NL80211_IFTYPE_P2P_CLIENT:
1423 ret = mwifiex_deauthenticate_infra(priv, mac);
1424 if (ret)
1425 cfg80211_disconnected(priv->netdev, 0, NULL, 0,
1426 GFP_KERNEL);
1427 break;
1428 case NL80211_IFTYPE_ADHOC:
1429 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
1430 HostCmd_ACT_GEN_SET, 0, NULL, true);
1431 case NL80211_IFTYPE_AP:
1432 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1433 HostCmd_ACT_GEN_SET, 0, NULL, true);
1434 default:
1435 break;
1436 }
1437
1438 return ret;
1439}
1440
1441
1442void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
1443{
1444 struct mwifiex_private *priv;
1445 int i;
1446
1447 for (i = 0; i < adapter->priv_num; i++) {
1448 priv = adapter->priv[i];
1449 if (priv)
1450 mwifiex_deauthenticate(priv, NULL);
1451 }
1452}
1453EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
1454
1455
1456
1457
1458u8
1459mwifiex_band_to_radio_type(u8 band)
1460{
1461 switch (band) {
1462 case BAND_A:
1463 case BAND_AN:
1464 case BAND_A | BAND_AN:
1465 case BAND_A | BAND_AN | BAND_AAC:
1466 return HostCmd_SCAN_RADIO_TYPE_A;
1467 case BAND_B:
1468 case BAND_G:
1469 case BAND_B | BAND_G:
1470 default:
1471 return HostCmd_SCAN_RADIO_TYPE_BG;
1472 }
1473}
1474