> Date: Wed, 5 Jul 2023 12:46:36 +0300
> From: Jonathan Matthew <[email protected]>
>
> 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;
>