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