summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/sta_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/sta_cmd.c')
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c150
1 files changed, 105 insertions, 45 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index df3a33c..5d87195 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -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;
OpenPOWER on IntegriCloud