Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Nov 2010 20:45:49 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r215882 - stable/8/sys/dev/mii
Message-ID:  <201011262045.oAQKjn8v075889@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Fri Nov 26 20:45:49 2010
New Revision: 215882
URL: http://svn.freebsd.org/changeset/base/215882

Log:
  MFC: r215298, r215459, r215714, r215716
  
  - Change these drivers to take advantage and use the generic IEEE 802.3
    annex 31B full duplex flow control as well as the IFM_1000_T master
    support committed in r215297 (merged to stable/8 in r215881). For
    atphy(4) and jmphy(4) this includes changing these PHY drivers to no
    longer unconditionally advertise support for flow control but only if
    the selected media has IFM_FLOW set (or MIIF_FORCEPAUSE is set).
  - Rename {atphy,jmphy}_auto() to {atphy,jmphy}_setmedia() as these handle
    other media types as well.
  
  Reviewed by:	yongari (plus additional testing)
  Obtained from:	NetBSD (partially), OpenBSD (partially)

Modified:
  stable/8/sys/dev/mii/atphy.c
  stable/8/sys/dev/mii/bmtphy.c
  stable/8/sys/dev/mii/gentbi.c
  stable/8/sys/dev/mii/inphy.c
  stable/8/sys/dev/mii/jmphy.c
  stable/8/sys/dev/mii/nsgphy.c
  stable/8/sys/dev/mii/nsphyter.c
  stable/8/sys/dev/mii/rgephy.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/mii/atphy.c
