diff options
author | Bruno Randolf <br1@einfach.org> | 2010-09-08 03:05:04 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-09-16 15:22:10 -0400 |
commit | 040e539e8e8d5585e1c3d7d15fa7215d3a691258 (patch) | |
tree | cf9e3b12ec237395e6743aae0a3eafa88c9f7fc1 /drivers | |
parent | 781f3136ff4cdd2b33149f2295fefa21f77b1c56 (diff) |
ath9k: Use common ath key management functions
Use key management functions which have been moved to ath/key.c and remove
ath9k copies of these functions and other now unused definitions.
Signed-off-by: Bruno Randolf <br1@einfach.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 270 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 271 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/phy.h | 3 |
10 files changed, 6 insertions, 583 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 2db24eb5f0e..f43a2d98421 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -148,276 +148,6 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, | |||
148 | } | 148 | } |
149 | EXPORT_SYMBOL(ath9k_cmn_get_curchannel); | 149 | EXPORT_SYMBOL(ath9k_cmn_get_curchannel); |
150 | 150 | ||
151 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, | ||
152 | struct ath9k_keyval *hk, const u8 *addr, | ||
153 | bool authenticator) | ||
154 | { | ||
155 | struct ath_hw *ah = common->ah; | ||
156 | const u8 *key_rxmic; | ||
157 | const u8 *key_txmic; | ||
158 | |||
159 | key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | ||
160 | key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | ||
161 | |||
162 | if (addr == NULL) { | ||
163 | /* | ||
164 | * Group key installation - only two key cache entries are used | ||
165 | * regardless of splitmic capability since group key is only | ||
166 | * used either for TX or RX. | ||
167 | */ | ||
168 | if (authenticator) { | ||
169 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
170 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); | ||
171 | } else { | ||
172 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
173 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | ||
174 | } | ||
175 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
176 | } | ||
177 | if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { | ||
178 | /* TX and RX keys share the same key cache entry. */ | ||
179 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
180 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | ||
181 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
182 | } | ||
183 | |||
184 | /* Separate key cache entries for TX and RX */ | ||
185 | |||
186 | /* TX key goes at first index, RX key at +32. */ | ||
187 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
188 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { | ||
189 | /* TX MIC entry failed. No need to proceed further */ | ||
190 | ath_print(common, ATH_DBG_FATAL, | ||
191 | "Setting TX MIC Key Failed\n"); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
196 | /* XXX delete tx key on failure? */ | ||
197 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); | ||
198 | } | ||
199 | |||
200 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) | ||
201 | { | ||
202 | int i; | ||
203 | |||
204 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
205 | if (test_bit(i, common->keymap) || | ||
206 | test_bit(i + 64, common->keymap)) | ||
207 | continue; /* At least one part of TKIP key allocated */ | ||
208 | if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) && | ||
209 | (test_bit(i + 32, common->keymap) || | ||
210 | test_bit(i + 64 + 32, common->keymap))) | ||
211 | continue; /* At least one part of TKIP key allocated */ | ||
212 | |||
213 | /* Found a free slot for a TKIP key */ | ||
214 | return i; | ||
215 | } | ||
216 | return -1; | ||
217 | } | ||
218 | |||
219 | static int ath_reserve_key_cache_slot(struct ath_common *common, | ||
220 | u32 cipher) | ||
221 | { | ||
222 | int i; | ||
223 | |||
224 | if (cipher == WLAN_CIPHER_SUITE_TKIP) | ||
225 | return ath_reserve_key_cache_slot_tkip(common); | ||
226 | |||
227 | /* First, try to find slots that would not be available for TKIP. */ | ||
228 | if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { | ||
229 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { | ||
230 | if (!test_bit(i, common->keymap) && | ||
231 | (test_bit(i + 32, common->keymap) || | ||
232 | test_bit(i + 64, common->keymap) || | ||
233 | test_bit(i + 64 + 32, common->keymap))) | ||
234 | return i; | ||
235 | if (!test_bit(i + 32, common->keymap) && | ||
236 | (test_bit(i, common->keymap) || | ||
237 | test_bit(i + 64, common->keymap) || | ||
238 | test_bit(i + 64 + 32, common->keymap))) | ||
239 | return i + 32; | ||
240 | if (!test_bit(i + 64, common->keymap) && | ||
241 | (test_bit(i , common->keymap) || | ||
242 | test_bit(i + 32, common->keymap) || | ||
243 | test_bit(i + 64 + 32, common->keymap))) | ||
244 | return i + 64; | ||
245 | if (!test_bit(i + 64 + 32, common->keymap) && | ||
246 | (test_bit(i, common->keymap) || | ||
247 | test_bit(i + 32, common->keymap) || | ||
248 | test_bit(i + 64, common->keymap))) | ||
249 | return i + 64 + 32; | ||
250 | } | ||
251 | } else { | ||
252 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
253 | if (!test_bit(i, common->keymap) && | ||
254 | test_bit(i + 64, common->keymap)) | ||
255 | return i; | ||
256 | if (test_bit(i, common->keymap) && | ||
257 | !test_bit(i + 64, common->keymap)) | ||
258 | return i + 64; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /* No partially used TKIP slots, pick any available slot */ | ||
263 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { | ||
264 | /* Do not allow slots that could be needed for TKIP group keys | ||
265 | * to be used. This limitation could be removed if we know that | ||
266 | * TKIP will not be used. */ | ||
267 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | ||
268 | continue; | ||
269 | if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { | ||
270 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | ||
271 | continue; | ||
272 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | ||
273 | continue; | ||
274 | } | ||
275 | |||
276 | if (!test_bit(i, common->keymap)) | ||
277 | return i; /* Found a free slot for a key */ | ||
278 | } | ||
279 | |||
280 | /* No free slot found */ | ||
281 | return -1; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Configure encryption in the HW. | ||
286 | */ | ||
287 | int ath9k_cmn_key_config(struct ath_common *common, | ||
288 | struct ieee80211_vif *vif, | ||
289 | struct ieee80211_sta *sta, | ||
290 | struct ieee80211_key_conf *key) | ||
291 | { | ||
292 | struct ath_hw *ah = common->ah; | ||
293 | struct ath9k_keyval hk; | ||
294 | const u8 *mac = NULL; | ||
295 | u8 gmac[ETH_ALEN]; | ||
296 | int ret = 0; | ||
297 | int idx; | ||
298 | |||
299 | memset(&hk, 0, sizeof(hk)); | ||
300 | |||
301 | switch (key->cipher) { | ||
302 | case WLAN_CIPHER_SUITE_WEP40: | ||
303 | case WLAN_CIPHER_SUITE_WEP104: | ||
304 | hk.kv_type = ATH9K_CIPHER_WEP; | ||
305 | break; | ||
306 | case WLAN_CIPHER_SUITE_TKIP: | ||
307 | hk.kv_type = ATH9K_CIPHER_TKIP; | ||
308 | break; | ||
309 | case WLAN_CIPHER_SUITE_CCMP: | ||
310 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | ||
311 | break; | ||
312 | default: | ||
313 | return -EOPNOTSUPP; | ||
314 | } | ||
315 | |||
316 | hk.kv_len = key->keylen; | ||
317 | memcpy(hk.kv_val, key->key, key->keylen); | ||
318 | |||
319 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
320 | switch (vif->type) { | ||
321 | case NL80211_IFTYPE_AP: | ||
322 | memcpy(gmac, vif->addr, ETH_ALEN); | ||
323 | gmac[0] |= 0x01; | ||
324 | mac = gmac; | ||
325 | idx = ath_reserve_key_cache_slot(common, key->cipher); | ||
326 | break; | ||
327 | case NL80211_IFTYPE_ADHOC: | ||
328 | if (!sta) { | ||
329 | idx = key->keyidx; | ||
330 | break; | ||
331 | } | ||
332 | memcpy(gmac, sta->addr, ETH_ALEN); | ||
333 | gmac[0] |= 0x01; | ||
334 | mac = gmac; | ||
335 | idx = ath_reserve_key_cache_slot(common, key->cipher); | ||
336 | break; | ||
337 | default: | ||
338 | idx = key->keyidx; | ||
339 | break; | ||
340 | } | ||
341 | } else if (key->keyidx) { | ||
342 | if (WARN_ON(!sta)) | ||
343 | return -EOPNOTSUPP; | ||
344 | mac = sta->addr; | ||
345 | |||
346 | if (vif->type != NL80211_IFTYPE_AP) { | ||
347 | /* Only keyidx 0 should be used with unicast key, but | ||
348 | * allow this for client mode for now. */ | ||
349 | idx = key->keyidx; | ||
350 | } else | ||
351 | return -EIO; | ||
352 | } else { | ||
353 | if (WARN_ON(!sta)) | ||
354 | return -EOPNOTSUPP; | ||
355 | mac = sta->addr; | ||
356 | |||
357 | idx = ath_reserve_key_cache_slot(common, key->cipher); | ||
358 | } | ||
359 | |||
360 | if (idx < 0) | ||
361 | return -ENOSPC; /* no free key cache entries */ | ||
362 | |||
363 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) | ||
364 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, | ||
365 | vif->type == NL80211_IFTYPE_AP); | ||
366 | else | ||
367 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); | ||
368 | |||
369 | if (!ret) | ||
370 | return -EIO; | ||
371 | |||
372 | set_bit(idx, common->keymap); | ||
373 | if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
374 | set_bit(idx + 64, common->keymap); | ||
375 | set_bit(idx, common->tkip_keymap); | ||
376 | set_bit(idx + 64, common->tkip_keymap); | ||
377 | if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { | ||
378 | set_bit(idx + 32, common->keymap); | ||
379 | set_bit(idx + 64 + 32, common->keymap); | ||
380 | set_bit(idx + 32, common->tkip_keymap); | ||
381 | set_bit(idx + 64 + 32, common->tkip_keymap); | ||
382 | } | ||
383 | } | ||
384 | |||
385 | return idx; | ||
386 | } | ||
387 | EXPORT_SYMBOL(ath9k_cmn_key_config); | ||
388 | |||
389 | /* | ||
390 | * Delete Key. | ||
391 | */ | ||
392 | void ath9k_cmn_key_delete(struct ath_common *common, | ||
393 | struct ieee80211_key_conf *key) | ||
394 | { | ||
395 | struct ath_hw *ah = common->ah; | ||
396 | |||
397 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
398 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | ||
399 | return; | ||
400 | |||
401 | clear_bit(key->hw_key_idx, common->keymap); | ||
402 | if (key->cipher != WLAN_CIPHER_SUITE_TKIP) | ||
403 | return; | ||
404 | |||
405 | clear_bit(key->hw_key_idx + 64, common->keymap); | ||
406 | |||
407 | clear_bit(key->hw_key_idx, common->tkip_keymap); | ||
408 | clear_bit(key->hw_key_idx + 64, common->tkip_keymap); | ||
409 | |||
410 | if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { | ||
411 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | ||
412 | clear_bit(key->hw_key_idx + 32, common->keymap); | ||
413 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | ||
414 | |||
415 | clear_bit(key->hw_key_idx + 32, common->tkip_keymap); | ||
416 | clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); | ||
417 | } | ||
418 | } | ||
419 | EXPORT_SYMBOL(ath9k_cmn_key_delete); | ||
420 | |||
421 | int ath9k_cmn_count_streams(unsigned int chainmask, int max) | 151 | int ath9k_cmn_count_streams(unsigned int chainmask, int max) |
422 | { | 152 | { |
423 | int streams = 0; | 153 | int streams = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 4aa4e7dbe4d..fea3b331539 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -66,12 +66,6 @@ void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, | |||
66 | struct ath9k_channel *ichan); | 66 | struct ath9k_channel *ichan); |
67 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, | 67 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, |
68 | struct ath_hw *ah); | 68 | struct ath_hw *ah); |
69 | int ath9k_cmn_key_config(struct ath_common *common, | ||
70 | struct ieee80211_vif *vif, | ||
71 | struct ieee80211_sta *sta, | ||
72 | struct ieee80211_key_conf *key); | ||
73 | void ath9k_cmn_key_delete(struct ath_common *common, | ||
74 | struct ieee80211_key_conf *key); | ||
75 | int ath9k_cmn_count_streams(unsigned int chainmask, int max); | 69 | int ath9k_cmn_count_streams(unsigned int chainmask, int max); |
76 | void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, | 70 | void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, |
77 | enum ath_stomp_type stomp_type); | 71 | enum ath_stomp_type stomp_type); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 717f2b821f0..33850c95231 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) | |||
566 | * reset the contents on initial power up. | 566 | * reset the contents on initial power up. |
567 | */ | 567 | */ |
568 | for (i = 0; i < common->keymax; i++) | 568 | for (i = 0; i < common->keymax; i++) |
569 | ath9k_hw_keyreset(priv->ah, (u16) i); | 569 | ath_hw_keyreset(common, (u16) i); |
570 | } | 570 | } |
571 | 571 | ||
572 | static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) | 572 | static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index bab894873bf..5124d04b240 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1590,7 +1590,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
1590 | 1590 | ||
1591 | switch (cmd) { | 1591 | switch (cmd) { |
1592 | case SET_KEY: | 1592 | case SET_KEY: |
1593 | ret = ath9k_cmn_key_config(common, vif, sta, key); | 1593 | ret = ath_key_config(common, vif, sta, key); |
1594 | if (ret >= 0) { | 1594 | if (ret >= 0) { |
1595 | key->hw_key_idx = ret; | 1595 | key->hw_key_idx = ret; |
1596 | /* push IV and Michael MIC generation to stack */ | 1596 | /* push IV and Michael MIC generation to stack */ |
@@ -1604,7 +1604,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
1604 | } | 1604 | } |
1605 | break; | 1605 | break; |
1606 | case DISABLE_KEY: | 1606 | case DISABLE_KEY: |
1607 | ath9k_cmn_key_delete(common, key); | 1607 | ath_key_delete(common, key); |
1608 | break; | 1608 | break; |
1609 | default: | 1609 | default: |
1610 | ret = -EINVAL; | 1610 | ret = -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 40c6451602d..f3c9d754957 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1476,277 +1476,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1476 | } | 1476 | } |
1477 | EXPORT_SYMBOL(ath9k_hw_reset); | 1477 | EXPORT_SYMBOL(ath9k_hw_reset); |
1478 | 1478 | ||
1479 | /************************/ | ||
1480 | /* Key Cache Management */ | ||
1481 | /************************/ | ||
1482 | |||
1483 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) | ||
1484 | { | ||
1485 | u32 keyType; | ||
1486 | |||
1487 | if (entry >= ah->caps.keycache_size) { | ||
1488 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
1489 | "keychache entry %u out of range\n", entry); | ||
1490 | return false; | ||
1491 | } | ||
1492 | |||
1493 | keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); | ||
1494 | |||
1495 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); | ||
1496 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); | ||
1497 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); | ||
1498 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); | ||
1499 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); | ||
1500 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); | ||
1501 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); | ||
1502 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); | ||
1503 | |||
1504 | if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { | ||
1505 | u16 micentry = entry + 64; | ||
1506 | |||
1507 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); | ||
1508 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); | ||
1509 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); | ||
1510 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); | ||
1511 | |||
1512 | } | ||
1513 | |||
1514 | return true; | ||
1515 | } | ||
1516 | EXPORT_SYMBOL(ath9k_hw_keyreset); | ||
1517 | |||
1518 | static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) | ||
1519 | { | ||
1520 | u32 macHi, macLo; | ||
1521 | u32 unicast_flag = AR_KEYTABLE_VALID; | ||
1522 | |||
1523 | if (entry >= ah->caps.keycache_size) { | ||
1524 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
1525 | "keychache entry %u out of range\n", entry); | ||
1526 | return false; | ||
1527 | } | ||
1528 | |||
1529 | if (mac != NULL) { | ||
1530 | /* | ||
1531 | * AR_KEYTABLE_VALID indicates that the address is a unicast | ||
1532 | * address, which must match the transmitter address for | ||
1533 | * decrypting frames. | ||
1534 | * Not setting this bit allows the hardware to use the key | ||
1535 | * for multicast frame decryption. | ||
1536 | */ | ||
1537 | if (mac[0] & 0x01) | ||
1538 | unicast_flag = 0; | ||
1539 | |||
1540 | macHi = (mac[5] << 8) | mac[4]; | ||
1541 | macLo = (mac[3] << 24) | | ||
1542 | (mac[2] << 16) | | ||
1543 | (mac[1] << 8) | | ||
1544 | mac[0]; | ||
1545 | macLo >>= 1; | ||
1546 | macLo |= (macHi & 1) << 31; | ||
1547 | macHi >>= 1; | ||
1548 | } else { | ||
1549 | macLo = macHi = 0; | ||
1550 | } | ||
1551 | REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); | ||
1552 | REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); | ||
1553 | |||
1554 | return true; | ||
1555 | } | ||
1556 | |||
1557 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | ||
1558 | const struct ath9k_keyval *k, | ||
1559 | const u8 *mac) | ||
1560 | { | ||
1561 | const struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
1562 | struct ath_common *common = ath9k_hw_common(ah); | ||
1563 | u32 key0, key1, key2, key3, key4; | ||
1564 | u32 keyType; | ||
1565 | |||
1566 | if (entry >= pCap->keycache_size) { | ||
1567 | ath_print(common, ATH_DBG_FATAL, | ||
1568 | "keycache entry %u out of range\n", entry); | ||
1569 | return false; | ||
1570 | } | ||
1571 | |||
1572 | switch (k->kv_type) { | ||
1573 | case ATH9K_CIPHER_AES_OCB: | ||
1574 | keyType = AR_KEYTABLE_TYPE_AES; | ||
1575 | break; | ||
1576 | case ATH9K_CIPHER_AES_CCM: | ||
1577 | keyType = AR_KEYTABLE_TYPE_CCM; | ||
1578 | break; | ||
1579 | case ATH9K_CIPHER_TKIP: | ||
1580 | keyType = AR_KEYTABLE_TYPE_TKIP; | ||
1581 | if (ATH9K_IS_MIC_ENABLED(ah) | ||
1582 | && entry + 64 >= pCap->keycache_size) { | ||
1583 | ath_print(common, ATH_DBG_ANY, | ||
1584 | "entry %u inappropriate for TKIP\n", entry); | ||
1585 | return false; | ||
1586 | } | ||
1587 | break; | ||
1588 | case ATH9K_CIPHER_WEP: | ||
1589 | if (k->kv_len < WLAN_KEY_LEN_WEP40) { | ||
1590 | ath_print(common, ATH_DBG_ANY, | ||
1591 | "WEP key length %u too small\n", k->kv_len); | ||
1592 | return false; | ||
1593 | } | ||
1594 | if (k->kv_len <= WLAN_KEY_LEN_WEP40) | ||
1595 | keyType = AR_KEYTABLE_TYPE_40; | ||
1596 | else if (k->kv_len <= WLAN_KEY_LEN_WEP104) | ||
1597 | keyType = AR_KEYTABLE_TYPE_104; | ||
1598 | else | ||
1599 | keyType = AR_KEYTABLE_TYPE_128; | ||
1600 | break; | ||
1601 | case ATH9K_CIPHER_CLR: | ||
1602 | keyType = AR_KEYTABLE_TYPE_CLR; | ||
1603 | break; | ||
1604 | default: | ||
1605 | ath_print(common, ATH_DBG_FATAL, | ||
1606 | "cipher %u not supported\n", k->kv_type); | ||
1607 | return false; | ||
1608 | } | ||
1609 | |||
1610 | key0 = get_unaligned_le32(k->kv_val + 0); | ||
1611 | key1 = get_unaligned_le16(k->kv_val + 4); | ||
1612 | key2 = get_unaligned_le32(k->kv_val + 6); | ||
1613 | key3 = get_unaligned_le16(k->kv_val + 10); | ||
1614 | key4 = get_unaligned_le32(k->kv_val + 12); | ||
1615 | if (k->kv_len <= WLAN_KEY_LEN_WEP104) | ||
1616 | key4 &= 0xff; | ||
1617 | |||
1618 | /* | ||
1619 | * Note: Key cache registers access special memory area that requires | ||
1620 | * two 32-bit writes to actually update the values in the internal | ||
1621 | * memory. Consequently, the exact order and pairs used here must be | ||
1622 | * maintained. | ||
1623 | */ | ||
1624 | |||
1625 | if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { | ||
1626 | u16 micentry = entry + 64; | ||
1627 | |||
1628 | /* | ||
1629 | * Write inverted key[47:0] first to avoid Michael MIC errors | ||
1630 | * on frames that could be sent or received at the same time. | ||
1631 | * The correct key will be written in the end once everything | ||
1632 | * else is ready. | ||
1633 | */ | ||
1634 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); | ||
1635 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); | ||
1636 | |||
1637 | /* Write key[95:48] */ | ||
1638 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); | ||
1639 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); | ||
1640 | |||
1641 | /* Write key[127:96] and key type */ | ||
1642 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); | ||
1643 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); | ||
1644 | |||
1645 | /* Write MAC address for the entry */ | ||
1646 | (void) ath9k_hw_keysetmac(ah, entry, mac); | ||
1647 | |||
1648 | if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { | ||
1649 | /* | ||
1650 | * TKIP uses two key cache entries: | ||
1651 | * Michael MIC TX/RX keys in the same key cache entry | ||
1652 | * (idx = main index + 64): | ||
1653 | * key0 [31:0] = RX key [31:0] | ||
1654 | * key1 [15:0] = TX key [31:16] | ||
1655 | * key1 [31:16] = reserved | ||
1656 | * key2 [31:0] = RX key [63:32] | ||
1657 | * key3 [15:0] = TX key [15:0] | ||
1658 | * key3 [31:16] = reserved | ||
1659 | * key4 [31:0] = TX key [63:32] | ||
1660 | */ | ||
1661 | u32 mic0, mic1, mic2, mic3, mic4; | ||
1662 | |||
1663 | mic0 = get_unaligned_le32(k->kv_mic + 0); | ||
1664 | mic2 = get_unaligned_le32(k->kv_mic + 4); | ||
1665 | mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; | ||
1666 | mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; | ||
1667 | mic4 = get_unaligned_le32(k->kv_txmic + 4); | ||
1668 | |||
1669 | /* Write RX[31:0] and TX[31:16] */ | ||
1670 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | ||
1671 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); | ||
1672 | |||
1673 | /* Write RX[63:32] and TX[15:0] */ | ||
1674 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); | ||
1675 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); | ||
1676 | |||
1677 | /* Write TX[63:32] and keyType(reserved) */ | ||
1678 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); | ||
1679 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | ||
1680 | AR_KEYTABLE_TYPE_CLR); | ||
1681 | |||
1682 | } else { | ||
1683 | /* | ||
1684 | * TKIP uses four key cache entries (two for group | ||
1685 | * keys): | ||
1686 | * Michael MIC TX/RX keys are in different key cache | ||
1687 | * entries (idx = main index + 64 for TX and | ||
1688 | * main index + 32 + 96 for RX): | ||
1689 | * key0 [31:0] = TX/RX MIC key [31:0] | ||
1690 | * key1 [31:0] = reserved | ||
1691 | * key2 [31:0] = TX/RX MIC key [63:32] | ||
1692 | * key3 [31:0] = reserved | ||
1693 | * key4 [31:0] = reserved | ||
1694 | * | ||
1695 | * Upper layer code will call this function separately | ||
1696 | * for TX and RX keys when these registers offsets are | ||
1697 | * used. | ||
1698 | */ | ||
1699 | u32 mic0, mic2; | ||
1700 | |||
1701 | mic0 = get_unaligned_le32(k->kv_mic + 0); | ||
1702 | mic2 = get_unaligned_le32(k->kv_mic + 4); | ||
1703 | |||
1704 | /* Write MIC key[31:0] */ | ||
1705 | REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); | ||
1706 | REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); | ||
1707 | |||
1708 | /* Write MIC key[63:32] */ | ||
1709 | REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); | ||
1710 | REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); | ||
1711 | |||
1712 | /* Write TX[63:32] and keyType(reserved) */ | ||
1713 | REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); | ||
1714 | REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), | ||
1715 | AR_KEYTABLE_TYPE_CLR); | ||
1716 | } | ||
1717 | |||
1718 | /* MAC address registers are reserved for the MIC entry */ | ||
1719 | REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); | ||
1720 | REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); | ||
1721 | |||
1722 | /* | ||
1723 | * Write the correct (un-inverted) key[47:0] last to enable | ||
1724 | * TKIP now that all other registers are set with correct | ||
1725 | * values. | ||
1726 | */ | ||
1727 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | ||
1728 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | ||
1729 | } else { | ||
1730 | /* Write key[47:0] */ | ||
1731 | REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); | ||
1732 | REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); | ||
1733 | |||
1734 | /* Write key[95:48] */ | ||
1735 | REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); | ||
1736 | REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); | ||
1737 | |||
1738 | /* Write key[127:96] and key type */ | ||
1739 | REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); | ||
1740 | REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); | ||
1741 | |||
1742 | /* Write MAC address for the entry */ | ||
1743 | (void) ath9k_hw_keysetmac(ah, entry, mac); | ||
1744 | } | ||
1745 | |||
1746 | return true; | ||
1747 | } | ||
1748 | EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); | ||
1749 | |||
1750 | /******************************/ | 1479 | /******************************/ |
1751 | /* Power Management (Chipset) */ | 1480 | /* Power Management (Chipset) */ |
1752 | /******************************/ | 1481 | /******************************/ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a3c2ce23512..df47f792cf4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -870,12 +870,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
870 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); | 870 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); |
871 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); | 871 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); |
872 | 872 | ||
873 | /* Key Cache Management */ | ||
874 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); | ||
875 | bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, | ||
876 | const struct ath9k_keyval *k, | ||
877 | const u8 *mac); | ||
878 | |||
879 | /* GPIO / RFKILL / Antennae */ | 873 | /* GPIO / RFKILL / Antennae */ |
880 | void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); | 874 | void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); |
881 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); | 875 | u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index fd651d8ef81..224df6d8fe2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -381,7 +381,7 @@ static void ath9k_init_crypto(struct ath_softc *sc) | |||
381 | * reset the contents on initial power up. | 381 | * reset the contents on initial power up. |
382 | */ | 382 | */ |
383 | for (i = 0; i < common->keymax; i++) | 383 | for (i = 0; i < common->keymax; i++) |
384 | ath9k_hw_keyreset(sc->sc_ah, (u16) i); | 384 | ath_hw_keyreset(common, (u16) i); |
385 | 385 | ||
386 | /* | 386 | /* |
387 | * Check whether the separate key cache entries | 387 | * Check whether the separate key cache entries |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 2633896d399..7c1a34d64f6 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -660,17 +660,6 @@ struct ath9k_11n_rate_series { | |||
660 | u32 RateFlags; | 660 | u32 RateFlags; |
661 | }; | 661 | }; |
662 | 662 | ||
663 | struct ath9k_keyval { | ||
664 | u8 kv_type; | ||
665 | u8 kv_pad; | ||
666 | u16 kv_len; | ||
667 | u8 kv_val[16]; /* TK */ | ||
668 | u8 kv_mic[8]; /* Michael MIC key */ | ||
669 | u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware | ||
670 | * supports both MIC keys in the same key cache entry; | ||
671 | * in that case, kv_mic is the RX key) */ | ||
672 | }; | ||
673 | |||
674 | enum ath9k_key_type { | 663 | enum ath9k_key_type { |
675 | ATH9K_KEY_TYPE_CLEAR, | 664 | ATH9K_KEY_TYPE_CLEAR, |
676 | ATH9K_KEY_TYPE_WEP, | 665 | ATH9K_KEY_TYPE_WEP, |
@@ -678,16 +667,6 @@ enum ath9k_key_type { | |||
678 | ATH9K_KEY_TYPE_TKIP, | 667 | ATH9K_KEY_TYPE_TKIP, |
679 | }; | 668 | }; |
680 | 669 | ||
681 | enum ath9k_cipher { | ||
682 | ATH9K_CIPHER_WEP = 0, | ||
683 | ATH9K_CIPHER_AES_OCB = 1, | ||
684 | ATH9K_CIPHER_AES_CCM = 2, | ||
685 | ATH9K_CIPHER_CKIP = 3, | ||
686 | ATH9K_CIPHER_TKIP = 4, | ||
687 | ATH9K_CIPHER_CLR = 5, | ||
688 | ATH9K_CIPHER_MIC = 127 | ||
689 | }; | ||
690 | |||
691 | struct ath_hw; | 670 | struct ath_hw; |
692 | struct ath9k_channel; | 671 | struct ath9k_channel; |
693 | 672 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a2f7eb2a552..fa875d1c7e9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1769,7 +1769,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1769 | 1769 | ||
1770 | switch (cmd) { | 1770 | switch (cmd) { |
1771 | case SET_KEY: | 1771 | case SET_KEY: |
1772 | ret = ath9k_cmn_key_config(common, vif, sta, key); | 1772 | ret = ath_key_config(common, vif, sta, key); |
1773 | if (ret >= 0) { | 1773 | if (ret >= 0) { |
1774 | key->hw_key_idx = ret; | 1774 | key->hw_key_idx = ret; |
1775 | /* push IV and Michael MIC generation to stack */ | 1775 | /* push IV and Michael MIC generation to stack */ |
@@ -1783,7 +1783,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1783 | } | 1783 | } |
1784 | break; | 1784 | break; |
1785 | case DISABLE_KEY: | 1785 | case DISABLE_KEY: |
1786 | ath9k_cmn_key_delete(common, key); | 1786 | ath_key_delete(common, key); |
1787 | break; | 1787 | break; |
1788 | default: | 1788 | default: |
1789 | ret = -EINVAL; | 1789 | ret = -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index e724c2c1ae2..17969af842f 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -45,9 +45,6 @@ | |||
45 | } \ | 45 | } \ |
46 | } while (0) | 46 | } while (0) |
47 | 47 | ||
48 | #define ATH9K_IS_MIC_ENABLED(ah) \ | ||
49 | ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE) | ||
50 | |||
51 | #define ANTSWAP_AB 0x0001 | 48 | #define ANTSWAP_AB 0x0001 |
52 | #define REDUCE_CHAIN_0 0x00000050 | 49 | #define REDUCE_CHAIN_0 0x00000050 |
53 | #define REDUCE_CHAIN_1 0x00000051 | 50 | #define REDUCE_CHAIN_1 0x00000051 |