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); 610