svn commit: r291676 - head/sys/dev/mii

Pyun YongHyeon yongari at FreeBSD.org
Thu Dec 3 05:27:40 UTC 2015


Author: yongari
Date: Thu Dec  3 05:27:39 2015
New Revision: 291676
URL: https://svnweb.freebsd.org/changeset/base/291676

Log:
  Disable EEE(Energy Efficient Ethernet) for RTL8211F PHY.
  It seems the EEE made RX MAC enter LPI(Low Power Idle) mode such
  that dwc(4) was not able to receive packets.  Ideally dwc(4) should
  be able to use EEE to save power during periods of low link
  utilization(i.e. gating off clock).  Due to lack of dwc(4)
  datasheet it's not easy to take required steps for EEE on LPI
  enter/exit events.  Disabling EEE in PHY seems to be easy
  workaround until dwc(4) supports EEE.
  
  Updating EEE advertisement register on RTL8211F seems to have no
  effect until reprogramming MII_ANAR, MII_100T2CR and MII_BMCR
  with auto-negotiation. It's not clear whether it's related with
  mii_phy_reset()'s BMCR_ISO handling for RTL8211F though.
  It seems rgephy_reset() needs careful investigation for newer
  RealTek PHYs.
  
  Ganbold submitted working version based on NetBSD change and
  tested lots of changes I made. Thanks a lot!
  
  Submitted by:	ganbold (initial version)
  In collaboration with:	ganbold

Modified:
  head/sys/dev/mii/rgephy.c
  head/sys/dev/mii/rgephyreg.h

Modified: head/sys/dev/mii/rgephy.c
==============================================================================
--- head/sys/dev/mii/rgephy.c	Thu Dec  3 04:35:44 2015	(r291675)
+++ head/sys/dev/mii/rgephy.c	Thu Dec  3 05:27:39 2015	(r291676)
@@ -90,6 +90,7 @@ static void	rgephy_reset(struct mii_soft
 static int	rgephy_linkup(struct mii_softc *);
 static void	rgephy_loop(struct mii_softc *);
 static void	rgephy_load_dspcode(struct mii_softc *);
+static void	rgephy_disable_eee(struct mii_softc *);
 
 static const struct mii_phydesc rgephys[] = {
 	MII_PHY_DESC(REALTEK, RTL8169S),
@@ -517,10 +518,9 @@ rgephy_reset(struct mii_softc *sc)
 	switch (sc->mii_mpd_rev) {
 	case RGEPHY_8211F:
 		pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1);
-		if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) {
-			pcr &= ~RGEPHY_F_PCR1_MDI_MM;
-			PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
-		}
+		pcr &= ~(RGEPHY_F_PCR1_MDI_MM | RGEPHY_F_PCR1_ALDPS_EN);
+		PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
+		rgephy_disable_eee(sc);
 		break;
 	case RGEPHY_8211C:
 		if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
@@ -548,3 +548,29 @@ rgephy_reset(struct mii_softc *sc)
 	DELAY(1000);
 	rgephy_load_dspcode(sc);
 }
+
+static void
+rgephy_disable_eee(struct mii_softc *sc)
+{
+	uint16_t anar;
+
+	PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000);
+	PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS |
+	    (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
+	PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR);
+	PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI |
+	    (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
+	PHY_WRITE(sc, MII_MMDAADR, 0x0000);
+	PHY_WRITE(sc, MII_MMDACR, 0x0000);
+	/*
+	 * XXX
+	 * Restart auto-negotiation to take changes effect.
+	 * This may result in link establishment.
+	 */
+	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
+	PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
+	PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD |
+	    RGEPHY_1000CTL_AFD);
+	PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET |
+	    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
+}

Modified: head/sys/dev/mii/rgephyreg.h
==============================================================================
--- head/sys/dev/mii/rgephyreg.h	Thu Dec  3 04:35:44 2015	(r291675)
+++ head/sys/dev/mii/rgephyreg.h	Thu Dec  3 05:27:39 2015	(r291676)
@@ -183,4 +183,20 @@
 #define	RGEPHY_F_SSR_MDI	0x0002	/* MDI/MDIX */
 #define	RGEPHY_F_SSR_JABBER	0x0001	/* Jabber */
 
+/* RTL8211F */
+#define	RGEPHY_F_EPAGSR		0x1F	/* Extension page select register */
+
+/* RTL8211F */
+#define	RGEPHY_F_MMD_DEV_7	0x07
+
+/* RTL8211F MMD device 7 */
+#define	RGEPHY_F_MMD_EEEAR	0x3C	/* EEE advertisement */
+#define	EEEAR_1000T		0x0004	/* adv. 1000baseT EEE */
+#define	EEEAR_100TX		0x0002	/* adv. 100baseTX EEE */
+
+/* RTL8211F MMD device 7 */
+#define	RGEPHY_F_MMD_EEELPAR	0x3D	/* EEE link partner abilities */
+#define	EEELPAR_1000T		0x0004	/* link partner 1000baseT EEE capable */
+#define	EEELPAR_100TX		0x0002	/* link partner 100baseTX EEE capable */
+
 #endif /* _DEV_RGEPHY_MIIREG_H_ */


More information about the svn-src-head mailing list