From 65f2c0ff587a41a964b6dc809466bb42fc3a5ab8 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Thu, 16 Sep 2010 09:29:48 +0000 Subject: [PATCH] Merge r207585 from cas(4): - Don't probe for PHYs if we already know to use a SERDES. Unlike as with cas(4) this only serves to speed up the the device attach though and can only be determined via the OFW device tree but not from the VPD. - Don't touch the MIF when using a SERDES. - Add some missing bus space barriers, mainly in the PCS code path. --- sys/dev/gem/if_gem.c | 36 ++++++++++++++++++++++++++++++++---- sys/dev/gem/if_gem_pci.c | 14 +++++++++++++- sys/dev/gem/if_gem_sbus.c | 2 ++ sys/modules/gem/Makefile | 9 +++++++-- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c index 6edb49e2f852..8be68abaf78b 100644 --- a/sys/dev/gem/if_gem.c +++ b/sys/dev/gem/if_gem.c @@ -268,10 +268,17 @@ gem_attach(struct gem_softc *sc) sc->sc_rxsoft[i].rxs_mbuf = NULL; } + /* Bypass probing PHYs if we already know for sure to use a SERDES. */ + if ((sc->sc_flags & GEM_SERDES) != 0) + goto serdes; + /* Bad things will happen when touching this register on ERI. */ - if (sc->sc_variant != GEM_SUN_ERI) + if (sc->sc_variant != GEM_SUN_ERI) { GEM_BANK1_WRITE_4(sc, GEM_MII_DATAPATH_MODE, GEM_MII_DATAPATH_MII); + GEM_BANK1_BARRIER(sc, GEM_MII_DATAPATH_MODE, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + } gem_mifinit(sc); @@ -283,6 +290,8 @@ gem_attach(struct gem_softc *sc) if ((v & GEM_MIF_CONFIG_MDI1) != 0) { v |= GEM_MIF_CONFIG_PHY_SEL; GEM_BANK1_WRITE_4(sc, GEM_MIF_CONFIG, v); + GEM_BANK1_BARRIER(sc, GEM_MIF_CONFIG, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); switch (sc->sc_variant) { case GEM_SUN_ERI: sc->sc_phyad = GEM_PHYAD_EXTERNAL; @@ -304,6 +313,8 @@ gem_attach(struct gem_softc *sc) ((v & GEM_MIF_CONFIG_MDI0) != 0 || GEM_IS_APPLE(sc))) { v &= ~GEM_MIF_CONFIG_PHY_SEL; GEM_BANK1_WRITE_4(sc, GEM_MIF_CONFIG, v); + GEM_BANK1_BARRIER(sc, GEM_MIF_CONFIG, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); switch (sc->sc_variant) { case GEM_SUN_ERI: case GEM_APPLE_K2_GMAC: @@ -324,17 +335,23 @@ gem_attach(struct gem_softc *sc) * Try the external PCS SERDES if we didn't find any PHYs. */ if (error != 0 && sc->sc_variant == GEM_SUN_GEM) { + serdes: GEM_BANK1_WRITE_4(sc, GEM_MII_DATAPATH_MODE, GEM_MII_DATAPATH_SERDES); + GEM_BANK1_BARRIER(sc, GEM_MII_DATAPATH_MODE, 4, + BUS_SPACE_BARRIER_WRITE); GEM_BANK1_WRITE_4(sc, GEM_MII_SLINK_CONTROL, GEM_MII_SLINK_LOOPBACK | GEM_MII_SLINK_EN_SYNC_D); + GEM_BANK1_BARRIER(sc, GEM_MII_SLINK_CONTROL, 4, + BUS_SPACE_BARRIER_WRITE); GEM_BANK1_WRITE_4(sc, GEM_MII_CONFIG, GEM_MII_CONFIG_ENABLE); + GEM_BANK1_BARRIER(sc, GEM_MII_CONFIG, 4, + BUS_SPACE_BARRIER_WRITE); sc->sc_flags |= GEM_SERDES; sc->sc_phyad = GEM_PHYAD_EXTERNAL; error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, gem_mediachange, gem_mediastatus); } - if (error != 0) { device_printf(sc->sc_dev, "PHY probe failed: %d\n", error); goto fail_rxd; @@ -918,8 +935,9 @@ gem_init_locked(struct gem_softc *sc) __func__); #endif - /* Re-initialize the MIF. */ - gem_mifinit(sc); + if ((sc->sc_flags & GEM_SERDES) == 0) + /* Re-initialize the MIF. */ + gem_mifinit(sc); /* step 3. Setup data structures in host memory. */ if (gem_meminit(sc) != 0) @@ -1800,6 +1818,8 @@ gem_mifinit(struct gem_softc *sc) /* Configure the MIF in frame mode. */ GEM_BANK1_WRITE_4(sc, GEM_MIF_CONFIG, GEM_BANK1_READ_4(sc, GEM_MIF_CONFIG) & ~GEM_MIF_CONFIG_BB_ENA); + GEM_BANK1_BARRIER(sc, GEM_MIF_CONFIG, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } /* @@ -1914,10 +1934,16 @@ gem_mii_writereg(device_t dev, int phy, int reg, int val) GEM_BANK1_BARRIER(sc, GEM_MII_CONFIG, 4, BUS_SPACE_BARRIER_WRITE); GEM_BANK1_WRITE_4(sc, GEM_MII_ANAR, val); + GEM_BANK1_BARRIER(sc, GEM_MII_ANAR, 4, + BUS_SPACE_BARRIER_WRITE); GEM_BANK1_WRITE_4(sc, GEM_MII_SLINK_CONTROL, GEM_MII_SLINK_LOOPBACK | GEM_MII_SLINK_EN_SYNC_D); + GEM_BANK1_BARRIER(sc, GEM_MII_SLINK_CONTROL, 4, + BUS_SPACE_BARRIER_WRITE); GEM_BANK1_WRITE_4(sc, GEM_MII_CONFIG, GEM_MII_CONFIG_ENABLE); + GEM_BANK1_BARRIER(sc, GEM_MII_CONFIG, 4, + BUS_SPACE_BARRIER_WRITE); return (0); case MII_ANLPAR: reg = GEM_MII_ANLPAR; @@ -1928,6 +1954,8 @@ gem_mii_writereg(device_t dev, int phy, int reg, int val) return (0); } GEM_BANK1_WRITE_4(sc, reg, val); + GEM_BANK1_BARRIER(sc, reg, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); return (0); } diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c index 051dbcc5bfbd..cfea337312c0 100644 --- a/sys/dev/gem/if_gem_pci.c +++ b/sys/dev/gem/if_gem_pci.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #if defined(__powerpc__) || defined(__sparc64__) +#include #include #include #endif @@ -140,12 +141,17 @@ static struct resource_spec gem_pci_res_spec[] = { { -1, 0 } }; +#define GEM_SHARED_PINS "shared-pins" +#define GEM_SHARED_PINS_SERDES "serdes" + static int gem_pci_attach(device_t dev) { struct gem_softc *sc; int i; -#if !(defined(__powerpc__) || defined(__sparc64__)) +#if defined(__powerpc__) || defined(__sparc64__) + char buf[sizeof(GEM_SHARED_PINS)]; +#else int j; #endif @@ -207,6 +213,12 @@ gem_pci_attach(device_t dev) #if defined(__powerpc__) || defined(__sparc64__) OF_getetheraddr(dev, sc->sc_enaddr); + if (OF_getprop(ofw_bus_get_node(dev), GEM_SHARED_PINS, buf, + sizeof(buf)) > 0) { + buf[sizeof(buf) - 1] = '\0'; + if (strcmp(buf, GEM_SHARED_PINS_SERDES) == 0) + sc->sc_flags |= GEM_SERDES; + } #else /* * Dig out VPD (vital product data) and read NA (network address). diff --git a/sys/dev/gem/if_gem_sbus.c b/sys/dev/gem/if_gem_sbus.c index 4402251354e9..205285d08e05 100644 --- a/sys/dev/gem/if_gem_sbus.c +++ b/sys/dev/gem/if_gem_sbus.c @@ -131,6 +131,8 @@ gem_sbus_attach(device_t dev) sc = device_get_softc(dev); sc->sc_variant = GEM_SUN_GEM; sc->sc_dev = dev; + /* All known SBus models use a SERDES. */ + sc->sc_flags = GEM_SERDES; if (bus_alloc_resources(dev, gem_sbus_res_spec, sc->sc_res)) { device_printf(dev, "failed to allocate resources\n"); diff --git a/sys/modules/gem/Makefile b/sys/modules/gem/Makefile index 94db46251a7f..941dc18f4a29 100644 --- a/sys/modules/gem/Makefile +++ b/sys/modules/gem/Makefile @@ -3,10 +3,15 @@ .PATH: ${.CURDIR}/../../dev/gem KMOD= if_gem -SRCS= bus_if.h device_if.h if_gem.c if_gem_pci.c miibus_if.h pci_if.h +SRCS= bus_if.h device_if.h if_gem.c if_gem_pci.c ${if_gem_sbus} miibus_if.h +SRCS+= ${ofw_bus_if} pci_if.h .if ${MACHINE} == "sparc64" -SRCS+= if_gem_sbus.c ofw_bus_if.h +if_gem_sbus= if_gem_sbus.c +.endif + +.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "sparc64" +ofw_bus_if= ofw_bus_if.h .endif .include