summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/rt2860.c83
-rw-r--r--sys/dev/ic/rt2860reg.h31
-rw-r--r--sys/dev/ic/rt2860var.h4
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 {