==============================================================================
--- stable/8/sys/dev/mii/atphy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/atphy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -82,7 +82,7 @@ static int	atphy_service(struct mii_soft
 static void	atphy_status(struct mii_softc *);
 static void	atphy_reset(struct mii_softc *);
 static uint16_t	atphy_anar(struct ifmedia_entry *);
-static int	atphy_auto(struct mii_softc *);
+static int	atphy_setmedia(struct mii_softc *, int);
 
 static const struct mii_phydesc atphys[] = {
 	MII_PHY_DESC(ATHEROS, F1),
@@ -158,7 +158,7 @@ atphy_service(struct mii_softc *sc, stru
 
 		if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO ||
 		    IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
-			atphy_auto(sc);
+			atphy_setmedia(sc, ife->ifm_media);
 			break;
 		}
 
@@ -175,7 +175,7 @@ atphy_service(struct mii_softc *sc, stru
 			/*
 			 * XXX
 			 * Due to an unknown reason powering down PHY resulted
-			 * in unexpected results such as inaccessbility of
+			 * in unexpected results such as inaccessibility of
 			 * hardware of freshly rebooted system. Disable
 			 * powering down PHY until I got more information for
 			 * Attansic/Atheros PHY hardwares.
@@ -189,8 +189,9 @@ atphy_service(struct mii_softc *sc, stru
 		anar = atphy_anar(ife);
 		if (((ife->ifm_media & IFM_GMASK) & IFM_FDX) != 0) {
 			bmcr |= BMCR_FDX;
-			/* Enable pause. */
-			anar |= (3 << 10);
+			if (((ife->ifm_media & IFM_GMASK) & IFM_FLOW) != 0 ||
+			    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
+				anar |= ANAR_PAUSE_TOWARDS;
 		}
 
 		if ((sc->mii_extcapabilities & (EXTSR_1000TFDX |
@@ -222,7 +223,7 @@ done:
 		}
 
 		/*
-		 * check for link.
+		 * Check for link.
 		 * Read the status register twice; BMSR_LINK is latch-low.
 		 */
 		bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
@@ -238,7 +239,7 @@ done:
 			return (0);
 
 		sc->mii_ticks = 0;
-		atphy_auto(sc);
+		atphy_setmedia(sc, ife->ifm_media);
 		break;
 	}
 
@@ -284,7 +285,7 @@ atphy_status(struct mii_softc *sc)
 	case ATPHY_SSR_1000MBS:
 		mii->mii_media_active |= IFM_1000_T;
 		/*
-		 * atphy(4) got a valid link so reset mii_ticks.
+		 * atphy(4) has a valid link so reset mii_ticks.
 		 * Resetting mii_ticks is needed in order to
 		 * detect link loss after auto-negotiation.
 		 */
@@ -304,16 +305,19 @@ atphy_status(struct mii_softc *sc)
 	}
 
 	if ((ssr & ATPHY_SSR_DUPLEX) != 0)
-		mii->mii_media_active |= IFM_FDX;
+		mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc);
 	else
 		mii->mii_media_active |= IFM_HDX;
 		
-	/* XXX Master/Slave, Flow-control */
+	if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) &&
+	    (PHY_READ(sc, MII_100T2SR) & GTSR_MS_RES) != 0)
+		mii->mii_media_active |= IFM_ETH_MASTER;
 }
 
 static void
 atphy_reset(struct mii_softc *sc)
 {
+	struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur;
 	struct atphy_softc *asc;
 	uint32_t reg;
 	int i;
@@ -336,7 +340,7 @@ atphy_reset(struct mii_softc *sc)
 	PHY_WRITE(sc, ATPHY_SCR, reg);
 
 	/* Workaround F1 bug to reset phy. */
-	atphy_auto(sc);
+	atphy_setmedia(sc, ife == NULL ? IFM_AUTO : ife->ifm_media);
 
 	for (i = 0; i < 1000; i++) {
 		DELAY(1);
@@ -378,12 +382,17 @@ atphy_anar(struct ifmedia_entry *ife)
 }
 
 static int
-atphy_auto(struct mii_softc *sc)
+atphy_setmedia(struct mii_softc *sc, int media)
 {
 	uint16_t anar;
 
-	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities);
-	PHY_WRITE(sc, MII_ANAR, anar | (3 << 10) | ANAR_CSMA);
+	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
+	if (((IFM_SUBTYPE(media) == IFM_AUTO ||
+	    ((media & IFM_GMASK) & IFM_FDX) != 0) &&
+	    ((media & IFM_GMASK) & IFM_FLOW) != 0) ||
+	    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
+		anar |= ANAR_PAUSE_TOWARDS;
+	PHY_WRITE(sc, MII_ANAR, anar);
 	if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
 		PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX |
 		    GTCR_ADV_1000THDX);

Modified: stable/8/sys/dev/mii/bmtphy.c
==============================================================================
--- stable/8/sys/dev/mii/bmtphy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/bmtphy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -153,6 +153,8 @@ bmtphy_attach(device_t dev)
 	sc->mii_service = bmtphy_service;
 	sc->mii_pdata = mii;
 
+	sc->mii_flags |= MIIF_NOMANPAUSE;
+
 	mii_phy_reset(sc);
 
 	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
@@ -243,7 +245,8 @@ bmtphy_status(struct mii_softc *sc)
 		else
 			mii->mii_media_active |= IFM_10_T;
 		if (aux_csr & AUX_CSR_FDX)
-			mii->mii_media_active |= IFM_FDX;
+			mii->mii_media_active |=
+			    IFM_FDX | mii_phy_flowstatus(sc);
 		else
 			mii->mii_media_active |= IFM_HDX;
 	} else

Modified: stable/8/sys/dev/mii/gentbi.c
==============================================================================
--- stable/8/sys/dev/mii/gentbi.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/gentbi.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -172,6 +172,8 @@ gentbi_attach(device_t dev)
 	sc->mii_service = gentbi_service;
 	sc->mii_pdata = mii;
 
