1250003Sadrian/* 2250003Sadrian * Copyright (c) 2013 Qualcomm Atheros, Inc. 3250003Sadrian * 4250003Sadrian * Permission to use, copy, modify, and/or distribute this software for any 5250003Sadrian * purpose with or without fee is hereby granted, provided that the above 6250003Sadrian * copyright notice and this permission notice appear in all copies. 7250003Sadrian * 8250003Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9250003Sadrian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10250003Sadrian * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11250003Sadrian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12250003Sadrian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13250003Sadrian * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14250003Sadrian * PERFORMANCE OF THIS SOFTWARE. 15250003Sadrian */ 16250003Sadrian 17250003Sadrian#include "opt_ah.h" 18250003Sadrian 19250003Sadrian#include "ah.h" 20250003Sadrian#include "ah_internal.h" 21250003Sadrian 22250003Sadrian#include "ar9300/ar9300.h" 23250003Sadrian#include "ar9300/ar9300reg.h" 24250003Sadrian 25250003Sadrian/* 26250003Sadrian * Note: The key cache hardware requires that each double-word 27250003Sadrian * pair be written in even/odd order (since the destination is 28250003Sadrian * a 64-bit register). Don't reorder the writes in this code 29250003Sadrian * w/o considering this! 30250003Sadrian */ 31250003Sadrian#define KEY_XOR 0xaa 32250003Sadrian 33250003Sadrian#define IS_MIC_ENABLED(ah) \ 34250003Sadrian (AH9300(ah)->ah_sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE) 35250003Sadrian 36250003Sadrian/* 37250008Sadrian * This isn't the keytable type; this is actually something separate 38250008Sadrian * for the TX descriptor. 39250008Sadrian */ 40250008Sadrianstatic const int keyType[] = { 41250008Sadrian 1, /* HAL_CIPHER_WEP */ 42250008Sadrian 0, /* HAL_CIPHER_AES_OCB */ 43250008Sadrian 2, /* HAL_CIPHER_AES_CCM */ 44250008Sadrian 0, /* HAL_CIPHER_CKIP */ 45250008Sadrian 3, /* HAL_CIPHER_TKIP */ 46250008Sadrian 0 /* HAL_CIPHER_CLR */ 47250008Sadrian}; 48250008Sadrian 49250008Sadrian/* 50250003Sadrian * Return the size of the hardware key cache. 51250003Sadrian */ 52250003Sadrianu_int32_t 53250003Sadrianar9300_get_key_cache_size(struct ath_hal *ah) 54250003Sadrian{ 55250008Sadrian return AH_PRIVATE(ah)->ah_caps.halKeyCacheSize; 56250003Sadrian} 57250003Sadrian 58250003Sadrian/* 59250003Sadrian * Return AH_TRUE if the specific key cache entry is valid. 60250003Sadrian */ 61250003SadrianHAL_BOOL 62250003Sadrianar9300_is_key_cache_entry_valid(struct ath_hal *ah, u_int16_t entry) 63250003Sadrian{ 64250008Sadrian if (entry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 65250003Sadrian u_int32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 66250003Sadrian if (val & AR_KEYTABLE_VALID) { 67250003Sadrian return AH_TRUE; 68250003Sadrian } 69250003Sadrian } 70250003Sadrian return AH_FALSE; 71250003Sadrian} 72250003Sadrian 73250003Sadrian/* 74250003Sadrian * Clear the specified key cache entry and any associated MIC entry. 75250003Sadrian */ 76250003SadrianHAL_BOOL 77250003Sadrianar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry) 78250003Sadrian{ 79250003Sadrian u_int32_t key_type; 80250003Sadrian struct ath_hal_9300 *ahp = AH9300(ah); 81250003Sadrian 82250008Sadrian if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 83250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 84250003Sadrian "%s: entry %u out of range\n", __func__, entry); 85250003Sadrian return AH_FALSE; 86250003Sadrian } 87250008Sadrian 88250008Sadrian ahp->ah_keytype[entry] = keyType[HAL_CIPHER_CLR]; 89250008Sadrian 90250003Sadrian key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); 91250003Sadrian 92250003Sadrian /* XXX why not clear key type/valid bit first? */ 93250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); 94250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); 95250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); 96250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); 97250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); 98250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); 99250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); 100250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); 101250003Sadrian if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { 102250003Sadrian u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */ 103250003Sadrian 104250008Sadrian HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); 105250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); 106250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 107250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); 108250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); 109250003Sadrian /* NB: key type and MAC are known to be ok */ 110250003Sadrian } 111250003Sadrian 112250003Sadrian if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) { 113250003Sadrian return AH_TRUE; 114250003Sadrian } 115250003Sadrian 116250003Sadrian if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL) 117250003Sadrian == HAL_OK) { 118250003Sadrian if (key_type == AR_KEYTABLE_TYPE_TKIP || 119250003Sadrian key_type == AR_KEYTABLE_TYPE_40 || 120250003Sadrian key_type == AR_KEYTABLE_TYPE_104 || 121250003Sadrian key_type == AR_KEYTABLE_TYPE_128) { 122250003Sadrian /* SW WAR for Bug 31602 */ 123250003Sadrian if (--ahp->ah_rifs_sec_cnt == 0) { 124250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 125250003Sadrian "%s: Count = %d, enabling RIFS\n", 126250003Sadrian __func__, ahp->ah_rifs_sec_cnt); 127250003Sadrian ar9300_set_rifs_delay(ah, AH_TRUE); 128250003Sadrian } 129250003Sadrian } 130250003Sadrian } 131250003Sadrian return AH_TRUE; 132250003Sadrian} 133250003Sadrian 134250003Sadrian/* 135250003Sadrian * Sets the mac part of the specified key cache entry (and any 136250003Sadrian * associated MIC entry) and mark them valid. 137250003Sadrian */ 138250003SadrianHAL_BOOL 139250003Sadrianar9300_set_key_cache_entry_mac( 140250003Sadrian struct ath_hal *ah, 141250003Sadrian u_int16_t entry, 142250003Sadrian const u_int8_t *mac) 143250003Sadrian{ 144250003Sadrian u_int32_t mac_hi, mac_lo; 145250003Sadrian u_int32_t unicast_addr = AR_KEYTABLE_VALID; 146250003Sadrian 147250008Sadrian if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 148250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 149250003Sadrian "%s: entry %u out of range\n", __func__, entry); 150250003Sadrian return AH_FALSE; 151250003Sadrian } 152250003Sadrian /* 153250003Sadrian * Set MAC address -- shifted right by 1. mac_lo is 154250003Sadrian * the 4 MSBs, and mac_hi is the 2 LSBs. 155250003Sadrian */ 156250003Sadrian if (mac != AH_NULL) { 157250003Sadrian /* 158250003Sadrian * If upper layers have requested mcast MACaddr lookup, then 159250003Sadrian * signify this to the hw by setting the (poorly named) valid_bit 160250003Sadrian * to 0. Yes, really 0. The hardware specs, pcu_registers.txt, is 161250003Sadrian * has incorrectly named valid_bit. It should be called "Unicast". 162250003Sadrian * When the Key Cache entry is to decrypt Unicast frames, this bit 163250003Sadrian * should be '1'; for multicast and broadcast frames, this bit is '0'. 164250003Sadrian */ 165250003Sadrian if (mac[0] & 0x01) { 166250003Sadrian unicast_addr = 0; /* Not an unicast address */ 167250003Sadrian } 168250003Sadrian 169250003Sadrian mac_hi = (mac[5] << 8) | mac[4]; 170250003Sadrian mac_lo = (mac[3] << 24) | (mac[2] << 16) 171250003Sadrian | (mac[1] << 8) | mac[0]; 172250003Sadrian mac_lo >>= 1; /* Note that the bit 0 is shifted out. This bit is used to 173250003Sadrian * indicate that this is a multicast key cache. */ 174250003Sadrian mac_lo |= (mac_hi & 1) << 31; /* carry */ 175250003Sadrian mac_hi >>= 1; 176250003Sadrian } else { 177250003Sadrian mac_lo = mac_hi = 0; 178250003Sadrian } 179250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), mac_lo); 180250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), mac_hi | unicast_addr); 181250003Sadrian return AH_TRUE; 182250003Sadrian} 183250003Sadrian 184250003Sadrian/* 185250003Sadrian * Sets the contents of the specified key cache entry 186250003Sadrian * and any associated MIC entry. 187250003Sadrian */ 188250003SadrianHAL_BOOL 189250003Sadrianar9300_set_key_cache_entry(struct ath_hal *ah, u_int16_t entry, 190250003Sadrian const HAL_KEYVAL *k, const u_int8_t *mac, 191250003Sadrian int xor_key) 192250003Sadrian{ 193250003Sadrian const HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 194250003Sadrian u_int32_t key0, key1, key2, key3, key4; 195250003Sadrian u_int32_t key_type; 196250003Sadrian u_int32_t xor_mask = xor_key ? 197250003Sadrian (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0; 198250003Sadrian struct ath_hal_9300 *ahp = AH9300(ah); 199250003Sadrian u_int32_t pwrmgt, pwrmgt_mic, uapsd_cfg, psta = 0; 200250003Sadrian int is_proxysta_key = k->kv_type & HAL_KEY_PROXY_STA_MASK; 201250003Sadrian 202250003Sadrian 203250008Sadrian if (entry >= p_cap->halKeyCacheSize) { 204250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 205250003Sadrian "%s: entry %u out of range\n", __func__, entry); 206250003Sadrian return AH_FALSE; 207250003Sadrian } 208250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n", 209250003Sadrian __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null", 210250003Sadrian is_proxysta_key); 211250003Sadrian 212250003Sadrian switch (k->kv_type & AH_KEYTYPE_MASK) { 213250003Sadrian case HAL_CIPHER_AES_OCB: 214250003Sadrian key_type = AR_KEYTABLE_TYPE_AES; 215250003Sadrian break; 216250003Sadrian case HAL_CIPHER_AES_CCM: 217250008Sadrian if (!p_cap->halCipherAesCcmSupport) { 218250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by " 219250003Sadrian "mac rev 0x%x\n", 220250003Sadrian __func__, AH_PRIVATE(ah)->ah_macRev); 221250003Sadrian return AH_FALSE; 222250003Sadrian } 223250003Sadrian key_type = AR_KEYTABLE_TYPE_CCM; 224250003Sadrian break; 225250003Sadrian case HAL_CIPHER_TKIP: 226250003Sadrian key_type = AR_KEYTABLE_TYPE_TKIP; 227250008Sadrian if (IS_MIC_ENABLED(ah) && entry + 64 >= p_cap->halKeyCacheSize) { 228250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 229250003Sadrian "%s: entry %u inappropriate for TKIP\n", 230250003Sadrian __func__, entry); 231250003Sadrian return AH_FALSE; 232250003Sadrian } 233250003Sadrian break; 234250003Sadrian case HAL_CIPHER_WEP: 235250003Sadrian if (k->kv_len < 40 / NBBY) { 236250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n", 237250003Sadrian __func__, k->kv_len); 238250003Sadrian return AH_FALSE; 239250003Sadrian } 240250003Sadrian if (k->kv_len <= 40 / NBBY) { 241250003Sadrian key_type = AR_KEYTABLE_TYPE_40; 242250003Sadrian } else if (k->kv_len <= 104 / NBBY) { 243250003Sadrian key_type = AR_KEYTABLE_TYPE_104; 244250003Sadrian } else { 245250003Sadrian key_type = AR_KEYTABLE_TYPE_128; 246250003Sadrian } 247250003Sadrian break; 248250003Sadrian case HAL_CIPHER_CLR: 249250003Sadrian key_type = AR_KEYTABLE_TYPE_CLR; 250250003Sadrian break; 251250003Sadrian default: 252250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n", 253250003Sadrian __func__, k->kv_type); 254250003Sadrian return AH_FALSE; 255250003Sadrian } 256250003Sadrian 257250003Sadrian key0 = LE_READ_4(k->kv_val + 0) ^ xor_mask; 258250003Sadrian key1 = (LE_READ_2(k->kv_val + 4) ^ xor_mask) & 0xffff; 259250003Sadrian key2 = LE_READ_4(k->kv_val + 6) ^ xor_mask; 260250003Sadrian key3 = (LE_READ_2(k->kv_val + 10) ^ xor_mask) & 0xffff; 261250003Sadrian key4 = LE_READ_4(k->kv_val + 12) ^ xor_mask; 262250003Sadrian if (k->kv_len <= 104 / NBBY) { 263250003Sadrian key4 &= 0xff; 264250003Sadrian } 265250003Sadrian 266250003Sadrian /* Extract the UAPSD AC bits and shift it appropriately */ 267250003Sadrian uapsd_cfg = k->kv_apsd; 268250003Sadrian uapsd_cfg = (u_int32_t) SM(uapsd_cfg, AR_KEYTABLE_UAPSD); 269250003Sadrian 270250003Sadrian /* Need to preserve the power management bit used by MAC */ 271250003Sadrian pwrmgt = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEYTABLE_PWRMGT; 272250003Sadrian 273250003Sadrian if (is_proxysta_key) { 274250003Sadrian u_int8_t bcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 275250008Sadrian if (!mac || OS_MEMCMP(mac, bcast_mac, 6)) { 276250003Sadrian psta = AR_KEYTABLE_DIR_ACK_BIT; 277250003Sadrian } 278250003Sadrian } 279250003Sadrian /* 280250003Sadrian * Note: key cache hardware requires that each double-word 281250003Sadrian * pair be written in even/odd order (since the destination is 282250003Sadrian * a 64-bit register). Don't reorder these writes w/o 283250003Sadrian * considering this! 284250003Sadrian */ 285250003Sadrian if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { 286250003Sadrian u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */ 287250003Sadrian 288250003Sadrian /* Need to preserve the power management bit used by MAC */ 289250003Sadrian pwrmgt_mic = 290250003Sadrian OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEYTABLE_PWRMGT; 291250003Sadrian 292250003Sadrian /* 293250003Sadrian * Invalidate the encrypt/decrypt key until the MIC 294250003Sadrian * key is installed so pending rx frames will fail 295250003Sadrian * with decrypt errors rather than a MIC error. 296250003Sadrian */ 297250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); 298250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); 299250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 300250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 301250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 302250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 303250003Sadrian key_type | pwrmgt | uapsd_cfg | psta); 304250003Sadrian ar9300_set_key_cache_entry_mac(ah, entry, mac); 305250003Sadrian 306250003Sadrian /* 307250003Sadrian * since the AR_MISC_MODE register was written with the contents of 308250003Sadrian * ah_misc_mode (if any) in ar9300_attach, just check ah_misc_mode and 309250003Sadrian * save a pci read per key set. 310250003Sadrian */ 311250003Sadrian if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { 312250003Sadrian u_int32_t mic0, mic1, mic2, mic3, mic4; 313250003Sadrian /* 314250003Sadrian * both RX and TX mic values can be combined into 315250003Sadrian * one cache slot entry. 316250003Sadrian * 8*N + 800 31:0 RX Michael key 0 317250003Sadrian * 8*N + 804 15:0 TX Michael key 0 [31:16] 318250003Sadrian * 8*N + 808 31:0 RX Michael key 1 319250003Sadrian * 8*N + 80C 15:0 TX Michael key 0 [15:0] 320250003Sadrian * 8*N + 810 31:0 TX Michael key 1 321250003Sadrian * 8*N + 814 15:0 reserved 322250003Sadrian * 8*N + 818 31:0 reserved 323250003Sadrian * 8*N + 81C 14:0 reserved 324250003Sadrian * 15 key valid == 0 325250003Sadrian */ 326250003Sadrian /* RX mic */ 327250003Sadrian mic0 = LE_READ_4(k->kv_mic + 0); 328250003Sadrian mic2 = LE_READ_4(k->kv_mic + 4); 329250003Sadrian /* TX mic */ 330250003Sadrian mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff; 331250003Sadrian mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff; 332250003Sadrian mic4 = LE_READ_4(k->kv_txmic + 4); 333250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 334250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); 335250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); 336250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); 337250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); 338250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 339250003Sadrian AR_KEYTABLE_TYPE_CLR | pwrmgt_mic | uapsd_cfg); 340250003Sadrian 341250003Sadrian } else { 342250003Sadrian u_int32_t mic0, mic2; 343250003Sadrian 344250003Sadrian mic0 = LE_READ_4(k->kv_mic + 0); 345250003Sadrian mic2 = LE_READ_4(k->kv_mic + 4); 346250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 347250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 348250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); 349250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); 350250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); 351250003Sadrian OS_REG_WRITE(ah, 352250003Sadrian AR_KEYTABLE_TYPE(micentry | pwrmgt_mic | uapsd_cfg), 353250003Sadrian AR_KEYTABLE_TYPE_CLR); 354250003Sadrian } 355250003Sadrian /* NB: MIC key is not marked valid and has no MAC address */ 356250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); 357250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); 358250003Sadrian 359250003Sadrian /* correct intentionally corrupted key */ 360250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 361250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 362250003Sadrian } else { 363250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 364250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 365250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 366250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 367250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 368250003Sadrian OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 369250003Sadrian key_type | pwrmgt | uapsd_cfg | psta); 370250003Sadrian 371250003Sadrian /* 372250003Sadrian ath_hal_printf(ah, "%s[%d] mac %s proxy %d\n", 373250003Sadrian __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null", 374250003Sadrian is_proxysta_key); 375250003Sadrian */ 376250003Sadrian 377250003Sadrian ar9300_set_key_cache_entry_mac(ah, entry, mac); 378250003Sadrian } 379250003Sadrian 380250008Sadrian ahp->ah_keytype[entry] = keyType[k->kv_type]; 381250008Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: entry=%d, k->kv_type=%d," 382250008Sadrian "keyType=%d\n", __func__, entry, k->kv_type, keyType[k->kv_type]); 383250008Sadrian 384250008Sadrian 385250003Sadrian if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) { 386250003Sadrian return AH_TRUE; 387250003Sadrian } 388250003Sadrian 389250003Sadrian if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL) 390250003Sadrian == HAL_OK) { 391250003Sadrian if (key_type == AR_KEYTABLE_TYPE_TKIP || 392250003Sadrian key_type == AR_KEYTABLE_TYPE_40 || 393250003Sadrian key_type == AR_KEYTABLE_TYPE_104 || 394250003Sadrian key_type == AR_KEYTABLE_TYPE_128) { 395250003Sadrian /* SW WAR for Bug 31602 */ 396250003Sadrian ahp->ah_rifs_sec_cnt++; 397250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 398250003Sadrian "%s: Count = %d, disabling RIFS\n", 399250003Sadrian __func__, ahp->ah_rifs_sec_cnt); 400250003Sadrian ar9300_set_rifs_delay(ah, AH_FALSE); 401250003Sadrian } 402250003Sadrian } 403250003Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n", 404250003Sadrian __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null", 405250003Sadrian is_proxysta_key); 406250003Sadrian 407250003Sadrian return AH_TRUE; 408250003Sadrian} 409250003Sadrian 410250003Sadrian/* 411250003Sadrian * Enable the Keysearch for every subframe of an aggregate 412250003Sadrian */ 413250003Sadrianvoid 414250003Sadrianar9300_enable_keysearch_always(struct ath_hal *ah, int enable) 415250003Sadrian{ 416250003Sadrian u_int32_t val; 417250003Sadrian 418250003Sadrian if (!ah) { 419250003Sadrian return; 420250003Sadrian } 421250003Sadrian val = OS_REG_READ(ah, AR_PCU_MISC); 422250003Sadrian if (enable) { 423250003Sadrian val |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; 424250003Sadrian } else { 425250003Sadrian val &= ~AR_PCU_ALWAYS_PERFORM_KEYSEARCH; 426250003Sadrian } 427250003Sadrian OS_REG_WRITE(ah, AR_PCU_MISC, val); 428250003Sadrian} 429250003Sadrianvoid ar9300_dump_keycache(struct ath_hal *ah, int n, u_int32_t *entry) 430250003Sadrian{ 431250003Sadrian#define AH_KEY_REG_SIZE 8 432250003Sadrian int i; 433250003Sadrian 434250003Sadrian for (i = 0; i < AH_KEY_REG_SIZE; i++) { 435250003Sadrian entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4); 436250003Sadrian } 437250003Sadrian#undef AH_KEY_REG_SIZE 438250003Sadrian} 439278741Sadrian 440278741Sadrian#if ATH_SUPPORT_KEYPLUMB_WAR 441278741Sadrian/* 442278741Sadrian * Check the contents of the specified key cache entry 443278741Sadrian * and any associated MIC entry. 444278741Sadrian */ 445278741Sadrian HAL_BOOL 446278741Sadrianar9300_check_key_cache_entry(struct ath_hal *ah, u_int16_t entry, 447278741Sadrian const HAL_KEYVAL *k, int xorKey) 448278741Sadrian{ 449278741Sadrian const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 450278741Sadrian u_int32_t key0, key1, key2, key3, key4; 451278741Sadrian u_int32_t keyType; 452278741Sadrian u_int32_t xorMask = xorKey ? 453278741Sadrian (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0; 454278741Sadrian struct ath_hal_9300 *ahp = AH9300(ah); 455278741Sadrian 456278741Sadrian 457278741Sadrian if (entry >= pCap->hal_key_cache_size) { 458278741Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 459278741Sadrian "%s: entry %u out of range\n", __func__, entry); 460278741Sadrian return AH_FALSE; 461278741Sadrian } 462278741Sadrian switch (k->kv_type) { 463278741Sadrian case HAL_CIPHER_AES_OCB: 464278741Sadrian keyType = AR_KEYTABLE_TYPE_AES; 465278741Sadrian break; 466278741Sadrian case HAL_CIPHER_AES_CCM: 467278741Sadrian if (!pCap->hal_cipher_aes_ccm_support) { 468278741Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by " 469278741Sadrian "mac rev 0x%x\n", 470278741Sadrian __func__, AH_PRIVATE(ah)->ah_macRev); 471278741Sadrian return AH_FALSE; 472278741Sadrian } 473278741Sadrian keyType = AR_KEYTABLE_TYPE_CCM; 474278741Sadrian break; 475278741Sadrian case HAL_CIPHER_TKIP: 476278741Sadrian keyType = AR_KEYTABLE_TYPE_TKIP; 477278741Sadrian if (IS_MIC_ENABLED(ah) && entry + 64 >= pCap->hal_key_cache_size) { 478278741Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, 479278741Sadrian "%s: entry %u inappropriate for TKIP\n", 480278741Sadrian __func__, entry); 481278741Sadrian return AH_FALSE; 482278741Sadrian } 483278741Sadrian break; 484278741Sadrian case HAL_CIPHER_WEP: 485278741Sadrian if (k->kv_len < 40 / NBBY) { 486278741Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n", 487278741Sadrian __func__, k->kv_len); 488278741Sadrian return AH_FALSE; 489278741Sadrian } 490278741Sadrian if (k->kv_len <= 40 / NBBY) { 491278741Sadrian keyType = AR_KEYTABLE_TYPE_40; 492278741Sadrian } else if (k->kv_len <= 104 / NBBY) { 493278741Sadrian keyType = AR_KEYTABLE_TYPE_104; 494278741Sadrian } else { 495278741Sadrian keyType = AR_KEYTABLE_TYPE_128; 496278741Sadrian } 497278741Sadrian break; 498278741Sadrian case HAL_CIPHER_CLR: 499278741Sadrian keyType = AR_KEYTABLE_TYPE_CLR; 500278741Sadrian return AH_TRUE; 501278741Sadrian default: 502278741Sadrian HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n", 503278741Sadrian __func__, k->kv_type); 504278741Sadrian return AH_TRUE; 505278741Sadrian } 506278741Sadrian 507278741Sadrian key0 = LE_READ_4(k->kv_val + 0) ^ xorMask; 508278741Sadrian key1 = (LE_READ_2(k->kv_val + 4) ^ xorMask) & 0xffff; 509278741Sadrian key2 = LE_READ_4(k->kv_val + 6) ^ xorMask; 510278741Sadrian key3 = (LE_READ_2(k->kv_val + 10) ^ xorMask) & 0xffff; 511278741Sadrian key4 = LE_READ_4(k->kv_val + 12) ^ xorMask; 512278741Sadrian if (k->kv_len <= 104 / NBBY) { 513278741Sadrian key4 &= 0xff; 514278741Sadrian } 515278741Sadrian 516278741Sadrian /* 517278741Sadrian * Note: key cache hardware requires that each double-word 518278741Sadrian * pair be written in even/odd order (since the destination is 519278741Sadrian * a 64-bit register). Don't reorder these writes w/o 520278741Sadrian * considering this! 521278741Sadrian */ 522278741Sadrian if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { 523278741Sadrian u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */ 524278741Sadrian 525278741Sadrian 526278741Sadrian /* 527278741Sadrian * Invalidate the encrypt/decrypt key until the MIC 528278741Sadrian * key is installed so pending rx frames will fail 529278741Sadrian * with decrypt errors rather than a MIC error. 530278741Sadrian */ 531278741Sadrian if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) && 532278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) && 533278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) && 534278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) && 535278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) && 536278741Sadrian ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE))) 537278741Sadrian { 538278741Sadrian 539278741Sadrian /* 540278741Sadrian * since the AR_MISC_MODE register was written with the contents of 541278741Sadrian * ah_miscMode (if any) in ar9300Attach, just check ah_miscMode and 542278741Sadrian * save a pci read per key set. 543278741Sadrian */ 544278741Sadrian if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { 545278741Sadrian u_int32_t mic0,mic1,mic2,mic3,mic4; 546278741Sadrian /* 547278741Sadrian * both RX and TX mic values can be combined into 548278741Sadrian * one cache slot entry. 549278741Sadrian * 8*N + 800 31:0 RX Michael key 0 550278741Sadrian * 8*N + 804 15:0 TX Michael key 0 [31:16] 551278741Sadrian * 8*N + 808 31:0 RX Michael key 1 552278741Sadrian * 8*N + 80C 15:0 TX Michael key 0 [15:0] 553278741Sadrian * 8*N + 810 31:0 TX Michael key 1 554278741Sadrian * 8*N + 814 15:0 reserved 555278741Sadrian * 8*N + 818 31:0 reserved 556278741Sadrian * 8*N + 81C 14:0 reserved 557278741Sadrian * 15 key valid == 0 558278741Sadrian */ 559278741Sadrian /* RX mic */ 560278741Sadrian mic0 = LE_READ_4(k->kv_mic + 0); 561278741Sadrian mic2 = LE_READ_4(k->kv_mic + 4); 562278741Sadrian /* TX mic */ 563278741Sadrian mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff; 564278741Sadrian mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff; 565278741Sadrian mic4 = LE_READ_4(k->kv_txmic + 4); 566278741Sadrian if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(micentry)) == mic0) && 567278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY1(micentry)) == mic1) && 568278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY2(micentry)) == mic2) && 569278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY3(micentry)) == mic3) && 570278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY4(micentry)) == mic4) && 571278741Sadrian ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEY_TYPE) == (AR_KEYTABLE_TYPE_CLR & AR_KEY_TYPE))) { 572278741Sadrian return AH_TRUE; 573278741Sadrian } 574278741Sadrian 575278741Sadrian } else { 576278741Sadrian return AH_TRUE; 577278741Sadrian } 578278741Sadrian } 579278741Sadrian } else { 580278741Sadrian if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) && 581278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) && 582278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) && 583278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) && 584278741Sadrian (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) && 585278741Sadrian ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE))) { 586278741Sadrian return AH_TRUE; 587278741Sadrian } 588278741Sadrian } 589278741Sadrian return AH_FALSE; 590278741Sadrian} 591278741Sadrian#endif 592