diff --git a/sys/boot/fdt/dts/db78100.dts b/sys/boot/fdt/dts/db78100.dts index 015768164826..caebaf18e8bf 100644 --- a/sys/boot/fdt/dts/db78100.dts +++ b/sys/boot/fdt/dts/db78100.dts @@ -221,6 +221,9 @@ phy0: ethernet-phy@0 { reg = <0x8>; }; + phy1: ethernet-phy@1 { + reg = <0x9>; + }; }; }; @@ -234,17 +237,7 @@ local-mac-address = [ 00 00 00 00 00 00 ]; interrupts = <45 46 47 44 70>; interrupt-parent = <&PIC>; - phy-handle = <&phy0>; - - mdio@0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "mrvl,mdio"; - - phy0: ethernet-phy@0 { - reg = <0x9>; - }; - }; + phy-handle = <&phy1>; }; serial0: serial@12000 { diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c index 8702df284e82..bf18e3485838 100644 --- a/sys/dev/fdt/fdt_common.c +++ b/sys/dev/fdt/fdt_common.c @@ -542,11 +542,13 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl, } int -fdt_get_phyaddr(phandle_t node, int *phy_addr) +fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc) { phandle_t phy_node; ihandle_t phy_ihandle; pcell_t phy_handle, phy_reg; + uint32_t i; + device_t parent, child; if (OF_getprop(node, "phy-handle", (void *)&phy_handle, sizeof(phy_handle)) <= 0) @@ -561,6 +563,47 @@ fdt_get_phyaddr(phandle_t node, int *phy_addr) return (ENXIO); *phy_addr = fdt32_to_cpu(phy_reg); + + /* + * Search for softc used to communicate with phy. + */ + + /* + * Step 1: Search for ancestor of the phy-node with a "phy-handle" + * property set. + */ + phy_node = OF_parent(phy_node); + while (phy_node != 0) { + if (OF_getprop(phy_node, "phy-handle", (void *)&phy_handle, + sizeof(phy_handle)) > 0) + break; + phy_node = OF_parent(phy_node); + } + if (phy_node == 0) + return (ENXIO); + + /* + * Step 2: For each device with the same parent and name as ours + * compare its node with the one found in step 1, ancestor of phy + * node (stored in phy_node). + */ + parent = device_get_parent(dev); + i = 0; + child = device_find_child(parent, device_get_name(dev), i); + while (child != NULL) { + if (ofw_bus_get_node(child) == phy_node) + break; + i++; + child = device_find_child(parent, device_get_name(dev), i); + } + if (child == NULL) + return (ENXIO); + + /* + * Use softc of the device found. + */ + *phy_sc = (void *)device_get_softc(child); + return (0); } diff --git a/sys/dev/fdt/fdt_common.h b/sys/dev/fdt/fdt_common.h index dc57dddde087..0bedb91916a1 100644 --- a/sys/dev/fdt/fdt_common.h +++ b/sys/dev/fdt/fdt_common.h @@ -89,7 +89,7 @@ int fdt_data_to_res(pcell_t *, int, int, u_long *, u_long *); int fdt_data_verify(void *, int); phandle_t fdt_find_compatible(phandle_t, const char *, int); int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *); -int fdt_get_phyaddr(phandle_t node, int *); +int fdt_get_phyaddr(phandle_t, device_t, int *, void **); int fdt_immr_addr(vm_offset_t); int fdt_regsize(phandle_t, u_long *, u_long *); int fdt_intr_decode(phandle_t, pcell_t *, int *, int *, int *); diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c index 824f8a21a615..5b7a78d2dc90 100644 --- a/sys/dev/mge/if_mge.c +++ b/sys/dev/mge/if_mge.c @@ -79,9 +79,6 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" -/* PHY registers are in the address space of the first mge unit */ -static struct mge_softc *sc_mge0 = NULL; - static int mge_probe(device_t dev); static int mge_attach(device_t dev); static int mge_detach(device_t dev); @@ -635,14 +632,11 @@ mge_attach(device_t dev) sc->dev = dev; sc->node = ofw_bus_get_node(dev); - if (device_get_unit(dev) == 0) - sc_mge0 = sc; - /* Set chip version-dependent parameters */ mge_ver_params(sc); - /* Get phy address from fdt */ - if (fdt_get_phyaddr(sc->node, &phy) != 0) + /* Get phy address and used softc from fdt */ + if (fdt_get_phyaddr(sc->node, sc->dev, &phy, (void **)&sc->phy_sc) != 0) return (ENXIO); /* Initialize mutexes */ @@ -1294,17 +1288,18 @@ mge_miibus_readreg(device_t dev, int phy, int reg) sc = device_get_softc(dev); - MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff & + MGE_WRITE(sc->phy_sc, MGE_REG_SMI, 0x1fffffff & (MGE_SMI_READ | (reg << 21) | (phy << 16))); retries = MGE_SMI_READ_RETRIES; - while (--retries && !(MGE_READ(sc_mge0, MGE_REG_SMI) & MGE_SMI_READVALID)) + while (--retries && + !(MGE_READ(sc->phy_sc, MGE_REG_SMI) & MGE_SMI_READVALID)) DELAY(MGE_SMI_READ_DELAY); if (retries == 0) device_printf(dev, "Timeout while reading from PHY\n"); - return (MGE_READ(sc_mge0, MGE_REG_SMI) & 0xffff); + return (MGE_READ(sc->phy_sc, MGE_REG_SMI) & 0xffff); } static int @@ -1315,11 +1310,11 @@ mge_miibus_writereg(device_t dev, int phy, int reg, int value) sc = device_get_softc(dev); - MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff & + MGE_WRITE(sc->phy_sc, MGE_REG_SMI, 0x1fffffff & (MGE_SMI_WRITE | (reg << 21) | (phy << 16) | (value & 0xffff))); retries = MGE_SMI_WRITE_RETRIES; - while (--retries && MGE_READ(sc_mge0, MGE_REG_SMI) & MGE_SMI_BUSY) + while (--retries && MGE_READ(sc->phy_sc, MGE_REG_SMI) & MGE_SMI_BUSY) DELAY(MGE_SMI_WRITE_DELAY); if (retries == 0) diff --git a/sys/dev/mge/if_mgevar.h b/sys/dev/mge/if_mgevar.h index 5f96fa760904..2ce6b6ffe71e 100644 --- a/sys/dev/mge/if_mgevar.h +++ b/sys/dev/mge/if_mgevar.h @@ -103,6 +103,8 @@ struct mge_softc { uint32_t mge_tx_tok_cnt; uint16_t mge_mtu; int mge_ver; + + struct mge_softc *phy_sc; }; diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c index ce257ab3a6b1..2e54129e5754 100644 --- a/sys/dev/tsec/if_tsec.c +++ b/sys/dev/tsec/if_tsec.c @@ -106,8 +106,6 @@ static void tsec_offload_process_frame(struct tsec_softc *sc, static void tsec_setup_multicast(struct tsec_softc *sc); static int tsec_set_mtu(struct tsec_softc *sc, unsigned int mtu); -struct tsec_softc *tsec0_sc = NULL; /* XXX ugly hack! */ - devclass_t tsec_devclass; DRIVER_MODULE(miibus, tsec, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(tsec, ether, 1, 1, 1); @@ -406,14 +404,14 @@ tsec_init_locked(struct tsec_softc *sc) TSEC_WRITE(sc, TSEC_REG_TBIPA, 5); /* Step 6: Reset the management interface */ - TSEC_WRITE(tsec0_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); /* Step 7: Setup the MII Mgmt clock speed */ - TSEC_WRITE(tsec0_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28); /* Step 8: Read MII Mgmt indicator register and check for Busy = 0 */ timeout = TSEC_READ_RETRY; - while (--timeout && (TSEC_READ(tsec0_sc, TSEC_REG_MIIMIND) & + while (--timeout && (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) & TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); if (timeout == 0) { @@ -1561,21 +1559,21 @@ tsec_miibus_readreg(device_t dev, int phy, int reg) struct tsec_softc *sc; uint32_t timeout; - sc = tsec0_sc; + sc = device_get_softc(dev); - TSEC_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg); - TSEC_WRITE(sc, TSEC_REG_MIIMCOM, 0); - TSEC_WRITE(sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, 0); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCOM, TSEC_MIIMCOM_READCYCLE); timeout = TSEC_READ_RETRY; - while (--timeout && TSEC_READ(sc, TSEC_REG_MIIMIND) & + while (--timeout && TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) & (TSEC_MIIMIND_NOTVALID | TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); if (timeout == 0) device_printf(dev, "Timeout while reading from PHY!\n"); - return (TSEC_READ(sc, TSEC_REG_MIIMSTAT)); + return (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMSTAT)); } int @@ -1584,13 +1582,13 @@ tsec_miibus_writereg(device_t dev, int phy, int reg, int value) struct tsec_softc *sc; uint32_t timeout; - sc = tsec0_sc; + sc = device_get_softc(dev); - TSEC_WRITE(sc, TSEC_REG_MIIMADD, (phy << 8) | reg); - TSEC_WRITE(sc, TSEC_REG_MIIMCON, value); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMADD, (phy << 8) | reg); + TSEC_WRITE(sc->phy_sc, TSEC_REG_MIIMCON, value); timeout = TSEC_READ_RETRY; - while (--timeout && (TSEC_READ(sc, TSEC_REG_MIIMIND) & + while (--timeout && (TSEC_READ(sc->phy_sc, TSEC_REG_MIIMIND) & TSEC_MIIMIND_BUSY)) DELAY(TSEC_READ_DELAY); diff --git a/sys/dev/tsec/if_tsec.h b/sys/dev/tsec/if_tsec.h index b98032202548..cfba3f6bcc3b 100644 --- a/sys/dev/tsec/if_tsec.h +++ b/sys/dev/tsec/if_tsec.h @@ -133,6 +133,7 @@ struct tsec_softc { struct mbuf *frame; int phyaddr; + struct tsec_softc *phy_sc; }; /* interface to get/put generic objects */ diff --git a/sys/dev/tsec/if_tsec_fdt.c b/sys/dev/tsec/if_tsec_fdt.c index 55132eb96811..7f6f414a35d8 100644 --- a/sys/dev/tsec/if_tsec_fdt.c +++ b/sys/dev/tsec/if_tsec_fdt.c @@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$"); #define TSEC_RID_RXIRQ 1 #define TSEC_RID_ERRIRQ 2 -extern struct tsec_softc *tsec0_sc; - static int tsec_fdt_probe(device_t dev); static int tsec_fdt_attach(device_t dev); static int tsec_fdt_detach(device_t dev); @@ -156,12 +154,9 @@ tsec_fdt_attach(device_t dev) sc->dev = dev; sc->node = ofw_bus_get_node(dev); - /* XXX add comment on weird FSL's MII registers access design */ - if (device_get_unit(dev) == 0) - tsec0_sc = sc; - /* Get phy address from fdt */ - if (fdt_get_phyaddr(sc->node, &sc->phyaddr) != 0) + if (fdt_get_phyaddr(sc->node, sc->dev, &sc->phyaddr, + (void **)&sc->phy_sc) != 0) return (ENXIO); /* Init timer */