From owner-svn-src-head@FreeBSD.ORG Thu Nov 19 18:43:44 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 23B2D1065698; Thu, 19 Nov 2009 18:43:44 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1231A8FC13; Thu, 19 Nov 2009 18:43:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAJIhhvv015298; Thu, 19 Nov 2009 18:43:43 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAJIhh0q015295; Thu, 19 Nov 2009 18:43:43 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200911191843.nAJIhh0q015295@svn.freebsd.org> From: John Baldwin Date: Thu, 19 Nov 2009 18:43:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199540 - head/sys/dev/my X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Nov 2009 18:43:44 -0000 Author: jhb Date: Thu Nov 19 18:43:43 2009 New Revision: 199540 URL: http://svn.freebsd.org/changeset/base/199540 Log: - This driver used the if_watchdog timer both as a watchdog on transmit and auto-negotiation. To make this simpler and easier to understand I have split this out into two separate timers. One just manages the auto-neg side of things and one is a transmit watchdog. Neither uses if_watchdog. - Call ether_ifdetach() at the start of detach. Modified: head/sys/dev/my/if_my.c head/sys/dev/my/if_myreg.h Modified: head/sys/dev/my/if_my.c ============================================================================== --- head/sys/dev/my/if_my.c Thu Nov 19 18:37:55 2009 (r199539) +++ head/sys/dev/my/if_my.c Thu Nov 19 18:43:43 2009 (r199540) @@ -126,7 +126,8 @@ static int my_ioctl(struct ifnet *, static void my_init(void *); static void my_init_locked(struct my_softc *); static void my_stop(struct my_softc *); -static void my_watchdog(struct ifnet *); +static void my_autoneg_timeout(void *); +static void my_watchdog(void *); static int my_shutdown(device_t); static int my_ifmedia_upd(struct ifnet *); static void my_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -382,6 +383,15 @@ my_autoneg_xmit(struct my_softc * sc) return; } +static void +my_autoneg_timeout(void *arg) +{ + struct my_softc *sc; + + sc = arg; + MY_LOCK_ASSERT(sc); + my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1); +} /* * Invoke autonegotiation on a PHY. @@ -439,12 +449,13 @@ my_autoneg_mii(struct my_softc * sc, int return; } my_autoneg_xmit(sc); - ifp->if_timer = 5; + callout_reset(&sc->my_autoneg_timer, hz * 5, my_autoneg_timeout, + sc); sc->my_autoneg = 1; sc->my_want_auto = 0; return; case MY_FLAG_DELAYTIMEO: - ifp->if_timer = 0; + callout_stop(&sc->my_autoneg_timer); sc->my_autoneg = 0; break; default: @@ -661,7 +672,8 @@ my_setmode_mii(struct my_softc * sc, int */ if (sc->my_autoneg) { device_printf(sc->my_dev, "canceling autoneg session\n"); - ifp->if_timer = sc->my_autoneg = sc->my_want_auto = 0; + callout_stop(&sc->my_autoneg_timer); + sc->my_autoneg = sc->my_want_auto = 0; bmcr = my_phy_readreg(sc, PHY_BMCR); bmcr &= ~PHY_BMCR_AUTONEGENBL; my_phy_writereg(sc, PHY_BMCR, bmcr); @@ -808,6 +820,8 @@ my_attach(device_t dev) sc->my_dev = dev; mtx_init(&sc->my_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); + callout_init_mtx(&sc->my_autoneg_timer, &sc->my_mtx, 0); + callout_init_mtx(&sc->my_watchdog, &sc->my_mtx, 0); /* * Map control/status registers. @@ -886,7 +900,6 @@ my_attach(device_t dev) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = my_ioctl; ifp->if_start = my_start; - ifp->if_watchdog = my_watchdog; ifp->if_init = my_init; ifp->if_baudrate = 10000000; IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); @@ -984,13 +997,15 @@ my_detach(device_t dev) struct ifnet *ifp; sc = device_get_softc(dev); + ifp = sc->my_ifp; + ether_ifdetach(ifp); MY_LOCK(sc); my_stop(sc); MY_UNLOCK(sc); bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand); + callout_drain(&sc->my_watchdog); + callout_drain(&sc->my_autoneg_timer); - ifp = sc->my_ifp; - ether_ifdetach(ifp); if_free(ifp); free(sc->my_ldata_ptr, M_DEVBUF); @@ -1188,7 +1203,7 @@ my_txeof(struct my_softc * sc) MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; /* Clear the timeout timer. */ - ifp->if_timer = 0; + sc->my_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { return; } @@ -1240,7 +1255,7 @@ my_txeoc(struct my_softc * sc) MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; - ifp->if_timer = 0; + sc->my_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->my_cdata.my_tx_tail = NULL; @@ -1249,7 +1264,7 @@ my_txeoc(struct my_softc * sc) } else { if (MY_TXOWN(sc->my_cdata.my_tx_head) == MY_UNSENT) { MY_TXOWN(sc->my_cdata.my_tx_head) = MY_OWNByNIC; - ifp->if_timer = 5; + sc->my_timer = 5; CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); } } @@ -1455,7 +1470,7 @@ my_start_locked(struct ifnet * ifp) /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->my_timer = 5; return; } @@ -1555,6 +1570,8 @@ my_init_locked(struct my_softc *sc) my_phy_writereg(sc, PHY_BMCR, phy_bmcr); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + callout_reset(&sc->my_watchdog, hz, my_watchdog, sc); return; } @@ -1680,17 +1697,18 @@ my_ioctl(struct ifnet * ifp, u_long comm } static void -my_watchdog(struct ifnet * ifp) +my_watchdog(void *arg) { struct my_softc *sc; + struct ifnet *ifp; - sc = ifp->if_softc; - MY_LOCK(sc); - if (sc->my_autoneg) { - my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1); - MY_UNLOCK(sc); + sc = arg; + MY_LOCK_ASSERT(sc); + callout_reset(&sc->my_watchdog, hz, my_watchdog, sc); + if (sc->my_timer == 0 || --sc->my_timer > 0) return; - } + + ifp = sc->my_ifp; ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); if (!(my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) @@ -1700,8 +1718,6 @@ my_watchdog(struct ifnet * ifp) my_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) my_start_locked(ifp); - MY_UNLOCK(sc); - return; } @@ -1716,7 +1732,9 @@ my_stop(struct my_softc * sc) MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; - ifp->if_timer = 0; + + callout_stop(&sc->my_autoneg_timer); + callout_stop(&sc->my_watchdog); MY_CLRBIT(sc, MY_TCRRCR, (MY_RE | MY_TE)); CSR_WRITE_4(sc, MY_IMR, 0x00000000); Modified: head/sys/dev/my/if_myreg.h ============================================================================== --- head/sys/dev/my/if_myreg.h Thu Nov 19 18:37:55 2009 (r199539) +++ head/sys/dev/my/if_myreg.h Thu Nov 19 18:43:43 2009 (r199540) @@ -371,8 +371,10 @@ struct my_softc { struct my_chain_data my_cdata; device_t my_miibus; /* Add by Surfer 2001/12/2 */ - struct mtx my_mtx; - + struct mtx my_mtx; + struct callout my_autoneg_timer; + struct callout my_watchdog; + int my_timer; }; /* Add by Surfer 2001/12/2 */