Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Oct 2003 09:29:02 -0700 (PDT)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 40099 for review
Message-ID:  <200310211629.h9LGT2BF086334@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=40099

Change 40099 by sam@sam_ebb on 2003/10/21 09:28:45

	terminate the rx descriptor list with a self-linked entry
	so high phy error rates don't cause rx overruns

Affected files ...

.. //depot/projects/netperf/sys/dev/ath/if_ath.c#27 edit

Differences ...

==== //depot/projects/netperf/sys/dev/ath/if_ath.c#27 (text+ko) ====

@@ -1544,9 +1544,23 @@
 	}
 	bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREREAD);
 
-	/* setup descriptors */
+	/*
+	 * Setup descriptors.  For receive we always terminate
+	 * the descriptor list with a self-linked entry so we'll
+	 * not get overrun under high load (as can happen with a
+	 * 5212 when ANI processing enables PHY errors).
+	 *
+	 * To insure the last descriptor is self-linked we create
+	 * each descriptor as self-linked and add it to the end.  As
+	 * each additional descriptor is added the previous self-linked
+	 * entry is ``fixed'' naturally.  This should be safe even
+	 * if DMA is happening.  When processing RX interrupts we
+	 * never remove/process the last, self-linked, entry on the
+	 * descriptor list.  This insures the hardware always has
+	 * someplace to write a new frame.
+	 */
 	ds = bf->bf_desc;
-	ds->ds_link = 0;
+	ds->ds_link = bf->bf_daddr;	/* link to self */
 	ds->ds_data = bf->bf_segs[0].ds_addr;
 	ath_hal_setuprxdesc(ah, ds
 		, m->m_len		/* buffer size */
@@ -1584,12 +1598,16 @@
 			if_printf(ifp, "ath_rx_proc: no buffer!\n");
 			break;
 		}
+		ds = bf->bf_desc;
+		if (ds->ds_link == bf->bf_daddr) {
+			/* NB: never process the self-linked entry at the end */
+			break;
+		}
 		m = bf->bf_m;
 		if (m == NULL) {		/* NB: shouldn't happen */
 			if_printf(ifp, "ath_rx_proc: no mbuf!\n");
 			continue;
 		}
-		ds = bf->bf_desc;
 		status = ath_hal_rxprocdesc(ah, ds);
 #ifdef AR_DEBUG
 		if (ath_debug > 1)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310211629.h9LGT2BF086334>