summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-04-14 21:16:06 -0700
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 15:59:58 -0400
commit6974e36356524fa856435cb1be40aaffbac9601a (patch)
treec5a98e784ce1d5c20ce99dec5ffcc7b1bca46efa /drivers/net/wireless/iwlwifi/iwl4965-base.c
parent0a0bed1d10105a9f58cd14ebe216e8479dd31fda (diff)
iwlwifi: default WEP HW encryption
This patch adds HW encryption support in default WEP mode. When no key mapping key/pairwise key is used. The key is broadcast key is used as default/global/static key. This code assumes that group cast key is added after pairwise key. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index ecc9cba62bf9..dfd2b75492e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -50,6 +50,7 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
+#include "iwl-sta.h"
static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl4965_tx_queue *txq);
@@ -941,6 +942,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
return -EIO;
}
priv->assoc_station_added = 1;
+ if (priv->default_wep_key &&
+ iwl_send_static_wepkey_cmd(priv, 0))
+ IWL_ERROR("Could not send WEP static key.\n");
}
return 0;
@@ -1180,6 +1184,8 @@ static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
{
unsigned long flags;
+ priv->key_mapping_key = 0;
+
spin_lock_irqsave(&priv->sta_lock, flags);
memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key));
memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo));
@@ -1198,6 +1204,8 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv,
{
int ret;
+ priv->key_mapping_key = 1;
+
switch (key->alg) {
case ALG_CCMP:
ret = iwl4965_set_ccmp_dynamic_key_info(priv, key, sta_id);
@@ -1216,23 +1224,6 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv,
return ret;
}
-static int iwl4965_remove_static_key(struct iwl_priv *priv)
-{
- int ret = -EOPNOTSUPP;
-
- return ret;
-}
-
-static int iwl4965_set_static_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key)
-{
- if (key->alg == ALG_WEP)
- return -EOPNOTSUPP;
-
- IWL_ERROR("Static key invalid: alg %d\n", key->alg);
- return -EINVAL;
-}
-
static void iwl4965_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
@@ -2115,6 +2106,10 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
int sta_id)
{
struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
+ struct iwl_wep_key *wepkey;
+ int keyidx = 0;
+
+ BUG_ON(ctl->key_idx > 3);
switch (keyinfo->alg) {
case ALG_CCMP:
@@ -2133,16 +2128,24 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
break;
case ALG_WEP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
- (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
-
- if (keyinfo->keylen == 13)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+ wepkey = &priv->wep_keys[ctl->key_idx];
+ cmd->cmd.tx.sec_ctl = 0;
+ if (priv->default_wep_key) {
+ /* the WEP key was sent as static */
+ keyidx = ctl->key_idx;
+ memcpy(&cmd->cmd.tx.key[3], wepkey->key,
+ wepkey->key_size);
+ if (wepkey->key_size == WEP_KEY_LEN_128)
+ cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+ } else {
+ IWL_ERROR("No support for WEP key mappings key\n");
+ }
- memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
+ cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP |
+ (keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
IWL_DEBUG_TX("Configuring packet for WEP encryption "
- "with key %d\n", ctl->key_idx);
+ "with key %d\n", keyidx);
break;
default:
@@ -6989,7 +6992,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
DECLARE_MAC_BUF(mac);
int ret = 0;
u8 sta_id = IWL_INVALID_STATION;
- u8 static_key;
+ u8 is_default_wep_key = 0;
IWL_DEBUG_MAC80211("enter\n");
@@ -7002,33 +7005,42 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
/* only support pairwise keys */
return -EOPNOTSUPP;
- /* FIXME: need to differenciate between static and dynamic key
- * in the level of mac80211 */
- static_key = !iwl_is_associated(priv);
+ sta_id = iwl4965_hw_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
+ print_mac(mac, addr));
+ return -EINVAL;
- if (!static_key) {
- sta_id = iwl4965_hw_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
- print_mac(mac, addr));
- return -EINVAL;
- }
}
+ mutex_lock(&priv->mutex);
iwl4965_scan_cancel_timeout(priv, 100);
+ mutex_unlock(&priv->mutex);
+
+ /* If we are getting WEP group key and we didn't receive any key mapping
+ * so far, we are in legacy wep mode (group key only), otherwise we are
+ * in 1X mode.
+ * In legacy wep mode, we use another host command to the uCode */
+ if (key->alg == ALG_WEP && sta_id == priv->hw_setting.bcast_sta_id &&
+ priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+ if (cmd == SET_KEY)
+ is_default_wep_key = !priv->key_mapping_key;
+ else
+ is_default_wep_key = priv->default_wep_key;
+ }
switch (cmd) {
case SET_KEY:
- if (static_key)
- ret = iwl4965_set_static_key(priv, key);
+ if (is_default_wep_key)
+ ret = iwl_set_default_wep_key(priv, key);
else
ret = iwl4965_set_dynamic_key(priv, key, sta_id);
IWL_DEBUG_MAC80211("enable hwcrypto key\n");
break;
case DISABLE_KEY:
- if (static_key)
- ret = iwl4965_remove_static_key(priv);
+ if (is_default_wep_key)
+ ret = iwl_remove_default_wep_key(priv, key);
else
ret = iwl4965_clear_sta_key_info(priv, sta_id);