summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/hifn7751.c42
-rw-r--r--sys/dev/pci/hifn7751reg.h7
-rw-r--r--sys/dev/pci/hifn7751var.h27
3 files changed, 66 insertions, 10 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c
index c5259d93a2e..51387d280f4 100644
--- a/sys/dev/pci/hifn7751.c
+++ b/sys/dev/pci/hifn7751.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751.c,v 1.123 2002/07/16 21:27:39 jason Exp $ */
+/* $OpenBSD: hifn7751.c,v 1.124 2002/07/21 19:08:26 jason Exp $ */
/*
* Invertex AEON / Hifn 7751 driver
@@ -109,6 +109,7 @@ void hifn_rng(void *);
void hifn_tick(void *);
void hifn_abort(struct hifn_softc *);
void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
+void hifn_write_waw_4(struct hifn_softc *, int, bus_size_t, u_int32_t);
struct hifn_stats hifnstats;
@@ -193,6 +194,19 @@ hifn_attach(parent, self, aux)
cmd &= 0xffff0000;
pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT, cmd);
+ if (sc->sc_flags & HIFN_IS_7811) {
+ u_int32_t revid;
+
+ READ_REG_1(sc, HIFN_1_REVID);
+ if (revid == 0x2)
+ sc->sc_flags |= HIFN_NO_BURSTWRITE;
+ }
+
+ if (sc->sc_flags & HIFN_NO_BURSTWRITE) {
+ sc->sc_waw_lastgroup = -1;
+ sc->sc_waw_lastreg = 0xffffffff;
+ }
+
sc->sc_dmat = pa->pa_dmat;
if (bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_dma), 1,
sizeof(*sc->sc_dma), 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) {
@@ -2279,3 +2293,29 @@ hifn_callback(sc, cmd, macbuf)
free(cmd, M_DEVBUF);
crypto_done(crp);
}
+
+void
+hifn_write_waw_4(sc, reggrp, reg, val)
+ struct hifn_softc *sc;
+ int reggrp;
+ bus_size_t reg;
+ u_int32_t val;
+{
+ /*
+ * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
+ * and Group 1 registers; avoid conditions that could create
+ * burst writes by doing a read in between the writes.
+ */
+ if (sc->sc_waw_lastgroup != reggrp)
+ goto chipit;
+ if (sc->sc_waw_lastreg == reg - 4)
+ bus_space_read_4(sc->sc_st1, sc->sc_sh1, HIFN_1_REVID);
+
+chipit:
+ sc->sc_waw_lastgroup = reggrp;
+ sc->sc_waw_lastreg = reg;
+ if (reggrp == 0)
+ bus_space_write_4(sc->sc_st0, sc->sc_sh0, reg, val);
+ else
+ bus_space_write_4(sc->sc_st1, sc->sc_sh1, reg, val);
+}
diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h
index 087062447df..cc515372a73 100644
--- a/sys/dev/pci/hifn7751reg.h
+++ b/sys/dev/pci/hifn7751reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
+/* $OpenBSD: hifn7751reg.h,v 1.36 2002/07/21 19:08:26 jason Exp $ */
/*
* Invertex AEON / Hifn 7751 driver
@@ -352,11 +352,6 @@ typedef struct hifn_desc {
#define HIFN_UNLOCK_SECRET1 0xf4
#define HIFN_UNLOCK_SECRET2 0xfc
-#define WRITE_REG_1(sc,reg,val) \
- bus_space_write_4((sc)->sc_st1, (sc)->sc_sh1, reg, val)
-#define READ_REG_1(sc,reg) \
- bus_space_read_4((sc)->sc_st1, (sc)->sc_sh1, reg)
-
/*********************************************************************
* Structs for board commands
*
diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h
index ec0bcd70bb6..6f672fe4330 100644
--- a/sys/dev/pci/hifn7751var.h
+++ b/sys/dev/pci/hifn7751var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
+/* $OpenBSD: hifn7751var.h,v 1.43 2002/07/21 19:08:26 jason Exp $ */
/*
* Invertex AEON / Hifn 7751 driver
@@ -155,6 +155,7 @@ struct hifn_softc {
#define HIFN_HAS_RNG 1
#define HIFN_HAS_PUBLIC 2
#define HIFN_IS_7811 4
+#define HIFN_NO_BURSTWRITE 8
struct timeout sc_rngto, sc_tickto;
int sc_rngfirst;
int sc_rnghz;
@@ -162,12 +163,32 @@ struct hifn_softc {
struct hifn_session sc_sessions[2048];
pci_chipset_tag_t sc_pci_pc;
pcitag_t sc_pci_tag;
+ bus_size_t sc_waw_lastreg;
+ int sc_waw_lastgroup;
};
-#define WRITE_REG_0(sc,reg,val) \
- bus_space_write_4((sc)->sc_st0, (sc)->sc_sh0, reg, val)
+#define WRITE_REG_0(sc,reg,val) \
+ do { \
+ if (sc->sc_flags & HIFN_NO_BURSTWRITE) \
+ hifn_write_waw_4((sc), 0, (reg), (val)); \
+ else \
+ bus_space_write_4((sc)->sc_st0, (sc)->sc_sh0, \
+ (reg), (val)); \
+ } while (0)
+
+#define WRITE_REG_1(sc,reg,val) \
+ do { \
+ if (sc->sc_flags & HIFN_NO_BURSTWRITE) \
+ hifn_write_waw_4((sc), 1, (reg), (val)); \
+ else \
+ bus_space_write_4((sc)->sc_st1, (sc)->sc_sh1, \
+ (reg), (val)); \
+ } while (0)
+
#define READ_REG_0(sc,reg) \
bus_space_read_4((sc)->sc_st0, (sc)->sc_sh0, reg)
+#define READ_REG_1(sc,reg) \
+ bus_space_read_4((sc)->sc_st1, (sc)->sc_sh1, reg)
/*
* hifn_command_t