From owner-svn-src-stable@FreeBSD.ORG Sun Mar 27 23:13:02 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 94BE2106566C; Sun, 27 Mar 2011 23:13:02 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 81AD98FC14; Sun, 27 Mar 2011 23:13:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2RND2du072575; Sun, 27 Mar 2011 23:13:02 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2RND2sg072573; Sun, 27 Mar 2011 23:13:02 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201103272313.p2RND2sg072573@svn.freebsd.org> From: Pyun YongHyeon Date: Sun, 27 Mar 2011 23:13:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220078 - stable/8/sys/dev/dc X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Mar 2011 23:13:02 -0000 Author: yongari Date: Sun Mar 27 23:13:02 2011 New Revision: 220078 URL: http://svn.freebsd.org/changeset/base/220078 Log: MFC r219407: Rearrange dc_tx_underrun() a bit to correctly set TX FIFO threshold value. Controllers that always require "store and forward" mode( Davicom and PNIC 82C168) have no way to recover from TX underrun except completely reinitializing hardware. Previously only Davicom was reinitialized and the TX FIFO threshold was changed not to use "store and forward" mode after reinitialization since the default FIFO threshold value was 0. This effectively disabled Davicom controller's "store and forward" mode once it encountered TX underruns. In theory, this can cause watchodg timeouts. Intel 21143 controller requires TX MAC should be idle before changing TX FIFO threshold. So driver tried to disable TX MAC and checked whether it saw the idle state of TX MAC. Driver should perform full hardware reinitialization on failing to enter to idle state and it should not touch TX MAC again once it performed full reinitialization. While I'm here remove resetting TX FIFO threshold to 0 when interface is put into down state. If driver ever encountered TX underrun, it's likely to trigger TX underrun again whenever interface is brought to up again. Keeping old/learned TX FIFO threshold value shall reduce the chance of seeing TX underrns in next run. Modified: stable/8/sys/dev/dc/if_dc.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/dc/if_dc.c ============================================================================== --- stable/8/sys/dev/dc/if_dc.c Sun Mar 27 23:09:09 2011 (r220077) +++ stable/8/sys/dev/dc/if_dc.c Sun Mar 27 23:13:02 2011 (r220078) @@ -3142,50 +3142,57 @@ dc_tick(void *xsc) static void dc_tx_underrun(struct dc_softc *sc) { - uint32_t isr; - int i; + uint32_t netcfg, isr; + int i, reinit; - if (DC_IS_DAVICOM(sc)) { - sc->dc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - dc_init_locked(sc); - } - - if (DC_IS_INTEL(sc)) { - /* - * The real 21143 requires that the transmitter be idle - * in order to change the transmit threshold or store - * and forward state. - */ - DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); - - for (i = 0; i < DC_TIMEOUT; i++) { - isr = CSR_READ_4(sc, DC_ISR); - if (isr & DC_ISR_TX_IDLE) - break; - DELAY(10); - } - if (i == DC_TIMEOUT) { - device_printf(sc->dc_dev, - "%s: failed to force tx to idle state\n", - __func__); - sc->dc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - dc_init_locked(sc); + reinit = 0; + netcfg = CSR_READ_4(sc, DC_NETCFG); + device_printf(sc->dc_dev, "TX underrun -- "); + if ((sc->dc_flags & DC_TX_STORENFWD) == 0) { + if (sc->dc_txthresh + DC_TXTHRESH_INC > DC_TXTHRESH_MAX) { + printf("using store and forward mode\n"); + netcfg |= DC_NETCFG_STORENFWD; + } else { + printf("increasing TX threshold\n"); + sc->dc_txthresh += DC_TXTHRESH_INC; + netcfg &= ~DC_NETCFG_TX_THRESH; + netcfg |= sc->dc_txthresh; + } + + if (DC_IS_INTEL(sc)) { + /* + * The real 21143 requires that the transmitter be idle + * in order to change the transmit threshold or store + * and forward state. + */ + CSR_WRITE_4(sc, DC_NETCFG, netcfg & ~DC_NETCFG_TX_ON); + + for (i = 0; i < DC_TIMEOUT; i++) { + isr = CSR_READ_4(sc, DC_ISR); + if (isr & DC_ISR_TX_IDLE) + break; + DELAY(10); + } + if (i == DC_TIMEOUT) { + device_printf(sc->dc_dev, + "%s: failed to force tx to idle state\n", + __func__); + reinit++; + } } + } else { + printf("resetting\n"); + reinit++; } - device_printf(sc->dc_dev, "TX underrun -- "); - sc->dc_txthresh += DC_TXTHRESH_INC; - if (sc->dc_txthresh > DC_TXTHRESH_MAX) { - printf("using store and forward mode\n"); - DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD); + if (reinit == 0) { + CSR_WRITE_4(sc, DC_NETCFG, netcfg); + if (DC_IS_INTEL(sc)) + CSR_WRITE_4(sc, DC_NETCFG, netcfg | DC_NETCFG_TX_ON); } else { - printf("increasing TX threshold\n"); - DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH); - DC_SETBIT(sc, DC_NETCFG, sc->dc_txthresh); + sc->dc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + dc_init_locked(sc); } - - if (DC_IS_INTEL(sc)) - DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); } #ifdef DEVICE_POLLING @@ -3825,7 +3832,6 @@ dc_ioctl(struct ifnet *ifp, u_long comma if (need_setfilt) dc_setfilt(sc); } else { - sc->dc_txthresh = 0; ifp->if_drv_flags &= ~IFF_DRV_RUNNING; dc_init_locked(sc); }