root/drivers/net/wireless/ath/key.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ath_hw_keyreset
  2. ath_hw_keysetmac
  3. ath_hw_set_keycache_entry
  4. ath_setkey_tkip
  5. ath_reserve_key_cache_slot_tkip
  6. ath_reserve_key_cache_slot
  7. ath_key_config
  8. ath_key_delete

   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 
  42 bool 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 }
  85 EXPORT_SYMBOL(ath_hw_keyreset);
  86 
  87 static 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 
 129 static 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 
 339 static 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 
 386 static 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 
 405 static 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  */
 473 int 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 }
 579 EXPORT_SYMBOL(ath_key_config);
 580 
 581 /*
 582  * Delete Key.
 583  */
 584 void 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 }
 609 EXPORT_SYMBOL(ath_key_delete);

/* [<][>][^][v][top][bottom][index][help] */