ath: make ath_hw_keysetmac() static
[pandora-kernel.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 static bool ath_hw_keysetmac(struct ath_common *common,
71                              u16 entry, const u8 *mac)
72 {
73         u32 macHi, macLo;
74         u32 unicast_flag = AR_KEYTABLE_VALID;
75         void *ah = common->ah;
76
77         if (entry >= common->keymax) {
78                 ath_print(common, ATH_DBG_FATAL,
79                           "keychache entry %u out of range\n", entry);
80                 return false;
81         }
82
83         if (mac != NULL) {
84                 /*
85                  * AR_KEYTABLE_VALID indicates that the address is a unicast
86                  * address, which must match the transmitter address for
87                  * decrypting frames.
88                  * Not setting this bit allows the hardware to use the key
89                  * for multicast frame decryption.
90                  */
91                 if (mac[0] & 0x01)
92                         unicast_flag = 0;
93
94                 macHi = (mac[5] << 8) | mac[4];
95                 macLo = (mac[3] << 24) |
96                         (mac[2] << 16) |
97                         (mac[1] << 8) |
98                         mac[0];
99                 macLo >>= 1;
100                 macLo |= (macHi & 1) << 31;
101                 macHi >>= 1;
102         } else {
103                 macLo = macHi = 0;
104         }
105         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
106         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
107
108         return true;
109 }
110
111 bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
112                                  const struct ath_keyval *k,
113                                  const u8 *mac)
114 {
115         void *ah = common->ah;
116         u32 key0, key1, key2, key3, key4;
117         u32 keyType;
118
119         if (entry >= common->keymax) {
120                 ath_print(common, ATH_DBG_FATAL,
121                           "keycache entry %u out of range\n", entry);
122                 return false;
123         }
124
125         switch (k->kv_type) {
126         case ATH_CIPHER_AES_OCB:
127                 keyType = AR_KEYTABLE_TYPE_AES;
128                 break;
129         case ATH_CIPHER_AES_CCM:
130                 if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
131                         ath_print(common, ATH_DBG_ANY,
132                                   "AES-CCM not supported by this mac rev\n");
133                         return false;
134                 }
135                 keyType = AR_KEYTABLE_TYPE_CCM;
136                 break;
137         case ATH_CIPHER_TKIP:
138                 keyType = AR_KEYTABLE_TYPE_TKIP;
139                 if (entry + 64 >= common->keymax) {
140                         ath_print(common, ATH_DBG_ANY,
141                                   "entry %u inappropriate for TKIP\n", entry);
142                         return false;
143                 }
144                 break;
145         case ATH_CIPHER_WEP:
146                 if (k->kv_len < WLAN_KEY_LEN_WEP40) {
147                         ath_print(common, ATH_DBG_ANY,
148                                   "WEP key length %u too small\n", k->kv_len);
149                         return false;
150                 }
151                 if (k->kv_len <= WLAN_KEY_LEN_WEP40)
152                         keyType = AR_KEYTABLE_TYPE_40;
153                 else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
154                         keyType = AR_KEYTABLE_TYPE_104;
155                 else
156                         keyType = AR_KEYTABLE_TYPE_128;
157                 break;
158         case ATH_CIPHER_CLR:
159                 keyType = AR_KEYTABLE_TYPE_CLR;
160                 break;
161         default:
162                 ath_print(common, ATH_DBG_FATAL,
163                           "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_print(common, ATH_DBG_FATAL,
345                           "Setting TX MIC Key Failed\n");
346                 return 0;
347         }
348
349         memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
350         /* XXX delete tx key on failure? */
351         return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
352 }
353
354 static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
355 {
356         int i;
357
358         for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
359                 if (test_bit(i, common->keymap) ||
360                     test_bit(i + 64, common->keymap))
361                         continue; /* At least one part of TKIP key allocated */
362                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
363                     (test_bit(i + 32, common->keymap) ||
364                      test_bit(i + 64 + 32, common->keymap)))
365                         continue; /* At least one part of TKIP key allocated */
366
367                 /* Found a free slot for a TKIP key */
368                 return i;
369         }
370         return -1;
371 }
372
373 static int ath_reserve_key_cache_slot(struct ath_common *common,
374                                       u32 cipher)
375 {
376         int i;
377
378         if (cipher == WLAN_CIPHER_SUITE_TKIP)
379                 return ath_reserve_key_cache_slot_tkip(common);
380
381         /* First, try to find slots that would not be available for TKIP. */
382         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
383                 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
384                         if (!test_bit(i, common->keymap) &&
385                             (test_bit(i + 32, common->keymap) ||
386                              test_bit(i + 64, common->keymap) ||
387                              test_bit(i + 64 + 32, common->keymap)))
388                                 return i;
389                         if (!test_bit(i + 32, common->keymap) &&
390                             (test_bit(i, common->keymap) ||
391                              test_bit(i + 64, common->keymap) ||
392                              test_bit(i + 64 + 32, common->keymap)))
393                                 return i + 32;
394                         if (!test_bit(i + 64, common->keymap) &&
395                             (test_bit(i , common->keymap) ||
396                              test_bit(i + 32, common->keymap) ||
397                              test_bit(i + 64 + 32, common->keymap)))
398                                 return i + 64;
399                         if (!test_bit(i + 64 + 32, common->keymap) &&
400                             (test_bit(i, common->keymap) ||
401                              test_bit(i + 32, common->keymap) ||
402                              test_bit(i + 64, common->keymap)))
403                                 return i + 64 + 32;
404                 }
405         } else {
406                 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
407                         if (!test_bit(i, common->keymap) &&
408                             test_bit(i + 64, common->keymap))
409                                 return i;
410                         if (test_bit(i, common->keymap) &&
411                             !test_bit(i + 64, common->keymap))
412                                 return i + 64;
413                 }
414         }
415
416         /* No partially used TKIP slots, pick any available slot */
417         for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
418                 /* Do not allow slots that could be needed for TKIP group keys
419                  * to be used. This limitation could be removed if we know that
420                  * TKIP will not be used. */
421                 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
422                         continue;
423                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
424                         if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
425                                 continue;
426                         if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
427                                 continue;
428                 }
429
430                 if (!test_bit(i, common->keymap))
431                         return i; /* Found a free slot for a key */
432         }
433
434         /* No free slot found */
435         return -1;
436 }
437
438 /*
439  * Configure encryption in the HW.
440  */
441 int ath_key_config(struct ath_common *common,
442                           struct ieee80211_vif *vif,
443                           struct ieee80211_sta *sta,
444                           struct ieee80211_key_conf *key)
445 {
446         struct ath_keyval hk;
447         const u8 *mac = NULL;
448         u8 gmac[ETH_ALEN];
449         int ret = 0;
450         int idx;
451
452         memset(&hk, 0, sizeof(hk));
453
454         switch (key->cipher) {
455         case WLAN_CIPHER_SUITE_WEP40:
456         case WLAN_CIPHER_SUITE_WEP104:
457                 hk.kv_type = ATH_CIPHER_WEP;
458                 break;
459         case WLAN_CIPHER_SUITE_TKIP:
460                 hk.kv_type = ATH_CIPHER_TKIP;
461                 break;
462         case WLAN_CIPHER_SUITE_CCMP:
463                 hk.kv_type = ATH_CIPHER_AES_CCM;
464                 break;
465         default:
466                 return -EOPNOTSUPP;
467         }
468
469         hk.kv_len = key->keylen;
470         memcpy(hk.kv_val, key->key, key->keylen);
471
472         if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
473                 switch (vif->type) {
474                 case NL80211_IFTYPE_AP:
475                         memcpy(gmac, vif->addr, ETH_ALEN);
476                         gmac[0] |= 0x01;
477                         mac = gmac;
478                         idx = ath_reserve_key_cache_slot(common, key->cipher);
479                         break;
480                 case NL80211_IFTYPE_ADHOC:
481                         if (!sta) {
482                                 idx = key->keyidx;
483                                 break;
484                         }
485                         memcpy(gmac, sta->addr, ETH_ALEN);
486                         gmac[0] |= 0x01;
487                         mac = gmac;
488                         idx = ath_reserve_key_cache_slot(common, key->cipher);
489                         break;
490                 default:
491                         idx = key->keyidx;
492                         break;
493                 }
494         } else if (key->keyidx) {
495                 if (WARN_ON(!sta))
496                         return -EOPNOTSUPP;
497                 mac = sta->addr;
498
499                 if (vif->type != NL80211_IFTYPE_AP) {
500                         /* Only keyidx 0 should be used with unicast key, but
501                          * allow this for client mode for now. */
502                         idx = key->keyidx;
503                 } else
504                         return -EIO;
505         } else {
506                 if (WARN_ON(!sta))
507                         return -EOPNOTSUPP;
508                 mac = sta->addr;
509
510                 idx = ath_reserve_key_cache_slot(common, key->cipher);
511         }
512
513         if (idx < 0)
514                 return -ENOSPC; /* no free key cache entries */
515
516         if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
517                 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
518                                       vif->type == NL80211_IFTYPE_AP);
519         else
520                 ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
521
522         if (!ret)
523                 return -EIO;
524
525         set_bit(idx, common->keymap);
526         if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
527                 set_bit(idx + 64, common->keymap);
528                 set_bit(idx, common->tkip_keymap);
529                 set_bit(idx + 64, common->tkip_keymap);
530                 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
531                         set_bit(idx + 32, common->keymap);
532                         set_bit(idx + 64 + 32, common->keymap);
533                         set_bit(idx + 32, common->tkip_keymap);
534                         set_bit(idx + 64 + 32, common->tkip_keymap);
535                 }
536         }
537
538         return idx;
539 }
540 EXPORT_SYMBOL(ath_key_config);
541
542 /*
543  * Delete Key.
544  */
545 void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
546 {
547         ath_hw_keyreset(common, key->hw_key_idx);
548         if (key->hw_key_idx < IEEE80211_WEP_NKID)
549                 return;
550
551         clear_bit(key->hw_key_idx, common->keymap);
552         if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
553                 return;
554
555         clear_bit(key->hw_key_idx + 64, common->keymap);
556
557         clear_bit(key->hw_key_idx, common->tkip_keymap);
558         clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
559
560         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
561                 ath_hw_keyreset(common, key->hw_key_idx + 32);
562                 clear_bit(key->hw_key_idx + 32, common->keymap);
563                 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
564
565                 clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
566                 clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
567         }
568 }
569 EXPORT_SYMBOL(ath_key_delete);