]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/ath/key.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[mv-sheeva.git] / drivers / net / wireless / ath / key.c
1 /*
2  * Copyright (c) 2009 Atheros Communications Inc.
3  * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include <asm/unaligned.h>
19 #include <net/mac80211.h>
20
21 #include "ath.h"
22 #include "reg.h"
23 #include "debug.h"
24
25 #define REG_READ                        (common->ops->read)
26 #define REG_WRITE(_ah, _reg, _val)      (common->ops->write)(_ah, _val, _reg)
27
28 #define IEEE80211_WEP_NKID      4       /* number of key ids */
29
30 /************************/
31 /* Key Cache Management */
32 /************************/
33
34 bool ath_hw_keyreset(struct ath_common *common, u16 entry)
35 {
36         u32 keyType;
37         void *ah = common->ah;
38
39         if (entry >= common->keymax) {
40                 ath_print(common, ATH_DBG_FATAL,
41                           "keychache entry %u out of range\n", entry);
42                 return false;
43         }
44
45         keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
46
47         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
48         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
49         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
50         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
51         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
52         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
53         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
54         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
55
56         if (keyType == AR_KEYTABLE_TYPE_TKIP) {
57                 u16 micentry = entry + 64;
58
59                 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
60                 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
61                 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
62                 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
63
64         }
65
66         return true;
67 }
68 EXPORT_SYMBOL(ath_hw_keyreset);
69
70 bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
71 {
72         u32 macHi, macLo;
73         u32 unicast_flag = AR_KEYTABLE_VALID;
74         void *ah = common->ah;
75
76         if (entry >= common->keymax) {
77                 ath_print(common, ATH_DBG_FATAL,
78                           "keychache entry %u out of range\n", entry);
79                 return false;
80         }
81
82         if (mac != NULL) {
83                 /*
84                  * AR_KEYTABLE_VALID indicates that the address is a unicast
85                  * address, which must match the transmitter address for
86                  * decrypting frames.
87                  * Not setting this bit allows the hardware to use the key
88                  * for multicast frame decryption.
89                  */
90                 if (mac[0] & 0x01)
91                         unicast_flag = 0;
92
93                 macHi = (mac[5] << 8) | mac[4];
94                 macLo = (mac[3] << 24) |
95                         (mac[2] << 16) |
96                         (mac[1] << 8) |
97                         mac[0];
98                 macLo >>= 1;
99                 macLo |= (macHi & 1) << 31;
100                 macHi >>= 1;
101         } else {
102                 macLo = macHi = 0;
103         }
104         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
105         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
106
107         return true;
108 }
109
110 bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
111                                  const struct ath_keyval *k,
112                                  const u8 *mac)
113 {
114         void *ah = common->ah;
115         u32 key0, key1, key2, key3, key4;
116         u32 keyType;
117
118         if (entry >= common->keymax) {
119                 ath_print(common, ATH_DBG_FATAL,
120                           "keycache entry %u out of range\n", entry);
121                 return false;
122         }
123
124         switch (k->kv_type) {
125         case ATH_CIPHER_AES_OCB:
126                 keyType = AR_KEYTABLE_TYPE_AES;
127                 break;
128         case ATH_CIPHER_AES_CCM:
129                 if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
130                         ath_print(common, ATH_DBG_ANY,
131                                   "AES-CCM not supported by this mac rev\n");
132                         return false;
133                 }
134                 keyType = AR_KEYTABLE_TYPE_CCM;
135                 break;
136         case ATH_CIPHER_TKIP:
137                 keyType = AR_KEYTABLE_TYPE_TKIP;
138                 if (entry + 64 >= common->keymax) {
139                         ath_print(common, ATH_DBG_ANY,
140                                   "entry %u inappropriate for TKIP\n", entry);
141                         return false;
142                 }
143                 break;
144         case ATH_CIPHER_WEP:
145                 if (k->kv_len < WLAN_KEY_LEN_WEP40) {
146                         ath_print(common, ATH_DBG_ANY,
147                                   "WEP key length %u too small\n", k->kv_len);
148                         return false;
149                 }
150                 if (k->kv_len <= WLAN_KEY_LEN_WEP40)
151                         keyType = AR_KEYTABLE_TYPE_40;
152                 else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
153                         keyType = AR_KEYTABLE_TYPE_104;
154                 else
155                         keyType = AR_KEYTABLE_TYPE_128;
156                 break;
157         case ATH_CIPHER_CLR:
158                 keyType = AR_KEYTABLE_TYPE_CLR;
159                 break;
160         default:
161                 ath_print(common, ATH_DBG_FATAL,
162                           "cipher %u not supported\n", k->kv_type);
163                 return false;
164         }
165
166         key0 = get_unaligned_le32(k->kv_val + 0);
167         key1 = get_unaligned_le16(k->kv_val + 4);
168         key2 = get_unaligned_le32(k->kv_val + 6);
169         key3 = get_unaligned_le16(k->kv_val + 10);
170         key4 = get_unaligned_le32(k->kv_val + 12);
171         if (k->kv_len <= WLAN_KEY_LEN_WEP104)
172                 key4 &= 0xff;
173
174         /*
175          * Note: Key cache registers access special memory area that requires
176          * two 32-bit writes to actually update the values in the internal
177          * memory. Consequently, the exact order and pairs used here must be
178          * maintained.
179          */
180
181         if (keyType == AR_KEYTABLE_TYPE_TKIP) {
182                 u16 micentry = entry + 64;
183
184                 /*
185                  * Write inverted key[47:0] first to avoid Michael MIC errors
186                  * on frames that could be sent or received at the same time.
187                  * The correct key will be written in the end once everything
188                  * else is ready.
189                  */
190                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
191                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
192
193                 /* Write key[95:48] */
194                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
195                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
196
197                 /* Write key[127:96] and key type */
198                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
199                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
200
201                 /* Write MAC address for the entry */
202                 (void) ath_hw_keysetmac(common, entry, mac);
203
204                 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
205                         /*
206                          * TKIP uses two key cache entries:
207                          * Michael MIC TX/RX keys in the same key cache entry
208                          * (idx = main index + 64):
209                          * key0 [31:0] = RX key [31:0]
210                          * key1 [15:0] = TX key [31:16]
211                          * key1 [31:16] = reserved
212                          * key2 [31:0] = RX key [63:32]
213                          * key3 [15:0] = TX key [15:0]
214                          * key3 [31:16] = reserved
215                          * key4 [31:0] = TX key [63:32]
216                          */
217                         u32 mic0, mic1, mic2, mic3, mic4;
218
219                         mic0 = get_unaligned_le32(k->kv_mic + 0);
220                         mic2 = get_unaligned_le32(k->kv_mic + 4);
221                         mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
222                         mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
223                         mic4 = get_unaligned_le32(k->kv_txmic + 4);
224
225                         /* Write RX[31:0] and TX[31:16] */
226                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
227                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
228
229                         /* Write RX[63:32] and TX[15:0] */
230                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
231                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
232
233                         /* Write TX[63:32] and keyType(reserved) */
234                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
235                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
236                                   AR_KEYTABLE_TYPE_CLR);
237
238                 } else {
239                         /*
240                          * TKIP uses four key cache entries (two for group
241                          * keys):
242                          * Michael MIC TX/RX keys are in different key cache
243                          * entries (idx = main index + 64 for TX and
244                          * main index + 32 + 96 for RX):
245                          * key0 [31:0] = TX/RX MIC key [31:0]
246                          * key1 [31:0] = reserved
247                          * key2 [31:0] = TX/RX MIC key [63:32]
248                          * key3 [31:0] = reserved
249                          * key4 [31:0] = reserved
250                          *
251                          * Upper layer code will call this function separately
252                          * for TX and RX keys when these registers offsets are
253                          * used.
254                          */
255                         u32 mic0, mic2;
256
257                         mic0 = get_unaligned_le32(k->kv_mic + 0);
258                         mic2 = get_unaligned_le32(k->kv_mic + 4);
259
260                         /* Write MIC key[31:0] */
261                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
262                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
263
264                         /* Write MIC key[63:32] */
265                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
266                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
267
268                         /* Write TX[63:32] and keyType(reserved) */
269                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
270                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
271                                   AR_KEYTABLE_TYPE_CLR);
272                 }
273
274                 /* MAC address registers are reserved for the MIC entry */
275                 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
276                 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
277
278                 /*
279                  * Write the correct (un-inverted) key[47:0] last to enable
280                  * TKIP now that all other registers are set with correct
281                  * values.
282                  */
283                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
284                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
285         } else {
286                 /* Write key[47:0] */
287                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
288                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
289
290                 /* Write key[95:48] */
291                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
292                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
293
294                 /* Write key[127:96] and key type */
295                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
296                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
297
298                 /* Write MAC address for the entry */
299                 (void) ath_hw_keysetmac(common, entry, mac);
300         }
301
302         return true;
303 }
304
305 static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
306                            struct ath_keyval *hk, const u8 *addr,
307                            bool authenticator)
308 {
309         const u8 *key_rxmic;
310         const u8 *key_txmic;
311
312         key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
313         key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
314
315         if (addr == NULL) {
316                 /*
317                  * Group key installation - only two key cache entries are used
318                  * regardless of splitmic capability since group key is only
319                  * used either for TX or RX.
320                  */
321                 if (authenticator) {
322                         memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
323                         memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
324                 } else {
325                         memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
326                         memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
327                 }
328                 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
329         }
330         if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
331                 /* TX and RX keys share the same key cache entry. */
332                 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
333                 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
334                 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
335         }
336
337         /* Separate key cache entries for TX and RX */
338
339         /* TX key goes at first index, RX key at +32. */
340         memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
341         if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
342                 /* TX MIC entry failed. No need to proceed further */
343                 ath_print(common, ATH_DBG_FATAL,
344                           "Setting TX MIC Key Failed\n");
345                 return 0;
346         }
347
348         memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
349         /* XXX delete tx key on failure? */
350         return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
351 }
352
353 static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
354 {
355         int i;
356
357         for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
358                 if (test_bit(i, common->keymap) ||
359                     test_bit(i + 64, common->keymap))
360                         continue; /* At least one part of TKIP key allocated */
361                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
362                     (test_bit(i + 32, common->keymap) ||
363                      test_bit(i + 64 + 32, common->keymap)))
364                         continue; /* At least one part of TKIP key allocated */
365
366                 /* Found a free slot for a TKIP key */
367                 return i;
368         }
369         return -1;
370 }
371
372 static int ath_reserve_key_cache_slot(struct ath_common *common,
373                                       u32 cipher)
374 {
375         int i;
376
377         if (cipher == WLAN_CIPHER_SUITE_TKIP)
378                 return ath_reserve_key_cache_slot_tkip(common);
379
380         /* First, try to find slots that would not be available for TKIP. */
381         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
382                 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
383                         if (!test_bit(i, common->keymap) &&
384                             (test_bit(i + 32, common->keymap) ||
385                              test_bit(i + 64, common->keymap) ||
386                              test_bit(i + 64 + 32, common->keymap)))
387                                 return i;
388                         if (!test_bit(i + 32, common->keymap) &&
389                             (test_bit(i, common->keymap) ||
390                              test_bit(i + 64, common->keymap) ||
391                              test_bit(i + 64 + 32, common->keymap)))
392                                 return i + 32;
393                         if (!test_bit(i + 64, common->keymap) &&
394                             (test_bit(i , common->keymap) ||
395                              test_bit(i + 32, common->keymap) ||
396                              test_bit(i + 64 + 32, common->keymap)))
397                                 return i + 64;
398                         if (!test_bit(i + 64 + 32, common->keymap) &&
399                             (test_bit(i, common->keymap) ||
400                              test_bit(i + 32, common->keymap) ||
401                              test_bit(i + 64, common->keymap)))
402                                 return i + 64 + 32;
403                 }
404         } else {
405                 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
406                         if (!test_bit(i, common->keymap) &&
407                             test_bit(i + 64, common->keymap))
408                                 return i;
409                         if (test_bit(i, common->keymap) &&
410                             !test_bit(i + 64, common->keymap))
411                                 return i + 64;
412                 }
413         }
414
415         /* No partially used TKIP slots, pick any available slot */
416         for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
417                 /* Do not allow slots that could be needed for TKIP group keys
418                  * to be used. This limitation could be removed if we know that
419                  * TKIP will not be used. */
420                 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
421                         continue;
422                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
423                         if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
424                                 continue;
425                         if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
426                                 continue;
427                 }
428
429                 if (!test_bit(i, common->keymap))
430                         return i; /* Found a free slot for a key */
431         }
432
433         /* No free slot found */
434         return -1;
435 }
436
437 /*
438  * Configure encryption in the HW.
439  */
440 int ath_key_config(struct ath_common *common,
441                           struct ieee80211_vif *vif,
442                           struct ieee80211_sta *sta,
443                           struct ieee80211_key_conf *key)
444 {
445         struct ath_keyval hk;
446         const u8 *mac = NULL;
447         u8 gmac[ETH_ALEN];
448         int ret = 0;
449         int idx;
450
451         memset(&hk, 0, sizeof(hk));
452
453         switch (key->cipher) {
454         case WLAN_CIPHER_SUITE_WEP40:
455         case WLAN_CIPHER_SUITE_WEP104:
456                 hk.kv_type = ATH_CIPHER_WEP;
457                 break;
458         case WLAN_CIPHER_SUITE_TKIP:
459                 hk.kv_type = ATH_CIPHER_TKIP;
460                 break;
461         case WLAN_CIPHER_SUITE_CCMP:
462                 hk.kv_type = ATH_CIPHER_AES_CCM;
463                 break;
464         default:
465                 return -EOPNOTSUPP;
466         }
467
468         hk.kv_len = key->keylen;
469         memcpy(hk.kv_val, key->key, key->keylen);
470
471         if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
472                 switch (vif->type) {
473                 case NL80211_IFTYPE_AP:
474                         memcpy(gmac, vif->addr, ETH_ALEN);
475                         gmac[0] |= 0x01;
476                         mac = gmac;
477                         idx = ath_reserve_key_cache_slot(common, key->cipher);
478                         break;
479                 case NL80211_IFTYPE_ADHOC:
480                         if (!sta) {
481                                 idx = key->keyidx;
482                                 break;
483                         }
484                         memcpy(gmac, sta->addr, ETH_ALEN);
485                         gmac[0] |= 0x01;
486                         mac = gmac;
487                         idx = ath_reserve_key_cache_slot(common, key->cipher);
488                         break;
489                 default:
490                         idx = key->keyidx;
491                         break;
492                 }
493         } else if (key->keyidx) {
494                 if (WARN_ON(!sta))
495                         return -EOPNOTSUPP;
496                 mac = sta->addr;
497
498                 if (vif->type != NL80211_IFTYPE_AP) {
499                         /* Only keyidx 0 should be used with unicast key, but
500                          * allow this for client mode for now. */
501                         idx = key->keyidx;
502                 } else
503                         return -EIO;
504         } else {
505                 if (WARN_ON(!sta))
506                         return -EOPNOTSUPP;
507                 mac = sta->addr;
508
509                 idx = ath_reserve_key_cache_slot(common, key->cipher);
510         }
511
512         if (idx < 0)
513                 return -ENOSPC; /* no free key cache entries */
514
515         if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
516                 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
517                                       vif->type == NL80211_IFTYPE_AP);
518         else
519                 ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
520
521         if (!ret)
522                 return -EIO;
523
524         set_bit(idx, common->keymap);
525         if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
526                 set_bit(idx + 64, common->keymap);
527                 set_bit(idx, common->tkip_keymap);
528                 set_bit(idx + 64, common->tkip_keymap);
529                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
530                         set_bit(idx + 32, common->keymap);
531                         set_bit(idx + 64 + 32, common->keymap);
532                         set_bit(idx + 32, common->tkip_keymap);
533                         set_bit(idx + 64 + 32, common->tkip_keymap);
534                 }
535         }
536
537         return idx;
538 }
539 EXPORT_SYMBOL(ath_key_config);
540
541 /*
542  * Delete Key.
543  */
544 void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
545 {
546         ath_hw_keyreset(common, key->hw_key_idx);
547         if (key->hw_key_idx < IEEE80211_WEP_NKID)
548                 return;
549
550         clear_bit(key->hw_key_idx, common->keymap);
551         if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
552                 return;
553
554         clear_bit(key->hw_key_idx + 64, common->keymap);
555
556         clear_bit(key->hw_key_idx, common->tkip_keymap);
557         clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
558
559         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
560                 ath_hw_keyreset(common, key->hw_key_idx + 32);
561                 clear_bit(key->hw_key_idx + 32, common->keymap);
562                 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
563
564                 clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
565                 clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
566         }
567 }
568 EXPORT_SYMBOL(ath_key_delete);