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