svn commit: r362353 - in head/sys: arm64/broadcom/genet dev/mii

Mike Karels karels at FreeBSD.org
Thu Jun 18 23:57:12 UTC 2020


Author: karels
Date: Thu Jun 18 23:57:10 2020
New Revision: 362353
URL: https://svnweb.freebsd.org/changeset/base/362353

Log:
  Add support for bcm54213PE in brgphy.
  
  This chip is used in the Rasperry Pi 4, and is supported by the if_genet
  driver. Currently we use the ukphy mii driver, this patch switches over
  to the brgphy mii driver instead. To support the rgmii-rxid phy mode,
  which is now the default in the Linux dtb, we add support for clock
  skewing.
  
  These changes are taken from OpenBSD and NetBSD, except for the bailout
  in brgphy_bcm54xx_clock_delay() in rgmii mode, which was found necessary
  after testing.
  
  Submitted by:	Robert Crowston, crowston at protomail.com
  Differential Revision:	https://reviews.freebsd.org/D25251

Modified:
  head/sys/arm64/broadcom/genet/if_genet.c
  head/sys/dev/mii/brgphy.c
  head/sys/dev/mii/brgphyreg.h
  head/sys/dev/mii/miidevs
  head/sys/dev/mii/miivar.h

Modified: head/sys/arm64/broadcom/genet/if_genet.c
==============================================================================
--- head/sys/arm64/broadcom/genet/if_genet.c	Thu Jun 18 23:31:56 2020	(r362352)
+++ head/sys/arm64/broadcom/genet/if_genet.c	Thu Jun 18 23:57:10 2020	(r362353)
@@ -237,7 +237,7 @@ gen_attach(device_t dev)
 {
 	struct ether_addr eaddr;
 	struct gen_softc *sc;
-	int major, minor, error;
+	int major, minor, error, mii_flags;
 	bool eaddr_found;
 
 	sc = device_get_softc(dev);
@@ -315,9 +315,24 @@ gen_attach(device_t dev)
 	if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
 
 	/* Attach MII driver */
+	mii_flags = 0;
+	switch (sc->phy_mode)
+	{
+	case MII_CONTYPE_RGMII_ID:
+		mii_flags |= MIIF_RX_DELAY | MIIF_TX_DELAY;
+		break;
+	case MII_CONTYPE_RGMII_RXID:
+		mii_flags |= MIIF_RX_DELAY;
+		break;
+	case MII_CONTYPE_RGMII_TXID:
+		mii_flags |= MIIF_TX_DELAY;
+		break;
+	default:
+		break;
+	}
 	error = mii_attach(dev, &sc->miibus, sc->ifp, gen_media_change,
 	    gen_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY,
-	    MIIF_DOPAUSE);
+	    mii_flags);
 	if (error != 0) {
 		device_printf(dev, "cannot attach PHY\n");
 		goto fail;
@@ -371,6 +386,7 @@ gen_get_phy_mode(device_t dev)
 
 	switch (type) {
 	case MII_CONTYPE_RGMII:
+	case MII_CONTYPE_RGMII_ID:
 	case MII_CONTYPE_RGMII_RXID:
 	case MII_CONTYPE_RGMII_TXID:
 		sc->phy_mode = type;
@@ -791,10 +807,17 @@ gen_init_locked(struct gen_softc *sc)
 	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
 		return;
 
-	if (sc->phy_mode == MII_CONTYPE_RGMII ||
-	    sc->phy_mode == MII_CONTYPE_RGMII_RXID)
-		WR4(sc, GENET_SYS_PORT_CTRL,
-		    GENET_SYS_PORT_MODE_EXT_GPHY);
+	switch (sc->phy_mode)
+	{
+	case MII_CONTYPE_RGMII:
+	case MII_CONTYPE_RGMII_ID:
+	case MII_CONTYPE_RGMII_RXID:
+	case MII_CONTYPE_RGMII_TXID:
+		WR4(sc, GENET_SYS_PORT_CTRL, GENET_SYS_PORT_MODE_EXT_GPHY);
+		break;
+	default:
+		WR4(sc, GENET_SYS_PORT_CTRL, 0);
+	}
 
 	gen_set_enaddr(sc);
 
@@ -1649,6 +1672,8 @@ gen_update_link_locked(struct gen_softc *sc)
 	val |= GENET_EXT_RGMII_OOB_RGMII_MODE_EN;
 	if (sc->phy_mode == MII_CONTYPE_RGMII)
 		val |= GENET_EXT_RGMII_OOB_ID_MODE_DISABLE;
+	else
+		val &= ~GENET_EXT_RGMII_OOB_ID_MODE_DISABLE;
 	WR4(sc, GENET_EXT_RGMII_OOB_CTRL, val);
 
 	val = RD4(sc, GENET_UMAC_CMD);

Modified: head/sys/dev/mii/brgphy.c
==============================================================================
--- head/sys/dev/mii/brgphy.c	Thu Jun 18 23:31:56 2020	(r362352)
+++ head/sys/dev/mii/brgphy.c	Thu Jun 18 23:57:10 2020	(r362353)
@@ -115,6 +115,7 @@ static void	brgphy_fixup_ber_bug(struct mii_softc *);
 static void	brgphy_fixup_crc_bug(struct mii_softc *);
 static void	brgphy_fixup_jitter_bug(struct mii_softc *);
 static void	brgphy_ethernet_wirespeed(struct mii_softc *);
+static void	brgphy_bcm54xx_clock_delay(struct mii_softc *);
 static void	brgphy_jumbo_settings(struct mii_softc *, u_long);
 
 static const struct mii_phydesc brgphys[] = {
@@ -158,6 +159,7 @@ static const struct mii_phydesc brgphys[] = {
 	MII_PHY_DESC(BROADCOM3, BCM5720C),
 	MII_PHY_DESC(BROADCOM3, BCM57765),
 	MII_PHY_DESC(BROADCOM3, BCM57780),
+	MII_PHY_DESC(BROADCOM4, BCM54213PE),
 	MII_PHY_DESC(BROADCOM4, BCM5725C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
 	MII_PHY_END
@@ -414,6 +416,12 @@ brgphy_service(struct mii_softc *sc, struct mii_data *
 				break;
 			}
 			break;
+		case MII_OUI_BROADCOM4:
+			switch (sc->mii_mpd_model) {
+			case MII_MODEL_BROADCOM4_BCM54213PE:
+				brgphy_bcm54xx_clock_delay(sc);
+				break;
+			}
 		}
 	}
 	mii_phy_update(sc, cmd);
@@ -861,6 +869,37 @@ brgphy_ethernet_wirespeed(struct mii_softc *sc)
 	PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7007);
 	val = PHY_READ(sc, BRGPHY_MII_AUXCTL);
 	PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4));
