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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to