diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2000-06-02 22:42:09 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2000-06-02 22:42:09 +0000 |
commit | cbe1e8e012250e9d881ecfb81519b31abf2ecc1b (patch) | |
tree | 8a70fd961ebff98287fa87cecb3236419f68e110 /sys/dev | |
parent | 117f27b8abc374d52ab98572c834700a898efe9e (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.c | 147 |
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); } |