/* * Clear the specified key cache entry and any associated MIC entry. */ HAL_BOOL ar5212ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) { uint32_t keyType; if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n", __func__, entry); return AH_FALSE; } keyType = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); /* XXX why not clear key type/valid bit first? */ OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { uint16_t micentry = entry+64; /* MIC goes at slot+64 */ HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); /* NB: key type and MAC are known to be ok */ } return AH_TRUE; }
bool ath_hw_keyreset(struct ath_common *common, u16 entry) { u32 keyType; void *ah = common->ah; if (entry >= common->keymax) { ath_print(common, ATH_DBG_FATAL, "keychache entry %u out of range\n", entry); return false; } keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (keyType == AR_KEYTABLE_TYPE_TKIP) { u16 micentry = entry + 64; REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); } return true; }
/* * Clear the specified key cache entry and any associated MIC entry. */ HAL_BOOL ar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry) { u_int32_t key_type; struct ath_hal_9300 *ahp = AH9300(ah); if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: entry %u out of range\n", __func__, entry); return AH_FALSE; } ahp->ah_keytype[entry] = keyType[HAL_CIPHER_CLR]; key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); /* XXX why not clear key type/valid bit first? */ OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */ HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); /* NB: key type and MAC are known to be ok */ } if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) { return AH_TRUE; } if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL) == HAL_OK) { if (key_type == AR_KEYTABLE_TYPE_TKIP || key_type == AR_KEYTABLE_TYPE_40 || key_type == AR_KEYTABLE_TYPE_104 || key_type == AR_KEYTABLE_TYPE_128) { /* SW WAR for Bug 31602 */ if (--ahp->ah_rifs_sec_cnt == 0) { HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: Count = %d, enabling RIFS\n", __func__, ahp->ah_rifs_sec_cnt); ar9300_set_rifs_delay(ah, AH_TRUE); } } } return AH_TRUE; }
/* * Clear the specified key cache entry and any associated MIC entry. */ HAL_BOOL ar5416ResetKeyCacheEntry(struct ath_hal *ah, u_int16_t entry) { u_int32_t keyType; struct ath_hal_5416 *ahp = AH5416(ah); if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { HDPRINTF(ah, HAL_DBG_KEYCACHE, "%s: entry %u out of range\n", __func__, entry); return AH_FALSE; } keyType = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); ENABLE_REG_WRITE_BUFFER /* XXX why not clear key type/valid bit first? */ OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { u_int16_t micentry = entry+64; /* MIC goes at slot+64 */ HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); /* NB: key type and MAC are known to be ok */ } OS_REG_WRITE_FLUSH(ah); DISABLE_REG_WRITE_BUFFER if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) return AH_TRUE; if (ar5416GetCapability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL) == HAL_OK) { if (keyType == AR_KEYTABLE_TYPE_TKIP || keyType == AR_KEYTABLE_TYPE_40 || keyType == AR_KEYTABLE_TYPE_104 || keyType == AR_KEYTABLE_TYPE_128) { /* SW WAR for Bug 31602 */ if (--ahp->ah_rifs_sec_cnt == 0) { HDPRINTF(ah, HAL_DBG_KEYCACHE, "%s: Count = %d, enabling RIFS\n", __func__, ahp->ah_rifs_sec_cnt); ar5416SetRifsDelay(ah, AH_TRUE); } } } return AH_TRUE; }
void register_keycache(u_int nslots, int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) { #define SET(r, a) do { \ r->addr = a; r->type = DUMP_KEYCACHE; r++; \ } while(0) struct dumpreg *keyregs, *r; int i; keyregs = (struct dumpreg *) calloc(nslots, 8*sizeof(struct dumpreg)); if (keyregs == NULL) errx(-1, "no space to %d keycache slots\n", nslots); r = keyregs; for (i = 0; i < nslots; i++) { SET(r, AR_KEYTABLE_KEY0(i)); SET(r, AR_KEYTABLE_KEY1(i)); SET(r, AR_KEYTABLE_KEY2(i)); SET(r, AR_KEYTABLE_KEY3(i)); SET(r, AR_KEYTABLE_KEY4(i)); SET(r, AR_KEYTABLE_TYPE(i)); SET(r, AR_KEYTABLE_MAC0(i)); SET(r, AR_KEYTABLE_MAC1(i)); } register_regs(keyregs, 8*nslots, def_srev_min, def_srev_max, def_phy_min, def_phy_max); #undef SET }
bool ath_hw_keyreset(struct ath_common *common, u16 entry) { u32 keyType; void *ah = common->ah; if (entry >= common->keymax) { ath_err(common, "keycache entry %u out of range\n", entry); return false; } keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); ENABLE_REGWRITE_BUFFER(ah); REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (keyType == AR_KEYTABLE_TYPE_TKIP) { u16 micentry = entry + 64; REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), AR_KEYTABLE_TYPE_CLR); } } REGWRITE_BUFFER_FLUSH(ah); return true; }
/* * Clear the specified key cache entry. */ HAL_BOOL ar5210ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) { if (entry < AR_KEYTABLE_SIZE) { OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); return AH_TRUE; } return AH_FALSE; }
static void ath_hal_dumpkeycache(FILE *fd, int nkeys) { static const char *keytypenames[] = { "WEP-40", /* AR_KEYTABLE_TYPE_40 */ "WEP-104", /* AR_KEYTABLE_TYPE_104 */ "#2", "WEP-128", /* AR_KEYTABLE_TYPE_128 */ "TKIP", /* AR_KEYTABLE_TYPE_TKIP */ "AES-OCB", /* AR_KEYTABLE_TYPE_AES */ "AES-CCM", /* AR_KEYTABLE_TYPE_CCM */ "CLR", /* AR_KEYTABLE_TYPE_CLR */ }; int micEnabled = SREV(state.revs.ah_macVersion, state.revs.ah_macRev) < SREV(4,8) ? 0 : OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_CRPT_MIC_ENABLE; u_int8_t mac[IEEE80211_ADDR_LEN]; u_int8_t ismic[128/NBBY]; int entry; int first = 1; memset(ismic, 0, sizeof(ismic)); for (entry = 0; entry < nkeys; entry++) { u_int32_t macLo, macHi, type; u_int32_t key0, key1, key2, key3, key4; macHi = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); if ((macHi & AR_KEYTABLE_VALID) == 0 && isclr(ismic, entry)) continue; macLo = OS_REG_READ(ah, AR_KEYTABLE_MAC0(entry)); macHi <<= 1; if (macLo & (1<<31)) macHi |= 1; macLo <<= 1; mac[4] = macHi & 0xff; mac[5] = macHi >> 8; mac[0] = macLo & 0xff; mac[1] = macLo >> 8; mac[2] = macLo >> 16; mac[3] = macLo >> 24; type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); if ((type & 7) == AR_KEYTABLE_TYPE_TKIP && micEnabled) setbit(ismic, entry+64); key0 = OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)); key1 = OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)); key2 = OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)); key3 = OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)); key4 = OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)); if (first) { fprintf(fd, "\n"); first = 0; } fprintf(fd, "KEY[%03u] MAC %s %-7s %02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x\n" , entry , ether_sprintf(mac) , isset(ismic, entry) ? "MIC" : keytypenames[type & 7] , (key0 >> 0) & 0xff , (key0 >> 8) & 0xff , (key0 >> 16) & 0xff , (key0 >> 24) & 0xff , (key1 >> 0) & 0xff , (key1 >> 8) & 0xff , (key2 >> 0) & 0xff , (key2 >> 8) & 0xff , (key2 >> 16) & 0xff , (key2 >> 24) & 0xff , (key3 >> 0) & 0xff , (key3 >> 8) & 0xff , (key4 >> 0) & 0xff , (key4 >> 8) & 0xff , (key4 >> 16) & 0xff , (key4 >> 24) & 0xff ); } }