ar5210_keycache.c revision 204644
1184610Salfred/* 2184610Salfred * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3184610Salfred * Copyright (c) 2002-2004 Atheros Communications, Inc. 4184610Salfred * 5184610Salfred * Permission to use, copy, modify, and/or distribute this software for any 6184610Salfred * purpose with or without fee is hereby granted, provided that the above 7184610Salfred * copyright notice and this permission notice appear in all copies. 8184610Salfred * 9184610Salfred * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10184610Salfred * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11184610Salfred * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12184610Salfred * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13184610Salfred * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14184610Salfred * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15184610Salfred * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16184610Salfred * 17184610Salfred * $FreeBSD: head/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c 204644 2010-03-03 17:32:32Z rpaulo $ 18184610Salfred */ 19184610Salfred#include "opt_ah.h" 20184610Salfred 21184610Salfred#include "ah.h" 22184610Salfred#include "ah_internal.h" 23184610Salfred 24184610Salfred#include "ar5210/ar5210.h" 25184610Salfred#include "ar5210/ar5210reg.h" 26184610Salfred 27188942Sthompsa#define AR_KEYTABLE_SIZE 64 28188942Sthompsa#define KEY_XOR 0xaa 29188942Sthompsa 30188942Sthompsa/* 31184610Salfred * Return the size of the hardware key cache. 32184610Salfred */ 33184610Salfredu_int 34188942Sthompsaar5210GetKeyCacheSize(struct ath_hal *ah) 35188942Sthompsa{ 36188942Sthompsa return AR_KEYTABLE_SIZE; 37188942Sthompsa} 38188942Sthompsa 39188942Sthompsa/* 40188942Sthompsa * Return the size of the hardware key cache. 41188942Sthompsa */ 42188942SthompsaHAL_BOOL 43188942Sthompsaar5210IsKeyCacheEntryValid(struct ath_hal *ah, uint16_t entry) 44188942Sthompsa{ 45188942Sthompsa if (entry < AR_KEYTABLE_SIZE) { 46184610Salfred uint32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 47188942Sthompsa if (val & AR_KEYTABLE_VALID) 48188942Sthompsa return AH_TRUE; 49184610Salfred } 50190191Sthompsa return AH_FALSE; 51190191Sthompsa} 52184610Salfred 53184610Salfred/* 54184610Salfred * Clear the specified key cache entry. 55184610Salfred */ 56184610SalfredHAL_BOOL 57184610Salfredar5210ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) 58184610Salfred{ 59184610Salfred if (entry < AR_KEYTABLE_SIZE) { 60193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); 61193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); 62193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); 63193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); 64193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); 65193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 0); 66193045Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); 67184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); 68193045Sthompsa return AH_TRUE; 69193045Sthompsa } 70193045Sthompsa return AH_FALSE; 71193045Sthompsa} 72193045Sthompsa 73193045Sthompsa/* 74193045Sthompsa * Sets the mac part of the specified key cache entry and mark it valid. 75184610Salfred */ 76192984SthompsaHAL_BOOL 77192984Sthompsaar5210SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac) 78192984Sthompsa{ 79192984Sthompsa uint32_t macHi, macLo; 80192984Sthompsa 81192984Sthompsa if (entry < AR_KEYTABLE_SIZE) { 82192984Sthompsa /* 83192984Sthompsa * Set MAC address -- shifted right by 1. MacLo is 84192984Sthompsa * the 4 MSBs, and MacHi is the 2 LSBs. 85194228Sthompsa */ 86192984Sthompsa if (mac != AH_NULL) { 87192984Sthompsa macHi = (mac[5] << 8) | mac[4]; 88192984Sthompsa macLo = (mac[3] << 24)| (mac[2] << 16) 89192984Sthompsa | (mac[1] << 8) | mac[0]; 90192984Sthompsa macLo >>= 1; 91184610Salfred macLo |= (macHi & 1) << 31; /* carry */ 92184610Salfred macHi >>= 1; 93184610Salfred } else { 94194228Sthompsa macLo = macHi = 0; 95184610Salfred } 96184610Salfred 97184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); 98185087Salfred OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 99184610Salfred macHi | AR_KEYTABLE_VALID); 100184610Salfred return AH_TRUE; 101184610Salfred } 102184610Salfred return AH_FALSE; 103184610Salfred} 104184610Salfred 105184610Salfred/* 106184610Salfred * Sets the contents of the specified key cache entry. 107184610Salfred */ 108192502SthompsaHAL_BOOL 109192502Sthompsaar5210SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, 110184610Salfred const HAL_KEYVAL *k, const uint8_t *mac, int xorKey) 111184610Salfred{ 112184610Salfred uint32_t key0, key1, key2, key3, key4; 113184610Salfred uint32_t keyType; 114184610Salfred uint32_t xorMask= xorKey ? 115184610Salfred (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0; 116184610Salfred 117192984Sthompsa if (entry >= AR_KEYTABLE_SIZE) 118192984Sthompsa return AH_FALSE; 119184610Salfred if (k->kv_type != HAL_CIPHER_WEP) { 120193644Sthompsa HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cipher %u not supported\n", 121192984Sthompsa __func__, k->kv_type); 122193644Sthompsa return AH_FALSE; 123184610Salfred } 124184610Salfred 125184610Salfred /* NB: only WEP supported */ 126184610Salfred if (k->kv_len < 40 / NBBY) 127184610Salfred return AH_FALSE; 128194228Sthompsa if (k->kv_len <= 40 / NBBY) 129184610Salfred keyType = AR_KEYTABLE_TYPE_40; 130184610Salfred else if (k->kv_len <= 104 / NBBY) 131194228Sthompsa keyType = AR_KEYTABLE_TYPE_104; 132184610Salfred else 133184610Salfred keyType = AR_KEYTABLE_TYPE_128; 134184610Salfred 135184610Salfred key0 = LE_READ_4(k->kv_val+0) ^ xorMask; 136194228Sthompsa key1 = (LE_READ_2(k->kv_val+4) ^ xorMask) & 0xffff; 137184610Salfred key2 = LE_READ_4(k->kv_val+6) ^ xorMask; 138184610Salfred key3 = (LE_READ_2(k->kv_val+10) ^ xorMask) & 0xffff; 139194228Sthompsa key4 = LE_READ_4(k->kv_val+12) ^ xorMask; 140184610Salfred if (k->kv_len <= 104 / NBBY) 141184610Salfred key4 &= 0xff; 142184610Salfred 143184610Salfred /* 144194228Sthompsa * Note: WEP key cache hardware requires that each double-word 145184610Salfred * pair be written in even/odd order (since the destination is 146184610Salfred * a 64-bit register). Don't reorder these writes w/o 147184610Salfred * understanding this! 148184610Salfred */ 149184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 150184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 151184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 152184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 153192984Sthompsa OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 154184610Salfred OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 155193644Sthompsa return ar5210SetKeyCacheEntryMac(ah, entry, mac); 156193644Sthompsa} 157184610Salfred