Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2009 Atheros Communications Inc.
0003  * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
0004  *
0005  * Permission to use, copy, modify, and/or distribute this software for any
0006  * purpose with or without fee is hereby granted, provided that the above
0007  * copyright notice and this permission notice appear in all copies.
0008  *
0009  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0010  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0011  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0012  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0013  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0014  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0015  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0016  */
0017 
0018 #include <linux/export.h>
0019 #include <asm/unaligned.h>
0020 #include <net/mac80211.h>
0021 
0022 #include "ath.h"
0023 #include "reg.h"
0024 
0025 #define REG_READ            (common->ops->read)
0026 #define REG_WRITE(_ah, _reg, _val)  (common->ops->write)(_ah, _val, _reg)
0027 #define ENABLE_REGWRITE_BUFFER(_ah)         \
0028     if (common->ops->enable_write_buffer)       \
0029         common->ops->enable_write_buffer((_ah));
0030 
0031 #define REGWRITE_BUFFER_FLUSH(_ah)          \
0032     if (common->ops->write_flush)           \
0033         common->ops->write_flush((_ah));
0034 
0035 
0036 #define IEEE80211_WEP_NKID      4       /* number of key ids */
0037 
0038 /************************/
0039 /* Key Cache Management */
0040 /************************/
0041 
0042 bool ath_hw_keyreset(struct ath_common *common, u16 entry)
0043 {
0044     u32 keyType;
0045     void *ah = common->ah;
0046 
0047     if (entry >= common->keymax) {
0048         ath_err(common, "keyreset: keycache entry %u out of range\n",
0049             entry);
0050         return false;
0051     }
0052 
0053     keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
0054 
0055     ENABLE_REGWRITE_BUFFER(ah);
0056 
0057     REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
0058     REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
0059     REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
0060     REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
0061     REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
0062     REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
0063     REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
0064     REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
0065 
0066     if (keyType == AR_KEYTABLE_TYPE_TKIP) {
0067         u16 micentry = entry + 64;
0068 
0069         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
0070         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
0071         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
0072         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
0073         if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0074             REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
0075             REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0076                   AR_KEYTABLE_TYPE_CLR);
0077         }
0078 
0079     }
0080 
0081     REGWRITE_BUFFER_FLUSH(ah);
0082 
0083     return true;
0084 }
0085 EXPORT_SYMBOL(ath_hw_keyreset);
0086 
0087 bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
0088 {
0089     u32 macHi, macLo;
0090     u32 unicast_flag = AR_KEYTABLE_VALID;
0091     void *ah = common->ah;
0092 
0093     if (entry >= common->keymax) {
0094         ath_err(common, "keysetmac: keycache entry %u out of range\n",
0095             entry);
0096         return false;
0097     }
0098 
0099     if (mac != NULL) {
0100         /*
0101          * AR_KEYTABLE_VALID indicates that the address is a unicast
0102          * address, which must match the transmitter address for
0103          * decrypting frames.
0104          * Not setting this bit allows the hardware to use the key
0105          * for multicast frame decryption.
0106          */
0107         if (mac[0] & 0x01)
0108             unicast_flag = 0;
0109 
0110         macLo = get_unaligned_le32(mac);
0111         macHi = get_unaligned_le16(mac + 4);
0112         macLo >>= 1;
0113         macLo |= (macHi & 1) << 31;
0114         macHi >>= 1;
0115     } else {
0116         macLo = macHi = 0;
0117     }
0118     ENABLE_REGWRITE_BUFFER(ah);
0119 
0120     REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
0121     REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
0122 
0123     REGWRITE_BUFFER_FLUSH(ah);
0124 
0125     return true;
0126 }
0127 EXPORT_SYMBOL(ath_hw_keysetmac);
0128 
0129 static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
0130                       const struct ath_keyval *k,
0131                       const u8 *mac)
0132 {
0133     void *ah = common->ah;
0134     u32 key0, key1, key2, key3, key4;
0135     u32 keyType;
0136 
0137     if (entry >= common->keymax) {
0138         ath_err(common, "set-entry: keycache entry %u out of range\n",
0139             entry);
0140         return false;
0141     }
0142 
0143     switch (k->kv_type) {
0144     case ATH_CIPHER_AES_OCB:
0145         keyType = AR_KEYTABLE_TYPE_AES;
0146         break;
0147     case ATH_CIPHER_AES_CCM:
0148         if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
0149             ath_dbg(common, ANY,
0150                 "AES-CCM not supported by this mac rev\n");
0151             return false;
0152         }
0153         keyType = AR_KEYTABLE_TYPE_CCM;
0154         break;
0155     case ATH_CIPHER_TKIP:
0156         keyType = AR_KEYTABLE_TYPE_TKIP;
0157         if (entry + 64 >= common->keymax) {
0158             ath_dbg(common, ANY,
0159                 "entry %u inappropriate for TKIP\n", entry);
0160             return false;
0161         }
0162         break;
0163     case ATH_CIPHER_WEP:
0164         if (k->kv_len < WLAN_KEY_LEN_WEP40) {
0165             ath_dbg(common, ANY, "WEP key length %u too small\n",
0166                 k->kv_len);
0167             return false;
0168         }
0169         if (k->kv_len <= WLAN_KEY_LEN_WEP40)
0170             keyType = AR_KEYTABLE_TYPE_40;
0171         else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
0172             keyType = AR_KEYTABLE_TYPE_104;
0173         else
0174             keyType = AR_KEYTABLE_TYPE_128;
0175         break;
0176     case ATH_CIPHER_CLR:
0177         keyType = AR_KEYTABLE_TYPE_CLR;
0178         break;
0179     default:
0180         ath_err(common, "cipher %u not supported\n", k->kv_type);
0181         return false;
0182     }
0183 
0184     key0 = get_unaligned_le32(k->kv_val + 0);
0185     key1 = get_unaligned_le16(k->kv_val + 4);
0186     key2 = get_unaligned_le32(k->kv_val + 6);
0187     key3 = get_unaligned_le16(k->kv_val + 10);
0188     key4 = get_unaligned_le32(k->kv_val + 12);
0189     if (k->kv_len <= WLAN_KEY_LEN_WEP104)
0190         key4 &= 0xff;
0191 
0192     /*
0193      * Note: Key cache registers access special memory area that requires
0194      * two 32-bit writes to actually update the values in the internal
0195      * memory. Consequently, the exact order and pairs used here must be
0196      * maintained.
0197      */
0198 
0199     if (keyType == AR_KEYTABLE_TYPE_TKIP) {
0200         u16 micentry = entry + 64;
0201 
0202         /*
0203          * Write inverted key[47:0] first to avoid Michael MIC errors
0204          * on frames that could be sent or received at the same time.
0205          * The correct key will be written in the end once everything
0206          * else is ready.
0207          */
0208         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
0209         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
0210 
0211         /* Write key[95:48] */
0212         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
0213         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
0214 
0215         /* Write key[127:96] and key type */
0216         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
0217         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
0218 
0219         /* Write MAC address for the entry */
0220         (void) ath_hw_keysetmac(common, entry, mac);
0221 
0222         if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0223             /*
0224              * TKIP uses two key cache entries:
0225              * Michael MIC TX/RX keys in the same key cache entry
0226              * (idx = main index + 64):
0227              * key0 [31:0] = RX key [31:0]
0228              * key1 [15:0] = TX key [31:16]
0229              * key1 [31:16] = reserved
0230              * key2 [31:0] = RX key [63:32]
0231              * key3 [15:0] = TX key [15:0]
0232              * key3 [31:16] = reserved
0233              * key4 [31:0] = TX key [63:32]
0234              */
0235             u32 mic0, mic1, mic2, mic3, mic4;
0236 
0237             mic0 = get_unaligned_le32(k->kv_mic + 0);
0238             mic2 = get_unaligned_le32(k->kv_mic + 4);
0239             mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
0240             mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
0241             mic4 = get_unaligned_le32(k->kv_txmic + 4);
0242 
0243             ENABLE_REGWRITE_BUFFER(ah);
0244 
0245             /* Write RX[31:0] and TX[31:16] */
0246             REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
0247             REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
0248 
0249             /* Write RX[63:32] and TX[15:0] */
0250             REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
0251             REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
0252 
0253             /* Write TX[63:32] and keyType(reserved) */
0254             REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
0255             REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0256                   AR_KEYTABLE_TYPE_CLR);
0257 
0258             REGWRITE_BUFFER_FLUSH(ah);
0259 
0260         } else {
0261             /*
0262              * TKIP uses four key cache entries (two for group
0263              * keys):
0264              * Michael MIC TX/RX keys are in different key cache
0265              * entries (idx = main index + 64 for TX and
0266              * main index + 32 + 96 for RX):
0267              * key0 [31:0] = TX/RX MIC key [31:0]
0268              * key1 [31:0] = reserved
0269              * key2 [31:0] = TX/RX MIC key [63:32]
0270              * key3 [31:0] = reserved
0271              * key4 [31:0] = reserved
0272              *
0273              * Upper layer code will call this function separately
0274              * for TX and RX keys when these registers offsets are
0275              * used.
0276              */
0277             u32 mic0, mic2;
0278 
0279             mic0 = get_unaligned_le32(k->kv_mic + 0);
0280             mic2 = get_unaligned_le32(k->kv_mic + 4);
0281 
0282             ENABLE_REGWRITE_BUFFER(ah);
0283 
0284             /* Write MIC key[31:0] */
0285             REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
0286             REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
0287 
0288             /* Write MIC key[63:32] */
0289             REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
0290             REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
0291 
0292             /* Write TX[63:32] and keyType(reserved) */
0293             REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
0294             REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0295                   AR_KEYTABLE_TYPE_CLR);
0296 
0297             REGWRITE_BUFFER_FLUSH(ah);
0298         }
0299 
0300         ENABLE_REGWRITE_BUFFER(ah);
0301 
0302         /* MAC address registers are reserved for the MIC entry */
0303         REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
0304         REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
0305 
0306         /*
0307          * Write the correct (un-inverted) key[47:0] last to enable
0308          * TKIP now that all other registers are set with correct
0309          * values.
0310          */
0311         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
0312         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
0313 
0314         REGWRITE_BUFFER_FLUSH(ah);
0315     } else {
0316         ENABLE_REGWRITE_BUFFER(ah);
0317 
0318         /* Write key[47:0] */
0319         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
0320         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
0321 
0322         /* Write key[95:48] */
0323         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
0324         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
0325 
0326         /* Write key[127:96] and key type */
0327         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
0328         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
0329 
0330         REGWRITE_BUFFER_FLUSH(ah);
0331 
0332         /* Write MAC address for the entry */
0333         (void) ath_hw_keysetmac(common, entry, mac);
0334     }
0335 
0336     return true;
0337 }
0338 
0339 static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
0340                struct ath_keyval *hk, const u8 *addr,
0341                bool authenticator)
0342 {
0343     const u8 *key_rxmic;
0344     const u8 *key_txmic;
0345 
0346     key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
0347     key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
0348 
0349     if (addr == NULL) {
0350         /*
0351          * Group key installation - only two key cache entries are used
0352          * regardless of splitmic capability since group key is only
0353          * used either for TX or RX.
0354          */
0355         if (authenticator) {
0356             memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
0357             memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
0358         } else {
0359             memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0360             memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
0361         }
0362         return ath_hw_set_keycache_entry(common, keyix, hk, addr);
0363     }
0364     if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0365         /* TX and RX keys share the same key cache entry. */
0366         memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0367         memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
0368         return ath_hw_set_keycache_entry(common, keyix, hk, addr);
0369     }
0370 
0371     /* Separate key cache entries for TX and RX */
0372 
0373     /* TX key goes at first index, RX key at +32. */
0374     memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
0375     if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
0376         /* TX MIC entry failed. No need to proceed further */
0377         ath_err(common, "Setting TX MIC Key Failed\n");
0378         return 0;
0379     }
0380 
0381     memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0382     /* XXX delete tx key on failure? */
0383     return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
0384 }
0385 
0386 static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
0387 {
0388     int i;
0389 
0390     for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
0391         if (test_bit(i, common->keymap) ||
0392             test_bit(i + 64, common->keymap))
0393             continue; /* At least one part of TKIP key allocated */
0394         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
0395             (test_bit(i + 32, common->keymap) ||
0396              test_bit(i + 64 + 32, common->keymap)))
0397             continue; /* At least one part of TKIP key allocated */
0398 
0399         /* Found a free slot for a TKIP key */
0400         return i;
0401     }
0402     return -1;
0403 }
0404 
0405 static int ath_reserve_key_cache_slot(struct ath_common *common,
0406                       u32 cipher)
0407 {
0408     int i;
0409 
0410     if (cipher == WLAN_CIPHER_SUITE_TKIP)
0411         return ath_reserve_key_cache_slot_tkip(common);
0412 
0413     /* First, try to find slots that would not be available for TKIP. */
0414     if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0415         for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
0416             if (!test_bit(i, common->keymap) &&
0417                 (test_bit(i + 32, common->keymap) ||
0418                  test_bit(i + 64, common->keymap) ||
0419                  test_bit(i + 64 + 32, common->keymap)))
0420                 return i;
0421             if (!test_bit(i + 32, common->keymap) &&
0422                 (test_bit(i, common->keymap) ||
0423                  test_bit(i + 64, common->keymap) ||
0424                  test_bit(i + 64 + 32, common->keymap)))
0425                 return i + 32;
0426             if (!test_bit(i + 64, common->keymap) &&
0427                 (test_bit(i , common->keymap) ||
0428                  test_bit(i + 32, common->keymap) ||
0429                  test_bit(i + 64 + 32, common->keymap)))
0430                 return i + 64;
0431             if (!test_bit(i + 64 + 32, common->keymap) &&
0432                 (test_bit(i, common->keymap) ||
0433                  test_bit(i + 32, common->keymap) ||
0434                  test_bit(i + 64, common->keymap)))
0435                 return i + 64 + 32;
0436         }
0437     } else {
0438         for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
0439             if (!test_bit(i, common->keymap) &&
0440                 test_bit(i + 64, common->keymap))
0441                 return i;
0442             if (test_bit(i, common->keymap) &&
0443                 !test_bit(i + 64, common->keymap))
0444                 return i + 64;
0445         }
0446     }
0447 
0448     /* No partially used TKIP slots, pick any available slot */
0449     for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
0450         /* Do not allow slots that could be needed for TKIP group keys
0451          * to be used. This limitation could be removed if we know that
0452          * TKIP will not be used. */
0453         if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
0454             continue;
0455         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0456             if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
0457                 continue;
0458             if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
0459                 continue;
0460         }
0461 
0462         if (!test_bit(i, common->keymap))
0463             return i; /* Found a free slot for a key */
0464     }
0465 
0466     /* No free slot found */
0467     return -1;
0468 }
0469 
0470 /*
0471  * Configure encryption in the HW.
0472  */
0473 int ath_key_config(struct ath_common *common,
0474               struct ieee80211_vif *vif,
0475               struct ieee80211_sta *sta,
0476               struct ieee80211_key_conf *key)
0477 {
0478     struct ath_keyval hk;
0479     const u8 *mac = NULL;
0480     u8 gmac[ETH_ALEN];
0481     int ret = 0;
0482     int idx;
0483 
0484     memset(&hk, 0, sizeof(hk));
0485 
0486     switch (key->cipher) {
0487     case 0:
0488         hk.kv_type = ATH_CIPHER_CLR;
0489         break;
0490     case WLAN_CIPHER_SUITE_WEP40:
0491     case WLAN_CIPHER_SUITE_WEP104:
0492         hk.kv_type = ATH_CIPHER_WEP;
0493         break;
0494     case WLAN_CIPHER_SUITE_TKIP:
0495         hk.kv_type = ATH_CIPHER_TKIP;
0496         break;
0497     case WLAN_CIPHER_SUITE_CCMP:
0498         hk.kv_type = ATH_CIPHER_AES_CCM;
0499         break;
0500     default:
0501         return -EOPNOTSUPP;
0502     }
0503 
0504     hk.kv_len = key->keylen;
0505     if (key->keylen)
0506         memcpy(hk.kv_val, key->key, key->keylen);
0507 
0508     if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
0509         switch (vif->type) {
0510         case NL80211_IFTYPE_AP:
0511             memcpy(gmac, vif->addr, ETH_ALEN);
0512             gmac[0] |= 0x01;
0513             mac = gmac;
0514             idx = ath_reserve_key_cache_slot(common, key->cipher);
0515             break;
0516         case NL80211_IFTYPE_ADHOC:
0517             if (!sta) {
0518                 idx = key->keyidx;
0519                 break;
0520             }
0521             memcpy(gmac, sta->addr, ETH_ALEN);
0522             gmac[0] |= 0x01;
0523             mac = gmac;
0524             idx = ath_reserve_key_cache_slot(common, key->cipher);
0525             break;
0526         default:
0527             idx = key->keyidx;
0528             break;
0529         }
0530     } else if (key->keyidx) {
0531         if (WARN_ON(!sta))
0532             return -EOPNOTSUPP;
0533         mac = sta->addr;
0534 
0535         if (vif->type != NL80211_IFTYPE_AP) {
0536             /* Only keyidx 0 should be used with unicast key, but
0537              * allow this for client mode for now. */
0538             idx = key->keyidx;
0539         } else
0540             return -EIO;
0541     } else {
0542         if (WARN_ON(!sta))
0543             return -EOPNOTSUPP;
0544         mac = sta->addr;
0545 
0546         idx = ath_reserve_key_cache_slot(common, key->cipher);
0547     }
0548 
0549     if (idx < 0)
0550         return -ENOSPC; /* no free key cache entries */
0551 
0552     if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
0553         ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
0554                       vif->type == NL80211_IFTYPE_AP);
0555     else
0556         ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
0557 
0558     if (!ret)
0559         return -EIO;
0560 
0561     set_bit(idx, common->keymap);
0562     if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
0563         set_bit(idx, common->ccmp_keymap);
0564 
0565     if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
0566         set_bit(idx + 64, common->keymap);
0567         set_bit(idx, common->tkip_keymap);
0568         set_bit(idx + 64, common->tkip_keymap);
0569         if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0570             set_bit(idx + 32, common->keymap);
0571             set_bit(idx + 64 + 32, common->keymap);
0572             set_bit(idx + 32, common->tkip_keymap);
0573             set_bit(idx + 64 + 32, common->tkip_keymap);
0574         }
0575     }
0576 
0577     return idx;
0578 }
0579 EXPORT_SYMBOL(ath_key_config);
0580 
0581 /*
0582  * Delete Key.
0583  */
0584 void ath_key_delete(struct ath_common *common, u8 hw_key_idx)
0585 {
0586     /* Leave CCMP and TKIP (main key) configured to avoid disabling
0587      * encryption for potentially pending frames already in a TXQ with the
0588      * keyix pointing to this key entry. Instead, only clear the MAC address
0589      * to prevent RX processing from using this key cache entry.
0590      */
0591     if (test_bit(hw_key_idx, common->ccmp_keymap) ||
0592         test_bit(hw_key_idx, common->tkip_keymap))
0593         ath_hw_keysetmac(common, hw_key_idx, NULL);
0594     else
0595         ath_hw_keyreset(common, hw_key_idx);
0596     if (hw_key_idx < IEEE80211_WEP_NKID)
0597         return;
0598 
0599     clear_bit(hw_key_idx, common->keymap);
0600     clear_bit(hw_key_idx, common->ccmp_keymap);
0601     if (!test_bit(hw_key_idx, common->tkip_keymap))
0602         return;
0603 
0604     clear_bit(hw_key_idx + 64, common->keymap);
0605 
0606     clear_bit(hw_key_idx, common->tkip_keymap);
0607     clear_bit(hw_key_idx + 64, common->tkip_keymap);
0608 
0609     if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0610         ath_hw_keyreset(common, hw_key_idx + 32);
0611         clear_bit(hw_key_idx + 32, common->keymap);
0612         clear_bit(hw_key_idx + 64 + 32, common->keymap);
0613 
0614         clear_bit(hw_key_idx + 32, common->tkip_keymap);
0615         clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap);
0616     }
0617 }
0618 EXPORT_SYMBOL(ath_key_delete);