From 5c009670f0761226400d7ab9688e1ba392ea15e1 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 11 Apr 2000 19:59:06 +0000 Subject: [PATCH] - add support for buffers that are not aligned (or end on a non 4byte boundary) - recompute destination length from destination descriptors and reclaim the destination ring there. --- sys/dev/pci/hifn7751.c | 82 ++++++++++++++++++++++++++++----------- sys/dev/pci/hifn7751var.h | 6 ++- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c index 1ba05a7d510..165d58424fe 100644 --- a/sys/dev/pci/hifn7751.c +++ b/sys/dev/pci/hifn7751.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751.c,v 1.28 2000/04/11 16:22:09 jason Exp $ */ +/* $OpenBSD: hifn7751.c,v 1.29 2000/04/11 19:59:06 jason Exp $ */ /* * Invertex AEON / Hi/fn 7751 driver @@ -96,7 +96,7 @@ u_int32_t hifn_next_signature __P((u_int a, u_int cnt)); int hifn_newsession __P((u_int32_t *, struct cryptoini *)); int hifn_freesession __P((u_int32_t)); int hifn_process __P((struct cryptop *)); -void hifn_callback __P((struct hifn_command *, u_int8_t *)); +void hifn_callback __P((struct hifn_softc *, struct hifn_command *, u_int8_t *)); int hifn_crypto __P((struct hifn_softc *, hifn_command_t *)); struct hifn_stats { @@ -1023,18 +1023,45 @@ hifn_crypto(sc, cmd) return (-1); if (nicealign == 0) { - cmd->dst_l = cmd->src_l; - MGETHDR(cmd->dst_m, M_DONTWAIT, MT_DATA); - if (cmd->dst_m == NULL) + int totlen, len; + struct mbuf *m, *top, **mp; + + totlen = cmd->dst_l = cmd->src_l; + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) return (-1); - if (cmd->src_l > MHLEN) { - MCLGET(cmd->dst_m, M_DONTWAIT); - if ((cmd->dst_m->m_flags & M_EXT) == 0) { - m_freem(cmd->dst_m); - return (-1); + len = MHLEN; + if (totlen >= MINCLSIZE) { + MCLGET(m, M_DONTWAIT); + if (m->m_flags & M_EXT) + len = MCLBYTES; + } + m->m_len = len; + top = NULL; + mp = ⊤ + + while (totlen > 0) { + if (top) { + MGET(m, M_DONTWAIT, MT_DATA); + if (m == NULL) { + m_freem(top); + return (-1); + } + len = MLEN; + } + if (top && totlen >= MINCLSIZE) { + MCLGET(m, M_DONTWAIT); + if (m->m_flags & M_EXT) + len = MCLBYTES; } + m->m_len = len = min(totlen, len); + totlen -= len; + *mp = m; + mp = &m->m_next; } - } else + cmd->dst_m = top; + } + else cmd->dst_m = cmd->src_m; cmd->dst_l = hifn_mbuf(cmd->dst_m, &cmd->dst_npa, @@ -1209,7 +1236,7 @@ hifn_intr(arg) } /* position is done, notify producer with callback */ - cmd->dest_ready_callback(cmd, macbuf); + cmd->dest_ready_callback(sc, cmd, macbuf); if (++dma->resk == HIFN_D_RES_RSIZE) dma->resk = 0; @@ -1227,15 +1254,6 @@ hifn_intr(arg) } dma->srck = i; dma->srcu = u; - i = dma->dstk; u = dma->dstu; - while (u != 0 && (dma->dstr[i].l & HIFN_D_VALID) == 0) { - hifnstats.hst_obytes += dma->dstr[i].l & 0xffff; - if (++i == HIFN_D_DST_RSIZE) - i = 0; - u--; - } - dma->dstk = i; dma->dstu = u; - i = dma->cmdk; u = dma->cmdu; while (u != 0 && (dma->cmdr[i].l & HIFN_D_VALID) == 0) { if (++i == HIFN_D_CMD_RSIZE) @@ -1516,18 +1534,38 @@ errout: } void -hifn_callback(cmd, macbuf) +hifn_callback(sc, cmd, macbuf) + struct hifn_softc *sc; struct hifn_command *cmd; u_int8_t *macbuf; { + struct hifn_dma *dma = sc->sc_dma; struct cryptop *crp = (struct cryptop *)cmd->private_data; struct cryptodesc *crd; + struct mbuf *m; 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 ((m = cmd->dst_m) != NULL) { + while (m) { + m->m_len = dma->dstr[dma->dstk].l & HIFN_D_LENGTH; + hifnstats.hst_obytes += m->m_len; + m = m->m_next; + if (++dma->dstk == HIFN_D_DST_RSIZE) + dma->dstk = 0; + dma->dstu--; + } + } + else { + hifnstats.hst_obytes += dma->dstr[dma->dstk].l & HIFN_D_LENGTH; + if (++dma->dstk == HIFN_D_DST_RSIZE) + dma->dstk = 0; + dma->dstu--; + } + if ((cmd->flags & HIFN_ENCODE) && ((cmd->flags & HIFN_CRYPT_DES) || (cmd->flags & HIFN_CRYPT_3DES))) { for (crd = crp->crp_desc; crd; crd = crd->crd_next) { diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h index 3619968c4d6..35c53ef98bb 100644 --- a/sys/dev/pci/hifn7751var.h +++ b/sys/dev/pci/hifn7751var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751var.h,v 1.11 2000/04/10 18:40:47 jason Exp $ */ +/* $OpenBSD: hifn7751var.h,v 1.12 2000/04/11 19:59:06 jason Exp $ */ /* * Invertex AEON / Hi/fn 7751 driver @@ -175,6 +175,8 @@ * An unsigned long quantity (i.e. large enough to hold a pointer), that * can be used by the callback routine if desired. */ +struct hifn_softc; + typedef struct hifn_command { u_int flags; volatile u_int result_flags; @@ -199,7 +201,7 @@ typedef struct hifn_command { u_short mac_header_skip, mac_process_len; u_short crypt_header_skip, crypt_process_len; - void (*dest_ready_callback)(struct hifn_command *, u_int8_t *); + void (*dest_ready_callback)(struct hifn_softc *, struct hifn_command *, u_int8_t *); u_long private_data; struct hifn_softc *softc; } hifn_command_t; -- 2.20.1