Index: if_dwqe_fdt.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/if_dwqe_fdt.c,v retrieving revision 1.9 diff -u -p -r1.9 if_dwqe_fdt.c --- if_dwqe_fdt.c 7 Apr 2023 22:55:26 -0000 1.9 +++ if_dwqe_fdt.c 9 Apr 2023 01:44:33 -0000 @@ -21,6 +21,7 @@ */ #include "bpfilter.h" +#include "dwmdio.h" #include #include @@ -51,6 +52,10 @@ #include #include +#if NDWMDIO > 0 +#include +#endif + #if NBPFILTER > 0 #include #endif @@ -89,7 +94,7 @@ dwqe_fdt_attach(struct device *parent, s 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; @@ -128,16 +133,6 @@ dwqe_fdt_attach(struct device *parent, s else sc->sc_phy_mode = DWQE_PHY_MODE_UNKNOWN; - /* Lookup PHY. */ - phy = OF_getpropint(faa->fa_node, "phy", 0); - if (phy == 0) - phy = OF_getpropint(faa->fa_node, "phy-handle", 0); - node = OF_getnodebyphandle(phy); - if (node) - sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY); - else - sc->sc_phyloc = MII_PHY_ANY; - pinctrl_byname(faa->fa_node, "default"); /* Enable clocks. */ @@ -156,13 +151,32 @@ dwqe_fdt_attach(struct device *parent, s if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac")) dwqe_setup_rk3568(sc); - /* Power up PHY. */ - phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0); - if (phy_supply) - regulator_enable(phy_supply); + node = OF_getnodebyname(sc->sc_node, "fixed-link"); + if (node == 0) { + /* Lookup PHY. */ + phy = OF_getpropint(faa->fa_node, "phy", 0); + if (phy == 0) + phy = OF_getpropint(faa->fa_node, "phy-handle", 0); + node = OF_getnodebyphandle(phy); + if (node) + sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY); + else + sc->sc_phyloc = MII_PHY_ANY; + + /* Power up PHY. */ + phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0); + if (phy_supply) + regulator_enable(phy_supply); - /* Reset PHY */ - dwqe_reset_phy(sc, phy); + /* Reset PHY */ + dwqe_reset_phy(sc, phy); + } else { + 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_UP; + } sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth"); if (sc->sc_clk > 500000000) @@ -227,10 +241,29 @@ dwqe_fdt_attach(struct device *parent, s if (sc->sc_ih == NULL) printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname); - ifp = &sc->sc_ac.ac_if; + OF_getpropstr(faa->fa_node, "label", + ifp->if_description, sizeof(ifp->if_description)); + sc->sc_ifd.if_node = faa->fa_node; sc->sc_ifd.if_ifp = ifp; if_register(&sc->sc_ifd); + +#if NDWMDIO > 0 + if (!sc->sc_fixed_link) + return; + + node = OF_getnodebyname(sc->sc_node, "mdio"); + if (node == 0) + return; + + sc->sc_mdio.md_node = sc->sc_node; + sc->sc_mdio.md_cookie = sc; + sc->sc_mdio.md_readreg = dwqe_mii_readreg; + sc->sc_mdio.md_writereg = dwqe_mii_writereg; + mii_register(&sc->sc_mdio); + + dwmdio_found(self, node); +#endif } void @@ -402,3 +435,4 @@ dwqe_mii_statchg_rk3588(struct device *s regmap_write_4(rm, sc->sc_clk_sel, gmac_clk_sel); } + Index: dwmdio.c =================================================================== RCS file: dwmdio.c diff -N dwmdio.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dwmdio.c 9 Apr 2023 01:44:33 -0000 @@ -0,0 +1,102 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2023 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +/* + * the dwmdio node is a child of an ethernet/gmac node in the device + * tree. this grafts the dwmdio kernel device to the gmac parent bus + * to avoid confusing kernel autoconf, which can't tell the differences + * between the mii devices we usually want to attach and this dwmdio + * device we sometimes want to attach. + */ + +extern int simplebus_print(void *, const char *); + +struct device * +dwmdio_found(struct device *dv, int node) +{ + char name[32]; + struct fdt_attach_args faa = { + .fa_node = node, + .fa_name = name, + }; + + OF_getpropstr(node, "name", name, sizeof(name)); + + return (config_found(dv->dv_parent, &faa, simplebus_print)); +} + +struct dwmdio_softc { + struct device sc_dev; +}; +#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) + +static int dwmdio_match(struct device *, void *, void *); +static void dwmdio_attach(struct device *, struct device *, void *); + +struct cfdriver dwmdio_cd = { + NULL, "dwmdio", DV_DULL +}; + +const struct cfattach dwmdio_ca = { + sizeof (struct dwmdio_softc), dwmdio_match, dwmdio_attach, +}; + +static int +dwmdio_match(struct device *parent, void *cfdata, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return (OF_is_compatible(faa->fa_node, "snps,dwmac-mdio")); +} + +static void +dwmdio_attach(struct device *parent, struct device *self, void *aux) +{ + struct fdt_attach_args *faa = aux; + int node; + struct mii_bus *mii; + + /* find the mii ops the "parent" gmac device provides */ + node = OF_parent(faa->fa_node); + mii = mii_bynode(node); + if (mii == NULL) { + printf(": mdio operations not found\n"); + return; + } + + printf("\n"); + + mdio_attach(self, mii, faa->fa_node); +} Index: dwmdiovar.h =================================================================== RCS file: dwmdiovar.h diff -N dwmdiovar.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dwmdiovar.h 9 Apr 2023 01:44:33 -0000 @@ -0,0 +1,19 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2023 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct device *dwmdio_found(struct device *, int);