diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2010-05-16 14:34:20 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2010-05-16 14:34:20 +0000 |
commit | a2ca1e3197e352361be0827457d1da054bce8631 (patch) | |
tree | f14537e63a85fbe916a50288f884ffe2ade941ec | |
parent | e7ed5d6a3fac0331caef90ee6b9198619e937def (diff) |
cleanup hardware key cache management (not used yet)
-rw-r--r-- | sys/dev/ic/ar5008.c | 16 | ||||
-rw-r--r-- | sys/dev/ic/ar9003.c | 16 | ||||
-rw-r--r-- | sys/dev/ic/ar9280.c | 5 | ||||
-rw-r--r-- | sys/dev/ic/athn.c | 130 | ||||
-rw-r--r-- | sys/dev/ic/athnvar.h | 3 |
5 files changed, 105 insertions, 65 deletions
diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c index 5ee1871501c..655888f6002 100644 --- a/sys/dev/ic/ar5008.c +++ b/sys/dev/ic/ar5008.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5008.c,v 1.6 2010/05/16 09:42:04 damien Exp $ */ +/* $OpenBSD: ar5008.c,v 1.7 2010/05/16 14:34:19 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -1363,29 +1363,27 @@ ar5008_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) IEEE80211_QOS_ACK_POLICY_NOACK)) ds->ds_ctl1 |= AR_TXC1_NO_ACK; - if (0 && wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - /* Retrieve key for encryption. */ - k = ieee80211_get_txkey(ic, wh, ni); + if (0 && k != NULL) { /* * Map 802.11 cipher to hardware encryption type and - * compute crypto overhead. + * compute MIC+ICV overhead. */ switch (k->k_cipher) { case IEEE80211_CIPHER_WEP40: case IEEE80211_CIPHER_WEP104: encrtype = AR_ENCR_TYPE_WEP; - totlen += 8; + totlen += 4; break; case IEEE80211_CIPHER_TKIP: encrtype = AR_ENCR_TYPE_TKIP; - totlen += 20; + totlen += 12; break; case IEEE80211_CIPHER_CCMP: encrtype = AR_ENCR_TYPE_AES; - totlen += 16; + totlen += 8; break; default: - panic("unsupported cipher"); /* XXX BIP? */ + panic("unsupported cipher"); } /* * NB: The key cache entry index is stored in the key diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c index 753cc3516d5..bddcb8f7912 100644 --- a/sys/dev/ic/ar9003.c +++ b/sys/dev/ic/ar9003.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9003.c,v 1.10 2010/05/16 09:49:27 damien Exp $ */ +/* $OpenBSD: ar9003.c,v 1.11 2010/05/16 14:34:19 damien Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -1391,29 +1391,27 @@ ar9003_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) IEEE80211_QOS_ACK_POLICY_NOACK)) ds->ds_ctl12 |= AR_TXC12_NO_ACK; - if (0 && wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - /* Retrieve key for encryption. */ - k = ieee80211_get_txkey(ic, wh, ni); + if (0 && k != NULL) { /* * Map 802.11 cipher to hardware encryption type and - * compute crypto overhead. + * compute MIC+ICV overhead. */ switch (k->k_cipher) { case IEEE80211_CIPHER_WEP40: case IEEE80211_CIPHER_WEP104: encrtype = AR_ENCR_TYPE_WEP; - totlen += 8; + totlen += 4; break; case IEEE80211_CIPHER_TKIP: encrtype = AR_ENCR_TYPE_TKIP; - totlen += 20; + totlen += 12; break; case IEEE80211_CIPHER_CCMP: encrtype = AR_ENCR_TYPE_AES; - totlen += 16; + totlen += 8; break; default: - panic("unsupported cipher"); /* XXX BIP? */ + panic("unsupported cipher"); } /* * NB: The key cache entry index is stored in the key diff --git a/sys/dev/ic/ar9280.c b/sys/dev/ic/ar9280.c index 9e05c47b5a3..233c27dcafa 100644 --- a/sys/dev/ic/ar9280.c +++ b/sys/dev/ic/ar9280.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar9280.c,v 1.6 2010/05/11 18:04:12 damien Exp $ */ +/* $OpenBSD: ar9280.c,v 1.7 2010/05/16 14:34:19 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -96,6 +96,9 @@ const struct ar_spur_chan * int ar9280_attach(struct athn_softc *sc) { + /* AR9280 1.0 needs separate entries for Tx/Rx TKIP MIC. */ + if (AR_SREV_9280_10(sc)) + sc->flags |= ATHN_FLAG_SPLIT_TKIP_MIC; sc->eep_base = AR5416_EEP_START_LOC; sc->eep_size = sizeof(struct ar5416_eeprom); sc->def_nf = AR9280_PHY_CCA_MAX_GOOD_VALUE; diff --git a/sys/dev/ic/athn.c b/sys/dev/ic/athn.c index 2d9b449fde9..d96423fd2b0 100644 --- a/sys/dev/ic/athn.c +++ b/sys/dev/ic/athn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: athn.c,v 1.43 2010/05/16 09:42:04 damien Exp $ */ +/* $OpenBSD: athn.c,v 1.44 2010/05/16 14:34:19 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -215,13 +215,18 @@ athn_attach(struct athn_softc *sc) sc->rfsilent_pin)); } DPRINTF(("%d key cache entries\n", sc->kc_entries)); - /* * In HostAP mode, the number of STAs that we can handle is * limited by the number of entries in the HW key cache. - * XXX TKIP MMIC + * TKIP keys consume 2 or 4 entries in the cache. */ - ic->ic_max_nnodes = sc->kc_entries - IEEE80211_GROUP_NKID; + ic->ic_max_nnodes = sc->kc_entries - IEEE80211_WEP_NKID; + if (sc->flags & ATHN_FLAG_SPLIT_TKIP_MIC) + ic->ic_max_nnodes /= 4; + else + ic->ic_max_nnodes /= 2; + if (ic->ic_max_nnodes > IEEE80211_CACHE_SIZE) + ic->ic_max_nnodes = IEEE80211_CACHE_SIZE; DPRINTF(("using %s loop power control\n", (sc->flags & ATHN_FLAG_OLPC) ? "open" : "closed")); @@ -389,13 +394,13 @@ void athn_radiotap_attach(struct athn_softc *sc) { bpfattach(&sc->sc_drvbpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN); + sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(ATHN_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(ATHN_TX_RADIOTAP_PRESENT); } @@ -939,52 +944,82 @@ athn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, return (ieee80211_set_key(ic, ni, k)); } - memset(keybuf, 0, sizeof keybuf); + memset(keybuf, 0, sizeof(keybuf)); memcpy(keybuf, k->k_key, MIN(k->k_len, 16)); if (!(k->k_flags & IEEE80211_KEY_GROUP)) - entry = IEEE80211_GROUP_NKID + IEEE80211_AID(ni->ni_associd); + entry = IEEE80211_WEP_NKID + IEEE80211_AID(ni->ni_associd); else entry = k->k_id; k->k_priv = (void *)entry; /* NB: See note about key cache registers access above. */ if (type == AR_KEYTABLE_TYPE_TKIP) { - micentry = entry + 64; - - /* XXX Split MIC. */ - AR_WRITE(sc, AR_KEYTABLE_KEY0(micentry), - micbuf[0] | micbuf[1] << 16); - AR_WRITE(sc, AR_KEYTABLE_KEY1(micentry), micbuf[2]); - - AR_WRITE(sc, AR_KEYTABLE_KEY2(micentry), - micbuf[3] | micbuf[4] << 16); - AR_WRITE(sc, AR_KEYTABLE_KEY3(micentry), micbuf[5]); - - AR_WRITE(sc, AR_KEYTABLE_KEY4(micentry), - micbuf[6] | micbuf[7] << 16); - AR_WRITE(sc, AR_KEYTABLE_TYPE(micentry), AR_KEYTABLE_TYPE_CLR); - - /* MAC address registers are reserved for the MIC entry. */ - AR_WRITE(sc, AR_KEYTABLE_MAC0(micentry), 0); - AR_WRITE(sc, AR_KEYTABLE_MAC1(micentry), 0); - } else { - AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), - keybuf[0] | keybuf[1] << 16); - AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), keybuf[2]); - - AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), - keybuf[3] | keybuf[4] << 16); - AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), keybuf[5]); - - AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), - keybuf[6] | keybuf[7] << 16); - AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), type); + if (sc->flags & ATHN_FLAG_SPLIT_TKIP_MIC) { + /* Tx MIC is at entry + 64. */ + micentry = entry + 64; + memcpy(micbuf, &k->k_key[16], 8); + AR_WRITE(sc, AR_KEYTABLE_KEY0(micentry), + micbuf[0] | micbuf[1] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY1(micentry), + micbuf[2]); + AR_WRITE(sc, AR_KEYTABLE_KEY2(micentry), + micbuf[3] | micbuf[4] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY3(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_KEY4(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + /* MAC address is reserved for the MIC entry. */ + AR_WRITE(sc, AR_KEYTABLE_MAC0(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_MAC1(micentry), 0); + + /* Rx MIC is at entry + 64 + 32. */ + micentry = entry + 64 + 32; + memcpy(micbuf, &k->k_key[24], 8); + AR_WRITE(sc, AR_KEYTABLE_KEY0(micentry), + micbuf[0] | micbuf[1] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY1(micentry), + micbuf[2]); + AR_WRITE(sc, AR_KEYTABLE_KEY2(micentry), + micbuf[3] | micbuf[4] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY3(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_KEY4(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + /* MAC address is reserved for the MIC entry. */ + AR_WRITE(sc, AR_KEYTABLE_MAC0(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_MAC1(micentry), 0); + } else { + /* Tx+Rx MIC is at entry + 64. */ + micentry = entry + 64; + memcpy(micbuf, &k->k_key[16], 16); + AR_WRITE(sc, AR_KEYTABLE_KEY0(micentry), + micbuf[0] | micbuf[1] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY1(micentry), + micbuf[2]); + AR_WRITE(sc, AR_KEYTABLE_KEY2(micentry), + micbuf[3] | micbuf[4] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY3(micentry), + micbuf[5]); + AR_WRITE(sc, AR_KEYTABLE_KEY4(micentry), + micbuf[6] | micbuf[7] << 16); + AR_WRITE(sc, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + /* MAC address is reserved for the MIC entry. */ + AR_WRITE(sc, AR_KEYTABLE_MAC0(micentry), 0); + AR_WRITE(sc, AR_KEYTABLE_MAC1(micentry), 0); + } } + AR_WRITE(sc, AR_KEYTABLE_KEY0(entry), keybuf[0] | keybuf[1] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY1(entry), keybuf[2]); + AR_WRITE(sc, AR_KEYTABLE_KEY2(entry), keybuf[3] | keybuf[4] << 16); + AR_WRITE(sc, AR_KEYTABLE_KEY3(entry), keybuf[5]); + AR_WRITE(sc, AR_KEYTABLE_KEY4(entry), keybuf[6] | keybuf[7] << 16); + AR_WRITE(sc, AR_KEYTABLE_TYPE(entry), type); /* Clear keys from the stack. */ - memset(keybuf, 0, sizeof keybuf); - memset(micbuf, 0, sizeof micbuf); + memset(keybuf, 0, sizeof(keybuf)); + memset(micbuf, 0, sizeof(micbuf)); if (!(k->k_flags & IEEE80211_KEY_GROUP)) { addr = ni->ni_macaddr; @@ -1009,11 +1044,17 @@ athn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, switch (k->k_cipher) { case IEEE80211_CIPHER_WEP40: case IEEE80211_CIPHER_WEP104: - case IEEE80211_CIPHER_TKIP: case IEEE80211_CIPHER_CCMP: entry = (uintptr_t)k->k_priv; athn_reset_key(sc, entry); break; + case IEEE80211_CIPHER_TKIP: + entry = (uintptr_t)k->k_priv; + athn_reset_key(sc, entry); + athn_reset_key(sc, entry + 64); + if (sc->flags & ATHN_FLAG_SPLIT_TKIP_MIC) + athn_reset_key(sc, entry + 64 + 32); + break; default: /* Fallback to software crypto for other ciphers. */ ieee80211_delete_key(ic, ni, k); @@ -2122,7 +2163,7 @@ athn_hw_reset(struct athn_softc *sc, struct ieee80211_channel *c, athn_init_qos(sc); - if (!AR_SREV_9280_10(sc)) + if (!(sc->flags & ATHN_FLAG_SPLIT_TKIP_MIC)) AR_SETBITS(sc, AR_PCU_MISC, AR_PCU_MIC_NEW_LOC_ENA); if (AR_SREV_9287_12_OR_LATER(sc)) @@ -2161,8 +2202,7 @@ athn_hw_reset(struct athn_softc *sc, struct ieee80211_channel *c, struct ieee80211_node * athn_node_alloc(struct ieee80211com *ic) { - return (malloc(sizeof (struct athn_node), M_DEVBUF, - M_NOWAIT | M_ZERO)); + return (malloc(sizeof(struct athn_node), M_DEVBUF, M_NOWAIT | M_ZERO)); } void diff --git a/sys/dev/ic/athnvar.h b/sys/dev/ic/athnvar.h index 4c7b8b14750..4ed94430fdf 100644 --- a/sys/dev/ic/athnvar.h +++ b/sys/dev/ic/athnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athnvar.h,v 1.13 2010/05/16 09:42:04 damien Exp $ */ +/* $OpenBSD: athnvar.h,v 1.14 2010/05/16 14:34:19 damien Exp $ */ /*- * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> @@ -427,6 +427,7 @@ struct athn_softc { #define ATHN_FLAG_11A (1 << 8) #define ATHN_FLAG_11G (1 << 9) #define ATHN_FLAG_11N (1 << 10) +#define ATHN_FLAG_SPLIT_TKIP_MIC (1 << 11) uint8_t ngpiopins; int led_pin; |