svn commit: r253129 - stable/8/sys/dev/bce

Pyun YongHyeon yongari at FreeBSD.org
Wed Jul 10 01:30:36 UTC 2013


Author: yongari
Date: Wed Jul 10 01:30:35 2013
New Revision: 253129
URL: http://svnweb.freebsd.org/changeset/base/253129

Log:
  MFC r252402:
    Fix triggering false watchdog timeout when controller is in PAUSE
    state.  Previously it used to check if controller has sent a
    PAUSE frame to the remote peer.

Modified:
  stable/8/sys/dev/bce/if_bce.c
  stable/8/sys/dev/bce/if_bcereg.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/dev/   (props changed)
  stable/8/sys/dev/bce/   (props changed)

Modified: stable/8/sys/dev/bce/if_bce.c
==============================================================================
--- stable/8/sys/dev/bce/if_bce.c	Wed Jul 10 01:29:51 2013	(r253128)
+++ stable/8/sys/dev/bce/if_bce.c	Wed Jul 10 01:30:35 2013	(r253129)
@@ -2097,10 +2097,12 @@ bce_miibus_statchg(device_t dev)
 		DBPRINT(sc, BCE_INFO_PHY,
 		    "%s(): Enabling RX flow control.\n", __FUNCTION__);
 		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
+		sc->bce_flags |= BCE_USING_RX_FLOW_CONTROL;
 	} else {
 		DBPRINT(sc, BCE_INFO_PHY,
 		    "%s(): Disabling RX flow control.\n", __FUNCTION__);
 		BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
+		sc->bce_flags &= ~BCE_USING_RX_FLOW_CONTROL;
 	}
 
 	if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
@@ -7889,18 +7891,42 @@ bce_ioctl(struct ifnet *ifp, u_long comm
 static void
 bce_watchdog(struct bce_softc *sc)
 {
+	uint32_t status;
+
 	DBENTER(BCE_EXTREME_SEND);
 
 	BCE_LOCK_ASSERT(sc);
 
+	status = 0;
 	/* If the watchdog timer hasn't expired then just exit. */
 	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
 		goto bce_watchdog_exit;
 
+	status = REG_RD(sc, BCE_EMAC_RX_STATUS);
 	/* If pause frames are active then don't reset the hardware. */
-	/* ToDo: Should we reset the timer here? */
-	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
-		goto bce_watchdog_exit;
+	if ((sc->bce_flags & BCE_USING_RX_FLOW_CONTROL) != 0) {
+		if ((status & BCE_EMAC_RX_STATUS_FFED) != 0) {
+			/*
+			 * If link partner has us in XOFF state then wait for
+			 * the condition to clear.
+			 */
+			sc->watchdog_timer = BCE_TX_TIMEOUT;
+			goto bce_watchdog_exit;
+		} else if ((status & BCE_EMAC_RX_STATUS_FF_RECEIVED) != 0 &&
+			(status & BCE_EMAC_RX_STATUS_N_RECEIVED) != 0) {
+			/*
+			 * If we're not currently XOFF'ed but have recently
+			 * been XOFF'd/XON'd then assume that's delaying TX
+			 * this time around.
+			 */
+			sc->watchdog_timer = BCE_TX_TIMEOUT;
+			goto bce_watchdog_exit;
+		}
+		/*
+		 * Any other condition is unexpected and the controller
+		 * should be reset.
+		 */
+	}
 
 	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
 	    __FILE__, __LINE__);
@@ -7924,6 +7950,7 @@ bce_watchdog(struct bce_softc *sc)
 	sc->bce_ifp->if_oerrors++;
 
 bce_watchdog_exit:
+	REG_WR(sc, BCE_EMAC_RX_STATUS, status);
 	DBEXIT(BCE_EXTREME_SEND);
 }
 

Modified: stable/8/sys/dev/bce/if_bcereg.h
==============================================================================
--- stable/8/sys/dev/bce/if_bcereg.h	Wed Jul 10 01:29:51 2013	(r253128)
+++ stable/8/sys/dev/bce/if_bcereg.h	Wed Jul 10 01:30:35 2013	(r253129)
@@ -6470,6 +6470,7 @@ struct bce_softc
 #define BCE_USING_MSIX_FLAG			0x00000100
 #define BCE_PCIE_FLAG				0x00000200
 #define BCE_USING_TX_FLOW_CONTROL		0x00000400
+#define BCE_USING_RX_FLOW_CONTROL		0x00000800
 
 	/* Controller capability flags. */
 	u32			bce_cap_flags;


More information about the svn-src-all mailing list