diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-04-15 00:16:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-16 15:59:58 -0400 |
commit | 7480513f5b436321f86f5a5210af5bf8edb19e9a (patch) | |
tree | 269824438ddc7fd7351d8f986f15565a8ea8ebbe /drivers/net/wireless/iwlwifi/iwl-sta.c | |
parent | 80fb47a11eaf3d1d70c02f3dc7976eaac9b0eef2 (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.c | 119 |
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 | ||
142 | int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | 142 | static 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 | |||
190 | static 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 | |||
230 | static 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 | |||
257 | int 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 | |||
281 | int 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 | |||