Merge tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[deliverable/linux.git] / drivers / net / wireless / mwifiex / sta_cmd.c
index df3a33c530cf1a30f9a4058b2bb01d3b24777d0a..5d87195390f863a9492aadaa9ea1d51d6ba8ae8e 100644 (file)
@@ -551,7 +551,6 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
        struct host_cmd_tlv_mac_addr *tlv_mac;
        u16 key_param_len = 0, cmd_size;
        int ret = 0;
-       const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
        key_material->action = cpu_to_le16(cmd_action);
@@ -593,7 +592,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                        /* set 0 when re-key */
                        key_material->key_param_set.key[1] = 0;
 
-               if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
+               if (!is_broadcast_ether_addr(enc_key->mac_addr)) {
                        /* WAPI pairwise key: unicast */
                        key_material->key_param_set.key_info |=
                                cpu_to_le16(KEY_UNICAST);
@@ -610,7 +609,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                memcpy(&key_material->key_param_set.key[2],
                       enc_key->key_material, enc_key->key_len);
                memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
-                      enc_key->wapi_rxpn, WAPI_RXPN_LEN);
+                      enc_key->pn, PN_LEN);
                key_material->key_param_set.length =
                        cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
 
@@ -621,23 +620,38 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                return ret;
        }
        if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
-               dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
-               key_material->key_param_set.key_type_id =
+               if (enc_key->is_igtk_key) {
+                       dev_dbg(priv->adapter->dev, "cmd: CMAC_AES\n");
+                       key_material->key_param_set.key_type_id =
+                                       cpu_to_le16(KEY_TYPE_ID_AES_CMAC);
+                       if (cmd_oid == KEY_INFO_ENABLED)
+                               key_material->key_param_set.key_info =
+                                               cpu_to_le16(KEY_ENABLED);
+                       else
+                               key_material->key_param_set.key_info =
+                                               cpu_to_le16(!KEY_ENABLED);
+
+                       key_material->key_param_set.key_info |=
+                                                       cpu_to_le16(KEY_IGTK);
+               } else {
+                       dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
+                       key_material->key_param_set.key_type_id =
                                                cpu_to_le16(KEY_TYPE_ID_AES);
-               if (cmd_oid == KEY_INFO_ENABLED)
-                       key_material->key_param_set.key_info =
+                       if (cmd_oid == KEY_INFO_ENABLED)
+                               key_material->key_param_set.key_info =
                                                cpu_to_le16(KEY_ENABLED);
-               else
-                       key_material->key_param_set.key_info =
+                       else
+                               key_material->key_param_set.key_info =
                                                cpu_to_le16(!KEY_ENABLED);
 
-               if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
+                       if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
                                /* AES pairwise key: unicast */
-                       key_material->key_param_set.key_info |=
+                               key_material->key_param_set.key_info |=
                                                cpu_to_le16(KEY_UNICAST);
-               else            /* AES group key: multicast */
-                       key_material->key_param_set.key_info |=
+                       else    /* AES group key: multicast */
+                               key_material->key_param_set.key_info |=
                                                        cpu_to_le16(KEY_MCAST);
+               }
        } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
                dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
                key_material->key_param_set.key_type_id =
@@ -668,6 +682,24 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
                                + sizeof(struct mwifiex_ie_types_header);
 
+               if (le16_to_cpu(key_material->key_param_set.key_type_id) ==
+                                                       KEY_TYPE_ID_AES_CMAC) {
+                       struct mwifiex_cmac_param *param =
+                                       (void *)key_material->key_param_set.key;
+
+                       memcpy(param->ipn, enc_key->pn, IGTK_PN_LEN);
+                       memcpy(param->key, enc_key->key_material,
+                              WLAN_KEY_LEN_AES_CMAC);
+
+                       key_param_len = sizeof(struct mwifiex_cmac_param);
+                       key_material->key_param_set.key_len =
+                                               cpu_to_le16(key_param_len);
+                       key_param_len += KEYPARAMSET_FIXED_LEN;
+                       key_material->key_param_set.length =
+                                               cpu_to_le16(key_param_len);
+                       key_param_len += sizeof(struct mwifiex_ie_types_header);
+               }
+
                cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
                                        + key_param_len);
 
@@ -1135,6 +1167,31 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
                                    S_DS_GEN);
                ret = 0;
                break;
+       case HostCmd_CMD_MGMT_FRAME_REG:
+               cmd_ptr->command = cpu_to_le16(cmd_no);
+               cmd_ptr->params.reg_mask.action = cpu_to_le16(cmd_action);
+               cmd_ptr->params.reg_mask.mask = cpu_to_le32(*(u32 *)data_buf);
+               cmd_ptr->size =
+                       cpu_to_le16(sizeof(struct host_cmd_ds_mgmt_frame_reg) +
+                                   S_DS_GEN);
+               ret = 0;
+               break;
+       case HostCmd_CMD_REMAIN_ON_CHAN:
+               cmd_ptr->command = cpu_to_le16(cmd_no);
+               memcpy(&cmd_ptr->params, data_buf,
+                      sizeof(struct host_cmd_ds_remain_on_chan));
+               cmd_ptr->size =
+                     cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
+                                 S_DS_GEN);
+               break;
+       case HostCmd_CMD_P2P_MODE_CFG:
+               cmd_ptr->command = cpu_to_le16(cmd_no);
+               cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
+               cmd_ptr->params.mode_cfg.mode = cpu_to_le16(*(u16 *)data_buf);
+               cmd_ptr->size =
+                       cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg) +
+                                   S_DS_GEN);
+               break;
        case HostCmd_CMD_FUNC_INIT:
                if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
                        priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
