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