assume RGMII-to-Copper mode by default in eephy(4) for 88E151x PHYs
authoruwe <uwe@openbsd.org>
Thu, 28 Dec 2023 14:03:21 +0000 (14:03 +0000)
committeruwe <uwe@openbsd.org>
Thu, 28 Dec 2023 14:03:21 +0000 (14:03 +0000)
The desired MII mode must be programmed explicitly for Marvel Atlantis
88E1512/88E1514 variants and we already do this for SGMII.

This change adds a missing case for RGMII-to-Copper that assumes RGMII,
unless the MAC driver sets MII_SGMII before calling mii_attach() or the
mode has already been programmed. (RGMII-to-Copper is also the hardware
default for E1510 and E1518.)

Suggestions and ok kettenis@

sys/dev/mii/eephy.c
sys/dev/mii/eephyreg.h

index ca68e05..049edb9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eephy.c,v 1.62 2023/12/07 09:46:58 uwe Exp $  */
+/*     $OpenBSD: eephy.c,v 1.63 2023/12/28 14:03:21 uwe Exp $  */
 /*
  * Principal Author: Parag Patel
  * Copyright (c) 2001
@@ -188,16 +188,28 @@ eephy_attach(struct device *parent, struct device *self, void *aux)
                PHY_WRITE(sc, E1000_EADR, page);
        }
 
-       /* Switch to SGMII-to-copper mode if necessary. */
-       if (sc->mii_model == MII_MODEL_MARVELL_E1512 &&
-           sc->mii_flags & MIIF_SGMII) {
+       /*
+        * GCR1 MII mode defaults to an invalid value on E1512/E1514
+        * and must be programmed with the desired mode of operation.
+        */
+       if (sc->mii_model == MII_MODEL_MARVELL_E1512) {
+               uint32_t mode;
+
                page = PHY_READ(sc, E1000_EADR);
                PHY_WRITE(sc, E1000_EADR, 18);
+
                reg = PHY_READ(sc, E1000_GCR1);
+               mode = reg & E1000_GCR1_MODE_MASK;
+
+               if (mode == E1000_GCR1_MODE_UNSET)
+                       mode = E1000_GCR1_MODE_RGMII;
+               if (sc->mii_flags & MIIF_SGMII)
+                       mode = E1000_GCR1_MODE_SGMII;
+
                reg &= ~E1000_GCR1_MODE_MASK;
-               reg |= E1000_GCR1_MODE_SGMII;
-               reg |= E1000_GCR1_RESET;
+               reg |= E1000_GCR1_RESET | mode;
                PHY_WRITE(sc, E1000_GCR1, reg);
+
                PHY_WRITE(sc, E1000_EADR, page);
        }
 
index 593127a..4113791 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eephyreg.h,v 1.10 2023/12/07 09:46:58 uwe Exp $       */
+/*     $OpenBSD: eephyreg.h,v 1.11 2023/12/28 14:03:21 uwe Exp $       */
 /*
  * Principal Author: Parag Patel
  * Copyright (c) 2001
 #define E1000_GCR1                     0x14    /* General Control Register 1 */
 #define E1000_GCR1_RESET               0x8000
 #define E1000_GCR1_MODE_MASK           0x0007
+#define E1000_GCR1_MODE_RGMII          0x0000
 #define E1000_GCR1_MODE_SGMII          0x0001
+#define E1000_GCR1_MODE_RGMII_1000X    0x0002
+#define E1000_GCR1_MODE_RGMII_100FX    0x0003
+#define E1000_GCR1_MODE_RGMII_TO_SGMII 0x0004
+#define E1000_GCR1_MODE_UNSET          0x0007