]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/ath/key.c
Merge branch 'for-2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc...
[karo-tx-linux.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
24 #define REG_READ                        (common->ops->read)
25 #define REG_WRITE(_ah, _reg, _val)      (common->ops->write)(_ah, _val, _reg)
26
27 #define IEEE80211_WEP_NKID      4       /* number of key ids */
28
29 /************************/
30 /* Key Cache Management */
31 /************************/
32
33 bool ath_hw_keyreset(struct ath_common *common, u16 entry)
34 {
35         u32 keyType;
36         void *ah = common->ah;
37
38         if (entry >= common->keymax) {
39                 ath_err(common, "keycache entry %u out of range\n", entry);
40                 return false;
41         }
42
43         keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
44
45         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
46         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
47         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
48         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
49         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
50         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
51         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
52         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
53
54         if (keyType == AR_KEYTABLE_TYPE_TKIP) {
55                 u16 micentry = entry + 64;
56
57                 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
58                 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
59                 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
60                 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
61                 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
62                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
63                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
64                                   AR_KEYTABLE_TYPE_CLR);
65                 }
66
67         }
68
69         return true;
70 }
71 EXPORT_SYMBOL(ath_hw_keyreset);
72
73 static bool ath_hw_keysetmac(struct ath_common *common,
74                              u16 entry, const u8 *mac)
75 {
76         u32 macHi, macLo;
77         u32 unicast_flag = AR_KEYTABLE_VALID;
78         void *ah = common->ah;
79
80         if (entry >= common->keymax) {
81                 ath_err(common, "keycache entry %u out of range\n", entry);
82                 return false;
83         }
84
85         if (mac != NULL) {
86                 /*
87                  * AR_KEYTABLE_VALID indicates that the address is a unicast
88                  * address, which must match the transmitter address for
89                  * decrypting frames.
90                  * Not setting this bit allows the hardware to use the key
91                  * for multicast frame decryption.
92                  */
93                 if (mac[0] & 0x01)
94                         unicast_flag = 0;
95
96                 macHi = (mac[5] << 8) | mac[4];
97                 macLo = (mac[3] << 24) |
98                         (mac[2] << 16) |
99                         (mac[1] << 8) |
100                         mac[0];
101                 macLo >>= 1;
102                 macLo |= (macHi & 1) << 31;
103                 macHi >>= 1;
104         } else {
105                 macLo = macHi = 0;
106         }
107         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
108         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
109
110         return true;
111 }
112
113 static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
114                                       const struct ath_keyval *k,
115                                       const u8 *mac)
116 {
117         void *ah = common->ah;
118         u32 key0, key1, key2, key3, key4;
119         u32 keyType;
120
121         if (entry >= common->keymax) {
122                 ath_err(common, "keycache entry %u out of range\n", entry);
123                 return false;
124         }
125
126         switch (k->kv_type) {
127         case ATH_CIPHER_AES_OCB:
128                 keyType = AR_KEYTABLE_TYPE_AES;
129                 break;
130         case ATH_CIPHER_AES_CCM:
131                 if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
132                         ath_dbg(common, ATH_DBG_ANY,
133                                 "AES-CCM not supported by this mac rev\n");
134                         return false;
135                 }
136                 keyType = AR_KEYTABLE_TYPE_CCM;
137                 break;
138         case ATH_CIPHER_TKIP:
139                 keyType = AR_KEYTABLE_TYPE_TKIP;
140                 if (entry + 64 >= common->keymax) {
141                         ath_dbg(common, ATH_DBG_ANY,
142                                 "entry %u inappropriate for TKIP\n", entry);
143                         return false;
144                 }
145                 break;
146         case ATH_CIPHER_WEP:
147                 if (k->kv_len < WLAN_KEY_LEN_WEP40) {
148                         ath_dbg(common, ATH_DBG_ANY,
149                                 "WEP key length %u too small\n", k->kv_len);
150                         return false;
151                 }
152                 if (k->kv_len <= WLAN_KEY_LEN_WEP40)
153                         keyType = AR_KEYTABLE_TYPE_40;
154                 else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
155                         keyType = AR_KEYTABLE_TYPE_104;
156                 else
157                         keyType = AR_KEYTABLE_TYPE_128;
158                 break;
159         case ATH_CIPHER_CLR:
160                 keyType = AR_KEYTABLE_TYPE_CLR;
161                 break;
162         default:
163                 ath_err(common, "cipher %u not supported\n", k->kv_type);
164                 return false;
165         }
166
167         key0 = get_unaligned_le32(k->kv_val + 0);
168         key1 = get_unaligned_le16(k->kv_val + 4);
169         key2 = get_unaligned_le32(k->kv_val + 6);
170         key3 = get_unaligned_le16(k->kv_val + 10);
171         key4 = get_unaligned_le32(k->kv_val + 12);
172         if (k->kv_len <= WLAN_KEY_LEN_WEP104)
173                 key4 &= 0xff;
174
175         /*
176          * Note: Key cache registers access special memory area that requires
177          * two 32-bit writes to actually update the values in the internal
178          * memory. Consequently, the exact order and pairs used here must be
179          * maintained.
180          */
181
182         if (keyType == AR_KEYTABLE_TYPE_TKIP) {
183                 u16 micentry = entry + 64;
184
185                 /*
186                  * Write inverted key[47:0] first to avoid Michael MIC errors
187                  * on frames that could be sent or received at the same time.
188                  * The correct key will be written in the end once everything
189                  * else is ready.
190                  */
191                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
192                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
193
194                 /* Write key[95:48] */
195                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
196                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
197
198                 /* Write key[127:96] and key type */
199                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
200                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
201
202                 /* Write MAC address for the entry */
203                 (void) ath_hw_keysetmac(common, entry, mac);
204
205                 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
206                         /*
207                          * TKIP uses two key cache entries:
208                          * Michael MIC TX/RX keys in the same key cache entry
209                          * (idx = main index + 64):
210                          * key0 [31:0] = RX key [31:0]
211                          * key1 [15:0] = TX key [31:16]
212                          * key1 [31:16] = reserved
213                          * key2 [31:0] = RX key [63:32]
214                          * key3 [15:0] = TX key [15:0]
215                          * key3 [31:16] = reserved
216                          * key4 [31:0] = TX key [63:32]
217                          */
218                         u32 mic0, mic1, mic2, mic3, mic4;
219
220                         mic0 = get_unaligned_le32(k->kv_mic + 0);
221                         mic2 = get_unaligned_le32(k->kv_mic + 4);
222                         mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
223                         mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
224                         mic4 = get_unaligned_le32(k->kv_txmic + 4);
225
226                         /* Write RX[31:0] and TX[31:16] */
227                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
228                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
229
230                         /* Write RX[63:32] and TX[15:0] */
231                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
232                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
233
234                         /* Write TX[63:32] and keyType(reserved) */
235                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
236                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
237                                   AR_KEYTABLE_TYPE_CLR);
238
239                 } else {
240                         /*
241                          * TKIP uses four key cache entries (two for group
242                          * keys):
243                          * Michael MIC TX/RX keys are in different key cache
244                          * entries (idx = main index + 64 for TX and
245                          * main index + 32 + 96 for RX):
246                          * key0 [31:0] = TX/RX MIC key [31:0]
247                          * key1 [31:0] = reserved
248                          * key2 [31:0] = TX/RX MIC key [63:32]
249                          * key3 [31:0] = reserved
250                          * key4 [31:0] = reserved
251                          *
252                          * Upper layer code will call this function separately
253                          * for TX and RX keys when these registers offsets are
254                          * used.
255                          */
256                         u32 mic0, mic2;
257
258                         mic0 = get_unaligned_le32(k->kv_mic + 0);
259                         mic2 = get_unaligned_le32(k->kv_mic + 4);
260
261                         /* Write MIC key[31:0] */
262                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
263                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
264
265                         /* Write MIC key[63:32] */
266                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
267                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
268
269                         /* Write TX[63:32] and keyType(reserved) */
270                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
271                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
272                                   AR_KEYTABLE_TYPE_CLR);
273                 }
274
275                 /* MAC address registers are reserved for the MIC entry */
276                 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
277                 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
278
279                 /*
280                  * Write the correct (un-inverted) key[47:0] last to enable
281                  * TKIP now that all other registers are set with correct
282                  * values.
283                  */
284                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
285                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
286         } else {
287                 /* Write key[47:0] */
288                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
289                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
290
291                 /* Write key[95:48] */
292                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
293                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
294
295                 /* Write key[127:96] and key type */
296                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
297                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
298
299                 /* Write MAC address for the entry */
300                 (void) ath_hw_keysetmac(common, entry, mac);
301         }
302
303         return true;
304 }
305
306 static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
307                            struct ath_keyval *hk, const u8 *addr,
308                            bool authenticator)
309 {
310         const u8 *key_rxmic;
311         const u8 *key_txmic;
312
313         key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
314         key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
315
316         if (addr == NULL) {
317                 /*
318                  * Group key installation - only two key cache entries are used
319                  * regardless of splitmic capability since group key is only
320                  * used either for TX or RX.
321                  */
322                 if (authenticator) {
323                         memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
324                         memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
325                 } else {
326                         memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
327                         memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
328                 }
329                 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
330         }
331         if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
332                 /* TX and RX keys share the same key cache entry. */
333                 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
334                 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
335                 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
336         }
337
338         /* Separate key cache entries for TX and RX */
339
340         /* TX key goes at first index, RX key at +32. */
341         memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
342         if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
343                 /* TX MIC entry failed. No need to proceed further */
344                 ath_err(common, "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);