ar5210_keycache.c revision 185406
1132718Skan/* 2169699Skan * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3132718Skan * Copyright (c) 2002-2004 Atheros Communications, Inc. 4132718Skan * 5132718Skan * Permission to use, copy, modify, and/or distribute this software for any 6132718Skan * purpose with or without fee is hereby granted, provided that the above 7132718Skan * copyright notice and this permission notice appear in all copies. 8132718Skan * 9132718Skan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10169699Skan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11132718Skan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12132718Skan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13132718Skan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14132718Skan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15169699Skan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16132718Skan * 17132718Skan * $Id: ar5210_keycache.c,v 1.4 2008/11/10 04:08:02 sam Exp $ 18169699Skan */ 19169699Skan#include "opt_ah.h" 20132718Skan 21169699Skan#include "ah.h" 22132718Skan#include "ah_internal.h" 23169699Skan 24132718Skan#include "ar5210/ar5210.h" 25132718Skan#include "ar5210/ar5210reg.h" 26132718Skan 27132718Skan#define AR_KEYTABLE_SIZE 64 28132718Skan#define KEY_XOR 0xaa 29132718Skan 30132718Skan/* 31132718Skan * Return the size of the hardware key cache. 32132718Skan */ 33132718Skanu_int 34132718Skanar5210GetKeyCacheSize(struct ath_hal *ah) 35132718Skan{ 36132718Skan return AR_KEYTABLE_SIZE; 37132718Skan} 38132718Skan 39132718Skan/* 40132718Skan * Return the size of the hardware key cache. 41132718Skan */ 42132718SkanHAL_BOOL 43132718Skanar5210IsKeyCacheEntryValid(struct ath_hal *ah, uint16_t entry) 44132718Skan{ 45132718Skan if (entry < AR_KEYTABLE_SIZE) { 46132718Skan uint32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 47132718Skan if (val & AR_KEYTABLE_VALID) 48132718Skan return AH_TRUE; 49132718Skan } 50132718Skan return AH_FALSE; 51132718Skan} 52132718Skan 53132718Skan/* 54132718Skan * Clear the specified key cache entry. 55132718Skan */ 56132718SkanHAL_BOOL 57132718Skanar5210ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) 58132718Skan{ 59132718Skan if (entry < AR_KEYTABLE_SIZE) { 60169699Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); 61169699Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); 62169699Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); 63169699Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); 64132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); 65132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 0); 66132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); 67132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); 68132718Skan return AH_TRUE; 69132718Skan } 70169699Skan return AH_FALSE; 71132718Skan} 72132718Skan 73132718Skan/* 74132718Skan * Sets the mac part of the specified key cache entry and mark it valid. 75132718Skan */ 76132718SkanHAL_BOOL 77132718Skanar5210SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac) 78132718Skan{ 79132718Skan uint32_t macHi, macLo; 80132718Skan 81132718Skan if (entry < AR_KEYTABLE_SIZE) { 82132718Skan /* 83132718Skan * Set MAC address -- shifted right by 1. MacLo is 84132718Skan * the 4 MSBs, and MacHi is the 2 LSBs. 85132718Skan */ 86132718Skan if (mac != AH_NULL) { 87132718Skan macHi = (mac[5] << 8) | mac[4]; 88132718Skan macLo = (mac[3] << 24)| (mac[2] << 16) 89132718Skan | (mac[1] << 8) | mac[0]; 90132718Skan macLo >>= 1; 91132718Skan macLo |= (macHi & 1) << 31; /* carry */ 92132718Skan macHi >>= 1; 93132718Skan } else { 94132718Skan macLo = macHi = 0; 95132718Skan } 96132718Skan 97132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); 98132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 99132718Skan macHi | AR_KEYTABLE_VALID); 100132718Skan return AH_TRUE; 101132718Skan } 102132718Skan return AH_FALSE; 103132718Skan} 104132718Skan 105132718Skan/* 106132718Skan * Sets the contents of the specified key cache entry. 107132718Skan */ 108132718SkanHAL_BOOL 109132718Skanar5210SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, 110132718Skan const HAL_KEYVAL *k, const uint8_t *mac, int xorKey) 111132718Skan{ 112132718Skan uint32_t key0, key1, key2, key3, key4; 113132718Skan uint32_t keyType; 114132718Skan uint32_t xorMask= xorKey ? 115132718Skan (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0; 116132718Skan 117169699Skan if (entry >= AR_KEYTABLE_SIZE) 118169699Skan return AH_FALSE; 119132718Skan if (k->kv_type != HAL_CIPHER_WEP) { 120169699Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cipher %u not supported\n", 121169699Skan __func__, k->kv_type); 122169699Skan return AH_FALSE; 123169699Skan } 124132718Skan 125132718Skan /* NB: only WEP supported */ 126132718Skan if (k->kv_len < 40 / NBBY) 127132718Skan return AH_FALSE; 128169699Skan if (k->kv_len <= 40 / NBBY) 129169699Skan keyType = AR_KEYTABLE_TYPE_40; 130169699Skan else if (k->kv_len <= 104 / NBBY) 131169699Skan keyType = AR_KEYTABLE_TYPE_104; 132132718Skan else 133169699Skan keyType = AR_KEYTABLE_TYPE_128; 134132718Skan 135132718Skan key0 = LE_READ_4(k->kv_val+0) ^ xorMask; 136169699Skan key1 = (LE_READ_2(k->kv_val+4) ^ xorMask) & 0xffff; 137169699Skan key2 = LE_READ_4(k->kv_val+6) ^ xorMask; 138169699Skan key3 = (LE_READ_2(k->kv_val+10) ^ xorMask) & 0xffff; 139169699Skan key4 = LE_READ_4(k->kv_val+12) ^ xorMask; 140169699Skan if (k->kv_len <= 104 / NBBY) 141132718Skan key4 &= 0xff; 142169699Skan 143132718Skan /* 144132718Skan * Note: WEP key cache hardware requires that each double-word 145132718Skan * pair be written in even/odd order (since the destination is 146169699Skan * a 64-bit register). Don't reorder these writes w/o 147132718Skan * understanding this! 148132718Skan */ 149132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 150132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 151132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 152132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 153132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 154132718Skan OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 155132718Skan return ar5210SetKeyCacheEntryMac(ah, entry, mac); 156132718Skan} 157132718Skan