+}
+
+static void
+brgphy_bcm54xx_clock_delay(struct mii_softc *sc)
+{
+	uint16_t val;
+
+	if (!(sc->mii_flags & (MIIF_RX_DELAY | MIIF_TX_DELAY)))
+		/* Adjusting the clocks in rgmii mode causes packet losses. */
+		return;
+
+	PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_SHADOW_MISC |
+	    BRGPHY_AUXCTL_SHADOW_MISC << BRGPHY_AUXCTL_MISC_READ_SHIFT);
+	val = PHY_READ(sc, BRGPHY_MII_AUXCTL);
+	val &= BRGPHY_AUXCTL_MISC_DATA_MASK;
+	if (sc->mii_flags & MIIF_RX_DELAY)
+		val |= BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN;
+	else
+		val &= ~BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN;
+	PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_MISC_WRITE_EN |
+	    BRGPHY_AUXCTL_SHADOW_MISC | val);
+
+	PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_CLK_CTRL);
+	val = PHY_READ(sc, BRGPHY_MII_SHADOW_1C);
+	val &= BRGPHY_SHADOW_1C_DATA_MASK;
+	if (sc->mii_flags & MIIF_TX_DELAY)
+		val |= BRGPHY_SHADOW_1C_GTXCLK_EN;
+	else
+		val &= ~BRGPHY_SHADOW_1C_GTXCLK_EN;
+	PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_WRITE_EN |
+	    BRGPHY_SHADOW_1C_CLK_CTRL | val);
 }
 
 static void

