Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Sync with Intel's original em driver:
details: https://anonhg.NetBSD.org/src/rev/e6de2f91e567
branches: trunk
changeset: 750095:e6de2f91e567
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Dec 16 14:37:26 2009 +0000
description:
Sync with Intel's original em driver:
- Add dspcode for igp3 and use it when the EEPROM isn't available.
- Add some delays.
- Stop the PHY transmitter before patching the DSP code and restart it after wrote.
- Save and restore register 0x2f5b.
diffstat:
sys/dev/mii/igphy.c | 157 +++++++++++++++++++++++++++++++++++++-----------
sys/dev/pci/if_wm.c | 48 ++++++--------
sys/dev/pci/if_wmvar.h | 18 +++++-
3 files changed, 158 insertions(+), 65 deletions(-)
diffs (truncated from 352 to 300 lines):
diff -r a5aa6d2d0286 -r e6de2f91e567 sys/dev/mii/igphy.c
--- a/sys/dev/mii/igphy.c Wed Dec 16 14:13:18 2009 +0000
+++ b/sys/dev/mii/igphy.c Wed Dec 16 14:37:26 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: igphy.c,v 1.19 2009/12/16 04:50:35 msaitoh Exp $ */
+/* $NetBSD: igphy.c,v 1.20 2009/12/16 14:37:26 msaitoh Exp $ */
/*
* The Intel copyright applies to the analog register setup, and the
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.19 2009/12/16 04:50:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.20 2009/12/16 14:37:26 msaitoh Exp $");
#include "opt_mii.h"
@@ -94,10 +94,12 @@
struct mii_softc sc_mii;
int sc_smartspeed;
uint32_t sc_mactype;
+ uint32_t sc_macflags;
};
static void igphy_reset(struct mii_softc *);
static void igphy_load_dspcode(struct mii_softc *);
+static void igphy_load_dspcode_igp3(struct mii_softc *);
static void igphy_smartspeed_workaround(struct mii_softc *sc);
static int igphymatch(device_t, cfdata_t, void *);
@@ -152,6 +154,8 @@
dict = device_properties(parent);
if (!prop_dictionary_get_uint32(dict, "mactype", &igsc->sc_mactype))
aprint_error("WARNING! Failed to get mactype\n");
+ if (!prop_dictionary_get_uint32(dict, "macflags", &igsc->sc_macflags))
+ aprint_error("WARNING! Failed to get macflags\n");
sc->mii_dev = self;
sc->mii_inst = mii->mii_instance;
@@ -176,62 +180,127 @@
aprint_normal("\n");
}
+typedef struct {
+ int reg;
+ uint16_t val;
+} dspcode;
+
+static const dspcode igp1code[] = {
+ { 0x1f95, 0x0001 },
+ { 0x1f71, 0xbd21 },
+ { 0x1f79, 0x0018 },
+ { 0x1f30, 0x1600 },
+ { 0x1f31, 0x0014 },
+ { 0x1f32, 0x161c },
+ { 0x1f94, 0x0003 },
+ { 0x1f96, 0x003f },
+ { 0x2010, 0x0008 },
+ { 0, 0 },
+};
+
+static const dspcode igp1code_r2[] = {
+ { 0x1f73, 0x0099 },
+ { 0, 0 },
+};
+
+static const dspcode igp3code[] = {
+ { 0x2f5b, 0x9018},
+ { 0x2f52, 0x0000},
+ { 0x2fb1, 0x8b24},
+ { 0x2fb2, 0xf8f0},
+ { 0x2010, 0x10b0},
+ { 0x2011, 0x0000},
+ { 0x20dd, 0x249a},
+ { 0x20de, 0x00d3},
+ { 0x28b4, 0x04ce},
+ { 0x2f70, 0x29e4},
+ { 0x0000, 0x0140},
+ { 0x1f30, 0x1606},
+ { 0x1f31, 0xb814},
+ { 0x1f35, 0x002a},
+ { 0x1f3e, 0x0067},
+ { 0x1f54, 0x0065},
+ { 0x1f55, 0x002a},
+ { 0x1f56, 0x002a},
+ { 0x1f72, 0x3fb0},
+ { 0x1f76, 0xc0ff},
+ { 0x1f77, 0x1dec},
+ { 0x1f78, 0xf9ef},
+ { 0x1f79, 0x0210},
+ { 0x1895, 0x0003},
+ { 0x1796, 0x0008},
+ { 0x1798, 0xd008},
+ { 0x1898, 0xd918},
+ { 0x187a, 0x0800},
+ { 0x0019, 0x008d},
+ { 0x001b, 0x2080},
+ { 0x0014, 0x0045},
+ { 0x0000, 0x1340},
+ { 0, 0 },
+};
+
+/* DSP patch for igp1 and igp2 */
static void
igphy_load_dspcode(struct mii_softc *sc)
{
struct igphy_softc *igsc = (struct igphy_softc *) sc;
- static const struct {
- int reg;
- uint16_t val;
- } dspcode[] = {
- { 0x1f95, 0x0001 },
- { 0x1f71, 0xbd21 },
- { 0x1f79, 0x0018 },
- { 0x1f30, 0x1600 },
- { 0x1f31, 0x0014 },
- { 0x1f32, 0x161c },
- { 0x1f94, 0x0003 },
- { 0x1f96, 0x003f },
- { 0x2010, 0x0008 },
- { 0, 0 },
- };
+ const dspcode *code;
+ uint16_t reg;
int i;
/* This workaround is only for 82541 and 82547 */
switch (igsc->sc_mactype) {
case WM_T_82541:
case WM_T_82547:
+ code = igp1code;
+ break;
case WM_T_82541_2:
case WM_T_82547_2:
+ code = igp1code_r2;
break;
default:
- /* byebye */
- return;
+ return; /* byebye */
}
- delay(10);
+ /* Delay after phy reset to enable NVM configuration to load */
+ delay(20000);
+
+ /*
+ * Save off the current value of register 0x2F5B to be restored at
+ * the end of this routine.
+ */
+ reg = IGPHY_READ(sc, 0x2f5b);
+
+ /* Disabled the PHY transmitter */
+ IGPHY_WRITE(sc, 0x2f5b, 0x0003);
+
+ delay(20000);
PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT, 0x0000);
PHY_WRITE(sc, 0x0000, 0x0140);
- delay(5);
+ delay(5000);
- switch (igsc->sc_mactype) {
- case WM_T_82541:
- case WM_T_82547:
- for (i = 0; dspcode[i].reg != 0; i++)
- IGPHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
- break;
- case WM_T_82541_2:
- case WM_T_82547_2:
- IGPHY_WRITE(sc, 0x1f73, 0x0099);
- break;
- default:
- break;
- }
+ for (i = 0; !((code[i].reg == 0) && (code[i].val == 0)); i++)
+ IGPHY_WRITE(sc, code[i].reg, code[i].val);
PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
PHY_WRITE(sc, 0x0000, 0x3300);
+
+ delay(20000);
+
+ /* Now enable the transmitter */
+ IGPHY_WRITE(sc, 0x2f5b, reg);
+}
+
+static void
+igphy_load_dspcode_igp3(struct mii_softc *sc)
+{
+ const dspcode *code = igp3code;
+ int i;
+
+ for (i = 0; !((code[i].reg == 0) && (code[i].val == 0)); i++)
+ IGPHY_WRITE(sc, code[i].reg, code[i].val);
}
static void
@@ -241,7 +310,23 @@
uint16_t fused, fine, coarse;
mii_phy_reset(sc);
- igphy_load_dspcode(sc);
+ delay(150);
+
+ switch (igsc->sc_mactype) {
+ case WM_T_82541:
+ case WM_T_82547:
+ case WM_T_82541_2:
+ case WM_T_82547_2:
+ igphy_load_dspcode(sc);
+ break;
+ case WM_T_ICH8:
+ case WM_T_ICH9:
+ if ((igsc->sc_macflags & WM_F_EEPROM_INVALID) != 0)
+ igphy_load_dspcode_igp3(sc);
+ break;
+ default: /* Not for ICH10, PCH and 8257[12] */
+ break;
+ }
if (igsc->sc_mactype == WM_T_82547) {
fused = IGPHY_READ(sc, MII_IGPHY_ANALOG_SPARE_FUSE_STATUS);
@@ -266,7 +351,7 @@
ANALOG_FUSE_ENABLE_SW_CONTROL);
}
}
- PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
+ PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT, 0x0000);
}
diff -r a5aa6d2d0286 -r e6de2f91e567 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Wed Dec 16 14:13:18 2009 +0000
+++ b/sys/dev/pci/if_wm.c Wed Dec 16 14:37:26 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.182 2009/12/16 04:50:35 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.183 2009/12/16 14:37:26 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.182 2009/12/16 04:50:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.183 2009/12/16 14:37:26 msaitoh Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -380,22 +380,6 @@
(sc)->sc_rxtailp = &(m)->m_next; \
} while (/*CONSTCOND*/0)
-/* sc_flags */
-#define WM_F_HAS_MII 0x0001 /* has MII */
-#define WM_F_EEPROM_HANDSHAKE 0x0002 /* requires EEPROM handshake */
-#define WM_F_EEPROM_SEMAPHORE 0x0004 /* EEPROM with semaphore */
-#define WM_F_EEPROM_EERDEEWR 0x0008 /* EEPROM access via EERD/EEWR */
-#define WM_F_EEPROM_SPI 0x0010 /* EEPROM is SPI */
-#define WM_F_EEPROM_FLASH 0x0020 /* EEPROM is FLASH */
-#define WM_F_EEPROM_INVALID 0x0040 /* EEPROM not present (bad checksum) */
-#define WM_F_IOH_VALID 0x0080 /* I/O handle is valid */
-#define WM_F_BUS64 0x0100 /* bus is 64-bit */
-#define WM_F_PCIX 0x0200 /* bus is PCI-X */
-#define WM_F_CSA 0x0400 /* bus is CSA */
-#define WM_F_PCIE 0x0800 /* bus is PCI-Express */
-#define WM_F_SWFW_SYNC 0x1000 /* Software-Firmware synchronisation */
-#define WM_F_SWFWHW_SYNC 0x2000 /* Software-Firmware synchronisation */
-
#ifdef WM_EVENT_COUNTERS
#define WM_EVCNT_INCR(ev) (ev)->ev_count++
#define WM_EVCNT_ADD(ev, val) (ev)->ev_count += (val)
@@ -981,7 +965,7 @@
sc->sc_type = WM_T_82542_2_0;
}
- /* Set device properties */
+ /* Set device properties (mactype)*/
dict = device_properties(sc->sc_dev);
prop_dictionary_set_uint32(dict, "mactype", sc->sc_type);
@@ -1351,18 +1335,26 @@
* that no EEPROM is attached.
*/
- /*
- * Validate the EEPROM checksum. If the checksum fails, flag this for
- * later, so we can fail future reads from the EEPROM.
- */
- if (wm_validate_eeprom_checksum(sc)) {
+ /* Check whether EEPROM is present or not */
+ if ((CSR_READ(sc, WMREG_EECD) & EECD_EE_PRES) == 0) {
+ /* Not found */
+ sc->sc_flags |= WM_F_EEPROM_INVALID;
+ } else {
/*
- * Read twice again because some PCI-e parts fail the first
Home |
Main Index |
Thread Index |
Old Index