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