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

mwifiex: support for WEP in AP mode

This patch adds support for WEP open/shared encryption in AP mode.
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5d66cb62
...@@ -170,7 +170,9 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, ...@@ -170,7 +170,9 @@ 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, NULL, 0)) { if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
priv->wep_key_curr_index = key_index;
} else 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;
} }
...@@ -187,9 +189,25 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, ...@@ -187,9 +189,25 @@ 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);
struct mwifiex_wep_key *wep_key;
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const u8 *peer_mac = pairwise ? mac_addr : bc_mac; const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
(params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
if (params->key && params->key_len) {
wep_key = &priv->wep_key[key_index];
memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
memcpy(wep_key->key_material, params->key,
params->key_len);
wep_key->key_index = key_index;
wep_key->key_length = params->key_len;
priv->sec_info.wep_enabled = 1;
}
return 0;
}
if (mwifiex_set_encode(priv, params->key, params->key_len, if (mwifiex_set_encode(priv, params->key, params->key_len,
key_index, peer_mac, 0)) { key_index, peer_mac, 0)) {
wiphy_err(wiphy, "crypto keys added\n"); wiphy_err(wiphy, "crypto keys added\n");
...@@ -1003,6 +1021,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, ...@@ -1003,6 +1021,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
return -1; return -1;
} }
if (priv->sec_info.wep_enabled)
priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
else
priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
HostCmd_ACT_GEN_SET, 0,
&priv->curr_pkt_filter))
return -1;
return 0; return 0;
} }
......
...@@ -124,6 +124,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { ...@@ -124,6 +124,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59)
#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
#define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65) #define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65)
...@@ -1201,6 +1202,13 @@ struct host_cmd_tlv_passphrase { ...@@ -1201,6 +1202,13 @@ struct host_cmd_tlv_passphrase {
u8 passphrase[0]; u8 passphrase[0];
} __packed; } __packed;
struct host_cmd_tlv_wep_key {
struct host_cmd_tlv tlv;
u8 key_index;
u8 is_default;
u8 key[1];
};
struct host_cmd_tlv_auth_type { struct host_cmd_tlv_auth_type {
struct host_cmd_tlv tlv; struct host_cmd_tlv tlv;
u8 auth_type; u8 auth_type;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define _MWIFIEX_IOCTL_H_ #define _MWIFIEX_IOCTL_H_
#include <net/mac80211.h> #include <net/mac80211.h>
#include <net/lib80211.h>
enum { enum {
MWIFIEX_SCAN_TYPE_UNCHANGED = 0, MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
...@@ -71,6 +72,13 @@ struct wpa_param { ...@@ -71,6 +72,13 @@ struct wpa_param {
u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN]; u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN];
}; };
struct wep_key {
u8 key_index;
u8 is_default;
u16 length;
u8 key[WLAN_KEY_LEN_WEP104];
};
#define KEY_MGMT_ON_HOST 0x03 #define KEY_MGMT_ON_HOST 0x03
#define MWIFIEX_AUTH_MODE_AUTO 0xFF #define MWIFIEX_AUTH_MODE_AUTO 0xFF
#define BAND_CONFIG_MANUAL 0x00 #define BAND_CONFIG_MANUAL 0x00
...@@ -90,6 +98,7 @@ struct mwifiex_uap_bss_param { ...@@ -90,6 +98,7 @@ struct mwifiex_uap_bss_param {
u16 key_mgmt; u16 key_mgmt;
u16 key_mgmt_operation; u16 key_mgmt_operation;
struct wpa_param wpa_cfg; struct wpa_param wpa_cfg;
struct wep_key wep_cfg[NUM_WEP_KEYS];
struct ieee80211_ht_cap ht_cap; struct ieee80211_ht_cap ht_cap;
}; };
......
...@@ -26,6 +26,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, ...@@ -26,6 +26,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
struct mwifiex_uap_bss_param *bss_config, struct mwifiex_uap_bss_param *bss_config,
struct cfg80211_ap_settings *params) { struct cfg80211_ap_settings *params) {
int i; int i;
struct mwifiex_wep_key wep_key;
if (!params->privacy) { if (!params->privacy) {
bss_config->protocol = PROTOCOL_NO_SECURITY; bss_config->protocol = PROTOCOL_NO_SECURITY;
...@@ -104,6 +105,27 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, ...@@ -104,6 +105,27 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
switch (params->crypto.cipher_group) { switch (params->crypto.cipher_group) {
case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_WEP104:
if (priv->sec_info.wep_enabled) {
bss_config->protocol = PROTOCOL_STATIC_WEP;
bss_config->key_mgmt = KEY_MGMT_NONE;
bss_config->wpa_cfg.length = 0;
for (i = 0; i < NUM_WEP_KEYS; i++) {
wep_key = priv->wep_key[i];
bss_config->wep_cfg[i].key_index = i;
if (priv->wep_key_curr_index == i)
bss_config->wep_cfg[i].is_default = 1;
else
bss_config->wep_cfg[i].is_default = 0;
bss_config->wep_cfg[i].length =
wep_key.key_length;
memcpy(&bss_config->wep_cfg[i].key,
&wep_key.key_material,
wep_key.key_length);
}
}
break; break;
case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_TKIP:
bss_config->wpa_cfg.group_cipher = CIPHER_TKIP; bss_config->wpa_cfg.group_cipher = CIPHER_TKIP;
...@@ -237,6 +259,44 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) ...@@ -237,6 +259,44 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
return; return;
} }
/* This function parses BSS related parameters from structure
* and prepares TLVs specific to WEP encryption.
* These TLVs are appended to command buffer.
*/
static void
mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
{
struct host_cmd_tlv_wep_key *wep_key;
u16 cmd_size = *param_size;
int i;
u8 *tlv = *tlv_buf;
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
for (i = 0; i < NUM_WEP_KEYS; i++) {
if (bss_cfg->wep_cfg[i].length &&
(bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 ||
bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) {
wep_key = (struct host_cmd_tlv_wep_key *)tlv;
wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
wep_key->tlv.len =
cpu_to_le16(bss_cfg->wep_cfg[i].length + 2);
wep_key->key_index = bss_cfg->wep_cfg[i].key_index;
wep_key->is_default = bss_cfg->wep_cfg[i].is_default;
memcpy(wep_key->key, bss_cfg->wep_cfg[i].key,
bss_cfg->wep_cfg[i].length);
cmd_size += sizeof(struct host_cmd_tlv) + 2 +
bss_cfg->wep_cfg[i].length;
tlv += sizeof(struct host_cmd_tlv) + 2 +
bss_cfg->wep_cfg[i].length;
}
}
*param_size = cmd_size;
*tlv_buf = tlv;
return;
}
/* This function parses BSS related parameters from structure /* This function parses BSS related parameters from structure
* and prepares TLVs. These TLVs are appended to command buffer. * and prepares TLVs. These TLVs are appended to command buffer.
*/ */
...@@ -345,6 +405,8 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) ...@@ -345,6 +405,8 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
(bss_cfg->protocol & PROTOCOL_WPA2) || (bss_cfg->protocol & PROTOCOL_WPA2) ||
(bss_cfg->protocol & PROTOCOL_EAP)) (bss_cfg->protocol & PROTOCOL_EAP))
mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size); mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size);
else
mwifiex_uap_bss_wep(&tlv, cmd_buf, &cmd_size);
if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
(bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
......
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