Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add support for the new i82540, i82545, and i825...
details: https://anonhg.NetBSD.org/src/rev/1fb67ffdd940
branches: trunk
changeset: 534999:1fb67ffdd940
user: thorpej <thorpej%NetBSD.org@localhost>
date: Thu Aug 08 00:12:08 2002 +0000
description:
Add support for the new i82540, i82545, and i82546 Gig-E chips. The
i82546 chip has 2 Gig-E interfaces in a single chip.
The main difference is these chips have a special handshaking protocol
for accessing the EEPROM (due to the shared nature on the i82546).
diffstat:
sys/dev/pci/if_wm.c | 102 ++++++++++++++++++++++++++++++++++++++++++++----
sys/dev/pci/if_wmreg.h | 9 +++-
2 files changed, 101 insertions(+), 10 deletions(-)
diffs (205 lines):
diff -r 0c38eb0760a0 -r 1fb67ffdd940 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Thu Aug 08 00:11:52 2002 +0000
+++ b/sys/dev/pci/if_wm.c Thu Aug 08 00:12:08 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.16 2002/08/07 04:53:18 simonb Exp $ */
+/* $NetBSD: if_wm.c,v 1.17 2002/08/08 00:12:08 thorpej Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
@@ -303,6 +303,7 @@
/* sc_flags */
#define WM_F_HAS_MII 0x01 /* has MII */
+#define WM_F_EEPROM_HANDSHAKE 0x02 /* requires EEPROM handshake */
#ifdef WM_EVENT_COUNTERS
#define WM_EVCNT_INCR(ev) (ev)->ev_count++
@@ -474,6 +475,30 @@
"Intel i82544GC (LOM) 1000BASE-T Ethernet",
WM_T_82544, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM,
+ "Intel i82540EM 1000BASE-T Ethernet",
+ WM_T_82540, WMP_F_1000T },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_COPPER,
+ "Intel i82545EM 1000BASE-T Ethernet",
+ WM_T_82545, WMP_F_1000T },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_COPPER,
+ "Intel i82546EB 1000BASE-T Ethernet",
+ WM_T_82546, WMP_F_1000T },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82545EM_FIBER,
+ "Intel i82545EM 1000BASE-X Ethernet",
+ WM_T_82545, WMP_F_1000X },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82546EB_FIBER,
+ "Intel i82546EB 1000BASE-X Ethernet",
+ WM_T_82546, WMP_F_1000X },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82540EM_LOM,
+ "Intel i82540EM (LOM) 1000BASE-T Ethernet",
+ WM_T_82540, WMP_F_1000T },
+
{ 0, 0,
NULL,
0, 0 },
@@ -572,6 +597,12 @@
}
/*
+ * Some chips require a handshake to access the EEPROM.
+ */
+ if (sc->sc_type >= WM_T_82540)
+ sc->sc_flags |= WM_F_EEPROM_HANDSHAKE;
+
+ /*
* Map the device.
*/
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, WM_PCI_MMBA);
@@ -718,6 +749,15 @@
enaddr[4] = myea[2] & 0xff;
enaddr[5] = myea[2] >> 8;
+ /*
+ * Toggle the LSB of the MAC address on the second port
+ * of the i82546.
+ */
+ if (sc->sc_type == WM_T_82546) {
+ if ((CSR_READ(sc, WMREG_STATUS) >> STATUS_FUNCID_SHIFT) & 1)
+ enaddr[5] ^= 1;
+ }
+
printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
ether_sprintf(enaddr));
@@ -2136,18 +2176,53 @@
wm_read_eeprom(struct wm_softc *sc, int word, int wordcnt, uint16_t *data)
{
uint32_t reg;
- int i, x;
+ int i, x, addrbits = 6;
for (i = 0; i < wordcnt; i++) {
- /* Send CHIP SELECT for one clock tick. */
- CSR_WRITE(sc, WMREG_EECD, EECD_CS);
+ if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) {
+ reg = CSR_READ(sc, WMREG_EECD);
+
+ /* Get number of address bits. */
+ if (reg & EECD_EE_SIZE)
+ addrbits = 8;
+
+ /* Request EEPROM access. */
+ reg |= EECD_EE_REQ;
+ CSR_WRITE(sc, WMREG_EECD, reg);
+
+ /* ..and wait for it to be granted. */
+ for (x = 0; x < 100; x++) {
+ reg = CSR_READ(sc, WMREG_EECD);
+ if (reg & EECD_EE_GNT)
+ break;
+ delay(5);
+ }
+ if ((reg & EECD_EE_GNT) == 0) {
+ printf("%s: could not acquire EEPROM GNT\n",
+ sc->sc_dev.dv_xname);
+ *data = 0xffff;
+ reg &= ~EECD_EE_REQ;
+ CSR_WRITE(sc, WMREG_EECD, reg);
+ continue;
+ }
+ } else
+ reg = 0;
+
+ /* Clear SK and DI. */
+ reg &= ~(EECD_SK | EECD_DI);
+ CSR_WRITE(sc, WMREG_EECD, reg);
+
+ /* Set CHIP SELECT. */
+ reg |= EECD_CS;
+ CSR_WRITE(sc, WMREG_EECD, reg);
delay(2);
/* Shift in the READ command. */
for (x = 3; x > 0; x--) {
- reg = EECD_CS;
if (UWIRE_OPC_READ & (1 << (x - 1)))
reg |= EECD_DI;
+ else
+ reg &= ~EECD_DI;
CSR_WRITE(sc, WMREG_EECD, reg);
delay(2);
CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK);
@@ -2157,10 +2232,11 @@
}
/* Shift in address. */
- for (x = 6; x > 0; x--) {
- reg = EECD_CS;
+ for (x = addrbits; x > 0; x--) {
if ((word + i) & (1 << (x - 1)))
reg |= EECD_DI;
+ else
+ reg &= ~EECD_DI;
CSR_WRITE(sc, WMREG_EECD, reg);
delay(2);
CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK);
@@ -2170,7 +2246,7 @@
}
/* Shift out the data. */
- reg = EECD_CS;
+ reg &= ~EECD_DI;
data[i] = 0;
for (x = 16; x > 0; x--) {
CSR_WRITE(sc, WMREG_EECD, reg | EECD_SK);
@@ -2182,7 +2258,15 @@
}
/* Clear CHIP SELECT. */
- CSR_WRITE(sc, WMREG_EECD, 0);
+ reg &= ~EECD_CS;
+ CSR_WRITE(sc, WMREG_EECD, reg);
+ delay(2);
+
+ if (sc->sc_flags & WM_F_EEPROM_HANDSHAKE) {
+ /* Release the EEPROM. */
+ reg &= ~EECD_EE_REQ;
+ CSR_WRITE(sc, WMREG_EECD, reg);
+ }
}
}
diff -r 0c38eb0760a0 -r 1fb67ffdd940 sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h Thu Aug 08 00:11:52 2002 +0000
+++ b/sys/dev/pci/if_wmreg.h Thu Aug 08 00:12:08 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wmreg.h,v 1.2 2002/07/14 00:56:22 thorpej Exp $ */
+/* $NetBSD: if_wmreg.h,v 1.3 2002/08/08 00:12:08 thorpej Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -201,6 +201,8 @@
#define STATUS_LU (1U << 1) /* link up */
#define STATUS_TCKOK (1U << 2) /* Tx clock running */
#define STATUS_RBCOK (1U << 3) /* Rx clock running */
+#define STATUS_FUNCID_SHIFT 2 /* 82546 function ID */
+#define STATUS_FUNCID_MASK 3 /* ... */
#define STATUS_TXOFF (1U << 4) /* Tx paused */
#define STATUS_TBIMODE (1U << 5) /* fiber mode (Livengood) */
#define STATUS_SPEED(x) ((x) << 6) /* speed indication */
@@ -225,6 +227,11 @@
#define EECD_FWE(x) ((x) << 4) /* flash write enable control */
#define EECD_FWE_DISABLED EECD_FWE(1)
#define EECD_FWE_ENABLED EECD_FWE(2)
+#define EECD_EE_REQ (1U << 6) /* (shared) EEPROM request */
+#define EECD_EE_GNT (1U << 7) /* (shared) EEPROM grant */
+#define EECD_EE_PRES (1U << 8) /* EEPROM present */
+#define EECD_EE_SIZE (1U << 9) /* EEPROM size
+ (0 = 64 word, 1 = 256 word) */
#define UWIRE_OPC_ERASE 0x04 /* MicroWire "erase" opcode */
#define UWIRE_OPC_WRITE 0x05 /* MicroWire "write" opcode */
Home |
Main Index |
Thread Index |
Old Index