diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/rt2860.c | 83 | ||||
-rw-r--r-- | sys/dev/ic/rt2860reg.h | 31 | ||||
-rw-r--r-- | sys/dev/ic/rt2860var.h | 4 |
3 files changed, 113 insertions, 5 deletions
diff --git a/sys/dev/ic/rt2860.c b/sys/dev/ic/rt2860.c index 89f9aeb2695..4775a2f35f1 100644 --- a/sys/dev/ic/rt2860.c +++ b/sys/dev/ic/rt2860.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860.c,v 1.4 2007/11/17 12:04:00 damien Exp $ */ +/* $OpenBSD: rt2860.c,v 1.5 2007/11/17 15:39:38 damien Exp $ */ /*- * Copyright (c) 2007 @@ -126,6 +126,10 @@ void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); void rt2860_updateslot(struct ieee80211com *); void rt2860_updateedca(struct ieee80211com *); +int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *, + const struct ieee80211_key *); +void rt2860_delete_key(struct ieee80211com *, + struct ieee80211_node *, int); int8_t rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t); uint8_t rt2860_maxrssi_chain(struct rt2860_softc *, const struct rt2860_rxwi *); @@ -278,6 +282,8 @@ rt2860_attach(void *xsc, int id) ic->ic_newassoc = rt2860_newassoc; ic->ic_updateslot = rt2860_updateslot; ic->ic_updateedca = rt2860_updateedca; + ic->ic_set_key = rt2860_set_key; + ic->ic_delete_key = rt2860_delete_key; /* override state transition machine */ sc->sc_newstate = ic->ic_newstate; @@ -1934,6 +1940,81 @@ rt2860_updateedca(struct ieee80211com *ic) ic->ic_edca_ac[EDCA_AC_VI].ac_txoplimit); } +int +rt2860_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, + const struct ieee80211_key *k) +{ + struct rt2860_softc *sc = ic->ic_softc; + bus_size_t base; + uint32_t attr; + uint8_t mode, wcid; + + /* map net80211 ciphers to RT2860 security mode */ + switch (k->k_cipher) { + case IEEE80211_CIPHER_WEP40: + mode = RT2860_MODE_WEP40; + break; + case IEEE80211_CIPHER_WEP104: + mode = RT2860_MODE_WEP104; + break; + case IEEE80211_CIPHER_TKIP: + mode = RT2860_MODE_TKIP; + break; + case IEEE80211_CIPHER_CCMP: + mode = RT2860_MODE_AES_CCMP; + break; + default: + return EINVAL; + } + + if (k->k_flags & IEEE80211_KEY_GROUP) { + /* install group key */ + base = RT2860_SKEY(0, k->k_id); + RAL_WRITE_REGION_1(sc, base, k->k_key, k->k_len); + RAL_WRITE_REGION_1(sc, base + 16, k->k_txmic, 8); + RAL_WRITE_REGION_1(sc, base + 24, k->k_rxmic, 8); + + attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7); + attr |= mode << (k->k_id * 4); + RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr); + + } else { + /* install pairwise key */ + wcid = RT2860_AID2WCID(ni->ni_associd); + base = RT2860_PKEY(wcid); + RAL_WRITE_REGION_1(sc, base, k->k_key, k->k_len); + RAL_WRITE_REGION_1(sc, base + 16, k->k_txmic, 8); + RAL_WRITE_REGION_1(sc, base + 24, k->k_rxmic, 8); + + attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid)); + attr = (attr & ~0xf) | (mode << 1) | RT2860_RX_PKEY_EN; + RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr); + } + return 0; +} + +void +rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, int kid) +{ + struct rt2860_softc *sc = ic->ic_softc; + uint32_t attr; + uint8_t wcid; + + if (ni == NULL) { + /* remove group key */ + attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7); + attr &= ~(0xf << (kid * 4)); + RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr); + + } else { + /* remove pairwise key */ + wcid = RT2860_AID2WCID(ni->ni_associd); + attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid)); + attr &= ~0xf; + RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr); + } +} + int8_t rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain) { diff --git a/sys/dev/ic/rt2860reg.h b/sys/dev/ic/rt2860reg.h index be1e5a500e0..66b89929ef8 100644 --- a/sys/dev/ic/rt2860reg.h +++ b/sys/dev/ic/rt2860reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860reg.h,v 1.1 2007/11/15 21:15:34 damien Exp $ */ +/* $OpenBSD: rt2860reg.h,v 1.2 2007/11/17 15:39:38 damien Exp $ */ /*- * Copyright (c) 2007 @@ -157,13 +157,29 @@ #define RT2860_TX_STA_CNT2 0x1714 #define RT2860_TX_STAT_FIFO 0x1718 +/* RX WCID search table */ #define RT2860_WCID_ENTRY(wcid) (0x1800 + (wcid) * 8) + #define RT2860_FW_BASE 0x2000 + +/* Pair-wise key table */ #define RT2860_PKEY(wcid) (0x4000 + (wcid) * 32) + +/* IV/EIV table */ #define RT2860_IVEIV(wcid) (0x6000 + (wcid) * 8) -#define RT2860_WCID_ATTR(wcid) (0x6800 + (wcid) * 8) + +/* WCID attribute table */ +#define RT2860_WCID_ATTR(wcid) (0x6800 + (wcid) * 4) + +/* Shared Key Table */ #define RT2860_SKEY(vap, kidx) (0x6c00 + (vap) * 128 + (kidx) * 32) +/* Shared Key Mode */ +#define RT2860_SKEY_MODE_0_7 0x7000 +#define RT2860_SKEY_MODE_8_15 0x7004 +#define RT2860_SKEY_MODE_16_23 0x7008 +#define RT2860_SKEY_MODE_24_31 0x700c + /* Shared Memory between MCU and host */ #define RT2860_H2M_MAILBOX 0x7010 #define RT2860_H2M_BBPAGENT 0x7028 @@ -581,6 +597,17 @@ #define RT2860_TXQ_PID_SHIFT 1 #define RT2860_TXQ_VLD (1 << 0) +/* possible flags for register WCID_ATTR */ +#define RT2860_MODE_NOSEC 0 +#define RT2860_MODE_WEP40 1 +#define RT2860_MODE_WEP104 2 +#define RT2860_MODE_TKIP 3 +#define RT2860_MODE_AES_CCMP 4 +#define RT2860_MODE_CKIP40 5 +#define RT2860_MODE_CKIP104 6 +#define RT2860_MODE_CKIP128 7 +#define RT2860_RX_PKEY_EN (1 << 0) + /* possible flags for register H2M_MAILBOX */ #define RT2860_H2M_BUSY (1 << 24) #define RT2860_TOKEN_NO_INTR 0xff diff --git a/sys/dev/ic/rt2860var.h b/sys/dev/ic/rt2860var.h index f552158cc5d..4371928a2f3 100644 --- a/sys/dev/ic/rt2860var.h +++ b/sys/dev/ic/rt2860var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2860var.h,v 1.1 2007/11/15 21:15:34 damien Exp $ */ +/* $OpenBSD: rt2860var.h,v 1.2 2007/11/17 15:39:38 damien Exp $ */ /*- * Copyright (c) 2007 @@ -24,7 +24,7 @@ #define RT2860_MAX_SCATTER ((RT2860_TX_RING_COUNT * 2) - 1) /* HW supports up to 255 STAs */ -#define RT2860_WCID_MAX 254 +#define RT2860_WCID_MAX 254 #define RT2860_AID2WCID(aid) ((aid) & 0xff) struct rt2860_tx_data { |