From owner-p4-projects@FreeBSD.ORG Thu Jan 5 01:54:42 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B776C16A422; Thu, 5 Jan 2006 01:54:41 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 822EE16A41F for ; Thu, 5 Jan 2006 01:54:41 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1849843D60 for ; Thu, 5 Jan 2006 01:54:39 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k051scsg052962 for ; Thu, 5 Jan 2006 01:54:38 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k051scKP052959 for perforce@freebsd.org; Thu, 5 Jan 2006 01:54:38 GMT (envelope-from imp@freebsd.org) Date: Thu, 5 Jan 2006 01:54:38 GMT Message-Id: <200601050154.k051scKP052959@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 89190 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Jan 2006 01:54:42 -0000 http://perforce.freebsd.org/chv.cgi?CH=89190 Change 89190 by imp@imp_Speedy on 2006/01/05 01:54:31 Write a stop routine. Start an init routine. Write a tick routine. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/if_ate.c#5 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/if_ate.c#5 (text+ko) ==== @@ -57,21 +57,25 @@ #include #include +#include #include "miibus_if.h" struct ate_softc { - struct ifnet *ifp; - struct mtx sc_mtx; - device_t dev; - device_t miibus; - void *intrhand; - struct resource *irq_res; - struct resource *mem_res; + struct ifnet *ifp; /* ifnet pointer */ + struct mtx sc_mtx; /* basically a perimeter lock */ + device_t dev; /* Myself */ + device_t miibus; /* My child miibus */ + void *intrhand; /* Interrupt handle */ + struct resource *irq_res; /* IRQ resource */ + struct resource *mem_res; /* Memory resource */ + struct callout tick_ch; /* Tick callout */ // XXX bogus int intr; + + struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */ }; static inline uint32_t @@ -148,6 +152,8 @@ /* calling atestop before ifp is set is OK */ atestop(sc); ATE_LOCK_INIT(sc); + callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); + sc->ifp = ifp = if_alloc(IFT_ETHER); ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -162,6 +168,9 @@ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); ifp->if_timer = 0; + ifp->if_linkmib = &sc->mibdata; + ifp->if_linkmiblen = sizeof(sc->mibdata); + sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; ether_ifattach(ifp, eaddr); @@ -219,6 +228,9 @@ if (sc->intrhand) bus_teardown_intr(dev, sc->irq_res, sc->intrhand); sc->intrhand = 0; + bus_generic_detach(sc->dev); + if (sc->miibus) + device_delete_child(sc->dev, sc->miibus); if (sc->mem_res) bus_release_resource(dev, SYS_RES_IOPORT, rman_get_rid(sc->mem_res), sc->mem_res); @@ -231,6 +243,42 @@ } static void +ate_tick(void *xsc) +{ + struct ate_softc *sc = xsc; + struct mii_data *mii; + int active; + + ATE_ASSERT_LOCKED(sc); + if (sc->miibus != NULL) { + mii = device_get_softc(sc->miibus); + active = mii->mii_media_active; + mii_tick(mii); + if (mii->mii_media_status & IFM_ACTIVE && + active != mii->mii_media_active) { + /* + * The speed and full/half-duplex state needs + * to be reflected in the ETH_CFG register, it + * seems. + */ + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & + ~ETH_CFG_SPD); + else + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | + ETH_CFG_SPD); + if (mii->mii_media_active & IFM_FDX) + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | + ETH_CFG_FD); + else + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & + ~ETH_CFG_FD); + } + } +} + + +static void ate_intr(void *xsc) { struct ate_softc *sc = xsc; @@ -245,13 +293,45 @@ ateinit_locked(void *xsc) { struct ate_softc *sc = xsc; -// struct ifnet *ifp = sc->ifp; + struct ifnet *ifp = sc->ifp; ATE_ASSERT_LOCKED(sc); -// XXX don't forget RMII vs MII - /* Insert code here */ - sc->intr++; + /* + * XXX we need to turn on the EMAC clock in the pmc. With the + * default boot loader, this is already turned on. However, we + * need to think about how best to turn it on/off as the interface + * is brought up/down, as well as dealing with the mii bus... + * + * We also need to multiplex the pins correctly. + */ + + /* + * There are two different ways that the mii bus is connected + * to this chip. Select the right one based on a compile-time + * option. + */ +#ifdef ATE_USE_RMII + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_RMII); +#else + WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII); +#endif + + /* XXX need to setup multicast filters */ + /* XXX need to setup rx buffers and assoc structures */ + /* XXX need to enable appropriate interrupt masks */ + /* XXX need to program station address, or is that + * XXX added by upper layers? */ + + /* + * Set 'running' flag, and clear output active flag + * and attempt to start the output + */ + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + atestart_locked(ifp); + + callout_reset(&sc->tick_ch, hz, ate_tick, sc); } /* @@ -293,6 +373,39 @@ static void atestop(struct ate_softc *sc) { + callout_stop(&sc->tick_ch); + + /* + * Enable some parts of the MAC that are needed always (like the + * MII bus. This turns off the RE and TE bits, which will remain + * off until atestart() is called to turn them on. + */ + WR4(sc, ETH_CTL, ETH_CTL_MPE); + + /* + * Turn off all the configured options and revert to defaults. + */ + WR4(sc, ETH_CFG, ETH_CFG_CLK_32); + + /* + * Turn off all the interrupts, and ack any pending ones by reading + * the ISR. + */ + WR4(sc, ETH_IDR, 0xffffffff); + RD4(sc, ETH_ISR); + + /* + * Clear out the Transmit and Receiver Status registers of any + * errors they may be reporting + */ + WR4(sc, ETH_TSR, 0xffffffff); + WR4(sc, ETH_RSR, 0xffffffff); + + /* + * XXX we should power down the EMAC if it isn't in use, after + * putting it into loopback mode. This saves about 400uA according + * to the datasheet. + */ } static void