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 82575, 82576 and 82580(ER).
details: https://anonhg.NetBSD.org/src/rev/00353b6fe140
branches: trunk
changeset: 752133:00353b6fe140
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Tue Feb 16 15:17:17 2010 +0000
description:
Add support for 82575, 82576 and 82580(ER).
- Apply the patch for 82575 from Wolfgang Stukenbrock (PR#42422). We use
only one RX ring and with the legacy mode.
- Add support for 82576.
- Partial support for 82580.
- Partial support for the serdes systems.
diffstat:
sys/dev/pci/if_wm.c | 589 ++++++++++++++++++++++++++++++++++++++++--------
sys/dev/pci/if_wmreg.h | 128 +++++++++-
sys/dev/pci/if_wmvar.h | 8 +-
3 files changed, 609 insertions(+), 116 deletions(-)
diffs (truncated from 1317 to 300 lines):
diff -r de78c809e737 -r 00353b6fe140 sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Tue Feb 16 10:11:47 2010 +0000
+++ b/sys/dev/pci/if_wm.c Tue Feb 16 15:17:17 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.198 2010/02/16 10:06:19 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.199 2010/02/16 15:17:17 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.198 2010/02/16 10:06:19 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.199 2010/02/16 15:17:17 msaitoh Exp $");
#include "rnd.h"
@@ -231,6 +231,13 @@
#define WM_LINKUP_TIMEOUT 50
+static uint16_t swfwphysem[] = {
+ SWFW_PHY0_SM,
+ SWFW_PHY1_SM,
+ SWFW_PHY2_SM,
+ SWFW_PHY3_SM
+};
+
/*
* Software state per device.
*/
@@ -243,31 +250,33 @@
bus_space_tag_t sc_flasht; /* flash registers space tag */
bus_space_handle_t sc_flashh; /* flash registers space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
+ bus_dmamap_t sc_cddmamap; /* control data DMA map */
+#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
+
struct ethercom sc_ethercom; /* ethernet common data */
+ struct mii_data sc_mii; /* MII/media information */
+
pci_chipset_tag_t sc_pc;
pcitag_t sc_pcitag;
+ int sc_bus_speed; /* PCI/PCIX bus speed */
+ int sc_pcixe_capoff; /* PCI[Xe] capability register offset */
wm_chip_type sc_type; /* MAC type */
int sc_rev; /* MAC revision */
wm_phy_type sc_phytype; /* PHY type */
+ int sc_funcid; /* unit number of the chip (0 to 3) */
int sc_flags; /* flags; see below */
int sc_if_flags; /* last if_flags */
- int sc_bus_speed; /* PCI/PCIX bus speed */
- int sc_pcix_offset; /* PCIX capability register offset */
int sc_flowflags; /* 802.3x flow control flags */
+ int sc_align_tweak;
void *sc_ih; /* interrupt cookie */
+ callout_t sc_tick_ch; /* tick callout */
int sc_ee_addrbits; /* EEPROM address bits */
-
- struct mii_data sc_mii; /* MII/media information */
-
- callout_t sc_tick_ch; /* tick callout */
-
- bus_dmamap_t sc_cddmamap; /* control data DMA map */
-#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
-
- int sc_align_tweak;
+ int sc_ich8_flash_base;
+ int sc_ich8_flash_bank_size;
+ int sc_nvm_k1_enabled;
/*
* Software state for the transmit and receive descriptors.
@@ -364,9 +373,6 @@
#if NRND > 0
rndsource_element_t rnd_source; /* random source */
#endif
- int sc_ich8_flash_base;
- int sc_ich8_flash_bank_size;
- int sc_nvm_k1_enabled;
};
#define WM_RXCHAIN_RESET(sc) \
@@ -523,6 +529,8 @@
static void wm_gmii_bm_writereg(device_t, int, int, int);
static int wm_gmii_hv_readreg(device_t, int, int);
static void wm_gmii_hv_writereg(device_t, int, int, int);
+static int wm_sgmii_readreg(device_t, int, int);
+static void wm_sgmii_writereg(device_t, int, int, int);
static void wm_gmii_statchg(device_t);
@@ -533,7 +541,7 @@
static int wm_kmrn_readreg(struct wm_softc *, int);
static void wm_kmrn_writereg(struct wm_softc *, int, int);
-static void wm_set_spiaddrsize(struct wm_softc *);
+static void wm_set_spiaddrbits(struct wm_softc *);
static int wm_match(device_t, cfdata_t, void *);
static void wm_attach(device_t, device_t, void *);
static int wm_is_onboard_nvm_eeprom(struct wm_softc *);
@@ -566,6 +574,8 @@
static void wm_hv_phy_workaround_ich8lan(struct wm_softc *);
static void wm_k1_gig_workaround_hv(struct wm_softc *, int);
static void wm_configure_k1_ich8lan(struct wm_softc *, int);
+static void wm_set_pcie_completion_timeout(struct wm_softc *);
+static void wm_reset_init_script_82575(struct wm_softc *);
CFATTACH_DECL_NEW(wm, sizeof(struct wm_softc),
wm_match, wm_attach, NULL, NULL);
@@ -882,6 +892,72 @@
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PCH_D_DC,
"PCH LAN (82578DC) Controller",
WM_T_PCH, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575EB_COPPER,
+ "82575EB dual-1000baseT Ethernet",
+ WM_T_82575, WMP_F_1000T },
+#if 0
+ /*
+ * not sure if WMP_F_1000X or WMP_F_SERDES - we do not have it - so
+ * disabled for now ...
+ */
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575EB_FIBER_SERDES,
+ "82575EB dual-1000baseX Ethernet (SERDES)",
+ WM_T_82575, WMP_F_SERDES },
+#endif
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575GB_QUAD_COPPER,
+ "82575GB quad-1000baseT Ethernet",
+ WM_T_82575, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82575GB_QUAD_COPPER_PM,
+ "82575GB quad-1000baseT Ethernet (PM)",
+ WM_T_82575, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_COPPER,
+ "82576 1000BaseT Ethernet",
+ WM_T_82576, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_FIBER,
+ "82576 1000BaseX Ethernet",
+ WM_T_82576, WMP_F_1000X },
+#if 0
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_SERDES,
+ "82576 gigabit Ethernet (SERDES)",
+ WM_T_82576, WMP_F_SERDES },
+#endif
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_QUAD_COPPER,
+ "82576 quad-1000BaseT Ethernet",
+ WM_T_82576, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_NS,
+ "82576 gigabit Ethernet",
+ WM_T_82576, WMP_F_1000T },
+#if 0
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_NS_SERDES,
+ "82576 gigabit Ethernet (SERDES)",
+ WM_T_82576, WMP_F_SERDES },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82576_SERDES_QUAD,
+ "82576 quad-gigabit Ethernet (SERDES)",
+ WM_T_82576, WMP_F_SERDES },
+#endif
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER,
+ "82580 1000BaseT Ethernet",
+ WM_T_82580, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_FIBER,
+ "82580 1000BaseX Ethernet",
+ WM_T_82580, WMP_F_1000X },
+#if 0
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SERDES,
+ "82580 1000BaseT Ethernet (SERDES)",
+ WM_T_82580, WMP_F_SERDES },
+#endif
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_SGMII,
+ "82580 gigabit Ethernet (SGMII)",
+ WM_T_82580, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_COPPER_DUAL,
+ "82580 dual-1000BaseT Ethernet",
+ WM_T_82580, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_ER,
+ "82580 1000BaseT Ethernet",
+ WM_T_82580ER, WMP_F_1000T },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82580_ER_DUAL,
+ "82580 dual-1000BaseT Ethernet",
+ WM_T_82580ER, WMP_F_1000T },
{ 0, 0,
NULL,
0, 0 },
@@ -910,6 +986,28 @@
}
static inline void
+wm_82575_write_8bit_ctlr_reg(struct wm_softc *sc, uint32_t reg, uint32_t off,
+ uint32_t data)
+{
+ uint32_t regval;
+ int i;
+
+ regval = (data & SCTL_CTL_DATA_MASK) | (off << SCTL_CTL_ADDR_SHIFT);
+
+ CSR_WRITE(sc, reg, regval);
+
+ for (i = 0; i < SCTL_CTL_POLL_TIMEOUT; i++) {
+ delay(5);
+ if (CSR_READ(sc, reg) & SCTL_CTL_READY)
+ break;
+ }
+ if (i == SCTL_CTL_POLL_TIMEOUT) {
+ aprint_error("%s: WARNING: i82575 reg 0x%08x setup did not indicate ready\n",
+ device_xname(sc->sc_dev), reg);
+ }
+}
+
+static inline void
wm_set_dma_addr(volatile wiseman_addr_t *wa, bus_addr_t v)
{
wa->wa_low = htole32(v & 0xffffffffU);
@@ -920,7 +1018,7 @@
}
static void
-wm_set_spiaddrsize(struct wm_softc *sc)
+wm_set_spiaddrbits(struct wm_softc *sc)
{
uint32_t reg;
@@ -1010,6 +1108,10 @@
sc->sc_type = WM_T_82542_2_0;
}
+ if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
+ || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER))
+ sc->sc_flags |= WM_F_NEWQUEUE;
+
/* Set device properties (mactype) */
dict = device_properties(sc->sc_dev);
prop_dictionary_set_uint32(dict, "mactype", sc->sc_type);
@@ -1110,6 +1212,17 @@
aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
/*
+ * Check the function ID (unit number of the chip).
+ */
+ if ((sc->sc_type == WM_T_82546) || (sc->sc_type == WM_T_82546_3)
+ || (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003)
+ || (sc->sc_type == WM_T_82575))
+ sc->sc_funcid = (CSR_READ(sc, WMREG_STATUS)
+ >> STATUS_FUNCID_SHIFT) & STATUS_FUNCID_MASK;
+ else
+ sc->sc_funcid = 0;
+
+ /*
* Determine a few things about the bus we're connected to.
*/
if (sc->sc_type < WM_T_82543) {
@@ -1135,8 +1248,15 @@
sc->sc_flags |= WM_F_PCIE;
if ((sc->sc_type != WM_T_ICH8) && (sc->sc_type != WM_T_ICH9)
&& (sc->sc_type != WM_T_ICH10)
- && (sc->sc_type != WM_T_PCH))
+ && (sc->sc_type != WM_T_PCH)) {
sc->sc_flags |= WM_F_EEPROM_SEMAPHORE;
+ /* ICH* and PCH have no PCIe capability registers */
+ if (pci_get_capability(pa->pa_pc, pa->pa_tag,
+ PCI_CAP_PCIEXPRESS, &sc->sc_pcixe_capoff,
+ NULL) == 0)
+ aprint_error_dev(sc->sc_dev,
+ "unable to find PCIe capability\n");
+ }
aprint_verbose_dev(sc->sc_dev, "PCI-Express bus\n");
} else {
reg = CSR_READ(sc, WMREG_STATUS);
@@ -1147,7 +1267,7 @@
sc->sc_flags |= WM_F_PCIX;
if (pci_get_capability(pa->pa_pc, pa->pa_tag,
- PCI_CAP_PCIX, &sc->sc_pcix_offset, NULL) == 0)
+ PCI_CAP_PCIX, &sc->sc_pcixe_capoff, NULL) == 0)
aprint_error_dev(sc->sc_dev,
"unable to find PCIX capability\n");
else if (sc->sc_type != WM_T_82545_3 &&
@@ -1158,9 +1278,9 @@
* incorrectly.
*/
pcix_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag,
- sc->sc_pcix_offset + PCI_PCIX_CMD);
+ sc->sc_pcixe_capoff + PCI_PCIX_CMD);
pcix_sts = pci_conf_read(pa->pa_pc, pa->pa_tag,
- sc->sc_pcix_offset + PCI_PCIX_STATUS);
+ sc->sc_pcixe_capoff + PCI_PCIX_STATUS);
bytecnt =
(pcix_cmd & PCI_PCIX_CMD_BYTECNT_MASK) >>
@@ -1176,7 +1296,7 @@
~PCI_PCIX_CMD_BYTECNT_MASK) |
(maxb << PCI_PCIX_CMD_BYTECNT_SHIFT);
pci_conf_write(pa->pa_pc, pa->pa_tag,
- sc->sc_pcix_offset + PCI_PCIX_CMD,
+ sc->sc_pcixe_capoff + PCI_PCIX_CMD,
pcix_cmd);
}
Home |
Main Index |
Thread Index |
Old Index