Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Sep 1996 11:45:31 +0100 (BST)
From:      Doug Rabson <dfr@render.com>
To:        Guido van Rooij <Guido.vanRooij@nl.cis.philips.com>
Cc:        freebsd-hackers@FreeBSD.org
Subject:   Re: vx device broken in 21.1.5?
Message-ID:  <Pine.BSF.3.95.960906114003.4396F-100000@minnow.render.com>
In-Reply-To: <Pine.BSF.3.95.960906103759.4396E-100000@minnow.render.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 6 Sep 1996, Doug Rabson wrote:

> On Fri, 6 Sep 1996, Guido van Rooij wrote:
> 
> > I am getting a very poor performance with a 3c590 card in FreeBSd 2.1.5.
> > When Ftp-ing I get like 600K/sec put performance, but only 10K/sec 
> > when getting data. Are there some overrun problems?
> 
> There are some problems but I don't know if they are overruns.  I have
> been experimenting with some patches based on examining the OpenBSD driver
> with some confusing but promising results.  I'll try to come up with a
> patch today.

Try this patch.  I pulled in some code from OpenBSD which detects a
particular overrun hang in this card.  This improves the throughput of the
device enourmously.  Oddly, the overrun hang which is code detects has
never happened for me.  Part of the test is to read the VX_W4_FIFO_DIAG
register; if I reduce the patch to simply reading this register and
discarding the result, I get a similar performance improvement.  Since I
have no documentation for the card, I have no idea why this should be the
case.

Index: if_vx.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_vx.c,v
retrieving revision 1.10
diff -u -r1.10 if_vx.c
--- if_vx.c	1996/06/12 05:10:42	1.10
+++ if_vx.c	1996/09/06 10:51:02
@@ -109,6 +109,7 @@
 
 static void vxinit __P((int));
 static void vxintr __P((int));
+static int vxstatus __P((int));
 static void vxread __P((struct vx_softc *));
 static void vxreset __P((int));
 static void vxstart __P((struct ifnet *));
@@ -573,6 +574,16 @@
      * fifo.
      */
 readcheck:
