This source file includes following definitions.
- mwifiex_cmd_append_generic_ie
- mwifiex_cmd_append_tsf_tlv
- mwifiex_get_common_rates
- mwifiex_setup_rates_from_bssdesc
- mwifiex_cmd_append_wps_ie
- mwifiex_cmd_append_wapi_ie
- mwifiex_append_rsn_ie_wpa_wpa2
- mwifiex_cmd_802_11_associate
- assoc_failure_reason_to_str
- mwifiex_ret_802_11_associate
- mwifiex_cmd_802_11_ad_hoc_start
- mwifiex_cmd_802_11_ad_hoc_join
- mwifiex_ret_802_11_ad_hoc
- mwifiex_associate
- mwifiex_adhoc_start
- mwifiex_adhoc_join
- mwifiex_deauthenticate_infra
- mwifiex_deauthenticate
- mwifiex_deauthenticate_all
- mwifiex_band_to_radio_type
   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 
  39 static int
  40 mwifiex_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 
 100 static int
 101 mwifiex_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 
 146 static 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;
 193 done:
 194         kfree(tmp);
 195         return ret;
 196 }
 197 
 198 
 199 
 200 
 201 
 202 static int
 203 mwifiex_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 
 237 static int
 238 mwifiex_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 
 281 static int
 282 mwifiex_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 
 330 static 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 
 387 int 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 
 559 static 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 
 638 int 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 
 809 done:
 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 
 839 int
 840 mwifiex_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         memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
 881 
 882         mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: SSID = %s\n",
 883                     adhoc_start->ssid);
 884 
 885         memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
 886         memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
 887 
 888         bss_desc->ssid.ssid_len = req_ssid->ssid_len;
 889 
 890         
 891         adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
 892         bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
 893         adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
 894         bss_desc->beacon_period = priv->beacon_period;
 895 
 896         
 897 
 898 #define DS_PARA_IE_ID   3
 899 
 900 #define DS_PARA_IE_LEN  1
 901 
 902         adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
 903         adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
 904 
 905         if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
 906                              (u16) priv->adhoc_channel, 0)) {
 907                 struct mwifiex_chan_freq_power *cfp;
 908                 cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
 909                                       FIRST_VALID_CHANNEL, 0);
 910                 if (cfp)
 911                         priv->adhoc_channel = (u8) cfp->channel;
 912         }
 913 
 914         if (!priv->adhoc_channel) {
 915                 mwifiex_dbg(adapter, ERROR,
 916                             "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
 917                 return -1;
 918         }
 919 
 920         mwifiex_dbg(adapter, INFO,
 921                     "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
 922                     priv->adhoc_channel);
 923 
 924         priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
 925         priv->curr_bss_params.band = adapter->adhoc_start_band;
 926 
 927         bss_desc->channel = priv->adhoc_channel;
 928         adhoc_start->phy_param_set.ds_param_set.current_chan =
 929                 priv->adhoc_channel;
 930 
 931         memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
 932                sizeof(union ieee_types_phy_param_set));
 933 
 934         
 935 
 936 #define IBSS_PARA_IE_ID   6
 937 
 938 #define IBSS_PARA_IE_LEN  2
 939 
 940         adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
 941         adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
 942         adhoc_start->ss_param_set.ibss_param_set.atim_window
 943                                         = cpu_to_le16(priv->atim_window);
 944         memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
 945                sizeof(union ieee_types_ss_param_set));
 946 
 947         
 948         bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
 949         tmp_cap = WLAN_CAPABILITY_IBSS;
 950 
 951         
 952         if (priv->sec_info.encryption_mode) {
 953                 
 954                 mwifiex_dbg(adapter, INFO,
 955                             "info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
 956                 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
 957                 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
 958         } else {
 959                 mwifiex_dbg(adapter, INFO,
 960                             "info: ADHOC_S_CMD: wep_status NOT set,\t"
 961                             "setting privacy to ACCEPT ALL\n");
 962                 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
 963         }
 964 
 965         memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate));
 966         mwifiex_get_active_data_rates(priv, adhoc_start->data_rate);
 967         if ((adapter->adhoc_start_band & BAND_G) &&
 968             (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
 969                 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
 970                                      HostCmd_ACT_GEN_SET, 0,
 971                                      &priv->curr_pkt_filter, false)) {
 972                         mwifiex_dbg(adapter, ERROR,
 973                                     "ADHOC_S_CMD: G Protection config failed\n");
 974                         return -1;
 975                 }
 976         }
 977         
 978         for (i = 0; i < sizeof(adhoc_start->data_rate); i++)
 979                 if (!adhoc_start->data_rate[i])
 980                         break;
 981 
 982         priv->curr_bss_params.num_of_rates = i;
 983 
 984         
 985         memcpy(&priv->curr_bss_params.data_rates,
 986                &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
 987 
 988         mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: rates=%4ph\n",
 989                     adhoc_start->data_rate);
 990 
 991         mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
 992 
 993         if (IS_SUPPORT_MULTI_BANDS(adapter)) {
 994                 
 995                 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
 996                 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
 997                 chan_tlv->header.len =
 998                         cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
 999 
1000                 memset(chan_tlv->chan_scan_param, 0x00,
1001                        sizeof(struct mwifiex_chan_scan_param_set));
1002                 chan_tlv->chan_scan_param[0].chan_number =
1003                         (u8) priv->curr_bss_params.bss_descriptor.channel;
1004 
1005                 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: TLV Chan = %d\n",
1006                             chan_tlv->chan_scan_param[0].chan_number);
1007 
1008                 chan_tlv->chan_scan_param[0].radio_type
1009                        = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1010                 if (adapter->adhoc_start_band & BAND_GN ||
1011                     adapter->adhoc_start_band & BAND_AN) {
1012                         if (adapter->sec_chan_offset ==
1013                                             IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
1014                                 chan_tlv->chan_scan_param[0].radio_type |=
1015                                         (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
1016                         else if (adapter->sec_chan_offset ==
1017                                             IEEE80211_HT_PARAM_CHA_SEC_BELOW)
1018                                 chan_tlv->chan_scan_param[0].radio_type |=
1019                                         (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
1020                 }
1021                 mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: TLV Band = %d\n",
1022                             chan_tlv->chan_scan_param[0].radio_type);
1023                 pos += sizeof(chan_tlv->header) +
1024                         sizeof(struct mwifiex_chan_scan_param_set);
1025                 cmd_append_size +=
1026                         sizeof(chan_tlv->header) +
1027                         sizeof(struct mwifiex_chan_scan_param_set);
1028         }
1029 
1030         
1031         cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1032                                 MWIFIEX_VSIE_MASK_ADHOC, &pos);
1033 
1034         if (priv->sec_info.wpa_enabled) {
1035                 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1036                 if (rsn_ie_len == -1)
1037                         return -1;
1038                 cmd_append_size += rsn_ie_len;
1039         }
1040 
1041         if (adapter->adhoc_11n_enabled) {
1042                 
1043                 ht_cap = (struct mwifiex_ie_types_htcap *) pos;
1044                 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
1045                 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
1046                 ht_cap->header.len =
1047                        cpu_to_le16(sizeof(struct ieee80211_ht_cap));
1048                 radio_type = mwifiex_band_to_radio_type(
1049                                         priv->adapter->config_bands);
1050                 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
1051 
1052                 if (adapter->sec_chan_offset ==
1053                                         IEEE80211_HT_PARAM_CHA_SEC_NONE) {
1054                         u16 tmp_ht_cap;
1055 
1056                         tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
1057                         tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1058                         tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
1059                         ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
1060                 }
1061 
1062                 pos += sizeof(struct mwifiex_ie_types_htcap);
1063                 cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
1064 
1065                 
1066                 ht_info = (struct mwifiex_ie_types_htinfo *) pos;
1067                 memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
1068                 ht_info->header.type = cpu_to_le16(WLAN_EID_HT_OPERATION);
1069                 ht_info->header.len =
1070                         cpu_to_le16(sizeof(struct ieee80211_ht_operation));
1071 
1072                 ht_info->ht_oper.primary_chan =
1073                         (u8) priv->curr_bss_params.bss_descriptor.channel;
1074                 if (adapter->sec_chan_offset) {
1075                         ht_info->ht_oper.ht_param = adapter->sec_chan_offset;
1076                         ht_info->ht_oper.ht_param |=
1077                                         IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
1078                 }
1079                 ht_info->ht_oper.operation_mode =
1080                      cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1081                 ht_info->ht_oper.basic_set[0] = 0xff;
1082                 pos += sizeof(struct mwifiex_ie_types_htinfo);
1083                 cmd_append_size +=
1084                                 sizeof(struct mwifiex_ie_types_htinfo);
1085         }
1086 
1087         cmd->size =
1088                 cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
1089                                   + S_DS_GEN + cmd_append_size));
1090 
1091         if (adapter->adhoc_start_band == BAND_B)
1092                 tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
1093         else
1094                 tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1095 
1096         adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
1097 
1098         return 0;
1099 }
1100 
1101 
1102 
1103 
1104 
1105 
1106 
1107 
1108 
1109 
1110 
1111 
1112 
1113 
1114 
1115 
1116 
1117 int
1118 mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
1119                                struct host_cmd_ds_command *cmd,
1120                                struct mwifiex_bssdescriptor *bss_desc)
1121 {
1122         int rsn_ie_len = 0;
1123         struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
1124                 &cmd->params.adhoc_join;
1125         struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
1126         u32 cmd_append_size = 0;
1127         u16 tmp_cap;
1128         u32 i, rates_size = 0;
1129         u16 curr_pkt_filter;
1130         u8 *pos =
1131                 (u8 *) adhoc_join +
1132                 sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
1133 
1134 
1135 #define USE_G_PROTECTION        0x02
1136         if (bss_desc->erp_flags & USE_G_PROTECTION) {
1137                 curr_pkt_filter =
1138                         priv->
1139                         curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
1140 
1141                 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1142                                      HostCmd_ACT_GEN_SET, 0,
1143                                      &curr_pkt_filter, false)) {
1144                         mwifiex_dbg(priv->adapter, ERROR,
1145                                     "ADHOC_J_CMD: G Protection config failed\n");
1146                         return -1;
1147                 }
1148         }
1149 
1150         priv->attempted_bss_desc = bss_desc;
1151 
1152         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
1153 
1154         adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
1155 
1156         adhoc_join->bss_descriptor.beacon_period
1157                 = cpu_to_le16(bss_desc->beacon_period);
1158 
1159         memcpy(&adhoc_join->bss_descriptor.bssid,
1160                &bss_desc->mac_address, ETH_ALEN);
1161 
1162         memcpy(&adhoc_join->bss_descriptor.ssid,
1163                &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
1164 
1165         memcpy(&adhoc_join->bss_descriptor.phy_param_set,
1166                &bss_desc->phy_param_set,
1167                sizeof(union ieee_types_phy_param_set));
1168 
1169         memcpy(&adhoc_join->bss_descriptor.ss_param_set,
1170                &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
1171 
1172         tmp_cap = bss_desc->cap_info_bitmap;
1173 
1174         tmp_cap &= CAPINFO_MASK;
1175 
1176         mwifiex_dbg(priv->adapter, INFO,
1177                     "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
1178                     tmp_cap, CAPINFO_MASK);
1179 
1180         
1181         mwifiex_dbg(priv->adapter, INFO,
1182                     "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
1183                     adhoc_join->bss_descriptor.bssid,
1184                     adhoc_join->bss_descriptor.ssid);
1185 
1186         for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
1187                     bss_desc->supported_rates[i]; i++)
1188                 ;
1189         rates_size = i;
1190 
1191         
1192         memset(adhoc_join->bss_descriptor.data_rates, 0,
1193                sizeof(adhoc_join->bss_descriptor.data_rates));
1194         memcpy(adhoc_join->bss_descriptor.data_rates,
1195                bss_desc->supported_rates, rates_size);
1196 
1197         
1198         priv->curr_bss_params.num_of_rates = rates_size;
1199         memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
1200                rates_size);
1201 
1202         
1203         priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
1204         priv->curr_bss_params.band = (u8) bss_desc->bss_band;
1205 
1206         if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled)
1207                 tmp_cap |= WLAN_CAPABILITY_PRIVACY;
1208 
1209         if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
1210                 
1211                 chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
1212                 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
1213                 chan_tlv->header.len =
1214                         cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
1215 
1216                 memset(chan_tlv->chan_scan_param, 0x00,
1217                        sizeof(struct mwifiex_chan_scan_param_set));
1218                 chan_tlv->chan_scan_param[0].chan_number =
1219                         (bss_desc->phy_param_set.ds_param_set.current_chan);
1220                 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_J_CMD: TLV Chan=%d\n",
1221                             chan_tlv->chan_scan_param[0].chan_number);
1222 
1223                 chan_tlv->chan_scan_param[0].radio_type =
1224                         mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
1225 
1226                 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_J_CMD: TLV Band=%d\n",
1227                             chan_tlv->chan_scan_param[0].radio_type);
1228                 pos += sizeof(chan_tlv->header) +
1229                                 sizeof(struct mwifiex_chan_scan_param_set);
1230                 cmd_append_size += sizeof(chan_tlv->header) +
1231                                 sizeof(struct mwifiex_chan_scan_param_set);
1232         }
1233 
1234         if (priv->sec_info.wpa_enabled)
1235                 rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
1236         if (rsn_ie_len == -1)
1237                 return -1;
1238         cmd_append_size += rsn_ie_len;
1239 
1240         if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
1241                 cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
1242                         bss_desc, &pos);
1243 
1244         
1245         cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
1246                         MWIFIEX_VSIE_MASK_ADHOC, &pos);
1247 
1248         cmd->size = cpu_to_le16
1249                 ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
1250                         + S_DS_GEN + cmd_append_size));
1251 
1252         adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
1253 
1254         return 0;
1255 }
1256 
1257 
1258 
1259 
1260 
1261 
1262 
1263 
1264 
1265 int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1266                               struct host_cmd_ds_command *resp)
1267 {
1268         int ret = 0;
1269         struct mwifiex_adapter *adapter = priv->adapter;
1270         struct host_cmd_ds_802_11_ad_hoc_start_result *start_result =
1271                                 &resp->params.start_result;
1272         struct host_cmd_ds_802_11_ad_hoc_join_result *join_result =
1273                                 &resp->params.join_result;
1274         struct mwifiex_bssdescriptor *bss_desc;
1275         u16 cmd = le16_to_cpu(resp->command);
1276         u8 result;
1277 
1278         if (!priv->attempted_bss_desc) {
1279                 mwifiex_dbg(priv->adapter, ERROR,
1280                             "ADHOC_RESP: failed, association terminated by host\n");
1281                 goto done;
1282         }
1283 
1284         if (cmd == HostCmd_CMD_802_11_AD_HOC_START)
1285                 result = start_result->result;
1286         else
1287                 result = join_result->result;
1288 
1289         bss_desc = priv->attempted_bss_desc;
1290 
1291         
1292         if (result) {
1293                 mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n");
1294                 if (priv->media_connected)
1295                         mwifiex_reset_connect_state(priv, result, true);
1296 
1297                 memset(&priv->curr_bss_params.bss_descriptor,
1298                        0x00, sizeof(struct mwifiex_bssdescriptor));
1299 
1300                 ret = -1;
1301                 goto done;
1302         }
1303 
1304         
1305         priv->media_connected = true;
1306 
1307         if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
1308                 mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_S_RESP %s\n",
1309                             bss_desc->ssid.ssid);
1310 
1311                 
1312                 memcpy(bss_desc->mac_address,
1313                        start_result->bssid, ETH_ALEN);
1314 
1315                 priv->adhoc_state = ADHOC_STARTED;
1316         } else {
1317                 
1318 
1319 
1320 
1321                 mwifiex_dbg(priv->adapter, INFO,
1322                             "info: ADHOC_J_RESP %s\n",
1323                             bss_desc->ssid.ssid);
1324 
1325                 
1326 
1327 
1328 
1329 
1330                 memcpy(&priv->curr_bss_params.bss_descriptor,
1331                        bss_desc, sizeof(struct mwifiex_bssdescriptor));
1332 
1333                 priv->adhoc_state = ADHOC_JOINED;
1334         }
1335 
1336         mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_RESP: channel = %d\n",
1337                     priv->adhoc_channel);
1338         mwifiex_dbg(priv->adapter, INFO, "info: ADHOC_RESP: BSSID = %pM\n",
1339                     priv->curr_bss_params.bss_descriptor.mac_address);
1340 
1341         if (!netif_carrier_ok(priv->netdev))
1342                 netif_carrier_on(priv->netdev);
1343         mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
1344 
1345         mwifiex_save_curr_bcn(priv);
1346 
1347 done:
1348         
1349         if (adapter->curr_cmd->wait_q_enabled) {
1350                 if (ret)
1351                         adapter->cmd_wait_q.status = -1;
1352                 else
1353                         adapter->cmd_wait_q.status = 0;
1354 
1355         }
1356 
1357         return ret;
1358 }
1359 
1360 
1361 
1362 
1363 
1364 
1365 
1366 
1367 int mwifiex_associate(struct mwifiex_private *priv,
1368                       struct mwifiex_bssdescriptor *bss_desc)
1369 {
1370         
1371 
1372 
1373         if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
1374             (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
1375                 return -1;
1376 
1377         if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1378             !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1379             priv->adapter->config_bands & BAND_AAC)
1380                 mwifiex_set_11ac_ba_params(priv);
1381         else
1382                 mwifiex_set_ba_params(priv);
1383 
1384         
1385 
1386         priv->assoc_rsp_size = 0;
1387 
1388         return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_ASSOCIATE,
1389                                 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1390 }
1391 
1392 
1393 
1394 
1395 
1396 
1397 int
1398 mwifiex_adhoc_start(struct mwifiex_private *priv,
1399                     struct cfg80211_ssid *adhoc_ssid)
1400 {
1401         mwifiex_dbg(priv->adapter, INFO, "info: Adhoc Channel = %d\n",
1402                     priv->adhoc_channel);
1403         mwifiex_dbg(priv->adapter, INFO, "info: curr_bss_params.channel = %d\n",
1404                     priv->curr_bss_params.bss_descriptor.channel);
1405         mwifiex_dbg(priv->adapter, INFO, "info: curr_bss_params.band = %d\n",
1406                     priv->curr_bss_params.band);
1407 
1408         if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1409             priv->adapter->config_bands & BAND_AAC)
1410                 mwifiex_set_11ac_ba_params(priv);
1411         else
1412                 mwifiex_set_ba_params(priv);
1413 
1414         return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_START,
1415                                 HostCmd_ACT_GEN_SET, 0, adhoc_ssid, true);
1416 }
1417 
1418 
1419 
1420 
1421 
1422 
1423 
1424 int mwifiex_adhoc_join(struct mwifiex_private *priv,
1425                        struct mwifiex_bssdescriptor *bss_desc)
1426 {
1427         mwifiex_dbg(priv->adapter, INFO,
1428                     "info: adhoc join: curr_bss ssid =%s\n",
1429                     priv->curr_bss_params.bss_descriptor.ssid.ssid);
1430         mwifiex_dbg(priv->adapter, INFO,
1431                     "info: adhoc join: curr_bss ssid_len =%u\n",
1432                     priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
1433         mwifiex_dbg(priv->adapter, INFO, "info: adhoc join: ssid =%s\n",
1434                     bss_desc->ssid.ssid);
1435         mwifiex_dbg(priv->adapter, INFO, "info: adhoc join: ssid_len =%u\n",
1436                     bss_desc->ssid.ssid_len);
1437 
1438         
1439         if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
1440             !mwifiex_ssid_cmp(&bss_desc->ssid,
1441                               &priv->curr_bss_params.bss_descriptor.ssid) &&
1442             (priv->curr_bss_params.bss_descriptor.bss_mode ==
1443                                                         NL80211_IFTYPE_ADHOC)) {
1444                 mwifiex_dbg(priv->adapter, INFO,
1445                             "info: ADHOC_J_CMD: new ad-hoc SSID\t"
1446                             "is the same as current; not attempting to re-join\n");
1447                 return -1;
1448         }
1449 
1450         if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info) &&
1451             !bss_desc->disable_11n && !bss_desc->disable_11ac &&
1452             priv->adapter->config_bands & BAND_AAC)
1453                 mwifiex_set_11ac_ba_params(priv);
1454         else
1455                 mwifiex_set_ba_params(priv);
1456 
1457         mwifiex_dbg(priv->adapter, INFO,
1458                     "info: curr_bss_params.channel = %d\n",
1459                     priv->curr_bss_params.bss_descriptor.channel);
1460         mwifiex_dbg(priv->adapter, INFO,
1461                     "info: curr_bss_params.band = %c\n",
1462                     priv->curr_bss_params.band);
1463 
1464         return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
1465                                 HostCmd_ACT_GEN_SET, 0, bss_desc, true);
1466 }
1467 
1468 
1469 
1470 
1471 
1472 static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1473 {
1474         u8 mac_address[ETH_ALEN];
1475         int ret;
1476 
1477         if (!mac || is_zero_ether_addr(mac))
1478                 memcpy(mac_address,
1479                        priv->curr_bss_params.bss_descriptor.mac_address,
1480                        ETH_ALEN);
1481         else
1482                 memcpy(mac_address, mac, ETH_ALEN);
1483 
1484         ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
1485                                HostCmd_ACT_GEN_SET, 0, mac_address, true);
1486 
1487         return ret;
1488 }
1489 
1490 
1491 
1492 
1493 
1494 
1495 
1496 
1497 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
1498 {
1499         int ret = 0;
1500 
1501         if (!priv->media_connected)
1502                 return 0;
1503 
1504         switch (priv->bss_mode) {
1505         case NL80211_IFTYPE_STATION:
1506         case NL80211_IFTYPE_P2P_CLIENT:
1507                 ret = mwifiex_deauthenticate_infra(priv, mac);
1508                 if (ret)
1509                         cfg80211_disconnected(priv->netdev, 0, NULL, 0,
1510                                               true, GFP_KERNEL);
1511                 break;
1512         case NL80211_IFTYPE_ADHOC:
1513                 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
1514                                         HostCmd_ACT_GEN_SET, 0, NULL, true);
1515         case NL80211_IFTYPE_AP:
1516                 return mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1517                                         HostCmd_ACT_GEN_SET, 0, NULL, true);
1518         default:
1519                 break;
1520         }
1521 
1522         return ret;
1523 }
1524 
1525 
1526 void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter)
1527 {
1528         struct mwifiex_private *priv;
1529         int i;
1530 
1531         for (i = 0; i < adapter->priv_num; i++) {
1532                 priv = adapter->priv[i];
1533                 if (priv)
1534                         mwifiex_deauthenticate(priv, NULL);
1535         }
1536 }
1537 EXPORT_SYMBOL_GPL(mwifiex_deauthenticate_all);
1538 
1539 
1540 
1541 
1542 u8
1543 mwifiex_band_to_radio_type(u8 band)
1544 {
1545         switch (band) {
1546         case BAND_A:
1547         case BAND_AN:
1548         case BAND_A | BAND_AN:
1549         case BAND_A | BAND_AN | BAND_AAC:
1550                 return HostCmd_SCAN_RADIO_TYPE_A;
1551         case BAND_B:
1552         case BAND_G:
1553         case BAND_B | BAND_G:
1554         default:
1555                 return HostCmd_SCAN_RADIO_TYPE_BG;
1556         }
1557 }