diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-02-04 21:48:35 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-02-04 21:48:35 +0000 |
commit | 6c023455d9fd0b3ca61f1b9fa2775802dde2f1f8 (patch) | |
tree | 867b095717466eeb146fa44ffc559ac81fc955a2 /sys/dev/pci | |
parent | 638d3699d0a41220530d4aa830c8ac09a5ce87c7 (diff) |
- start MII timer in nfe_init() and move timer initialization in nfe_attach()
- set RX filter before enabling RX in nfe_init()
- call mii_down() in nfe_stop()
- fix setting of full/half-duplex mode
- call mii_phy_reset() for each PHY attached and call mii_mediachg() in
nfe_ifmedia_upd()
- some cleaning while i'm here
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_nfe.c | 110 | ||||
-rw-r--r-- | sys/dev/pci/if_nfereg.h | 24 | ||||
-rw-r--r-- | sys/dev/pci/if_nfevar.h | 7 |
3 files changed, 76 insertions, 65 deletions
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c index c842b1cd355..7bf9db47340 100644 --- a/sys/dev/pci/if_nfe.c +++ b/sys/dev/pci/if_nfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_nfe.c,v 1.12 2006/02/04 16:51:15 damien Exp $ */ +/* $OpenBSD: if_nfe.c,v 1.13 2006/02/04 21:48:34 damien Exp $ */ /*- * Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr> @@ -91,8 +91,8 @@ void nfe_free_rx_ring(struct nfe_softc *, struct nfe_rx_ring *); int nfe_alloc_tx_ring(struct nfe_softc *, struct nfe_tx_ring *); void nfe_reset_tx_ring(struct nfe_softc *, struct nfe_tx_ring *); void nfe_free_tx_ring(struct nfe_softc *, struct nfe_tx_ring *); -int nfe_mediachange(struct ifnet *); -void nfe_mediastatus(struct ifnet *, struct ifmediareq *); +int nfe_ifmedia_upd(struct ifnet *); +void nfe_ifmedia_sts(struct ifnet *, struct ifmediareq *); void nfe_setmulti(struct nfe_softc *); void nfe_get_macaddr(struct nfe_softc *, uint8_t *); void nfe_set_macaddr(struct nfe_softc *, const uint8_t *); @@ -159,9 +159,6 @@ nfe_attach(struct device *parent, struct device *self, void *aux) return; } - /* - * Allocate interrupt. - */ if (pci_intr_map(pa, &ih) != 0) { printf(": couldn't map interrupt\n"); return; @@ -245,8 +242,8 @@ nfe_attach(struct device *parent, struct device *self, void *aux) sc->sc_mii.mii_writereg = nfe_miibus_writereg; sc->sc_mii.mii_statchg = nfe_miibus_statchg; - ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_mediachange, - nfe_mediastatus); + ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd, + nfe_ifmedia_sts); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { @@ -260,6 +257,8 @@ nfe_attach(struct device *parent, struct device *self, void *aux) if_attach(ifp); ether_ifattach(ifp); + timeout_set(&sc->sc_tick_ch, nfe_tick, sc); + sc->sc_powerhook = powerhook_establish(nfe_power, sc); } @@ -284,20 +283,41 @@ nfe_miibus_statchg(struct device *dev) { struct nfe_softc *sc = (struct nfe_softc *)dev; struct mii_data *mii = &sc->sc_mii; - uint32_t reg; + uint32_t phy, seed, misc = NFE_MISC1_MAGIC, link = NFE_MEDIA_SET; - reg = NFE_READ(sc, NFE_PHY_INT); + phy = NFE_READ(sc, NFE_PHY_IFACE); + phy &= ~(NFE_PHY_HDX | NFE_PHY_100TX | NFE_PHY_1000T); + + seed = NFE_READ(sc, NFE_RNDSEED); + seed &= ~NFE_SEED_MASK; + + if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) { + phy |= NFE_PHY_HDX; /* half-duplex */ + misc |= NFE_MISC1_HDX; + } switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_1000_T: - reg |= NFE_PHY_1000T; + case IFM_1000_T: /* full-duplex only */ + link |= NFE_MEDIA_1000T; + seed |= NFE_SEED_1000T; + phy |= NFE_PHY_1000T; break; case IFM_100_TX: - reg |= NFE_PHY_100TX; + link |= NFE_MEDIA_100TX; + seed |= NFE_SEED_100TX; + phy |= NFE_PHY_100TX; + break; + case IFM_10_T: + link |= NFE_MEDIA_10T; + seed |= NFE_SEED_10T; break; } - NFE_WRITE(sc, NFE_PHY_INT, reg); + NFE_WRITE(sc, NFE_RNDSEED, seed); /* XXX: gigabit NICs only? */ + + NFE_WRITE(sc, NFE_PHY_IFACE, phy); + NFE_WRITE(sc, NFE_MISC1, misc); + NFE_WRITE(sc, NFE_LINKSPEED, link); } int @@ -963,22 +983,24 @@ nfe_init(struct ifnet *ifp) DELAY(10); NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT1 | rxtxctl); + /* configure media */ + mii_mediachg(&sc->sc_mii); + + /* set Rx filter */ + nfe_setmulti(sc); + /* enable Rx */ NFE_WRITE(sc, NFE_RX_CTL, NFE_RX_START); /* enable Tx */ NFE_WRITE(sc, NFE_TX_CTL, NFE_TX_START); - nfe_setmulti(sc); - NFE_WRITE(sc, NFE_PHY_STATUS, 0xf); /* enable interrupts */ NFE_WRITE(sc, NFE_IRQ_MASK, NFE_IRQ_WANTED); - mii_mediachg(&sc->sc_mii); - - timeout_set(&sc->sc_timeout, nfe_tick, sc); + timeout_add(&sc->sc_tick_ch, hz); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -991,11 +1013,13 @@ nfe_stop(struct ifnet *ifp, int disable) { struct nfe_softc *sc = ifp->if_softc; - timeout_del(&sc->sc_timeout); + timeout_del(&sc->sc_tick_ch); ifp->if_timer = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + mii_down(&sc->sc_mii); + /* abort Tx */ NFE_WRITE(sc, NFE_TX_CTL, 0); @@ -1333,48 +1357,28 @@ nfe_free_tx_ring(struct nfe_softc *sc, struct nfe_tx_ring *ring) } int -nfe_mediachange(struct ifnet *ifp) +nfe_ifmedia_upd(struct ifnet *ifp) { struct nfe_softc *sc = ifp->if_softc; - struct mii_data *mii = &sc->sc_mii; - uint32_t val; - - DPRINTF(("nfe_mediachange\n")); -#if 0 - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) - /* XXX? */ - else -#endif - val = 0; - - val |= NFE_MEDIA_SET; + struct mii_data *mii = &sc->sc_mii; + struct mii_softc *miisc; - switch (IFM_SUBTYPE(mii->mii_media_active)) { - case IFM_1000_T: - val |= NFE_MEDIA_1000T; - break; - case IFM_100_TX: - val |= NFE_MEDIA_100TX; - break; - case IFM_10_T: - val |= NFE_MEDIA_10T; - break; + if (mii->mii_instance != 0) { + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + mii_phy_reset(miisc); } - - DPRINTF(("nfe_miibus_statchg: val=0x%x\n", val)); - NFE_WRITE(sc, NFE_LINKSPEED, val); - - return 0; + return mii_mediachg(mii); } void -nfe_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) +nfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { struct nfe_softc *sc = ifp->if_softc; + struct mii_data *mii = &sc->sc_mii; - mii_pollstat(&sc->sc_mii); - ifmr->ifm_status = sc->sc_mii.mii_media_status; - ifmr->ifm_active = sc->sc_mii.mii_media_active; + mii_pollstat(mii); + ifmr->ifm_status = mii->mii_media_status; + ifmr->ifm_active = mii->mii_media_active; } void @@ -1465,5 +1469,5 @@ nfe_tick(void *arg) mii_tick(&sc->sc_mii); splx(s); - timeout_add(&sc->sc_timeout, hz); + timeout_add(&sc->sc_tick_ch, hz); } diff --git a/sys/dev/pci/if_nfereg.h b/sys/dev/pci/if_nfereg.h index 44170213fe1..c32685943db 100644 --- a/sys/dev/pci/if_nfereg.h +++ b/sys/dev/pci/if_nfereg.h @@ -1,5 +1,6 @@ -/* $OpenBSD: if_nfereg.h,v 1.5 2006/02/04 09:46:48 damien Exp $ */ -/* +/* $OpenBSD: if_nfereg.h,v 1.6 2006/02/04 21:48:34 damien Exp $ */ + +/*- * Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -33,7 +34,7 @@ #define NFE_OFFLD_CFG 0x090 #define NFE_RX_CTL 0x094 #define NFE_RX_STATUS 0x098 -#define NFE_RDM_SEED 0x09c +#define NFE_RNDSEED 0x09c #define NFE_SETUP_R1 0x0a0 #define NFE_SETUP_R2 0x0a4 #define NFE_MACADDR_HI 0x0a8 @@ -42,7 +43,7 @@ #define NFE_MULTIADDR_LO 0x0b4 #define NFE_MULTIMASK_HI 0x0b8 #define NFE_MULTIMASK_LO 0x0bc -#define NFE_PHY_INT 0x0c0 +#define NFE_PHY_IFACE 0x0c0 #define NFE_TX_RING_ADDR 0x100 #define NFE_RX_RING_ADDR 0x104 #define NFE_RING_SIZE 0x108 @@ -104,12 +105,17 @@ #define NFE_MEDIA_100TX 0x00064 #define NFE_MEDIA_10T 0x003e8 -#define NFE_PHY_100TX 0x01 -#define NFE_PHY_1000T 0x02 +#define NFE_PHY_100TX (1 << 0) +#define NFE_PHY_1000T (1 << 1) +#define NFE_PHY_HDX (1 << 8) + +#define NFE_MISC1_MAGIC 0x003b0f3c +#define NFE_MISC1_HDX (1 << 1) -#define NFE_RDM_SEED_FORCE1 0x7f00 -#define NFE_RDM_SEED_FORCE2 0x2d00 -#define NFE_RDM_SEED_FORCE3 0x7400 +#define NFE_SEED_MASK 0x0003ff00 +#define NFE_SEED_10T 0x00007f00 +#define NFE_SEED_100TX 0x00002d00 +#define NFE_SEED_1000T 0x00007400 /* Rx/Tx descriptor */ struct nfe_desc32 { diff --git a/sys/dev/pci/if_nfevar.h b/sys/dev/pci/if_nfevar.h index ce0ab9407e5..8ea5c7c71a8 100644 --- a/sys/dev/pci/if_nfevar.h +++ b/sys/dev/pci/if_nfevar.h @@ -1,5 +1,6 @@ -/* $OpenBSD: if_nfevar.h,v 1.6 2006/02/04 09:46:48 damien Exp $ */ -/* +/* $OpenBSD: if_nfevar.h,v 1.7 2006/02/04 21:48:34 damien Exp $ */ + +/*- * Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -59,7 +60,7 @@ struct nfe_softc { void *sc_ih; bus_dma_tag_t sc_dmat; struct mii_data sc_mii; - struct timeout sc_timeout; + struct timeout sc_tick_ch; void *sc_powerhook; int sc_if_flags; |