Commit 75edd2c6 authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville

mwifiex: append peer mac address TLV in key material command to firmware

Modify key related cfg80211 handlers to copy peer mac address for
pairwise keys. If peer mac address is not present or group keys,
it will be sent as broadcast mac address.
This would be required since hostapd downloads per peer PTK.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: default avatarKiran Divekar <dkiran@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 67fdf39e
...@@ -97,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, ...@@ -97,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool pairwise, const u8 *mac_addr) u8 key_index, bool pairwise, const u8 *mac_addr)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) {
wiphy_err(wiphy, "deleting the crypto keys\n"); wiphy_err(wiphy, "deleting the crypto keys\n");
return -EFAULT; return -EFAULT;
} }
...@@ -168,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, ...@@ -168,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
if (!priv->sec_info.wep_enabled) if (!priv->sec_info.wep_enabled)
return 0; return 0;
if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
wiphy_err(wiphy, "set default Tx key index\n"); wiphy_err(wiphy, "set default Tx key index\n");
return -EFAULT; return -EFAULT;
} }
...@@ -185,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, ...@@ -185,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
struct key_params *params) struct key_params *params)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
if (mwifiex_set_encode(priv, params->key, params->key_len, if (mwifiex_set_encode(priv, params->key, params->key_len,
key_index, 0)) { key_index, peer_mac, 0)) {
wiphy_err(wiphy, "crypto keys added\n"); wiphy_err(wiphy, "crypto keys added\n");
return -EFAULT; return -EFAULT;
} }
...@@ -947,7 +951,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -947,7 +951,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
priv->wep_key_curr_index = 0; priv->wep_key_curr_index = 0;
priv->sec_info.encryption_mode = 0; priv->sec_info.encryption_mode = 0;
priv->sec_info.is_authtype_auto = 0; priv->sec_info.is_authtype_auto = 0;
ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1);
if (mode == NL80211_IFTYPE_ADHOC) { if (mode == NL80211_IFTYPE_ADHOC) {
/* "privacy" is set only for ad-hoc mode */ /* "privacy" is set only for ad-hoc mode */
...@@ -995,7 +999,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -995,7 +999,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
" with key len %d\n", sme->key_len); " with key len %d\n", sme->key_len);
priv->wep_key_curr_index = sme->key_idx; priv->wep_key_curr_index = sme->key_idx;
ret = mwifiex_set_encode(priv, sme->key, sme->key_len, ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
sme->key_idx, 0); sme->key_idx, NULL, 0);
} }
} }
done: done:
......
...@@ -104,6 +104,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { ...@@ -104,6 +104,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) #define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) #define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
#define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) #define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
#define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83) #define TLV_TYPE_RATE_SCOPE (PROPRIETARY_TLV_BASE_ID + 83)
...@@ -1103,6 +1104,16 @@ struct host_cmd_ds_802_11_eeprom_access { ...@@ -1103,6 +1104,16 @@ struct host_cmd_ds_802_11_eeprom_access {
u8 value; u8 value;
} __packed; } __packed;
struct host_cmd_tlv {
__le16 type;
__le16 len;
} __packed;
struct host_cmd_tlv_mac_addr {
struct host_cmd_tlv tlv;
u8 mac_addr[ETH_ALEN];
} __packed;
struct host_cmd_ds_802_11_rf_channel { struct host_cmd_ds_802_11_rf_channel {
__le16 action; __le16 action;
__le16 current_channel; __le16 current_channel;
......
...@@ -935,7 +935,8 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); ...@@ -935,7 +935,8 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
int key_len, u8 key_index, int disable); int key_len, u8 key_index, const u8 *mac_addr,
int disable);
int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len); int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
......
...@@ -498,7 +498,8 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, ...@@ -498,7 +498,8 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
{ {
struct host_cmd_ds_802_11_key_material *key_material = struct host_cmd_ds_802_11_key_material *key_material =
&cmd->params.key_material; &cmd->params.key_material;
u16 key_param_len = 0; struct host_cmd_tlv_mac_addr *tlv_mac;
u16 key_param_len = 0, cmd_size;
int ret = 0; int ret = 0;
const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
...@@ -614,11 +615,26 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, ...@@ -614,11 +615,26 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
cpu_to_le16((u16) enc_key->key_len + cpu_to_le16((u16) enc_key->key_len +
KEYPARAMSET_FIXED_LEN); KEYPARAMSET_FIXED_LEN);
key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
+ sizeof(struct mwifiex_ie_types_header); + sizeof(struct mwifiex_ie_types_header);
cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
+ key_param_len); + key_param_len);
if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
tlv_mac = (void *)((u8 *)&key_material->key_param_set +
key_param_len);
tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
cmd_size = key_param_len + S_DS_GEN +
sizeof(key_material->action) +
sizeof(struct host_cmd_tlv_mac_addr);
} else {
cmd_size = key_param_len + S_DS_GEN +
sizeof(key_material->action);
}
cmd->size = cpu_to_le16(cmd_size);
} }
return ret; return ret;
......
...@@ -1219,7 +1219,8 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version, ...@@ -1219,7 +1219,8 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
* with requisite parameters and calls the IOCTL handler. * with requisite parameters and calls the IOCTL handler.
*/ */
int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
int key_len, u8 key_index, int disable) int key_len, u8 key_index,
const u8 *mac_addr, int disable)
{ {
struct mwifiex_ds_encrypt_key encrypt_key; struct mwifiex_ds_encrypt_key encrypt_key;
...@@ -1229,8 +1230,12 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, ...@@ -1229,8 +1230,12 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
encrypt_key.key_index = key_index; encrypt_key.key_index = key_index;
if (key_len) if (key_len)
memcpy(encrypt_key.key_material, key, key_len); memcpy(encrypt_key.key_material, key, key_len);
if (mac_addr)
memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
} else { } else {
encrypt_key.key_disable = true; encrypt_key.key_disable = true;
if (mac_addr)
memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
} }
return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key); return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment