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