> Date: Wed, 5 Jul 2023 12:46:36 +0300 > From: Jonathan Matthew <jonat...@d14n.org> > > On the Banana Pi R1 (aka Lamobo R1), the dwge interface on the soc is > connected to a broadcom switch chip. It looks like this in the device > tree: > > &gmac { > pinctrl-names = "default"; > pinctrl-0 = <&gmac_rgmii_pins>; > phy-mode = "rgmii"; > phy-supply = <®_gmac_3v3>; > status = "okay"; > > fixed-link { > speed = <1000>; > full-duplex; > }; > > mdio { > ... > } > }; > > This diff makes the fixed-link part work, setting the interface's link > state to up and the media type to IFM_1000_T|IFM_FDX instead of trying to > attach a phy. After setting the media type, we need to call mii_statchg() > to configure the MAC appropriately. > > ok?
Is there a reason why you structured this differently than how this is done for dwqe(4)? > Index: if_dwge.c > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/if_dwge.c,v > retrieving revision 1.16 > diff -u -p -r1.16 if_dwge.c > --- if_dwge.c 25 Jun 2023 22:36:09 -0000 1.16 > +++ if_dwge.c 5 Jul 2023 09:16:41 -0000 > @@ -271,6 +271,7 @@ struct dwge_softc { > #define sc_lladdr sc_ac.ac_enaddr > struct mii_data sc_mii; > #define sc_media sc_mii.mii_media > + uint64_t sc_fixed_media; > int sc_link; > int sc_phyloc; > int sc_force_thresh_dma_mode; > @@ -386,7 +387,7 @@ dwge_attach(struct device *parent, struc > { > struct dwge_softc *sc = (void *)self; > struct fdt_attach_args *faa = aux; > - struct ifnet *ifp; > + struct ifnet *ifp = &sc->sc_ac.ac_if; > uint32_t phy, phy_supply; > uint32_t axi_config; > uint32_t mode, pbl; > @@ -403,16 +404,6 @@ dwge_attach(struct device *parent, struc > } > sc->sc_dmat = faa->fa_dmat; > > - /* 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. */ > @@ -449,13 +440,48 @@ dwge_attach(struct device *parent, struc > if (OF_is_compatible(faa->fa_node, "starfive,jh7100-gmac")) > sc->sc_defrag = 1; > > - /* Power up PHY. */ > - phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0); > - if (phy_supply) > - regulator_enable(phy_supply); > + node = OF_getnodebyname(faa->fa_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 */ > - dwge_reset_phy(sc); > + /* Reset PHY */ > + dwge_reset_phy(sc); > + } else { > + ifp->if_baudrate = IF_Mbps(OF_getpropint(node, > + "speed", 0)); > + > + switch (OF_getpropint(node, "speed", 0)) { > + case 1000: > + sc->sc_fixed_media = IFM_ETHER | IFM_1000_T; > + break; > + case 100: > + sc->sc_fixed_media = IFM_ETHER | IFM_100_TX; > + break; > + default: > + sc->sc_fixed_media = IFM_ETHER | IFM_AUTO; > + break; > + } > + > + if (OF_getpropbool(node, "full-duplex")) { > + ifp->if_link_state = LINK_STATE_FULL_DUPLEX; > + sc->sc_fixed_media |= IFM_FDX; > + } else { > + ifp->if_link_state = LINK_STATE_UP; > + } > + } > > sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth"); > if (sc->sc_clk > 250000000) > @@ -479,7 +505,6 @@ dwge_attach(struct device *parent, struc > timeout_set(&sc->sc_tick, dwge_tick, sc); > timeout_set(&sc->sc_rxto, dwge_rxtick, sc); > > - ifp = &sc->sc_ac.ac_if; > ifp->if_softc = sc; > ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; > ifp->if_xflags = IFXF_MPSAFE; > @@ -576,14 +601,21 @@ dwge_attach(struct device *parent, struc > dwge_write(sc, GMAC_AXI_BUS_MODE, mode); > } > > - mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc, > - (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, 0); > - if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { > - printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); > - ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); > - ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); > - } else > - ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); > + if (sc->sc_fixed_media == 0) { > + mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc, > + (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, 0); > + if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { > + printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); > + ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, > + NULL); > + ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); > + } else > + ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); > + } else { > + ifmedia_add(&sc->sc_media, sc->sc_fixed_media, 0, NULL); > + ifmedia_set(&sc->sc_media, sc->sc_fixed_media); > + sc->sc_mii.mii_statchg(self); > + } > > if_attach(ifp); > ether_ifattach(ifp); > @@ -804,7 +836,10 @@ dwge_media_status(struct ifnet *ifp, str > { > struct dwge_softc *sc = ifp->if_softc; > > - if (LIST_FIRST(&sc->sc_mii.mii_phys)) { > + if (sc->sc_fixed_media != 0) { > + ifmr->ifm_active = sc->sc_fixed_media; > + ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; > + } else if (LIST_FIRST(&sc->sc_mii.mii_phys)) { > mii_pollstat(&sc->sc_mii); > ifmr->ifm_active = sc->sc_mii.mii_media_active; > ifmr->ifm_status = sc->sc_mii.mii_media_status; > @@ -858,11 +893,16 @@ dwge_mii_statchg(struct device *self) > { > struct dwge_softc *sc = (void *)self; > uint32_t conf; > + uint64_t media_active; > + > + media_active = sc->sc_fixed_media; > + if (media_active == 0) > + media_active = sc->sc_mii.mii_media_active; > > conf = dwge_read(sc, GMAC_MAC_CONF); > conf &= ~(GMAC_MAC_CONF_PS | GMAC_MAC_CONF_FES); > > - switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { > + switch (IFM_SUBTYPE(media_active)) { > case IFM_1000_SX: > case IFM_1000_LX: > case IFM_1000_CX: > @@ -886,7 +926,7 @@ dwge_mii_statchg(struct device *self) > return; > > conf &= ~GMAC_MAC_CONF_DM; > - if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) > + if ((media_active & IFM_GMASK) == IFM_FDX) > conf |= GMAC_MAC_CONF_DM; > > /* XXX: RX/TX flow control? */ > @@ -1679,6 +1719,7 @@ dwge_mii_statchg_rockchip(struct device > struct regmap *rm; > uint32_t grf; > uint32_t gmac_clk_sel = 0; > + uint64_t media_active; > > dwge_mii_statchg(self); > > @@ -1687,7 +1728,11 @@ dwge_mii_statchg_rockchip(struct device > if (rm == NULL) > return; > > - switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { > + media_active = sc->sc_fixed_media; > + if (media_active == 0) > + media_active = sc->sc_mii.mii_media_active; > + > + switch (IFM_SUBTYPE(media_active)) { > case IFM_10_T: > gmac_clk_sel = sc->sc_clk_sel_2_5; > break; >