summaryrefslogtreecommitdiffstats
path: root/sys/dev/mii
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2010-12-18 23:52:50 +0000
committeryongari <yongari@FreeBSD.org>2010-12-18 23:52:50 +0000
commitb52a1b882d10997e24ae7e5a9eebb4967b9cdf11 (patch)
tree5b530523b866e864753791f3f6a60d3de5cc22b6 /sys/dev/mii
parentf652d40af333a97c256711fc5b849806fa38861b (diff)
downloadFreeBSD-src-b52a1b882d10997e24ae7e5a9eebb4967b9cdf11.zip
FreeBSD-src-b52a1b882d10997e24ae7e5a9eebb4967b9cdf11.tar.gz
Add support for JMicron JMC251/JMC261 Gigabit/Fast ethernet
controller with Card Read Host Controller. These controllers are multi-function devices and have the same ethernet core of JMC250/JMC260. Starting from REVFM 5(chip full mask revision) controllers have the following features. o eFuse support o PCD(Packet Completion Deferring) o More advanced PHY power saving Because these controllers started to use eFuse, station address modified by driver is permanent as if it was written to EEPROM. If you have to change station address please save your controller default address to safe place before reprogramming it. There is no way to restore factory default station address. Many thanks to JMicron for continuing to support FreeBSD. HW donated by: JMicron
Diffstat (limited to 'sys/dev/mii')
-rw-r--r--sys/dev/mii/jmphy.c39
-rw-r--r--sys/dev/mii/jmphyreg.h9
2 files changed, 48 insertions, 0 deletions
diff --git a/sys/dev/mii/jmphy.c b/sys/dev/mii/jmphy.c
index 00611c4..3347a29 100644
--- a/sys/dev/mii/jmphy.c
+++ b/sys/dev/mii/jmphy.c
@@ -104,6 +104,7 @@ jmphy_attach(device_t dev)
struct mii_softc *sc;
struct mii_attach_args *ma;
struct mii_data *mii;
+ struct ifnet *ifp;
jsc = device_get_softc(dev);
sc = &jsc->mii_sc;
@@ -118,6 +119,10 @@ jmphy_attach(device_t dev)
sc->mii_service = jmphy_service;
sc->mii_pdata = mii;
+ ifp = sc->mii_pdata->mii_ifp;
+ if (strcmp(ifp->if_dname, "jme") == 0 &&
+ (sc->mii_flags & MIIF_MACPRIV0) != 0)
+ sc->mii_flags |= MIIF_PHYPRIV0;
jsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
jsc->mii_model = MII_MODEL(ma->mii_id2);
jsc->mii_rev = MII_REV(ma->mii_id2);
@@ -265,6 +270,7 @@ static void
jmphy_reset(struct mii_softc *sc)
{
struct jmphy_softc *jsc;
+ uint16_t t2cr, val;
int i;
jsc = (struct jmphy_softc *)sc;
@@ -279,6 +285,39 @@ jmphy_reset(struct mii_softc *sc)
if ((PHY_READ(sc, MII_BMCR) & BMCR_RESET) == 0)
break;
}
+ /* Perform vendor recommended PHY calibration. */
+ if ((sc->mii_flags & MIIF_PHYPRIV0) != 0) {
+ /* Select PHY test mode 1. */
+ t2cr = PHY_READ(sc, MII_100T2CR);
+ t2cr &= ~GTCR_TEST_MASK;
+ t2cr |= 0x2000;
+ PHY_WRITE(sc, MII_100T2CR, t2cr);
+ /* Apply calibration patch. */
+ PHY_WRITE(sc, JMPHY_SPEC_ADDR, JMPHY_SPEC_ADDR_READ |
+ JMPHY_EXT_COMM_2);
+ val = PHY_READ(sc, JMPHY_SPEC_DATA);
+ val &= ~0x0002;
+ val |= 0x0010 | 0x0001;
+ PHY_WRITE(sc, JMPHY_SPEC_DATA, val);
+ PHY_WRITE(sc, JMPHY_SPEC_ADDR, JMPHY_SPEC_ADDR_WRITE |
+ JMPHY_EXT_COMM_2);
+
+ /* XXX 20ms to complete recalibration. */
+ DELAY(20 * 1000);
+
+ PHY_READ(sc, MII_100T2CR);
+ PHY_WRITE(sc, JMPHY_SPEC_ADDR, JMPHY_SPEC_ADDR_READ |
+ JMPHY_EXT_COMM_2);
+ val = PHY_READ(sc, JMPHY_SPEC_DATA);
+ val &= ~(0x0001 | 0x0002 | 0x0010);
+ PHY_WRITE(sc, JMPHY_SPEC_DATA, val);
+ PHY_WRITE(sc, JMPHY_SPEC_ADDR, JMPHY_SPEC_ADDR_WRITE |
+ JMPHY_EXT_COMM_2);
+ /* Disable PHY test mode. */
+ PHY_READ(sc, MII_100T2CR);
+ t2cr &= ~GTCR_TEST_MASK;
+ PHY_WRITE(sc, MII_100T2CR, t2cr);
+ }
}
static uint16_t
diff --git a/sys/dev/mii/jmphyreg.h b/sys/dev/mii/jmphyreg.h
index 743ae29..ec668ad 100644
--- a/sys/dev/mii/jmphyreg.h
+++ b/sys/dev/mii/jmphyreg.h
@@ -105,4 +105,13 @@
#define JMPHY_TMCTL 0x1A
#define JMPHY_TMCTL_SLEEP_ENB 0x1000
+/* PHY specific configuration register. */
+#define JMPHY_SPEC_ADDR 0x1E
+#define JMPHY_SPEC_ADDR_READ 0x4000
+#define JMPHY_SPEC_ADDR_WRITE 0x8000
+
+#define JMPHY_SPEC_DATA 0x1F
+
+#define JMPHY_EXT_COMM_2 0x32
+
#endif /* _DEV_MII_JMPHYREG_H_ */
OpenPOWER on IntegriCloud