diff options
author | Pyun YongHyeon <yongari@FreeBSD.org> | 2013-06-30 05:56:13 +0000 |
---|---|---|
committer | Pyun YongHyeon <yongari@FreeBSD.org> | 2013-06-30 05:56:13 +0000 |
commit | b584d2b3f478a75327af49bbfefc533dd3a25dc1 (patch) | |
tree | 794dba01fd8d68474a7c231001be0dbdbe14288a /sys/dev/bge | |
parent | bd3d8bed6cb0e2705ad7ec580021d66b99e5ef05 (diff) | |
download | src-b584d2b3f478a75327af49bbfefc533dd3a25dc1.tar.gz src-b584d2b3f478a75327af49bbfefc533dd3a25dc1.zip |
Fix triggering false watchdog timeout as done in bce(4) when
controller is in PAUSE state.
Notes
Notes:
svn path=/head/; revision=252404
Diffstat (limited to 'sys/dev/bge')
-rw-r--r-- | sys/dev/bge/if_bge.c | 30 | ||||
-rw-r--r-- | sys/dev/bge/if_bgereg.h | 1 |
2 files changed, 30 insertions, 1 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index ff1f0308ce71..306acc6ca131 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 760fc85f9a1b..6f9822e99d22 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; |