Am 01.06.22 um 14:50 schrieb Gedare Bloom:
Should this be upstreamed?

I don't think so. The solution is quite device specific and has some restrictions like the right initialization order (like noted in the commit description). I don't think that FreeBSD will accept it.

I have seen some discussions on FreeBSD that they think about a more generic approach. Basically that would make it necessary to split the MDIO part from the remaining Ethernet controller part and make it a separate driver. That would most likely make it necessary to change multiple or all Ethernet drivers. I assume that some-when someone at FreeBSD will add a solution like that. But till then, I think the slightly hacked solution that I did with this patch should work well enough for us.


On Mon, May 23, 2022 at 6:22 AM Christian Mauderer
<christian.maude...@embedded-brains.de> wrote:

The i.MX6UL (and some others from the i.MX family) have shared MDIO
lines for multiple FFECs. This patch allows to use the MDIO interface
from another Ethernet controller.

Note that you have to make sure that the FFECs are initialized in the
right order. Normally that can be done via FDT.
---
  freebsd/sys/dev/ffec/if_ffec.c | 120 +++++++++++++++++++++++++++++++++
  1 file changed, 120 insertions(+)

diff --git a/freebsd/sys/dev/ffec/if_ffec.c b/freebsd/sys/dev/ffec/if_ffec.c
index 4c1e147b..316e077c 100644
--- a/freebsd/sys/dev/ffec/if_ffec.c
+++ b/freebsd/sys/dev/ffec/if_ffec.c
@@ -209,6 +209,11 @@ struct ffec_softc {
         int             rx_ic_count;    /* RW, valid values 0..255 */
         int             tx_ic_time;
         int             tx_ic_count;
+#ifdef __rtems__
+
+       device_t                mdio_device;
+       struct mtx              mdio_mtx;
+#endif /* __rtems__ */
  };

  static struct resource_spec irq_res_spec[MAX_IRQ_COUNT + 1] = {
@@ -376,6 +381,13 @@ ffec_miibus_readreg(device_t dev, int phy, int reg)
         int val;

         sc = device_get_softc(dev);
+#ifdef __rtems__
+       if (sc->mdio_device) {
+               return (MIIBUS_READREG(sc->mdio_device, phy, reg));
+       }
+
+       mtx_lock(&sc->mdio_mtx);
+#endif /* __rtems__ */

         WR4(sc, FEC_IER_REG, FEC_IER_MII);

@@ -386,11 +398,17 @@ ffec_miibus_readreg(device_t dev, int phy, int reg)

         if (!ffec_miibus_iowait(sc)) {
                 device_printf(dev, "timeout waiting for mii read\n");
+#ifdef __rtems__
+               mtx_unlock(&sc->mdio_mtx);
+#endif /* __rtems__ */
                 return (-1); /* All-ones is a symptom of bad mdio. */
         }

         val = RD4(sc, FEC_MMFR_REG) & FEC_MMFR_DATA_MASK;

+#ifdef __rtems__
+       mtx_unlock(&sc->mdio_mtx);
+#endif /* __rtems__ */
         return (val);
  }

@@ -400,6 +418,13 @@ ffec_miibus_writereg(device_t dev, int phy, int reg, int 
val)
         struct ffec_softc *sc;

         sc = device_get_softc(dev);
+#ifdef __rtems__
+       if (sc->mdio_device) {
+               return (MIIBUS_WRITEREG(sc->mdio_device, phy, reg, val));
+       }
+
+       mtx_lock(&sc->mdio_mtx);
+#endif /* __rtems__ */

         WR4(sc, FEC_IER_REG, FEC_IER_MII);

@@ -411,9 +436,15 @@ ffec_miibus_writereg(device_t dev, int phy, int reg, int 
val)

         if (!ffec_miibus_iowait(sc)) {
                 device_printf(dev, "timeout waiting for mii write\n");
+#ifdef __rtems__
+               mtx_unlock(&sc->mdio_mtx);
+#endif /* __rtems__ */
                 return (-1);
         }

+#ifdef __rtems__
+       mtx_unlock(&sc->mdio_mtx);
+#endif /* __rtems__ */
         return (0);
  }

@@ -1577,6 +1608,9 @@ ffec_detach(device_t dev)
         if (sc->mem_res != NULL)
                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);

