svn commit: r225595 - stable/7/sys/dev/vge
Pyun YongHyeon
yongari at FreeBSD.org
Thu Sep 15 17:22:39 UTC 2011
Author: yongari
Date: Thu Sep 15 17:22:38 2011
New Revision: 225595
URL: http://svn.freebsd.org/changeset/base/225595
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/7/sys/dev/vge/if_vge.c
stable/7/sys/dev/vge/if_vgereg.h
Directory Properties:
stable/7/sys/ (props changed)
stable/7/sys/cddl/contrib/opensolaris/ (props changed)
stable/7/sys/contrib/dev/acpica/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
Modified: stable/7/sys/dev/vge/if_vge.c
==============================================================================
--- stable/7/sys/dev/vge/if_vge.c Thu Sep 15 17:20:20 2011 (r225594)
+++ stable/7/sys/dev/vge/if_vge.c Thu Sep 15 17:22:38 2011 (r225595)
@@ -1753,6 +1753,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;
}
@@ -2110,11 +2114,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
{
@@ -2122,9 +2125,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);
@@ -2281,8 +2284,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/7/sys/dev/vge/if_vgereg.h
==============================================================================
--- stable/7/sys/dev/vge/if_vgereg.h Thu Sep 15 17:20:20 2011 (r225594)
+++ stable/7/sys/dev/vge/if_vgereg.h Thu Sep 15 17:22:38 2011 (r225595)
@@ -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 */
More information about the svn-src-all
mailing list