summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2015-03-26 05:44:21 +0000
committeryongari <yongari@FreeBSD.org>2015-03-26 05:44:21 +0000
commit2f25ad094c26d229d2e0806b8ca9c6244a5af63d (patch)
tree07e78b5481dd1a99160f3fb88acb04ececc8c8e9 /sys/dev
parenta9edaae369b07cec99714368baba56d0c0dfe739 (diff)
downloadFreeBSD-src-2f25ad094c26d229d2e0806b8ca9c6244a5af63d.zip
FreeBSD-src-2f25ad094c26d229d2e0806b8ca9c6244a5af63d.tar.gz
MFC r279903,279941:
Add RTL8211F gigabit PHY support. PR: 197265
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mii/rgephy.c165
-rw-r--r--sys/dev/mii/rgephyreg.h21
2 files changed, 126 insertions, 60 deletions
diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c
index 8345f1f..2c28068 100644
--- a/sys/dev/mii/rgephy.c
+++ b/sys/dev/mii/rgephy.c
@@ -85,6 +85,7 @@ 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 *, int);
static void rgephy_reset(struct mii_softc *);
+static int rgephy_linkup(struct mii_softc *);
static void rgephy_loop(struct mii_softc *);
static void rgephy_load_dspcode(struct mii_softc *);
@@ -147,7 +148,7 @@ static int
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
- int reg, speed, gig, anar;
+ int speed, gig, anar;
switch (cmd) {
case MII_POLLSTAT:
@@ -249,20 +250,9 @@ setit:
* Check to see if we have link. If we do, we don't
* need to restart the autonegotiation process.
*/
- if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
- sc->mii_mpd_rev >= 2) {
- /* RTL8211B(L) */
- reg = PHY_READ(sc, RGEPHY_MII_SSR);
- if (reg & RGEPHY_SSR_LINK) {
- sc->mii_ticks = 0;
- break;
- }
- } else {
- reg = PHY_READ(sc, RL_GMEDIASTAT);
- if (reg & RL_GMEDIASTAT_LINK) {
- sc->mii_ticks = 0;
- break;
- }
+ if (rgephy_linkup(sc) != 0) {
+ sc->mii_ticks = 0;
+ break;
}
/* Announce link loss right after it happens. */
@@ -295,6 +285,33 @@ setit:
return (0);
}
+static int
+rgephy_linkup(struct mii_softc *sc)
+{
+ int linkup;
+ uint16_t reg;
+
+ linkup = 0;
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
+ sc->mii_mpd_rev >= RGEPHY_8211B) {
+ if (sc->mii_mpd_rev == RGEPHY_8211F) {
+ reg = PHY_READ(sc, RGEPHY_F_MII_SSR);
+ if (reg & RGEPHY_F_SSR_LINK)
+ linkup++;
+ } else {
+ reg = PHY_READ(sc, RGEPHY_MII_SSR);
+ if (reg & RGEPHY_SSR_LINK)
+ linkup++;
+ }
+ } else {
+ reg = PHY_READ(sc, RL_GMEDIASTAT);
+ if (reg & RL_GMEDIASTAT_LINK)
+ linkup++;
+ }
+
+ return (linkup);
+}
+
static void
rgephy_status(struct mii_softc *sc)
{
@@ -305,18 +322,10 @@ rgephy_status(struct mii_softc *sc)
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
- ssr = PHY_READ(sc, RGEPHY_MII_SSR);
- if (ssr & RGEPHY_SSR_LINK)
- mii->mii_media_status |= IFM_ACTIVE;
- } else {
- bmsr = PHY_READ(sc, RL_GMEDIASTAT);
- if (bmsr & RL_GMEDIASTAT_LINK)
- mii->mii_media_status |= IFM_ACTIVE;
- }
+ if (rgephy_linkup(sc) != 0)
+ mii->mii_media_status |= IFM_ACTIVE;
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
-
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
if (bmcr & RGEPHY_BMCR_ISO) {
mii->mii_media_active |= IFM_NONE;
@@ -335,26 +344,50 @@ rgephy_status(struct mii_softc *sc)
}
}
- if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
- ssr = PHY_READ(sc, RGEPHY_MII_SSR);
- switch (ssr & RGEPHY_SSR_SPD_MASK) {
- case RGEPHY_SSR_S1000:
- mii->mii_media_active |= IFM_1000_T;
- break;
- case RGEPHY_SSR_S100:
- mii->mii_media_active |= IFM_100_TX;
- break;
- case RGEPHY_SSR_S10:
- mii->mii_media_active |= IFM_10_T;
- break;
- default:
- mii->mii_media_active |= IFM_NONE;
- break;
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
+ sc->mii_mpd_rev >= RGEPHY_8211B) {
+ if (sc->mii_mpd_rev == RGEPHY_8211F) {
+ ssr = PHY_READ(sc, RGEPHY_F_MII_SSR);
+ switch (ssr & RGEPHY_F_SSR_SPD_MASK) {
+ case RGEPHY_F_SSR_S1000:
+ mii->mii_media_active |= IFM_1000_T;
+ break;
+ case RGEPHY_F_SSR_S100:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case RGEPHY_F_SSR_S10:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ default:
+ mii->mii_media_active |= IFM_NONE;
+ break;
+ }
+ if (ssr & RGEPHY_F_SSR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+
+ } else {
+ ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+ switch (ssr & RGEPHY_SSR_SPD_MASK) {
+ case RGEPHY_SSR_S1000:
+ mii->mii_media_active |= IFM_1000_T;
+ break;
+ case RGEPHY_SSR_S100:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case RGEPHY_SSR_S10:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ default:
+ mii->mii_media_active |= IFM_NONE;
+ break;
+ }
+ if (ssr & RGEPHY_SSR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
}
- if (ssr & RGEPHY_SSR_FDX)
- mii->mii_media_active |= IFM_FDX;
- else
- mii->mii_media_active |= IFM_HDX;
} else {
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_1000MBPS)
@@ -408,7 +441,7 @@ rgephy_loop(struct mii_softc *sc)
int i;
if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 &&
- sc->mii_mpd_rev < 2) {
+ sc->mii_mpd_rev < RGEPHY_8211B) {
PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
DELAY(1000);
}
@@ -442,7 +475,7 @@ rgephy_load_dspcode(struct mii_softc *sc)
int val;
if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 ||
- sc->mii_mpd_rev >= 2)
+ sc->mii_mpd_rev >= RGEPHY_8211B)
return;
PHY_WRITE(sc, 31, 0x0001);
@@ -493,22 +526,34 @@ rgephy_reset(struct mii_softc *sc)
{
uint16_t pcr, ssr;
- if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) {
- /* RTL8211C(L) */
- ssr = PHY_READ(sc, RGEPHY_MII_SSR);
- if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
- ssr &= ~RGEPHY_SSR_ALDPS;
- PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
+ 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);
}
- }
-
- if (sc->mii_mpd_rev >= 2) {
- pcr = PHY_READ(sc, RGEPHY_MII_PCR);
- if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
- pcr &= ~RGEPHY_PCR_MDI_MASK;
- pcr |= RGEPHY_PCR_MDIX_AUTO;
- PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
+ break;
+ case RGEPHY_8211C:
+ if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
+ /* RTL8211C(L) */
+ ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+ if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
+ ssr &= ~RGEPHY_SSR_ALDPS;
+ PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
+ }
}
+ /* FALLTHROUGH */
+ default:
+ if (sc->mii_mpd_rev >= RGEPHY_8211B) {
+ pcr = PHY_READ(sc, RGEPHY_MII_PCR);
+ if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
+ pcr &= ~RGEPHY_PCR_MDI_MASK;
+ pcr |= RGEPHY_PCR_MDIX_AUTO;
+ PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
+ }
+ }
+ break;
}
mii_phy_reset(sc);
diff --git a/sys/dev/mii/rgephyreg.h b/sys/dev/mii/rgephyreg.h
index fb02ae6..2a00517 100644
--- a/sys/dev/mii/rgephyreg.h
+++ b/sys/dev/mii/rgephyreg.h
@@ -35,6 +35,10 @@
#ifndef _DEV_MII_RGEPHYREG_H_
#define _DEV_MII_RGEPHYREG_H_
+#define RGEPHY_8211B 2
+#define RGEPHY_8211C 3
+#define RGEPHY_8211F 6
+
/*
* RealTek 8169S/8110S gigE PHY registers
*/
@@ -162,4 +166,21 @@
#define RGEPHY_SSR_ALDPS 0x0008 /* RTL8211C(L) only */
#define RGEPHY_SSR_JABBER 0x0001 /* Jabber */
+/* RTL8211F */
+#define RGEPHY_F_MII_PCR1 0x18 /* PHY Specific control register 1 */
+#define RGEPHY_F_PCR1_MDI_MM 0x0200 /* MDI / MDIX Manual Mode */
+#define RGEPHY_F_PCR1_MDI_MODE 0x0100 /* MDI Mode (0=MDIX,1=MDI) */
+#define RGEPHY_F_PCR1_ALDPS_EN 0x0004 /* Link Down Power Saving Enable */
+
+/* RTL8211F */
+#define RGEPHY_F_MII_SSR 0x1A /* PHY Specific status register */
+#define RGEPHY_F_SSR_S1000 0x0020 /* 1000Mbps */
+#define RGEPHY_F_SSR_S100 0x0010 /* 100Mbps */
+#define RGEPHY_F_SSR_S10 0x0000 /* 10Mbps */
+#define RGEPHY_F_SSR_SPD_MASK 0x0030
+#define RGEPHY_F_SSR_FDX 0x0008 /* full duplex */
+#define RGEPHY_F_SSR_LINK 0x0004 /* link up */
+#define RGEPHY_F_SSR_MDI 0x0002 /* MDI/MDIX */
+#define RGEPHY_F_SSR_JABBER 0x0001 /* Jabber */
+
#endif /* _DEV_RGEPHY_MIIREG_H_ */
OpenPOWER on IntegriCloud