summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/socppc/dev/if_tsec.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/sys/arch/socppc/dev/if_tsec.c b/sys/arch/socppc/dev/if_tsec.c
index fc8367164f7..cd5ccd1a4da 100644
--- a/sys/arch/socppc/dev/if_tsec.c
+++ b/sys/arch/socppc/dev/if_tsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tsec.c,v 1.18 2009/01/30 10:44:56 kettenis Exp $ */
+/* $OpenBSD: if_tsec.c,v 1.19 2009/01/30 12:47:15 kettenis Exp $ */
/*
* Copyright (c) 2008 Mark Kettenis
@@ -60,12 +60,23 @@ extern void myetheraddr(u_char *);
#define TSEC_IEVENT 0x010
#define TSEC_IEVENT_BABR 0x80000000
+#define TSEC_IEVENT_RXC 0x40000000
+#define TSEC_IEVENT_BSY 0x20000000
+#define TSEC_IEVENT_EBERR 0x10000000
+#define TSEC_IEVENT_MSRO 0x04000000
#define TSEC_IEVENT_GTSC 0x02000000
+#define TSEC_IEVENT_BABT 0x01000000
#define TSEC_IEVENT_TXC 0x00800000
#define TSEC_IEVENT_TXE 0x00400000
#define TSEC_IEVENT_TXB 0x00200000
#define TSEC_IEVENT_TXF 0x00100000
+#define TSEC_IEVENT_LC 0x00040000
+#define TSEC_IEVENT_CRL 0x00020000
+#define TSEC_IEVENT_DXA TSEC_IEVENT_CRL
+#define TSEC_IEVENT_XFUN 0x00010000
#define TSEC_IEVENT_RXB 0x00008000
+#define TSEC_IEVENT_MMRD 0x00000400
+#define TSEC_IEVENT_MMWR 0x00000200
#define TSEC_IEVENT_GRSC 0x00000100
#define TSEC_IEVENT_RXF 0x00000080
#define TSEC_IEVENT_FMT "\020" "\040BABR" "\037RXC" "\036BSY" \
@@ -626,6 +637,9 @@ tsec_txintr(void *arg)
uint32_t ievent;
ievent = tsec_read(sc, TSEC_IEVENT);
+ if ((ievent & (TSEC_IEVENT_TXC | TSEC_IEVENT_TXE |
+ TSEC_IEVENT_TXB | TSEC_IEVENT_TXF)) == 0)
+ printf("%s: tx %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT);
ievent &= (TSEC_IEVENT_TXC | TSEC_IEVENT_TXE |
TSEC_IEVENT_TXB | TSEC_IEVENT_TXF);
tsec_write(sc, TSEC_IEVENT, ievent);
@@ -642,6 +656,8 @@ tsec_rxintr(void *arg)
uint32_t ievent;
ievent = tsec_read(sc, TSEC_IEVENT);
+ if ((ievent & (TSEC_IEVENT_RXB | TSEC_IEVENT_RXF)) == 0)
+ printf("%s: rx %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT);
ievent &= (TSEC_IEVENT_RXB | TSEC_IEVENT_RXF);
tsec_write(sc, TSEC_IEVENT, ievent);
@@ -654,11 +670,25 @@ int
tsec_errintr(void *arg)
{
struct tsec_softc *sc = arg;
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
uint32_t ievent;
ievent = tsec_read(sc, TSEC_IEVENT);
+ if ((ievent & TSEC_IEVENT_BSY) == 0)
+ printf("%s: err %b\n", DEVNAME(sc), ievent, TSEC_IEVENT_FMT);
+ ievent &= TSEC_IEVENT_BSY;
tsec_write(sc, TSEC_IEVENT, ievent);
- printf("%s: %b\n", __func__, ievent, TSEC_IEVENT_FMT);
+
+ if (ievent & TSEC_IEVENT_BSY) {
+ /*
+ * We ran out of buffers and dropped one (or more)
+ * packets. We must clear RSTAT[QHLT] after
+ * processing the ring to get things started again.
+ */
+ tsec_rx_proc(sc);
+ tsec_write(sc, TSEC_RSTAT, TSEC_RSTAT_QHLT);
+ ifp->if_ierrors++;
+ }
return (1);
}
@@ -903,7 +933,7 @@ tsec_up(struct tsec_softc *sc)
tsec_write(sc, TSEC_IMASK, TSEC_IMASK_TXEEN |
TSEC_IMASK_TXBEN | TSEC_IMASK_TXFEN |
- TSEC_IMASK_RXBEN | TSEC_IMASK_RXFEN);
+ TSEC_IMASK_RXBEN | TSEC_IMASK_RXFEN | TSEC_IMASK_BSYEN);
timeout_add_sec(&sc->sc_tick, 1);
}