svn commit: r199762 - head/sys/mips/adm5120

John Baldwin jhb at FreeBSD.org
Tue Nov 24 18:34:48 UTC 2009


Author: jhb
Date: Tue Nov 24 18:34:47 2009
New Revision: 199762
URL: http://svn.freebsd.org/changeset/base/199762

Log:
  Use a single private timer to drive the transmit watchdog rather than using
  if_watchdog and if_timer from the first port.
  
  Reviewed by:	gonzo

Modified:
  head/sys/mips/adm5120/if_admsw.c
  head/sys/mips/adm5120/if_admswvar.h

Modified: head/sys/mips/adm5120/if_admsw.c
==============================================================================
--- head/sys/mips/adm5120/if_admsw.c	Tue Nov 24 17:46:58 2009	(r199761)
+++ head/sys/mips/adm5120/if_admsw.c	Tue Nov 24 18:34:47 2009	(r199762)
@@ -128,7 +128,7 @@ static uint8_t vlan_matrix[SW_DEVS] = {
 
 /* ifnet entry points */
 static void	admsw_start(struct ifnet *);
-static void	admsw_watchdog(struct ifnet *);
+static void	admsw_watchdog(void *);
 static int	admsw_ioctl(struct ifnet *, u_long, caddr_t);
 static void	admsw_init(void *);
 static void	admsw_stop(struct ifnet *, int);
@@ -398,6 +398,7 @@ admsw_attach(device_t dev)
 
 	device_printf(sc->sc_dev, "base Ethernet address %s\n",
 	    ether_sprintf(enaddr));
+	callout_init(&sc->sc_watchdog, 1);
 
 	rid = 0;
 	if ((sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
@@ -536,8 +537,6 @@ admsw_attach(device_t dev)
 		ifp->if_ioctl = admsw_ioctl;
 		ifp->if_output = ether_output;
 		ifp->if_start = admsw_start;
-		ifp->if_watchdog = admsw_watchdog;
-		ifp->if_timer = 0;
 		ifp->if_init = admsw_init;
 		ifp->if_mtu = ETHERMTU;
 		ifp->if_baudrate = IF_Mbps(100);
@@ -733,7 +732,7 @@ admsw_start(struct ifnet *ifp)
 		BPF_MTAP(ifp, m0);
 
 		/* Set a watchdog timer in case the chip flakes out. */
-		sc->sc_ifnet[0]->if_timer = 5;
+		sc->sc_timer = 5;
 	}
 }
 
@@ -743,25 +742,29 @@ admsw_start(struct ifnet *ifp)
  *	Watchdog timer handler.
  */
 static void
-admsw_watchdog(struct ifnet *ifp)
+admsw_watchdog(void *arg)
 {
-	struct admsw_softc *sc = ifp->if_softc;
+	struct admsw_softc *sc = arg;
 	int vlan;
 
+	callout_reset(&sc->watchdog, hz, admsw_watchdog, sc);
+	if (sc->sc_timer == 0 || --sc->timer > 0)
+		return;
+
 	/* Check if an interrupt was lost. */
 	if (sc->sc_txfree == ADMSW_NTXLDESC) {
 		device_printf(sc->sc_dev, "watchdog false alarm\n");
 		return;
 	}
-	if (sc->sc_ifnet[0]->if_timer != 0)
+	if (sc->sc_timer != 0)
 		device_printf(sc->sc_dev, "watchdog timer is %d!\n",  
-		    sc->sc_ifnet[0]->if_timer);
+		    sc->sc_timer);
 	admsw_txintr(sc, 0);
 	if (sc->sc_txfree == ADMSW_NTXLDESC) {
 		device_printf(sc->sc_dev, "tx IRQ lost (queue empty)\n");
 		return;
 	}
-	if (sc->sc_ifnet[0]->if_timer != 0) {
+	if (sc->sc_timer != 0) {
 		device_printf(sc->sc_dev, "tx IRQ lost (timer recharged)\n");
 		return;
 	}
@@ -938,7 +941,7 @@ admsw_txintr(struct admsw_softc *sc, int
 		 * cancel the watchdog timer.
 		 */
 		if (sc->sc_txfree == ADMSW_NTXLDESC)
-			ifp->if_timer = 0;
+			sc->sc_timer = 0;
 
 	}
 
@@ -1096,6 +1099,9 @@ admsw_init(void *xsc)
 				    ~(ADMSW_INTR_SHD | ADMSW_INTR_SLD | 
 					ADMSW_INTR_RHD | ADMSW_INTR_RLD | 
 					ADMSW_INTR_HDF | ADMSW_INTR_LDF));
+
+				callout_reset(&sc->sc_watchdog, hz,
+				    admsw_watchdog, sc);
 			}
 			sc->ndevs++;
 		}
@@ -1137,11 +1143,14 @@ admsw_stop(struct ifnet *ifp, int disabl
 
 		/* disable interrupts */
 		REG_WRITE(ADMSW_INT_MASK, INT_MASK);
+
+		/* Cancel the watchdog timer. */
+		sc->sc_timer = 0;
+		callout_stop(&sc->sc_watchdog);
 	}
 
-	/* Mark the interface as down and cancel the watchdog timer. */
+	/* Mark the interface as down. */
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-	ifp->if_timer = 0;
 
 	return;
 }

Modified: head/sys/mips/adm5120/if_admswvar.h
==============================================================================
--- head/sys/mips/adm5120/if_admswvar.h	Tue Nov 24 17:46:58 2009	(r199761)
+++ head/sys/mips/adm5120/if_admswvar.h	Tue Nov 24 18:34:47 2009	(r199762)
@@ -132,7 +132,9 @@ struct admsw_softc {
 	bus_dma_tag_t	 sc_bufs_dmat;	/* bus DMA tag for buffers */
 	struct ifmedia	 sc_ifmedia[SW_DEVS];
 	int		 ndevs;		/* number of IFF_RUNNING interfaces */
-	struct ifnet	*sc_ifnet[SW_DEVS];	
+	struct ifnet	*sc_ifnet[SW_DEVS];
+	struct callout	 sc_watchdog;
+	int		 sc_timer;
 					/* Ethernet common data */
 	void		*sc_ih;		/* interrupt cookie */
 	struct resource	*irq_res;


More information about the svn-src-head mailing list