From owner-svn-src-stable@FreeBSD.ORG Thu Sep 15 17:20:20 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 B42A01065675; Thu, 15 Sep 2011 17:20:20 +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 A1EE18FC17; Thu, 15 Sep 2011 17:20:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8FHKKZn082886; Thu, 15 Sep 2011 17:20:20 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8FHKK7D082883; Thu, 15 Sep 2011 17:20:20 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201109151720.p8FHKK7D082883@svn.freebsd.org> From: Pyun YongHyeon Date: Thu, 15 Sep 2011 17:20:20 +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: r225594 - stable/8/sys/dev/vge 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: Thu, 15 Sep 2011 17:20:20 -0000 Author: yongari Date: Thu Sep 15 17:20:20 2011 New Revision: 225594 URL: http://svn.freebsd.org/changeset/base/225594 Log: MFC r225440: vge(4) hardwares poll media status and generates an interrupt whenever the link state is changed. Using software based polling for media status tracking is known to cause MII access failure under certain conditions once link is established so vge(4) used to rely on link status change interrupt. However DEVICE_POLLING completely disables generation of all kind of interrupts on vge(4) such that this resulted in not detecting link state change event. This means vge(4) does not correctly detect established/lost link with DEVICE_POLLING. Losing the interrupt made vge(4) not to send any packets to peer since vge(4) does not try to send any packets when there is no established link. Work around the issue by generating link state change interrupt with DEVICE_POLLING. PR: kern/160442 Modified: stable/8/sys/dev/vge/if_vge.c stable/8/sys/dev/vge/if_vgereg.h 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/vge/if_vge.c ============================================================================== --- stable/8/sys/dev/vge/if_vge.c Thu Sep 15 17:11:03 2011 (r225593) +++ stable/8/sys/dev/vge/if_vge.c Thu Sep 15 17:20:20 2011 (r225594) @@ -1752,6 +1752,10 @@ vge_intr(void *arg) #ifdef DEVICE_POLLING if (ifp->if_capenable & IFCAP_POLLING) { + status = CSR_READ_4(sc, VGE_ISR); + CSR_WRITE_4(sc, VGE_ISR, status); + if (status != 0xFFFFFFFF && (status & VGE_ISR_LINKSTS) != 0) + vge_link_statchg(sc); VGE_UNLOCK(sc); return; } @@ -2109,11 +2113,10 @@ vge_init_locked(struct vge_softc *sc) #ifdef DEVICE_POLLING /* - * Disable interrupts if we are polling. + * Disable interrupts except link state change if we are polling. */ if (ifp->if_capenable & IFCAP_POLLING) { - CSR_WRITE_4(sc, VGE_IMR, 0); - CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK); + CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS_POLLING); } else /* otherwise ... */ #endif { @@ -2121,9 +2124,9 @@ vge_init_locked(struct vge_softc *sc) * Enable interrupts. */ CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS); - CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF); - CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); } + CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF); + CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); sc->vge_flags &= ~VGE_FLAG_LINK; mii_mediachg(mii); @@ -2280,8 +2283,9 @@ vge_ioctl(struct ifnet *ifp, u_long comm return (error); VGE_LOCK(sc); /* Disable interrupts */ - CSR_WRITE_4(sc, VGE_IMR, 0); - CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK); + CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS_POLLING); + CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF); + CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); ifp->if_capenable |= IFCAP_POLLING; VGE_UNLOCK(sc); } else { Modified: stable/8/sys/dev/vge/if_vgereg.h ============================================================================== --- stable/8/sys/dev/vge/if_vgereg.h Thu Sep 15 17:11:03 2011 (r225593) +++ stable/8/sys/dev/vge/if_vgereg.h Thu Sep 15 17:20:20 2011 (r225594) @@ -302,6 +302,8 @@ VGE_ISR_LINKSTS|VGE_ISR_RXNODESC| \ VGE_ISR_RXDMA_STALL|VGE_ISR_TXDMA_STALL) +#define VGE_INTRS_POLLING (VGE_ISR_PHYINT|VGE_ISR_LINKSTS) + /* Interrupt mask register */ #define VGE_IMR_RXOK_HIPRIO 0x00000001 /* hi prio RX int */