aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-04-15 00:16:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 15:59:58 -0400
commit0211ddda9deb681a804572936cd49e466a1aa88b (patch)
treea9bb069458364ba40c8c7024352f9ac36a8bdfcf /drivers/net/wireless/iwlwifi
parent6974e36356524fa856435cb1be40aaffbac9601a (diff)
iwlwifi: add 1X HW WEP support
This patch adds support for HW encryption/decryption in 1X WEP. 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')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c9
4 files changed, 58 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 93df29e4689a..23ab5236504b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -461,6 +461,7 @@ struct iwl4965_tid_data {
461struct iwl4965_hw_key { 461struct iwl4965_hw_key {
462 enum ieee80211_key_alg alg; 462 enum ieee80211_key_alg alg;
463 int keylen; 463 int keylen;
464 u8 keyidx;
464 struct ieee80211_key_conf *conf; 465 struct ieee80211_key_conf *conf;
465 u8 key[32]; 466 u8 key[32];
466}; 467};
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index a48e228e2ffd..cb964196ad2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -35,6 +35,7 @@
35#include "iwl-sta.h" 35#include "iwl-sta.h"
36#include "iwl-io.h" 36#include "iwl-io.h"
37#include "iwl-helpers.h" 37#include "iwl-helpers.h"
38#include "iwl-4965.h"
38 39
39int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) 40int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
40{ 41{
@@ -117,3 +118,49 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
117 return ret; 118 return ret;
118} 119}
119 120
121int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
122 struct ieee80211_key_conf *keyconf,
123 u8 sta_id)
124{
125 unsigned long flags;
126 __le16 key_flags = 0;
127 int ret;
128
129 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
130 keyconf->hw_key_idx = keyconf->keyidx;
131
132 key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
133 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
134 key_flags &= ~STA_KEY_FLG_INVALID;
135
136 if (keyconf->keylen == WEP_KEY_LEN_128)
137 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
138
139 if (sta_id == priv->hw_setting.bcast_sta_id)
140 key_flags |= STA_KEY_MULTICAST_MSK;
141
142 spin_lock_irqsave(&priv->sta_lock, flags);
143
144 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
145 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
146 priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
147
148 memcpy(priv->stations[sta_id].keyinfo.key,
149 keyconf->key, keyconf->keylen);
150
151 memcpy(&priv->stations[sta_id].sta.key.key[3],
152 keyconf->key, keyconf->keylen);
153
154 priv->stations[sta_id].sta.key.key_offset = sta_id % 8; /* FIXME */
155 priv->stations[sta_id].sta.key.key_flags = key_flags;
156
157 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
158 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
159
160 ret = iwl4965_send_add_station(priv,
161 &priv->stations[sta_id].sta, CMD_ASYNC);
162
163 spin_unlock_irqrestore(&priv->sta_lock, flags);
164
165 return ret;
166}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 50e9f1470d8d..78e0254c93b5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -42,5 +42,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
42 struct ieee80211_key_conf *key); 42 struct ieee80211_key_conf *key);
43int iwl_set_default_wep_key(struct iwl_priv *priv, 43int iwl_set_default_wep_key(struct iwl_priv *priv,
44 struct ieee80211_key_conf *key); 44 struct ieee80211_key_conf *key);
45int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
46 struct ieee80211_key_conf *keyconf,
47 u8 sta_id);
45 48
46#endif /* __iwl_sta_h__ */ 49#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index dfd2b75492e6..37ab1c565ce1 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1214,7 +1214,7 @@ static int iwl4965_set_dynamic_key(struct iwl_priv *priv,
1214 ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id); 1214 ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id);
1215 break; 1215 break;
1216 case ALG_WEP: 1216 case ALG_WEP:
1217 ret = -EOPNOTSUPP; 1217 ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id);
1218 break; 1218 break;
1219 default: 1219 default:
1220 IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); 1220 IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg);
@@ -2138,7 +2138,12 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
2138 if (wepkey->key_size == WEP_KEY_LEN_128) 2138 if (wepkey->key_size == WEP_KEY_LEN_128)
2139 cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; 2139 cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
2140 } else { 2140 } else {
2141 IWL_ERROR("No support for WEP key mappings key\n"); 2141 /* the WEP key was sent as dynamic */
2142 keyidx = keyinfo->keyidx;
2143 memcpy(&cmd->cmd.tx.key[3], keyinfo->key,
2144 keyinfo->keylen);
2145 if (keyinfo->keylen == WEP_KEY_LEN_128)
2146 cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
2142 } 2147 }
2143 2148
2144 cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP | 2149 cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP |