From: dlg Date: Mon, 24 Apr 2023 01:33:32 +0000 (+0000) Subject: handle fixed-link configuration in the device tree. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=45f5f3c80b3e678af70abbf179c80635e791abe1;p=openbsd handle fixed-link configuration in the device tree. if fixed-link is present, populate the interface baudrate and link status (full duplex or half duplex), and then call the statch handler to apply that config to the MAC. if fixed-link is specified then do not attach a phy. note that phy lookup and reset still occurs in case the device tree still uses the deprecated snps,reset-gpio properties. the fixed link port on the bpi r2 pro is connected to a switch chip (which is not really a phy) that needs needs a reset provided by the snps,reset-gpio handling. an improved device tree would have the reset properties on the switch node so it could do its own reset, but we can't have nice things can we? tested on a nanopi r5s, which has a phy but no fixed-link config, and a banana pi bpi-r2 pro, which has both (cos it has two dwqes, one with a phy and one without). --- diff --git a/sys/dev/fdt/if_dwqe_fdt.c b/sys/dev/fdt/if_dwqe_fdt.c index 0da10556b7d..f189524755b 100644 --- a/sys/dev/fdt/if_dwqe_fdt.c +++ b/sys/dev/fdt/if_dwqe_fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_dwqe_fdt.c,v 1.10 2023/04/22 05:01:44 dlg Exp $ */ +/* $OpenBSD: if_dwqe_fdt.c,v 1.11 2023/04/24 01:33:32 dlg Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2022 Patrick Wildt @@ -89,7 +89,7 @@ dwqe_fdt_attach(struct device *parent, struct device *self, void *aux) char phy_mode[16] = { 0 }; uint32_t phy, phy_supply; uint32_t axi_config; - struct ifnet *ifp; + struct ifnet *ifp = &sc->sc_ac.ac_if; int i, node; sc->sc_node = faa->fa_node; @@ -164,6 +164,15 @@ dwqe_fdt_attach(struct device *parent, struct device *self, void *aux) /* Reset PHY */ dwqe_reset_phy(sc, phy); + node = OF_getnodebyname(sc->sc_node, "fixed-link"); + if (node) { + sc->sc_fixed_link = 1; + + ifp->if_baudrate = IF_Mbps(OF_getpropint(node, "speed", 0)); + ifp->if_link_state = OF_getpropbool(node, "full-duplex") ? + LINK_STATE_FULL_DUPLEX : LINK_STATE_HALF_DUPLEX; + } + sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth"); if (sc->sc_clk > 500000000) sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_500_800; @@ -227,10 +236,13 @@ dwqe_fdt_attach(struct device *parent, struct device *self, void *aux) if (sc->sc_ih == NULL) printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname); - ifp = &sc->sc_ac.ac_if; sc->sc_ifd.if_node = faa->fa_node; sc->sc_ifd.if_ifp = ifp; if_register(&sc->sc_ifd); + + /* force a configuraton of the clocks/mac */ + if (sc->sc_fixed_link) + sc->sc_mii.mii_statchg(self); } void diff --git a/sys/dev/ic/dwqe.c b/sys/dev/ic/dwqe.c index 82e5581a683..2ecd3e83aa7 100644 --- a/sys/dev/ic/dwqe.c +++ b/sys/dev/ic/dwqe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwqe.c,v 1.7 2023/04/23 06:22:15 dlg Exp $ */ +/* $OpenBSD: dwqe.c,v 1.8 2023/04/24 01:33:32 dlg Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2022 Patrick Wildt @@ -74,6 +74,7 @@ void dwqe_watchdog(struct ifnet *); int dwqe_media_change(struct ifnet *); void dwqe_media_status(struct ifnet *, struct ifmediareq *); +void dwqe_mii_attach(struct dwqe_softc *); int dwqe_mii_readreg(struct device *, int, int); void dwqe_mii_writereg(struct device *, int, int, int); void dwqe_mii_statchg(struct device *); @@ -106,7 +107,6 @@ dwqe_attach(struct dwqe_softc *sc) { struct ifnet *ifp; uint32_t version, mode; - int mii_flags = 0; int i; version = dwqe_read(sc, GMAC_VERSION); @@ -213,6 +213,24 @@ dwqe_attach(struct dwqe_softc *sc) dwqe_write(sc, GMAC_SYS_BUS_MODE, mode); } + if (!sc->sc_fixed_link) + dwqe_mii_attach(sc); + + if_attach(ifp); + ether_ifattach(ifp); + + /* Disable interrupts. */ + dwqe_write(sc, GMAC_INT_EN, 0); + dwqe_write(sc, GMAC_CHAN_INTR_ENA(0), 0); + + return 0; +} + +void +dwqe_mii_attach(struct dwqe_softc *sc) +{ + int mii_flags = 0; + switch (sc->sc_phy_mode) { case DWQE_PHY_MODE_RGMII: mii_flags |= MIIF_SETDELAY; @@ -238,15 +256,6 @@ dwqe_attach(struct dwqe_softc *sc) ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); } else ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); - - if_attach(ifp); - ether_ifattach(ifp); - - /* Disable interrupts. */ - dwqe_write(sc, GMAC_INT_EN, 0); - dwqe_write(sc, GMAC_CHAN_INTR_ENA(0), 0); - - return 0; } uint32_t @@ -373,7 +382,10 @@ dwqe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) case SIOCGIFMEDIA: case SIOCSIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); + if (sc->sc_fixed_link) + error = ENOTTY; + else + error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); break; case SIOCGIFRXR: @@ -824,7 +836,8 @@ dwqe_up(struct dwqe_softc *sc) GMAC_CHAN_INTR_ENA_RIE | GMAC_CHAN_INTR_ENA_TIE); - timeout_add_sec(&sc->sc_phy_tick, 1); + if (!sc->sc_fixed_link) + timeout_add_sec(&sc->sc_phy_tick, 1); } void @@ -836,7 +849,8 @@ dwqe_down(struct dwqe_softc *sc) int i; timeout_del(&sc->sc_rxto); - timeout_del(&sc->sc_phy_tick); + if (!sc->sc_fixed_link) + timeout_del(&sc->sc_phy_tick); ifp->if_flags &= ~IFF_RUNNING; ifq_clr_oactive(&ifp->if_snd); diff --git a/sys/dev/ic/dwqevar.h b/sys/dev/ic/dwqevar.h index bdf0e3e1a57..69e95a34ed3 100644 --- a/sys/dev/ic/dwqevar.h +++ b/sys/dev/ic/dwqevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dwqevar.h,v 1.5 2023/04/23 06:22:15 dlg Exp $ */ +/* $OpenBSD: dwqevar.h,v 1.6 2023/04/24 01:33:32 dlg Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2022 Patrick Wildt @@ -63,6 +63,7 @@ struct dwqe_softc { int sc_phyloc; enum dwqe_phy_mode sc_phy_mode; struct timeout sc_phy_tick; + int sc_fixed_link; struct dwqe_dmamem *sc_txring; struct dwqe_buf *sc_txbuf;