summaryrefslogtreecommitdiff
path: root/sys/dev/pci/ubsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/ubsec.c')
-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);
}