+	sc->mii_flags |= MIIF_NOMANPAUSE;
+
 	mii_phy_reset(sc);
 
 	/*
@@ -267,7 +269,8 @@ gentbi_status(struct mii_softc *sc)
 		anlpar = PHY_READ(sc, MII_ANLPAR);
 		if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0 &&
 		    (anlpar & ANLPAR_X_FD) != 0)
-			mii->mii_media_active |= IFM_FDX;
+			mii->mii_media_active |=
+			    IFM_FDX | mii_phy_flowstatus(sc);
 		else
 			mii->mii_media_active |= IFM_HDX;
 	} else

Modified: stable/8/sys/dev/mii/inphy.c
==============================================================================
--- stable/8/sys/dev/mii/inphy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/inphy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -113,6 +113,8 @@ inphy_attach(device_t dev)
 	sc->mii_service = inphy_service;
 	sc->mii_pdata = mii;
 
+	sc->mii_flags |= MIIF_NOMANPAUSE;
+
 	ifmedia_add(&mii->mii_media,
 	    IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
 	    MII_MEDIA_100_TX, NULL);
@@ -197,7 +199,8 @@ inphy_status(struct mii_softc *sc)
 		else
 			mii->mii_media_active |= IFM_10_T;
 		if (scr & SCR_FDX)
-			mii->mii_media_active |= IFM_FDX;
+			mii->mii_media_active |=
+			    IFM_FDX | mii_phy_flowstatus(sc);
 		else
 			mii->mii_media_active |= IFM_HDX;
 	} else

Modified: stable/8/sys/dev/mii/jmphy.c
==============================================================================
--- stable/8/sys/dev/mii/jmphy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/jmphy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -50,11 +50,11 @@ __FBSDID("$FreeBSD$");
 
 #include "miibus_if.h"
 
-static int 	jmphy_probe(device_t);
-static int 	jmphy_attach(device_t);
+static int	jmphy_probe(device_t);
+static int	jmphy_attach(device_t);
 static void	jmphy_reset(struct mii_softc *);
 static uint16_t	jmphy_anar(struct ifmedia_entry *);
-static int	jmphy_auto(struct mii_softc *, struct ifmedia_entry *);
+static int	jmphy_setmedia(struct mii_softc *, struct ifmedia_entry *);
 
 struct jmphy_softc {
 	struct mii_softc mii_sc;
@@ -154,7 +154,7 @@ jmphy_service(struct mii_softc *sc, stru
 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
 			break;
 
-		if (jmphy_auto(sc, ife) != EJUSTRETURN)
+		if (jmphy_setmedia(sc, ife) != EJUSTRETURN)
 			return (EINVAL);
 		break;
 
@@ -186,7 +186,7 @@ jmphy_service(struct mii_softc *sc, stru
 			return (0);
 
 		sc->mii_ticks = 0;
-		jmphy_auto(sc, ife);
+		(void)jmphy_setmedia(sc, ife);
 		break;
 	}
 
@@ -251,16 +251,14 @@ jmphy_status(struct mii_softc *sc)
 	}
 
 	if ((ssr & JMPHY_SSR_DUPLEX) != 0)
-		mii->mii_media_active |= IFM_FDX;
+		mii->mii_media_active |= IFM_FDX | mii_phy_flowstatus(sc);
 	else
 		mii->mii_media_active |= IFM_HDX;
-	/* XXX Flow-control. */
-#ifdef notyet
+
 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
 		if ((PHY_READ(sc, MII_100T2SR) & GTSR_MS_RES) != 0)
 			mii->mii_media_active |= IFM_ETH_MASTER;
 	}
-#endif
 }
 
 static void
@@ -309,7 +307,7 @@ jmphy_anar(struct ifmedia_entry *ife)
 }
 
 static int
