From ae23e1de0dc7ac578a88495cbf94a5a33d3c74e0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 4 Apr 2017 15:26:28 +0200 Subject: [PATCH] if_tsec: Assume fixed link if no PHY is present On the P1020RDB for example the tsec0 is connected via a fixed link to an on-board switch. --- sys/dev/tsec/if_tsec.c | 80 +++++++++++++++++++++++++++------------------- sys/dev/tsec/if_tsec_fdt.c | 26 +++++++-------- 2 files changed, 59 insertions(+), 47 deletions(-) diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c index 37350fc..74ec96f 100644 --- a/sys/dev/tsec/if_tsec.c +++ b/sys/dev/tsec/if_tsec.c @@ -268,19 +268,23 @@ tsec_attach(struct tsec_softc *sc) /* Advertise that polling is supported */ ifp->if_capabilities |= IFCAP_POLLING; #endif - + /* Attach PHY(s) */ - error = mii_attach(sc->dev, &sc->tsec_miibus, ifp, tsec_ifmedia_upd, - tsec_ifmedia_sts, BMSR_DEFCAPMASK, sc->phyaddr, MII_OFFSET_ANY, - 0); - if (error) { - device_printf(sc->dev, "attaching PHYs failed\n"); - if_free(ifp); - sc->tsec_ifp = NULL; - tsec_detach(sc); - return (error); + if (sc->phy_bsh != 0) { + error = mii_attach(sc->dev, &sc->tsec_miibus, ifp, + tsec_ifmedia_upd, tsec_ifmedia_sts, BMSR_DEFCAPMASK, + sc->phyaddr, MII_OFFSET_ANY, 0); + if (error) { + device_printf(sc->dev, "attaching PHYs failed\n"); + if_free(ifp); + sc->tsec_ifp = NULL; + tsec_detach(sc); + return (error); + } + sc->tsec_mii = device_get_softc(sc->tsec_miibus); + } else { + sc->tsec_link = 1; } - sc->tsec_mii = device_get_softc(sc->tsec_miibus); /* Set MAC address */ tsec_get_hwaddr(sc, hwaddr); @@ -424,31 +428,37 @@ tsec_init_locked(struct tsec_softc *sc) /* Step 4: Initialize MAC station address */ tsec_set_mac_address(sc); - /* - * Step 5: Assign a Physical address to the TBI so as to not conflict - * with the external PHY physical address - */ - TSEC_WRITE(sc, TSEC_REG_TBIPA, 5); + if (sc->tsec_mii != NULL) { + /* + * Step 5: Assign a Physical address to the TBI so as to not + * conflict with the external PHY physical address + */ + TSEC_WRITE(sc, TSEC_REG_TBIPA, 5); - TSEC_PHY_LOCK(sc); + TSEC_PHY_LOCK(sc); - /* Step 6: Reset the management interface */ - TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); + /* Step 6: Reset the management interface */ + TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_RESETMGMT); - /* Step 7: Setup the MII Mgmt clock speed */ - TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28); + /* Step 7: Setup the MII Mgmt clock speed */ + TSEC_PHY_WRITE(sc, TSEC_REG_MIIMCFG, TSEC_MIIMCFG_CLKDIV28); - /* Step 8: Read MII Mgmt indicator register and check for Busy = 0 */ - timeout = tsec_mii_wait(sc, TSEC_MIIMIND_BUSY); + /* + * Step 8: Read MII Mgmt indicator register and check for + * Busy = 0 + */ + timeout = tsec_mii_wait(sc, TSEC_MIIMIND_BUSY); - TSEC_PHY_UNLOCK(sc); - if (timeout) { - if_printf(ifp, "tsec_init_locked(): Mgmt busy timeout\n"); - return; - } + TSEC_PHY_UNLOCK(sc); + if (timeout) { + if_printf(ifp, + "tsec_init_locked(): Mgmt busy timeout\n"); + return; + } - /* Step 9: Setup the MII Mgmt */ - mii_mediachg(sc->tsec_mii); + /* Step 9: Setup the MII Mgmt */ + mii_mediachg(sc->tsec_mii); + } /* Step 10: Clear IEVENT register */ TSEC_WRITE(sc, TSEC_REG_IEVENT, 0xffffffff); @@ -971,8 +981,11 @@ tsec_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } case SIOCGIFMEDIA: case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->tsec_mii->mii_media, - command); + if (sc->tsec_mii != NULL) + error = ifmedia_ioctl(ifp, ifr, + &sc->tsec_mii->mii_media, command); + else + error = ENXIO; break; case SIOCSIFCAP: mask = ifp->if_capenable ^ ifr->ifr_reqcap; @@ -1264,7 +1277,8 @@ tsec_tick(void *arg) ifp = sc->tsec_ifp; link = sc->tsec_link; - mii_tick(sc->tsec_mii); + if (sc->tsec_mii != NULL) + mii_tick(sc->tsec_mii); if (link == 0 && sc->tsec_link == 1 && (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))) diff --git a/sys/dev/tsec/if_tsec_fdt.c b/sys/dev/tsec/if_tsec_fdt.c index 7f25a42..eb1d342 100644 --- a/sys/dev/tsec/if_tsec_fdt.c +++ b/sys/dev/tsec/if_tsec_fdt.c @@ -188,22 +188,20 @@ tsec_fdt_attach(device_t dev) } /* Get phy address from fdt */ - if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) { - device_printf(dev, "PHY not found in device tree"); - return (ENXIO); - } + if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) > 0) { + phy = OF_node_from_xref(phy); + mdio = OF_parent(phy); + OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL); + OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr)); - phy = OF_node_from_xref(phy); - mdio = OF_parent(phy); - OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL); - OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr)); + /* + * etsec2 MDIO nodes are given the MDIO module base address, so + * we need to add the MII offset to get the PHY registers. + */ + if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio")) + sc->phy_regoff = TSEC_REG_MIIBASE; + } - /* - * etsec2 MDIO nodes are given the MDIO module base address, so we need - * to add the MII offset to get the PHY registers. - */ - if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio")) - sc->phy_regoff = TSEC_REG_MIIBASE; /* Init timer */ callout_init(&sc->tsec_callout, 1); -- 1.8.4.5