summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2000-03-29 20:55:00 +0000
committerJason Wright <jason@cvs.openbsd.org>2000-03-29 20:55:00 +0000
commit3ab02fc81d90a0157cc020b0c61660faa072e7ce (patch)
treefe84dab83fd894757e1c8c629c78ab373082a445 /sys/dev/pci
parente23adf48556def630d861e7e0f95b9e7e71abc70 (diff)
Long over due checkpoint:
o register the hifn as handling DES and 3DES (no md5 or sha1 yet) depending on whether the board is unlocked (none, half, or full) o Fix many KNF nits o print the amount of memory correctly and don't print the number of sessions o set command and result buffer sizes correctly o reclaim the descriptor rings so new commands and buffers can be added o remove some bogus checks on the command buffer o add new variables mac_process_len and crypt_process_len to hifn_command_t o fix calculation in hifn_mbuf to generate the pa/len array for src/dst o simplify the code for setting up the jump descriptor o rework the hifn_intr routine to interrupt at IPL_IMP and simplify it's results processing o more to come...
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/hifn7751.c458
-rw-r--r--sys/dev/pci/hifn7751reg.h77
-rw-r--r--sys/dev/pci/hifn7751var.h10
3 files changed, 408 insertions, 137 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c
index 7a996122203..4e8e648beeb 100644
--- a/sys/dev/pci/hifn7751.c
+++ b/sys/dev/pci/hifn7751.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751.c,v 1.16 2000/03/22 05:30:47 jason Exp $ */
+/* $OpenBSD: hifn7751.c,v 1.17 2000/03/29 20:54:59 jason Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -46,6 +46,9 @@
#include <machine/pmap.h>
#include <sys/device.h>
+#include <crypto/crypto.h>
+#include <dev/rndvar.h>
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@@ -69,26 +72,28 @@ struct cfdriver hifn_cd = {
0, "hifn", DV_DULL
};
-void hifn_reset_board __P((struct hifn_softc *));
-int hifn_enable_crypto __P((struct hifn_softc *, pcireg_t));
-void hifn_init_dma __P((struct hifn_softc *));
+void hifn_reset_board __P((struct hifn_softc *));
+int hifn_enable_crypto __P((struct hifn_softc *, pcireg_t));
+void hifn_init_dma __P((struct hifn_softc *));
void hifn_init_pci_registers __P((struct hifn_softc *));
int hifn_sramsize __P((struct hifn_softc *));
int hifn_dramsize __P((struct hifn_softc *));
int hifn_checkramaddr __P((struct hifn_softc *, int));
void hifn_sessions __P((struct hifn_softc *));
-int hifn_intr __P((void *));
+int hifn_intr __P((void *));
u_int hifn_write_command __P((const struct hifn_command_buf_data *,
u_int8_t *));
int hifn_build_command __P((const struct hifn_command * cmd,
struct hifn_command_buf_data *));
-int hifn_mbuf __P((struct mbuf *, int *np, long *pp, int *lp, int maxp,
- int *nicealign));
+int hifn_mbuf __P((struct mbuf *, int *, long *, int *, int, int *));
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 *));
+void hifn_timeout __P((void *));
+void hifn_print_stats __P((struct hifn_softc *));
-/*
- * Used for round robin crypto requests
- */
int
hifn_probe(parent, match, aux)
struct device *parent;
@@ -116,9 +121,11 @@ hifn_attach(parent, self, aux)
pci_chipset_tag_t pc = pa->pa_pc;
pci_intr_handle_t ih;
const char *intrstr = NULL;
+ char rbase;
bus_addr_t iobase;
bus_size_t iosize;
u_int32_t cmd;
+ u_int16_t ena;
bus_dma_segment_t seg;
bus_dmamap_t dmamap;
int rseg;
@@ -222,7 +229,7 @@ hifn_attach(parent, self, aux)
return;
}
intrstr = pci_intr_string(pc, ih);
- sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, hifn_intr, sc,
+ sc->sc_ih = pci_intr_establish(pc, ih, IPL_IMP, hifn_intr, sc,
self->dv_xname);
if (sc->sc_ih == NULL) {
printf(": couldn't establish interrupt\n");
@@ -234,9 +241,39 @@ hifn_attach(parent, self, aux)
hifn_sessions(sc);
- printf(", %dk %cram, %d sessions, %s\n",
- sc->sc_ramsize/1024, sc->sc_drammodel ? 'd' : 's',
- sc->sc_maxses, intrstr);
+ rseg = sc->sc_ramsize / 1024;
+ rbase = 'K';
+ if (sc->sc_ramsize >= (1024 * 1024)) {
+ rbase = 'M';
+ rseg /= 1024;
+ }
+ printf(", %d%cB %cram, %s\n", rseg, rbase,
+ sc->sc_drammodel ? 'd' : 's', intrstr);
+
+ sc->sc_cid = crypto_get_driverid();
+ if (sc->sc_cid < 0)
+ return;
+
+ WRITE_REG_0(sc, HIFN_0_PUCNFG,
+ READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
+ ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
+
+ switch (ena) {
+ case HIFN_PUSTAT_ENA_2:
+ crypto_register(sc->sc_cid, CRYPTO_3DES_CBC,
+ hifn_newsession, hifn_freesession, hifn_process);
+ /*FALLTHROUGH*/
+ case HIFN_PUSTAT_ENA_1:
+#if 0
+ /* Can't do md5/sha1 yet */
+ crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC96,
+ hifn_newsession, hifn_freesession, hifn_process);
+ crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC96,
+ NULL, NULL, NULL);
+#endif
+ crypto_register(sc->sc_cid, CRYPTO_DES_CBC,
+ hifn_newsession, hifn_freesession, hifn_process);
+ }
}
/*
@@ -463,8 +500,7 @@ hifn_init_pci_registers(sc)
WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
- HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE |
- HIFN_DMACNFG_LAST |
+ HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
}
@@ -572,7 +608,7 @@ hifn_checkramaddr(sc, addr)
read_command.total_source_count = addr & 0x3fff;
read_command.total_dest_count = 8;
-#if (HIFN_D_RSIZE < 3)
+#if (HIFN_D_CMD_RSIZE < 3)
#error "descriptor ring size too small DRAM/SRAM check"
#endif
@@ -637,6 +673,9 @@ hifn_init_dma(sc)
dma->srcr[HIFN_D_SRC_RSIZE].p = vtophys(dma->srcr);
dma->dstr[HIFN_D_DST_RSIZE].p = vtophys(dma->dstr);
dma->resr[HIFN_D_RES_RSIZE].p = vtophys(dma->resr);
+ dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
+ dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
+ dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
}
/*
@@ -721,7 +760,7 @@ hifn_build_command(const struct hifn_command *cmd,
hifn_mac_command_t *mac_cmd = &cmd_buf_data->mac_cmd;
hifn_crypt_command_t *crypt_cmd = &cmd_buf_data->crypt_cmd;
u_int mac_length;
-#ifdef HIFN_COMMAND_CHECKING
+#if defined(HIFN_COMMAND_CHECKING) && 0
int dest_diff;
#endif
@@ -757,12 +796,14 @@ hifn_build_command(const struct hifn_command *cmd,
*/
/*
- * XXX XXX We need to include header counts into all these
+ * XXX XXX We need to include header counts into all these
* checks!!!!
+ * XXX These tests are totally wrong.
*/
-
+#if 0
if (cmd->src_npa <= mac_length) {
- printf("hifn: command source buffer has no data\n");
+ printf("hifn: command source buffer has no data: %d <= %d\n",
+ cmd->src_npa, mac_length);
return -1;
}
dest_diff = (flags & HIFN_ENCODE) ? mac_length : -mac_length;
@@ -772,6 +813,7 @@ hifn_build_command(const struct hifn_command *cmd,
return -1;
}
#endif
+#endif
/*
* Set MAC bit
@@ -835,7 +877,7 @@ hifn_build_command(const struct hifn_command *cmd,
* Set the mac header skip and source count.
*/
mac_cmd->header_skip = cmd->mac_header_skip;
- mac_cmd->source_count = cmd->src_npa - cmd->mac_header_skip;
+ mac_cmd->source_count = cmd->mac_process_len;
if (flags & HIFN_DECODE)
mac_cmd->source_count -= mac_length;
}
@@ -854,7 +896,7 @@ hifn_build_command(const struct hifn_command *cmd,
/*
* Setup to send new encrypt key if needed.
*/
- if (flags & HIFN_CRYPT_CMD_NEW_KEY) {
+ if (flags & HIFN_CRYPT_NEW_KEY) {
crypt_cmd->masks |= HIFN_CRYPT_CMD_NEW_KEY;
cmd_buf_data->ck = cmd->ck;
}
@@ -862,7 +904,7 @@ hifn_build_command(const struct hifn_command *cmd,
* Set the encrypt header skip and source count.
*/
crypt_cmd->header_skip = cmd->crypt_header_skip;
- crypt_cmd->source_count = cmd->src_npa - cmd->crypt_header_skip;
+ crypt_cmd->source_count = cmd->crypt_process_len;
if (flags & HIFN_DECODE)
crypt_cmd->source_count -= mac_length;
@@ -878,7 +920,7 @@ hifn_build_command(const struct hifn_command *cmd,
cmd_buf_data->iv = cmd->iv;
-#if 1
+#if 0
printf("hifn: command parameters"
" -- session num %u"
" -- base t.s.c: %u"
@@ -904,11 +946,9 @@ hifn_mbuf(m, np, pp, lp, maxp, nicep)
int *nicep;
{
struct mbuf *m0;
- int npa = *np;
- int tlen = 0;
+ int npa = 0, tlen = 0;
/* generate a [pa,len] array from an mbuf */
- npa = 0;
for (m0 = m; m; m = m->m_next) {
void *va;
long pg, npg;
@@ -928,18 +968,23 @@ hifn_mbuf(m, np, pp, lp, maxp, nicep)
npg = vtophys(va);
if (npg != pg) {
/* FUCKED UP condition */
- npa++;
+ if (++npa > maxp)
+ return (0);
continue;
}
lp[npa] = PAGE_SIZE - off;
off = 0;
- ++npa;
- if (npa > maxp)
+
+ if (++npa > maxp)
return (0);
+
lp[npa] = len - (PAGE_SIZE - off);
len -= lp[npa];
pp[npa] = vtophys(va);
}
+
+ if (++npa == maxp)
+ return (0);
}
if (nicep) {
@@ -971,7 +1016,9 @@ hifn_crypto(struct hifn_command *cmd)
/* Pick the hifn board to send the data to. Right now we use a round
* robin approach. */
sc = hifn_cd.cd_devs[current_device];
- if (++current_device == hifn_cd.cd_ndevs)
+ current_device++;
+ if (current_device == hifn_cd.cd_ndevs ||
+ hifn_cd.cd_devs[current_device] == NULL)
current_device = 0;
dma = sc->sc_dma;
@@ -1004,11 +1051,13 @@ hifn_crypto(struct hifn_command *cmd)
if (hifn_build_command(cmd, &cmd_buf_data) != 0)
return HIFN_CRYPTO_BAD_INPUT;
+#ifdef HIFN_DEBUG
printf("%s: Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
sc->sc_dv.dv_xname,
READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER),
dma->cmdu, dma->srcu, dma->dstu, dma->resu, cmd->src_npa,
cmd->dst_npa);
+#endif
s = splimp();
@@ -1028,25 +1077,27 @@ hifn_crypto(struct hifn_command *cmd)
}
if (dma->cmdi == HIFN_D_CMD_RSIZE) {
- cmdi = 0, dma->cmdi = 1;
+ dma->cmdi = 0;
dma->cmdr[HIFN_D_CMD_RSIZE].l = HIFN_D_VALID | HIFN_D_LAST |
HIFN_D_MASKDONEIRQ | HIFN_D_JUMP;
- } else
- cmdi = dma->cmdi++;
+ }
+ cmdi = dma->cmdi++;
if (dma->resi == HIFN_D_RES_RSIZE) {
- resi = 0, dma->resi = 1;
+ dma->resi = 0;
dma->resr[HIFN_D_RES_RSIZE].l = HIFN_D_VALID | HIFN_D_LAST |
HIFN_D_MASKDONEIRQ | HIFN_D_JUMP;
- } else
- resi = dma->resi++;
+ }
+ resi = dma->resi++;
cmdlen = hifn_write_command(&cmd_buf_data, dma->command_bufs[cmdi]);
- dma->hifn_commands[cmdi] = cmd;
+#ifdef HIFN_DEBUG
+ printf("write_command %d (nice %d)\n", cmdlen, nicealign);
+#endif
/* .p for command/result already set */
dma->cmdr[cmdi].l = cmdlen | HIFN_D_VALID | HIFN_D_LAST |
HIFN_D_MASKDONEIRQ;
- dma->cmdu += 1;
+ dma->cmdu++;
for (i = 0; i < cmd->src_npa; i++) {
int last = 0;
@@ -1057,10 +1108,10 @@ hifn_crypto(struct hifn_command *cmd)
if (dma->srci == HIFN_D_SRC_RSIZE) {
srci = 0, dma->srci = 1;
dma->srcr[HIFN_D_SRC_RSIZE].l = HIFN_D_VALID |
- HIFN_D_MASKDONEIRQ | HIFN_D_JUMP;
+ HIFN_D_MASKDONEIRQ | HIFN_D_JUMP | HIFN_D_LAST;
} else
srci = dma->srci++;
- dma->srcr[srci].p = vtophys(cmd->src_packp[i]);
+ dma->srcr[srci].p = cmd->src_packp[i];
dma->srcr[srci].l = cmd->src_packl[i] | HIFN_D_VALID |
HIFN_D_MASKDONEIRQ | last;
}
@@ -1069,13 +1120,16 @@ hifn_crypto(struct hifn_command *cmd)
for (i = 0; i < cmd->dst_npa; i++) {
int last = 0;
+ if (i == cmd->dst_npa-1)
+ last = HIFN_D_LAST;
+
if (dma->dsti == HIFN_D_DST_RSIZE) {
dsti = 0, dma->dsti = 1;
dma->dstr[HIFN_D_DST_RSIZE].l = HIFN_D_VALID |
- HIFN_D_MASKDONEIRQ | HIFN_D_JUMP;
+ HIFN_D_MASKDONEIRQ | HIFN_D_JUMP | HIFN_D_LAST;
} else
dsti = dma->dsti++;
- dma->dstr[dsti].p = vtophys(cmd->dst_packp[i]);
+ dma->dstr[dsti].p = cmd->dst_packp[i];
dma->dstr[dsti].l = cmd->dst_packl[i] | HIFN_D_VALID |
HIFN_D_MASKDONEIRQ | last;
}
@@ -1085,18 +1139,12 @@ hifn_crypto(struct hifn_command *cmd)
* Unlike other descriptors, we don't mask done interrupt from
* result descriptor.
*/
+#ifdef HIFN_DEBUG
+ printf("load res\n");
+#endif
+ dma->hifn_commands[resi] = cmd;
dma->resr[resi].l = HIFN_MAX_RESULT | HIFN_D_VALID | HIFN_D_LAST;
- dma->resu += 1;
-
- /*
- * We don't worry about missing an interrupt (which a waiting
- * on command interrupt salvages us from), unless there is more
- * than one command in the queue.
- */
- if (dma->slots_in_use > 1) {
- WRITE_REG_1(sc, HIFN_1_DMA_IER,
- HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_WAIT);
- }
+ dma->resu++;
/*
* If not given a callback routine, we block until the dest data is
@@ -1113,9 +1161,11 @@ hifn_crypto(struct hifn_command *cmd)
sc->sc_dv.dv_xname, error);
}
+#ifdef HIFN_DEBUG
printf("%s: command: stat %8x ier %8x\n",
sc->sc_dv.dv_xname,
READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER));
+#endif
splx(s);
return 0; /* success */
@@ -1128,63 +1178,283 @@ hifn_intr(arg)
struct hifn_softc *sc = arg;
struct hifn_dma *dma = sc->sc_dma;
u_int32_t dmacsr;
+ int i, u;
dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
- printf("%s: irq: stat %8x ien %8x u %d/%d/%d/%d\n",
+#ifdef HIFN_DEBUG
+ printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n",
sc->sc_dv.dv_xname,
dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER),
dma->cmdu, dma->srcu, dma->dstu, dma->resu);
+#endif
- if ((dmacsr & (HIFN_DMACSR_C_WAIT|HIFN_DMACSR_R_DONE)) == 0)
+ if ((dmacsr & HIFN_DMACSR_R_DONE) == 0)
return (0);
- if ((dma->slots_in_use == 0) && (dmacsr & HIFN_DMACSR_C_WAIT)) {
- /*
- * If no slots to process and we received a "waiting on
- * result" interrupt, we disable the "waiting on result"
- * (by clearing it).
- */
- WRITE_REG_1(sc, HIFN_1_DMA_IER, HIFN_DMAIER_R_DONE);
- } else {
- if (dma->slots_in_use > HIFN_D_RSIZE)
- printf("%s: Internal Error -- ring overflow\n",
- sc->sc_dv.dv_xname);
-
- while (dma->slots_in_use > 0) {
- u_int32_t wake_pos = dma->wakeup_rpos;
- struct hifn_command *cmd = dma->hifn_commands[wake_pos];
-
- /* if still valid, stop processing */
- if (dma->resr[wake_pos].l & HIFN_D_VALID)
- break;
-
- if (HIFN_USING_MAC(cmd->flags) && (cmd->flags & HIFN_DECODE)) {
- u_int8_t *result_buf = dma->result_bufs[wake_pos];
+ if (dma->resu > HIFN_D_RES_RSIZE)
+ printf("%s: Internal Error -- ring overflow\n",
+ sc->sc_dv.dv_xname);
+
+ while (dma->resu > 0) {
+ struct hifn_command *cmd;
+
+ cmd = dma->hifn_commands[dma->resk];
+
+ /* if still valid, stop processing */
+ if (dma->resr[dma->resk].l & HIFN_D_VALID)
+ break;
+
+ if (HIFN_USING_MAC(cmd->flags) && (cmd->flags & HIFN_DECODE)) {
+ u_int8_t *result_buf = dma->result_bufs[dma->resk];
- cmd->result_flags = (result_buf[8] & 0x2) ?
- HIFN_MAC_BAD : 0;
- printf("%s: byte index 8 of result 0x%02x\n",
- sc->sc_dv.dv_xname, (u_int32_t) result_buf[8]);
- }
+ cmd->result_flags = (result_buf[8] & 0x2) ?
+ HIFN_MAC_BAD : 0;
+ }
- /* position is done, notify producer with wakup or callback */
- if (cmd->dest_ready_callback == NULL)
- wakeup((caddr_t) &dma->resr[wake_pos]);
- else
- cmd->dest_ready_callback(cmd);
+ /* position is done, notify producer with wakup or callback */
+ if (cmd->dest_ready_callback == NULL)
+ wakeup((caddr_t) &dma->resr[dma->resk]);
+ else
+ cmd->dest_ready_callback(cmd);
- if (++dma->wakeup_rpos == HIFN_D_RSIZE)
- dma->wakeup_rpos = 0;
- dma->slots_in_use--;
- }
+ if (++dma->resk == HIFN_D_RES_RSIZE)
+ dma->resk = 0;
+ dma->resu--;
+ }
+
+ /* clear the rings */
+
+ i = dma->srck; u = dma->srcu;
+ while (u != 0 && (dma->srcr[i].l & HIFN_D_VALID) == 0) {
+ if (++i == HIFN_D_SRC_RSIZE)
+ i = 0;
+ u--;
+ }
+ dma->srck = i; dma->srcu = u;
+
+ i = dma->dstk; u = dma->dstu;
+ while (u != 0 && (dma->dstr[i].l & HIFN_D_VALID) == 0) {
+ 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)
+ i = 0;
+ u--;
}
+ dma->cmdk = i; dma->cmdu = u;
/*
* Clear "result done" and "waiting on command ring" flags in status
* register. If we still have slots to process and we received a
* waiting interrupt, this will interupt us again.
*/
- WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_DONE|HIFN_DMACSR_C_WAIT);
+ WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_DONE);
return (1);
}
+
+int
+hifn_newsession(sidp, cri)
+ u_int32_t *sidp;
+ struct cryptoini *cri;
+{
+ struct cryptoini *c;
+ struct hifn_softc *sc;
+ int i, mac = 0, cry = 0;
+
+ if (sidp == NULL || cri == NULL)
+ return (EINVAL);
+
+ for (i = 0; i < hifn_cd.cd_ndevs; i++) {
+ sc = hifn_cd.cd_devs[i];
+ if (sc->sc_cid == (*sidp))
+ break;
+ }
+ if (sc == NULL)
+ return (EINVAL);
+
+ for (c = cri, i = 0; c != NULL; c = c->cri_next) {
+ if (c->cri_alg == CRYPTO_MD5_HMAC96 ||
+ c->cri_alg == CRYPTO_SHA1_HMAC96) {
+ if (mac)
+ return (EINVAL);
+ mac = 1;
+ }
+ else if (c->cri_alg == CRYPTO_DES_CBC ||
+ c->cri_alg == CRYPTO_3DES_CBC) {
+ if (cry)
+ return (EINVAL);
+ cry = 1;
+ }
+ else
+ return (EINVAL);
+ }
+
+ if (mac == 0 && cry == 0)
+ return (EINVAL);
+
+ *sidp = HIFN_SID(sc->sc_dv.dv_unit, 1);
+ return (0);
+}
+
+int
+hifn_freesession(sid)
+ u_int32_t sid;
+{
+ return (0);
+}
+
+int
+hifn_process(crp)
+ struct cryptop *crp;
+{
+ struct hifn_command *cmd = NULL;
+ int card, session;
+ struct hifn_softc *sc;
+ struct cryptodesc *crd;
+
+ if (crp == NULL)
+ goto errout;
+ card = HIFN_CARD(crp->crp_sid);
+ if (card >= hifn_cd.cd_ndevs)
+ goto errout;
+ sc = hifn_cd.cd_devs[card];
+ session = HIFN_SESSION(crp->crp_sid);
+ if (session >= sc->sc_maxses)
+ goto errout;
+
+ cmd = (struct hifn_command *)malloc(sizeof(struct hifn_command),
+ M_DEVBUF, M_NOWAIT);
+ if (cmd == NULL)
+ goto errout;
+ bzero(cmd, sizeof(struct hifn_command));
+
+ cmd->flags = HIFN_DMA_FULL_NOBLOCK;
+
+ if (crp->crp_flags & CRYPTO_F_IMBUF) {
+ cmd->src_m = (struct mbuf *)crp->crp_buf;
+ cmd->dst_m = (struct mbuf *)crp->crp_buf;
+ }
+ else
+ goto errout; /* XXX only handle mbufs right now */
+
+ for (crd = crp->crp_desc; crd != NULL; crd = crd->crd_next) {
+ if (crd->crd_flags & CRD_F_ENCRYPT)
+ cmd->flags |= HIFN_ENCODE;
+ else
+ cmd->flags |= HIFN_DECODE;
+
+ if (crd->crd_alg == CRYPTO_MD5_HMAC96) {
+ /* XXX not right */
+ cmd->flags |= HIFN_MAC_MD5 | HIFN_MAC_TRUNC |
+ HIFN_MAC_NEW_KEY;
+ cmd->mac_header_skip = crd->crd_skip;
+ cmd->mac_process_len = crd->crd_len;
+ cmd->mac = crd->crd_key;
+ cmd->mac_len = crd->crd_klen >> 3;
+ }
+ else if (crd->crd_alg == CRYPTO_SHA1_HMAC96) {
+ /* XXX not right */
+ cmd->flags |= HIFN_MAC_SHA1 | HIFN_MAC_TRUNC |
+ HIFN_MAC_NEW_KEY;
+ cmd->mac_header_skip = crd->crd_skip;
+ cmd->mac_process_len = crd->crd_len;
+ cmd->mac = crd->crd_key;
+ cmd->mac_len = crd->crd_klen >> 3;
+ }
+ else if (crd->crd_alg == CRYPTO_DES_CBC) {
+ if ((crd->crd_flags &
+ (CRD_F_ENCRYPT | CRD_F_IV_PRESENT)) ==
+ CRD_F_ENCRYPT) {
+ get_random_bytes(cmd->iv, HIFN_IV_LENGTH);
+ m_copyback(cmd->src_m, crd->crd_inject,
+ HIFN_IV_LENGTH, cmd->iv);
+ }
+ else
+ m_copydata(cmd->src_m, crd->crd_inject,
+ HIFN_IV_LENGTH, cmd->iv);
+
+ cmd->flags |= HIFN_CRYPT_DES | HIFN_CRYPT_NEW_KEY;
+ cmd->crypt_header_skip = crd->crd_skip;
+ cmd->crypt_process_len = crd->crd_len;
+ cmd->ck = crd->crd_key;
+ cmd->ck_len = crd->crd_klen >> 3;
+ }
+ else if (crd->crd_alg == CRYPTO_3DES_CBC) {
+ if ((crd->crd_flags &
+ (CRD_F_ENCRYPT | CRD_F_IV_PRESENT)) ==
+ CRD_F_IV_PRESENT) {
+ get_random_bytes(cmd->iv, HIFN_IV_LENGTH);
+ m_copyback(cmd->src_m, crd->crd_inject,
+ HIFN_IV_LENGTH, cmd->iv);
+ }
+ else
+ m_copydata(cmd->src_m, crd->crd_inject,
+ HIFN_IV_LENGTH, cmd->iv);
+
+ cmd->flags |= HIFN_CRYPT_3DES | HIFN_CRYPT_NEW_KEY;
+ cmd->crypt_header_skip = crd->crd_skip;
+ cmd->crypt_process_len = crd->crd_len;
+ cmd->ck = crd->crd_key;
+ cmd->ck_len = crd->crd_klen >> 3;
+ }
+ else
+ goto errout;
+ }
+
+ cmd->private_data = (u_long)crp;
+ cmd->dest_ready_callback = hifn_callback;
+
+ if (hifn_crypto(cmd) == 0)
+ return (0);
+
+errout:
+ if (cmd != NULL)
+ free(cmd, M_DEVBUF);
+ return (EINVAL);
+}
+
+void
+hifn_callback(cmd)
+ struct hifn_command *cmd;
+{
+ struct cryptop *crp = (struct cryptop *)cmd->private_data;
+
+ if (HIFN_USING_MAC(cmd->flags) && !HIFN_MAC_OK(cmd->result_flags))
+ crp->crp_etype = EIO;
+ else
+ crp->crp_etype = 0;
+
+ 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;
+ }
+
+ free(cmd, M_DEVBUF);
+ (*crp->crp_callback)(crp);
+}
+
+void
+hifn_timeout(v)
+ void *v;
+{
+ struct hifn_softc *sc = v;
+
+ hifn_print_stats(sc);
+}
+
+void
+hifn_print_stats(sc)
+ struct hifn_softc *sc;
+{
+ printf("timeout: dmacsr %08x\n",
+ READ_REG_1(sc, HIFN_1_DMA_CSR));
+ printf("timeout: %08x, %08x, %08x, %08x\n",
+ READ_REG_1(sc, HIFN_1_DMA_CRAR), READ_REG_1(sc, HIFN_1_DMA_SRAR),
+ READ_REG_1(sc, HIFN_1_DMA_DRAR), READ_REG_1(sc, HIFN_1_DMA_RRAR));
+}
diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h
index b3cd8ab5e50..b6465d01312 100644
--- a/sys/dev/pci/hifn7751reg.h
+++ b/sys/dev/pci/hifn7751reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751reg.h,v 1.8 2000/03/17 20:31:31 jason Exp $ */
+/* $OpenBSD: hifn7751reg.h,v 1.9 2000/03/29 20:54:59 jason Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -40,15 +40,12 @@
* Some PCI configuration space offset defines. The names were made
* identical to the names used by the Linux kernel.
*/
-#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */
-#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */
+#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */
+#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */
/*
* Some configurable values for the driver
*/
-#define HIFN_D_RSIZE 24
-#define HIFN_MAX_DEVICES 4
-
#define HIFN_D_CMD_RSIZE 24
#define HIFN_D_SRC_RSIZE 80
#define HIFN_D_DST_RSIZE 80
@@ -57,9 +54,15 @@
/*
* The values below should multiple of 4 -- and be large enough to handle
* any command the driver implements.
+ *
+ * MAX_COMMAND = base command + mac command + encrypt command +
+ * mac-key des-iv + 3des-key
+ * MAX_RESULT = base result + mac result + mac + encrypt result
+ *
+ *
*/
-#define HIFN_MAX_COMMAND 120
-#define HIFN_MAX_RESULT 16
+#define HIFN_MAX_COMMAND (8 + 8 + 8 + 8 + 64 + 24)
+#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
/*
* hifn_desc_t
@@ -94,15 +97,15 @@ struct hifn_dma {
* Descriptor rings. We add +1 to the size to accomidate the
* jump descriptor.
*/
- struct hifn_desc cmdr[HIFN_D_RSIZE+1];
- struct hifn_desc srcr[HIFN_D_RSIZE+1];
- struct hifn_desc dstr[HIFN_D_RSIZE+1];
- struct hifn_desc resr[HIFN_D_RSIZE+1];
+ struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
+ struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
+ struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
+ struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
- struct hifn_command *hifn_commands[HIFN_D_RSIZE];
+ struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
- u_char command_bufs[HIFN_D_RSIZE][HIFN_MAX_COMMAND];
- u_char result_bufs[HIFN_D_RSIZE][HIFN_MAX_RESULT];
+ u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
+ u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
/*
* Our current positions for insertion and removal from the desriptor
@@ -110,9 +113,7 @@ struct hifn_dma {
*/
int cmdi, srci, dsti, resi;
volatile int cmdu, srcu, dstu, resu;
-
- u_int32_t wakeup_rpos;
- volatile u_int32_t slots_in_use;
+ int cmdk, srck, dstk, resk;
};
/*
@@ -342,46 +343,46 @@ typedef struct hifn_base_command {
u_int16_t total_dest_count;
} hifn_base_command_t;
-#define HIFN_BASE_CMD_MAC (0x1 << 10)
-#define HIFN_BASE_CMD_CRYPT (0x1 << 11)
-#define HIFN_BASE_CMD_DECODE (0x1 << 13)
+#define HIFN_BASE_CMD_MAC (0x1 << 10)
+#define HIFN_BASE_CMD_CRYPT (0x1 << 11)
+#define HIFN_BASE_CMD_DECODE (0x1 << 13)
/*
* Structure to help build up the command data structure.
*/
typedef struct hifn_crypt_command {
- u_int16_t masks;
+ u_int16_t masks;
u_int16_t header_skip;
u_int32_t source_count;
} hifn_crypt_command_t;
-#define HIFN_CRYPT_CMD_ALG_MASK (0x3 << 0)
-#define HIFN_CRYPT_CMD_ALG_DES (0x0 << 0)
-#define HIFN_CRYPT_CMD_ALG_3DES (0x1 << 0)
-#define HIFN_CRYPT_CMD_MODE_CBC (0x1 << 3)
-#define HIFN_CRYPT_CMD_NEW_KEY (0x1 << 11)
-#define HIFN_CRYPT_CMD_NEW_IV (0x1 << 12)
+#define HIFN_CRYPT_CMD_ALG_MASK (0x3 << 0)
+#define HIFN_CRYPT_CMD_ALG_DES (0x0 << 0)
+#define HIFN_CRYPT_CMD_ALG_3DES (0x1 << 0)
+#define HIFN_CRYPT_CMD_MODE_CBC (0x1 << 3)
+#define HIFN_CRYPT_CMD_NEW_KEY (0x1 << 11)
+#define HIFN_CRYPT_CMD_NEW_IV (0x1 << 12)
/*
* Structure to help build up the command data structure.
*/
typedef struct hifn_mac_command {
- u_int16_t masks;
+ u_int16_t masks;
u_int16_t header_skip;
u_int32_t source_count;
} hifn_mac_command_t;
-#define HIFN_MAC_CMD_ALG_MD5 (0x1 << 0)
-#define HIFN_MAC_CMD_ALG_SHA1 (0x0 << 0)
-#define HIFN_MAC_CMD_MODE_HMAC (0x0 << 2)
-#define HIFN_MAC_CMD_TRUNC (0x1 << 4)
-#define HIFN_MAC_CMD_APPEND (0x1 << 6)
+#define HIFN_MAC_CMD_ALG_MD5 (0x1 << 0)
+#define HIFN_MAC_CMD_ALG_SHA1 (0x0 << 0)
+#define HIFN_MAC_CMD_MODE_HMAC (0x0 << 2)
+#define HIFN_MAC_CMD_TRUNC (0x1 << 4)
+#define HIFN_MAC_CMD_APPEND (0x1 << 6)
/*
* MAC POS IPSec initiates authentication after encryption on encodes
* and before decryption on decodes.
*/
-#define HIFN_MAC_CMD_POS_IPSEC (0x2 << 8)
-#define HIFN_MAC_CMD_NEW_KEY (0x1 << 11)
+#define HIFN_MAC_CMD_POS_IPSEC (0x2 << 8)
+#define HIFN_MAC_CMD_NEW_KEY (0x1 << 11)
/*
* Structure with all fields necessary to write the command buffer.
@@ -402,11 +403,11 @@ typedef struct hifn_command_buf_data {
* to set fields in the DMA Configuration Register.
*/
#ifndef HIFN_POLL_FREQUENCY
-#define HIFN_POLL_FREQUENCY 0x1
+#define HIFN_POLL_FREQUENCY 0x1
#endif
#ifndef HIFN_POLL_SCALAR
-#define HIFN_POLL_SCALAR 0x0
+#define HIFN_POLL_SCALAR 0x0
#endif
#endif /* __HIFN_H__ */
diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h
index f50bf7acd11..4b758174348 100644
--- a/sys/dev/pci/hifn7751var.h
+++ b/sys/dev/pci/hifn7751var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751var.h,v 1.6 2000/03/22 15:49:51 jason Exp $ */
+/* $OpenBSD: hifn7751var.h,v 1.7 2000/03/29 20:54:59 jason Exp $ */
/*
* Invertex AEON / Hi/fn 7751 driver
@@ -186,8 +186,8 @@ typedef struct hifn_command {
u_short session_num;
- u_char *iv, *ck, *mac;
- int iv_len, ck_len, mac_len;
+ u_char iv[HIFN_IV_LENGTH], *ck, *mac;
+ int ck_len, mac_len;
struct mbuf *src_m;
long src_packp[MAX_SCATTER];
@@ -201,8 +201,8 @@ typedef struct hifn_command {
int dst_npa;
int dst_l;
- u_short mac_header_skip;
- u_short crypt_header_skip;
+ u_short mac_header_skip, mac_process_len;
+ u_short crypt_header_skip, crypt_process_len;
void (*dest_ready_callback)(struct hifn_command *);
u_long private_data;