svn commit: r215883 - stable/7/sys/dev/mii
Marius Strobl
marius at FreeBSD.org
Fri Nov 26 20:45:52 UTC 2010
Author: marius
Date: Fri Nov 26 20:45:52 2010
New Revision: 215883
URL: http://svn.freebsd.org/changeset/base/215883
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/7 in r215879). 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/7/sys/dev/mii/atphy.c
stable/7/sys/dev/mii/bmtphy.c
stable/7/sys/dev/mii/gentbi.c
stable/7/sys/dev/mii/inphy.c
stable/7/sys/dev/mii/jmphy.c
stable/7/sys/dev/mii/nsgphy.c
stable/7/sys/dev/mii/nsphyter.c
stable/7/sys/dev/mii/rgephy.c
Directory Properties:
stable/7/sys/ (props changed)
stable/7/sys/cddl/contrib/opensolaris/ (props changed)
stable/7/sys/contrib/dev/acpica/ (props changed)
stable/7/sys/contrib/pf/ (props changed)
Modified: stable/7/sys/dev/mii/atphy.c
==============================================================================
--- stable/7/sys/dev/mii/atphy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/atphy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/bmtphy.c
==============================================================================
--- stable/7/sys/dev/mii/bmtphy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/bmtphy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/gentbi.c
==============================================================================
--- stable/7/sys/dev/mii/gentbi.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/gentbi.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/inphy.c
==============================================================================
--- stable/7/sys/dev/mii/inphy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/inphy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/jmphy.c
==============================================================================
--- stable/7/sys/dev/mii/jmphy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/jmphy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/nsgphy.c
==============================================================================
--- stable/7/sys/dev/mii/nsgphy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/nsgphy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/nsphyter.c
==============================================================================
--- stable/7/sys/dev/mii/nsphyter.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/nsphyter.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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/7/sys/dev/mii/rgephy.c
==============================================================================
--- stable/7/sys/dev/mii/rgephy.c Fri Nov 26 20:45:49 2010 (r215882)
+++ stable/7/sys/dev/mii/rgephy.c Fri Nov 26 20:45:52 2010 (r215883)
@@ -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);
More information about the svn-src-stable
mailing list