aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c119
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c120
3 files changed, 123 insertions, 123 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 3f1b20534396..44f272ecc827 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,8 +43,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
43 struct ieee80211_key_conf *key); 43 struct ieee80211_key_conf *key);
44int iwl_set_default_wep_key(struct iwl_priv *priv, 44int iwl_set_default_wep_key(struct iwl_priv *priv,
45 struct ieee80211_key_conf *key); 45 struct ieee80211_key_conf *key);
46int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, 46int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id);
47 struct ieee80211_key_conf *keyconf, 47int iwl_set_dynamic_key(struct iwl_priv *priv,
48 u8 sta_id); 48 struct ieee80211_key_conf *key, u8 sta_id);
49
50#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 da01896bd406..bfefb05e18e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1112,122 +1112,6 @@ int iwl4965_send_add_station(struct iwl_priv *priv,
1112 return rc; 1112 return rc;
1113} 1113}
1114 1114
1115static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
1116 struct ieee80211_key_conf *keyconf,
1117 u8 sta_id)
1118{
1119 unsigned long flags;
1120 __le16 key_flags = 0;
1121
1122 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
1123 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
1124
1125 if (sta_id == priv->hw_setting.bcast_sta_id)
1126 key_flags |= STA_KEY_MULTICAST_MSK;
1127
1128 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1129 keyconf->hw_key_idx = keyconf->keyidx;
1130
1131 key_flags &= ~STA_KEY_FLG_INVALID;
1132
1133 spin_lock_irqsave(&priv->sta_lock, flags);
1134 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
1135 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
1136
1137 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
1138 keyconf->keylen);
1139
1140 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
1141 keyconf->keylen);
1142
1143 priv->stations[sta_id].sta.key.key_offset =
1144 iwl_get_free_ucode_key_index(priv);
1145 priv->stations[sta_id].sta.key.key_flags = key_flags;
1146 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1147 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1148
1149 spin_unlock_irqrestore(&priv->sta_lock, flags);
1150
1151 IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
1152 return iwl4965_send_add_station(priv,
1153 &priv->stations[sta_id].sta, CMD_ASYNC);
1154}
1155
1156static int iwl4965_set_tkip_dynamic_key_info(struct iwl_priv *priv,
1157 struct ieee80211_key_conf *keyconf,
1158 u8 sta_id)
1159{
1160 unsigned long flags;
1161 int ret = 0;
1162
1163 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1164 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1165 keyconf->hw_key_idx = keyconf->keyidx;
1166
1167 spin_lock_irqsave(&priv->sta_lock, flags);
1168
1169 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
1170 priv->stations[sta_id].keyinfo.conf = keyconf;
1171 priv->stations[sta_id].keyinfo.keylen = 16;
1172
1173 /* This copy is acutally not needed: we get the key with each TX */
1174 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
1175
1176 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
1177
1178 spin_unlock_irqrestore(&priv->sta_lock, flags);
1179
1180 return ret;
1181}
1182
1183static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
1184{
1185 unsigned long flags;
1186
1187 priv->key_mapping_key = 0;
1188
1189 spin_lock_irqsave(&priv->sta_lock, flags);
1190 if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
1191 &priv->ucode_key_table))
1192 IWL_ERROR("index %d not used in uCode key table.\n",
1193 priv->stations[sta_id].sta.key.key_offset);
1194 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key));
1195 memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo));
1196 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
1197 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1198 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1199 spin_unlock_irqrestore(&priv->sta_lock, flags);
1200
1201 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
1202 iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
1203 return 0;
1204}
1205
1206static int iwl4965_set_dynamic_key(struct iwl_priv *priv,
1207 struct ieee80211_key_conf *key, u8 sta_id)
1208{
1209 int ret;
1210
1211 priv->key_mapping_key = 1;
1212
1213 switch (key->alg) {
1214 case ALG_CCMP:
1215 ret = iwl4965_set_ccmp_dynamic_key_info(priv, key, sta_id);
1216 break;
1217 case ALG_TKIP:
1218 ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id);
1219 break;
1220 case ALG_WEP:
1221 ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id);
1222 break;
1223 default:
1224 IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg);
1225 ret = -EINVAL;
1226 }
1227
1228 return ret;
1229}
1230
1231static void iwl4965_clear_free_frames(struct iwl_priv *priv) 1115static void iwl4965_clear_free_frames(struct iwl_priv *priv)
1232{ 1116{
1233 struct list_head *element; 1117 struct list_head *element;
@@ -7043,7 +6927,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
7043 if (is_default_wep_key) 6927 if (is_default_wep_key)
7044 ret = iwl_set_default_wep_key(priv, key); 6928 ret = iwl_set_default_wep_key(priv, key);
7045 else 6929 else
7046 ret = iwl4965_set_dynamic_key(priv, key, sta_id); 6930 ret = iwl_set_dynamic_key(priv, key, sta_id);
7047 6931
7048 IWL_DEBUG_MAC80211("enable hwcrypto key\n"); 6932 IWL_DEBUG_MAC80211("enable hwcrypto key\n");
7049 break; 6933 break;
@@ -7051,7 +6935,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
7051 if (is_default_wep_key) 6935 if (is_default_wep_key)
7052 ret = iwl_remove_default_wep_key(priv, key); 6936 ret = iwl_remove_default_wep_key(priv, key);
7053 else 6937 else
7054 ret = iwl4965_clear_sta_key_info(priv, sta_id); 6938 ret = iwl_remove_dynamic_key(priv, sta_id);
7055 6939
7056 IWL_DEBUG_MAC80211("disable hwcrypto key\n"); 6940 IWL_DEBUG_MAC80211("disable hwcrypto key\n");
7057 break; 6941 break;