@@ -1204,6 +1261,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
                else if (priv->bss_mode == NL80211_IFTYPE_STATION)
                        cmd_ptr->params.bss_mode.con_type =
                                CONNECTION_TYPE_INFRA;
+               else if (priv->bss_mode == NL80211_IFTYPE_AP)
+                       cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_AP;
                cmd_ptr->size = cpu_to_le16(sizeof(struct
                                host_cmd_ds_set_bss_mode) + S_DS_GEN);
                ret = 0;
@@ -1253,35 +1312,35 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 
        if (first_sta) {
                if (priv->adapter->iface_type == MWIFIEX_PCIE) {
-                       ret = mwifiex_send_cmd_async(priv,
+                       ret = mwifiex_send_cmd_sync(priv,
                                                HostCmd_CMD_PCIE_DESC_DETAILS,
                                                HostCmd_ACT_GEN_SET, 0, NULL);
                        if (ret)
                                return -1;
                }
 
-               ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
-                                            HostCmd_ACT_GEN_SET, 0, NULL);
+               ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_FUNC_INIT,
+                                           HostCmd_ACT_GEN_SET, 0, NULL);
                if (ret)
                        return -1;
                /* Read MAC address from HW */
-               ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC,
-                                            HostCmd_ACT_GEN_GET, 0, NULL);
+               ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
+                                           HostCmd_ACT_GEN_GET, 0, NULL);
                if (ret)
                        return -1;
 
                /* Reconfigure tx buf size */
-               ret = mwifiex_send_cmd_async(priv,
-                                            HostCmd_CMD_RECONFIGURE_TX_BUFF,
-                                            HostCmd_ACT_GEN_SET, 0,
-                                            &priv->adapter->tx_buf_size);
+               ret = mwifiex_send_cmd_sync(priv,
+                                           HostCmd_CMD_RECONFIGURE_TX_BUFF,
+                                           HostCmd_ACT_GEN_SET, 0,
+                                           &priv->adapter->tx_buf_size);
                if (ret)
                        return -1;
 
                if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
                        /* Enable IEEE PS by default */
                        priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
-                       ret = mwifiex_send_cmd_async(
+                       ret = mwifiex_send_cmd_sync(
                                        priv, HostCmd_CMD_802_11_PS_MODE_ENH,
                                        EN_AUTO_PS, BITMAP_STA_PS, NULL);
                        if (ret)
@@ -1290,21 +1349,21 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
        }
 
        /* get tx rate */
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
-                                    HostCmd_ACT_GEN_GET, 0, NULL);
+       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
+                                   HostCmd_ACT_GEN_GET, 0, NULL);
        if (ret)
                return -1;
        priv->data_rate = 0;
 
        /* get tx power */
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR,
-                                    HostCmd_ACT_GEN_GET, 0, NULL);
+       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RF_TX_PWR,
+                                   HostCmd_ACT_GEN_GET, 0, NULL);
        if (ret)
                return -1;
 
        if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
                /* set ibss coalescing_status */
-               ret = mwifiex_send_cmd_async(
+               ret = mwifiex_send_cmd_sync(
                                priv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
                                HostCmd_ACT_GEN_SET, 0, &enable);
                if (ret)
@@ -1314,16 +1373,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
        memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
        amsdu_aggr_ctrl.enable = true;
        /* Send request to firmware */
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
-                                    HostCmd_ACT_GEN_SET, 0,
-                                    &amsdu_aggr_ctrl);
+       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
+                                   HostCmd_ACT_GEN_SET, 0,
+                                   &amsdu_aggr_ctrl);
        if (ret)
                return -1;
        /* MAC Control must be the last command in init_fw */
        /* set MAC Control */
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
-                                    HostCmd_ACT_GEN_SET, 0,
-                                    &priv->curr_pkt_filter);
+       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
+                                   HostCmd_ACT_GEN_SET, 0,
+                                   &priv->curr_pkt_filter);
        if (ret)
                return -1;
 
@@ -1332,10 +1391,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
                /* Enable auto deep sleep */
                auto_ds.auto_ds = DEEP_SLEEP_ON;
                auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
-               ret = mwifiex_send_cmd_async(priv,
-                                            HostCmd_CMD_802_11_PS_MODE_ENH,
-                                            EN_AUTO_PS, BITMAP_AUTO_DS,
-                                            &auto_ds);
+               ret = mwifiex_send_cmd_sync(priv,
+                                           HostCmd_CMD_802_11_PS_MODE_ENH,
+                                           EN_AUTO_PS, BITMAP_AUTO_DS,
+                                           &auto_ds);
                if (ret)
                        return -1;
        }
@@ -1343,23 +1402,24 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
        if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
                /* Send cmd to FW to enable/disable 11D function */
                state_11d = ENABLE_11D;
-               ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
-                                            HostCmd_ACT_GEN_SET, DOT11D_I,
-                                            &state_11d);
+               ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+                                           HostCmd_ACT_GEN_SET, DOT11D_I,
+                                           &state_11d);
                if (ret)
                        dev_err(priv->adapter->dev,
                                "11D: failed to enable 11D\n");
        }
 
+       /* set last_init_cmd before sending the command */
+       priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
+
        /* Send cmd to FW to configure 11n specific configuration
         * (Short GI, Channel BW, Green field support etc.) for transmit
         */
        tx_cfg.tx_htcap = MWIFIEX_FW_DEF_HTTXCFG;
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_CFG,
-                                    HostCmd_ACT_GEN_SET, 0, &tx_cfg);
+       ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_11N_CFG,
+                                   HostCmd_ACT_GEN_SET, 0, &tx_cfg);
 
-       /* set last_init_cmd */
-       priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
        ret = -EINPROGRESS;
 
        return ret;
This page took 0.03488 seconds and 5 git commands to generate.