From b584d2b3f478a75327af49bbfefc533dd3a25dc1 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sun, 30 Jun 2013 05:56:13 +0000 Subject: [PATCH] Fix triggering false watchdog timeout as done in bce(4) when controller is in PAUSE state. --- sys/dev/bge/if_bge.c | 30 +++++++++++++++++++++++++++++- sys/dev/bge/if_bgereg.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index ff1f0308ce7..306acc6ca13 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -5271,7 +5271,7 @@ bge_start_locked(struct ifnet *ifp) /* * Set a timeout in case the chip goes out to lunch. */ - sc->bge_timer = 5; + sc->bge_timer = BGE_TX_TIMEOUT; } } @@ -5776,12 +5776,40 @@ static void bge_watchdog(struct bge_softc *sc) { struct ifnet *ifp; + uint32_t status; BGE_LOCK_ASSERT(sc); if (sc->bge_timer == 0 || --sc->bge_timer) return; + /* If pause frames are active then don't reset the hardware. */ + if ((CSR_READ_4(sc, BGE_RX_MODE) & BGE_RXMODE_FLOWCTL_ENABLE) != 0) { + status = CSR_READ_4(sc, BGE_RX_STS); + if ((status & BGE_RXSTAT_REMOTE_XOFFED) != 0) { + /* + * If link partner has us in XOFF state then wait for + * the condition to clear. + */ + CSR_WRITE_4(sc, BGE_RX_STS, status); + sc->bge_timer = BGE_TX_TIMEOUT; + return; + } else if ((status & BGE_RXSTAT_RCVD_XOFF) != 0 && + (status & BGE_RXSTAT_RCVD_XON) != 0) { + /* + * If link partner has us in XOFF state then wait for + * the condition to clear. + */ + CSR_WRITE_4(sc, BGE_RX_STS, status); + sc->bge_timer = BGE_TX_TIMEOUT; + return; + } + /* + * Any other condition is unexpected and the controller + * should be reset. + */ + } + ifp = sc->bge_ifp; if_printf(ifp, "watchdog timeout -- resetting\n"); diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index 760fc85f9a1..6f9822e99d2 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -2918,6 +2918,7 @@ struct bge_dmamap_arg { #define BGE_HWREV_TIGON_II 0x02 #define BGE_TIMEOUT 100000 #define BGE_TXCONS_UNSET 0xFFFF /* impossible value */ +#define BGE_TX_TIMEOUT 5 struct bge_bcom_hack { int reg;