-jmphy_auto(struct mii_softc *sc, struct ifmedia_entry *ife)
+jmphy_setmedia(struct mii_softc *sc, struct ifmedia_entry *ife)
 {
 	uint16_t anar, bmcr, gig;
 
@@ -336,17 +334,18 @@ jmphy_auto(struct mii_softc *sc, struct 
 		bmcr |= BMCR_LOOP;
 
 	anar = jmphy_anar(ife);
-	/* XXX Always advertise pause capability. */
-	anar |= (3 << 10);
+	if (((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO ||
+	    (ife->ifm_media & IFM_FDX) != 0) &&
+	    (ife->ifm_media & IFM_FLOW) != 0) ||
+	    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
+		anar |= ANAR_PAUSE_TOWARDS;
 
 	if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) {
-#ifdef notyet
-		struct mii_data *mii;
-
-		mii = sc->mii_pdata;
-		if ((mii->mii_media.ifm_media & IFM_ETH_MASTER) != 0)
-			gig |= GTCR_MAN_MS | GTCR_MAN_ADV;
-#endif
+		if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
+			gig |= GTCR_MAN_MS;
+			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
+				gig |= GTCR_ADV_MS;
+		}
 		PHY_WRITE(sc, MII_100T2CR, gig);
 	}
 	PHY_WRITE(sc, MII_ANAR, anar | ANAR_CSMA);

Modified: stable/8/sys/dev/mii/nsgphy.c
==============================================================================
--- stable/8/sys/dev/mii/nsgphy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/nsgphy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -135,6 +135,8 @@ nsgphy_attach(device_t dev)
 	sc->mii_service = nsgphy_service;
 	sc->mii_pdata = mii;
 
+	sc->mii_flags |= MIIF_NOMANPAUSE;
+
 	mii_phy_reset(sc);
 
 	/*
@@ -246,7 +248,8 @@ nsgphy_status(struct mii_softc *sc)
 		}
 
 		if (physup & PHY_SUP_DUPLEX)
-			mii->mii_media_active |= IFM_FDX;
+			mii->mii_media_active |=
+			    IFM_FDX | mii_phy_flowstatus(sc);
 		else
 			mii->mii_media_active |= IFM_HDX;
 	} else

Modified: stable/8/sys/dev/mii/nsphyter.c
==============================================================================
--- stable/8/sys/dev/mii/nsphyter.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/nsphyter.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -143,6 +143,8 @@ nsphyter_attach(device_t dev)
 	sc->mii_service = nsphyter_service;
 	sc->mii_pdata = mii;
 
+	sc->mii_flags |= MIIF_NOMANPAUSE;
+
 #if 1
 
 #define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)
@@ -242,12 +244,8 @@ nsphyter_status(struct mii_softc *sc)
 		else
 			mii->mii_media_active |= IFM_100_TX;
 		if ((physts & PHYSTS_DUPLEX) != 0)
-#ifdef notyet
 			mii->mii_media_active |=
 			    IFM_FDX | mii_phy_flowstatus(sc);
-#else
-			mii->mii_media_active |= IFM_FDX;
-#endif
 		else
 			mii->mii_media_active |= IFM_HDX;
 	} else

Modified: stable/8/sys/dev/mii/rgephy.c
==============================================================================
--- stable/8/sys/dev/mii/rgephy.c	Fri Nov 26 20:37:19 2010	(r215881)
+++ stable/8/sys/dev/mii/rgephy.c	Fri Nov 26 20:45:49 2010	(r215882)
@@ -89,7 +89,7 @@ DRIVER_MODULE(rgephy, miibus, rgephy_dri
 
 static int	rgephy_service(struct mii_softc *, struct mii_data *, int);
 static void	rgephy_status(struct mii_softc *);
-static int	rgephy_mii_phy_auto(struct mii_softc *);
+static int	rgephy_mii_phy_auto(struct mii_softc *, int);
 static void	rgephy_reset(struct mii_softc *);
 static void	rgephy_loop(struct mii_softc *);
 static void	rgephy_load_dspcode(struct mii_softc *);
@@ -113,7 +113,6 @@ rgephy_attach(device_t dev)
 	struct mii_softc *sc;
 	struct mii_attach_args *ma;
 	struct mii_data *mii;
-	const char *sep = "";
 
 	rsc = device_get_softc(dev);
 	sc = &rsc->mii_sc;
@@ -132,27 +131,21 @@ rgephy_attach(device_t dev)
 	rsc->mii_revision = MII_REV(ma->mii_id2);
 
 #define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)
-#define PRINT(s)	printf("%s%s", sep, s); sep = ", "
 
 #if 0
 	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
 	    MII_MEDIA_100_TX);
 #endif
 
-	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
-	sc->mii_capabilities &= ~BMSR_ANEG;
+	/* RTL8169S do not report auto-sense; add manually. */
+	sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) | BMSR_ANEG) &
+	    ma->mii_capmask;
 	if (sc->mii_capabilities & BMSR_EXTSTAT)
 		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
-
 	device_printf(dev, " ");
 	mii_phy_add_media(sc);
-	/* RTL8169S do not report auto-sense; add manually. */
-	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), MII_NMEDIA);
-	sep = ", ";
-	PRINT("auto");
 	printf("\n");
 #undef ADD
-#undef PRINT
 
 	rgephy_reset(sc);
 	MIIBUS_MEDIAINIT(sc->mii_dev);