+    if (inw(BASE + VX_W1_RX_STATUS) & ERR_RX_INCOMPLETE) {
+	/* Check if we are stuck and reset [see XXX comment] */
+	if (vxstatus(ifp->if_unit)) {
+		if (ifp->if_flags & IFF_DEBUG)
+			printf("vx%d: adapter reset\n",
+			       ifp->if_unit);
+		vxreset(ifp->if_unit);
+		goto startagain;
+	}
+    }
     if (inw(BASE + VX_W1_RX_STATUS) & RX_BYTES_MASK) {
 	/*
 	 * we check if we have packets left, in that case we prepare to come
@@ -588,6 +599,56 @@
     goto startagain;
 }
 
+/*
+ * XXX: The 3c509 card can get in a mode where both the fifo status bit
+ *	FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
+ *	We detect this situation and we reset the adapter.
+ *	It happens at times when there is a lot of broadcast traffic
+ *	on the cable (once in a blue moon).
+ */
+static int
+vxstatus(unit)
+	int unit;
+{
+	register struct vx_softc *sc = &vx_softc[unit];
+	int fifost;
+
+	/*
+	 * Check the FIFO status and act accordingly
+	 */
+	GO_WINDOW(4);
+	fifost = inw(BASE + VX_W4_FIFO_DIAG);
+	GO_WINDOW(1);
+
+	if (fifost & FIFOS_RX_UNDERRUN) {
+		if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+			printf("vx%d: RX underrun\n", unit);
+		vxreset(unit);
+		return 0;
+	}
+
+	if (fifost & FIFOS_RX_STATUS_OVERRUN) {
+		if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+			printf("vx%d: RX Status overrun\n", unit);
+		return 1;
+	}
+
+	if (fifost & FIFOS_RX_OVERRUN) {
+		if (sc->arpcom..ac_if.if_flags & IFF_DEBUG)
+			printf("vx%d: RX overrun\n", unit);
+		return 1;
+	}
+
+	if (fifost & FIFOS_TX_OVERRUN) {
+		if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+			printf("vx%d: TX overrun\n", unit);
+		vxreset(unit);
+		return 0;
+	}
+
+	return 0;
+}
+
 static void
 vxintr(unit)
     int unit;
@@ -821,6 +882,17 @@
 
     if (status & ERR_RX_INCOMPLETE) {	/* we haven't received the complete
 					 * packet */
+	int unit = sc - &vx_softc[0];
+	if (vxstatus(unit)) {
+		status = inw(BASE + VX_W1_RX_STATUS);
+		/* Check if we are stuck and reset [see XXX comment] */
+		if (status & ERR_RX_INCOMPLETE) {
+			if (sc->arpcom.ac_if.if_flags & IFF_DEBUG)
+				printf("vx%d: adapter reset\n", unit);
+			vxreset(unit);
+			return;
+		}
+	}
 	sc->mcur = m;
 #ifdef VX_LOCAL_STATS
 	sc->rx_no_first++;	/* to know how often we come here */
Index: if_vxreg.h
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_vxreg.h,v
retrieving revision 1.5
diff -u -r1.5 if_vxreg.h
--- if_vxreg.h	1996/08/06 21:14:36	1.5
+++ if_vxreg.h	1996/09/02 13:24:52
@@ -398,6 +398,46 @@
 #define TXS_MAX_COLLISION	0x8
 #define TXS_STATUS_OVERFLOW	0x4
 
+/*
+ * FIFO Status (Window 4)
+ *
+ *   Supports FIFO diagnostics
+ *
+ *   Window 4/Port 0x04.1
+ *
+ *     15:	1=RX receiving (RO). Set when a packet is being received
+ *		into the RX FIFO.
+ *     14:	Reserved
+ *     13:	1=RX underrun (RO). Generates Adapter Failure interrupt.
+ *		Requires RX Reset or Global Reset command to recover.
+ *		It is generated when you read past the end of a packet -
+ *		reading past what has been received so far will give bad
+ *		data.
+ *     12:	1=RX status overrun (RO). Set when there are already 8
+ *		packets in the RX FIFO. While this bit is set, no additional
+ *		packets are received. Requires no action on the part of
+ *		the host. The condition is cleared once a packet has been
+ *		read out of the RX FIFO.
+ *     11:	1=RX overrun (RO). Set when the RX FIFO is full (there
+ *		may not be an overrun packet yet). While this bit is set,
+ *		no additional packets will be received (some additional
+ *		bytes can still be pending between the wire and the RX
+ *		FIFO). Requires no action on the part of the host. The
+ *		condition is cleared once a few bytes have been read out
+ *		from the RX FIFO.
+ *     10:	1=TX overrun (RO). Generates adapter failure interrupt.
+ *		Requires TX Reset or Global Reset command to recover.
+ *		Disables Transmitter.
+ *     9-8:	Unassigned.
+ *     7-0:	Built in self test bits for the RX and TX FIFO's.
+ */
+
+#define	FIFOS_RX_RECEIVING	(u_short) 0x8000
+#define	FIFOS_RX_UNDERRUN	(u_short) 0x2000
+#define	FIFOS_RX_STATUS_OVERRUN	(u_short) 0x1000
+#define	FIFOS_RX_OVERRUN	(u_short) 0x0800
+#define	FIFOS_TX_OVERRUN	(u_short) 0x0400
+
 #define RS_AUI				(1<<5)
 #define RS_BNC				(1<<4)
 #define RS_UTP				(1<<3)


--
Doug Rabson, Microsoft RenderMorphics Ltd.	Mail:  dfr@render.com
						Phone: +44 171 734 3761
						FAX:   +44 171 734 6426




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.960906114003.4396F-100000>