diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/sta_cmd.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_cmd.c | 471 |
1 files changed, 426 insertions, 45 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 9208a8816b80..e3cac1495cc7 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -185,6 +185,13 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
185 | i++) | 185 | i++) |
186 | rate_scope->ht_mcs_rate_bitmap[i] = | 186 | rate_scope->ht_mcs_rate_bitmap[i] = |
187 | cpu_to_le16(pbitmap_rates[2 + i]); | 187 | cpu_to_le16(pbitmap_rates[2 + i]); |
188 | if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) { | ||
189 | for (i = 0; | ||
190 | i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap); | ||
191 | i++) | ||
192 | rate_scope->vht_mcs_rate_bitmap[i] = | ||
193 | cpu_to_le16(pbitmap_rates[10 + i]); | ||
194 | } | ||
188 | } else { | 195 | } else { |
189 | rate_scope->hr_dsss_rate_bitmap = | 196 | rate_scope->hr_dsss_rate_bitmap = |
190 | cpu_to_le16(priv->bitmap_rates[0]); | 197 | cpu_to_le16(priv->bitmap_rates[0]); |
@@ -195,6 +202,13 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
195 | i++) | 202 | i++) |
196 | rate_scope->ht_mcs_rate_bitmap[i] = | 203 | rate_scope->ht_mcs_rate_bitmap[i] = |
197 | cpu_to_le16(priv->bitmap_rates[2 + i]); | 204 | cpu_to_le16(priv->bitmap_rates[2 + i]); |
205 | if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) { | ||
206 | for (i = 0; | ||
207 | i < ARRAY_SIZE(rate_scope->vht_mcs_rate_bitmap); | ||
208 | i++) | ||
209 | rate_scope->vht_mcs_rate_bitmap[i] = | ||
210 | cpu_to_le16(priv->bitmap_rates[10 + i]); | ||
211 | } | ||
198 | } | 212 | } |
199 | 213 | ||
200 | rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + | 214 | rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + |
@@ -532,8 +546,228 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
532 | return 0; | 546 | return 0; |
533 | } | 547 | } |
534 | 548 | ||
549 | /* This function populates key material v2 command | ||
550 | * to set network key for AES & CMAC AES. | ||
551 | */ | ||
552 | static int mwifiex_set_aes_key_v2(struct mwifiex_private *priv, | ||
553 | struct host_cmd_ds_command *cmd, | ||
554 | struct mwifiex_ds_encrypt_key *enc_key, | ||
555 | struct host_cmd_ds_802_11_key_material_v2 *km) | ||
556 | { | ||
557 | struct mwifiex_adapter *adapter = priv->adapter; | ||
558 | u16 size, len = KEY_PARAMS_FIXED_LEN; | ||
559 | |||
560 | if (enc_key->is_igtk_key) { | ||
561 | dev_dbg(adapter->dev, "%s: Set CMAC AES Key\n", __func__); | ||
562 | if (enc_key->is_rx_seq_valid) | ||
563 | memcpy(km->key_param_set.key_params.cmac_aes.ipn, | ||
564 | enc_key->pn, enc_key->pn_len); | ||
565 | km->key_param_set.key_info &= cpu_to_le16(~KEY_MCAST); | ||
566 | km->key_param_set.key_info |= cpu_to_le16(KEY_IGTK); | ||
567 | km->key_param_set.key_type = KEY_TYPE_ID_AES_CMAC; | ||
568 | km->key_param_set.key_params.cmac_aes.key_len = | ||
569 | cpu_to_le16(enc_key->key_len); | ||
570 | memcpy(km->key_param_set.key_params.cmac_aes.key, | ||
571 | enc_key->key_material, enc_key->key_len); | ||
572 | len += sizeof(struct mwifiex_cmac_aes_param); | ||
573 | } else { | ||
574 | dev_dbg(adapter->dev, "%s: Set AES Key\n", __func__); | ||
575 | if (enc_key->is_rx_seq_valid) | ||
576 | memcpy(km->key_param_set.key_params.aes.pn, | ||
577 | enc_key->pn, enc_key->pn_len); | ||
578 | km->key_param_set.key_type = KEY_TYPE_ID_AES; | ||
579 | km->key_param_set.key_params.aes.key_len = | ||
580 | cpu_to_le16(enc_key->key_len); | ||
581 | memcpy(km->key_param_set.key_params.aes.key, | ||
582 | enc_key->key_material, enc_key->key_len); | ||
583 | len += sizeof(struct mwifiex_aes_param); | ||
584 | } | ||
585 | |||
586 | km->key_param_set.len = cpu_to_le16(len); | ||
587 | size = len + sizeof(struct mwifiex_ie_types_header) + | ||
588 | sizeof(km->action) + S_DS_GEN; | ||
589 | cmd->size = cpu_to_le16(size); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | /* This function prepares command to set/get/reset network key(s). | ||
595 | * This function prepares key material command for V2 format. | ||
596 | * Preparation includes - | ||
597 | * - Setting command ID, action and proper size | ||
598 | * - Setting WEP keys, WAPI keys or WPA keys along with required | ||
599 | * encryption (TKIP, AES) (as required) | ||
600 | * - Ensuring correct endian-ness | ||
601 | */ | ||
602 | static int | ||
603 | mwifiex_cmd_802_11_key_material_v2(struct mwifiex_private *priv, | ||
604 | struct host_cmd_ds_command *cmd, | ||
605 | u16 cmd_action, u32 cmd_oid, | ||
606 | struct mwifiex_ds_encrypt_key *enc_key) | ||
607 | { | ||
608 | struct mwifiex_adapter *adapter = priv->adapter; | ||
609 | u8 *mac = enc_key->mac_addr; | ||
610 | u16 key_info, len = KEY_PARAMS_FIXED_LEN; | ||
611 | struct host_cmd_ds_802_11_key_material_v2 *km = | ||
612 | &cmd->params.key_material_v2; | ||
613 | |||
614 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL); | ||
615 | km->action = cpu_to_le16(cmd_action); | ||
616 | |||
617 | if (cmd_action == HostCmd_ACT_GEN_GET) { | ||
618 | dev_dbg(adapter->dev, "%s: Get key\n", __func__); | ||
619 | km->key_param_set.key_idx = | ||
620 | enc_key->key_index & KEY_INDEX_MASK; | ||
621 | km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2); | ||
622 | km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN); | ||
623 | memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN); | ||
624 | |||
625 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | ||
626 | key_info = KEY_UNICAST; | ||
627 | else | ||
628 | key_info = KEY_MCAST; | ||
629 | |||
630 | if (enc_key->is_igtk_key) | ||
631 | key_info |= KEY_IGTK; | ||
632 | |||
633 | km->key_param_set.key_info = cpu_to_le16(key_info); | ||
634 | |||
635 | cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) + | ||
636 | S_DS_GEN + KEY_PARAMS_FIXED_LEN + | ||
637 | sizeof(km->action)); | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | memset(&km->key_param_set, 0, | ||
642 | sizeof(struct mwifiex_ie_type_key_param_set_v2)); | ||
643 | |||
644 | if (enc_key->key_disable) { | ||
645 | dev_dbg(adapter->dev, "%s: Remove key\n", __func__); | ||
646 | km->action = cpu_to_le16(HostCmd_ACT_GEN_REMOVE); | ||
647 | km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2); | ||
648 | km->key_param_set.len = cpu_to_le16(KEY_PARAMS_FIXED_LEN); | ||
649 | km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK; | ||
650 | key_info = KEY_MCAST | KEY_UNICAST; | ||
651 | km->key_param_set.key_info = cpu_to_le16(key_info); | ||
652 | memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN); | ||
653 | cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) + | ||
654 | S_DS_GEN + KEY_PARAMS_FIXED_LEN + | ||
655 | sizeof(km->action)); | ||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | km->action = cpu_to_le16(HostCmd_ACT_GEN_SET); | ||
660 | km->key_param_set.key_idx = enc_key->key_index & KEY_INDEX_MASK; | ||
661 | km->key_param_set.type = cpu_to_le16(TLV_TYPE_KEY_PARAM_V2); | ||
662 | key_info = KEY_ENABLED; | ||
663 | memcpy(km->key_param_set.mac_addr, mac, ETH_ALEN); | ||
664 | |||
665 | if (enc_key->key_len <= WLAN_KEY_LEN_WEP104) { | ||
666 | dev_dbg(adapter->dev, "%s: Set WEP Key\n", __func__); | ||
667 | len += sizeof(struct mwifiex_wep_param); | ||
668 | km->key_param_set.len = cpu_to_le16(len); | ||
669 | km->key_param_set.key_type = KEY_TYPE_ID_WEP; | ||
670 | |||
671 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { | ||
672 | key_info |= KEY_MCAST | KEY_UNICAST; | ||
673 | } else { | ||
674 | if (enc_key->is_current_wep_key) { | ||
675 | key_info |= KEY_MCAST | KEY_UNICAST; | ||
676 | if (km->key_param_set.key_idx == | ||
677 | (priv->wep_key_curr_index & KEY_INDEX_MASK)) | ||
678 | key_info |= KEY_DEFAULT; | ||
679 | } else { | ||
680 | if (mac) { | ||
681 | if (is_broadcast_ether_addr(mac)) | ||
682 | key_info |= KEY_MCAST; | ||
683 | else | ||
684 | key_info |= KEY_UNICAST | | ||
685 | KEY_DEFAULT; | ||
686 | } else { | ||
687 | key_info |= KEY_MCAST; | ||
688 | } | ||
689 | } | ||
690 | } | ||
691 | km->key_param_set.key_info = cpu_to_le16(key_info); | ||
692 | |||
693 | km->key_param_set.key_params.wep.key_len = | ||
694 | cpu_to_le16(enc_key->key_len); | ||
695 | memcpy(km->key_param_set.key_params.wep.key, | ||
696 | enc_key->key_material, enc_key->key_len); | ||
697 | |||
698 | cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) + | ||
699 | len + sizeof(km->action) + S_DS_GEN); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | if (is_broadcast_ether_addr(mac)) | ||
704 | key_info |= KEY_MCAST | KEY_RX_KEY; | ||
705 | else | ||
706 | key_info |= KEY_UNICAST | KEY_TX_KEY | KEY_RX_KEY; | ||
707 | |||
708 | if (enc_key->is_wapi_key) { | ||
709 | dev_dbg(adapter->dev, "%s: Set WAPI Key\n", __func__); | ||
710 | km->key_param_set.key_type = KEY_TYPE_ID_WAPI; | ||
711 | memcpy(km->key_param_set.key_params.wapi.pn, enc_key->pn, | ||
712 | PN_LEN); | ||
713 | km->key_param_set.key_params.wapi.key_len = | ||
714 | cpu_to_le16(enc_key->key_len); | ||
715 | memcpy(km->key_param_set.key_params.wapi.key, | ||
716 | enc_key->key_material, enc_key->key_len); | ||
717 | if (is_broadcast_ether_addr(mac)) | ||
718 | priv->sec_info.wapi_key_on = true; | ||
719 | |||
720 | if (!priv->sec_info.wapi_key_on) | ||
721 | key_info |= KEY_DEFAULT; | ||
722 | km->key_param_set.key_info = cpu_to_le16(key_info); | ||
723 | |||
724 | len += sizeof(struct mwifiex_wapi_param); | ||
725 | km->key_param_set.len = cpu_to_le16(len); | ||
726 | cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) + | ||
727 | len + sizeof(km->action) + S_DS_GEN); | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | ||
732 | key_info |= KEY_DEFAULT; | ||
733 | /* Enable unicast bit for WPA-NONE/ADHOC_AES */ | ||
734 | if (!priv->sec_info.wpa2_enabled && | ||
735 | !is_broadcast_ether_addr(mac)) | ||
736 | key_info |= KEY_UNICAST; | ||
737 | } else { | ||
738 | /* Enable default key for WPA/WPA2 */ | ||
739 | if (!priv->wpa_is_gtk_set) | ||
740 | key_info |= KEY_DEFAULT; | ||
741 | } | ||
742 | |||
743 | km->key_param_set.key_info = cpu_to_le16(key_info); | ||
744 | |||
745 | if (enc_key->key_len == WLAN_KEY_LEN_CCMP) | ||
746 | return mwifiex_set_aes_key_v2(priv, cmd, enc_key, km); | ||
747 | |||
748 | if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { | ||
749 | dev_dbg(adapter->dev, "%s: Set TKIP Key\n", __func__); | ||
750 | if (enc_key->is_rx_seq_valid) | ||
751 | memcpy(km->key_param_set.key_params.tkip.pn, | ||
752 | enc_key->pn, enc_key->pn_len); | ||
753 | km->key_param_set.key_type = KEY_TYPE_ID_TKIP; | ||
754 | km->key_param_set.key_params.tkip.key_len = | ||
755 | cpu_to_le16(enc_key->key_len); | ||
756 | memcpy(km->key_param_set.key_params.tkip.key, | ||
757 | enc_key->key_material, enc_key->key_len); | ||
758 | |||
759 | len += sizeof(struct mwifiex_tkip_param); | ||
760 | km->key_param_set.len = cpu_to_le16(len); | ||
761 | cmd->size = cpu_to_le16(sizeof(struct mwifiex_ie_types_header) + | ||
762 | len + sizeof(km->action) + S_DS_GEN); | ||
763 | } | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
535 | /* | 768 | /* |
536 | * This function prepares command to set/get/reset network key(s). | 769 | * This function prepares command to set/get/reset network key(s). |
770 | * This function prepares key material command for V1 format. | ||
537 | * | 771 | * |
538 | * Preparation includes - | 772 | * Preparation includes - |
539 | * - Setting command ID, action and proper size | 773 | * - Setting command ID, action and proper size |
@@ -542,10 +776,10 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
542 | * - Ensuring correct endian-ness | 776 | * - Ensuring correct endian-ness |
543 | */ | 777 | */ |
544 | static int | 778 | static int |
545 | mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | 779 | mwifiex_cmd_802_11_key_material_v1(struct mwifiex_private *priv, |
546 | struct host_cmd_ds_command *cmd, | 780 | struct host_cmd_ds_command *cmd, |
547 | u16 cmd_action, u32 cmd_oid, | 781 | u16 cmd_action, u32 cmd_oid, |
548 | struct mwifiex_ds_encrypt_key *enc_key) | 782 | struct mwifiex_ds_encrypt_key *enc_key) |
549 | { | 783 | { |
550 | struct host_cmd_ds_802_11_key_material *key_material = | 784 | struct host_cmd_ds_802_11_key_material *key_material = |
551 | &cmd->params.key_material; | 785 | &cmd->params.key_material; |
@@ -724,6 +958,24 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
724 | return ret; | 958 | return ret; |
725 | } | 959 | } |
726 | 960 | ||
961 | /* Wrapper function for setting network key depending upon FW KEY API version */ | ||
962 | static int | ||
963 | mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | ||
964 | struct host_cmd_ds_command *cmd, | ||
965 | u16 cmd_action, u32 cmd_oid, | ||
966 | struct mwifiex_ds_encrypt_key *enc_key) | ||
967 | { | ||
968 | if (priv->adapter->fw_key_api_major_ver == FW_KEY_API_VER_MAJOR_V2) | ||
969 | return mwifiex_cmd_802_11_key_material_v2(priv, cmd, | ||
970 | cmd_action, cmd_oid, | ||
971 | enc_key); | ||
972 | |||
973 | else | ||
974 | return mwifiex_cmd_802_11_key_material_v1(priv, cmd, | ||
975 | cmd_action, cmd_oid, | ||
976 | enc_key); | ||
977 | } | ||
978 | |||
727 | /* | 979 | /* |
728 | * This function prepares command to set/get 11d domain information. | 980 | * This function prepares command to set/get 11d domain information. |
729 | * | 981 | * |
@@ -1173,9 +1425,9 @@ int mwifiex_dnld_dt_cfgdata(struct mwifiex_private *priv, | |||
1173 | /* property header is 6 bytes, data must fit in cmd buffer */ | 1425 | /* property header is 6 bytes, data must fit in cmd buffer */ |
1174 | if (prop && prop->value && prop->length > 6 && | 1426 | if (prop && prop->value && prop->length > 6 && |
1175 | prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) { | 1427 | prop->length <= MWIFIEX_SIZE_OF_CMD_BUFFER - S_DS_GEN) { |
1176 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, | 1428 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA, |
1177 | HostCmd_ACT_GEN_SET, 0, | 1429 | HostCmd_ACT_GEN_SET, 0, |
1178 | prop); | 1430 | prop, true); |
1179 | if (ret) | 1431 | if (ret) |
1180 | return ret; | 1432 | return ret; |
1181 | } | 1433 | } |
@@ -1280,6 +1532,127 @@ mwifiex_cmd_coalesce_cfg(struct mwifiex_private *priv, | |||
1280 | return 0; | 1532 | return 0; |
1281 | } | 1533 | } |
1282 | 1534 | ||
1535 | static int | ||
1536 | mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, | ||
1537 | struct host_cmd_ds_command *cmd, | ||
1538 | void *data_buf) | ||
1539 | { | ||
1540 | struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper; | ||
1541 | struct mwifiex_ds_tdls_oper *oper = data_buf; | ||
1542 | struct mwifiex_sta_node *sta_ptr; | ||
1543 | struct host_cmd_tlv_rates *tlv_rates; | ||
1544 | struct mwifiex_ie_types_htcap *ht_capab; | ||
1545 | struct mwifiex_ie_types_qos_info *wmm_qos_info; | ||
1546 | struct mwifiex_ie_types_extcap *extcap; | ||
1547 | struct mwifiex_ie_types_vhtcap *vht_capab; | ||
1548 | struct mwifiex_ie_types_aid *aid; | ||
1549 | u8 *pos, qos_info; | ||
1550 | u16 config_len = 0; | ||
1551 | struct station_parameters *params = priv->sta_params; | ||
1552 | |||
1553 | cmd->command = cpu_to_le16(HostCmd_CMD_TDLS_OPER); | ||
1554 | cmd->size = cpu_to_le16(S_DS_GEN); | ||
1555 | le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_tdls_oper)); | ||
1556 | |||
1557 | tdls_oper->reason = 0; | ||
1558 | memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN); | ||
1559 | sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac); | ||
1560 | |||
1561 | pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper); | ||
1562 | |||
1563 | switch (oper->tdls_action) { | ||
1564 | case MWIFIEX_TDLS_DISABLE_LINK: | ||
1565 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE); | ||
1566 | break; | ||
1567 | case MWIFIEX_TDLS_CREATE_LINK: | ||
1568 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE); | ||
1569 | break; | ||
1570 | case MWIFIEX_TDLS_CONFIG_LINK: | ||
1571 | tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CONFIG); | ||
1572 | |||
1573 | if (!params) { | ||
1574 | dev_err(priv->adapter->dev, | ||
1575 | "TDLS config params not available for %pM\n", | ||
1576 | oper->peer_mac); | ||
1577 | return -ENODATA; | ||
1578 | } | ||
1579 | |||
1580 | *(__le16 *)pos = cpu_to_le16(params->capability); | ||
1581 | config_len += sizeof(params->capability); | ||
1582 | |||
1583 | qos_info = params->uapsd_queues | (params->max_sp << 5); | ||
1584 | wmm_qos_info = (struct mwifiex_ie_types_qos_info *)(pos + | ||
1585 | config_len); | ||
1586 | wmm_qos_info->header.type = cpu_to_le16(WLAN_EID_QOS_CAPA); | ||
1587 | wmm_qos_info->header.len = cpu_to_le16(sizeof(qos_info)); | ||
1588 | wmm_qos_info->qos_info = qos_info; | ||
1589 | config_len += sizeof(struct mwifiex_ie_types_qos_info); | ||
1590 | |||
1591 | if (params->ht_capa) { | ||
1592 | ht_capab = (struct mwifiex_ie_types_htcap *)(pos + | ||
1593 | config_len); | ||
1594 | ht_capab->header.type = | ||
1595 | cpu_to_le16(WLAN_EID_HT_CAPABILITY); | ||
1596 | ht_capab->header.len = | ||
1597 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | ||
1598 | memcpy(&ht_capab->ht_cap, params->ht_capa, | ||
1599 | sizeof(struct ieee80211_ht_cap)); | ||
1600 | config_len += sizeof(struct mwifiex_ie_types_htcap); | ||
1601 | } | ||
1602 | |||
1603 | if (params->supported_rates && params->supported_rates_len) { | ||
1604 | tlv_rates = (struct host_cmd_tlv_rates *)(pos + | ||
1605 | config_len); | ||
1606 | tlv_rates->header.type = | ||
1607 | cpu_to_le16(WLAN_EID_SUPP_RATES); | ||
1608 | tlv_rates->header.len = | ||
1609 | cpu_to_le16(params->supported_rates_len); | ||
1610 | memcpy(tlv_rates->rates, params->supported_rates, | ||
1611 | params->supported_rates_len); | ||
1612 | config_len += sizeof(struct host_cmd_tlv_rates) + | ||
1613 | params->supported_rates_len; | ||
1614 | } | ||
1615 | |||
1616 | if (params->ext_capab && params->ext_capab_len) { | ||
1617 | extcap = (struct mwifiex_ie_types_extcap *)(pos + | ||
1618 | config_len); | ||
1619 | extcap->header.type = | ||
1620 | cpu_to_le16(WLAN_EID_EXT_CAPABILITY); | ||
1621 | extcap->header.len = cpu_to_le16(params->ext_capab_len); | ||
1622 | memcpy(extcap->ext_capab, params->ext_capab, | ||
1623 | params->ext_capab_len); | ||
1624 | config_len += sizeof(struct mwifiex_ie_types_extcap) + | ||
1625 | params->ext_capab_len; | ||
1626 | } | ||
1627 | if (params->vht_capa) { | ||
1628 | vht_capab = (struct mwifiex_ie_types_vhtcap *)(pos + | ||
1629 | config_len); | ||
1630 | vht_capab->header.type = | ||
1631 | cpu_to_le16(WLAN_EID_VHT_CAPABILITY); | ||
1632 | vht_capab->header.len = | ||
1633 | cpu_to_le16(sizeof(struct ieee80211_vht_cap)); | ||
1634 | memcpy(&vht_capab->vht_cap, params->vht_capa, | ||
1635 | sizeof(struct ieee80211_vht_cap)); | ||
1636 | config_len += sizeof(struct mwifiex_ie_types_vhtcap); | ||
1637 | } | ||
1638 | if (params->aid) { | ||
1639 | aid = (struct mwifiex_ie_types_aid *)(pos + config_len); | ||
1640 | aid->header.type = cpu_to_le16(WLAN_EID_AID); | ||
1641 | aid->header.len = cpu_to_le16(sizeof(params->aid)); | ||
1642 | aid->aid = cpu_to_le16(params->aid); | ||
1643 | config_len += sizeof(struct mwifiex_ie_types_aid); | ||
1644 | } | ||
1645 | |||
1646 | break; | ||
1647 | default: | ||
1648 | dev_err(priv->adapter->dev, "Unknown TDLS operation\n"); | ||
1649 | return -ENOTSUPP; | ||
1650 | } | ||
1651 | |||
1652 | le16_add_cpu(&cmd->size, config_len); | ||
1653 | |||
1654 | return 0; | ||
1655 | } | ||
1283 | /* | 1656 | /* |
1284 | * This function prepares the commands before sending them to the firmware. | 1657 | * This function prepares the commands before sending them to the firmware. |
1285 | * | 1658 | * |
@@ -1472,6 +1845,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1472 | ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, | 1845 | ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action, |
1473 | data_buf); | 1846 | data_buf); |
1474 | break; | 1847 | break; |
1848 | case HostCmd_CMD_802_11_SCAN_EXT: | ||
1849 | ret = mwifiex_cmd_802_11_scan_ext(priv, cmd_ptr, data_buf); | ||
1850 | break; | ||
1475 | case HostCmd_CMD_MAC_REG_ACCESS: | 1851 | case HostCmd_CMD_MAC_REG_ACCESS: |
1476 | case HostCmd_CMD_BBP_REG_ACCESS: | 1852 | case HostCmd_CMD_BBP_REG_ACCESS: |
1477 | case HostCmd_CMD_RF_REG_ACCESS: | 1853 | case HostCmd_CMD_RF_REG_ACCESS: |
@@ -1507,6 +1883,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1507 | ret = mwifiex_cmd_coalesce_cfg(priv, cmd_ptr, cmd_action, | 1883 | ret = mwifiex_cmd_coalesce_cfg(priv, cmd_ptr, cmd_action, |
1508 | data_buf); | 1884 | data_buf); |
1509 | break; | 1885 | break; |
1886 | case HostCmd_CMD_TDLS_OPER: | ||
1887 | ret = mwifiex_cmd_tdls_oper(priv, cmd_ptr, data_buf); | ||
1888 | break; | ||
1510 | default: | 1889 | default: |
1511 | dev_err(priv->adapter->dev, | 1890 | dev_err(priv->adapter->dev, |
1512 | "PREP_CMD: unknown cmd- %#x\n", cmd_no); | 1891 | "PREP_CMD: unknown cmd- %#x\n", cmd_no); |
@@ -1547,15 +1926,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1547 | 1926 | ||
1548 | if (first_sta) { | 1927 | if (first_sta) { |
1549 | if (priv->adapter->iface_type == MWIFIEX_PCIE) { | 1928 | if (priv->adapter->iface_type == MWIFIEX_PCIE) { |
1550 | ret = mwifiex_send_cmd_sync(priv, | 1929 | ret = mwifiex_send_cmd(priv, |
1551 | HostCmd_CMD_PCIE_DESC_DETAILS, | 1930 | HostCmd_CMD_PCIE_DESC_DETAILS, |
1552 | HostCmd_ACT_GEN_SET, 0, NULL); | 1931 | HostCmd_ACT_GEN_SET, 0, NULL, |
1932 | true); | ||
1553 | if (ret) | 1933 | if (ret) |
1554 | return -1; | 1934 | return -1; |
1555 | } | 1935 | } |
1556 | 1936 | ||
1557 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_FUNC_INIT, | 1937 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_FUNC_INIT, |
1558 | HostCmd_ACT_GEN_SET, 0, NULL); | 1938 | HostCmd_ACT_GEN_SET, 0, NULL, true); |
1559 | if (ret) | 1939 | if (ret) |
1560 | return -1; | 1940 | return -1; |
1561 | 1941 | ||
@@ -1573,55 +1953,57 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1573 | } | 1953 | } |
1574 | 1954 | ||
1575 | if (adapter->cal_data) { | 1955 | if (adapter->cal_data) { |
1576 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA, | 1956 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_CFG_DATA, |
1577 | HostCmd_ACT_GEN_SET, 0, NULL); | 1957 | HostCmd_ACT_GEN_SET, 0, NULL, |
1958 | true); | ||
1578 | if (ret) | 1959 | if (ret) |
1579 | return -1; | 1960 | return -1; |
1580 | } | 1961 | } |
1581 | 1962 | ||
1582 | /* Read MAC address from HW */ | 1963 | /* Read MAC address from HW */ |
1583 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC, | 1964 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_GET_HW_SPEC, |
1584 | HostCmd_ACT_GEN_GET, 0, NULL); | 1965 | HostCmd_ACT_GEN_GET, 0, NULL, true); |
1585 | if (ret) | 1966 | if (ret) |
1586 | return -1; | 1967 | return -1; |
1587 | 1968 | ||
1588 | /* Reconfigure tx buf size */ | 1969 | /* Reconfigure tx buf size */ |
1589 | ret = mwifiex_send_cmd_sync(priv, | 1970 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, |
1590 | HostCmd_CMD_RECONFIGURE_TX_BUFF, | 1971 | HostCmd_ACT_GEN_SET, 0, |
1591 | HostCmd_ACT_GEN_SET, 0, | 1972 | &priv->adapter->tx_buf_size, true); |
1592 | &priv->adapter->tx_buf_size); | ||
1593 | if (ret) | 1973 | if (ret) |
1594 | return -1; | 1974 | return -1; |
1595 | 1975 | ||
1596 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { | 1976 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { |
1597 | /* Enable IEEE PS by default */ | 1977 | /* Enable IEEE PS by default */ |
1598 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; | 1978 | priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP; |
1599 | ret = mwifiex_send_cmd_sync( | 1979 | ret = mwifiex_send_cmd(priv, |
1600 | priv, HostCmd_CMD_802_11_PS_MODE_ENH, | 1980 | HostCmd_CMD_802_11_PS_MODE_ENH, |
1601 | EN_AUTO_PS, BITMAP_STA_PS, NULL); | 1981 | EN_AUTO_PS, BITMAP_STA_PS, NULL, |
1982 | true); | ||
1602 | if (ret) | 1983 | if (ret) |
1603 | return -1; | 1984 | return -1; |
1604 | } | 1985 | } |
1605 | } | 1986 | } |
1606 | 1987 | ||
1607 | /* get tx rate */ | 1988 | /* get tx rate */ |
1608 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, | 1989 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_TX_RATE_CFG, |
1609 | HostCmd_ACT_GEN_GET, 0, NULL); | 1990 | HostCmd_ACT_GEN_GET, 0, NULL, true); |
1610 | if (ret) | 1991 | if (ret) |
1611 | return -1; | 1992 | return -1; |
1612 | priv->data_rate = 0; | 1993 | priv->data_rate = 0; |
1613 | 1994 | ||
1614 | /* get tx power */ | 1995 | /* get tx power */ |
1615 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_TX_PWR, | 1996 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR, |
1616 | HostCmd_ACT_GEN_GET, 0, NULL); | 1997 | HostCmd_ACT_GEN_GET, 0, NULL, true); |
1617 | if (ret) | 1998 | if (ret) |
1618 | return -1; | 1999 | return -1; |
1619 | 2000 | ||
1620 | if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { | 2001 | if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { |
1621 | /* set ibss coalescing_status */ | 2002 | /* set ibss coalescing_status */ |
1622 | ret = mwifiex_send_cmd_sync( | 2003 | ret = mwifiex_send_cmd( |
1623 | priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, | 2004 | priv, |
1624 | HostCmd_ACT_GEN_SET, 0, &enable); | 2005 | HostCmd_CMD_802_11_IBSS_COALESCING_STATUS, |
2006 | HostCmd_ACT_GEN_SET, 0, &enable, true); | ||
1625 | if (ret) | 2007 | if (ret) |
1626 | return -1; | 2008 | return -1; |
1627 | } | 2009 | } |
@@ -1629,16 +2011,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1629 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); | 2011 | memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); |
1630 | amsdu_aggr_ctrl.enable = true; | 2012 | amsdu_aggr_ctrl.enable = true; |
1631 | /* Send request to firmware */ | 2013 | /* Send request to firmware */ |
1632 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, | 2014 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_AMSDU_AGGR_CTRL, |
1633 | HostCmd_ACT_GEN_SET, 0, | 2015 | HostCmd_ACT_GEN_SET, 0, |
1634 | &amsdu_aggr_ctrl); | 2016 | &amsdu_aggr_ctrl, true); |
1635 | if (ret) | 2017 | if (ret) |
1636 | return -1; | 2018 | return -1; |
1637 | /* MAC Control must be the last command in init_fw */ | 2019 | /* MAC Control must be the last command in init_fw */ |
1638 | /* set MAC Control */ | 2020 | /* set MAC Control */ |
1639 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, | 2021 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL, |
1640 | HostCmd_ACT_GEN_SET, 0, | 2022 | HostCmd_ACT_GEN_SET, 0, |
1641 | &priv->curr_pkt_filter); | 2023 | &priv->curr_pkt_filter, true); |
1642 | if (ret) | 2024 | if (ret) |
1643 | return -1; | 2025 | return -1; |
1644 | 2026 | ||
@@ -1647,10 +2029,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1647 | /* Enable auto deep sleep */ | 2029 | /* Enable auto deep sleep */ |
1648 | auto_ds.auto_ds = DEEP_SLEEP_ON; | 2030 | auto_ds.auto_ds = DEEP_SLEEP_ON; |
1649 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; | 2031 | auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME; |
1650 | ret = mwifiex_send_cmd_sync(priv, | 2032 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH, |
1651 | HostCmd_CMD_802_11_PS_MODE_ENH, | 2033 | EN_AUTO_PS, BITMAP_AUTO_DS, |
1652 | EN_AUTO_PS, BITMAP_AUTO_DS, | 2034 | &auto_ds, true); |
1653 | &auto_ds); | ||
1654 | if (ret) | 2035 | if (ret) |
1655 | return -1; | 2036 | return -1; |
1656 | } | 2037 | } |
@@ -1658,9 +2039,9 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1658 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { | 2039 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { |
1659 | /* Send cmd to FW to enable/disable 11D function */ | 2040 | /* Send cmd to FW to enable/disable 11D function */ |
1660 | state_11d = ENABLE_11D; | 2041 | state_11d = ENABLE_11D; |
1661 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, | 2042 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, |
1662 | HostCmd_ACT_GEN_SET, DOT11D_I, | 2043 | HostCmd_ACT_GEN_SET, DOT11D_I, |
1663 | &state_11d); | 2044 | &state_11d, true); |
1664 | if (ret) | 2045 | if (ret) |
1665 | dev_err(priv->adapter->dev, | 2046 | dev_err(priv->adapter->dev, |
1666 | "11D: failed to enable 11D\n"); | 2047 | "11D: failed to enable 11D\n"); |
@@ -1673,8 +2054,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1673 | * (Short GI, Channel BW, Green field support etc.) for transmit | 2054 | * (Short GI, Channel BW, Green field support etc.) for transmit |
1674 | */ | 2055 | */ |
1675 | tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; | 2056 | tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG; |
1676 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_11N_CFG, | 2057 | ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG, |
1677 | HostCmd_ACT_GEN_SET, 0, &tx_cfg); | 2058 | HostCmd_ACT_GEN_SET, 0, &tx_cfg, true); |
1678 | 2059 | ||
1679 | ret = -EINPROGRESS; | 2060 | ret = -EINPROGRESS; |
1680 | 2061 | ||