Index | Thread | Search

From:
Uwe Stuehler <ustuehler@growit.io>
Subject:
support Marvell 88E151x RGMII delay timing modes in eephy(4)
To:
tech@openbsd.org
Date:
Thu, 11 Jan 2024 14:22:41 +0100

Download raw body.

Thread
  • Uwe Stuehler:

    support Marvell 88E151x RGMII delay timing modes in eephy(4)

The following change, originally from stsp@, adds initial support for
platforms which require Rx and/or Tx delays between MAC and PHY in RGMII
mode (as per section "2.4.2 RGMII" in the datasheet.)

I don't have access to a platform which requires this but I tested it on
an Intel Elkhart Lake machine though where it had no effect.

Does anyone know a platform which needs this, or should this go in as an
improvement anyway?

---
 sys/dev/mii/eephy.c    | 44 +++++++++++++++++++++++++++++++++++++-----
 sys/dev/mii/eephyreg.h |  7 +++++++
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/sys/dev/mii/eephy.c b/sys/dev/mii/eephy.c
index 049edb92021..c99bac094dd 100644
--- a/sys/dev/mii/eephy.c
+++ b/sys/dev/mii/eephy.c
@@ -57,6 +57,7 @@
 
 int	eephy_match(struct device *, void *, void *);
 void	eephy_attach(struct device *, struct device *, void *);
+int	eephy_set_delay(struct mii_softc *);
 
 const struct cfattach eephy_ca = {
 	sizeof (struct mii_softc), eephy_match, eephy_attach, mii_phy_detach
@@ -213,6 +214,8 @@ eephy_attach(struct device *parent, struct device *self, void *aux)
 		PHY_WRITE(sc, E1000_EADR, page);
 	}
 
+	eephy_set_delay(sc);
+
 	PHY_RESET(sc);
 
 	sc->mii_capabilities = PHY_READ(sc, E1000_SR) & ma->mii_capmask;
@@ -315,6 +318,11 @@ eephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 {
 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
 	int bmcr;
+	/*
+	 * If autonegotiation is not enabled, we need a
+	 * software reset for the settings to take effect.
+	 */
+	int sw_reset = (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO);
 
 	if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0)
 		return (ENXIO);
@@ -347,11 +355,10 @@ eephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 
 		mii_phy_setmedia(sc);
 
-		/*
-		 * If autonegotiation is not enabled, we need a
-		 * software reset for the settings to take effect.
-		 */
-		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
+		if (eephy_set_delay(sc))
+			sw_reset = 1;
+
+		if (sw_reset) {
 			bmcr = PHY_READ(sc, E1000_CR);
 			PHY_WRITE(sc, E1000_CR, bmcr | E1000_CR_RESET);
 		}
@@ -381,6 +388,33 @@ eephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 	return (0);
 }
 
+int
+eephy_set_delay(struct mii_softc *sc)
+{
+	if (sc->mii_model == MII_MODEL_MARVELL_E1512 &&
+	    (sc->mii_flags & MIIF_SETDELAY)) {
+		int page, reg;
+
+		page = PHY_READ(sc, E1000_EADR);
+		PHY_WRITE(sc, E1000_EADR, 2);
+
+		reg = PHY_READ(sc, E1000_MSCR2);
+		reg &= ~E1000_MSCR2_DELAY_MASK;
+		if (sc->mii_flags & MIIF_RXID)
+			reg |= E1000_MSCR2_RXDELAY;
+		if (sc->mii_flags & MIIF_TXID)
+			reg |= E1000_MSCR2_TXDELAY;
+
+		PHY_WRITE(sc, E1000_MSCR2, reg);
+		PHY_WRITE(sc, E1000_EADR, page);
+
+		/* Indicate software reset needed. */
+		return 1;
+	}
+
+	return 0;
+}
+
 void
 eephy_status(struct mii_softc *sc)
 {
diff --git a/sys/dev/mii/eephyreg.h b/sys/dev/mii/eephyreg.h
index 4113791be61..7ac33885e27 100644
--- a/sys/dev/mii/eephyreg.h
+++ b/sys/dev/mii/eephyreg.h
@@ -337,3 +337,10 @@
 #define E1000_GCR1_MODE_RGMII_100FX	0x0003
 #define E1000_GCR1_MODE_RGMII_TO_SGMII	0x0004
 #define E1000_GCR1_MODE_UNSET		0x0007
+
+/* The following register is found only on the 88E151x Alaska PHY */
+/* Page 2 */
+#define E1000_MSCR2		0x15	/* MAC-Specific Control Register 2 */
+#define E1000_MSCR2_RXDELAY	0x20
+#define E1000_MSCR2_TXDELAY	0x10
+#define E1000_MSCR2_DELAY_MASK	0x30
-- 
2.43.0