Download raw body.
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
support Marvell 88E151x RGMII delay timing modes in eephy(4)