aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-04-15 00:16:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-16 15:59:58 -0400
commit7480513f5b436321f86f5a5210af5bf8edb19e9a (patch)
tree269824438ddc7fd7351d8f986f15565a8ea8ebbe /drivers/net/wireless/iwlwifi/iwl-sta.c
parent80fb47a11eaf3d1d70c02f3dc7976eaac9b0eef2 (diff)
iwlwifi: moves security functions to iwl-sta.c
This patch moves security related functions to iwl-sta.c. Note that iwl4965_mac_update_tkip_key is still in iwl4965-base.c since it is a mac80211 handler. 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/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c119
1 files changed, 118 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 41238f208ed5..8765358c1a11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -139,7 +139,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
139 return ret; 139 return ret;
140} 140}
141 141
142int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, 142static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
143 struct ieee80211_key_conf *keyconf, 143 struct ieee80211_key_conf *keyconf,
144 u8 sta_id) 144 u8 sta_id)
145{ 145{
@@ -186,3 +186,120 @@ int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
186 186
187 return ret; 187 return ret;
188} 188}
189
190static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
191 struct ieee80211_key_conf *keyconf,
192 u8 sta_id)
193{
194 unsigned long flags;
195 __le16 key_flags = 0;
196
197 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
198 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
199 key_flags &= ~STA_KEY_FLG_INVALID;
200
201 if (sta_id == priv->hw_setting.bcast_sta_id)
202 key_flags |= STA_KEY_MULTICAST_MSK;
203
204 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
205 keyconf->hw_key_idx = keyconf->keyidx;
206
207 spin_lock_irqsave(&priv->sta_lock, flags);
208 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
209 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
210
211 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
212 keyconf->keylen);
213
214 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
215 keyconf->keylen);
216
217 priv->stations[sta_id].sta.key.key_offset =
218 iwl_get_free_ucode_key_index(priv);
219 priv->stations[sta_id].sta.key.key_flags = key_flags;
220 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
221 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
222
223 spin_unlock_irqrestore(&priv->sta_lock, flags);
224
225 IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
226 return iwl4965_send_add_station(priv,
227 &priv->stations[sta_id].sta, CMD_ASYNC);
228}
229
230static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
231 struct ieee80211_key_conf *keyconf,
232 u8 sta_id)
233{
234 unsigned long flags;
235 int ret = 0;
236
237 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
238 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
239 keyconf->hw_key_idx = keyconf->keyidx;
240
241 spin_lock_irqsave(&priv->sta_lock, flags);
242
243 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
244 priv->stations[sta_id].keyinfo.conf = keyconf;
245 priv->stations[sta_id].keyinfo.keylen = 16;
246
247 /* This copy is acutally not needed: we get the key with each TX */
248 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
249
250 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
251
252 spin_unlock_irqrestore(&priv->sta_lock, flags);
253
254 return ret;
255}
256
257int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id)
258{
259 unsigned long flags;
260
261 priv->key_mapping_key = 0;
262
263 spin_lock_irqsave(&priv->sta_lock, flags);
264 if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
265 &priv->ucode_key_table))
266 IWL_ERROR("index %d not used in uCode key table.\n",
267 priv->stations[sta_id].sta.key.key_offset);
268 memset(&priv->stations[sta_id].keyinfo, 0,
269 sizeof(struct iwl4965_hw_key));
270 memset(&priv->stations[sta_id].sta.key, 0,
271 sizeof(struct iwl4965_keyinfo));
272 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
273 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
274 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
275 spin_unlock_irqrestore(&priv->sta_lock, flags);
276
277 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
278 return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
279}
280
281int iwl_set_dynamic_key(struct iwl_priv *priv,
282 struct ieee80211_key_conf *key, u8 sta_id)
283{
284 int ret;
285
286 priv->key_mapping_key = 1;
287
288 switch (key->alg) {
289 case ALG_CCMP:
290 ret = iwl_set_ccmp_dynamic_key_info(priv, key, sta_id);
291 break;
292 case ALG_TKIP:
293 ret = iwl_set_tkip_dynamic_key_info(priv, key, sta_id);
294 break;
295 case ALG_WEP:
296 ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id);
297 break;
298 default:
299 IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg);
300 ret = -EINVAL;
301 }
302
303 return ret;
304}
305