Author: yongari
Date: Wed Jul 10 01:29:51 2013
New Revision: 253128
URL: http://svnweb.freebsd.org/changeset/base/253128

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/9/sys/dev/bce/if_bce.c
  stable/9/sys/dev/bce/if_bcereg.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/bce/if_bce.c
==============================================================================
--- stable/9/sys/dev/bce/if_bce.c       Wed Jul 10 01:27:05 2013        
(r253127)
+++ stable/9/sys/dev/bce/if_bce.c       Wed Jul 10 01:29:51 2013        
(r253128)
@@ -2077,10 +2077,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) {
@@ -7828,18 +7830,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__);
@@ -7863,6 +7889,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/9/sys/dev/bce/if_bcereg.h
==============================================================================
--- stable/9/sys/dev/bce/if_bcereg.h    Wed Jul 10 01:27:05 2013        
(r253127)
+++ stable/9/sys/dev/bce/if_bcereg.h    Wed Jul 10 01:29:51 2013        
(r253128)
@@ -6466,6 +6466,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;
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to