svn commit: r258962 - stable/9/sys/dev/bge

Pyun YongHyeon yongari at FreeBSD.org
Thu Dec 5 07:18:33 UTC 2013


Author: yongari
Date: Thu Dec  5 07:18:32 2013
New Revision: 258962
URL: http://svnweb.freebsd.org/changeset/base/258962

Log:
  MFC r253408:
    Implement workaround for BCM5719/BCM5720 TX hang.
    The read DMA request logic operation is based on having sufficient
    available space in the transmit data buffer (TXMBUF) before a read
    DMA can be requested.  There are four read DMA channels that use
    the TXMBUF, and the logic checks if the available free space in the
    TXMBUF is large enough for all the data in the four Send Buffers
    for which buffer descriptors have been fetched.  The Enable_Request
    signal is asserted only if the free TXMBUF space is larger than the
    sum of the four DMA length registers.  The power-up default value
    of BGE_RDMA_LSO_CRPTEN_CTRL register bit 25 (bit 21 on BCM5720) is
    zero, which selects the DMA length registers to connect to the
    input of the adder block.  The DMA length registers are
    asynchronously reset following BCM5719/BCM5720 power-up, and due to
    the lack of synchronous deassertion of the length registers reset
    signal these resisters may contain uninitialized values following
    the reset deassertion.
    In the case of the failure the uninitialized DMA length register
    values added up to more than the TXMBUF size, which prevented the
    assertion of the Enable_Request signal and any subsequent read DMA
    to start.  This lockup condition is the root cause of failing to
    generate any transmit traffic.
  
    To workaround the issue, select alternate output of multiplexers
    and transmit the first four Ethernet frames. This overwrites the
    DMA length registers with valid values.

Modified:
  stable/9/sys/dev/bge/if_bge.c
  stable/9/sys/dev/bge/if_bgereg.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/bge/if_bge.c
==============================================================================
--- stable/9/sys/dev/bge/if_bge.c	Thu Dec  5 07:18:06 2013	(r258961)
+++ stable/9/sys/dev/bge/if_bge.c	Thu Dec  5 07:18:32 2013	(r258962)
@@ -2508,6 +2508,24 @@ bge_blockinit(struct bge_softc *sc)
 	CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
 	DELAY(40);
 
+	if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
+		for (i = 0; i < BGE_NUM_RDMA_CHANNELS / 2; i++) {
+			val = CSR_READ_4(sc, BGE_RDMA_LENGTH + i * 4);
+			if ((val & 0xFFFF) > BGE_FRAMELEN)
+				break;
+			if (((val >> 16) & 0xFFFF) > BGE_FRAMELEN)
+				break;
+		}
+		if (i != BGE_NUM_RDMA_CHANNELS / 2) {
+			val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+				val |= BGE_RDMA_TX_LENGTH_WA_5719;
+			else
+				val |= BGE_RDMA_TX_LENGTH_WA_5720;
+			CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
+		}
+	}
+
 	/* Turn on RX data completion state machine */
 	CSR_WRITE_4(sc, BGE_RDC_MODE, BGE_RDCMODE_ENABLE);
 
@@ -3344,10 +3362,18 @@ bge_attach(device_t dev)
 		sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
 		    BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
 		    BGE_FLAG_JUMBO_FRAME;
-		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
-		    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
-			/* Jumbo frame on BCM5719 A0 does not work. */
-			sc->bge_flags &= ~BGE_FLAG_JUMBO;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5719 ||
+		    sc->bge_asicrev == BGE_ASICREV_BCM5720) {
+			/*
+			 * Enable work around for DMA engine miscalculation
+			 * of TXMBUF available space.
+			 */
+			sc->bge_flags |= BGE_FLAG_RDMA_BUG;
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
+			    sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
+				/* Jumbo frame on BCM5719 A0 does not work. */
+				sc->bge_flags &= ~BGE_FLAG_JUMBO;
+			}
 		}
 		break;
 	case BGE_ASICREV_BCM5755:
@@ -4765,6 +4791,7 @@ bge_stats_update_regs(struct bge_softc *
 {
 	struct ifnet *ifp;
 	struct bge_mac_stats *stats;
+	uint32_t val;
 
 	ifp = sc->bge_ifp;
 	stats = &sc->bge_mac_stats;
@@ -4865,6 +4892,24 @@ bge_stats_update_regs(struct bge_softc *
 	ifp->if_collisions = (u_long)stats->etherStatsCollisions;
 	ifp->if_ierrors = (u_long)(stats->NoMoreRxBDs + stats->InputDiscards +
 	    stats->InputErrors);
+
+	if (sc->bge_flags & BGE_FLAG_RDMA_BUG) {
+		/*
+		 * If controller transmitted more than BGE_NUM_RDMA_CHANNELS
+		 * frames, it's safe to disable workaround for DMA engine's
+		 * miscalculation of TXMBUF space.
+		 */
+		if (stats->ifHCOutUcastPkts + stats->ifHCOutMulticastPkts +
+		    stats->ifHCOutBroadcastPkts > BGE_NUM_RDMA_CHANNELS) {
+			val = CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL);
+			if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
+				val &= ~BGE_RDMA_TX_LENGTH_WA_5719;
+			else
+				val &= ~BGE_RDMA_TX_LENGTH_WA_5720;
+			CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL, val);
+			sc->bge_flags &= ~BGE_FLAG_RDMA_BUG;
+		}
+	}
 }
 
 static void

Modified: stable/9/sys/dev/bge/if_bgereg.h
==============================================================================
--- stable/9/sys/dev/bge/if_bgereg.h	Thu Dec  5 07:18:06 2013	(r258961)
+++ stable/9/sys/dev/bge/if_bgereg.h	Thu Dec  5 07:18:32 2013	(r258962)
@@ -1586,6 +1586,8 @@
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_512	0x00020000
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K	0x00030000
 #define	BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K	0x000C0000
+#define	BGE_RDMA_TX_LENGTH_WA_5719		0x02000000
+#define	BGE_RDMA_TX_LENGTH_WA_5720		0x00200000
 
 /* BD Read DMA Mode register */
 #define	BGE_RDMA_BD_MODE		0x4A00
@@ -1603,6 +1605,9 @@
 #define	BGE_RDMA_NON_LSO_MODE_RESET	0x00000001
 #define	BGE_RDMA_NON_LSO_MODE_ENABLE	0x00000002
 
+#define	BGE_RDMA_LENGTH			0x4BE0
+#define	BGE_NUM_RDMA_CHANNELS		4
+
 /*
  * Write DMA control registers
  */
@@ -2982,6 +2987,7 @@ struct bge_softc {
 #define	BGE_FLAG_SHORT_DMA_BUG	0x08000000
 #define	BGE_FLAG_4K_RDMA_BUG	0x10000000
 #define	BGE_FLAG_MBOX_REORDER	0x20000000
+#define	BGE_FLAG_RDMA_BUG	0x40000000
 	uint32_t		bge_mfw_flags;	/* Management F/W flags */
 #define	BGE_MFW_ON_RXCPU	0x00000001
 #define	BGE_MFW_ON_APE		0x00000002


More information about the svn-src-all mailing list