On the Turris Omnia, the host can't transmit over the interface linked to
the switch unless mvsw applies phy-mode settings to the port on its side,
specifically the rgmii delay settings.

ok?


Index: mvsw.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/mvsw.c,v
retrieving revision 1.5
diff -u -p -r1.5 mvsw.c
--- mvsw.c      6 Apr 2022 18:59:28 -0000       1.5
+++ mvsw.c      9 Apr 2023 04:19:21 -0000
@@ -52,6 +52,10 @@
 #define MVSW_PORT(x)                   (0x10 + (x))
 #define MVSW_G2                                0x1c
 
+#define MVSW_PORT_MAC_CTL              0x01
+#define  MVSW_PORT_MAC_CTL_RGMII_RXID  0x8000
+#define  MVSW_PORT_MAC_CTL_RGMII_TXID  0x4000
+#define  MVSW_PORT_MAC_CTL_RGMII_MASK  0xc000
 #define MVSW_PORT_SWITCHID             0x03
 #define  MVSW_PORT_SWITCHID_PROD_MASK  0xfff0
 #define  MVSW_PORT_SWITCHID_PROD_88E6141 0x3400
@@ -70,6 +74,17 @@
 /* XXX #include <dev/mii/mdio.h> */
 #define MDIO_MMD_PHYXS         4
 
+const struct {
+        const char      *name;
+        uint16_t        mac_ctl;
+} mvsw_phy_modes[] = {
+        { "rgmii",      0 },
+        { "rgmii-id",   MVSW_PORT_MAC_CTL_RGMII_TXID |
+                        MVSW_PORT_MAC_CTL_RGMII_RXID },
+        { "rgmii-rxid", MVSW_PORT_MAC_CTL_RGMII_RXID },
+        { "rgmii-txid", MVSW_PORT_MAC_CTL_RGMII_TXID }
+};
+
 struct mvsw_softc {
        struct device   sc_dev;
 
@@ -310,12 +325,27 @@ mvsw_serdes_write(struct mvsw_softc *sc,
 void
 mvsw_port_enable(struct mvsw_softc *sc, int node)
 {
+       char phy_mode[16] = { 0 };
        uint16_t val;
-       int port;
+       int port, i;
 
        port = OF_getpropint(node, "reg", -1);
        if (port == -1)
                return;
+
+       OF_getprop(node, "phy-mode", phy_mode, sizeof(phy_mode));
+       for (i = 0; i < nitems(mvsw_phy_modes); i++) {
+               if (strcmp(phy_mode, mvsw_phy_modes[i].name) == 0) {
+                       val = mvsw_smi_read(sc, MVSW_PORT(port),
+                           MVSW_PORT_MAC_CTL);
+                       val &= ~MVSW_PORT_MAC_CTL_RGMII_MASK;
+                       val |= mvsw_phy_modes[i].mac_ctl;
+                       mvsw_smi_write(sc, MVSW_PORT(port),
+                           MVSW_PORT_MAC_CTL, val);
+
+                       break;
+               }
+       }
 
        /* Enable port. */
        val = mvsw_smi_read(sc, MVSW_PORT(port), MVSW_PORT_CTRL);

Reply via email to