0001
0002
0003
0004
0005
0006
0007
0008 #include "decl.h"
0009 #include "ioctl.h"
0010 #include "util.h"
0011 #include "fw.h"
0012 #include "main.h"
0013 #include "wmm.h"
0014 #include "11n.h"
0015 #include "11ac.h"
0016
0017 #define CAPINFO_MASK (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 static int
0028 mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
0029 {
0030 int ret_len = 0;
0031 struct mwifiex_ie_types_header ie_header;
0032
0033
0034 if (!buffer)
0035 return 0;
0036 if (!(*buffer))
0037 return 0;
0038
0039
0040
0041
0042
0043 if (priv->gen_ie_buf_len) {
0044 mwifiex_dbg(priv->adapter, INFO,
0045 "info: %s: append generic ie len %d to %p\n",
0046 __func__, priv->gen_ie_buf_len, *buffer);
0047
0048
0049 ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
0050 ie_header.len = cpu_to_le16(priv->gen_ie_buf_len);
0051 memcpy(*buffer, &ie_header, sizeof(ie_header));
0052
0053
0054
0055 *buffer += sizeof(ie_header);
0056 ret_len += sizeof(ie_header);
0057
0058
0059
0060 memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
0061
0062
0063
0064 *buffer += priv->gen_ie_buf_len;
0065 ret_len += priv->gen_ie_buf_len;
0066
0067
0068 priv->gen_ie_buf_len = 0;
0069 }
0070
0071
0072 return ret_len;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 static int
0089 mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
0090 struct mwifiex_bssdescriptor *bss_desc)
0091 {
0092 struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
0093 __le64 tsf_val;
0094
0095
0096 if (buffer == NULL)
0097 return 0;
0098 if (*buffer == NULL)
0099 return 0;
0100
0101 memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp));
0102
0103 tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
0104 tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val));
0105
0106 memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
0107 *buffer += sizeof(tsf_tlv.header);
0108
0109
0110 tsf_val = cpu_to_le64(bss_desc->fw_tsf);
0111 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
0112 *buffer += sizeof(tsf_val);
0113
0114 tsf_val = cpu_to_le64(bss_desc->timestamp);
0115
0116 mwifiex_dbg(priv->adapter, INFO,
0117 "info: %s: TSF offset calc: %016llx - %016llx\n",
0118 __func__, bss_desc->timestamp, bss_desc->fw_tsf);
0119
0120 memcpy(*buffer, &tsf_val, sizeof(tsf_val));
0121 *buffer += sizeof(tsf_val);
0122
0123 return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val));
0124 }
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
0135 u32 rate1_size, u8 *rate2, u32 rate2_size)
0136 {
0137 int ret;
0138 u8 *ptr = rate1, *tmp;
0139 u32 i, j;
0140
0141 tmp = kmemdup(rate1, rate1_size, GFP_KERNEL);
0142 if (!tmp) {
0143 mwifiex_dbg(priv->adapter, ERROR, "failed to alloc tmp buf\n");
0144 return -ENOMEM;
0145 }
0146
0147 memset(rate1, 0, rate1_size);
0148
0149 for (i = 0; i < rate2_size && rate2[i]; i++) {
0150 for (j = 0; j < rate1_size && tmp[j]; j++) {
0151
0152
0153 if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
0154 *rate1++ = tmp[j];
0155 break;
0156 }
0157 }
0158 }
0159
0160 mwifiex_dbg(priv->adapter, INFO, "info: Tx data rate set to %#x\n",
0161 priv->data_rate);
0162
0163 if (!priv->is_data_rate_auto) {
0164 while (*ptr) {
0165 if ((*ptr & 0x7f) == priv->data_rate) {
0166 ret = 0;
0167 goto done;
0168 }
0169 ptr++;
0170 }
0171 mwifiex_dbg(priv->adapter, ERROR,
0172 "previously set fixed data rate %#x\t"
0173 "is not compatible with the network\n",
0174 priv->data_rate);
0175
0176 ret = -1;
0177 goto done;
0178 }
0179
0180 ret = 0;
0181 done:
0182 kfree(tmp);
0183 return ret;
0184 }
0185
0186
0187
0188
0189
0190 static int
0191 mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
0192 struct mwifiex_bssdescriptor *bss_desc,
0193 u8 *out_rates, u32 *out_rates_size)
0194 {
0195 u8 card_rates[MWIFIEX_SUPPORTED_RATES];
0196 u32 card_rates_size;
0197
0198
0199 memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
0200
0201 card_rates_size = mwifiex_get_active_data_rates(priv, card_rates);
0202
0203 if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES,
0204 card_rates, card_rates_size)) {
0205 *out_rates_size = 0;
0206 mwifiex_dbg(priv->adapter, ERROR,
0207 "%s: cannot get common rates\n",
0208 __func__);
0209 return -1;
0210 }
0211
0212 *out_rates_size =
0213 min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES);
0214
0215 return 0;
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225 static int
0226 mwifiex_cmd_append_wps_ie(struct mwifiex_private *priv, u8 **buffer)
0227 {
0228 int retLen = 0;
0229 struct mwifiex_ie_types_header ie_header;
0230
0231 if (!buffer || !*buffer)
0232 return 0;
0233
0234
0235
0236
0237
0238 if (priv->wps_ie_len) {
0239 mwifiex_dbg(priv->adapter, CMD,
0240 "cmd: append wps ie %d to %p\n",
0241 priv->wps_ie_len, *buffer);
0242
0243
0244 ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
0245 ie_header.len = cpu_to_le16(priv->wps_ie_len);
0246 memcpy(*buffer, &ie_header, sizeof(ie_header));
0247 *buffer += sizeof(ie_header);
0248 retLen += sizeof(ie_header);
0249
0250 memcpy(*buffer, priv->wps_ie, priv->wps_ie_len);
0251 *buffer += priv->wps_ie_len;
0252 retLen += priv->wps_ie_len;
0253
0254 }
0255
0256 kfree(priv->wps_ie);
0257 priv->wps_ie_len = 0;
0258 return retLen;
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 static int
0270 mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
0271 {
0272 int retLen = 0;
0273 struct mwifiex_ie_types_header ie_header;
0274
0275
0276 if (buffer == NULL)
0277 return 0;
0278 if (*buffer == NULL)
0279 return 0;
0280
0281
0282
0283
0284
0285 if (priv->wapi_ie_len) {
0286 mwifiex_dbg(priv->adapter, CMD,
0287 "cmd: append wapi ie %d to %p\n",
0288 priv->wapi_ie_len, *buffer);
0289
0290
0291 ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
0292 ie_header.len = cpu_to_le16(priv->wapi_ie_len);
0293 memcpy(*buffer, &ie_header, sizeof(ie_header));
0294
0295
0296
0297 *buffer += sizeof(ie_header);
0298 retLen += sizeof(ie_header);
0299
0300
0301
0302 memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len);
0303
0304
0305
0306 *buffer += priv->wapi_ie_len;
0307 retLen += priv->wapi_ie_len;
0308
0309 }
0310
0311 return retLen;
0312 }
0313
0314
0315
0316
0317
0318 static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
0319 u8 **buffer)
0320 {
0321 struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv;
0322 int rsn_ie_len;
0323
0324 if (!buffer || !(*buffer))
0325 return 0;
0326
0327 rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer);
0328 rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]);
0329 rsn_ie_tlv->header.type = cpu_to_le16(
0330 le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
0331 rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
0332 rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
0333 & 0x00FF);
0334 if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
0335 memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
0336 le16_to_cpu(rsn_ie_tlv->header.len));
0337 else
0338 return -1;
0339
0340 rsn_ie_len = sizeof(rsn_ie_tlv->header) +
0341 le16_to_cpu(rsn_ie_tlv->header.len);
0342 *buffer += rsn_ie_len;
0343
0344 return rsn_ie_len;
0345 }
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375 int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
0376 struct host_cmd_ds_command *cmd,
0377 struct mwifiex_bssdescriptor *bss_desc)
0378 {
0379 struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate;
0380 struct mwifiex_ie_types_ssid_param_set *ssid_tlv;
0381 struct mwifiex_ie_types_phy_param_set *phy_tlv;
0382 struct mwifiex_ie_types_ss_param_set *ss_tlv;
0383 struct mwifiex_ie_types_rates_param_set *rates_tlv;
0384 struct mwifiex_ie_types_auth_type *auth_tlv;
0385 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
0386 u8 rates[MWIFIEX_SUPPORTED_RATES];
0387 u32 rates_size;
0388 u16 tmp_cap;
0389 u8 *pos;
0390 int rsn_ie_len = 0;
0391
0392 pos = (u8 *) assoc;
0393
0394 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
0395
0396
0397 priv->attempted_bss_desc = bss_desc;
0398
0399 memcpy(assoc->peer_sta_addr,
0400 bss_desc->mac_address, sizeof(assoc->peer_sta_addr));
0401 pos += sizeof(assoc->peer_sta_addr);
0402
0403
0404 assoc->listen_interval = cpu_to_le16(priv->listen_interval);
0405
0406 assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period);
0407
0408 pos += sizeof(assoc->cap_info_bitmap);
0409 pos += sizeof(assoc->listen_interval);
0410 pos += sizeof(assoc->beacon_period);
0411 pos += sizeof(assoc->dtim_period);
0412
0413 ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos;
0414 ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
0415 ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
0416 memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
0417 le16_to_cpu(ssid_tlv->header.len));
0418 pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
0419
0420 phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
0421 phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
0422 phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
0423 memcpy(&phy_tlv->fh_ds.ds_param_set,
0424 &bss_desc->phy_param_set.ds_param_set.current_chan,
0425 sizeof(phy_tlv->fh_ds.ds_param_set));
0426 pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
0427
0428 ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
0429 ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
0430 ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
0431 pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
0432
0433
0434 if (mwifiex_setup_rates_from_bssdesc
0435 (priv, bss_desc, rates, &rates_size))
0436 return -1;
0437
0438
0439 priv->curr_bss_params.num_of_rates = rates_size;
0440 memcpy(&priv->curr_bss_params.data_rates, rates, rates_size);
0441
0442
0443 rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos;
0444 rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
0445 rates_tlv->header.len = cpu_to_le16((u16) rates_size);
0446 memcpy(rates_tlv->rates, rates, rates_size);
0447 pos += sizeof(rates_tlv->header) + rates_size;
0448 mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_CMD: rates size = %d\n",
0449 rates_size);
0450
0451
0452 auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
0453 auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
0454 auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
0455 if (priv->sec_info.wep_enabled)
0456 auth_tlv->auth_type = cpu_to_le16(
0457 (u16) priv->sec_info.authentication_mode);
0458 else
0459 auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM);
0460
0461 pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
0462
0463 if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
0464 !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
0465 (!bss_desc->disable_11n) &&
0466 (priv->adapter->config_bands & BAND_GN ||
0467 priv->adapter->config_bands & BAND_AN) &&
0468 (bss_desc->bcn_ht_cap)
0469 )
0470 ) {
0471
0472
0473 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
0474 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
0475 chan_tlv->header.len =
0476 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
0477
0478 memset(chan_tlv->chan_scan_param, 0x00,
0479 sizeof(struct mwifiex_chan_scan_param_set));
0480 chan_tlv->chan_scan_param[0].chan_number =
0481 (bss_desc->phy_param_set.ds_param_set.current_chan);
0482 mwifiex_dbg(priv->adapter, INFO, "info: Assoc: TLV Chan = %d\n",
0483 chan_tlv->chan_scan_param[0].chan_number);
0484
0485 chan_tlv->chan_scan_param[0].radio_type =
0486 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
0487
0488 mwifiex_dbg(priv->adapter, INFO, "info: Assoc: TLV Band = %d\n",
0489 chan_tlv->chan_scan_param[0].radio_type);
0490 pos += sizeof(chan_tlv->header) +
0491 sizeof(struct mwifiex_chan_scan_param_set);
0492 }
0493
0494 if (!priv->wps.session_enable) {
0495 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
0496 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
0497
0498 if (rsn_ie_len == -1)
0499 return -1;
0500 }
0501
0502 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
0503 (!bss_desc->disable_11n) &&
0504 (priv->adapter->config_bands & BAND_GN ||
0505 priv->adapter->config_bands & BAND_AN))
0506 mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
0507
0508 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
0509 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
0510 priv->adapter->config_bands & BAND_AAC)
0511 mwifiex_cmd_append_11ac_tlv(priv, bss_desc, &pos);
0512
0513
0514 mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
0515
0516 mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
0517 bss_desc->bcn_ht_cap);
0518 if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
0519 mwifiex_cmd_append_wapi_ie(priv, &pos);
0520
0521 if (priv->wps.session_enable && priv->wps_ie_len)
0522 mwifiex_cmd_append_wps_ie(priv, &pos);
0523
0524 mwifiex_cmd_append_generic_ie(priv, &pos);
0525
0526 mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
0527
0528 mwifiex_11h_process_join(priv, &pos, bss_desc);
0529
0530 cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
0531
0532
0533 tmp_cap = bss_desc->cap_info_bitmap;
0534
0535 if (priv->adapter->config_bands == BAND_B)
0536 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
0537
0538 tmp_cap &= CAPINFO_MASK;
0539 mwifiex_dbg(priv->adapter, INFO,
0540 "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
0541 tmp_cap, CAPINFO_MASK);
0542 assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
0543
0544 return 0;
0545 }
0546
0547 static const char *assoc_failure_reason_to_str(u16 cap_info)
0548 {
0549 switch (cap_info) {
0550 case CONNECT_ERR_AUTH_ERR_STA_FAILURE:
0551 return "CONNECT_ERR_AUTH_ERR_STA_FAILURE";
0552 case CONNECT_ERR_AUTH_MSG_UNHANDLED:
0553 return "CONNECT_ERR_AUTH_MSG_UNHANDLED";
0554 case CONNECT_ERR_ASSOC_ERR_TIMEOUT:
0555 return "CONNECT_ERR_ASSOC_ERR_TIMEOUT";
0556 case CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED:
0557 return "CONNECT_ERR_ASSOC_ERR_AUTH_REFUSED";
0558 case CONNECT_ERR_STA_FAILURE:
0559 return "CONNECT_ERR_STA_FAILURE";
0560 }
0561
0562 return "Unknown connect failure";
0563 }
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626 int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
0627 struct host_cmd_ds_command *resp)
0628 {
0629 struct mwifiex_adapter *adapter = priv->adapter;
0630 int ret = 0;
0631 struct ieee_types_assoc_rsp *assoc_rsp;
0632 struct mwifiex_bssdescriptor *bss_desc;
0633 bool enable_data = true;
0634 u16 cap_info, status_code, aid;
0635 const u8 *ie_ptr;
0636 struct ieee80211_ht_operation *assoc_resp_ht_oper;
0637
0638 if (!priv->attempted_bss_desc) {
0639 mwifiex_dbg(priv->adapter, ERROR,
0640 "ASSOC_RESP: failed, association terminated by host\n");
0641 goto done;
0642 }
0643
0644 assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
0645
0646 cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap);
0647 status_code = le16_to_cpu(assoc_rsp->status_code);
0648 aid = le16_to_cpu(assoc_rsp->a_id);
0649
0650 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
0651 dev_err(priv->adapter->dev,
0652 "invalid AID value 0x%x; bits 15:14 not set\n",
0653 aid);
0654
0655 aid &= ~(BIT(15) | BIT(14));
0656
0657 priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
0658 sizeof(priv->assoc_rsp_buf));
0659
0660 assoc_rsp->a_id = cpu_to_le16(aid);
0661 memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
0662
0663 if (status_code) {
0664 priv->adapter->dbg.num_cmd_assoc_failure++;
0665 mwifiex_dbg(priv->adapter, ERROR,
0666 "ASSOC_RESP: failed,\t"
0667 "status code=%d err=%#x a_id=%#x\n",
0668 status_code, cap_info,
0669 le16_to_cpu(assoc_rsp->a_id));
0670
0671 mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n",
0672 assoc_failure_reason_to_str(cap_info));
0673 if (cap_info == CONNECT_ERR_ASSOC_ERR_TIMEOUT) {
0674 if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) {
0675 ret = WLAN_STATUS_AUTH_TIMEOUT;
0676 mwifiex_dbg(priv->adapter, ERROR,
0677 "ASSOC_RESP: AUTH timeout\n");
0678 } else {
0679 ret = WLAN_STATUS_UNSPECIFIED_FAILURE;
0680 mwifiex_dbg(priv->adapter, ERROR,
0681 "ASSOC_RESP: UNSPECIFIED failure\n");
0682 }
0683 } else {
0684 ret = status_code;
0685 }
0686
0687 goto done;
0688 }
0689
0690
0691 priv->media_connected = true;
0692
0693 priv->adapter->ps_state = PS_STATE_AWAKE;
0694 priv->adapter->pps_uapsd_mode = false;
0695 priv->adapter->tx_lock_flag = false;
0696
0697
0698 bss_desc = priv->attempted_bss_desc;
0699
0700 mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_RESP: %s\n",
0701 bss_desc->ssid.ssid);
0702
0703
0704 memcpy(&priv->curr_bss_params.bss_descriptor,
0705 bss_desc, sizeof(struct mwifiex_bssdescriptor));
0706
0707
0708 priv->curr_bss_params.bss_descriptor.channel
0709 = bss_desc->phy_param_set.ds_param_set.current_chan;
0710
0711 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
0712
0713 if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
0714 priv->curr_bss_params.wmm_enabled = true;
0715 else
0716 priv->curr_bss_params.wmm_enabled = false;
0717
0718 if ((priv->wmm_required || bss_desc->bcn_ht_cap) &&
0719 priv->curr_bss_params.wmm_enabled)
0720 priv->wmm_enabled = true;
0721 else
0722 priv->wmm_enabled = false;
0723
0724 priv->curr_bss_params.wmm_uapsd_enabled = false;
0725
0726 if (priv->wmm_enabled)
0727 priv->curr_bss_params.wmm_uapsd_enabled
0728 = ((bss_desc->wmm_ie.qos_info_bitmap &
0729 IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
0730
0731
0732 ie_ptr = cfg80211_find_ie(WLAN_EID_HT_OPERATION, assoc_rsp->ie_buffer,
0733 priv->assoc_rsp_size
0734 - sizeof(struct ieee_types_assoc_rsp));
0735 if (ie_ptr) {
0736 assoc_resp_ht_oper = (struct ieee80211_ht_operation *)(ie_ptr
0737 + sizeof(struct ieee_types_header));
0738 priv->assoc_resp_ht_param = assoc_resp_ht_oper->ht_param;
0739 priv->ht_param_present = true;
0740 } else {
0741 priv->ht_param_present = false;
0742 }
0743
0744 mwifiex_dbg(priv->adapter, INFO,
0745 "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
0746 priv->curr_pkt_filter);
0747 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
0748 priv->wpa_is_gtk_set = false;
0749
0750 if (priv->wmm_enabled) {
0751
0752
0753 enable_data = false;
0754 } else {
0755
0756
0757 mwifiex_wmm_setup_queue_priorities(priv, NULL);
0758 mwifiex_wmm_setup_ac_downgrade(priv);
0759 }
0760
0761 if (enable_data)
0762 mwifiex_dbg(priv->adapter, INFO,
0763 "info: post association, re-enabling data flow\n");
0764
0765
0766 priv->data_rssi_last = 0;
0767 priv->data_nf_last = 0;
0768 priv->data_rssi_avg = 0;
0769 priv->data_nf_avg = 0;
0770 priv->bcn_rssi_last = 0;
0771 priv->bcn_nf_last = 0;
0772 priv->bcn_rssi_avg = 0;
0773 priv->bcn_nf_avg = 0;
0774 priv->rxpd_rate = 0;
0775 priv->rxpd_htinfo = 0;
0776
0777 mwifiex_save_curr_bcn(priv);
0778
0779 priv->adapter->dbg.num_cmd_assoc_success++;
0780
0781 mwifiex_dbg(priv->adapter, INFO, "info: ASSOC_RESP: associated\n");
0782
0783
0784
0785 mwifiex_ralist_add(priv,
0786 priv->curr_bss_params.bss_descriptor.mac_address);
0787
0788 if (!netif_carrier_ok(priv->netdev))
0789 netif_carrier_on(priv->netdev);
0790 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
0791
0792 if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
0793 priv->scan_block = true;
0794 else
0795 priv->port_open = true;
0796
0797 done:
0798
0799 if (adapter->curr_cmd->wait_q_enabled) {
0800 if (ret)
0801 adapter->cmd_wait_q.status = -1;
0802 else
0803 adapter->cmd_wait_q.status = 0;
0804 }
0805
0806 return ret;
0807 }
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 int
0828 mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
0829 struct host_cmd_ds_command *cmd,
0830 struct cfg80211_ssid *req_ssid)
0831 {
0832 int rsn_ie_len = 0;
0833 struct mwifiex_adapter *adapter = priv->adapter;
0834 struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
0835 &cmd->params.adhoc_start;
0836 struct mwifiex_bssdescriptor *bss_desc;
0837 u32 cmd_append_size = 0;
0838 u32 i;
0839 u16 tmp_cap;
0840 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
0841 u8 radio_type;
0842
0843 struct mwifiex_ie_types_htcap *ht_cap;
0844 struct mwifiex_ie_types_htinfo *ht_info;
0845 u8 *pos = (u8 *) adhoc_start +
0846 sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
0847
0848 if (!adapter)
0849 return -1;
0850
0851 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
0852
0853 bss_desc = &priv->curr_bss_params.bss_descriptor;
0854 priv->attempted_bss_desc = bss_desc;
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866 memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
0867
0868 if (req_ssid->ssid_len > IEEE80211_MAX_SSID_LEN)
0869 req_ssid->ssid_len = IEEE80211_MAX_SSID_LEN;
0870 memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
0871
0872 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: SSID = %s\n",
0873 adhoc_start->ssid);
0874
0875 memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
0876 memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
0877
0878 bss_desc->ssid.ssid_len = req_ssid->ssid_len;
0879
0880
0881 adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
0882 bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
0883 adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
0884 bss_desc->beacon_period = priv->beacon_period;
0885
0886
0887
0888 #define DS_PARA_IE_ID 3
0889
0890 #define DS_PARA_IE_LEN 1
0891
0892 adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
0893 adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
0894
0895 if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
0896 (u16) priv->adhoc_channel, 0)) {
0897 struct mwifiex_chan_freq_power *cfp;
0898 cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
0899 FIRST_VALID_CHANNEL, 0);
0900 if (cfp)
0901 priv->adhoc_channel = (u8) cfp->channel;
0902 }
0903
0904 if (!priv->adhoc_channel) {
0905 mwifiex_dbg(adapter, ERROR,
0906 "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
0907 return -1;
0908 }
0909
0910 mwifiex_dbg(adapter, INFO,
0911 "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
0912 priv->adhoc_channel);
0913
0914 priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
0915 priv->curr_bss_params.band = adapter->adhoc_start_band;
0916
0917 bss_desc->channel = priv->adhoc_channel;
0918 adhoc_start->phy_param_set.ds_param_set.current_chan =
0919 priv->adhoc_channel;
0920
0921 memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
0922 sizeof(union ieee_types_phy_param_set));
0923
0924
0925
0926 #define IBSS_PARA_IE_ID 6
0927
0928 #define IBSS_PARA_IE_LEN 2
0929
0930 adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
0931 adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
0932 adhoc_start->ss_param_set.ibss_param_set.atim_window
0933 = cpu_to_le16(priv->atim_window);
0934 memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
0935 sizeof(union ieee_types_ss_param_set));
0936
0937
0938 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
0939 tmp_cap = WLAN_CAPABILITY_IBSS;
0940
0941
0942 if (priv->sec_info.encryption_mode) {
0943
0944 mwifiex_dbg(adapter, INFO,
0945 "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
0946 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
0947 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
0948 } else {
0949 mwifiex_dbg(adapter, INFO,
0950 "info: ADHOC_S_CMD: wep_status NOT set,\t"
0951 "setting privacy to ACCEPT ALL\n");
0952 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
0953 }
0954
0955 memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate));
0956 mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
0957 if ((adapter->adhoc_start_band & BAND_G) &&
0958 (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
0959 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
0960 HostCmd_ACT_GEN_SET, 0,
0961 &priv->curr_pkt_filter, false)) {
0962 mwifiex_dbg(adapter, ERROR,
0963 "ADHOC_S_CMD: G Protection config failed\n");
0964 return -1;
0965 }
0966 }
0967
0968 for (i = 0; i < sizeof(adhoc_start->data_rate); i++)
0969 if (!adhoc_start->data_rate[i])
0970 break;
0971
0972 priv->curr_bss_params.num_of_rates = i;
0973
0974
0975 memcpy(&priv->curr_bss_params.data_rates,
0976 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
0977
0978 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: rates=%4ph\n",
0979 adhoc_start->data_rate);
0980
0981 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
0982
0983 if (IS_SUPPORT_MULTI_BANDS(adapter)) {
0984
0985 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
0986 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
0987 chan_tlv->header.len =
0988 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
0989
0990 memset(chan_tlv->chan_scan_param, 0x00,
0991 sizeof(struct mwifiex_chan_scan_param_set));
0992 chan_tlv->chan_scan_param[0].chan_number =
0993 (u8) priv->curr_bss_params.bss_descriptor.channel;
0994
0995 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: TLV Chan = %d\n",
0996 chan_tlv->chan_scan_param[0].chan_number);
0997
0998 chan_tlv->chan_scan_param[0].radio_type
0999 = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1000 if (adapter->adhoc_start_band & BAND_GN ||
1001 adapter->adhoc_start_band & BAND_AN) {
1002 if (adapter->sec_chan_offset ==
1003 IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
1004 chan_tlv->chan_scan_param[0].radio_type |=
1005 (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
1006 else if (adapter->sec_chan_offset ==
1007 IEEE80211_HT_PARAM_CHA_SEC_BELOW)
1008 chan_tlv->chan_scan_param[0].radio_type |=
1009 (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
1010 }
1011 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: TLV Band = %d\n",
1012 chan_tlv->chan_scan_param[0].radio_type);
1013 pos += sizeof(chan_tlv->header) +
1014 sizeof(struct mwifiex_chan_scan_param_set);
1015 cmd_append_size +=
1016 sizeof(chan_tlv->header) +
1017 sizeof(struct mwifiex_chan_scan_param_set);
1018 }
1019
1020
1021 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1022 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1023
1024 if (priv->sec_info.wpa_enabled) {
1025 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1026 if (rsn_ie_len == -1)
1027 return -1;
1028 cmd_append_size += rsn_ie_len;
1029 }
1030
1031 if (adapter->adhoc_11n_enabled) {
1032
1033 ht_cap = (struct mwifiex_ie_types_htcap *) pos;
1034 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
1035 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
1036 ht_cap->header.len =
1037 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
1038 radio_type = mwifiex_band_to_radio_type(
1039 priv->adapter->config_bands);
1040 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
1041
1042 if (adapter->sec_chan_offset ==
1043 IEEE80211_HT_PARAM_CHA_SEC_NONE) {
1044 u16 tmp_ht_cap;
1045
1046 tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
1047 tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1048 tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
1049 ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
1050 }
1051
1052 pos += sizeof(struct mwifiex_ie_types_htcap);
1053 cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
1054
1055
1056 ht_info = (struct mwifiex_ie_types_htinfo *) pos;
1057 memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
1058 ht_info->header.type = cpu_to_le16(WLAN_EID_HT_OPERATION);
1059 ht_info->header.len =
1060 cpu_to_le16(sizeof(struct ieee80211_ht_operation));
1061
1062 ht_info->ht_oper.primary_chan =
1063 (u8) priv->curr_bss_params.bss_descriptor.channel;
1064 if (adapter->sec_chan_offset) {
1065 ht_info->ht_oper.ht_param = adapter->sec_chan_offset;
1066 ht_info->ht_oper.ht_param |=
1067 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1068 }
1069 ht_info->ht_oper.operation_mode =
1070 cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1071 ht_info->ht_oper.basic_set[0] = 0xff;
1072 pos += sizeof(struct mwifiex_ie_types_htinfo);
1073 cmd_append_size +=
1074 sizeof(struct mwifiex_ie_types_htinfo);
1075 }
1076
1077 cmd->size =
1078 cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
1079 + S_DS_GEN + cmd_append_size));
1080
1081 if (adapter->adhoc_start_band == BAND_B)
1082 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
1083 else
1084 tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1085
1086 adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
1087
1088 return 0;
1089 }
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107 int
1108 mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1109 struct host_cmd_ds_command *cmd,
1110 struct mwifiex_bssdescriptor *bss_desc)
1111 {
1112 int rsn_ie_len = 0;
1113 struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
1114 &cmd->params.adhoc_join;
1115 struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
1116 u32 cmd_append_size = 0;
1117 u16 tmp_cap;
1118 u32 i, rates_size = 0;
1119 u16 curr_pkt_filter;
1120 u8 *pos =
1121 (u8 *) adhoc_join +
1122 sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
1123
1124
1125 #define USE_G_PROTECTION 0x02
1126 if (bss_desc->erp_flags & USE_G_PROTECTION) {
1127 curr_pkt_filter =
1128 priv->
1129 curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1130
1131 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1132 HostCmd_ACT_GEN_SET, 0,
1133 &curr_pkt_filter, false)) {
1134 mwifiex_dbg(priv->adapter, ERROR,
1135 "ADHOC_J_CMD: G Protection config failed\n");
1136 return -1;
1137 }
1138 }
1139
1140 priv->attempted_bss_desc = bss_desc;
1141
1142 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
1143
1144 adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
1145
1146 adhoc_join->bss_descriptor.beacon_period
1147 = cpu_to_le16(bss_desc->beacon_period);
1148
1149 memcpy(&adhoc_join->bss_descriptor.bssid,
1150 &bss_desc->mac_address, ETH_ALEN);
1151
1152 memcpy(&adhoc_join->bss_descriptor.ssid,
1153 &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
1154
1155 memcpy(&adhoc_join->bss_descriptor.phy_param_set,
1156 &bss_desc->phy_param_set,
1157 sizeof(union ieee_types_phy_param_set));
1158
1159 memcpy(&adhoc_join->bss_descriptor.ss_param_set,
1160 &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
1161
1162 tmp_cap = bss_desc->cap_info_bitmap;
1163
1164 tmp_cap &= CAPINFO_MASK;
1165
1166 mwifiex_dbg(priv->adapter, INFO,
1167 "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
1168 tmp_cap, CAPINFO_MASK);
1169
1170
1171 mwifiex_dbg(priv->adapter, INFO,
1172 "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
1173 adhoc_join->bss_descriptor.bssid,
1174 adhoc_join->bss_descriptor.ssid);
1175
1176 for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
1177 bss_desc->supported_rates[i]; i++)
1178 ;
1179 rates_size = i;
1180
1181
1182 memset(adhoc_join->bss_descriptor.data_rates, 0,
1183 sizeof(adhoc_join->bss_descriptor.data_rates));
1184 memcpy(adhoc_join->bss_descriptor.data_rates,
1185 bss_desc->supported_rates, rates_size);
1186
1187
1188 priv->curr_bss_params.num_of_rates = rates_size;
1189 memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
1190 rates_size);
1191
1192
1193 priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
1194 priv->curr_bss_params.band = (u8) bss_desc->bss_band;
1195
1196 if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled)
1197 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
1198
1199 if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
1200
1201 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
1202 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
1203 chan_tlv->header.len =
1204 cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
1205
1206 memset(chan_tlv->chan_scan_param, 0x00,
1207 sizeof(struct mwifiex_chan_scan_param_set));
1208 chan_tlv->chan_scan_param[0].chan_number =
1209 (bss_desc->phy_param_set.ds_param_set.current_chan);
1210 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_J_CMD: TLV Chan=%d\n",
1211 chan_tlv->chan_scan_param[0].chan_number);
1212
1213 chan_tlv->chan_scan_param[0].radio_type =
1214 mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
1215
1216 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_J_CMD: TLV Band=%d\n",
1217 chan_tlv->chan_scan_param[0].radio_type);
1218 pos += sizeof(chan_tlv->header) +
1219 sizeof(struct mwifiex_chan_scan_param_set);
1220 cmd_append_size += sizeof(chan_tlv->header) +
1221 sizeof(struct mwifiex_chan_scan_param_set);
1222 }
1223
1224 if (priv->sec_info.wpa_enabled)
1225 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1226 if (rsn_ie_len == -1)
1227 return -1;
1228 cmd_append_size += rsn_ie_len;
1229
1230 if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
1231 cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
1232 bss_desc, &pos);
1233
1234
1235 cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1236 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1237
1238 cmd->size = cpu_to_le16
1239 ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
1240 + S_DS_GEN + cmd_append_size));
1241
1242 adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
1243
1244 return 0;
1245 }
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255 int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1256 struct host_cmd_ds_command *resp)
1257 {
1258 int ret = 0;
1259 struct mwifiex_adapter *adapter = priv->adapter;
1260 struct host_cmd_ds_802_11_ad_hoc_start_result *start_result =
1261 &resp->params.start_result;
1262 struct host_cmd_ds_802_11_ad_hoc_join_result *join_result =
1263 &resp->params.join_result;
1264 struct mwifiex_bssdescriptor *bss_desc;
1265 u16 cmd = le16_to_cpu(resp->command);
1266 u8 result;
1267
1268 if (!priv->attempted_bss_desc) {
1269 mwifiex_dbg(priv->adapter, ERROR,
1270 "ADHOC_RESP: failed, association terminated by host\n");
1271 goto done;
1272 }
1273
1274 if (cmd == HostCmd_CMD_802_11_AD_HOC_START)
1275 result = start_result->result;
1276 else
1277 result = join_result->result;
1278
1279 bss_desc = priv->attempted_bss_desc;
1280
1281
1282 if (result) {
1283 mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n");
1284 if (priv->media_connected)
1285 mwifiex_reset_connect_state(priv, result, true);
1286
1287 memset(&priv->curr_bss_params.bss_descriptor,
1288 0x00, sizeof(struct mwifiex_bssdescriptor));
1289
1290 ret = -1;
1291 goto done;
1292 }
1293
1294
1295 priv->media_connected = true;
1296
1297 if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
1298 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_S_RESP %s\n",
1299 bss_desc->ssid.ssid);
1300
1301
1302 memcpy(bss_desc->mac_address,
1303 start_result->bssid, ETH_ALEN);
1304
1305 priv->adhoc_state = ADHOC_STARTED;
1306 } else {
1307
1308
1309
1310
1311 mwifiex_dbg(priv->adapter, INFO,
1312 "info: ADHOC_J_RESP %s\n",
1313 bss_desc->ssid.ssid);
1314
1315
1316
1317
1318
1319
1320 memcpy(&priv->curr_bss_params.bss_descriptor,
1321 bss_desc, sizeof(struct mwifiex_bssdescriptor));
1322
1323 priv->adhoc_state = ADHOC_JOINED;
1324 }
1325
1326 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_RESP: channel = %d\n",
1327 priv->adhoc_channel);
1328 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_RESP: BSSID = %pM\n",
1329 priv->curr_bss_params.bss_descriptor.mac_address);
1330
1331 if (!netif_carrier_ok(priv->netdev))
1332 netif_carrier_on(priv->netdev);
1333 mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
1334
1335 mwifiex_save_curr_bcn(priv);
1336
1337 done:
1338
1339 if (adapter->curr_cmd->wait_q_enabled) {
1340 if (ret)
1341 adapter->cmd_wait_q.status = -1;
1342 else
1343 adapter->cmd_wait_q.status = 0;
1344
1345 }
1346
1347 return ret;
1348 }
1349
1350
1351
1352
1353
1354
1355
1356
1357 int mwifiex_associate(struct mwifiex_private *priv,
1358 struct mwifiex_bssdescriptor *bss_desc)
1359 {
1360
1361
1362
1363 if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
1364 (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1365 return -1;
1366
1367 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1368 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1369 priv->adapter->config_bands & BAND_AAC)
1370 mwifiex_set_11ac_ba_params(priv);
1371 else
1372 mwifiex_set_ba_params(priv);
1373
1374
1375
1376 priv->assoc_rsp_size = 0;
1377
1378 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1379 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1380 }
1381
1382
1383
1384
1385
1386
1387 int
1388 mwifiex_adhoc_start(struct mwifiex_private *priv,
1389 struct cfg80211_ssid *adhoc_ssid)
1390 {
1391 mwifiex_dbg(priv->adapter, INFO, "info: Adhoc Channel = %d\n",
1392 priv->adhoc_channel);
1393 mwifiex_dbg(priv->adapter, INFO, "info: curr_bss_params.channel = %d\n",
1394 priv->curr_bss_params.bss_descriptor.channel);
1395 mwifiex_dbg(priv->adapter, INFO, "info: curr_bss_params.band = %d\n",
1396 priv->curr_bss_params.band);
1397
1398 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1399 priv->adapter->config_bands & BAND_AAC)
1400 mwifiex_set_11ac_ba_params(priv);
1401 else
1402 mwifiex_set_ba_params(priv);
1403
1404 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1405 HostCmd_ACT_GEN_SET, 0, adhoc_ssid, true);
1406 }
1407
1408
1409
1410
1411
1412
1413
1414 int mwifiex_adhoc_join(struct mwifiex_private *priv,
1415 struct mwifiex_bssdescriptor *bss_desc)
1416 {
1417 mwifiex_dbg(priv->adapter, INFO,
1418 "info: adhoc join: curr_bss ssid =%s\n",
1419 priv->curr_bss_params.bss_descriptor.ssid.ssid);
1420 mwifiex_dbg(priv->adapter, INFO,
1421 "info: adhoc join: curr_bss ssid_len =%u\n",
1422 priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
1423 mwifiex_dbg(priv->adapter, INFO, "info: adhoc join: ssid =%s\n",
1424 bss_desc->ssid.ssid);
1425 mwifiex_dbg(priv->adapter, INFO, "info: adhoc join: ssid_len =%u\n",
1426 bss_desc->ssid.ssid_len);
1427
1428
1429 if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
1430 !mwifiex_ssid_cmp(&bss_desc->ssid,
1431 &priv->curr_bss_params.bss_descriptor.ssid) &&
1432 (priv->curr_bss_params.bss_descriptor.bss_mode ==
1433 NL80211_IFTYPE_ADHOC)) {
1434 mwifiex_dbg(priv->adapter, INFO,
1435 "info: ADHOC_J_CMD: new ad-hoc SSID\t"
1436 "is the same as current; not attempting to re-join\n");
1437 return -1;
1438 }
1439
1440 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1441 !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1442 priv->adapter->config_bands & BAND_AAC)
1443 mwifiex_set_11ac_ba_params(priv);
1444 else
1445 mwifiex_set_ba_params(priv);
1446
1447 mwifiex_dbg(priv->adapter, INFO,
1448 "info: curr_bss_params.channel = %d\n",
1449 priv->curr_bss_params.bss_descriptor.channel);
1450 mwifiex_dbg(priv->adapter, INFO,
1451 "info: curr_bss_params.band = %c\n",
1452 priv->curr_bss_params.band);
1453
1454 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1455 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1456 }
1457
1458
1459
1460
1461
1462 static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1463 {
1464 u8 mac_address[ETH_ALEN];
1465 int ret;
1466
1467 if (!mac || is_zero_ether_addr(mac))
1468 memcpy(mac_address,
1469 priv->curr_bss_params.bss_descriptor.mac_address,
1470 ETH_ALEN);
1471 else
1472 memcpy(mac_address, mac, ETH_ALEN);
1473
1474 ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1475 HostCmd_ACT_GEN_SET, 0, mac_address, true);
1476
1477 return ret;
1478 }
1479
1480
1481
1482
1483
1484
1485
1486
1487 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1488 {
1489 int ret = 0;
1490
1491 if (!priv->media_connected)
1492 return 0;
1493
1494 switch (priv->bss_mode) {
1495 case NL80211_IFTYPE_STATION:
1496 case NL80211_IFTYPE_P2P_CLIENT:
1497 ret = mwifiex_deauthenticate_infra(priv, mac);
1498 if (ret)
1499 cfg80211_disconnected(priv->netdev, 0, NULL, 0,
1500 true, GFP_KERNEL);
1501 break;
1502 case NL80211_IFTYPE_ADHOC:
1503 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
1504 HostCmd_ACT_GEN_SET, 0, NULL, true);
1505 case NL80211_IFTYPE_AP:
1506 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1507 HostCmd_ACT_GEN_SET, 0, NULL, true);
1508 default:
1509 break;
1510 }
1511
1512 return ret;
1513 }
1514
1515
1516 void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
1517 {
1518 struct mwifiex_private *priv;
1519 int i;
1520
1521 for (i = 0; i < adapter->priv_num; i++) {
1522 priv = adapter->priv[i];
1523 if (priv)
1524 mwifiex_deauthenticate(priv, NULL);
1525 }
1526 }
1527 EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
1528
1529
1530
1531
1532 u8
1533 mwifiex_band_to_radio_type(u8 band)
1534 {
1535 switch (band) {
1536 case BAND_A:
1537 case BAND_AN:
1538 case BAND_A | BAND_AN:
1539 case BAND_A | BAND_AN | BAND_AAC:
1540 return HostCmd_SCAN_RADIO_TYPE_A;
1541 case BAND_B:
1542 case BAND_G:
1543 case BAND_B | BAND_G:
1544 default:
1545 return HostCmd_SCAN_RADIO_TYPE_BG;
1546 }
1547 }