Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Jun 2011 17:18:33 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r223681 - stable/8/sys/dev/vr
Message-ID:  <201106291718.p5THIXib006892@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Wed Jun 29 17:18:33 2011
New Revision: 223681
URL: http://svn.freebsd.org/changeset/base/223681

Log:
  MFC r223405:
    Remove link state change callback handler.  There is no need to
    register both status change and link state change callbacks.
    Implement checking valid link in state change callback and poll
    active link state in vr_tick().  This allows immediate detection of
    lost link as well as protecting driver from frequent link flips during
    link renegotiation.  taskq implementation was removed because driver
    now needs to poll link state in vr_tick().
    While I'm here do not report current link state if interface is not
    running.
  
    Tested by:	n_hibma

Modified:
  stable/8/sys/dev/vr/if_vr.c
  stable/8/sys/dev/vr/if_vrreg.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/vr/if_vr.c
==============================================================================
--- stable/8/sys/dev/vr/if_vr.c	Wed Jun 29 16:58:27 2011	(r223680)
+++ stable/8/sys/dev/vr/if_vr.c	Wed Jun 29 17:18:33 2011	(r223681)
@@ -185,7 +185,6 @@ static int vr_miibus_readreg(device_t, i
 static int vr_miibus_writereg(device_t, int, int, int);
 static void vr_miibus_statchg(device_t);
 
-static void vr_link_task(void *, int);
 static void vr_cam_mask(struct vr_softc *, uint32_t, int);
 static int vr_cam_data(struct vr_softc *, int, int, uint8_t *);
 static void vr_set_filter(struct vr_softc *);
@@ -226,7 +225,6 @@ static device_method_t vr_methods[] = {
 	DEVMETHOD(miibus_readreg,	vr_miibus_readreg),
 	DEVMETHOD(miibus_writereg,	vr_miibus_writereg),
 	DEVMETHOD(miibus_statchg,	vr_miibus_statchg),
-	DEVMETHOD(miibus_linkchg,	vr_miibus_statchg),
 
 	{ NULL, NULL }
 };
@@ -290,22 +288,13 @@ vr_miibus_writereg(device_t dev, int phy
 	return (0);
 }
 
-static void
-vr_miibus_statchg(device_t dev)
-{
-	struct vr_softc		*sc;
-
-	sc = device_get_softc(dev);
-	taskqueue_enqueue(taskqueue_swi, &sc->vr_link_task);
-}
-
 /*
  * In order to fiddle with the
  * 'full-duplex' and '100Mbps' bits in the netconfig register, we
  * first have to put the transmit and/or receive logic in the idle state.
  */
 static void
-vr_link_task(void *arg, int pending)
+vr_miibus_statchg(device_t dev)
 {
 	struct vr_softc		*sc;
 	struct mii_data		*mii;
@@ -313,22 +302,25 @@ vr_link_task(void *arg, int pending)
 	int			lfdx, mfdx;
 	uint8_t			cr0, cr1, fc;
 
-	sc = (struct vr_softc *)arg;
-
-	VR_LOCK(sc);
+	sc = device_get_softc(dev);
 	mii = device_get_softc(sc->vr_miibus);
 	ifp = sc->vr_ifp;
 	if (mii == NULL || ifp == NULL ||
-	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-		VR_UNLOCK(sc);
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 		return;
-	}
 
-	if (mii->mii_media_status & IFM_ACTIVE) {
-		if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
+	sc->vr_link = 0;
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+		case IFM_100_TX:
 			sc->vr_link = 1;
-	} else
-		sc->vr_link = 0;
+			break;
+		default:
+			break;
+		}
+	}
 
 	if (sc->vr_link != 0) {
 		cr0 = CSR_READ_1(sc, VR_CR0);
@@ -384,11 +376,8 @@ vr_link_task(void *arg, int pending)
 			    "%s: Tx/Rx shutdown error -- resetting\n",
 			    __func__);
 			sc->vr_flags |= VR_F_RESTART;
-			VR_UNLOCK(sc);
-			return;
 		}
 	}
-	VR_UNLOCK(sc);
 }
 
 
@@ -621,7 +610,6 @@ vr_attach(device_t dev)
 	mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
 	callout_init_mtx(&sc->vr_stat_callout, &sc->vr_mtx, 0);
-	TASK_INIT(&sc->vr_link_task, 0, vr_link_task, sc);
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
 	    OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
@@ -841,7 +829,6 @@ vr_detach(device_t dev)
 		vr_stop(sc);
 		VR_UNLOCK(sc);
 		callout_drain(&sc->vr_stat_callout);
-		taskqueue_drain(taskqueue_swi, &sc->vr_link_task);
 		ether_ifdetach(ifp);
 	}
 	if (sc->vr_miibus)
@@ -1559,6 +1546,8 @@ vr_tick(void *xsc)
 
 	mii = device_get_softc(sc->vr_miibus);
 	mii_tick(mii);
+	if (sc->vr_link == 0)
+		vr_miibus_statchg(sc->vr_dev);
 	vr_watchdog(sc);
 	callout_reset(&sc->vr_stat_callout, hz, vr_tick, sc);
 }
@@ -2163,6 +2152,10 @@ vr_ifmedia_sts(struct ifnet *ifp, struct
 	sc = ifp->if_softc;
 	mii = device_get_softc(sc->vr_miibus);
 	VR_LOCK(sc);
+	if ((ifp->if_flags & IFF_UP) == 0) {
+		VR_UNLOCK(sc);
+		return;
+	}
 	mii_pollstat(mii);
 	VR_UNLOCK(sc);
 	ifmr->ifm_active = mii->mii_media_active;

Modified: stable/8/sys/dev/vr/if_vrreg.h
==============================================================================
--- stable/8/sys/dev/vr/if_vrreg.h	Wed Jun 29 16:58:27 2011	(r223680)
+++ stable/8/sys/dev/vr/if_vrreg.h	Wed Jun 29 17:18:33 2011	(r223681)
@@ -723,7 +723,6 @@ struct vr_softc {
 	uint8_t			vr_flags;	/* See VR_F_* below */
 #define	VR_F_RESTART		0x01		/* Restart unit on next tick */
 	int			vr_if_flags;
-	struct task		vr_link_task;
 	struct vr_chain_data	vr_cdata;
 	struct vr_ring_data	vr_rdata;
 	struct vr_statistics	vr_stat;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106291718.p5THIXib006892>