Path: blob/main/sys/dev/ath/ath_hal/ar5210/ar5210_keycache.c
39566 views
/*-1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting4* Copyright (c) 2002-2004 Atheros Communications, Inc.5*6* Permission to use, copy, modify, and/or distribute this software for any7* purpose with or without fee is hereby granted, provided that the above8* copyright notice and this permission notice appear in all copies.9*10* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES11* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR13* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF16* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17*/18#include "opt_ah.h"1920#include "ah.h"21#include "ah_internal.h"2223#include "ar5210/ar5210.h"24#include "ar5210/ar5210reg.h"2526#define AR_KEYTABLE_SIZE 6427#define KEY_XOR 0xaa2829/*30* Return the size of the hardware key cache.31*/32u_int33ar5210GetKeyCacheSize(struct ath_hal *ah)34{35return AR_KEYTABLE_SIZE;36}3738/*39* Return the size of the hardware key cache.40*/41HAL_BOOL42ar5210IsKeyCacheEntryValid(struct ath_hal *ah, uint16_t entry)43{44if (entry < AR_KEYTABLE_SIZE) {45uint32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));46if (val & AR_KEYTABLE_VALID)47return AH_TRUE;48}49return AH_FALSE;50}5152/*53* Clear the specified key cache entry.54*/55HAL_BOOL56ar5210ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry)57{58if (entry < AR_KEYTABLE_SIZE) {59OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);60OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);61OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);62OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);63OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);64OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), 0);65OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);66OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);67return AH_TRUE;68}69return AH_FALSE;70}7172/*73* Sets the mac part of the specified key cache entry and mark it valid.74*/75HAL_BOOL76ar5210SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac)77{78uint32_t macHi, macLo;7980if (entry < AR_KEYTABLE_SIZE) {81/*82* Set MAC address -- shifted right by 1. MacLo is83* the 4 MSBs, and MacHi is the 2 LSBs.84*/85if (mac != AH_NULL) {86macHi = (mac[5] << 8) | mac[4];87macLo = (mac[3] << 24)| (mac[2] << 16)88| (mac[1] << 8) | mac[0];89macLo >>= 1;90macLo |= (macHi & 1) << 31; /* carry */91macHi >>= 1;92} else {93macLo = macHi = 0;94}9596OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);97OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry),98macHi | AR_KEYTABLE_VALID);99return AH_TRUE;100}101return AH_FALSE;102}103104/*105* Sets the contents of the specified key cache entry.106*/107HAL_BOOL108ar5210SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry,109const HAL_KEYVAL *k, const uint8_t *mac, int xorKey)110{111uint32_t key0, key1, key2, key3, key4;112uint32_t keyType;113uint32_t xorMask= xorKey ?114(KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;115116if (entry >= AR_KEYTABLE_SIZE)117return AH_FALSE;118if (k->kv_type != HAL_CIPHER_WEP) {119HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cipher %u not supported\n",120__func__, k->kv_type);121return AH_FALSE;122}123124/* NB: only WEP supported */125if (k->kv_len < 40 / NBBY)126return AH_FALSE;127if (k->kv_len <= 40 / NBBY)128keyType = AR_KEYTABLE_TYPE_40;129else if (k->kv_len <= 104 / NBBY)130keyType = AR_KEYTABLE_TYPE_104;131else132keyType = AR_KEYTABLE_TYPE_128;133134key0 = LE_READ_4(k->kv_val+0) ^ xorMask;135key1 = (LE_READ_2(k->kv_val+4) ^ xorMask) & 0xffff;136key2 = LE_READ_4(k->kv_val+6) ^ xorMask;137key3 = (LE_READ_2(k->kv_val+10) ^ xorMask) & 0xffff;138key4 = LE_READ_4(k->kv_val+12) ^ xorMask;139if (k->kv_len <= 104 / NBBY)140key4 &= 0xff;141142/*143* Note: WEP key cache hardware requires that each double-word144* pair be written in even/odd order (since the destination is145* a 64-bit register). Don't reorder these writes w/o146* understanding this!147*/148OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);149OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);150OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);151OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);152OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);153OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);154return ar5210SetKeyCacheEntryMac(ah, entry, mac);155}156157158