svn commit: r251600 - head/sys/dev/fxp

Pyun YongHyeon yongari at FreeBSD.org
Mon Jun 10 07:31:50 UTC 2013


Author: yongari
Date: Mon Jun 10 07:31:49 2013
New Revision: 251600
URL: http://svnweb.freebsd.org/changeset/base/251600

Log:
  Avoid unnecessary controller reinitialization by checking driver
  running state.  fxp(4) requires controller reinitialization for the
  following cases.
   o RX lockup condition on i82557
   o promiscuous mode change
   o multicast filter change
   o WOL configuration
   o TSO/VLAN hardware tagging/checksum offloading configuration
   o MAC reprogramming after speed/duplex/flow-control resolution
   o Any events that result in MAC reprogramming(link UP/DOWN,
     remote link partner's restart of auto-negotiation etc)
   o Microcode loading/unloading
  Apart from above cases which come from hardware limitation, upper
  stack also blindly reinitializes controller whenever an IP address
  is assigned. After r194573, fxp(4) no longer needs to reinitialize
  the controller to program multicast filter after upping the
  interface. So keeping track of driver running state should remove
  all unnecessary controller reinitializations.
  
  This change will also address endless controller reinitialization
  triggered by dhclient(8).
  
  Tested by:	hrs, Alban Hertroys <haramrae at gmail.com>

Modified:
  head/sys/dev/fxp/if_fxp.c

Modified: head/sys/dev/fxp/if_fxp.c
==============================================================================
--- head/sys/dev/fxp/if_fxp.c	Mon Jun 10 06:04:58 2013	(r251599)
+++ head/sys/dev/fxp/if_fxp.c	Mon Jun 10 07:31:49 2013	(r251600)
@@ -1075,7 +1075,8 @@ fxp_suspend(device_t dev)
 			pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
 			sc->flags |= FXP_FLAG_WOL;
 			/* Reconfigure hardware to accept magic frames. */
-			fxp_init_body(sc, 1);
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			fxp_init_body(sc, 0);
 		}
 		pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
 	}
@@ -2141,8 +2142,10 @@ fxp_tick(void *xsc)
 	 */
 	if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
 		sc->rx_idle_secs = 0;
-		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			fxp_init_body(sc, 1);
+		}
 		return;
 	}
 	/*
@@ -2240,6 +2243,7 @@ fxp_watchdog(struct fxp_softc *sc)
 	device_printf(sc->dev, "device timeout\n");
 	sc->ifp->if_oerrors++;
 
+	sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	fxp_init_body(sc, 1);
 }
 
@@ -2274,6 +2278,10 @@ fxp_init_body(struct fxp_softc *sc, int 
 	int i, prm;
 
 	FXP_LOCK_ASSERT(sc, MA_OWNED);
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
 	/*
 	 * Cancel any pending I/O
 	 */
@@ -2813,6 +2821,7 @@ fxp_miibus_statchg(device_t dev)
 	 */
 	if (sc->revision == FXP_REV_82557)
 		return;
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	fxp_init_body(sc, 0);
 }
 
@@ -2836,9 +2845,10 @@ fxp_ioctl(struct ifnet *ifp, u_long comm
 		if (ifp->if_flags & IFF_UP) {
 			if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) &&
 			    ((ifp->if_flags ^ sc->if_flags) &
-			    (IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0)
+			    (IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0) {
+				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 				fxp_init_body(sc, 0);
-			else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+			} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
 				fxp_init_body(sc, 1);
 		} else {
 			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
@@ -2851,8 +2861,10 @@ fxp_ioctl(struct ifnet *ifp, u_long comm
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		FXP_LOCK(sc);
-		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			fxp_init_body(sc, 0);
+		}
 		FXP_UNLOCK(sc);
 		break;
 
@@ -2942,8 +2954,10 @@ fxp_ioctl(struct ifnet *ifp, u_long comm
 				    ~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
 			reinit++;
 		}
-		if (reinit > 0 && ifp->if_flags & IFF_UP)
+		if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			fxp_init_body(sc, 0);
+		}
 		FXP_UNLOCK(sc);
 		VLAN_CAPABILITIES(ifp);
 		break;


More information about the svn-src-all mailing list