summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2008-12-17 06:01:03 +0000
committeryongari <yongari@FreeBSD.org>2008-12-17 06:01:03 +0000
commit4b0736516edcee5ab7ef5051c75ecb3efcbbc476 (patch)
treeb064598332527235a3c97a3b8dbcfc93ff5de05a /sys
parent832d8c0e290d1c9e734619e1791bbc98d5462f24 (diff)
downloadFreeBSD-src-4b0736516edcee5ab7ef5051c75ecb3efcbbc476.zip
FreeBSD-src-4b0736516edcee5ab7ef5051c75ecb3efcbbc476.tar.gz
For RTL8168C SPIN2 controllers, make sure to take the controller
out of sleep mode prior to accessing to PHY. This should fix device attach failure seen on these controllers. Also enable the sleep mode when device is put into sleep state. PR: kern/123123, kern/123053
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/re/if_re.c29
-rw-r--r--sys/pci/if_rlreg.h3
2 files changed, 31 insertions, 1 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 6709d6d..efd5930 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -1262,8 +1262,13 @@ re_attach(device_t dev)
sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
RL_FLAG_MACSTAT;
break;
- case RL_HWREV_8168C:
case RL_HWREV_8168C_SPIN2:
+ sc->rl_flags |= RL_FLAG_MACSLEEP;
+ /* FALLTHROUGH */
+ case RL_HWREV_8168C:
+ if ((hwrev & 0x00700000) == 0x00200000)
+ sc->rl_flags |= RL_FLAG_MACSLEEP;
+ /* FALLTHROUGH */
case RL_HWREV_8168CP:
case RL_HWREV_8168D:
sc->rl_flags |= RL_FLAG_INVMAR | RL_FLAG_PHYWAKE |
@@ -1351,6 +1356,16 @@ re_attach(device_t dev)
goto fail;
}
+ /* Take controller out of deep sleep mode. */
+ if ((sc->rl_flags & RL_FLAG_MACSLEEP) != 0) {
+ if ((CSR_READ_1(sc, RL_MACDBG) & 0x80) == 0x80)
+ CSR_WRITE_1(sc, RL_GPIO,
+ CSR_READ_1(sc, RL_GPIO) | 0x01);
+ else
+ CSR_WRITE_1(sc, RL_GPIO,
+ CSR_READ_1(sc, RL_GPIO) & ~0x01);
+ }
+
/* Take PHY out of power down mode. */
if ((sc->rl_flags & RL_FLAG_PHYWAKE) != 0) {
re_gmii_writereg(dev, 1, 0x1f, 0);
@@ -2963,6 +2978,12 @@ re_resume(device_t dev)
RL_LOCK(sc);
ifp = sc->rl_ifp;
+ /* Take controller out of sleep mode. */
+ if ((sc->rl_flags & RL_FLAG_MACSLEEP) != 0) {
+ if ((CSR_READ_1(sc, RL_MACDBG) & 0x80) == 0x80)
+ CSR_WRITE_1(sc, RL_GPIO,
+ CSR_READ_1(sc, RL_GPIO) | 0x01);
+ }
/* reinitialize interface if necessary */
if (ifp->if_flags & IFF_UP)
@@ -3018,6 +3039,12 @@ re_setwol(struct rl_softc *sc)
return;
ifp = sc->rl_ifp;
+ /* Put controller into sleep mode. */
+ if ((sc->rl_flags & RL_FLAG_MACSLEEP) != 0) {
+ if ((CSR_READ_1(sc, RL_MACDBG) & 0x80) == 0x80)
+ CSR_WRITE_1(sc, RL_GPIO,
+ CSR_READ_1(sc, RL_GPIO) & ~0x01);
+ }
if ((ifp->if_capenable & IFCAP_WOL) != 0 &&
(sc->rl_flags & RL_FLAG_WOLRXENB) != 0)
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB);
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index d9df78c..ccea051 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -131,6 +131,8 @@
#define RL_TBI_ANAR 0x0068
#define RL_TBI_LPAR 0x006A
#define RL_GMEDIASTAT 0x006C /* 8 bits */
+#define RL_MACDBG 0x006D /* 8 bits, 8168C SPIN2 only */
+#define RL_GPIO 0x006E /* 8 bits, 8168C SPIN2 only */
#define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
#define RL_GTXSTART 0x0038 /* 8 bits */
@@ -888,6 +890,7 @@ struct rl_softc {
#define RL_FLAG_PHY8169 0x0400
#define RL_FLAG_PHY8110S 0x0800
#define RL_FLAG_WOLRXENB 0x1000
+#define RL_FLAG_MACSLEEP 0x2000
#define RL_FLAG_LINK 0x8000
};
OpenPOWER on IntegriCloud