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