> 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 = <&reg_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;
> 

Reply via email to