summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2000-06-02 22:42:09 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2000-06-02 22:42:09 +0000
commitcbe1e8e012250e9d881ecfb81519b31abf2ecc1b (patch)
tree8a70fd961ebff98287fa87cecb3236419f68e110 /sys/dev
parent117f27b8abc374d52ab98572c834700a898efe9e (diff)
squeeze basic framework into place. process generates SIMPLEQ of requests,
they get fed in, irq recovers old one, feeds new one in, callback schreds and calls back to crypto(9)... mac result buffers and packet offsets need work.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/ubsec.c147
1 files changed, 90 insertions, 57 deletions
diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c
index b0f938837f9..398358256d8 100644
--- a/sys/dev/pci/ubsec.c
+++ b/sys/dev/pci/ubsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ubsec.c,v 1.1 2000/05/18 01:25:19 jason Exp $ */
+/* $OpenBSD: ubsec.c,v 1.2 2000/06/02 22:42:08 deraadt Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason@thought.net)
@@ -102,12 +102,6 @@
#define UBSEC_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
#define MAX_SCATTER 10
-struct ubsec_command {
- struct mbuf *src_m;
- struct mbuf *dst_m;
- long private_data;
-};
-
struct ubsec_pktctx {
u_int8_t pc_deskey[24]; /* 3DES key */
u_int8_t pc_hminner[20]; /* hmac inner state */
@@ -143,8 +137,8 @@ struct ubsec_mcr {
#define UBS_MCR_ERROR 0x00020000 /* error in processing */
#define UBS_MCR_ERRORCODE 0xff000000 /* error type */
-struct ubsec_queue {
- LIST_ENTRY(ubsec_queue) q_next;
+struct ubsec_q {
+ SIMPLEQ_ENTRY(ubsec_q) q_next;
struct ubsec_softc *q_sc;
struct cryptop *q_crp;
struct ubsec_mcr q_mcr;
@@ -172,8 +166,9 @@ struct ubsec_softc {
int sc_5601; /* device is 5601 */
int32_t sc_cid; /* crypto tag */
u_int32_t sc_intrmask; /* interrupt mask */
- LIST_HEAD(,ubsec_queue) sc_queue; /* packet queue */
+ SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue */
int sc_nqueue; /* count enqueued */
+ SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip */
};
/*
@@ -194,7 +189,8 @@ int ubsec_intr __P((void *));
int ubsec_newsession __P((u_int32_t *, struct cryptoini *));
int ubsec_freesession __P((u_int64_t));
int ubsec_process __P((struct cryptop *));
-void ubsec_callback __P((struct ubsec_softc *, struct ubsec_command *, u_int8_t *));
+void ubsec_callback __P((struct ubsec_softc *, struct ubsec_q *, u_int8_t *));
+int ubsec_crypto __P((struct ubsec_softc *, struct ubsec_q *q));
int
ubsec_probe(parent, match, aux)
@@ -227,7 +223,8 @@ ubsec_attach(parent, self, aux)
bus_size_t iosize;
u_int32_t cmd;
- LIST_INIT(&sc->sc_queue);
+ SIMPLEQ_INIT(&sc->sc_queue);
+ SIMPLEQ_INIT(&sc->sc_qchip);
sc->sc_intrmask = BS_CTRL_MCR1INT | BS_CTRL_DMAERR;
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BLUESTEEL &&
@@ -290,18 +287,63 @@ ubsec_attach(parent, self, aux)
#define READ_REG(sc,r) \
bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (r))
+#define WRITE_REG(sc,reg,val) \
+ bus_space_write_4((sc)->sc_st, (sc)->sc_sh, reg, val)
+
int
ubsec_intr(arg)
void *arg;
{
struct ubsec_softc *sc = arg;
u_int32_t stat;
+ struct ubsec_q *q;
- stat = READ_REG(sc, BS_STAT) & sc->sc_intrmask;
- if (stat == 0)
- return (stat);
+ stat = READ_REG(sc, BS_STAT);
+
+ if (stat & BS_STAT_MCR1_DONE) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_qchip, q, q_next);
+ if (q) {
+ /* XXX must generate macbuf ... */
+ ubsec_callback(sc, q, NULL);
+ }
+ }
+
+ if (stat & BS_STAT_DMAERR) {
+ printf("%s: dmaerr\n", sc->sc_dv.dv_xname);
+ }
+
+ /* if MCR is non-full, put a new command in it */
+ if ((stat & BS_STAT_MCR1_FULL) == 0) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, q, q_next);
+ --sc->sc_nqueue;
+ if (q) {
+ SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
+ WRITE_REG(sc, BS_MCR1, (u_int32_t)&q->q_mcr);
+ }
+ }
- return (1);
+ return (stat ? 1 : 0);
+}
+
+int
+ubsec_crypto(sc, q)
+ struct ubsec_softc *sc;
+ struct ubsec_q *q;
+{
+ int s;
+ u_int32_t stat;
+
+ s = splnet();
+ stat = READ_REG(sc, BS_STAT);
+ if ((stat & BS_STAT_MCR1_FULL) == 0) {
+ WRITE_REG(sc, BS_MCR1, (u_int32_t)&q->q_mcr);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_qchip, q, q_next);
+ } else {
+ SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next);
+ sc->sc_nqueue++;
+ }
+ splx(s);
+ return (0);
}
/*
@@ -337,14 +379,12 @@ ubsec_newsession(sidp, cri)
if (mac)
return (EINVAL);
mac = 1;
- }
- else if (c->cri_alg == CRYPTO_DES_CBC ||
+ } else if (c->cri_alg == CRYPTO_DES_CBC ||
c->cri_alg == CRYPTO_3DES_CBC) {
if (cry)
return (EINVAL);
cry = 1;
- }
- else
+ } else
return (EINVAL);
}
if (mac == 0 && cry == 0)
@@ -370,7 +410,7 @@ int
ubsec_process(crp)
struct cryptop *crp;
{
- struct ubsec_queue *q;
+ struct ubsec_q *q;
int card, err, i;
struct ubsec_softc *sc;
struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
@@ -386,13 +426,13 @@ ubsec_process(crp)
sc = ubsec_cd.cd_devs[card];
- q = (struct ubsec_queue *)malloc(sizeof(struct ubsec_queue),
+ q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q),
M_DEVBUF, M_NOWAIT);
if (q == NULL) {
err = ENOMEM;
goto errout;
}
- bzero(q, sizeof(struct ubsec_queue));
+ bzero(q, sizeof(struct ubsec_q));
q->q_mcr.mcr_flags = 1 & UBS_MCR_PACKETS;
q->q_mcr.mcr_cmdctxp = vtophys(&q->q_ctx);
@@ -402,8 +442,7 @@ ubsec_process(crp)
if (crp->crp_flags & CRYPTO_F_IMBUF) {
q->q_src_m = (struct mbuf *)crp->crp_buf;
q->q_dst_m = (struct mbuf *)crp->crp_buf;
- }
- else {
+ } else {
err = EINVAL;
goto errout; /* XXX only handle mbufs right now */
}
@@ -420,18 +459,15 @@ ubsec_process(crp)
crd1->crd_alg == CRYPTO_SHA1_HMAC96) {
maccrd = crd1;
enccrd = NULL;
- }
- else if (crd1->crd_alg == CRYPTO_DES_CBC ||
+ } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
crd1->crd_alg == CRYPTO_3DES_CBC) {
maccrd = NULL;
enccrd = crd1;
- }
- else {
+ } else {
err = EINVAL;
goto errout;
}
- }
- else {
+ } else {
if ((crd1->crd_alg == CRYPTO_MD5_HMAC96 ||
crd1->crd_alg == CRYPTO_SHA1_HMAC96) &&
(crd2->crd_alg == CRYPTO_DES_CBC ||
@@ -439,16 +475,14 @@ ubsec_process(crp)
((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
maccrd = crd1;
enccrd = crd2;
- }
- else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
+ } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
crd1->crd_alg == CRYPTO_3DES_CBC) &&
(crd2->crd_alg == CRYPTO_MD5_HMAC96 ||
crd2->crd_alg == CRYPTO_SHA1_HMAC96) &&
(crd1->crd_flags & CRD_F_ENCRYPT)) {
enccrd = crd1;
maccrd = crd2;
- }
- else {
+ } else {
/*
* We cannot order the ubsec as requested
*/
@@ -471,8 +505,7 @@ ubsec_process(crp)
if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
m_copyback(q->q_src_m, enccrd->crd_inject,
sizeof(q->q_ctx.pc_iv), q->q_ctx.pc_iv);
- }
- else {
+ } else {
q->q_ctx.pc_flags |= UBS_PKTCTX_INBOUND;
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
@@ -488,14 +521,9 @@ ubsec_process(crp)
bcopy(enccrd->crd_key, &q->q_ctx.pc_deskey[0], 8);
bcopy(enccrd->crd_key, &q->q_ctx.pc_deskey[8], 8);
bcopy(enccrd->crd_key, &q->q_ctx.pc_deskey[16], 8);
- }
- else
+ } else
bcopy(enccrd->crd_key, &q->q_ctx.pc_deskey[0], 24);
-#if 0
- cmd->crypt_header_skip = enccrd->crd_skip;
- cmd->crypt_process_len = enccrd->crd_len;
-#endif
}
if (maccrd) {
@@ -508,10 +536,6 @@ ubsec_process(crp)
bcopy(maccrd->crd_key, &q->q_ctx.pc_hminner[0],
maccrd->crd_klen >> 3);
-#if 0
- cmd->mac_header_skip = maccrd->crd_skip;
- cmd->mac_process_len = maccrd->crd_len;
-#endif
}
q->q_src_l = mbuf2pages(q->q_src_m, &q->q_src_npa, q->q_src_packp,
@@ -562,13 +586,20 @@ ubsec_process(crp)
mp = &m->m_next;
}
q->q_dst_m = top;
- }
- else
+ } else
q->q_dst_m = q->q_src_m;
q->q_dst_l = mbuf2pages(q->q_dst_m, &q->q_dst_npa, q->q_dst_packp,
q->q_dst_packl, MAX_SCATTER, NULL);
+#if 0
+ /* XXX time to incorporate the information in crd_skip... */
+
+ cmd->crypt_header_skip = enccrd->crd_skip;
+ cmd->crypt_process_len = enccrd->crd_len;
+ cmd->mac_header_skip = maccrd->crd_skip;
+ cmd->mac_process_len = maccrd->crd_len;
+#endif
for (i = 0; i < q->q_src_npa; i++) {
struct ubsec_pktbuf *pb;
@@ -603,7 +634,9 @@ ubsec_process(crp)
pb->pb_next = vtophys(&q->q_dstpkt[i]);
}
- err = ENOMEM;
+ /* queues it, or sends it to the chip */
+ ubsec_crypto(sc, q);
+ return (0);
errout:
if (q != NULL) {
@@ -617,17 +650,17 @@ errout:
}
void
-ubsec_callback(sc, cmd, macbuf)
+ubsec_callback(sc, q, macbuf)
struct ubsec_softc *sc;
- struct ubsec_command *cmd;
+ struct ubsec_q *q;
u_int8_t *macbuf;
{
- struct cryptop *crp = (struct cryptop *)cmd->private_data;
+ struct cryptop *crp = (struct cryptop *)q->q_crp;
struct cryptodesc *crd;
- if ((crp->crp_flags & CRYPTO_F_IMBUF) && (cmd->src_m != cmd->dst_m)) {
- m_freem(cmd->src_m);
- crp->crp_buf = (caddr_t)cmd->dst_m;
+ if ((crp->crp_flags & CRYPTO_F_IMBUF) && (q->q_src_m != q->q_dst_m)) {
+ m_freem(q->q_src_m);
+ crp->crp_buf = (caddr_t)q->q_dst_m;
}
if (macbuf != NULL) {
@@ -641,6 +674,6 @@ ubsec_callback(sc, cmd, macbuf)
}
}
- free(cmd, M_DEVBUF);
+ free(q, M_DEVBUF);
crp->crp_callback(crp);
}