Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Apr 2011 06:33:35 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220356 - head/sys/mips/atheros
Message-ID:  <201104050633.p356XZSY008050@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Apr  5 06:33:35 2011
New Revision: 220356
URL: http://svn.freebsd.org/changeset/base/220356

Log:
  * Add some more debugging to if_arge
  * Make doubly sure that IFF_DRV_OACTIVE is set if the hardware TX queue is full

Modified:
  head/sys/mips/atheros/if_arge.c
  head/sys/mips/atheros/if_argevar.h

Modified: head/sys/mips/atheros/if_arge.c
==============================================================================
--- head/sys/mips/atheros/if_arge.c	Tue Apr  5 05:29:10 2011	(r220355)
+++ head/sys/mips/atheros/if_arge.c	Tue Apr  5 06:33:35 2011	(r220356)
@@ -84,7 +84,11 @@ MODULE_DEPEND(arge, miibus, 1, 1, 1);
 
 typedef enum {
 	ARGE_DBG_MII 	=	0x00000001,
-	ARGE_DBG_INTR	=	0x00000002
+	ARGE_DBG_INTR	=	0x00000002,
+	ARGE_DBG_TX	=	0x00000004,
+	ARGE_DBG_RX	=	0x00000008,
+	ARGE_DBG_ERR	=	0x00000010,
+	ARGE_DBG_RESET	=	0x00000020,
 } arge_debug_flags;
 
 #ifdef ARGE_DEBUG
@@ -985,6 +989,7 @@ arge_encap(struct arge_softc *sc, struct
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	/* Start transmitting */
+	ARGEDEBUG(sc, ARGE_DBG_TX, "%s: setting DMA_TX_CONTROL_EN\n", __func__);
 	ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, DMA_TX_CONTROL_EN);
 	return (0);
 }
@@ -1006,16 +1011,32 @@ arge_start_locked(struct ifnet *ifp)
 {
 	struct arge_softc	*sc;
 	struct mbuf		*m_head;
-	int			enq;
+	int			enq = 0;
 
 	sc = ifp->if_softc;
 
 	ARGE_LOCK_ASSERT(sc);
 
+	ARGEDEBUG(sc, ARGE_DBG_TX, "%s: beginning\n", __func__);
+
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
 	    IFF_DRV_RUNNING || sc->arge_link_status == 0 )
 		return;
 
+	/*
+	 * Before we go any further, check whether we're already full.
+	 * The below check errors out immediately if the ring is full
+	 * and never gets a chance to set this flag. Although it's
+	 * likely never needed, this at least avoids an unexpected
+	 * situation.
+	 */
+	if (sc->arge_cdata.arge_tx_cnt >= ARGE_TX_RING_COUNT - 2) {
+		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+		ARGEDEBUG(sc, ARGE_DBG_ERR, "%s: tx_cnt %d >= max %d; setting IFF_DRV_OACTIVE\n",
+		    __func__, sc->arge_cdata.arge_tx_cnt, ARGE_TX_RING_COUNT - 2);
+		return;
+	}
+
 	arge_flush_ddr(sc);
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
@@ -1043,6 +1064,7 @@ arge_start_locked(struct ifnet *ifp)
 		 */
 		ETHER_BPF_MTAP(ifp, m_head);
 	}
+	ARGEDEBUG(sc, ARGE_DBG_TX, "%s: finished; queued %d packets\n", __func__, enq);
 }
 
 static void
@@ -1621,6 +1643,9 @@ arge_tx_locked(struct arge_softc *sc)
 
 	cons = sc->arge_cdata.arge_tx_cons;
 	prod = sc->arge_cdata.arge_tx_prod;
+
+	ARGEDEBUG(sc, ARGE_DBG_TX, "%s: cons=%d, prod=%d\n", __func__, cons, prod);
+
 	if (cons == prod)
 		return;
 
@@ -1771,6 +1796,7 @@ arge_intr(void *arg)
 {
 	struct arge_softc	*sc = arg;
 	uint32_t		status;
+	struct ifnet		*ifp = sc->arge_ifp;
 
 	status = ARGE_READ(sc, AR71XX_DMA_INTR_STATUS);
 	status |= sc->arge_intr_status;
@@ -1809,6 +1835,7 @@ arge_intr(void *arg)
 	if ( status & DMA_INTR_RX_OVERFLOW) {
 		ARGE_WRITE(sc, AR71XX_DMA_RX_STATUS, DMA_RX_STATUS_OVERFLOW);
 		ARGE_WRITE(sc, AR71XX_DMA_RX_CONTROL, DMA_RX_CONTROL_EN);
+		sc->stats.rx_overflow++;
 	}
 
 	if (status & DMA_INTR_TX_PKT_SENT)
@@ -1819,6 +1846,8 @@ arge_intr(void *arg)
 	 */
 	if (status & DMA_INTR_TX_UNDERRUN) {
 		ARGE_WRITE(sc, AR71XX_DMA_TX_STATUS, DMA_TX_STATUS_UNDERRUN);
+		sc->stats.tx_underflow++;
+		ARGEDEBUG(sc, ARGE_DBG_TX, "%s: TX underrun; tx_cnt=%d\n", __func__, sc->arge_cdata.arge_tx_cnt);
 		if (sc->arge_cdata.arge_tx_cnt > 0 ) {
 			ARGE_WRITE(sc, AR71XX_DMA_TX_CONTROL, 
 			    DMA_TX_CONTROL_EN);

Modified: head/sys/mips/atheros/if_argevar.h
==============================================================================
--- head/sys/mips/atheros/if_argevar.h	Tue Apr  5 05:29:10 2011	(r220355)
+++ head/sys/mips/atheros/if_argevar.h	Tue Apr  5 06:33:35 2011	(r220356)
@@ -154,6 +154,8 @@ struct arge_softc {
 	struct {
 		uint32_t	tx_pkts_unaligned;
 		uint32_t	tx_pkts_aligned;
+		uint32_t	rx_overflow;
+		uint32_t	tx_underflow;
 	} stats;
 };
 



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