Modified: head/sys/dev/mii/brgphyreg.h
==============================================================================
--- head/sys/dev/mii/brgphyreg.h	Thu Jun 18 23:31:56 2020	(r362352)
+++ head/sys/dev/mii/brgphyreg.h	Thu Jun 18 23:57:10 2020	(r362353)
@@ -293,6 +293,17 @@
 /* Begin: PHY register values for the 5706 PHY         */
 /*******************************************************/
 
+/*
+ * Aux control shadow register, bits 0-2 select function (0x00 to
+ * 0x07).
+ */
+#define	BRGPHY_AUXCTL_SHADOW_MISC	0x07
+#define	BRGPHY_AUXCTL_MISC_DATA_MASK	0x7ff8
+#define	BRGPHY_AUXCTL_MISC_READ_SHIFT	12
+#define	BRGPHY_AUXCTL_MISC_WRITE_EN	0x8000
+#define	BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN 0x0200
+#define	BRGPHY_AUXCTL_MISC_WIRESPEED_EN	0x0010
+
 /* 
  * Shadow register 0x1C, bit 15 is write enable,
  * bits 14-10 select function (0x00 to 0x1F).
@@ -300,6 +311,11 @@
 #define	BRGPHY_MII_SHADOW_1C		0x1C
 #define	BRGPHY_SHADOW_1C_WRITE_EN	0x8000
 #define	BRGPHY_SHADOW_1C_SELECT_MASK	0x7C00
+#define	BRGPHY_SHADOW_1C_DATA_MASK	0x03FF
+
+/* Shadow 0x1C Clock Alignment Control Register (select value 0x03) */
+#define	BRGPHY_SHADOW_1C_CLK_CTRL	(0x03 << 10)
+#define	BRGPHY_SHADOW_1C_GTXCLK_EN	0x0200
 
 /* Shadow 0x1C Mode Control Register (select value 0x1F) */
 #define	BRGPHY_SHADOW_1C_MODE_CTRL	(0x1F << 10)

Modified: head/sys/dev/mii/miidevs
==============================================================================
--- head/sys/dev/mii/miidevs	Thu Jun 18 23:31:56 2020	(r362352)
+++ head/sys/dev/mii/miidevs	Thu Jun 18 23:57:10 2020	(r362353)
@@ -196,6 +196,7 @@ model BROADCOM3 BCM5717C	0x0020 BCM5717C 1000BASE-T me
 model BROADCOM3 BCM5719C	0x0022 BCM5719C 1000BASE-T media interface
 model BROADCOM3 BCM57765	0x0024 BCM57765 1000BASE-T media interface
 model BROADCOM3 BCM5720C	0x0036 BCM5720C 1000BASE-T media interface
+model BROADCOM4 BCM54213PE	0x000a BCM54213PE 1000BASE-T media interface
 model BROADCOM4 BCM5725C	0x0038 BCM5725C 1000BASE-T media interface
 model xxBROADCOM_ALT1 BCM5906	0x0004 BCM5906 10/100baseTX media interface
 

Modified: head/sys/dev/mii/miivar.h
==============================================================================
--- head/sys/dev/mii/miivar.h	Thu Jun 18 23:31:56 2020	(r362352)
+++ head/sys/dev/mii/miivar.h	Thu Jun 18 23:57:10 2020	(r362353)
@@ -134,6 +134,8 @@ typedef struct mii_softc mii_softc_t;
 #define	MIIF_DOPAUSE	0x00000100	/* advertise PAUSE capability */
 #define	MIIF_IS_HPNA	0x00000200	/* is a HomePNA device */
 #define	MIIF_FORCEANEG	0x00000400	/* force auto-negotiation */
+#define	MIIF_RX_DELAY	0x00000800	/* add RX delay */
+#define	MIIF_TX_DELAY	0x00001000	/* add TX delay */
 #define	MIIF_NOMANPAUSE	0x00100000	/* no manual PAUSE selection */
 #define	MIIF_FORCEPAUSE	0x00200000	/* force PAUSE advertisement */
 #define	MIIF_MACPRIV0	0x01000000	/* private to the MAC driver */


More information about the svn-src-head mailing list