+#ifdef __rtems__
+       mtx_destroy(&sc->mtx);
+#endif /* __rtems__ */
         FFEC_LOCK_DESTROY(sc);
         return (0);
  }
@@ -1726,6 +1760,80 @@ ffec_set_txic(struct ffec_softc *sc)
         ffec_set_ic(sc, FEC_TXIC0_REG, sc->tx_ic_count, sc->tx_ic_time);
  }

+#ifdef __rtems__
+int
+ffec_get_phy_information(
+       struct ffec_softc *sc,
+       phandle_t node,
+       device_t dev,
+       int *phy_addr
+)
+{
+       phandle_t phy_node;
+       phandle_t parent_node;
+       pcell_t phy_handle, phy_reg;
+       device_t other;
+       phandle_t xref;
+
+       /* Search for the phy-handle and get the address */
+
+       if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
+           sizeof(phy_handle)) <= 0)
+               return (ENXIO);
+
+       phy_node = OF_node_from_xref(phy_handle);
+
+       if (OF_getencprop(phy_node, "reg", (void *)&phy_reg,
+           sizeof(phy_reg)) <= 0)
+               return (ENXIO);
+
+       *phy_addr = phy_reg;
+
+       /* Detect whether PHY handle is connected to this or another FFEC. */
+       parent_node = phy_node;
+
+       while (parent_node != 0) {
+               if (parent_node == node) {
+                       /* PHY is directly connected. That's easy. */
+                       sc->mdio_device = NULL;
+                       return 0;
+               }
+
+               /*
+                * Check whether the node is also an Ethernet controller. Do
+                * that by just assuming that every Ethernet controller has a
+                * PHY attached to it.
+                */
+               if (OF_getencprop(parent_node, "phy-handle",
+                   (void *)&phy_handle, sizeof(phy_handle)) > 0) {
+                       /*
+                        * Try to find the device of the other Ethernet
+                        * controller and use that for MDIO communication.
+                        * Note: This is not really a nice workaround but it
+                        * works.
+                        */
+                       xref = OF_xref_from_node(parent_node);
+                       if (xref == 0) {
+                               device_printf(dev,
+                                   "Couldn't get device that handles PHY\n");
+                               return (ENXIO);
+                       }
+                       other = OF_device_from_xref(xref);
+                       if (other == 0) {
+                               device_printf(dev,
+                                   "Couldn't get device that handles PHY\n");
+                               return (ENXIO);
+                       }
+                       sc->mdio_device = other;
+                       return 0;
+               }
+
+               parent_node = OF_parent(parent_node);
+       }
+       return (ENXIO);
+}
+
+#endif /* __rtems__ */
  static int
  ffec_attach(device_t dev)
  {
@@ -1743,6 +1851,10 @@ ffec_attach(device_t dev)
         sc->dev = dev;

         FFEC_LOCK_INIT(sc);
+#ifdef __rtems__
+       mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
+           MTX_NETWORK_LOCK, MTX_DEF);
+#endif /* __rtems__ */

         /*
          * There are differences in the implementation and features of the FEC
@@ -2047,9 +2159,17 @@ ffec_attach(device_t dev)
         ffec_miigasket_setup(sc);

         /* Attach the mii driver. */
+#ifdef __rtems__
+       OF_device_register_xref(OF_xref_from_node(ofw_node), dev);
+       if (ffec_get_phy_information(sc, ofw_node, dev, &phynum) != 0) {
+               phynum = MII_PHY_ANY;
+       }
+       (void) dummy;
+#else /* __rtems__ */
         if (fdt_get_phyaddr(ofw_node, dev, &phynum, &dummy) != 0) {
                 phynum = MII_PHY_ANY;
         }
+#endif /* __rtems__ */
         error = mii_attach(dev, &sc->miibus, ifp, ffec_media_change,
             ffec_media_status, BMSR_DEFCAPMASK, phynum, MII_OFFSET_ANY,
             (sc->fecflags & FECTYPE_MVF) ? MIIF_FORCEANEG : 0);
--
2.35.3

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

--
--------------------------------------------
embedded brains GmbH
Herr Christian MAUDERER
Dornierstr. 4
82178 Puchheim
Germany
email: christian.maude...@embedded-brains.de
phone: +49-89-18 94 741 - 18
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to