@@ -182,7 +175,8 @@ rgephy_service(struct mii_softc *sc, str
 		rgephy_reset(sc);	/* XXX hardware bug work-around */
 
 		anar = PHY_READ(sc, RGEPHY_MII_ANAR);
-		anar &= ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX |
+		anar &= ~(RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP |
+		    RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX |
 		    RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10);
 
 		switch (IFM_SUBTYPE(ife->ifm_media)) {
@@ -194,7 +188,7 @@ rgephy_service(struct mii_softc *sc, str
 			if (PHY_READ(sc, RGEPHY_MII_BMCR) & RGEPHY_BMCR_AUTOEN)
 				return (0);
 #endif
-			(void) rgephy_mii_phy_auto(sc);
+			(void)rgephy_mii_phy_auto(sc, ife->ifm_media);
 			break;
 		case IFM_1000_T:
 			speed = RGEPHY_S1000;
@@ -222,32 +216,26 @@ setit:
 				PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
 				PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
 				PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
-				    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
+				    RGEPHY_BMCR_AUTOEN |
+				    RGEPHY_BMCR_STARTNEG);
 				break;
 			}
 
-			/*
-			 * When setting the link manually, one side must
-			 * be the master and the other the slave. However
-			 * ifmedia doesn't give us a good way to specify
-			 * this, so we fake it by using one of the LINK
-			 * flags. If LINK0 is set, we program the PHY to
-			 * be a master, otherwise it's a slave.
-			 */
-			if ((mii->mii_ifp->if_flags & IFF_LINK0)) {
-				PHY_WRITE(sc, RGEPHY_MII_1000CTL,
-				    gig|RGEPHY_1000CTL_MSE|RGEPHY_1000CTL_MSC);
-			} else {
-				PHY_WRITE(sc, RGEPHY_MII_1000CTL,
-				    gig|RGEPHY_1000CTL_MSE);
-			}
+			if ((ife->ifm_media & IFM_FLOW) != 0 ||
+			    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
+				anar |= RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP;
+
+			gig |= RGEPHY_1000CTL_MSE;
+			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
+			    gig |= RGEPHY_1000CTL_MSC;
+			PHY_WRITE(sc, RGEPHY_MII_1000CTL, gig);
+			PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
 			PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
 			    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
 			break;
 		case IFM_NONE:
-			PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN);
+			PHY_WRITE(sc, MII_BMCR, BMCR_ISO | BMCR_PDOWN);
 			break;
-		case IFM_100_T4:
 		default:
 			return (EINVAL);
 		}
@@ -297,7 +285,7 @@ setit:
 			return (0);
 
 		sc->mii_ticks = 0;
-		rgephy_mii_phy_auto(sc);
+		rgephy_mii_phy_auto(sc, ife->ifm_media);
 		break;
 	}
 
@@ -395,22 +383,32 @@ rgephy_status(struct mii_softc *sc)
 		else
 			mii->mii_media_active |= IFM_HDX;
 	}
+
+	if ((mii->mii_media_active & IFM_FDX) != 0)
+		mii->mii_media_active |= mii_phy_flowstatus(sc);
+
+	if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) &&
+	    (PHY_READ(sc, RGEPHY_MII_1000STS) & RGEPHY_1000STS_MSR) != 0)
+		mii->mii_media_active |= IFM_ETH_MASTER;
 }
 
 static int
-rgephy_mii_phy_auto(struct mii_softc *mii)
+rgephy_mii_phy_auto(struct mii_softc *sc, int media)
 {
+	int anar;
 
-	rgephy_loop(mii);
-	rgephy_reset(mii);
+	rgephy_loop(sc);
+	rgephy_reset(sc);
 
-	PHY_WRITE(mii, RGEPHY_MII_ANAR,
-	    BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA);
+	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
+	if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
+		anar |= RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP;
+	PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
 	DELAY(1000);
-	PHY_WRITE(mii, RGEPHY_MII_1000CTL,
-            RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD);
+	PHY_WRITE(sc, RGEPHY_MII_1000CTL,
+	    RGEPHY_1000CTL_AHD | RGEPHY_1000CTL_AFD);
 	DELAY(1000);
-	PHY_WRITE(mii, RGEPHY_MII_BMCR,
+	PHY_WRITE(sc, RGEPHY_MII_BMCR,
 	    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
 	DELAY(100);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011262045.oAQKjn8v075889>