aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-03-02 08:06:31 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-03-05 14:39:38 -0500
commit672903b329579ff43ae3d553cf55bd82041921c1 (patch)
tree50f06169a9563f45fd0630d7287c373421fcbebf /drivers
parente65c22633c14eabe9593a71a727f81544378b892 (diff)
ath9k: Document keycache operations
There are number of small details about the keycache operations that are very easy to miss (and forget), so better include detailed comments in ath9k_hw_set_keycache_entry() to avoid having to figure out this every time when having to touch this area. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath9k/hw.c76
-rw-r--r--drivers/net/wireless/ath9k/mac.h8
2 files changed, 78 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 2acbb84dc2ba..5672f43e58e2 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -2482,18 +2482,49 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
2482 if (k->kv_len <= LEN_WEP104) 2482 if (k->kv_len <= LEN_WEP104)
2483 key4 &= 0xff; 2483 key4 &= 0xff;
2484 2484
2485 /*
2486 * Note: Key cache registers access special memory area that requires
2487 * two 32-bit writes to actually update the values in the internal
2488 * memory. Consequently, the exact order and pairs used here must be
2489 * maintained.
2490 */
2491
2485 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { 2492 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
2486 u16 micentry = entry + 64; 2493 u16 micentry = entry + 64;
2487 2494
2495 /*
2496 * Write inverted key[47:0] first to avoid Michael MIC errors
2497 * on frames that could be sent or received at the same time.
2498 * The correct key will be written in the end once everything
2499 * else is ready.
2500 */
2488 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); 2501 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
2489 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); 2502 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
2503
2504 /* Write key[95:48] */
2490 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 2505 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
2491 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 2506 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
2507
2508 /* Write key[127:96] and key type */
2492 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 2509 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
2493 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 2510 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
2511
2512 /* Write MAC address for the entry */
2494 (void) ath9k_hw_keysetmac(ah, entry, mac); 2513 (void) ath9k_hw_keysetmac(ah, entry, mac);
2495 2514
2496 if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { 2515 if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
2516 /*
2517 * TKIP uses two key cache entries:
2518 * Michael MIC TX/RX keys in the same key cache entry
2519 * (idx = main index + 64):
2520 * key0 [31:0] = RX key [31:0]
2521 * key1 [15:0] = TX key [31:16]
2522 * key1 [31:16] = reserved
2523 * key2 [31:0] = RX key [63:32]
2524 * key3 [15:0] = TX key [15:0]
2525 * key3 [31:16] = reserved
2526 * key4 [31:0] = TX key [63:32]
2527 */
2497 u32 mic0, mic1, mic2, mic3, mic4; 2528 u32 mic0, mic1, mic2, mic3, mic4;
2498 2529
2499 mic0 = get_unaligned_le32(k->kv_mic + 0); 2530 mic0 = get_unaligned_le32(k->kv_mic + 0);
@@ -2501,45 +2532,84 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
2501 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; 2532 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
2502 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; 2533 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
2503 mic4 = get_unaligned_le32(k->kv_txmic + 4); 2534 mic4 = get_unaligned_le32(k->kv_txmic + 4);
2535
2536 /* Write RX[31:0] and TX[31:16] */
2504 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 2537 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
2505 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); 2538 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
2539
2540 /* Write RX[63:32] and TX[15:0] */
2506 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); 2541 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
2507 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); 2542 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
2543
2544 /* Write TX[63:32] and keyType(reserved) */
2508 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); 2545 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
2509 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 2546 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
2510 AR_KEYTABLE_TYPE_CLR); 2547 AR_KEYTABLE_TYPE_CLR);
2511 2548
2512 } else { 2549 } else {
2550 /*
2551 * TKIP uses four key cache entries (two for group
2552 * keys):
2553 * Michael MIC TX/RX keys are in different key cache
2554 * entries (idx = main index + 64 for TX and
2555 * main index + 32 + 96 for RX):
2556 * key0 [31:0] = TX/RX MIC key [31:0]
2557 * key1 [31:0] = reserved
2558 * key2 [31:0] = TX/RX MIC key [63:32]
2559 * key3 [31:0] = reserved
2560 * key4 [31:0] = reserved
2561 *
2562 * Upper layer code will call this function separately
2563 * for TX and RX keys when these registers offsets are
2564 * used.
2565 */
2513 u32 mic0, mic2; 2566 u32 mic0, mic2;
2514 2567
2515 mic0 = get_unaligned_le32(k->kv_mic + 0); 2568 mic0 = get_unaligned_le32(k->kv_mic + 0);
2516 mic2 = get_unaligned_le32(k->kv_mic + 4); 2569 mic2 = get_unaligned_le32(k->kv_mic + 4);
2570
2571 /* Write MIC key[31:0] */
2517 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 2572 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
2518 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 2573 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
2574
2575 /* Write MIC key[63:32] */
2519 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); 2576 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
2520 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); 2577 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
2578
2579 /* Write TX[63:32] and keyType(reserved) */
2521 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); 2580 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
2522 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 2581 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
2523 AR_KEYTABLE_TYPE_CLR); 2582 AR_KEYTABLE_TYPE_CLR);
2524 } 2583 }
2584
2585 /* MAC address registers are reserved for the MIC entry */
2525 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); 2586 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
2526 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); 2587 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
2588
2589 /*
2590 * Write the correct (un-inverted) key[47:0] last to enable
2591 * TKIP now that all other registers are set with correct
2592 * values.
2593 */
2527 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 2594 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
2528 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 2595 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
2529 } else { 2596 } else {
2597 /* Write key[47:0] */
2530 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 2598 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
2531 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 2599 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
2600
2601 /* Write key[95:48] */
2532 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 2602 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
2533 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 2603 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
2604
2605 /* Write key[127:96] and key type */
2534 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 2606 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
2535 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 2607 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
2536 2608
2609 /* Write MAC address for the entry */
2537 (void) ath9k_hw_keysetmac(ah, entry, mac); 2610 (void) ath9k_hw_keysetmac(ah, entry, mac);
2538 } 2611 }
2539 2612
2540 if (ah->curchan == NULL)
2541 return true;
2542
2543 return true; 2613 return true;
2544} 2614}
2545 2615
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
index 862a63f7634b..fbd2d6ad2a53 100644
--- a/drivers/net/wireless/ath9k/mac.h
+++ b/drivers/net/wireless/ath9k/mac.h
@@ -588,9 +588,11 @@ struct ath9k_keyval {
588 u8 kv_type; 588 u8 kv_type;
589 u8 kv_pad; 589 u8 kv_pad;
590 u16 kv_len; 590 u16 kv_len;
591 u8 kv_val[16]; 591 u8 kv_val[16]; /* TK */
592 u8 kv_mic[8]; 592 u8 kv_mic[8]; /* Michael MIC key */
593 u8 kv_txmic[8]; 593 u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
594 * supports both MIC keys in the same key cache entry;
595 * in that case, kv_mic is the RX key) */
594}; 596};
595 597
596enum ath9k_key_type { 598enum ath9k_key_type {